]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/usb/serial/kobil_sct.c
Merge branch 'testing/bcmring' into next/cleanups
[karo-tx-linux.git] / drivers / usb / serial / kobil_sct.c
1 /*
2  *  KOBIL USB Smart Card Terminal Driver
3  *
4  *  Copyright (C) 2002  KOBIL Systems GmbH
5  *  Author: Thomas Wahrenbruch
6  *
7  *  Contact: linuxusb@kobil.de
8  *
9  *  This program is largely derived from work by the linux-usb group
10  *  and associated source files.  Please see the usb/serial files for
11  *  individual credits and copyrights.
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and
19  *  patience.
20  *
21  * Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
22  * (Adapter K), B1 Professional and KAAN Professional (Adapter B)
23  */
24
25
26 #include <linux/kernel.h>
27 #include <linux/errno.h>
28 #include <linux/init.h>
29 #include <linux/slab.h>
30 #include <linux/tty.h>
31 #include <linux/tty_driver.h>
32 #include <linux/tty_flip.h>
33 #include <linux/module.h>
34 #include <linux/spinlock.h>
35 #include <linux/uaccess.h>
36 #include <linux/usb.h>
37 #include <linux/usb/serial.h>
38 #include <linux/ioctl.h>
39 #include "kobil_sct.h"
40
41 static bool debug;
42
43 /* Version Information */
44 #define DRIVER_VERSION "21/05/2004"
45 #define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com"
46 #define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)"
47
48 #define KOBIL_VENDOR_ID                 0x0D46
49 #define KOBIL_ADAPTER_B_PRODUCT_ID      0x2011
50 #define KOBIL_ADAPTER_K_PRODUCT_ID      0x2012
51 #define KOBIL_USBTWIN_PRODUCT_ID        0x0078
52 #define KOBIL_KAAN_SIM_PRODUCT_ID       0x0081
53
54 #define KOBIL_TIMEOUT           500
55 #define KOBIL_BUF_LENGTH        300
56
57
58 /* Function prototypes */
59 static int  kobil_startup(struct usb_serial *serial);
60 static void kobil_release(struct usb_serial *serial);
61 static int  kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
62 static void kobil_close(struct usb_serial_port *port);
63 static int  kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
64                          const unsigned char *buf, int count);
65 static int  kobil_write_room(struct tty_struct *tty);
66 static int  kobil_ioctl(struct tty_struct *tty,
67                         unsigned int cmd, unsigned long arg);
68 static int  kobil_tiocmget(struct tty_struct *tty);
69 static int  kobil_tiocmset(struct tty_struct *tty,
70                            unsigned int set, unsigned int clear);
71 static void kobil_read_int_callback(struct urb *urb);
72 static void kobil_write_callback(struct urb *purb);
73 static void kobil_set_termios(struct tty_struct *tty,
74                         struct usb_serial_port *port, struct ktermios *old);
75 static void kobil_init_termios(struct tty_struct *tty);
76
77 static const struct usb_device_id id_table[] = {
78         { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) },
79         { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_K_PRODUCT_ID) },
80         { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_USBTWIN_PRODUCT_ID) },
81         { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_KAAN_SIM_PRODUCT_ID) },
82         { }                     /* Terminating entry */
83 };
84 MODULE_DEVICE_TABLE(usb, id_table);
85
86 static struct usb_serial_driver kobil_device = {
87         .driver = {
88                 .owner =        THIS_MODULE,
89                 .name =         "kobil",
90         },
91         .description =          "KOBIL USB smart card terminal",
92         .id_table =             id_table,
93         .num_ports =            1,
94         .attach =               kobil_startup,
95         .release =              kobil_release,
96         .ioctl =                kobil_ioctl,
97         .set_termios =          kobil_set_termios,
98         .init_termios =         kobil_init_termios,
99         .tiocmget =             kobil_tiocmget,
100         .tiocmset =             kobil_tiocmset,
101         .open =                 kobil_open,
102         .close =                kobil_close,
103         .write =                kobil_write,
104         .write_room =           kobil_write_room,
105         .read_int_callback =    kobil_read_int_callback,
106 };
107
108 static struct usb_serial_driver * const serial_drivers[] = {
109         &kobil_device, NULL
110 };
111
112 struct kobil_private {
113         int write_int_endpoint_address;
114         int read_int_endpoint_address;
115         unsigned char buf[KOBIL_BUF_LENGTH]; /* buffer for the APDU to send */
116         int filled;  /* index of the last char in buf */
117         int cur_pos; /* index of the next char to send in buf */
118         __u16 device_type;
119 };
120
121
122 static int kobil_startup(struct usb_serial *serial)
123 {
124         int i;
125         struct kobil_private *priv;
126         struct usb_device *pdev;
127         struct usb_host_config *actconfig;
128         struct usb_interface *interface;
129         struct usb_host_interface *altsetting;
130         struct usb_host_endpoint *endpoint;
131
132         priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL);
133         if (!priv)
134                 return -ENOMEM;
135
136         priv->filled = 0;
137         priv->cur_pos = 0;
138         priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct);
139
140         switch (priv->device_type) {
141         case KOBIL_ADAPTER_B_PRODUCT_ID:
142                 printk(KERN_DEBUG "KOBIL B1 PRO / KAAN PRO detected\n");
143                 break;
144         case KOBIL_ADAPTER_K_PRODUCT_ID:
145                 printk(KERN_DEBUG
146                   "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n");
147                 break;
148         case KOBIL_USBTWIN_PRODUCT_ID:
149                 printk(KERN_DEBUG "KOBIL USBTWIN detected\n");
150                 break;
151         case KOBIL_KAAN_SIM_PRODUCT_ID:
152                 printk(KERN_DEBUG "KOBIL KAAN SIM detected\n");
153                 break;
154         }
155         usb_set_serial_port_data(serial->port[0], priv);
156
157         /* search for the necessary endpoints */
158         pdev = serial->dev;
159         actconfig = pdev->actconfig;
160         interface = actconfig->interface[0];
161         altsetting = interface->cur_altsetting;
162         endpoint = altsetting->endpoint;
163
164         for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
165                 endpoint = &altsetting->endpoint[i];
166                 if (usb_endpoint_is_int_out(&endpoint->desc)) {
167                         dbg("%s Found interrupt out endpoint. Address: %d",
168                                 __func__, endpoint->desc.bEndpointAddress);
169                         priv->write_int_endpoint_address =
170                                 endpoint->desc.bEndpointAddress;
171                 }
172                 if (usb_endpoint_is_int_in(&endpoint->desc)) {
173                         dbg("%s Found interrupt in  endpoint. Address: %d",
174                                 __func__, endpoint->desc.bEndpointAddress);
175                         priv->read_int_endpoint_address =
176                                 endpoint->desc.bEndpointAddress;
177                 }
178         }
179         return 0;
180 }
181
182
183 static void kobil_release(struct usb_serial *serial)
184 {
185         int i;
186
187         for (i = 0; i < serial->num_ports; ++i)
188                 kfree(usb_get_serial_port_data(serial->port[i]));
189 }
190
191 static void kobil_init_termios(struct tty_struct *tty)
192 {
193         /* Default to echo off and other sane device settings */
194         tty->termios->c_lflag = 0;
195         tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
196         tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
197         /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
198         tty->termios->c_oflag &= ~ONLCR;
199 }
200
201 static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
202 {
203         int result = 0;
204         struct kobil_private *priv;
205         unsigned char *transfer_buffer;
206         int transfer_buffer_length = 8;
207         int write_urb_transfer_buffer_length = 8;
208
209         priv = usb_get_serial_port_data(port);
210
211         /* allocate memory for transfer buffer */
212         transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
213         if (!transfer_buffer)
214                 return -ENOMEM;
215
216         /* allocate write_urb */
217         if (!port->write_urb) {
218                 dbg("%s - port %d  Allocating port->write_urb",
219                                                 __func__, port->number);
220                 port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
221                 if (!port->write_urb) {
222                         dbg("%s - port %d usb_alloc_urb failed",
223                                                 __func__, port->number);
224                         kfree(transfer_buffer);
225                         return -ENOMEM;
226                 }
227         }
228
229         /* allocate memory for write_urb transfer buffer */
230         port->write_urb->transfer_buffer =
231                         kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
232         if (!port->write_urb->transfer_buffer) {
233                 kfree(transfer_buffer);
234                 usb_free_urb(port->write_urb);
235                 port->write_urb = NULL;
236                 return -ENOMEM;
237         }
238
239         /* get hardware version */
240         result = usb_control_msg(port->serial->dev,
241                           usb_rcvctrlpipe(port->serial->dev, 0),
242                           SUSBCRequest_GetMisc,
243                           USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
244                           SUSBCR_MSC_GetHWVersion,
245                           0,
246                           transfer_buffer,
247                           transfer_buffer_length,
248                           KOBIL_TIMEOUT
249         );
250         dbg("%s - port %d Send get_HW_version URB returns: %i",
251                 __func__, port->number, result);
252         dbg("Harware version: %i.%i.%i",
253                 transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]);
254
255         /* get firmware version */
256         result = usb_control_msg(port->serial->dev,
257                           usb_rcvctrlpipe(port->serial->dev, 0),
258                           SUSBCRequest_GetMisc,
259                           USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
260                           SUSBCR_MSC_GetFWVersion,
261                           0,
262                           transfer_buffer,
263                           transfer_buffer_length,
264                           KOBIL_TIMEOUT
265         );
266         dbg("%s - port %d Send get_FW_version URB returns: %i",
267                                         __func__, port->number, result);
268         dbg("Firmware version: %i.%i.%i",
269                 transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]);
270
271         if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
272                         priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
273                 /* Setting Baudrate, Parity and Stopbits */
274                 result = usb_control_msg(port->serial->dev,
275                           usb_rcvctrlpipe(port->serial->dev, 0),
276                           SUSBCRequest_SetBaudRateParityAndStopBits,
277                           USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
278                           SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity |
279                                                         SUSBCR_SPASB_1StopBit,
280                           0,
281                           transfer_buffer,
282                           0,
283                           KOBIL_TIMEOUT
284                 );
285                 dbg("%s - port %d Send set_baudrate URB returns: %i",
286                                         __func__, port->number, result);
287
288                 /* reset all queues */
289                 result = usb_control_msg(port->serial->dev,
290                           usb_rcvctrlpipe(port->serial->dev, 0),
291                           SUSBCRequest_Misc,
292                           USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
293                           SUSBCR_MSC_ResetAllQueues,
294                           0,
295                           transfer_buffer,
296                           0,
297                           KOBIL_TIMEOUT
298                 );
299                 dbg("%s - port %d Send reset_all_queues URB returns: %i",
300                                         __func__, port->number, result);
301         }
302         if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
303             priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
304             priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
305                 /* start reading (Adapter B 'cause PNP string) */
306                 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
307                 dbg("%s - port %d Send read URB returns: %i",
308                                         __func__, port->number, result);
309         }
310
311         kfree(transfer_buffer);
312         return 0;
313 }
314
315
316 static void kobil_close(struct usb_serial_port *port)
317 {
318         /* FIXME: Add rts/dtr methods */
319         if (port->write_urb) {
320                 usb_poison_urb(port->write_urb);
321                 kfree(port->write_urb->transfer_buffer);
322                 usb_free_urb(port->write_urb);
323                 port->write_urb = NULL;
324         }
325         usb_kill_urb(port->interrupt_in_urb);
326 }
327
328
329 static void kobil_read_int_callback(struct urb *urb)
330 {
331         int result;
332         struct usb_serial_port *port = urb->context;
333         struct tty_struct *tty;
334         unsigned char *data = urb->transfer_buffer;
335         int status = urb->status;
336 /*      char *dbg_data; */
337
338         if (status) {
339                 dbg("%s - port %d Read int status not zero: %d",
340                     __func__, port->number, status);
341                 return;
342         }
343
344         tty = tty_port_tty_get(&port->port);
345         if (tty && urb->actual_length) {
346
347                 /* BEGIN DEBUG */
348                 /*
349                   dbg_data = kzalloc((3 *  purb->actual_length + 10)
350                                                 * sizeof(char), GFP_KERNEL);
351                   if (! dbg_data) {
352                           return;
353                   }
354                   for (i = 0; i < purb->actual_length; i++) {
355                           sprintf(dbg_data +3*i, "%02X ", data[i]);
356                   }
357                   dbg(" <-- %s", dbg_data);
358                   kfree(dbg_data);
359                 */
360                 /* END DEBUG */
361
362                 tty_insert_flip_string(tty, data, urb->actual_length);
363                 tty_flip_buffer_push(tty);
364         }
365         tty_kref_put(tty);
366
367         result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
368         dbg("%s - port %d Send read URB returns: %i",
369                         __func__, port->number, result);
370 }
371
372
373 static void kobil_write_callback(struct urb *purb)
374 {
375 }
376
377
378 static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
379                         const unsigned char *buf, int count)
380 {
381         int length = 0;
382         int result = 0;
383         int todo = 0;
384         struct kobil_private *priv;
385
386         if (count == 0) {
387                 dbg("%s - port %d write request of 0 bytes",
388                                                 __func__, port->number);
389                 return 0;
390         }
391
392         priv = usb_get_serial_port_data(port);
393
394         if (count > (KOBIL_BUF_LENGTH - priv->filled)) {
395                 dbg("%s - port %d Error: write request bigger than buffer size", __func__, port->number);
396                 return -ENOMEM;
397         }
398
399         /* Copy data to buffer */
400         memcpy(priv->buf + priv->filled, buf, count);
401         usb_serial_debug_data(debug, &port->dev, __func__, count,
402                                                 priv->buf + priv->filled);
403         priv->filled = priv->filled + count;
404
405         /* only send complete block. TWIN, KAAN SIM and adapter K
406            use the same protocol. */
407         if (((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) ||
408              ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4)))) {
409                 /* stop reading (except TWIN and KAAN SIM) */
410                 if ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID)
411                         || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID))
412                         usb_kill_urb(port->interrupt_in_urb);
413
414                 todo = priv->filled - priv->cur_pos;
415
416                 while (todo > 0) {
417                         /* max 8 byte in one urb (endpoint size) */
418                         length = (todo < 8) ? todo : 8;
419                         /* copy data to transfer buffer */
420                         memcpy(port->write_urb->transfer_buffer,
421                                         priv->buf + priv->cur_pos, length);
422                         usb_fill_int_urb(port->write_urb,
423                                   port->serial->dev,
424                                   usb_sndintpipe(port->serial->dev,
425                                         priv->write_int_endpoint_address),
426                                   port->write_urb->transfer_buffer,
427                                   length,
428                                   kobil_write_callback,
429                                   port,
430                                   8
431                         );
432
433                         priv->cur_pos = priv->cur_pos + length;
434                         result = usb_submit_urb(port->write_urb, GFP_NOIO);
435                         dbg("%s - port %d Send write URB returns: %i",
436                                         __func__, port->number, result);
437                         todo = priv->filled - priv->cur_pos;
438
439                         if (todo > 0)
440                                 msleep(24);
441                 }
442
443                 priv->filled = 0;
444                 priv->cur_pos = 0;
445
446                 /* start reading (except TWIN and KAAN SIM) */
447                 if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
448                         priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
449                         result = usb_submit_urb(port->interrupt_in_urb,
450                                                                 GFP_NOIO);
451                         dbg("%s - port %d Send read URB returns: %i",
452                                         __func__, port->number, result);
453                 }
454         }
455         return count;
456 }
457
458
459 static int kobil_write_room(struct tty_struct *tty)
460 {
461         /* FIXME */
462         return 8;
463 }
464
465
466 static int kobil_tiocmget(struct tty_struct *tty)
467 {
468         struct usb_serial_port *port = tty->driver_data;
469         struct kobil_private *priv;
470         int result;
471         unsigned char *transfer_buffer;
472         int transfer_buffer_length = 8;
473
474         priv = usb_get_serial_port_data(port);
475         if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID
476                         || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
477                 /* This device doesn't support ioctl calls */
478                 return -EINVAL;
479         }
480
481         /* allocate memory for transfer buffer */
482         transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
483         if (!transfer_buffer)
484                 return -ENOMEM;
485
486         result = usb_control_msg(port->serial->dev,
487                           usb_rcvctrlpipe(port->serial->dev, 0),
488                           SUSBCRequest_GetStatusLineState,
489                           USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
490                           0,
491                           0,
492                           transfer_buffer,
493                           transfer_buffer_length,
494                           KOBIL_TIMEOUT);
495
496         dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x",
497             __func__, port->number, result, transfer_buffer[0]);
498
499         result = 0;
500         if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0)
501                 result = TIOCM_DSR;
502         kfree(transfer_buffer);
503         return result;
504 }
505
506 static int kobil_tiocmset(struct tty_struct *tty,
507                            unsigned int set, unsigned int clear)
508 {
509         struct usb_serial_port *port = tty->driver_data;
510         struct kobil_private *priv;
511         int result;
512         int dtr = 0;
513         int rts = 0;
514         unsigned char *transfer_buffer;
515         int transfer_buffer_length = 8;
516
517         /* FIXME: locking ? */
518         priv = usb_get_serial_port_data(port);
519         if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID
520                 || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
521                 /* This device doesn't support ioctl calls */
522                 return -EINVAL;
523         }
524
525         /* allocate memory for transfer buffer */
526         transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
527         if (!transfer_buffer)
528                 return -ENOMEM;
529
530         if (set & TIOCM_RTS)
531                 rts = 1;
532         if (set & TIOCM_DTR)
533                 dtr = 1;
534         if (clear & TIOCM_RTS)
535                 rts = 0;
536         if (clear & TIOCM_DTR)
537                 dtr = 0;
538
539         if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) {
540                 if (dtr != 0)
541                         dbg("%s - port %d Setting DTR",
542                                                 __func__, port->number);
543                 else
544                         dbg("%s - port %d Clearing DTR",
545                                                 __func__, port->number);
546                 result = usb_control_msg(port->serial->dev,
547                           usb_rcvctrlpipe(port->serial->dev, 0),
548                           SUSBCRequest_SetStatusLinesOrQueues,
549                           USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
550                           ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),
551                           0,
552                           transfer_buffer,
553                           0,
554                           KOBIL_TIMEOUT);
555         } else {
556                 if (rts != 0)
557                         dbg("%s - port %d Setting RTS",
558                                                 __func__, port->number);
559                 else
560                         dbg("%s - port %d Clearing RTS",
561                                                 __func__, port->number);
562                 result = usb_control_msg(port->serial->dev,
563                         usb_rcvctrlpipe(port->serial->dev, 0),
564                         SUSBCRequest_SetStatusLinesOrQueues,
565                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
566                         ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),
567                         0,
568                         transfer_buffer,
569                         0,
570                         KOBIL_TIMEOUT);
571         }
572         dbg("%s - port %d Send set_status_line URB returns: %i",
573                                         __func__, port->number, result);
574         kfree(transfer_buffer);
575         return (result < 0) ? result : 0;
576 }
577
578 static void kobil_set_termios(struct tty_struct *tty,
579                         struct usb_serial_port *port, struct ktermios *old)
580 {
581         struct kobil_private *priv;
582         int result;
583         unsigned short urb_val = 0;
584         int c_cflag = tty->termios->c_cflag;
585         speed_t speed;
586
587         priv = usb_get_serial_port_data(port);
588         if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
589                         priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
590                 /* This device doesn't support ioctl calls */
591                 *tty->termios = *old;
592                 return;
593         }
594
595         speed = tty_get_baud_rate(tty);
596         switch (speed) {
597         case 1200:
598                 urb_val = SUSBCR_SBR_1200;
599                 break;
600         default:
601                 speed = 9600;
602         case 9600:
603                 urb_val = SUSBCR_SBR_9600;
604                 break;
605         }
606         urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits :
607                                                         SUSBCR_SPASB_1StopBit;
608         if (c_cflag & PARENB) {
609                 if  (c_cflag & PARODD)
610                         urb_val |= SUSBCR_SPASB_OddParity;
611                 else
612                         urb_val |= SUSBCR_SPASB_EvenParity;
613         } else
614                 urb_val |= SUSBCR_SPASB_NoParity;
615         tty->termios->c_cflag &= ~CMSPAR;
616         tty_encode_baud_rate(tty, speed, speed);
617
618         result = usb_control_msg(port->serial->dev,
619                   usb_rcvctrlpipe(port->serial->dev, 0),
620                   SUSBCRequest_SetBaudRateParityAndStopBits,
621                   USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
622                   urb_val,
623                   0,
624                   NULL,
625                   0,
626                   KOBIL_TIMEOUT
627                 );
628 }
629
630 static int kobil_ioctl(struct tty_struct *tty,
631                                         unsigned int cmd, unsigned long arg)
632 {
633         struct usb_serial_port *port = tty->driver_data;
634         struct kobil_private *priv = usb_get_serial_port_data(port);
635         unsigned char *transfer_buffer;
636         int transfer_buffer_length = 8;
637         int result;
638
639         if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
640                         priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
641                 /* This device doesn't support ioctl calls */
642                 return -ENOIOCTLCMD;
643
644         switch (cmd) {
645         case TCFLSH:
646                 transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
647                 if (!transfer_buffer)
648                         return -ENOBUFS;
649
650                 result = usb_control_msg(port->serial->dev,
651                           usb_rcvctrlpipe(port->serial->dev, 0),
652                           SUSBCRequest_Misc,
653                           USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
654                           SUSBCR_MSC_ResetAllQueues,
655                           0,
656                           NULL, /* transfer_buffer, */
657                           0,
658                           KOBIL_TIMEOUT
659                         );
660
661                 dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __func__, port->number, result);
662                 kfree(transfer_buffer);
663                 return (result < 0) ? -EIO: 0;
664         default:
665                 return -ENOIOCTLCMD;
666         }
667 }
668
669 module_usb_serial_driver(serial_drivers, id_table);
670
671 MODULE_AUTHOR(DRIVER_AUTHOR);
672 MODULE_DESCRIPTION(DRIVER_DESC);
673 MODULE_LICENSE("GPL");
674
675 module_param(debug, bool, S_IRUGO | S_IWUSR);
676 MODULE_PARM_DESC(debug, "Debug enabled or not");