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 int bps; 686 long timeout; 687 wait_queue_t wait; 688 689 dbg("%s - port %d", __FUNCTION__, port->number); 690 691 /* wait for data to drain from buffer */ 692 spin_lock_irq(&priv->lock); 693 timeout = CYPRESS_CLOSING_WAIT; 694 init_waitqueue_entry(&wait, current); 695 add_wait_queue(&port->tty->write_wait, &wait); 696 for (;;) { 697 set_current_state(TASK_INTERRUPTIBLE); 698 if (cypress_buf_data_avail(priv->buf) == 0 699 || timeout == 0 || signal_pending(current) 700 /* without mutex, allowed due to harmless failure mode */ 701 || port->serial->disconnected) 702 break; 703 spin_unlock_irq(&priv->lock); 704 timeout = schedule_timeout(timeout); 705 spin_lock_irq(&priv->lock); 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_irq(&priv->lock); 712 713 /* writing is potentially harmful, lock must be taken */ 714 mutex_lock(&port->serial->disc_mutex); 715 if (port->serial->disconnected) { 716 mutex_unlock(&port->serial->disc_mutex); 717 return; 718 } 719 /* wait for characters to drain from device */ 720 bps = tty_get_baud_rate(port->tty); 721 if (bps > 1200) 722 timeout = max((HZ*2560)/bps,HZ/10); 723 else 724 timeout = 2*HZ; 725 schedule_timeout_interruptible(timeout); 726 727 dbg("%s - stopping urbs", __FUNCTION__); 728 usb_kill_urb (port->interrupt_in_urb); 729 usb_kill_urb (port->interrupt_out_urb); 730 731 if (port->tty) { 732 c_cflag = port->tty->termios->c_cflag; 733 if (c_cflag & HUPCL) { 734 /* drop dtr and rts */ 735 priv = usb_get_serial_port_data(port); 736 spin_lock_irq(&priv->lock); 737 priv->line_control = 0; 738 priv->cmd_ctrl = 1; 739 spin_unlock_irq(&priv->lock); 740 cypress_write(port, NULL, 0); 741 } 742 } 743 744 if (stats) 745 dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", 746 priv->bytes_in, priv->bytes_out, priv->cmd_count); 747 mutex_unlock(&port->serial->disc_mutex); 748 } /* cypress_close */ 749 750 751 static int cypress_write(struct usb_serial_port *port, const unsigned char *buf, int count) 752 { 753 struct cypress_private *priv = usb_get_serial_port_data(port); 754 unsigned long flags; 755 756 dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count); 757 758 /* line control commands, which need to be executed immediately, 759 are not put into the buffer for obvious reasons. 760 */ 761 if (priv->cmd_ctrl) { 762 count = 0; 763 goto finish; 764 } 765 766 if (!count) 767 return count; 768 769 spin_lock_irqsave(&priv->lock, flags); 770 count = cypress_buf_put(priv->buf, buf, count); 771 spin_unlock_irqrestore(&priv->lock, flags); 772 773 finish: 774 cypress_send(port); 775 776 return count; 777 } /* cypress_write */ 778 779 780 static void cypress_send(struct usb_serial_port *port) 781 { 782 int count = 0, result, offset, actual_size; 783 struct cypress_private *priv = usb_get_serial_port_data(port); 784 unsigned long flags; 785 786 if (!priv->comm_is_ok) 787 return; 788 789 dbg("%s - port %d", __FUNCTION__, port->number); 790 dbg("%s - interrupt out size is %d", __FUNCTION__, port->interrupt_out_size); 791 792 spin_lock_irqsave(&priv->lock, flags); 793 if (priv->write_urb_in_use) { 794 dbg("%s - can't write, urb in use", __FUNCTION__); 795 spin_unlock_irqrestore(&priv->lock, flags); 796 return; 797 } 798 spin_unlock_irqrestore(&priv->lock, flags); 799 800 /* clear buffer */ 801 memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size); 802 803 spin_lock_irqsave(&priv->lock, flags); 804 switch (port->interrupt_out_size) { 805 case 32: 806 /* this is for the CY7C64013... */ 807 offset = 2; 808 port->interrupt_out_buffer[0] = priv->line_control; 809 break; 810 case 8: 811 /* this is for the CY7C63743... */ 812 offset = 1; 813 port->interrupt_out_buffer[0] = priv->line_control; 814 break; 815 default: 816 dbg("%s - wrong packet size", __FUNCTION__); 817 spin_unlock_irqrestore(&priv->lock, flags); 818 return; 819 } 820 821 if (priv->line_control & CONTROL_RESET) 822 priv->line_control &= ~CONTROL_RESET; 823 824 if (priv->cmd_ctrl) { 825 priv->cmd_count++; 826 dbg("%s - line control command being issued", __FUNCTION__); 827 spin_unlock_irqrestore(&priv->lock, flags); 828 goto send; 829 } else 830 spin_unlock_irqrestore(&priv->lock, flags); 831 832 count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset], 833 port->interrupt_out_size-offset); 834 835 if (count == 0) { 836 return; 837 } 838 839 switch (port->interrupt_out_size) { 840 case 32: 841 port->interrupt_out_buffer[1] = count; 842 break; 843 case 8: 844 port->interrupt_out_buffer[0] |= count; 845 } 846 847 dbg("%s - count is %d", __FUNCTION__, count); 848 849 send: 850 spin_lock_irqsave(&priv->lock, flags); 851 priv->write_urb_in_use = 1; 852 spin_unlock_irqrestore(&priv->lock, flags); 853 854 if (priv->cmd_ctrl) 855 actual_size = 1; 856 else 857 actual_size = count + (port->interrupt_out_size == 32 ? 2 : 1); 858 859 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, port->interrupt_out_size, 860 port->interrupt_out_urb->transfer_buffer); 861 862 usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev, 863 usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress), 864 port->interrupt_out_buffer, port->interrupt_out_size, 865 cypress_write_int_callback, port, priv->write_urb_interval); 866 result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC); 867 if (result) { 868 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, 869 result); 870 priv->write_urb_in_use = 0; 871 cypress_set_dead(port); 872 } 873 874 spin_lock_irqsave(&priv->lock, flags); 875 if (priv->cmd_ctrl) { 876 priv->cmd_ctrl = 0; 877 } 878 priv->bytes_out += count; /* do not count the line control and size bytes */ 879 spin_unlock_irqrestore(&priv->lock, flags); 880 881 usb_serial_port_softint(port); 882 } /* cypress_send */ 883 884 885 /* returns how much space is available in the soft buffer */ 886 static int cypress_write_room(struct usb_serial_port *port) 887 { 888 struct cypress_private *priv = usb_get_serial_port_data(port); 889 int room = 0; 890 unsigned long flags; 891 892 dbg("%s - port %d", __FUNCTION__, port->number); 893 894 spin_lock_irqsave(&priv->lock, flags); 895 room = cypress_buf_space_avail(priv->buf); 896 spin_unlock_irqrestore(&priv->lock, flags); 897 898 dbg("%s - returns %d", __FUNCTION__, room); 899 return room; 900 } 901 902 903 static int cypress_tiocmget (struct usb_serial_port *port, struct file *file) 904 { 905 struct cypress_private *priv = usb_get_serial_port_data(port); 906 __u8 status, control; 907 unsigned int result = 0; 908 unsigned long flags; 909 910 dbg("%s - port %d", __FUNCTION__, port->number); 911 912 spin_lock_irqsave(&priv->lock, flags); 913 control = priv->line_control; 914 status = priv->current_status; 915 spin_unlock_irqrestore(&priv->lock, flags); 916 917 result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) 918 | ((control & CONTROL_RTS) ? TIOCM_RTS : 0) 919 | ((status & UART_CTS) ? TIOCM_CTS : 0) 920 | ((status & UART_DSR) ? TIOCM_DSR : 0) 921 | ((status & UART_RI) ? TIOCM_RI : 0) 922 | ((status & UART_CD) ? TIOCM_CD : 0); 923 924 dbg("%s - result = %x", __FUNCTION__, result); 925 926 return result; 927 } 928 929 930 static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, 931 unsigned int set, unsigned int clear) 932 { 933 struct cypress_private *priv = usb_get_serial_port_data(port); 934 unsigned long flags; 935 936 dbg("%s - port %d", __FUNCTION__, port->number); 937 938 spin_lock_irqsave(&priv->lock, flags); 939 if (set & TIOCM_RTS) 940 priv->line_control |= CONTROL_RTS; 941 if (set & TIOCM_DTR) 942 priv->line_control |= CONTROL_DTR; 943 if (clear & TIOCM_RTS) 944 priv->line_control &= ~CONTROL_RTS; 945 if (clear & TIOCM_DTR) 946 priv->line_control &= ~CONTROL_DTR; 947 spin_unlock_irqrestore(&priv->lock, flags); 948 949 priv->cmd_ctrl = 1; 950 return cypress_write(port, NULL, 0); 951 } 952 953 954 static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) 955 { 956 struct cypress_private *priv = usb_get_serial_port_data(port); 957 958 dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); 959 960 switch (cmd) { 961 case TIOCGSERIAL: 962 if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct ktermios))) { 963 return -EFAULT; 964 } 965 return (0); 966 break; 967 case TIOCSSERIAL: 968 if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct ktermios))) { 969 return -EFAULT; 970 } 971 /* here we need to call cypress_set_termios to invoke the new settings */ 972 cypress_set_termios(port, &priv->tmp_termios); 973 return (0); 974 break; 975 /* This code comes from drivers/char/serial.c and ftdi_sio.c */ 976 case TIOCMIWAIT: 977 while (priv != NULL) { 978 interruptible_sleep_on(&priv->delta_msr_wait); 979 /* see if a signal did it */ 980 if (signal_pending(current)) 981 return -ERESTARTSYS; 982 else { 983 char diff = priv->diff_status; 984 985 if (diff == 0) { 986 return -EIO; /* no change => error */ 987 } 988 989 /* consume all events */ 990 priv->diff_status = 0; 991 992 /* return 0 if caller wanted to know about these bits */ 993 if ( ((arg & TIOCM_RNG) && (diff & UART_RI)) || 994 ((arg & TIOCM_DSR) && (diff & UART_DSR)) || 995 ((arg & TIOCM_CD) && (diff & UART_CD)) || 996 ((arg & TIOCM_CTS) && (diff & UART_CTS)) ) { 997 return 0; 998 } 999 /* otherwise caller can't care less about what happened, 1000 * and so we continue to wait for more events. 1001 */ 1002 } 1003 } 1004 return 0; 1005 break; 1006 default: 1007 break; 1008 } 1009 1010 dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __FUNCTION__, cmd); 1011 1012 return -ENOIOCTLCMD; 1013 } /* cypress_ioctl */ 1014 1015 1016 static void cypress_set_termios (struct usb_serial_port *port, 1017 struct ktermios *old_termios) 1018 { 1019 struct cypress_private *priv = usb_get_serial_port_data(port); 1020 struct tty_struct *tty; 1021 int data_bits, stop_bits, parity_type, parity_enable; 1022 unsigned cflag, iflag, baud_mask; 1023 unsigned long flags; 1024 __u8 oldlines; 1025 int linechange = 0; 1026 1027 dbg("%s - port %d", __FUNCTION__, port->number); 1028 1029 tty = port->tty; 1030 if ((!tty) || (!tty->termios)) { 1031 dbg("%s - no tty structures", __FUNCTION__); 1032 return; 1033 } 1034 1035 spin_lock_irqsave(&priv->lock, flags); 1036 if (!priv->termios_initialized) { 1037 if (priv->chiptype == CT_EARTHMATE) { 1038 *(tty->termios) = tty_std_termios; 1039 tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | 1040 CLOCAL; 1041 } else if (priv->chiptype == CT_CYPHIDCOM) { 1042 *(tty->termios) = tty_std_termios; 1043 tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | 1044 CLOCAL; 1045 } else if (priv->chiptype == CT_CA42V2) { 1046 *(tty->termios) = tty_std_termios; 1047 tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | 1048 CLOCAL; 1049 } 1050 priv->termios_initialized = 1; 1051 } 1052 spin_unlock_irqrestore(&priv->lock, flags); 1053 1054 cflag = tty->termios->c_cflag; 1055 iflag = tty->termios->c_iflag; 1056 1057 /* check if there are new settings */ 1058 if (old_termios) { 1059 if ((cflag != old_termios->c_cflag) || 1060 (RELEVANT_IFLAG(iflag) != 1061 RELEVANT_IFLAG(old_termios->c_iflag))) { 1062 dbg("%s - attempting to set new termios settings", 1063 __FUNCTION__); 1064 /* should make a copy of this in case something goes 1065 * wrong in the function, we can restore it */ 1066 spin_lock_irqsave(&priv->lock, flags); 1067 priv->tmp_termios = *(tty->termios); 1068 spin_unlock_irqrestore(&priv->lock, flags); 1069 } else { 1070 dbg("%s - nothing to do, exiting", __FUNCTION__); 1071 return; 1072 } 1073 } else 1074 return; 1075 1076 /* set number of data bits, parity, stop bits */ 1077 /* when parity is disabled the parity type bit is ignored */ 1078 1079 /* 1 means 2 stop bits, 0 means 1 stop bit */ 1080 stop_bits = cflag & CSTOPB ? 1 : 0; 1081 1082 if (cflag & PARENB) { 1083 parity_enable = 1; 1084 /* 1 means odd parity, 0 means even parity */ 1085 parity_type = cflag & PARODD ? 1 : 0; 1086 } else 1087 parity_enable = parity_type = 0; 1088 1089 if (cflag & CSIZE) { 1090 switch (cflag & CSIZE) { 1091 case CS5: 1092 data_bits = 0; 1093 break; 1094 case CS6: 1095 data_bits = 1; 1096 break; 1097 case CS7: 1098 data_bits = 2; 1099 break; 1100 case CS8: 1101 data_bits = 3; 1102 break; 1103 default: 1104 err("%s - CSIZE was set, but not CS5-CS8", 1105 __FUNCTION__); 1106 data_bits = 3; 1107 } 1108 } else 1109 data_bits = 3; 1110 1111 spin_lock_irqsave(&priv->lock, flags); 1112 oldlines = priv->line_control; 1113 if ((cflag & CBAUD) == B0) { 1114 /* drop dtr and rts */ 1115 dbg("%s - dropping the lines, baud rate 0bps", __FUNCTION__); 1116 baud_mask = B0; 1117 priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); 1118 } else { 1119 baud_mask = (cflag & CBAUD); 1120 switch(baud_mask) { 1121 case B300: 1122 dbg("%s - setting baud 300bps", __FUNCTION__); 1123 break; 1124 case B600: 1125 dbg("%s - setting baud 600bps", __FUNCTION__); 1126 break; 1127 case B1200: 1128 dbg("%s - setting baud 1200bps", __FUNCTION__); 1129 break; 1130 case B2400: 1131 dbg("%s - setting baud 2400bps", __FUNCTION__); 1132 break; 1133 case B4800: 1134 dbg("%s - setting baud 4800bps", __FUNCTION__); 1135 break; 1136 case B9600: 1137 dbg("%s - setting baud 9600bps", __FUNCTION__); 1138 break; 1139 case B19200: 1140 dbg("%s - setting baud 19200bps", __FUNCTION__); 1141 break; 1142 case B38400: 1143 dbg("%s - setting baud 38400bps", __FUNCTION__); 1144 break; 1145 case B57600: 1146 dbg("%s - setting baud 57600bps", __FUNCTION__); 1147 break; 1148 case B115200: 1149 dbg("%s - setting baud 115200bps", __FUNCTION__); 1150 break; 1151 default: 1152 dbg("%s - unknown masked baud rate", __FUNCTION__); 1153 } 1154 priv->line_control = (CONTROL_DTR | CONTROL_RTS); 1155 } 1156 spin_unlock_irqrestore(&priv->lock, flags); 1157 1158 dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, " 1159 "%d data_bits (+5)", __FUNCTION__, stop_bits, 1160 parity_enable, parity_type, data_bits); 1161 1162 cypress_serial_control(port, baud_mask, data_bits, stop_bits, 1163 parity_enable, parity_type, 0, CYPRESS_SET_CONFIG); 1164 1165 /* we perform a CYPRESS_GET_CONFIG so that the current settings are 1166 * filled into the private structure this should confirm that all is 1167 * working if it returns what we just set */ 1168 cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG); 1169 1170 /* Here we can define custom tty settings for devices; the main tty 1171 * termios flag base comes from empeg.c */ 1172 1173 spin_lock_irqsave(&priv->lock, flags); 1174 if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) { 1175 dbg("Using custom termios settings for a baud rate of " 1176 "4800bps."); 1177 /* define custom termios settings for NMEA protocol */ 1178 1179 tty->termios->c_iflag /* input modes - */ 1180 &= ~(IGNBRK /* disable ignore break */ 1181 | BRKINT /* disable break causes interrupt */ 1182 | PARMRK /* disable mark parity errors */ 1183 | ISTRIP /* disable clear high bit of input char */ 1184 | INLCR /* disable translate NL to CR */ 1185 | IGNCR /* disable ignore CR */ 1186 | ICRNL /* disable translate CR to NL */ 1187 | IXON); /* disable enable XON/XOFF flow control */ 1188 1189 tty->termios->c_oflag /* output modes */ 1190 &= ~OPOST; /* disable postprocess output char */ 1191 1192 tty->termios->c_lflag /* line discipline modes */ 1193 &= ~(ECHO /* disable echo input characters */ 1194 | ECHONL /* disable echo new line */ 1195 | ICANON /* disable erase, kill, werase, and rprnt 1196 special characters */ 1197 | ISIG /* disable interrupt, quit, and suspend 1198 special characters */ 1199 | IEXTEN); /* disable non-POSIX special characters */ 1200 } /* CT_CYPHIDCOM: Application should handle this for device */ 1201 1202 linechange = (priv->line_control != oldlines); 1203 spin_unlock_irqrestore(&priv->lock, flags); 1204 1205 /* if necessary, set lines */ 1206 if (linechange) { 1207 priv->cmd_ctrl = 1; 1208 cypress_write(port, NULL, 0); 1209 } 1210 } /* cypress_set_termios */ 1211 1212 1213 /* returns amount of data still left in soft buffer */ 1214 static int cypress_chars_in_buffer(struct usb_serial_port *port) 1215 { 1216 struct cypress_private *priv = usb_get_serial_port_data(port); 1217 int chars = 0; 1218 unsigned long flags; 1219 1220 dbg("%s - port %d", __FUNCTION__, port->number); 1221 1222 spin_lock_irqsave(&priv->lock, flags); 1223 chars = cypress_buf_data_avail(priv->buf); 1224 spin_unlock_irqrestore(&priv->lock, flags); 1225 1226 dbg("%s - returns %d", __FUNCTION__, chars); 1227 return chars; 1228 } 1229 1230 1231 static void cypress_throttle (struct usb_serial_port *port) 1232 { 1233 struct cypress_private *priv = usb_get_serial_port_data(port); 1234 unsigned long flags; 1235 1236 dbg("%s - port %d", __FUNCTION__, port->number); 1237 1238 spin_lock_irqsave(&priv->lock, flags); 1239 priv->rx_flags = THROTTLED; 1240 spin_unlock_irqrestore(&priv->lock, flags); 1241 } 1242 1243 1244 static void cypress_unthrottle (struct usb_serial_port *port) 1245 { 1246 struct cypress_private *priv = usb_get_serial_port_data(port); 1247 int actually_throttled, result; 1248 unsigned long flags; 1249 1250 dbg("%s - port %d", __FUNCTION__, port->number); 1251 1252 spin_lock_irqsave(&priv->lock, flags); 1253 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; 1254 priv->rx_flags = 0; 1255 spin_unlock_irqrestore(&priv->lock, flags); 1256 1257 if (!priv->comm_is_ok) 1258 return; 1259 1260 if (actually_throttled) { 1261 port->interrupt_in_urb->dev = port->serial->dev; 1262 1263 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1264 if (result) { 1265 dev_err(&port->dev, "%s - failed submitting read urb, " 1266 "error %d\n", __FUNCTION__, result); 1267 cypress_set_dead(port); 1268 } 1269 } 1270 } 1271 1272 1273 static void cypress_read_int_callback(struct urb *urb) 1274 { 1275 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1276 struct cypress_private *priv = usb_get_serial_port_data(port); 1277 struct tty_struct *tty; 1278 unsigned char *data = urb->transfer_buffer; 1279 unsigned long flags; 1280 char tty_flag = TTY_NORMAL; 1281 int havedata = 0; 1282 int bytes = 0; 1283 int result; 1284 int i = 0; 1285 int status = urb->status; 1286 1287 dbg("%s - port %d", __FUNCTION__, port->number); 1288 1289 switch (status) { 1290 case 0: /* success */ 1291 break; 1292 case -ECONNRESET: 1293 case -ENOENT: 1294 case -ESHUTDOWN: 1295 /* precursor to disconnect so just go away */ 1296 return; 1297 case -EPIPE: 1298 usb_clear_halt(port->serial->dev,0x81); 1299 break; 1300 default: 1301 /* something ugly is going on... */ 1302 dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n", 1303 __FUNCTION__, status); 1304 cypress_set_dead(port); 1305 return; 1306 } 1307 1308 spin_lock_irqsave(&priv->lock, flags); 1309 if (priv->rx_flags & THROTTLED) { 1310 dbg("%s - now throttling", __FUNCTION__); 1311 priv->rx_flags |= ACTUALLY_THROTTLED; 1312 spin_unlock_irqrestore(&priv->lock, flags); 1313 return; 1314 } 1315 spin_unlock_irqrestore(&priv->lock, flags); 1316 1317 tty = port->tty; 1318 if (!tty) { 1319 dbg("%s - bad tty pointer - exiting", __FUNCTION__); 1320 return; 1321 } 1322 1323 spin_lock_irqsave(&priv->lock, flags); 1324 switch(urb->actual_length) { 1325 case 32: 1326 /* This is for the CY7C64013... */ 1327 priv->current_status = data[0] & 0xF8; 1328 bytes = data[1] + 2; 1329 i = 2; 1330 if (bytes > 2) 1331 havedata = 1; 1332 break; 1333 case 8: 1334 /* This is for the CY7C63743... */ 1335 priv->current_status = data[0] & 0xF8; 1336 bytes = (data[0] & 0x07) + 1; 1337 i = 1; 1338 if (bytes > 1) 1339 havedata = 1; 1340 break; 1341 default: 1342 dbg("%s - wrong packet size - received %d bytes", 1343 __FUNCTION__, urb->actual_length); 1344 spin_unlock_irqrestore(&priv->lock, flags); 1345 goto continue_read; 1346 } 1347 spin_unlock_irqrestore(&priv->lock, flags); 1348 1349 usb_serial_debug_data (debug, &port->dev, __FUNCTION__, 1350 urb->actual_length, data); 1351 1352 spin_lock_irqsave(&priv->lock, flags); 1353 /* check to see if status has changed */ 1354 if (priv != NULL) { 1355 if (priv->current_status != priv->prev_status) { 1356 priv->diff_status |= priv->current_status ^ 1357 priv->prev_status; 1358 wake_up_interruptible(&priv->delta_msr_wait); 1359 priv->prev_status = priv->current_status; 1360 } 1361 } 1362 spin_unlock_irqrestore(&priv->lock, flags); 1363 1364 /* hangup, as defined in acm.c... this might be a bad place for it 1365 * though */ 1366 if (tty && !(tty->termios->c_cflag & CLOCAL) && 1367 !(priv->current_status & UART_CD)) { 1368 dbg("%s - calling hangup", __FUNCTION__); 1369 tty_hangup(tty); 1370 goto continue_read; 1371 } 1372 1373 /* There is one error bit... I'm assuming it is a parity error 1374 * indicator as the generic firmware will set this bit to 1 if a 1375 * parity error occurs. 1376 * I can not find reference to any other error events. */ 1377 spin_lock_irqsave(&priv->lock, flags); 1378 if (priv->current_status & CYP_ERROR) { 1379 spin_unlock_irqrestore(&priv->lock, flags); 1380 tty_flag = TTY_PARITY; 1381 dbg("%s - Parity Error detected", __FUNCTION__); 1382 } else 1383 spin_unlock_irqrestore(&priv->lock, flags); 1384 1385 /* process read if there is data other than line status */ 1386 if (tty && (bytes > i)) { 1387 bytes = tty_buffer_request_room(tty, bytes); 1388 for (; i < bytes ; ++i) { 1389 dbg("pushing byte number %d - %d - %c", i, data[i], 1390 data[i]); 1391 tty_insert_flip_char(tty, data[i], tty_flag); 1392 } 1393 tty_flip_buffer_push(port->tty); 1394 } 1395 1396 spin_lock_irqsave(&priv->lock, flags); 1397 /* control and status byte(s) are also counted */ 1398 priv->bytes_in += bytes; 1399 spin_unlock_irqrestore(&priv->lock, flags); 1400 1401 continue_read: 1402 1403 /* Continue trying to always read... unless the port has closed. */ 1404 1405 if (port->open_count > 0 && priv->comm_is_ok) { 1406 usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, 1407 usb_rcvintpipe(port->serial->dev, 1408 port->interrupt_in_endpointAddress), 1409 port->interrupt_in_urb->transfer_buffer, 1410 port->interrupt_in_urb->transfer_buffer_length, 1411 cypress_read_int_callback, port, priv->read_urb_interval); 1412 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1413 if (result) { 1414 dev_err(&urb->dev->dev, "%s - failed resubmitting " 1415 "read urb, error %d\n", __FUNCTION__, 1416 result); 1417 cypress_set_dead(port); 1418 } 1419 } 1420 1421 return; 1422 } /* cypress_read_int_callback */ 1423 1424 1425 static void cypress_write_int_callback(struct urb *urb) 1426 { 1427 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1428 struct cypress_private *priv = usb_get_serial_port_data(port); 1429 int result; 1430 int status = urb->status; 1431 1432 dbg("%s - port %d", __FUNCTION__, port->number); 1433 1434 switch (status) { 1435 case 0: 1436 /* success */ 1437 break; 1438 case -ECONNRESET: 1439 case -ENOENT: 1440 case -ESHUTDOWN: 1441 /* this urb is terminated, clean up */ 1442 dbg("%s - urb shutting down with status: %d", 1443 __FUNCTION__, status); 1444 priv->write_urb_in_use = 0; 1445 return; 1446 case -EPIPE: /* no break needed; clear halt and resubmit */ 1447 if (!priv->comm_is_ok) 1448 break; 1449 usb_clear_halt(port->serial->dev, 0x02); 1450 /* error in the urb, so we have to resubmit it */ 1451 dbg("%s - nonzero write bulk status received: %d", 1452 __FUNCTION__, status); 1453 port->interrupt_out_urb->transfer_buffer_length = 1; 1454 port->interrupt_out_urb->dev = port->serial->dev; 1455 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); 1456 if (!result) 1457 return; 1458 dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n", 1459 __FUNCTION__, result); 1460 cypress_set_dead(port); 1461 break; 1462 default: 1463 dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n", 1464 __FUNCTION__, status); 1465 cypress_set_dead(port); 1466 break; 1467 } 1468 1469 priv->write_urb_in_use = 0; 1470 1471 /* send any buffered data */ 1472 cypress_send(port); 1473 } 1474 1475 1476 /***************************************************************************** 1477 * Write buffer functions - buffering code from pl2303 used 1478 *****************************************************************************/ 1479 1480 /* 1481 * cypress_buf_alloc 1482 * 1483 * Allocate a circular buffer and all associated memory. 1484 */ 1485 1486 static struct cypress_buf *cypress_buf_alloc(unsigned int size) 1487 { 1488 1489 struct cypress_buf *cb; 1490 1491 1492 if (size == 0) 1493 return NULL; 1494 1495 cb = kmalloc(sizeof(struct cypress_buf), GFP_KERNEL); 1496 if (cb == NULL) 1497 return NULL; 1498 1499 cb->buf_buf = kmalloc(size, GFP_KERNEL); 1500 if (cb->buf_buf == NULL) { 1501 kfree(cb); 1502 return NULL; 1503 } 1504 1505 cb->buf_size = size; 1506 cb->buf_get = cb->buf_put = cb->buf_buf; 1507 1508 return cb; 1509 1510 } 1511 1512 1513 /* 1514 * cypress_buf_free 1515 * 1516 * Free the buffer and all associated memory. 1517 */ 1518 1519 static void cypress_buf_free(struct cypress_buf *cb) 1520 { 1521 if (cb) { 1522 kfree(cb->buf_buf); 1523 kfree(cb); 1524 } 1525 } 1526 1527 1528 /* 1529 * cypress_buf_clear 1530 * 1531 * Clear out all data in the circular buffer. 1532 */ 1533 1534 static void cypress_buf_clear(struct cypress_buf *cb) 1535 { 1536 if (cb != NULL) 1537 cb->buf_get = cb->buf_put; 1538 /* equivalent to a get of all data available */ 1539 } 1540 1541 1542 /* 1543 * cypress_buf_data_avail 1544 * 1545 * Return the number of bytes of data available in the circular 1546 * buffer. 1547 */ 1548 1549 static unsigned int cypress_buf_data_avail(struct cypress_buf *cb) 1550 { 1551 if (cb != NULL) 1552 return ((cb->buf_size + cb->buf_put - cb->buf_get) % cb->buf_size); 1553 else 1554 return 0; 1555 } 1556 1557 1558 /* 1559 * cypress_buf_space_avail 1560 * 1561 * Return the number of bytes of space available in the circular 1562 * buffer. 1563 */ 1564 1565 static unsigned int cypress_buf_space_avail(struct cypress_buf *cb) 1566 { 1567 if (cb != NULL) 1568 return ((cb->buf_size + cb->buf_get - cb->buf_put - 1) % cb->buf_size); 1569 else 1570 return 0; 1571 } 1572 1573 1574 /* 1575 * cypress_buf_put 1576 * 1577 * Copy data data from a user buffer and put it into the circular buffer. 1578 * Restrict to the amount of space available. 1579 * 1580 * Return the number of bytes copied. 1581 */ 1582 1583 static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, 1584 unsigned int count) 1585 { 1586 1587 unsigned int len; 1588 1589 1590 if (cb == NULL) 1591 return 0; 1592 1593 len = cypress_buf_space_avail(cb); 1594 if (count > len) 1595 count = len; 1596 1597 if (count == 0) 1598 return 0; 1599 1600 len = cb->buf_buf + cb->buf_size - cb->buf_put; 1601 if (count > len) { 1602 memcpy(cb->buf_put, buf, len); 1603 memcpy(cb->buf_buf, buf+len, count - len); 1604 cb->buf_put = cb->buf_buf + count - len; 1605 } else { 1606 memcpy(cb->buf_put, buf, count); 1607 if (count < len) 1608 cb->buf_put += count; 1609 else /* count == len */ 1610 cb->buf_put = cb->buf_buf; 1611 } 1612 1613 return count; 1614 1615 } 1616 1617 1618 /* 1619 * cypress_buf_get 1620 * 1621 * Get data from the circular buffer and copy to the given buffer. 1622 * Restrict to the amount of data available. 1623 * 1624 * Return the number of bytes copied. 1625 */ 1626 1627 static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, 1628 unsigned int count) 1629 { 1630 1631 unsigned int len; 1632 1633 1634 if (cb == NULL) 1635 return 0; 1636 1637 len = cypress_buf_data_avail(cb); 1638 if (count > len) 1639 count = len; 1640 1641 if (count == 0) 1642 return 0; 1643 1644 len = cb->buf_buf + cb->buf_size - cb->buf_get; 1645 if (count > len) { 1646 memcpy(buf, cb->buf_get, len); 1647 memcpy(buf+len, cb->buf_buf, count - len); 1648 cb->buf_get = cb->buf_buf + count - len; 1649 } else { 1650 memcpy(buf, cb->buf_get, count); 1651 if (count < len) 1652 cb->buf_get += count; 1653 else /* count == len */ 1654 cb->buf_get = cb->buf_buf; 1655 } 1656 1657 return count; 1658 1659 } 1660 1661 /***************************************************************************** 1662 * Module functions 1663 *****************************************************************************/ 1664 1665 static int __init cypress_init(void) 1666 { 1667 int retval; 1668 1669 dbg("%s", __FUNCTION__); 1670 1671 retval = usb_serial_register(&cypress_earthmate_device); 1672 if (retval) 1673 goto failed_em_register; 1674 retval = usb_serial_register(&cypress_hidcom_device); 1675 if (retval) 1676 goto failed_hidcom_register; 1677 retval = usb_serial_register(&cypress_ca42v2_device); 1678 if (retval) 1679 goto failed_ca42v2_register; 1680 retval = usb_register(&cypress_driver); 1681 if (retval) 1682 goto failed_usb_register; 1683 1684 info(DRIVER_DESC " " DRIVER_VERSION); 1685 return 0; 1686 1687 failed_usb_register: 1688 usb_serial_deregister(&cypress_ca42v2_device); 1689 failed_ca42v2_register: 1690 usb_serial_deregister(&cypress_hidcom_device); 1691 failed_hidcom_register: 1692 usb_serial_deregister(&cypress_earthmate_device); 1693 failed_em_register: 1694 return retval; 1695 } 1696 1697 1698 static void __exit cypress_exit (void) 1699 { 1700 dbg("%s", __FUNCTION__); 1701 1702 usb_deregister (&cypress_driver); 1703 usb_serial_deregister (&cypress_earthmate_device); 1704 usb_serial_deregister (&cypress_hidcom_device); 1705 usb_serial_deregister (&cypress_ca42v2_device); 1706 } 1707 1708 1709 module_init(cypress_init); 1710 module_exit(cypress_exit); 1711 1712 MODULE_AUTHOR( DRIVER_AUTHOR ); 1713 MODULE_DESCRIPTION( DRIVER_DESC ); 1714 MODULE_VERSION( DRIVER_VERSION ); 1715 MODULE_LICENSE("GPL"); 1716 1717 module_param(debug, bool, S_IRUGO | S_IWUSR); 1718 MODULE_PARM_DESC(debug, "Debug enabled or not"); 1719 module_param(stats, bool, S_IRUGO | S_IWUSR); 1720 MODULE_PARM_DESC(stats, "Enable statistics or not"); 1721 module_param(interval, int, S_IRUGO | S_IWUSR); 1722 MODULE_PARM_DESC(interval, "Overrides interrupt interval"); 1723