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