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"); 677