kobil_sct.c revision 95da310e66ee8090119596c70ca8432e57f9a97f
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 <asm/uaccess.h> 48#include <linux/usb.h> 49#include <linux/usb/serial.h> 50#include <linux/ioctl.h> 51#include "kobil_sct.h" 52 53static 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 */ 71static int kobil_startup (struct usb_serial *serial); 72static void kobil_shutdown (struct usb_serial *serial); 73static int kobil_open (struct tty_struct *tty, 74 struct usb_serial_port *port, struct file *filp); 75static void kobil_close (struct tty_struct *tty, struct usb_serial_port *port, 76 struct file *filp); 77static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, 78 const unsigned char *buf, int count); 79static int kobil_write_room(struct tty_struct *tty); 80static int kobil_ioctl(struct tty_struct *tty, struct file *file, 81 unsigned int cmd, unsigned long arg); 82static int kobil_tiocmget(struct tty_struct *tty, struct file *file); 83static int kobil_tiocmset(struct tty_struct *tty, struct file *file, 84 unsigned int set, unsigned int clear); 85static void kobil_read_int_callback( struct urb *urb ); 86static void kobil_write_callback( struct urb *purb ); 87static void kobil_set_termios(struct tty_struct *tty, 88 struct usb_serial_port *port, struct ktermios *old); 89 90 91static 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 100MODULE_DEVICE_TABLE (usb, id_table); 101 102static 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 111static 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 134struct 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 144static 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 159 priv->filled = 0; 160 priv->cur_pos = 0; 161 priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct); 162 163 switch (priv->device_type){ 164 case KOBIL_ADAPTER_B_PRODUCT_ID: 165 printk(KERN_DEBUG "KOBIL B1 PRO / KAAN PRO detected\n"); 166 break; 167 case KOBIL_ADAPTER_K_PRODUCT_ID: 168 printk(KERN_DEBUG "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", __func__, endpoint->desc.bEndpointAddress); 190 priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress; 191 } 192 if (usb_endpoint_is_int_in(&endpoint->desc)) { 193 dbg("%s Found interrupt in endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); 194 priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress; 195 } 196 } 197 return 0; 198} 199 200 201static void kobil_shutdown (struct usb_serial *serial) 202{ 203 int i; 204 dbg("%s - port %d", __func__, serial->port[0]->number); 205 206 for (i=0; i < serial->num_ports; ++i) { 207 while (serial->port[i]->port.count > 0) { 208 kobil_close (NULL, serial->port[i], NULL); 209 } 210 kfree(usb_get_serial_port_data(serial->port[i])); 211 usb_set_serial_port_data(serial->port[i], NULL); 212 } 213} 214 215 216static int kobil_open(struct tty_struct *tty, 217 struct usb_serial_port *port, struct file *filp) 218{ 219 int result = 0; 220 struct kobil_private *priv; 221 unsigned char *transfer_buffer; 222 int transfer_buffer_length = 8; 223 int write_urb_transfer_buffer_length = 8; 224 225 dbg("%s - port %d", __func__, port->number); 226 priv = usb_get_serial_port_data(port); 227 228 // someone sets the dev to 0 if the close method has been called 229 port->interrupt_in_urb->dev = port->serial->dev; 230 231 232 /* force low_latency on so that our tty_push actually forces 233 * the data through, otherwise it is scheduled, and with high 234 * data rates (like with OHCI) data can get lost. 235 */ 236 if (tty) { 237 tty->low_latency = 1; 238 239 /* Default to echo off and other sane device settings */ 240 tty->termios->c_lflag = 0; 241 tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); 242 tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; 243 tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) 244 } 245 // allocate memory for transfer buffer 246 transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); 247 if (! transfer_buffer) { 248 return -ENOMEM; 249 } 250 251 // allocate write_urb 252 if (!port->write_urb) { 253 dbg("%s - port %d Allocating port->write_urb", __func__, port->number); 254 port->write_urb = usb_alloc_urb(0, GFP_KERNEL); 255 if (!port->write_urb) { 256 dbg("%s - port %d usb_alloc_urb failed", __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 = kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL); 264 if (! port->write_urb->transfer_buffer) { 265 kfree(transfer_buffer); 266 usb_free_urb(port->write_urb); 267 port->write_urb = NULL; 268 return -ENOMEM; 269 } 270 271 // get hardware version 272 result = usb_control_msg( port->serial->dev, 273 usb_rcvctrlpipe(port->serial->dev, 0 ), 274 SUSBCRequest_GetMisc, 275 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN, 276 SUSBCR_MSC_GetHWVersion, 277 0, 278 transfer_buffer, 279 transfer_buffer_length, 280 KOBIL_TIMEOUT 281 ); 282 dbg("%s - port %d Send get_HW_version URB returns: %i", __func__, port->number, result); 283 dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] ); 284 285 // get firmware version 286 result = usb_control_msg( port->serial->dev, 287 usb_rcvctrlpipe(port->serial->dev, 0 ), 288 SUSBCRequest_GetMisc, 289 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN, 290 SUSBCR_MSC_GetFWVersion, 291 0, 292 transfer_buffer, 293 transfer_buffer_length, 294 KOBIL_TIMEOUT 295 ); 296 dbg("%s - port %d Send get_FW_version URB returns: %i", __func__, port->number, result); 297 dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] ); 298 299 if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { 300 // Setting Baudrate, Parity and Stopbits 301 result = usb_control_msg( port->serial->dev, 302 usb_rcvctrlpipe(port->serial->dev, 0 ), 303 SUSBCRequest_SetBaudRateParityAndStopBits, 304 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, 305 SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | SUSBCR_SPASB_1StopBit, 306 0, 307 transfer_buffer, 308 0, 309 KOBIL_TIMEOUT 310 ); 311 dbg("%s - port %d Send set_baudrate URB returns: %i", __func__, port->number, result); 312 313 // reset all queues 314 result = usb_control_msg( port->serial->dev, 315 usb_rcvctrlpipe(port->serial->dev, 0 ), 316 SUSBCRequest_Misc, 317 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, 318 SUSBCR_MSC_ResetAllQueues, 319 0, 320 transfer_buffer, 321 0, 322 KOBIL_TIMEOUT 323 ); 324 dbg("%s - port %d Send reset_all_queues URB returns: %i", __func__, port->number, result); 325 } 326 if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || 327 priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { 328 // start reading (Adapter B 'cause PNP string) 329 result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); 330 dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); 331 } 332 333 kfree(transfer_buffer); 334 return 0; 335} 336 337 338static void kobil_close(struct tty_struct *tty, 339 struct usb_serial_port *port, struct file *filp) 340{ 341 dbg("%s - port %d", __func__, port->number); 342 343 if (port->write_urb) { 344 usb_kill_urb(port->write_urb); 345 usb_free_urb( port->write_urb ); 346 port->write_urb = NULL; 347 } 348 usb_kill_urb(port->interrupt_in_urb); 349} 350 351 352static void kobil_read_int_callback(struct urb *urb) 353{ 354 int result; 355 struct usb_serial_port *port = urb->context; 356 struct tty_struct *tty; 357 unsigned char *data = urb->transfer_buffer; 358 int status = urb->status; 359// char *dbg_data; 360 361 dbg("%s - port %d", __func__, port->number); 362 363 if (status) { 364 dbg("%s - port %d Read int status not zero: %d", 365 __func__, port->number, status); 366 return; 367 } 368 369 tty = port->port.tty; 370 if (urb->actual_length) { 371 372 // BEGIN DEBUG 373 /* 374 dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); 375 if (! dbg_data) { 376 return; 377 } 378 for (i = 0; i < purb->actual_length; i++) { 379 sprintf(dbg_data +3*i, "%02X ", data[i]); 380 } 381 dbg(" <-- %s", dbg_data ); 382 kfree(dbg_data); 383 */ 384 // END DEBUG 385 386 tty_buffer_request_room(tty, urb->actual_length); 387 tty_insert_flip_string(tty, data, urb->actual_length); 388 tty_flip_buffer_push(tty); 389 } 390 391 // someone sets the dev to 0 if the close method has been called 392 port->interrupt_in_urb->dev = port->serial->dev; 393 394 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 395 dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); 396} 397 398 399static void kobil_write_callback( struct urb *purb ) 400{ 401} 402 403 404static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, 405 const unsigned char *buf, int count) 406{ 407 int length = 0; 408 int result = 0; 409 int todo = 0; 410 struct kobil_private * priv; 411 412 if (count == 0) { 413 dbg("%s - port %d write request of 0 bytes", __func__, port->number); 414 return 0; 415 } 416 417 priv = usb_get_serial_port_data(port); 418 419 if (count > (KOBIL_BUF_LENGTH - priv->filled)) { 420 dbg("%s - port %d Error: write request bigger than buffer size", __func__, port->number); 421 return -ENOMEM; 422 } 423 424 // Copy data to buffer 425 memcpy (priv->buf + priv->filled, buf, count); 426 usb_serial_debug_data(debug, &port->dev, __func__, count, priv->buf + priv->filled); 427 priv->filled = priv->filled + count; 428 429 // only send complete block. TWIN, KAAN SIM and adapter K use the same protocol. 430 if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || 431 ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) { 432 433 // stop reading (except TWIN and KAAN SIM) 434 if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) 435 usb_kill_urb(port->interrupt_in_urb); 436 437 todo = priv->filled - priv->cur_pos; 438 439 while(todo > 0) { 440 // max 8 byte in one urb (endpoint size) 441 length = (todo < 8) ? todo : 8; 442 // copy data to transfer buffer 443 memcpy(port->write_urb->transfer_buffer, priv->buf + priv->cur_pos, length ); 444 usb_fill_int_urb( port->write_urb, 445 port->serial->dev, 446 usb_sndintpipe(port->serial->dev, priv->write_int_endpoint_address), 447 port->write_urb->transfer_buffer, 448 length, 449 kobil_write_callback, 450 port, 451 8 452 ); 453 454 priv->cur_pos = priv->cur_pos + length; 455 result = usb_submit_urb( port->write_urb, GFP_NOIO ); 456 dbg("%s - port %d Send write URB returns: %i", __func__, port->number, result); 457 todo = priv->filled - priv->cur_pos; 458 459 if (todo > 0) { 460 msleep(24); 461 } 462 463 } // end while 464 465 priv->filled = 0; 466 priv->cur_pos = 0; 467 468 // someone sets the dev to 0 if the close method has been called 469 port->interrupt_in_urb->dev = port->serial->dev; 470 471 // start reading (except TWIN and KAAN SIM) 472 if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) { 473 // someone sets the dev to 0 if the close method has been called 474 port->interrupt_in_urb->dev = port->serial->dev; 475 476 result = usb_submit_urb( port->interrupt_in_urb, GFP_NOIO ); 477 dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); 478 } 479 } 480 return count; 481} 482 483 484static int kobil_write_room (struct tty_struct *tty) 485{ 486 //dbg("%s - port %d", __func__, port->number); 487 /* FIXME */ 488 return 8; 489} 490 491 492static int kobil_tiocmget(struct tty_struct *tty, struct file *file) 493{ 494 struct usb_serial_port *port = tty->driver_data; 495 struct kobil_private * priv; 496 int result; 497 unsigned char *transfer_buffer; 498 int transfer_buffer_length = 8; 499 500 priv = usb_get_serial_port_data(port); 501 if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { 502 // This device doesn't support ioctl calls 503 return -EINVAL; 504 } 505 506 // allocate memory for transfer buffer 507 transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); 508 if (!transfer_buffer) { 509 return -ENOMEM; 510 } 511 512 result = usb_control_msg( port->serial->dev, 513 usb_rcvctrlpipe(port->serial->dev, 0 ), 514 SUSBCRequest_GetStatusLineState, 515 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN, 516 0, 517 0, 518 transfer_buffer, 519 transfer_buffer_length, 520 KOBIL_TIMEOUT); 521 522 dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x", 523 __func__, port->number, result, transfer_buffer[0]); 524 525 result = 0; 526 if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) 527 result = TIOCM_DSR; 528 kfree(transfer_buffer); 529 return result; 530} 531 532static int kobil_tiocmset(struct tty_struct *tty, struct file *file, 533 unsigned int set, unsigned int clear) 534{ 535 struct usb_serial_port *port = tty->driver_data; 536 struct kobil_private * priv; 537 int result; 538 int dtr = 0; 539 int rts = 0; 540 unsigned char *transfer_buffer; 541 int transfer_buffer_length = 8; 542 543 /* FIXME: locking ? */ 544 priv = usb_get_serial_port_data(port); 545 if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { 546 // This device doesn't support ioctl calls 547 return -EINVAL; 548 } 549 550 // allocate memory for transfer buffer 551 transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); 552 if (! transfer_buffer) { 553 return -ENOMEM; 554 } 555 556 if (set & TIOCM_RTS) 557 rts = 1; 558 if (set & TIOCM_DTR) 559 dtr = 1; 560 if (clear & TIOCM_RTS) 561 rts = 0; 562 if (clear & TIOCM_DTR) 563 dtr = 0; 564 565 if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) { 566 if (dtr != 0) 567 dbg("%s - port %d Setting DTR", __func__, port->number); 568 else 569 dbg("%s - port %d Clearing DTR", __func__, port->number); 570 result = usb_control_msg( port->serial->dev, 571 usb_rcvctrlpipe(port->serial->dev, 0 ), 572 SUSBCRequest_SetStatusLinesOrQueues, 573 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, 574 ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR), 575 0, 576 transfer_buffer, 577 0, 578 KOBIL_TIMEOUT); 579 } else { 580 if (rts != 0) 581 dbg("%s - port %d Setting RTS", __func__, port->number); 582 else 583 dbg("%s - port %d Clearing RTS", __func__, port->number); 584 result = usb_control_msg( port->serial->dev, 585 usb_rcvctrlpipe(port->serial->dev, 0 ), 586 SUSBCRequest_SetStatusLinesOrQueues, 587 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, 588 ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS), 589 0, 590 transfer_buffer, 591 0, 592 KOBIL_TIMEOUT); 593 } 594 dbg("%s - port %d Send set_status_line URB returns: %i", __func__, port->number, result); 595 kfree(transfer_buffer); 596 return (result < 0) ? result : 0; 597} 598 599static void kobil_set_termios(struct tty_struct *tty, 600 struct usb_serial_port *port, struct ktermios *old) 601{ 602 struct kobil_private * priv; 603 int result; 604 unsigned short urb_val = 0; 605 int c_cflag = tty->termios->c_cflag; 606 speed_t speed; 607 void * settings; 608 609 priv = usb_get_serial_port_data(port); 610 if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) 611 // This device doesn't support ioctl calls 612 return; 613 614 switch (speed = tty_get_baud_rate(tty)) { 615 case 1200: 616 urb_val = SUSBCR_SBR_1200; 617 break; 618 default: 619 speed = 9600; 620 case 9600: 621 urb_val = SUSBCR_SBR_9600; 622 break; 623 } 624 urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; 625 626 settings = kzalloc(50, GFP_KERNEL); 627 if (! settings) 628 return; 629 630 sprintf(settings, "%d ", speed); 631 632 if (c_cflag & PARENB) { 633 if (c_cflag & PARODD) { 634 urb_val |= SUSBCR_SPASB_OddParity; 635 strcat(settings, "Odd Parity"); 636 } else { 637 urb_val |= SUSBCR_SPASB_EvenParity; 638 strcat(settings, "Even Parity"); 639 } 640 } else { 641 urb_val |= SUSBCR_SPASB_NoParity; 642 strcat(settings, "No Parity"); 643 } 644 tty->termios->c_cflag &= ~CMSPAR; 645 tty_encode_baud_rate(tty, speed, speed); 646 647 result = usb_control_msg( port->serial->dev, 648 usb_rcvctrlpipe(port->serial->dev, 0 ), 649 SUSBCRequest_SetBaudRateParityAndStopBits, 650 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, 651 urb_val, 652 0, 653 settings, 654 0, 655 KOBIL_TIMEOUT 656 ); 657 kfree(settings); 658} 659 660static int kobil_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) 661{ 662 struct usb_serial_port *port = tty->driver_data; 663 struct kobil_private * priv = usb_get_serial_port_data(port); 664 unsigned char *transfer_buffer; 665 int transfer_buffer_length = 8; 666 int result; 667 668 if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) 669 // This device doesn't support ioctl calls 670 return 0; 671 672 switch (cmd) { 673 case TCFLSH: 674 transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); 675 if (! transfer_buffer) 676 return -ENOBUFS; 677 678 result = usb_control_msg( port->serial->dev, 679 usb_rcvctrlpipe(port->serial->dev, 0 ), 680 SUSBCRequest_Misc, 681 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, 682 SUSBCR_MSC_ResetAllQueues, 683 0, 684 NULL,//transfer_buffer, 685 0, 686 KOBIL_TIMEOUT 687 ); 688 689 dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __func__, port->number, result); 690 kfree(transfer_buffer); 691 return (result < 0) ? -EIO: 0; 692 default: 693 return -ENOIOCTLCMD; 694 } 695} 696 697static int __init kobil_init (void) 698{ 699 int retval; 700 retval = usb_serial_register(&kobil_device); 701 if (retval) 702 goto failed_usb_serial_register; 703 retval = usb_register(&kobil_driver); 704 if (retval) 705 goto failed_usb_register; 706 707 info(DRIVER_VERSION " " DRIVER_AUTHOR); 708 info(DRIVER_DESC); 709 710 return 0; 711failed_usb_register: 712 usb_serial_deregister(&kobil_device); 713failed_usb_serial_register: 714 return retval; 715} 716 717 718static void __exit kobil_exit (void) 719{ 720 usb_deregister (&kobil_driver); 721 usb_serial_deregister (&kobil_device); 722} 723 724module_init(kobil_init); 725module_exit(kobil_exit); 726 727MODULE_AUTHOR( DRIVER_AUTHOR ); 728MODULE_DESCRIPTION( DRIVER_DESC ); 729MODULE_LICENSE( "GPL" ); 730 731module_param(debug, bool, S_IRUGO | S_IWUSR); 732MODULE_PARM_DESC(debug, "Debug enabled or not"); 733