aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/cypress_m8.c617
-rw-r--r--drivers/usb/serial/cypress_m8.h2
2 files changed, 325 insertions, 294 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 6999d3372d85..bb9c7c45e98f 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -2,7 +2,7 @@
2 * USB Cypress M8 driver 2 * USB Cypress M8 driver
3 * 3 *
4 * Copyright (C) 2004 4 * Copyright (C) 2004
5 * Lonnie Mendez (dignome@gmail.com) 5 * Lonnie Mendez (dignome@gmail.com)
6 * Copyright (C) 2003,2004 6 * Copyright (C) 2003,2004
7 * Neil Whelchel (koyama@firstlight.net) 7 * Neil Whelchel (koyama@firstlight.net)
8 * 8 *
@@ -11,19 +11,21 @@
11 * the Free Software Foundation; either version 2 of the License, or 11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version. 12 * (at your option) any later version.
13 * 13 *
14 * See Documentation/usb/usb-serial.txt for more information on using this driver 14 * See Documentation/usb/usb-serial.txt for more information on using this
15 * driver
15 * 16 *
16 * See http://geocities.com/i0xox0i for information on this driver and the 17 * See http://geocities.com/i0xox0i for information on this driver and the
17 * earthmate usb device. 18 * earthmate usb device.
18 * 19 *
19 * Lonnie Mendez <dignome@gmail.com> 20 * Lonnie Mendez <dignome@gmail.com>
20 * 4-29-2005 21 * 4-29-2005
21 * Fixed problem where setting or retreiving the serial config would fail with 22 * Fixed problem where setting or retreiving the serial config would fail
22 * EPIPE. Removed CRTS toggling so the driver behaves more like other usbserial 23 * with EPIPE. Removed CRTS toggling so the driver behaves more like
23 * adapters. Issued new interval of 1ms instead of the default 10ms. As a 24 * other usbserial adapters. Issued new interval of 1ms instead of the
24 * result, transfer speed has been substantially increased. From avg. 850bps to 25 * default 10ms. As a result, transfer speed has been substantially
25 * avg. 3300bps. initial termios has also been modified. Cleaned up code and 26 * increased from avg. 850bps to avg. 3300bps. initial termios has also
26 * formatting issues so it is more readable. Replaced the C++ style comments. 27 * been modified. Cleaned up code and formatting issues so it is more
28 * readable. Replaced the C++ style comments.
27 * 29 *
28 * Lonnie Mendez <dignome@gmail.com> 30 * Lonnie Mendez <dignome@gmail.com>
29 * 12-15-2004 31 * 12-15-2004
@@ -42,10 +44,11 @@
42 * 44 *
43 */ 45 */
44 46
45/* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */ 47/* Thanks to Neil Whelchel for writing the first cypress m8 implementation
48 for linux. */
46/* Thanks to cypress for providing references for the hid reports. */ 49/* Thanks to cypress for providing references for the hid reports. */
47/* Thanks to Jiang Zhang for providing links and for general help. */ 50/* 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. */ 51/* Code originates and was built up from ftdi_sio, belkin, pl2303 and others.*/
49 52
50 53
51#include <linux/kernel.h> 54#include <linux/kernel.h>
@@ -62,7 +65,7 @@
62#include <linux/usb/serial.h> 65#include <linux/usb/serial.h>
63#include <linux/serial.h> 66#include <linux/serial.h>
64#include <linux/delay.h> 67#include <linux/delay.h>
65#include <asm/uaccess.h> 68#include <linux/uaccess.h>
66 69
67#include "cypress_m8.h" 70#include "cypress_m8.h"
68 71
@@ -112,7 +115,7 @@ static struct usb_device_id id_table_combined [] = {
112 { } /* Terminating entry */ 115 { } /* Terminating entry */
113}; 116};
114 117
115MODULE_DEVICE_TABLE (usb, id_table_combined); 118MODULE_DEVICE_TABLE(usb, id_table_combined);
116 119
117static struct usb_driver cypress_driver = { 120static struct usb_driver cypress_driver = {
118 .name = "cypress", 121 .name = "cypress",
@@ -146,11 +149,13 @@ struct cypress_private {
146 __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */ 149 __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */
147 enum packet_format pkt_fmt; /* format to use for packet send / receive */ 150 enum packet_format pkt_fmt; /* format to use for packet send / receive */
148 int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */ 151 int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */
149 int baud_rate; /* stores current baud rate in integer form */ 152 int baud_rate; /* stores current baud rate in
153 integer form */
150 int isthrottled; /* if throttled, discard reads */ 154 int isthrottled; /* if throttled, discard reads */
151 wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ 155 wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */
152 char prev_status, diff_status; /* used for TIOCMIWAIT */ 156 char prev_status, diff_status; /* used for TIOCMIWAIT */
153 /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */ 157 /* we pass a pointer to this as the arguement sent to
158 cypress_set_termios old_termios */
154 struct ktermios tmp_termios; /* stores the old termios settings */ 159 struct ktermios tmp_termios; /* stores the old termios settings */
155}; 160};
156 161
@@ -163,33 +168,41 @@ struct cypress_buf {
163}; 168};
164 169
165/* function prototypes for the Cypress USB to serial device */ 170/* function prototypes for the Cypress USB to serial device */
166static int cypress_earthmate_startup (struct usb_serial *serial); 171static int cypress_earthmate_startup(struct usb_serial *serial);
167static int cypress_hidcom_startup (struct usb_serial *serial); 172static int cypress_hidcom_startup(struct usb_serial *serial);
168static int cypress_ca42v2_startup (struct usb_serial *serial); 173static int cypress_ca42v2_startup(struct usb_serial *serial);
169static void cypress_shutdown (struct usb_serial *serial); 174static void cypress_shutdown(struct usb_serial *serial);
170static int cypress_open (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp); 175static int cypress_open(struct tty_struct *tty,
171static void cypress_close (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp); 176 struct usb_serial_port *port, struct file *filp);
172static int cypress_write (struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); 177static void cypress_close(struct tty_struct *tty,
173static void cypress_send (struct usb_serial_port *port); 178 struct usb_serial_port *port, struct file *filp);
174static int cypress_write_room (struct tty_struct *tty); 179static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
175static int cypress_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg); 180 const unsigned char *buf, int count);
176static void cypress_set_termios (struct tty_struct *tty, struct usb_serial_port *port, struct ktermios * old); 181static void cypress_send(struct usb_serial_port *port);
177static int cypress_tiocmget (struct tty_struct *tty, struct file *file); 182static int cypress_write_room(struct tty_struct *tty);
178static int cypress_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); 183static int cypress_ioctl(struct tty_struct *tty, struct file *file,
179static int cypress_chars_in_buffer (struct tty_struct *tty); 184 unsigned int cmd, unsigned long arg);
180static void cypress_throttle (struct tty_struct *tty); 185static void cypress_set_termios(struct tty_struct *tty,
181static void cypress_unthrottle (struct tty_struct *tty); 186 struct usb_serial_port *port, struct ktermios *old);
182static void cypress_set_dead (struct usb_serial_port *port); 187static int cypress_tiocmget(struct tty_struct *tty, struct file *file);
183static void cypress_read_int_callback (struct urb *urb); 188static int cypress_tiocmset(struct tty_struct *tty, struct file *file,
184static void cypress_write_int_callback (struct urb *urb); 189 unsigned int set, unsigned int clear);
190static int cypress_chars_in_buffer(struct tty_struct *tty);
191static void cypress_throttle(struct tty_struct *tty);
192static void cypress_unthrottle(struct tty_struct *tty);
193static void cypress_set_dead(struct usb_serial_port *port);
194static void cypress_read_int_callback(struct urb *urb);
195static void cypress_write_int_callback(struct urb *urb);
185/* write buffer functions */ 196/* write buffer functions */
186static struct cypress_buf *cypress_buf_alloc(unsigned int size); 197static struct cypress_buf *cypress_buf_alloc(unsigned int size);
187static void cypress_buf_free(struct cypress_buf *cb); 198static void cypress_buf_free(struct cypress_buf *cb);
188static void cypress_buf_clear(struct cypress_buf *cb); 199static void cypress_buf_clear(struct cypress_buf *cb);
189static unsigned int cypress_buf_data_avail(struct cypress_buf *cb); 200static unsigned int cypress_buf_data_avail(struct cypress_buf *cb);
190static unsigned int cypress_buf_space_avail(struct cypress_buf *cb); 201static unsigned int cypress_buf_space_avail(struct cypress_buf *cb);
191static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, unsigned int count); 202static unsigned int cypress_buf_put(struct cypress_buf *cb,
192static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count); 203 const char *buf, unsigned int count);
204static unsigned int cypress_buf_get(struct cypress_buf *cb,
205 char *buf, unsigned int count);
193 206
194 207
195static struct usb_serial_driver cypress_earthmate_device = { 208static struct usb_serial_driver cypress_earthmate_device = {
@@ -247,7 +260,7 @@ static struct usb_serial_driver cypress_hidcom_device = {
247static struct usb_serial_driver cypress_ca42v2_device = { 260static struct usb_serial_driver cypress_ca42v2_device = {
248 .driver = { 261 .driver = {
249 .owner = THIS_MODULE, 262 .owner = THIS_MODULE,
250 .name = "nokiaca42v2", 263 .name = "nokiaca42v2",
251 }, 264 },
252 .description = "Nokia CA-42 V2 Adapter", 265 .description = "Nokia CA-42 V2 Adapter",
253 .usb_driver = &cypress_driver, 266 .usb_driver = &cypress_driver,
@@ -322,7 +335,7 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
322 335
323 336
324/* This function can either set or retrieve the current serial line settings */ 337/* This function can either set or retrieve the current serial line settings */
325static int cypress_serial_control (struct tty_struct *tty, 338static int cypress_serial_control(struct tty_struct *tty,
326 struct usb_serial_port *port, speed_t baud_rate, int data_bits, 339 struct usb_serial_port *port, speed_t baud_rate, int data_bits,
327 int stop_bits, int parity_enable, int parity_type, int reset, 340 int stop_bits, int parity_enable, int parity_type, int reset,
328 int cypress_request_type) 341 int cypress_request_type)
@@ -333,111 +346,114 @@ static int cypress_serial_control (struct tty_struct *tty,
333 unsigned long flags; 346 unsigned long flags;
334 347
335 dbg("%s", __func__); 348 dbg("%s", __func__);
336 349
337 priv = usb_get_serial_port_data(port); 350 priv = usb_get_serial_port_data(port);
338 351
339 if (!priv->comm_is_ok) 352 if (!priv->comm_is_ok)
340 return -ENODEV; 353 return -ENODEV;
341 354
342 switch(cypress_request_type) { 355 switch (cypress_request_type) {
343 case CYPRESS_SET_CONFIG: 356 case CYPRESS_SET_CONFIG:
357 new_baudrate = priv->baud_rate;
358 /* 0 means 'Hang up' so doesn't change the true bit rate */
359 if (baud_rate == 0)
344 new_baudrate = priv->baud_rate; 360 new_baudrate = priv->baud_rate;
345 /* 0 means 'Hang up' so doesn't change the true bit rate */ 361 /* Change of speed ? */
346 if (baud_rate == 0) 362 else if (baud_rate != priv->baud_rate) {
347 new_baudrate = priv->baud_rate; 363 dbg("%s - baud rate is changing", __func__);
348 /* Change of speed ? */ 364 retval = analyze_baud_rate(port, baud_rate);
349 else if (baud_rate != priv->baud_rate) { 365 if (retval >= 0) {
350 dbg("%s - baud rate is changing", __func__); 366 new_baudrate = retval;
351 retval = analyze_baud_rate(port, baud_rate); 367 dbg("%s - New baud rate set to %d",
352 if (retval >= 0) { 368 __func__, new_baudrate);
353 new_baudrate = retval;
354 dbg("%s - New baud rate set to %d",
355 __func__, new_baudrate);
356 }
357 }
358 dbg("%s - baud rate is being sent as %d", __func__, new_baudrate);
359
360 memset(feature_buffer, 0, sizeof(feature_buffer));
361 /* fill the feature_buffer with new configuration */
362 *((u_int32_t *)feature_buffer) = new_baudrate;
363
364 feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */
365 /* 1 bit gap */
366 feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */
367 feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */
368 feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */
369 /* 1 bit gap */
370 feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */
371
372 dbg("%s - device is being sent this feature report:", __func__);
373 dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__, feature_buffer[0], feature_buffer[1],
374 feature_buffer[2], feature_buffer[3], feature_buffer[4]);
375
376 do {
377 retval = usb_control_msg(port->serial->dev,
378 usb_sndctrlpipe(port->serial->dev, 0),
379 HID_REQ_SET_REPORT,
380 USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
381 0x0300, 0, feature_buffer,
382 sizeof(feature_buffer), 500);
383
384 if (tries++ >= 3)
385 break;
386
387 } while (retval != sizeof(feature_buffer) &&
388 retval != -ENODEV);
389
390 if (retval != sizeof(feature_buffer)) {
391 err("%s - failed sending serial line settings - %d", __func__, retval);
392 cypress_set_dead(port);
393 } else {
394 spin_lock_irqsave(&priv->lock, flags);
395 priv->baud_rate = new_baudrate;
396 priv->current_config = feature_buffer[4];
397 spin_unlock_irqrestore(&priv->lock, flags);
398 /* If we asked for a speed change encode it */
399 if (baud_rate)
400 tty_encode_baud_rate(tty,
401 new_baudrate, new_baudrate);
402 }
403 break;
404 case CYPRESS_GET_CONFIG:
405 if (priv->get_cfg_unsafe) {
406 /* Not implemented for this device,
407 and if we try to do it we're likely
408 to crash the hardware. */
409 return -ENOTTY;
410 }
411 dbg("%s - retreiving serial line settings", __func__);
412 /* set initial values in feature buffer */
413 memset(feature_buffer, 0, sizeof(feature_buffer));
414
415 do {
416 retval = usb_control_msg(port->serial->dev,
417 usb_rcvctrlpipe(port->serial->dev, 0),
418 HID_REQ_GET_REPORT,
419 USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
420 0x0300, 0, feature_buffer,
421 sizeof(feature_buffer), 500);
422
423 if (tries++ >= 3)
424 break;
425
426 } while (retval != sizeof(feature_buffer) &&
427 retval != -ENODEV);
428
429 if (retval != sizeof(feature_buffer)) {
430 err("%s - failed to retrieve serial line settings - %d", __func__, retval);
431 cypress_set_dead(port);
432 return retval;
433 } else {
434 spin_lock_irqsave(&priv->lock, flags);
435
436 /* store the config in one byte, and later use bit masks to check values */
437 priv->current_config = feature_buffer[4];
438 priv->baud_rate = *((u_int32_t *)feature_buffer);
439 spin_unlock_irqrestore(&priv->lock, flags);
440 } 369 }
370 }
371 dbg("%s - baud rate is being sent as %d",
372 __func__, new_baudrate);
373
374 memset(feature_buffer, 0, sizeof(feature_buffer));
375 /* fill the feature_buffer with new configuration */
376 *((u_int32_t *)feature_buffer) = new_baudrate;
377 feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */
378 /* 1 bit gap */
379 feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */
380 feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */
381 feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */
382 /* 1 bit gap */
383 feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */
384
385 dbg("%s - device is being sent this feature report:",
386 __func__);
387 dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__,
388 feature_buffer[0], feature_buffer[1],
389 feature_buffer[2], feature_buffer[3],
390 feature_buffer[4]);
391
392 do {
393 retval = usb_control_msg(port->serial->dev,
394 usb_sndctrlpipe(port->serial->dev, 0),
395 HID_REQ_SET_REPORT,
396 USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
397 0x0300, 0, feature_buffer,
398 sizeof(feature_buffer), 500);
399
400 if (tries++ >= 3)
401 break;
402
403 } while (retval != sizeof(feature_buffer) &&
404 retval != -ENODEV);
405
406 if (retval != sizeof(feature_buffer)) {
407 err("%s - failed sending serial line settings - %d",
408 __func__, retval);
409 cypress_set_dead(port);
410 } else {
411 spin_lock_irqsave(&priv->lock, flags);
412 priv->baud_rate = new_baudrate;
413 priv->current_config = feature_buffer[4];
414 spin_unlock_irqrestore(&priv->lock, flags);
415 /* If we asked for a speed change encode it */
416 if (baud_rate)
417 tty_encode_baud_rate(tty,
418 new_baudrate, new_baudrate);
419 }
420 break;
421 case CYPRESS_GET_CONFIG:
422 if (priv->get_cfg_unsafe) {
423 /* Not implemented for this device,
424 and if we try to do it we're likely
425 to crash the hardware. */
426 return -ENOTTY;
427 }
428 dbg("%s - retreiving serial line settings", __func__);
429 /* set initial values in feature buffer */
430 memset(feature_buffer, 0, sizeof(feature_buffer));
431
432 do {
433 retval = usb_control_msg(port->serial->dev,
434 usb_rcvctrlpipe(port->serial->dev, 0),
435 HID_REQ_GET_REPORT,
436 USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
437 0x0300, 0, feature_buffer,
438 sizeof(feature_buffer), 500);
439
440 if (tries++ >= 3)
441 break;
442 } while (retval != sizeof(feature_buffer)
443 && retval != -ENODEV);
444
445 if (retval != sizeof(feature_buffer)) {
446 err("%s - failed to retrieve serial line settings - %d", __func__, retval);
447 cypress_set_dead(port);
448 return retval;
449 } else {
450 spin_lock_irqsave(&priv->lock, flags);
451 /* store the config in one byte, and later
452 use bit masks to check values */
453 priv->current_config = feature_buffer[4];
454 priv->baud_rate = *((u_int32_t *)feature_buffer);
455 spin_unlock_irqrestore(&priv->lock, flags);
456 }
441 } 457 }
442 spin_lock_irqsave(&priv->lock, flags); 458 spin_lock_irqsave(&priv->lock, flags);
443 ++priv->cmd_count; 459 ++priv->cmd_count;
@@ -470,14 +486,14 @@ static void cypress_set_dead(struct usb_serial_port *port)
470 *****************************************************************************/ 486 *****************************************************************************/
471 487
472 488
473static int generic_startup (struct usb_serial *serial) 489static int generic_startup(struct usb_serial *serial)
474{ 490{
475 struct cypress_private *priv; 491 struct cypress_private *priv;
476 struct usb_serial_port *port = serial->port[0]; 492 struct usb_serial_port *port = serial->port[0];
477 493
478 dbg("%s - port %d", __func__, port->number); 494 dbg("%s - port %d", __func__, port->number);
479 495
480 priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL); 496 priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
481 if (!priv) 497 if (!priv)
482 return -ENOMEM; 498 return -ENOMEM;
483 499
@@ -489,9 +505,9 @@ static int generic_startup (struct usb_serial *serial)
489 return -ENOMEM; 505 return -ENOMEM;
490 } 506 }
491 init_waitqueue_head(&priv->delta_msr_wait); 507 init_waitqueue_head(&priv->delta_msr_wait);
492 508
493 usb_reset_configuration (serial->dev); 509 usb_reset_configuration(serial->dev);
494 510
495 priv->cmd_ctrl = 0; 511 priv->cmd_ctrl = 0;
496 priv->line_control = 0; 512 priv->line_control = 0;
497 priv->termios_initialized = 0; 513 priv->termios_initialized = 0;
@@ -502,30 +518,30 @@ static int generic_startup (struct usb_serial *serial)
502 small. Otherwise we can use the slightly more compact 518 small. Otherwise we can use the slightly more compact
503 format. This is in accordance with the cypress_m8 serial 519 format. This is in accordance with the cypress_m8 serial
504 converter app note. */ 520 converter app note. */
505 if (port->interrupt_out_size > 9) { 521 if (port->interrupt_out_size > 9)
506 priv->pkt_fmt = packet_format_1; 522 priv->pkt_fmt = packet_format_1;
507 } else { 523 else
508 priv->pkt_fmt = packet_format_2; 524 priv->pkt_fmt = packet_format_2;
509 } 525
510 if (interval > 0) { 526 if (interval > 0) {
511 priv->write_urb_interval = interval; 527 priv->write_urb_interval = interval;
512 priv->read_urb_interval = interval; 528 priv->read_urb_interval = interval;
513 dbg("%s - port %d read & write intervals forced to %d", 529 dbg("%s - port %d read & write intervals forced to %d",
514 __func__,port->number,interval); 530 __func__, port->number, interval);
515 } else { 531 } else {
516 priv->write_urb_interval = port->interrupt_out_urb->interval; 532 priv->write_urb_interval = port->interrupt_out_urb->interval;
517 priv->read_urb_interval = port->interrupt_in_urb->interval; 533 priv->read_urb_interval = port->interrupt_in_urb->interval;
518 dbg("%s - port %d intervals: read=%d write=%d", 534 dbg("%s - port %d intervals: read=%d write=%d",
519 __func__,port->number, 535 __func__, port->number,
520 priv->read_urb_interval,priv->write_urb_interval); 536 priv->read_urb_interval, priv->write_urb_interval);
521 } 537 }
522 usb_set_serial_port_data(port, priv); 538 usb_set_serial_port_data(port, priv);
523 539
524 return 0; 540 return 0;
525} 541}
526 542
527 543
528static int cypress_earthmate_startup (struct usb_serial *serial) 544static int cypress_earthmate_startup(struct usb_serial *serial)
529{ 545{
530 struct cypress_private *priv; 546 struct cypress_private *priv;
531 struct usb_serial_port *port = serial->port[0]; 547 struct usb_serial_port *port = serial->port[0];
@@ -543,7 +559,8 @@ static int cypress_earthmate_startup (struct usb_serial *serial)
543 /* All Earthmate devices use the separated-count packet 559 /* All Earthmate devices use the separated-count packet
544 format! Idiotic. */ 560 format! Idiotic. */
545 priv->pkt_fmt = packet_format_1; 561 priv->pkt_fmt = packet_format_1;
546 if (serial->dev->descriptor.idProduct != cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) { 562 if (serial->dev->descriptor.idProduct !=
563 cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) {
547 /* The old original USB Earthmate seemed able to 564 /* The old original USB Earthmate seemed able to
548 handle GET_CONFIG requests; everything they've 565 handle GET_CONFIG requests; everything they've
549 produced since that time crashes if this command is 566 produced since that time crashes if this command is
@@ -557,7 +574,7 @@ static int cypress_earthmate_startup (struct usb_serial *serial)
557} /* cypress_earthmate_startup */ 574} /* cypress_earthmate_startup */
558 575
559 576
560static int cypress_hidcom_startup (struct usb_serial *serial) 577static int cypress_hidcom_startup(struct usb_serial *serial)
561{ 578{
562 struct cypress_private *priv; 579 struct cypress_private *priv;
563 580
@@ -571,12 +588,12 @@ static int cypress_hidcom_startup (struct usb_serial *serial)
571 588
572 priv = usb_get_serial_port_data(serial->port[0]); 589 priv = usb_get_serial_port_data(serial->port[0]);
573 priv->chiptype = CT_CYPHIDCOM; 590 priv->chiptype = CT_CYPHIDCOM;
574 591
575 return 0; 592 return 0;
576} /* cypress_hidcom_startup */ 593} /* cypress_hidcom_startup */
577 594
578 595
579static int cypress_ca42v2_startup (struct usb_serial *serial) 596static int cypress_ca42v2_startup(struct usb_serial *serial)
580{ 597{
581 struct cypress_private *priv; 598 struct cypress_private *priv;
582 599
@@ -595,11 +612,11 @@ static int cypress_ca42v2_startup (struct usb_serial *serial)
595} /* cypress_ca42v2_startup */ 612} /* cypress_ca42v2_startup */
596 613
597 614
598static void cypress_shutdown (struct usb_serial *serial) 615static void cypress_shutdown(struct usb_serial *serial)
599{ 616{
600 struct cypress_private *priv; 617 struct cypress_private *priv;
601 618
602 dbg ("%s - port %d", __func__, serial->port[0]->number); 619 dbg("%s - port %d", __func__, serial->port[0]->number);
603 620
604 /* all open ports are closed at this point */ 621 /* all open ports are closed at this point */
605 622
@@ -650,7 +667,9 @@ static int cypress_open(struct tty_struct *tty,
650 result = cypress_write(tty, port, NULL, 0); 667 result = cypress_write(tty, port, NULL, 0);
651 668
652 if (result) { 669 if (result) {
653 dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __func__, result); 670 dev_err(&port->dev,
671 "%s - failed setting the control lines - error %d\n",
672 __func__, result);
654 return result; 673 return result;
655 } else 674 } else
656 dbg("%s - success setting the control lines", __func__); 675 dbg("%s - success setting the control lines", __func__);
@@ -659,19 +678,22 @@ static int cypress_open(struct tty_struct *tty,
659 cypress_set_termios(tty, port, &priv->tmp_termios); 678 cypress_set_termios(tty, port, &priv->tmp_termios);
660 679
661 /* setup the port and start reading from the device */ 680 /* setup the port and start reading from the device */
662 if(!port->interrupt_in_urb){ 681 if (!port->interrupt_in_urb) {
663 err("%s - interrupt_in_urb is empty!", __func__); 682 err("%s - interrupt_in_urb is empty!", __func__);
664 return(-1); 683 return -1;
665 } 684 }
666 685
667 usb_fill_int_urb(port->interrupt_in_urb, serial->dev, 686 usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
668 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), 687 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
669 port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length, 688 port->interrupt_in_urb->transfer_buffer,
689 port->interrupt_in_urb->transfer_buffer_length,
670 cypress_read_int_callback, port, priv->read_urb_interval); 690 cypress_read_int_callback, port, priv->read_urb_interval);
671 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 691 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
672 692
673 if (result){ 693 if (result) {
674 dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); 694 dev_err(&port->dev,
695 "%s - failed submitting read urb, error %d\n",
696 __func__, result);
675 cypress_set_dead(port); 697 cypress_set_dead(port);
676 } 698 }
677 699
@@ -680,7 +702,7 @@ static int cypress_open(struct tty_struct *tty,
680 702
681 703
682static void cypress_close(struct tty_struct *tty, 704static void cypress_close(struct tty_struct *tty,
683 struct usb_serial_port *port, struct file * filp) 705 struct usb_serial_port *port, struct file *filp)
684{ 706{
685 struct cypress_private *priv = usb_get_serial_port_data(port); 707 struct cypress_private *priv = usb_get_serial_port_data(port);
686 unsigned int c_cflag; 708 unsigned int c_cflag;
@@ -722,15 +744,15 @@ static void cypress_close(struct tty_struct *tty,
722 if (tty) { 744 if (tty) {
723 bps = tty_get_baud_rate(tty); 745 bps = tty_get_baud_rate(tty);
724 if (bps > 1200) 746 if (bps > 1200)
725 timeout = max((HZ*2560)/bps,HZ/10); 747 timeout = max((HZ * 2560) / bps, HZ / 10);
726 else 748 else
727 timeout = 2*HZ; 749 timeout = 2 * HZ;
728 schedule_timeout_interruptible(timeout); 750 schedule_timeout_interruptible(timeout);
729 } 751 }
730 752
731 dbg("%s - stopping urbs", __func__); 753 dbg("%s - stopping urbs", __func__);
732 usb_kill_urb (port->interrupt_in_urb); 754 usb_kill_urb(port->interrupt_in_urb);
733 usb_kill_urb (port->interrupt_out_urb); 755 usb_kill_urb(port->interrupt_out_urb);
734 756
735 if (tty) { 757 if (tty) {
736 c_cflag = tty->termios->c_cflag; 758 c_cflag = tty->termios->c_cflag;
@@ -746,8 +768,8 @@ static void cypress_close(struct tty_struct *tty,
746 } 768 }
747 769
748 if (stats) 770 if (stats)
749 dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", 771 dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
750 priv->bytes_in, priv->bytes_out, priv->cmd_count); 772 priv->bytes_in, priv->bytes_out, priv->cmd_count);
751 mutex_unlock(&port->serial->disc_mutex); 773 mutex_unlock(&port->serial->disc_mutex);
752} /* cypress_close */ 774} /* cypress_close */
753 775
@@ -757,7 +779,7 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
757{ 779{
758 struct cypress_private *priv = usb_get_serial_port_data(port); 780 struct cypress_private *priv = usb_get_serial_port_data(port);
759 unsigned long flags; 781 unsigned long flags;
760 782
761 dbg("%s - port %d, %d bytes", __func__, port->number, count); 783 dbg("%s - port %d, %d bytes", __func__, port->number, count);
762 784
763 /* line control commands, which need to be executed immediately, 785 /* line control commands, which need to be executed immediately,
@@ -767,10 +789,10 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
767 count = 0; 789 count = 0;
768 goto finish; 790 goto finish;
769 } 791 }
770 792
771 if (!count) 793 if (!count)
772 return count; 794 return count;
773 795
774 spin_lock_irqsave(&priv->lock, flags); 796 spin_lock_irqsave(&priv->lock, flags);
775 count = cypress_buf_put(priv->buf, buf, count); 797 count = cypress_buf_put(priv->buf, buf, count);
776 spin_unlock_irqrestore(&priv->lock, flags); 798 spin_unlock_irqrestore(&priv->lock, flags);
@@ -787,13 +809,14 @@ static void cypress_send(struct usb_serial_port *port)
787 int count = 0, result, offset, actual_size; 809 int count = 0, result, offset, actual_size;
788 struct cypress_private *priv = usb_get_serial_port_data(port); 810 struct cypress_private *priv = usb_get_serial_port_data(port);
789 unsigned long flags; 811 unsigned long flags;
790 812
791 if (!priv->comm_is_ok) 813 if (!priv->comm_is_ok)
792 return; 814 return;
793 815
794 dbg("%s - port %d", __func__, port->number); 816 dbg("%s - port %d", __func__, port->number);
795 dbg("%s - interrupt out size is %d", __func__, port->interrupt_out_size); 817 dbg("%s - interrupt out size is %d", __func__,
796 818 port->interrupt_out_size);
819
797 spin_lock_irqsave(&priv->lock, flags); 820 spin_lock_irqsave(&priv->lock, flags);
798 if (priv->write_urb_in_use) { 821 if (priv->write_urb_in_use) {
799 dbg("%s - can't write, urb in use", __func__); 822 dbg("%s - can't write, urb in use", __func__);
@@ -803,7 +826,8 @@ static void cypress_send(struct usb_serial_port *port)
803 spin_unlock_irqrestore(&priv->lock, flags); 826 spin_unlock_irqrestore(&priv->lock, flags);
804 827
805 /* clear buffer */ 828 /* clear buffer */
806 memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size); 829 memset(port->interrupt_out_urb->transfer_buffer, 0,
830 port->interrupt_out_size);
807 831
808 spin_lock_irqsave(&priv->lock, flags); 832 spin_lock_irqsave(&priv->lock, flags);
809 switch (priv->pkt_fmt) { 833 switch (priv->pkt_fmt) {
@@ -834,9 +858,8 @@ static void cypress_send(struct usb_serial_port *port)
834 count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset], 858 count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset],
835 port->interrupt_out_size-offset); 859 port->interrupt_out_size-offset);
836 860
837 if (count == 0) { 861 if (count == 0)
838 return; 862 return;
839 }
840 863
841 switch (priv->pkt_fmt) { 864 switch (priv->pkt_fmt) {
842 default: 865 default:
@@ -860,26 +883,29 @@ send:
860 actual_size = count + 883 actual_size = count +
861 (priv->pkt_fmt == packet_format_1 ? 2 : 1); 884 (priv->pkt_fmt == packet_format_1 ? 2 : 1);
862 885
863 usb_serial_debug_data(debug, &port->dev, __func__, port->interrupt_out_size, 886 usb_serial_debug_data(debug, &port->dev, __func__,
864 port->interrupt_out_urb->transfer_buffer); 887 port->interrupt_out_size,
888 port->interrupt_out_urb->transfer_buffer);
865 889
866 usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev, 890 usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev,
867 usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress), 891 usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
868 port->interrupt_out_buffer, port->interrupt_out_size, 892 port->interrupt_out_buffer, port->interrupt_out_size,
869 cypress_write_int_callback, port, priv->write_urb_interval); 893 cypress_write_int_callback, port, priv->write_urb_interval);
870 result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC); 894 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
871 if (result) { 895 if (result) {
872 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, 896 dev_err(&port->dev,
873 result); 897 "%s - failed submitting write urb, error %d\n",
898 __func__, result);
874 priv->write_urb_in_use = 0; 899 priv->write_urb_in_use = 0;
875 cypress_set_dead(port); 900 cypress_set_dead(port);
876 } 901 }
877 902
878 spin_lock_irqsave(&priv->lock, flags); 903 spin_lock_irqsave(&priv->lock, flags);
879 if (priv->cmd_ctrl) { 904 if (priv->cmd_ctrl)
880 priv->cmd_ctrl = 0; 905 priv->cmd_ctrl = 0;
881 } 906
882 priv->bytes_out += count; /* do not count the line control and size bytes */ 907 /* do not count the line control and size bytes */
908 priv->bytes_out += count;
883 spin_unlock_irqrestore(&priv->lock, flags); 909 spin_unlock_irqrestore(&priv->lock, flags);
884 910
885 usb_serial_port_softint(port); 911 usb_serial_port_softint(port);
@@ -912,7 +938,7 @@ static int cypress_tiocmget(struct tty_struct *tty, struct file *file)
912 __u8 status, control; 938 __u8 status, control;
913 unsigned int result = 0; 939 unsigned int result = 0;
914 unsigned long flags; 940 unsigned long flags;
915 941
916 dbg("%s - port %d", __func__, port->number); 942 dbg("%s - port %d", __func__, port->number);
917 943
918 spin_lock_irqsave(&priv->lock, flags); 944 spin_lock_irqsave(&priv->lock, flags);
@@ -939,7 +965,7 @@ static int cypress_tiocmset(struct tty_struct *tty, struct file *file,
939 struct usb_serial_port *port = tty->driver_data; 965 struct usb_serial_port *port = tty->driver_data;
940 struct cypress_private *priv = usb_get_serial_port_data(port); 966 struct cypress_private *priv = usb_get_serial_port_data(port);
941 unsigned long flags; 967 unsigned long flags;
942 968
943 dbg("%s - port %d", __func__, port->number); 969 dbg("%s - port %d", __func__, port->number);
944 970
945 spin_lock_irqsave(&priv->lock, flags); 971 spin_lock_irqsave(&priv->lock, flags);
@@ -958,7 +984,7 @@ static int cypress_tiocmset(struct tty_struct *tty, struct file *file,
958} 984}
959 985
960 986
961static int cypress_ioctl(struct tty_struct *tty, struct file * file, 987static int cypress_ioctl(struct tty_struct *tty, struct file *file,
962 unsigned int cmd, unsigned long arg) 988 unsigned int cmd, unsigned long arg)
963{ 989{
964 struct usb_serial_port *port = tty->driver_data; 990 struct usb_serial_port *port = tty->driver_data;
@@ -967,38 +993,37 @@ static int cypress_ioctl(struct tty_struct *tty, struct file * file,
967 dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); 993 dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
968 994
969 switch (cmd) { 995 switch (cmd) {
970 /* This code comes from drivers/char/serial.c and ftdi_sio.c */ 996 /* This code comes from drivers/char/serial.c and ftdi_sio.c */
971 case TIOCMIWAIT: 997 case TIOCMIWAIT:
972 while (priv != NULL) { 998 while (priv != NULL) {
973 interruptible_sleep_on(&priv->delta_msr_wait); 999 interruptible_sleep_on(&priv->delta_msr_wait);
974 /* see if a signal did it */ 1000 /* see if a signal did it */
975 if (signal_pending(current)) 1001 if (signal_pending(current))
976 return -ERESTARTSYS; 1002 return -ERESTARTSYS;
977 else { 1003 else {
978 char diff = priv->diff_status; 1004 char diff = priv->diff_status;
979 1005 if (diff == 0)
980 if (diff == 0) { 1006 return -EIO; /* no change => error */
981 return -EIO; /* no change => error */ 1007
982 } 1008 /* consume all events */
983 1009 priv->diff_status = 0;
984 /* consume all events */ 1010
985 priv->diff_status = 0; 1011 /* return 0 if caller wanted to know about
986 1012 these bits */
987 /* return 0 if caller wanted to know about these bits */ 1013 if (((arg & TIOCM_RNG) && (diff & UART_RI)) ||
988 if ( ((arg & TIOCM_RNG) && (diff & UART_RI)) || 1014 ((arg & TIOCM_DSR) && (diff & UART_DSR)) ||
989 ((arg & TIOCM_DSR) && (diff & UART_DSR)) || 1015 ((arg & TIOCM_CD) && (diff & UART_CD)) ||
990 ((arg & TIOCM_CD) && (diff & UART_CD)) || 1016 ((arg & TIOCM_CTS) && (diff & UART_CTS)))
991 ((arg & TIOCM_CTS) && (diff & UART_CTS)) ) { 1017 return 0;
992 return 0; 1018 /* otherwise caller can't care less about what
993 } 1019 * happened, and so we continue to wait for
994 /* otherwise caller can't care less about what happened, 1020 * more events.
995 * and so we continue to wait for more events. 1021 */
996 */
997 }
998 } 1022 }
999 return 0; 1023 }
1000 default: 1024 return 0;
1001 break; 1025 default:
1026 break;
1002 } 1027 }
1003 dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd); 1028 dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd);
1004 return -ENOIOCTLCMD; 1029 return -ENOIOCTLCMD;
@@ -1070,23 +1095,22 @@ static void cypress_set_termios(struct tty_struct *tty,
1070 1095
1071 if (cflag & CSIZE) { 1096 if (cflag & CSIZE) {
1072 switch (cflag & CSIZE) { 1097 switch (cflag & CSIZE) {
1073 case CS5: 1098 case CS5:
1074 data_bits = 0; 1099 data_bits = 0;
1075 break; 1100 break;
1076 case CS6: 1101 case CS6:
1077 data_bits = 1; 1102 data_bits = 1;
1078 break; 1103 break;
1079 case CS7: 1104 case CS7:
1080 data_bits = 2; 1105 data_bits = 2;
1081 break; 1106 break;
1082 case CS8: 1107 case CS8:
1083 data_bits = 3; 1108 data_bits = 3;
1084 break; 1109 break;
1085 default: 1110 default:
1086 err("%s - CSIZE was set, but not CS5-CS8", 1111 err("%s - CSIZE was set, but not CS5-CS8",
1087 __func__); 1112 __func__);
1088 data_bits = 3; 1113 data_bits = 3;
1089 }
1090 } else 1114 } else
1091 data_bits = 3; 1115 data_bits = 3;
1092 1116
@@ -1104,8 +1128,10 @@ static void cypress_set_termios(struct tty_struct *tty,
1104 "%d data_bits (+5)", __func__, stop_bits, 1128 "%d data_bits (+5)", __func__, stop_bits,
1105 parity_enable, parity_type, data_bits); 1129 parity_enable, parity_type, data_bits);
1106 1130
1107 cypress_serial_control(tty, port, tty_get_baud_rate(tty), data_bits, stop_bits, 1131 cypress_serial_control(tty, port, tty_get_baud_rate(tty),
1108 parity_enable, parity_type, 0, CYPRESS_SET_CONFIG); 1132 data_bits, stop_bits,
1133 parity_enable, parity_type,
1134 0, CYPRESS_SET_CONFIG);
1109 1135
1110 /* we perform a CYPRESS_GET_CONFIG so that the current settings are 1136 /* we perform a CYPRESS_GET_CONFIG so that the current settings are
1111 * filled into the private structure this should confirm that all is 1137 * filled into the private structure this should confirm that all is
@@ -1116,7 +1142,7 @@ static void cypress_set_termios(struct tty_struct *tty,
1116 * termios flag base comes from empeg.c */ 1142 * termios flag base comes from empeg.c */
1117 1143
1118 spin_lock_irqsave(&priv->lock, flags); 1144 spin_lock_irqsave(&priv->lock, flags);
1119 if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) { 1145 if (priv->chiptype == CT_EARTHMATE && priv->baud_rate == 4800) {
1120 dbg("Using custom termios settings for a baud rate of " 1146 dbg("Using custom termios settings for a baud rate of "
1121 "4800bps."); 1147 "4800bps.");
1122 /* define custom termios settings for NMEA protocol */ 1148 /* define custom termios settings for NMEA protocol */
@@ -1164,7 +1190,7 @@ static int cypress_chars_in_buffer(struct tty_struct *tty)
1164 unsigned long flags; 1190 unsigned long flags;
1165 1191
1166 dbg("%s - port %d", __func__, port->number); 1192 dbg("%s - port %d", __func__, port->number);
1167 1193
1168 spin_lock_irqsave(&priv->lock, flags); 1194 spin_lock_irqsave(&priv->lock, flags);
1169 chars = cypress_buf_data_avail(priv->buf); 1195 chars = cypress_buf_data_avail(priv->buf);
1170 spin_unlock_irqrestore(&priv->lock, flags); 1196 spin_unlock_irqrestore(&priv->lock, flags);
@@ -1243,12 +1269,13 @@ static void cypress_read_int_callback(struct urb *urb)
1243 /* precursor to disconnect so just go away */ 1269 /* precursor to disconnect so just go away */
1244 return; 1270 return;
1245 case -EPIPE: 1271 case -EPIPE:
1246 usb_clear_halt(port->serial->dev,0x81); 1272 usb_clear_halt(port->serial->dev, 0x81);
1247 break; 1273 break;
1248 default: 1274 default:
1249 /* something ugly is going on... */ 1275 /* something ugly is going on... */
1250 dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n", 1276 dev_err(&urb->dev->dev,
1251 __func__, status); 1277 "%s - unexpected nonzero read status received: %d\n",
1278 __func__, status);
1252 cypress_set_dead(port); 1279 cypress_set_dead(port);
1253 return; 1280 return;
1254 } 1281 }
@@ -1296,8 +1323,8 @@ static void cypress_read_int_callback(struct urb *urb)
1296 goto continue_read; 1323 goto continue_read;
1297 } 1324 }
1298 1325
1299 usb_serial_debug_data (debug, &port->dev, __func__, 1326 usb_serial_debug_data(debug, &port->dev, __func__,
1300 urb->actual_length, data); 1327 urb->actual_length, data);
1301 1328
1302 spin_lock_irqsave(&priv->lock, flags); 1329 spin_lock_irqsave(&priv->lock, flags);
1303 /* check to see if status has changed */ 1330 /* check to see if status has changed */
@@ -1356,7 +1383,8 @@ continue_read:
1356 port->interrupt_in_endpointAddress), 1383 port->interrupt_in_endpointAddress),
1357 port->interrupt_in_urb->transfer_buffer, 1384 port->interrupt_in_urb->transfer_buffer,
1358 port->interrupt_in_urb->transfer_buffer_length, 1385 port->interrupt_in_urb->transfer_buffer_length,
1359 cypress_read_int_callback, port, priv->read_urb_interval); 1386 cypress_read_int_callback, port,
1387 priv->read_urb_interval);
1360 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1388 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1361 if (result) { 1389 if (result) {
1362 dev_err(&urb->dev->dev, "%s - failed resubmitting " 1390 dev_err(&urb->dev->dev, "%s - failed resubmitting "
@@ -1380,42 +1408,43 @@ static void cypress_write_int_callback(struct urb *urb)
1380 dbg("%s - port %d", __func__, port->number); 1408 dbg("%s - port %d", __func__, port->number);
1381 1409
1382 switch (status) { 1410 switch (status) {
1383 case 0: 1411 case 0:
1384 /* success */ 1412 /* success */
1413 break;
1414 case -ECONNRESET:
1415 case -ENOENT:
1416 case -ESHUTDOWN:
1417 /* this urb is terminated, clean up */
1418 dbg("%s - urb shutting down with status: %d",
1419 __func__, status);
1420 priv->write_urb_in_use = 0;
1421 return;
1422 case -EPIPE: /* no break needed; clear halt and resubmit */
1423 if (!priv->comm_is_ok)
1385 break; 1424 break;
1386 case -ECONNRESET: 1425 usb_clear_halt(port->serial->dev, 0x02);
1387 case -ENOENT: 1426 /* error in the urb, so we have to resubmit it */
1388 case -ESHUTDOWN: 1427 dbg("%s - nonzero write bulk status received: %d",
1389 /* this urb is terminated, clean up */ 1428 __func__, status);
1390 dbg("%s - urb shutting down with status: %d", 1429 port->interrupt_out_urb->transfer_buffer_length = 1;
1391 __func__, status); 1430 port->interrupt_out_urb->dev = port->serial->dev;
1392 priv->write_urb_in_use = 0; 1431 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
1432 if (!result)
1393 return; 1433 return;
1394 case -EPIPE: /* no break needed; clear halt and resubmit */ 1434 dev_err(&urb->dev->dev,
1395 if (!priv->comm_is_ok) 1435 "%s - failed resubmitting write urb, error %d\n",
1396 break; 1436 __func__, result);
1397 usb_clear_halt(port->serial->dev, 0x02); 1437 cypress_set_dead(port);
1398 /* error in the urb, so we have to resubmit it */ 1438 break;
1399 dbg("%s - nonzero write bulk status received: %d", 1439 default:
1400 __func__, status); 1440 dev_err(&urb->dev->dev,
1401 port->interrupt_out_urb->transfer_buffer_length = 1; 1441 "%s - unexpected nonzero write status received: %d\n",
1402 port->interrupt_out_urb->dev = port->serial->dev; 1442 __func__, status);
1403 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); 1443 cypress_set_dead(port);
1404 if (!result) 1444 break;
1405 return;
1406 dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n",
1407 __func__, result);
1408 cypress_set_dead(port);
1409 break;
1410 default:
1411 dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n",
1412 __func__, status);
1413 cypress_set_dead(port);
1414 break;
1415 } 1445 }
1416
1417 priv->write_urb_in_use = 0; 1446 priv->write_urb_in_use = 0;
1418 1447
1419 /* send any buffered data */ 1448 /* send any buffered data */
1420 cypress_send(port); 1449 cypress_send(port);
1421} 1450}
@@ -1497,7 +1526,8 @@ static void cypress_buf_clear(struct cypress_buf *cb)
1497static unsigned int cypress_buf_data_avail(struct cypress_buf *cb) 1526static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
1498{ 1527{
1499 if (cb != NULL) 1528 if (cb != NULL)
1500 return ((cb->buf_size + cb->buf_put - cb->buf_get) % cb->buf_size); 1529 return (cb->buf_size + cb->buf_put - cb->buf_get)
1530 % cb->buf_size;
1501 else 1531 else
1502 return 0; 1532 return 0;
1503} 1533}
@@ -1513,7 +1543,8 @@ static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
1513static unsigned int cypress_buf_space_avail(struct cypress_buf *cb) 1543static unsigned int cypress_buf_space_avail(struct cypress_buf *cb)
1514{ 1544{
1515 if (cb != NULL) 1545 if (cb != NULL)
1516 return ((cb->buf_size + cb->buf_get - cb->buf_put - 1) % cb->buf_size); 1546 return (cb->buf_size + cb->buf_get - cb->buf_put - 1)
1547 % cb->buf_size;
1517 else 1548 else
1518 return 0; 1549 return 0;
1519} 1550}
@@ -1613,9 +1644,9 @@ static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf,
1613static int __init cypress_init(void) 1644static int __init cypress_init(void)
1614{ 1645{
1615 int retval; 1646 int retval;
1616 1647
1617 dbg("%s", __func__); 1648 dbg("%s", __func__);
1618 1649
1619 retval = usb_serial_register(&cypress_earthmate_device); 1650 retval = usb_serial_register(&cypress_earthmate_device);
1620 if (retval) 1651 if (retval)
1621 goto failed_em_register; 1652 goto failed_em_register;
@@ -1643,23 +1674,23 @@ failed_em_register:
1643} 1674}
1644 1675
1645 1676
1646static void __exit cypress_exit (void) 1677static void __exit cypress_exit(void)
1647{ 1678{
1648 dbg("%s", __func__); 1679 dbg("%s", __func__);
1649 1680
1650 usb_deregister (&cypress_driver); 1681 usb_deregister(&cypress_driver);
1651 usb_serial_deregister (&cypress_earthmate_device); 1682 usb_serial_deregister(&cypress_earthmate_device);
1652 usb_serial_deregister (&cypress_hidcom_device); 1683 usb_serial_deregister(&cypress_hidcom_device);
1653 usb_serial_deregister (&cypress_ca42v2_device); 1684 usb_serial_deregister(&cypress_ca42v2_device);
1654} 1685}
1655 1686
1656 1687
1657module_init(cypress_init); 1688module_init(cypress_init);
1658module_exit(cypress_exit); 1689module_exit(cypress_exit);
1659 1690
1660MODULE_AUTHOR( DRIVER_AUTHOR ); 1691MODULE_AUTHOR(DRIVER_AUTHOR);
1661MODULE_DESCRIPTION( DRIVER_DESC ); 1692MODULE_DESCRIPTION(DRIVER_DESC);
1662MODULE_VERSION( DRIVER_VERSION ); 1693MODULE_VERSION(DRIVER_VERSION);
1663MODULE_LICENSE("GPL"); 1694MODULE_LICENSE("GPL");
1664 1695
1665module_param(debug, bool, S_IRUGO | S_IWUSR); 1696module_param(debug, bool, S_IRUGO | S_IWUSR);
diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h
index 0388065bb794..e772b01ac3ac 100644
--- a/drivers/usb/serial/cypress_m8.h
+++ b/drivers/usb/serial/cypress_m8.h
@@ -54,7 +54,7 @@
54#define UART_DSR 0x20 /* data set ready - flow control - device to host */ 54#define UART_DSR 0x20 /* data set ready - flow control - device to host */
55#define CONTROL_RTS 0x10 /* request to send - flow control - host to device */ 55#define CONTROL_RTS 0x10 /* request to send - flow control - host to device */
56#define UART_CTS 0x10 /* clear to send - flow control - device to host */ 56#define UART_CTS 0x10 /* clear to send - flow control - device to host */
57#define UART_RI 0x10 /* ring indicator - modem - device to host */ 57#define UART_RI 0x10 /* ring indicator - modem - device to host */
58#define UART_CD 0x40 /* carrier detect - modem - device to host */ 58#define UART_CD 0x40 /* carrier detect - modem - device to host */
59#define CYP_ERROR 0x08 /* received from input report - device to host */ 59#define CYP_ERROR 0x08 /* received from input report - device to host */
60/* Note - the below has nothing to to with the "feature report" reset */ 60/* Note - the below has nothing to to with the "feature report" reset */