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