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