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