aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/cypress_m8.c
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2006-08-29 23:06:59 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-27 14:58:58 -0400
commit0257fa9ffe4f0287a9d90476bb733cfc2272396e (patch)
tree323e08e486099d996be410e36a4d7ba927688956 /drivers/usb/serial/cypress_m8.c
parent13f4db9e1bf0a6efcdbbb3a1e4da8a1a8c620fff (diff)
cypress_m8: use appropriate URB polling interval
The polling interval for the device can't always be 1msec. If it is too quick, the device can fail causing a fatal (to the driver) EILSEQ error from the USB core. The actual correct value is reported by the device as part of its configuration data, so use that value as the default. On a DeLorme Earthmate for example, the device reports that it wants a 6msec interval. As part of this fix, the "interval" module option has been fixed as well; the device's default can be overridden by specifying interval=<value> as a module option. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/cypress_m8.c')
-rw-r--r--drivers/usb/serial/cypress_m8.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index ee70fddcab60..40cfbe1d3517 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -129,6 +129,8 @@ struct cypress_private {
129 int cmd_ctrl; /* always set this to 1 before issuing a command */ 129 int cmd_ctrl; /* always set this to 1 before issuing a command */
130 struct cypress_buf *buf; /* write buffer */ 130 struct cypress_buf *buf; /* write buffer */
131 int write_urb_in_use; /* write urb in use indicator */ 131 int write_urb_in_use; /* write urb in use indicator */
132 int write_urb_interval; /* interval to use for write urb */
133 int read_urb_interval; /* interval to use for read urb */
132 int termios_initialized; 134 int termios_initialized;
133 __u8 line_control; /* holds dtr / rts value */ 135 __u8 line_control; /* holds dtr / rts value */
134 __u8 current_status; /* received from last read - info on dsr,cts,cd,ri,etc */ 136 __u8 current_status; /* received from last read - info on dsr,cts,cd,ri,etc */
@@ -472,8 +474,9 @@ static unsigned rate_to_mask (int rate)
472static int generic_startup (struct usb_serial *serial) 474static int generic_startup (struct usb_serial *serial)
473{ 475{
474 struct cypress_private *priv; 476 struct cypress_private *priv;
477 struct usb_serial_port *port = serial->port[0];
475 478
476 dbg("%s - port %d", __FUNCTION__, serial->port[0]->number); 479 dbg("%s - port %d", __FUNCTION__, port->number);
477 480
478 priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL); 481 priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL);
479 if (!priv) 482 if (!priv)
@@ -489,13 +492,24 @@ static int generic_startup (struct usb_serial *serial)
489 492
490 usb_reset_configuration (serial->dev); 493 usb_reset_configuration (serial->dev);
491 494
492 interval = 1;
493 priv->cmd_ctrl = 0; 495 priv->cmd_ctrl = 0;
494 priv->line_control = 0; 496 priv->line_control = 0;
495 priv->termios_initialized = 0; 497 priv->termios_initialized = 0;
496 priv->rx_flags = 0; 498 priv->rx_flags = 0;
497 priv->cbr_mask = B300; 499 priv->cbr_mask = B300;
498 usb_set_serial_port_data(serial->port[0], priv); 500 if (interval > 0) {
501 priv->write_urb_interval = interval;
502 priv->read_urb_interval = interval;
503 dbg("%s - port %d read & write intervals forced to %d",
504 __FUNCTION__,port->number,interval);
505 } else {
506 priv->write_urb_interval = port->interrupt_out_urb->interval;
507 priv->read_urb_interval = port->interrupt_in_urb->interval;
508 dbg("%s - port %d intervals: read=%d write=%d",
509 __FUNCTION__,port->number,
510 priv->read_urb_interval,priv->write_urb_interval);
511 }
512 usb_set_serial_port_data(port, priv);
499 513
500 return 0; 514 return 0;
501} 515}
@@ -624,7 +638,7 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
624 usb_fill_int_urb(port->interrupt_in_urb, serial->dev, 638 usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
625 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), 639 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
626 port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length, 640 port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length,
627 cypress_read_int_callback, port, interval); 641 cypress_read_int_callback, port, priv->read_urb_interval);
628 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 642 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
629 643
630 if (result){ 644 if (result){
@@ -808,7 +822,7 @@ send:
808 822
809 port->interrupt_out_urb->transfer_buffer_length = actual_size; 823 port->interrupt_out_urb->transfer_buffer_length = actual_size;
810 port->interrupt_out_urb->dev = port->serial->dev; 824 port->interrupt_out_urb->dev = port->serial->dev;
811 port->interrupt_out_urb->interval = interval; 825 port->interrupt_out_urb->interval = priv->write_urb_interval;
812 result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC); 826 result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
813 if (result) { 827 if (result) {
814 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, 828 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__,
@@ -1349,7 +1363,7 @@ continue_read:
1349 port->interrupt_in_endpointAddress), 1363 port->interrupt_in_endpointAddress),
1350 port->interrupt_in_urb->transfer_buffer, 1364 port->interrupt_in_urb->transfer_buffer,
1351 port->interrupt_in_urb->transfer_buffer_length, 1365 port->interrupt_in_urb->transfer_buffer_length,
1352 cypress_read_int_callback, port, interval); 1366 cypress_read_int_callback, port, priv->read_urb_interval);
1353 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1367 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1354 if (result) 1368 if (result)
1355 dev_err(&urb->dev->dev, "%s - failed resubmitting " 1369 dev_err(&urb->dev->dev, "%s - failed resubmitting "