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