1 /* 2 * USB Cypress M8 driver 3 * 4 * Copyright (C) 2004 5 * Lonnie Mendez (dignome@gmail.com) 6 * Copyright (C) 2003,2004 7 * Neil Whelchel (koyama@firstlight.net) 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * See Documentation/usb/usb-serial.txt for more information on using this 15 * driver 16 * 17 * See http://geocities.com/i0xox0i for information on this driver and the 18 * earthmate usb device. 19 * 20 * Lonnie Mendez <dignome@gmail.com> 21 * 4-29-2005 22 * Fixed problem where setting or retreiving the serial config would fail 23 * with EPIPE. Removed CRTS toggling so the driver behaves more like 24 * other usbserial adapters. Issued new interval of 1ms instead of the 25 * default 10ms. As a result, transfer speed has been substantially 26 * increased from avg. 850bps to avg. 3300bps. initial termios has also 27 * been modified. Cleaned up code and formatting issues so it is more 28 * readable. Replaced the C++ style comments. 29 * 30 * Lonnie Mendez <dignome@gmail.com> 31 * 12-15-2004 32 * Incorporated write buffering from pl2303 driver. Fixed bug with line 33 * handling so both lines are raised in cypress_open. (was dropping rts) 34 * Various code cleanups made as well along with other misc bug fixes. 35 * 36 * Lonnie Mendez <dignome@gmail.com> 37 * 04-10-2004 38 * Driver modified to support dynamic line settings. Various improvments 39 * and features. 40 * 41 * Neil Whelchel 42 * 10-2003 43 * Driver first released. 44 * 45 */ 46 47 /* Thanks to Neil Whelchel for writing the first cypress m8 implementation 48 for linux. */ 49 /* Thanks to cypress for providing references for the hid reports. */ 50 /* Thanks to Jiang Zhang for providing links and for general help. */ 51 /* Code originates and was built up from ftdi_sio, belkin, pl2303 and others.*/ 52 53 54 #include <linux/kernel.h> 55 #include <linux/errno.h> 56 #include <linux/init.h> 57 #include <linux/slab.h> 58 #include <linux/tty.h> 59 #include <linux/tty_driver.h> 60 #include <linux/tty_flip.h> 61 #include <linux/module.h> 62 #include <linux/moduleparam.h> 63 #include <linux/spinlock.h> 64 #include <linux/usb.h> 65 #include <linux/usb/serial.h> 66 #include <linux/serial.h> 67 #include <linux/kfifo.h> 68 #include <linux/delay.h> 69 #include <linux/uaccess.h> 70 #include <asm/unaligned.h> 71 72 #include "cypress_m8.h" 73 74 75 static int debug; 76 static int stats; 77 static int interval; 78 static int unstable_bauds; 79 80 /* 81 * Version Information 82 */ 83 #define DRIVER_VERSION "v1.10" 84 #define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>" 85 #define DRIVER_DESC "Cypress USB to Serial Driver" 86 87 /* write buffer size defines */ 88 #define CYPRESS_BUF_SIZE 1024 89 90 static const struct usb_device_id id_table_earthmate[] = { 91 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, 92 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, 93 { } /* Terminating entry */ 94 }; 95 96 static const struct usb_device_id id_table_cyphidcomrs232[] = { 97 { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, 98 { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, 99 { } /* Terminating entry */ 100 }; 101 102 static const struct usb_device_id id_table_nokiaca42v2[] = { 103 { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, 104 { } /* Terminating entry */ 105 }; 106 107 static const struct usb_device_id id_table_combined[] = { 108 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, 109 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, 110 { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, 111 { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, 112 { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, 113 { } /* Terminating entry */ 114 }; 115 116 MODULE_DEVICE_TABLE(usb, id_table_combined); 117 118 static struct usb_driver cypress_driver = { 119 .name = "cypress", 120 .probe = usb_serial_probe, 121 .disconnect = usb_serial_disconnect, 122 .id_table = id_table_combined, 123 .no_dynamic_id = 1, 124 }; 125 126 enum packet_format { 127 packet_format_1, /* b0:status, b1:payload count */ 128 packet_format_2 /* b0[7:3]:status, b0[2:0]:payload count */ 129 }; 130 131 struct cypress_private { 132 spinlock_t lock; /* private lock */ 133 int chiptype; /* identifier of device, for quirks/etc */ 134 int bytes_in; /* used for statistics */ 135 int bytes_out; /* used for statistics */ 136 int cmd_count; /* used for statistics */ 137 int cmd_ctrl; /* always set this to 1 before issuing a command */ 138 struct kfifo write_fifo; /* write fifo */ 139 int write_urb_in_use; /* write urb in use indicator */ 140 int write_urb_interval; /* interval to use for write urb */ 141 int read_urb_interval; /* interval to use for read urb */ 142 int comm_is_ok; /* true if communication is (still) ok */ 143 int termios_initialized; 144 __u8 line_control; /* holds dtr / rts value */ 145 __u8 current_status; /* received from last read - info on dsr,cts,cd,ri,etc */ 146 __u8 current_config; /* stores the current configuration byte */ 147 __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */ 148 enum packet_format pkt_fmt; /* format to use for packet send / receive */ 149 int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */ 150 int baud_rate; /* stores current baud rate in 151 integer form */ 152 int isthrottled; /* if throttled, discard reads */ 153 wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ 154 char prev_status, diff_status; /* used for TIOCMIWAIT */ 155 /* we pass a pointer to this as the argument sent to 156 cypress_set_termios old_termios */ 157 struct ktermios tmp_termios; /* stores the old termios settings */ 158 }; 159 160 /* function prototypes for the Cypress USB to serial device */ 161 static int cypress_earthmate_startup(struct usb_serial *serial); 162 static int cypress_hidcom_startup(struct usb_serial *serial); 163 static int cypress_ca42v2_startup(struct usb_serial *serial); 164 static void cypress_release(struct usb_serial *serial); 165 static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port); 166 static void cypress_close(struct usb_serial_port *port); 167 static void cypress_dtr_rts(struct usb_serial_port *port, int on); 168 static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, 169 const unsigned char *buf, int count); 170 static void cypress_send(struct usb_serial_port *port); 171 static int cypress_write_room(struct tty_struct *tty); 172 static int cypress_ioctl(struct tty_struct *tty, struct file *file, 173 unsigned int cmd, unsigned long arg); 174 static void cypress_set_termios(struct tty_struct *tty, 175 struct usb_serial_port *port, struct ktermios *old); 176 static int cypress_tiocmget(struct tty_struct *tty, struct file *file); 177 static int cypress_tiocmset(struct tty_struct *tty, struct file *file, 178 unsigned int set, unsigned int clear); 179 static int cypress_chars_in_buffer(struct tty_struct *tty); 180 static void cypress_throttle(struct tty_struct *tty); 181 static void cypress_unthrottle(struct tty_struct *tty); 182 static void cypress_set_dead(struct usb_serial_port *port); 183 static void cypress_read_int_callback(struct urb *urb); 184 static void cypress_write_int_callback(struct urb *urb); 185 186 static struct usb_serial_driver cypress_earthmate_device = { 187 .driver = { 188 .owner = THIS_MODULE, 189 .name = "earthmate", 190 }, 191 .description = "DeLorme Earthmate USB", 192 .usb_driver = &cypress_driver, 193 .id_table = id_table_earthmate, 194 .num_ports = 1, 195 .attach = cypress_earthmate_startup, 196 .release = cypress_release, 197 .open = cypress_open, 198 .close = cypress_close, 199 .dtr_rts = cypress_dtr_rts, 200 .write = cypress_write, 201 .write_room = cypress_write_room, 202 .ioctl = cypress_ioctl, 203 .set_termios = cypress_set_termios, 204 .tiocmget = cypress_tiocmget, 205 .tiocmset = cypress_tiocmset, 206 .chars_in_buffer = cypress_chars_in_buffer, 207 .throttle = cypress_throttle, 208 .unthrottle = cypress_unthrottle, 209 .read_int_callback = cypress_read_int_callback, 210 .write_int_callback = cypress_write_int_callback, 211 }; 212 213 static struct usb_serial_driver cypress_hidcom_device = { 214 .driver = { 215 .owner = THIS_MODULE, 216 .name = "cyphidcom", 217 }, 218 .description = "HID->COM RS232 Adapter", 219 .usb_driver = &cypress_driver, 220 .id_table = id_table_cyphidcomrs232, 221 .num_ports = 1, 222 .attach = cypress_hidcom_startup, 223 .release = cypress_release, 224 .open = cypress_open, 225 .close = cypress_close, 226 .dtr_rts = cypress_dtr_rts, 227 .write = cypress_write, 228 .write_room = cypress_write_room, 229 .ioctl = cypress_ioctl, 230 .set_termios = cypress_set_termios, 231 .tiocmget = cypress_tiocmget, 232 .tiocmset = cypress_tiocmset, 233 .chars_in_buffer = cypress_chars_in_buffer, 234 .throttle = cypress_throttle, 235 .unthrottle = cypress_unthrottle, 236 .read_int_callback = cypress_read_int_callback, 237 .write_int_callback = cypress_write_int_callback, 238 }; 239 240 static struct usb_serial_driver cypress_ca42v2_device = { 241 .driver = { 242 .owner = THIS_MODULE, 243 .name = "nokiaca42v2", 244 }, 245 .description = "Nokia CA-42 V2 Adapter", 246 .usb_driver = &cypress_driver, 247 .id_table = id_table_nokiaca42v2, 248 .num_ports = 1, 249 .attach = cypress_ca42v2_startup, 250 .release = cypress_release, 251 .open = cypress_open, 252 .close = cypress_close, 253 .dtr_rts = cypress_dtr_rts, 254 .write = cypress_write, 255 .write_room = cypress_write_room, 256 .ioctl = cypress_ioctl, 257 .set_termios = cypress_set_termios, 258 .tiocmget = cypress_tiocmget, 259 .tiocmset = cypress_tiocmset, 260 .chars_in_buffer = cypress_chars_in_buffer, 261 .throttle = cypress_throttle, 262 .unthrottle = cypress_unthrottle, 263 .read_int_callback = cypress_read_int_callback, 264 .write_int_callback = cypress_write_int_callback, 265 }; 266 267 /***************************************************************************** 268 * Cypress serial helper functions 269 *****************************************************************************/ 270 271 272 static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) 273 { 274 struct cypress_private *priv; 275 priv = usb_get_serial_port_data(port); 276 277 if (unstable_bauds) 278 return new_rate; 279 280 /* 281 * The general purpose firmware for the Cypress M8 allows for 282 * a maximum speed of 57600bps (I have no idea whether DeLorme 283 * chose to use the general purpose firmware or not), if you 284 * need to modify this speed setting for your own project 285 * please add your own chiptype and modify the code likewise. 286 * The Cypress HID->COM device will work successfully up to 287 * 115200bps (but the actual throughput is around 3kBps). 288 */ 289 if (port->serial->dev->speed == USB_SPEED_LOW) { 290 /* 291 * Mike Isely <isely@pobox.com> 2-Feb-2008: The 292 * Cypress app note that describes this mechanism 293 * states the the low-speed part can't handle more 294 * than 800 bytes/sec, in which case 4800 baud is the 295 * safest speed for a part like that. 296 */ 297 if (new_rate > 4800) { 298 dbg("%s - failed setting baud rate, device incapable " 299 "speed %d", __func__, new_rate); 300 return -1; 301 } 302 } 303 switch (priv->chiptype) { 304 case CT_EARTHMATE: 305 if (new_rate <= 600) { 306 /* 300 and 600 baud rates are supported under 307 * the generic firmware, but are not used with 308 * NMEA and SiRF protocols */ 309 dbg("%s - failed setting baud rate, unsupported speed " 310 "of %d on Earthmate GPS", __func__, new_rate); 311 return -1; 312 } 313 break; 314 default: 315 break; 316 } 317 return new_rate; 318 } 319 320 321 /* This function can either set or retrieve the current serial line settings */ 322 static int cypress_serial_control(struct tty_struct *tty, 323 struct usb_serial_port *port, speed_t baud_rate, int data_bits, 324 int stop_bits, int parity_enable, int parity_type, int reset, 325 int cypress_request_type) 326 { 327 int new_baudrate = 0, retval = 0, tries = 0; 328 struct cypress_private *priv; 329 u8 *feature_buffer; 330 const unsigned int feature_len = 5; 331 unsigned long flags; 332 333 dbg("%s", __func__); 334 335 priv = usb_get_serial_port_data(port); 336 337 if (!priv->comm_is_ok) 338 return -ENODEV; 339 340 feature_buffer = kcalloc(feature_len, sizeof(u8), GFP_KERNEL); 341 if (!feature_buffer) 342 return -ENOMEM; 343 344 switch (cypress_request_type) { 345 case CYPRESS_SET_CONFIG: 346 /* 0 means 'Hang up' so doesn't change the true bit rate */ 347 new_baudrate = priv->baud_rate; 348 if (baud_rate && baud_rate != priv->baud_rate) { 349 dbg("%s - baud rate is changing", __func__); 350 retval = analyze_baud_rate(port, baud_rate); 351 if (retval >= 0) { 352 new_baudrate = retval; 353 dbg("%s - New baud rate set to %d", 354 __func__, new_baudrate); 355 } 356 } 357 dbg("%s - baud rate is being sent as %d", 358 __func__, new_baudrate); 359 360 /* fill the feature_buffer with new configuration */ 361 put_unaligned_le32(new_baudrate, feature_buffer); 362 feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */ 363 /* 1 bit gap */ 364 feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */ 365 feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */ 366 feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */ 367 /* 1 bit gap */ 368 feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */ 369 370 dbg("%s - device is being sent this feature report:", 371 __func__); 372 dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__, 373 feature_buffer[0], feature_buffer[1], 374 feature_buffer[2], feature_buffer[3], 375 feature_buffer[4]); 376 377 do { 378 retval = usb_control_msg(port->serial->dev, 379 usb_sndctrlpipe(port->serial->dev, 0), 380 HID_REQ_SET_REPORT, 381 USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, 382 0x0300, 0, feature_buffer, 383 feature_len, 500); 384 385 if (tries++ >= 3) 386 break; 387 388 } while (retval != feature_len && 389 retval != -ENODEV); 390 391 if (retval != feature_len) { 392 dev_err(&port->dev, "%s - failed sending serial " 393 "line settings - %d\n", __func__, retval); 394 cypress_set_dead(port); 395 } else { 396 spin_lock_irqsave(&priv->lock, flags); 397 priv->baud_rate = new_baudrate; 398 priv->current_config = feature_buffer[4]; 399 spin_unlock_irqrestore(&priv->lock, flags); 400 /* If we asked for a speed change encode it */ 401 if (baud_rate) 402 tty_encode_baud_rate(tty, 403 new_baudrate, new_baudrate); 404 } 405 break; 406 case CYPRESS_GET_CONFIG: 407 if (priv->get_cfg_unsafe) { 408 /* Not implemented for this device, 409 and if we try to do it we're likely 410 to crash the hardware. */ 411 retval = -ENOTTY; 412 goto out; 413 } 414 dbg("%s - retreiving serial line settings", __func__); 415 do { 416 retval = usb_control_msg(port->serial->dev, 417 usb_rcvctrlpipe(port->serial->dev, 0), 418 HID_REQ_GET_REPORT, 419 USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, 420 0x0300, 0, feature_buffer, 421 feature_len, 500); 422 423 if (tries++ >= 3) 424 break; 425 } while (retval != feature_len 426 && retval != -ENODEV); 427 428 if (retval != feature_len) { 429 dev_err(&port->dev, "%s - failed to retrieve serial " 430 "line settings - %d\n", __func__, retval); 431 cypress_set_dead(port); 432 goto out; 433 } else { 434 spin_lock_irqsave(&priv->lock, flags); 435 /* store the config in one byte, and later 436 use bit masks to check values */ 437 priv->current_config = feature_buffer[4]; 438 priv->baud_rate = get_unaligned_le32(feature_buffer); 439 spin_unlock_irqrestore(&priv->lock, flags); 440 } 441 } 442 spin_lock_irqsave(&priv->lock, flags); 443 ++priv->cmd_count; 444 spin_unlock_irqrestore(&priv->lock, flags); 445 out: 446 kfree(feature_buffer); 447 return retval; 448 } /* cypress_serial_control */ 449 450 451 static void cypress_set_dead(struct usb_serial_port *port) 452 { 453 struct cypress_private *priv = usb_get_serial_port_data(port); 454 unsigned long flags; 455 456 spin_lock_irqsave(&priv->lock, flags); 457 if (!priv->comm_is_ok) { 458 spin_unlock_irqrestore(&priv->lock, flags); 459 return; 460 } 461 priv->comm_is_ok = 0; 462 spin_unlock_irqrestore(&priv->lock, flags); 463 464 dev_err(&port->dev, "cypress_m8 suspending failing port %d - " 465 "interval might be too short\n", port->number); 466 } 467 468 469 /***************************************************************************** 470 * Cypress serial driver functions 471 *****************************************************************************/ 472 473 474 static int generic_startup(struct usb_serial *serial) 475 { 476 struct cypress_private *priv; 477 struct usb_serial_port *port = serial->port[0]; 478 479 dbg("%s - port %d", __func__, port->number); 480 481 priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); 482 if (!priv) 483 return -ENOMEM; 484 485 priv->comm_is_ok = !0; 486 spin_lock_init(&priv->lock); 487 if (kfifo_alloc(&priv->write_fifo, CYPRESS_BUF_SIZE, GFP_KERNEL)) { 488 kfree(priv); 489 return -ENOMEM; 490 } 491 init_waitqueue_head(&priv->delta_msr_wait); 492 493 usb_reset_configuration(serial->dev); 494 495 priv->cmd_ctrl = 0; 496 priv->line_control = 0; 497 priv->termios_initialized = 0; 498 priv->rx_flags = 0; 499 /* Default packet format setting is determined by packet size. 500 Anything with a size larger then 9 must have a separate 501 count field since the 3 bit count field is otherwise too 502 small. Otherwise we can use the slightly more compact 503 format. This is in accordance with the cypress_m8 serial 504 converter app note. */ 505 if (port->interrupt_out_size > 9) 506 priv->pkt_fmt = packet_format_1; 507 else 508 priv->pkt_fmt = packet_format_2; 509 510 if (interval > 0) { 511 priv->write_urb_interval = interval; 512 priv->read_urb_interval = interval; 513 dbg("%s - port %d read & write intervals forced to %d", 514 __func__, port->number, interval); 515 } else { 516 priv->write_urb_interval = port->interrupt_out_urb->interval; 517 priv->read_urb_interval = port->interrupt_in_urb->interval; 518 dbg("%s - port %d intervals: read=%d write=%d", 519 __func__, port->number, 520 priv->read_urb_interval, priv->write_urb_interval); 521 } 522 usb_set_serial_port_data(port, priv); 523 524 return 0; 525 } 526 527 528 static int cypress_earthmate_startup(struct usb_serial *serial) 529 { 530 struct cypress_private *priv; 531 struct usb_serial_port *port = serial->port[0]; 532 533 dbg("%s", __func__); 534 535 if (generic_startup(serial)) { 536 dbg("%s - Failed setting up port %d", __func__, 537 port->number); 538 return 1; 539 } 540 541 priv = usb_get_serial_port_data(port); 542 priv->chiptype = CT_EARTHMATE; 543 /* All Earthmate devices use the separated-count packet 544 format! Idiotic. */ 545 priv->pkt_fmt = packet_format_1; 546 if (serial->dev->descriptor.idProduct != 547 cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) { 548 /* The old original USB Earthmate seemed able to 549 handle GET_CONFIG requests; everything they've 550 produced since that time crashes if this command is 551 attempted :-( */ 552 dbg("%s - Marking this device as unsafe for GET_CONFIG " 553 "commands", __func__); 554 priv->get_cfg_unsafe = !0; 555 } 556 557 return 0; 558 } /* cypress_earthmate_startup */ 559 560 561 static int cypress_hidcom_startup(struct usb_serial *serial) 562 { 563 struct cypress_private *priv; 564 565 dbg("%s", __func__); 566 567 if (generic_startup(serial)) { 568 dbg("%s - Failed setting up port %d", __func__, 569 serial->port[0]->number); 570 return 1; 571 } 572 573 priv = usb_get_serial_port_data(serial->port[0]); 574 priv->chiptype = CT_CYPHIDCOM; 575 576 return 0; 577 } /* cypress_hidcom_startup */ 578 579 580 static int cypress_ca42v2_startup(struct usb_serial *serial) 581 { 582 struct cypress_private *priv; 583 584 dbg("%s", __func__); 585 586 if (generic_startup(serial)) { 587 dbg("%s - Failed setting up port %d", __func__, 588 serial->port[0]->number); 589 return 1; 590 } 591 592 priv = usb_get_serial_port_data(serial->port[0]); 593 priv->chiptype = CT_CA42V2; 594 595 return 0; 596 } /* cypress_ca42v2_startup */ 597 598 599 static void cypress_release(struct usb_serial *serial) 600 { 601 struct cypress_private *priv; 602 603 dbg("%s - port %d", __func__, serial->port[0]->number); 604 605 /* all open ports are closed at this point */ 606 607 priv = usb_get_serial_port_data(serial->port[0]); 608 609 if (priv) { 610 kfifo_free(&priv->write_fifo); 611 kfree(priv); 612 } 613 } 614 615 616 static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) 617 { 618 struct cypress_private *priv = usb_get_serial_port_data(port); 619 struct usb_serial *serial = port->serial; 620 unsigned long flags; 621 int result = 0; 622 623 dbg("%s - port %d", __func__, port->number); 624 625 if (!priv->comm_is_ok) 626 return -EIO; 627 628 /* clear halts before open */ 629 usb_clear_halt(serial->dev, 0x81); 630 usb_clear_halt(serial->dev, 0x02); 631 632 spin_lock_irqsave(&priv->lock, flags); 633 /* reset read/write statistics */ 634 priv->bytes_in = 0; 635 priv->bytes_out = 0; 636 priv->cmd_count = 0; 637 priv->rx_flags = 0; 638 spin_unlock_irqrestore(&priv->lock, flags); 639 640 /* Set termios */ 641 cypress_send(port); 642 643 if (tty) 644 cypress_set_termios(tty, port, &priv->tmp_termios); 645 646 /* setup the port and start reading from the device */ 647 if (!port->interrupt_in_urb) { 648 dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n", 649 __func__); 650 return -1; 651 } 652 653 usb_fill_int_urb(port->interrupt_in_urb, serial->dev, 654 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), 655 port->interrupt_in_urb->transfer_buffer, 656 port->interrupt_in_urb->transfer_buffer_length, 657 cypress_read_int_callback, port, priv->read_urb_interval); 658 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 659 660 if (result) { 661 dev_err(&port->dev, 662 "%s - failed submitting read urb, error %d\n", 663 __func__, result); 664 cypress_set_dead(port); 665 } 666 port->port.drain_delay = 256; 667 return result; 668 } /* cypress_open */ 669 670 static void cypress_dtr_rts(struct usb_serial_port *port, int on) 671 { 672 struct cypress_private *priv = usb_get_serial_port_data(port); 673 /* drop dtr and rts */ 674 spin_lock_irq(&priv->lock); 675 if (on == 0) 676 priv->line_control = 0; 677 else 678 priv->line_control = CONTROL_DTR | CONTROL_RTS; 679 priv->cmd_ctrl = 1; 680 spin_unlock_irq(&priv->lock); 681 cypress_write(NULL, port, NULL, 0); 682 } 683 684 static void cypress_close(struct usb_serial_port *port) 685 { 686 struct cypress_private *priv = usb_get_serial_port_data(port); 687 unsigned long flags; 688 689 dbg("%s - port %d", __func__, port->number); 690 691 /* writing is potentially harmful, lock must be taken */ 692 mutex_lock(&port->serial->disc_mutex); 693 if (port->serial->disconnected) { 694 mutex_unlock(&port->serial->disc_mutex); 695 return; 696 } 697 spin_lock_irqsave(&priv->lock, flags); 698 kfifo_reset_out(&priv->write_fifo); 699 spin_unlock_irqrestore(&priv->lock, flags); 700 701 dbg("%s - stopping urbs", __func__); 702 usb_kill_urb(port->interrupt_in_urb); 703 usb_kill_urb(port->interrupt_out_urb); 704 705 if (stats) 706 dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", 707 priv->bytes_in, priv->bytes_out, priv->cmd_count); 708 mutex_unlock(&port->serial->disc_mutex); 709 } /* cypress_close */ 710 711 712 static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, 713 const unsigned char *buf, int count) 714 { 715 struct cypress_private *priv = usb_get_serial_port_data(port); 716 717 dbg("%s - port %d, %d bytes", __func__, port->number, count); 718 719 /* line control commands, which need to be executed immediately, 720 are not put into the buffer for obvious reasons. 721 */ 722 if (priv->cmd_ctrl) { 723 count = 0; 724 goto finish; 725 } 726 727 if (!count) 728 return count; 729 730 count = kfifo_in_locked(&priv->write_fifo, buf, count, &priv->lock); 731 732 finish: 733 cypress_send(port); 734 735 return count; 736 } /* cypress_write */ 737 738 739 static void cypress_send(struct usb_serial_port *port) 740 { 741 int count = 0, result, offset, actual_size; 742 struct cypress_private *priv = usb_get_serial_port_data(port); 743 unsigned long flags; 744 745 if (!priv->comm_is_ok) 746 return; 747 748 dbg("%s - port %d", __func__, port->number); 749 dbg("%s - interrupt out size is %d", __func__, 750 port->interrupt_out_size); 751 752 spin_lock_irqsave(&priv->lock, flags); 753 if (priv->write_urb_in_use) { 754 dbg("%s - can't write, urb in use", __func__); 755 spin_unlock_irqrestore(&priv->lock, flags); 756 return; 757 } 758 spin_unlock_irqrestore(&priv->lock, flags); 759 760 /* clear buffer */ 761 memset(port->interrupt_out_urb->transfer_buffer, 0, 762 port->interrupt_out_size); 763 764 spin_lock_irqsave(&priv->lock, flags); 765 switch (priv->pkt_fmt) { 766 default: 767 case packet_format_1: 768 /* this is for the CY7C64013... */ 769 offset = 2; 770 port->interrupt_out_buffer[0] = priv->line_control; 771 break; 772 case packet_format_2: 773 /* this is for the CY7C63743... */ 774 offset = 1; 775 port->interrupt_out_buffer[0] = priv->line_control; 776 break; 777 } 778 779 if (priv->line_control & CONTROL_RESET) 780 priv->line_control &= ~CONTROL_RESET; 781 782 if (priv->cmd_ctrl) { 783 priv->cmd_count++; 784 dbg("%s - line control command being issued", __func__); 785 spin_unlock_irqrestore(&priv->lock, flags); 786 goto send; 787 } else 788 spin_unlock_irqrestore(&priv->lock, flags); 789 790 count = kfifo_out_locked(&priv->write_fifo, 791 &port->interrupt_out_buffer[offset], 792 port->interrupt_out_size - offset, 793 &priv->lock); 794 if (count == 0) 795 return; 796 797 switch (priv->pkt_fmt) { 798 default: 799 case packet_format_1: 800 port->interrupt_out_buffer[1] = count; 801 break; 802 case packet_format_2: 803 port->interrupt_out_buffer[0] |= count; 804 } 805 806 dbg("%s - count is %d", __func__, count); 807 808 send: 809 spin_lock_irqsave(&priv->lock, flags); 810 priv->write_urb_in_use = 1; 811 spin_unlock_irqrestore(&priv->lock, flags); 812 813 if (priv->cmd_ctrl) 814 actual_size = 1; 815 else 816 actual_size = count + 817 (priv->pkt_fmt == packet_format_1 ? 2 : 1); 818 819 usb_serial_debug_data(debug, &port->dev, __func__, 820 port->interrupt_out_size, 821 port->interrupt_out_urb->transfer_buffer); 822 823 usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev, 824 usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress), 825 port->interrupt_out_buffer, port->interrupt_out_size, 826 cypress_write_int_callback, port, priv->write_urb_interval); 827 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); 828 if (result) { 829 dev_err(&port->dev, 830 "%s - failed submitting write urb, error %d\n", 831 __func__, result); 832 priv->write_urb_in_use = 0; 833 cypress_set_dead(port); 834 } 835 836 spin_lock_irqsave(&priv->lock, flags); 837 if (priv->cmd_ctrl) 838 priv->cmd_ctrl = 0; 839 840 /* do not count the line control and size bytes */ 841 priv->bytes_out += count; 842 spin_unlock_irqrestore(&priv->lock, flags); 843 844 usb_serial_port_softint(port); 845 } /* cypress_send */ 846 847 848 /* returns how much space is available in the soft buffer */ 849 static int cypress_write_room(struct tty_struct *tty) 850 { 851 struct usb_serial_port *port = tty->driver_data; 852 struct cypress_private *priv = usb_get_serial_port_data(port); 853 int room = 0; 854 unsigned long flags; 855 856 dbg("%s - port %d", __func__, port->number); 857 858 spin_lock_irqsave(&priv->lock, flags); 859 room = kfifo_avail(&priv->write_fifo); 860 spin_unlock_irqrestore(&priv->lock, flags); 861 862 dbg("%s - returns %d", __func__, room); 863 return room; 864 } 865 866 867 static int cypress_tiocmget(struct tty_struct *tty, struct file *file) 868 { 869 struct usb_serial_port *port = tty->driver_data; 870 struct cypress_private *priv = usb_get_serial_port_data(port); 871 __u8 status, control; 872 unsigned int result = 0; 873 unsigned long flags; 874 875 dbg("%s - port %d", __func__, port->number); 876 877 spin_lock_irqsave(&priv->lock, flags); 878 control = priv->line_control; 879 status = priv->current_status; 880 spin_unlock_irqrestore(&priv->lock, flags); 881 882 result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) 883 | ((control & CONTROL_RTS) ? TIOCM_RTS : 0) 884 | ((status & UART_CTS) ? TIOCM_CTS : 0) 885 | ((status & UART_DSR) ? TIOCM_DSR : 0) 886 | ((status & UART_RI) ? TIOCM_RI : 0) 887 | ((status & UART_CD) ? TIOCM_CD : 0); 888 889 dbg("%s - result = %x", __func__, result); 890 891 return result; 892 } 893 894 895 static int cypress_tiocmset(struct tty_struct *tty, struct file *file, 896 unsigned int set, unsigned int clear) 897 { 898 struct usb_serial_port *port = tty->driver_data; 899 struct cypress_private *priv = usb_get_serial_port_data(port); 900 unsigned long flags; 901 902 dbg("%s - port %d", __func__, port->number); 903 904 spin_lock_irqsave(&priv->lock, flags); 905 if (set & TIOCM_RTS) 906 priv->line_control |= CONTROL_RTS; 907 if (set & TIOCM_DTR) 908 priv->line_control |= CONTROL_DTR; 909 if (clear & TIOCM_RTS) 910 priv->line_control &= ~CONTROL_RTS; 911 if (clear & TIOCM_DTR) 912 priv->line_control &= ~CONTROL_DTR; 913 priv->cmd_ctrl = 1; 914 spin_unlock_irqrestore(&priv->lock, flags); 915 916 return cypress_write(tty, port, NULL, 0); 917 } 918 919 920 static int cypress_ioctl(struct tty_struct *tty, struct file *file, 921 unsigned int cmd, unsigned long arg) 922 { 923 struct usb_serial_port *port = tty->driver_data; 924 struct cypress_private *priv = usb_get_serial_port_data(port); 925 926 dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); 927 928 switch (cmd) { 929 /* This code comes from drivers/char/serial.c and ftdi_sio.c */ 930 case TIOCMIWAIT: 931 while (priv != NULL) { 932 interruptible_sleep_on(&priv->delta_msr_wait); 933 /* see if a signal did it */ 934 if (signal_pending(current)) 935 return -ERESTARTSYS; 936 else { 937 char diff = priv->diff_status; 938 if (diff == 0) 939 return -EIO; /* no change => error */ 940 941 /* consume all events */ 942 priv->diff_status = 0; 943 944 /* return 0 if caller wanted to know about 945 these bits */ 946 if (((arg & TIOCM_RNG) && (diff & UART_RI)) || 947 ((arg & TIOCM_DSR) && (diff & UART_DSR)) || 948 ((arg & TIOCM_CD) && (diff & UART_CD)) || 949 ((arg & TIOCM_CTS) && (diff & UART_CTS))) 950 return 0; 951 /* otherwise caller can't care less about what 952 * happened, and so we continue to wait for 953 * more events. 954 */ 955 } 956 } 957 return 0; 958 default: 959 break; 960 } 961 dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd); 962 return -ENOIOCTLCMD; 963 } /* cypress_ioctl */ 964 965 966 static void cypress_set_termios(struct tty_struct *tty, 967 struct usb_serial_port *port, struct ktermios *old_termios) 968 { 969 struct cypress_private *priv = usb_get_serial_port_data(port); 970 int data_bits, stop_bits, parity_type, parity_enable; 971 unsigned cflag, iflag; 972 unsigned long flags; 973 __u8 oldlines; 974 int linechange = 0; 975 976 dbg("%s - port %d", __func__, port->number); 977 978 spin_lock_irqsave(&priv->lock, flags); 979 /* We can't clean this one up as we don't know the device type 980 early enough */ 981 if (!priv->termios_initialized) { 982 if (priv->chiptype == CT_EARTHMATE) { 983 *(tty->termios) = tty_std_termios; 984 tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | 985 CLOCAL; 986 tty->termios->c_ispeed = 4800; 987 tty->termios->c_ospeed = 4800; 988 } else if (priv->chiptype == CT_CYPHIDCOM) { 989 *(tty->termios) = tty_std_termios; 990 tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | 991 CLOCAL; 992 tty->termios->c_ispeed = 9600; 993 tty->termios->c_ospeed = 9600; 994 } else if (priv->chiptype == CT_CA42V2) { 995 *(tty->termios) = tty_std_termios; 996 tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | 997 CLOCAL; 998 tty->termios->c_ispeed = 9600; 999 tty->termios->c_ospeed = 9600; 1000 } 1001 priv->termios_initialized = 1; 1002 } 1003 spin_unlock_irqrestore(&priv->lock, flags); 1004 1005 /* Unsupported features need clearing */ 1006 tty->termios->c_cflag &= ~(CMSPAR|CRTSCTS); 1007 1008 cflag = tty->termios->c_cflag; 1009 iflag = tty->termios->c_iflag; 1010 1011 /* check if there are new settings */ 1012 if (old_termios) { 1013 spin_lock_irqsave(&priv->lock, flags); 1014 priv->tmp_termios = *(tty->termios); 1015 spin_unlock_irqrestore(&priv->lock, flags); 1016 } 1017 1018 /* set number of data bits, parity, stop bits */ 1019 /* when parity is disabled the parity type bit is ignored */ 1020 1021 /* 1 means 2 stop bits, 0 means 1 stop bit */ 1022 stop_bits = cflag & CSTOPB ? 1 : 0; 1023 1024 if (cflag & PARENB) { 1025 parity_enable = 1; 1026 /* 1 means odd parity, 0 means even parity */ 1027 parity_type = cflag & PARODD ? 1 : 0; 1028 } else 1029 parity_enable = parity_type = 0; 1030 1031 switch (cflag & CSIZE) { 1032 case CS5: 1033 data_bits = 0; 1034 break; 1035 case CS6: 1036 data_bits = 1; 1037 break; 1038 case CS7: 1039 data_bits = 2; 1040 break; 1041 case CS8: 1042 data_bits = 3; 1043 break; 1044 default: 1045 dev_err(&port->dev, "%s - CSIZE was set, but not CS5-CS8\n", 1046 __func__); 1047 data_bits = 3; 1048 } 1049 spin_lock_irqsave(&priv->lock, flags); 1050 oldlines = priv->line_control; 1051 if ((cflag & CBAUD) == B0) { 1052 /* drop dtr and rts */ 1053 dbg("%s - dropping the lines, baud rate 0bps", __func__); 1054 priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); 1055 } else 1056 priv->line_control = (CONTROL_DTR | CONTROL_RTS); 1057 spin_unlock_irqrestore(&priv->lock, flags); 1058 1059 dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, " 1060 "%d data_bits (+5)", __func__, stop_bits, 1061 parity_enable, parity_type, data_bits); 1062 1063 cypress_serial_control(tty, port, tty_get_baud_rate(tty), 1064 data_bits, stop_bits, 1065 parity_enable, parity_type, 1066 0, CYPRESS_SET_CONFIG); 1067 1068 /* we perform a CYPRESS_GET_CONFIG so that the current settings are 1069 * filled into the private structure this should confirm that all is 1070 * working if it returns what we just set */ 1071 cypress_serial_control(tty, port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG); 1072 1073 /* Here we can define custom tty settings for devices; the main tty 1074 * termios flag base comes from empeg.c */ 1075 1076 spin_lock_irqsave(&priv->lock, flags); 1077 if (priv->chiptype == CT_EARTHMATE && priv->baud_rate == 4800) { 1078 dbg("Using custom termios settings for a baud rate of " 1079 "4800bps."); 1080 /* define custom termios settings for NMEA protocol */ 1081 1082 tty->termios->c_iflag /* input modes - */ 1083 &= ~(IGNBRK /* disable ignore break */ 1084 | BRKINT /* disable break causes interrupt */ 1085 | PARMRK /* disable mark parity errors */ 1086 | ISTRIP /* disable clear high bit of input char */ 1087 | INLCR /* disable translate NL to CR */ 1088 | IGNCR /* disable ignore CR */ 1089 | ICRNL /* disable translate CR to NL */ 1090 | IXON); /* disable enable XON/XOFF flow control */ 1091 1092 tty->termios->c_oflag /* output modes */ 1093 &= ~OPOST; /* disable postprocess output char */ 1094 1095 tty->termios->c_lflag /* line discipline modes */ 1096 &= ~(ECHO /* disable echo input characters */ 1097 | ECHONL /* disable echo new line */ 1098 | ICANON /* disable erase, kill, werase, and rprnt 1099 special characters */ 1100 | ISIG /* disable interrupt, quit, and suspend 1101 special characters */ 1102 | IEXTEN); /* disable non-POSIX special characters */ 1103 } /* CT_CYPHIDCOM: Application should handle this for device */ 1104 1105 linechange = (priv->line_control != oldlines); 1106 spin_unlock_irqrestore(&priv->lock, flags); 1107 1108 /* if necessary, set lines */ 1109 if (linechange) { 1110 priv->cmd_ctrl = 1; 1111 cypress_write(tty, port, NULL, 0); 1112 } 1113 } /* cypress_set_termios */ 1114 1115 1116 /* returns amount of data still left in soft buffer */ 1117 static int cypress_chars_in_buffer(struct tty_struct *tty) 1118 { 1119 struct usb_serial_port *port = tty->driver_data; 1120 struct cypress_private *priv = usb_get_serial_port_data(port); 1121 int chars = 0; 1122 unsigned long flags; 1123 1124 dbg("%s - port %d", __func__, port->number); 1125 1126 spin_lock_irqsave(&priv->lock, flags); 1127 chars = kfifo_len(&priv->write_fifo); 1128 spin_unlock_irqrestore(&priv->lock, flags); 1129 1130 dbg("%s - returns %d", __func__, chars); 1131 return chars; 1132 } 1133 1134 1135 static void cypress_throttle(struct tty_struct *tty) 1136 { 1137 struct usb_serial_port *port = tty->driver_data; 1138 struct cypress_private *priv = usb_get_serial_port_data(port); 1139 1140 dbg("%s - port %d", __func__, port->number); 1141 1142 spin_lock_irq(&priv->lock); 1143 priv->rx_flags = THROTTLED; 1144 spin_unlock_irq(&priv->lock); 1145 } 1146 1147 1148 static void cypress_unthrottle(struct tty_struct *tty) 1149 { 1150 struct usb_serial_port *port = tty->driver_data; 1151 struct cypress_private *priv = usb_get_serial_port_data(port); 1152 int actually_throttled, result; 1153 1154 dbg("%s - port %d", __func__, port->number); 1155 1156 spin_lock_irq(&priv->lock); 1157 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; 1158 priv->rx_flags = 0; 1159 spin_unlock_irq(&priv->lock); 1160 1161 if (!priv->comm_is_ok) 1162 return; 1163 1164 if (actually_throttled) { 1165 port->interrupt_in_urb->dev = port->serial->dev; 1166 1167 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 1168 if (result) { 1169 dev_err(&port->dev, "%s - failed submitting read urb, " 1170 "error %d\n", __func__, result); 1171 cypress_set_dead(port); 1172 } 1173 } 1174 } 1175 1176 1177 static void cypress_read_int_callback(struct urb *urb) 1178 { 1179 struct usb_serial_port *port = urb->context; 1180 struct cypress_private *priv = usb_get_serial_port_data(port); 1181 struct tty_struct *tty; 1182 unsigned char *data = urb->transfer_buffer; 1183 unsigned long flags; 1184 char tty_flag = TTY_NORMAL; 1185 int havedata = 0; 1186 int bytes = 0; 1187 int result; 1188 int i = 0; 1189 int status = urb->status; 1190 1191 dbg("%s - port %d", __func__, port->number); 1192 1193 switch (status) { 1194 case 0: /* success */ 1195 break; 1196 case -ECONNRESET: 1197 case -ENOENT: 1198 case -ESHUTDOWN: 1199 /* precursor to disconnect so just go away */ 1200 return; 1201 case -EPIPE: 1202 /* Can't call usb_clear_halt while in_interrupt */ 1203 /* FALLS THROUGH */ 1204 default: 1205 /* something ugly is going on... */ 1206 dev_err(&urb->dev->dev, 1207 "%s - unexpected nonzero read status received: %d\n", 1208 __func__, status); 1209 cypress_set_dead(port); 1210 return; 1211 } 1212 1213 spin_lock_irqsave(&priv->lock, flags); 1214 if (priv->rx_flags & THROTTLED) { 1215 dbg("%s - now throttling", __func__); 1216 priv->rx_flags |= ACTUALLY_THROTTLED; 1217 spin_unlock_irqrestore(&priv->lock, flags); 1218 return; 1219 } 1220 spin_unlock_irqrestore(&priv->lock, flags); 1221 1222 tty = tty_port_tty_get(&port->port); 1223 if (!tty) { 1224 dbg("%s - bad tty pointer - exiting", __func__); 1225 return; 1226 } 1227 1228 spin_lock_irqsave(&priv->lock, flags); 1229 result = urb->actual_length; 1230 switch (priv->pkt_fmt) { 1231 default: 1232 case packet_format_1: 1233 /* This is for the CY7C64013... */ 1234 priv->current_status = data[0] & 0xF8; 1235 bytes = data[1] + 2; 1236 i = 2; 1237 if (bytes > 2) 1238 havedata = 1; 1239 break; 1240 case packet_format_2: 1241 /* This is for the CY7C63743... */ 1242 priv->current_status = data[0] & 0xF8; 1243 bytes = (data[0] & 0x07) + 1; 1244 i = 1; 1245 if (bytes > 1) 1246 havedata = 1; 1247 break; 1248 } 1249 spin_unlock_irqrestore(&priv->lock, flags); 1250 if (result < bytes) { 1251 dbg("%s - wrong packet size - received %d bytes but packet " 1252 "said %d bytes", __func__, result, bytes); 1253 goto continue_read; 1254 } 1255 1256 usb_serial_debug_data(debug, &port->dev, __func__, 1257 urb->actual_length, data); 1258 1259 spin_lock_irqsave(&priv->lock, flags); 1260 /* check to see if status has changed */ 1261 if (priv->current_status != priv->prev_status) { 1262 priv->diff_status |= priv->current_status ^ 1263 priv->prev_status; 1264 wake_up_interruptible(&priv->delta_msr_wait); 1265 priv->prev_status = priv->current_status; 1266 } 1267 spin_unlock_irqrestore(&priv->lock, flags); 1268 1269 /* hangup, as defined in acm.c... this might be a bad place for it 1270 * though */ 1271 if (tty && !(tty->termios->c_cflag & CLOCAL) && 1272 !(priv->current_status & UART_CD)) { 1273 dbg("%s - calling hangup", __func__); 1274 tty_hangup(tty); 1275 goto continue_read; 1276 } 1277 1278 /* There is one error bit... I'm assuming it is a parity error 1279 * indicator as the generic firmware will set this bit to 1 if a 1280 * parity error occurs. 1281 * I can not find reference to any other error events. */ 1282 spin_lock_irqsave(&priv->lock, flags); 1283 if (priv->current_status & CYP_ERROR) { 1284 spin_unlock_irqrestore(&priv->lock, flags); 1285 tty_flag = TTY_PARITY; 1286 dbg("%s - Parity Error detected", __func__); 1287 } else 1288 spin_unlock_irqrestore(&priv->lock, flags); 1289 1290 /* process read if there is data other than line status */ 1291 if (tty && bytes > i) { 1292 tty_insert_flip_string_fixed_flag(tty, data + i, 1293 tty_flag, bytes - i); 1294 tty_flip_buffer_push(tty); 1295 } 1296 1297 spin_lock_irqsave(&priv->lock, flags); 1298 /* control and status byte(s) are also counted */ 1299 priv->bytes_in += bytes; 1300 spin_unlock_irqrestore(&priv->lock, flags); 1301 1302 continue_read: 1303 tty_kref_put(tty); 1304 1305 /* Continue trying to always read */ 1306 1307 if (priv->comm_is_ok) { 1308 usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, 1309 usb_rcvintpipe(port->serial->dev, 1310 port->interrupt_in_endpointAddress), 1311 port->interrupt_in_urb->transfer_buffer, 1312 port->interrupt_in_urb->transfer_buffer_length, 1313 cypress_read_int_callback, port, 1314 priv->read_urb_interval); 1315 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1316 if (result && result != -EPERM) { 1317 dev_err(&urb->dev->dev, "%s - failed resubmitting " 1318 "read urb, error %d\n", __func__, 1319 result); 1320 cypress_set_dead(port); 1321 } 1322 } 1323 } /* cypress_read_int_callback */ 1324 1325 1326 static void cypress_write_int_callback(struct urb *urb) 1327 { 1328 struct usb_serial_port *port = urb->context; 1329 struct cypress_private *priv = usb_get_serial_port_data(port); 1330 int result; 1331 int status = urb->status; 1332 1333 dbg("%s - port %d", __func__, port->number); 1334 1335 switch (status) { 1336 case 0: 1337 /* success */ 1338 break; 1339 case -ECONNRESET: 1340 case -ENOENT: 1341 case -ESHUTDOWN: 1342 /* this urb is terminated, clean up */ 1343 dbg("%s - urb shutting down with status: %d", 1344 __func__, status); 1345 priv->write_urb_in_use = 0; 1346 return; 1347 case -EPIPE: /* no break needed; clear halt and resubmit */ 1348 if (!priv->comm_is_ok) 1349 break; 1350 usb_clear_halt(port->serial->dev, 0x02); 1351 /* error in the urb, so we have to resubmit it */ 1352 dbg("%s - nonzero write bulk status received: %d", 1353 __func__, status); 1354 port->interrupt_out_urb->transfer_buffer_length = 1; 1355 port->interrupt_out_urb->dev = port->serial->dev; 1356 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); 1357 if (!result) 1358 return; 1359 dev_err(&urb->dev->dev, 1360 "%s - failed resubmitting write urb, error %d\n", 1361 __func__, result); 1362 cypress_set_dead(port); 1363 break; 1364 default: 1365 dev_err(&urb->dev->dev, 1366 "%s - unexpected nonzero write status received: %d\n", 1367 __func__, status); 1368 cypress_set_dead(port); 1369 break; 1370 } 1371 priv->write_urb_in_use = 0; 1372 1373 /* send any buffered data */ 1374 cypress_send(port); 1375 } 1376 1377 1378 /***************************************************************************** 1379 * Module functions 1380 *****************************************************************************/ 1381 1382 static int __init cypress_init(void) 1383 { 1384 int retval; 1385 1386 dbg("%s", __func__); 1387 1388 retval = usb_serial_register(&cypress_earthmate_device); 1389 if (retval) 1390 goto failed_em_register; 1391 retval = usb_serial_register(&cypress_hidcom_device); 1392 if (retval) 1393 goto failed_hidcom_register; 1394 retval = usb_serial_register(&cypress_ca42v2_device); 1395 if (retval) 1396 goto failed_ca42v2_register; 1397 retval = usb_register(&cypress_driver); 1398 if (retval) 1399 goto failed_usb_register; 1400 1401 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" 1402 DRIVER_DESC "\n"); 1403 return 0; 1404 1405 failed_usb_register: 1406 usb_serial_deregister(&cypress_ca42v2_device); 1407 failed_ca42v2_register: 1408 usb_serial_deregister(&cypress_hidcom_device); 1409 failed_hidcom_register: 1410 usb_serial_deregister(&cypress_earthmate_device); 1411 failed_em_register: 1412 return retval; 1413 } 1414 1415 1416 static void __exit cypress_exit(void) 1417 { 1418 dbg("%s", __func__); 1419 1420 usb_deregister(&cypress_driver); 1421 usb_serial_deregister(&cypress_earthmate_device); 1422 usb_serial_deregister(&cypress_hidcom_device); 1423 usb_serial_deregister(&cypress_ca42v2_device); 1424 } 1425 1426 1427 module_init(cypress_init); 1428 module_exit(cypress_exit); 1429 1430 MODULE_AUTHOR(DRIVER_AUTHOR); 1431 MODULE_DESCRIPTION(DRIVER_DESC); 1432 MODULE_VERSION(DRIVER_VERSION); 1433 MODULE_LICENSE("GPL"); 1434 1435 module_param(debug, bool, S_IRUGO | S_IWUSR); 1436 MODULE_PARM_DESC(debug, "Debug enabled or not"); 1437 module_param(stats, bool, S_IRUGO | S_IWUSR); 1438 MODULE_PARM_DESC(stats, "Enable statistics or not"); 1439 module_param(interval, int, S_IRUGO | S_IWUSR); 1440 MODULE_PARM_DESC(interval, "Overrides interrupt interval"); 1441 module_param(unstable_bauds, bool, S_IRUGO | S_IWUSR); 1442 MODULE_PARM_DESC(unstable_bauds, "Allow unstable baud rates"); 1443