xref: /openbmc/linux/drivers/usb/serial/kobil_sct.c (revision 3b64b188)
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");
659