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