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