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