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