patch-2.4.0-test11 linux/drivers/usb/serial/digi_acceleport.c
Next file: linux/drivers/usb/serial/ftdi_sio.c
Previous file: linux/drivers/usb/serial/belkin_sa.h
Back to the patch index
Back to the overall index
- Lines: 237
- Date:
Sat Nov 11 19:06:01 2000
- Orig file:
v2.4.0-test10/linux/drivers/usb/serial/digi_acceleport.c
- Orig date:
Tue Oct 31 12:42:27 2000
diff -u --recursive --new-file v2.4.0-test10/linux/drivers/usb/serial/digi_acceleport.c linux/drivers/usb/serial/digi_acceleport.c
@@ -1,5 +1,5 @@
/*
-* Digi AccelePort USB-4 Serial Converter
+* Digi AccelePort USB-4 and USB-2 Serial Converters
*
* Copyright 2000 by Digi International
*
@@ -14,6 +14,16 @@
* Peter Berger (pberger@brimson.com)
* Al Borchers (borchers@steinerpoint.com)
*
+* (11/01/2000) Adam J. Richter
+* usb_device_id table support
+*
+* (11/01/2000) pberger and borchers
+* -- Turned off the USB_DISABLE_SPD flag for write bulk urbs--it caused
+* USB 4 ports to hang on startup.
+* -- Serialized access to write urbs by adding the dp_write_urb_in_use
+* flag; otherwise, the driver caused SMP system hangs. Watching the
+* urb status is not sufficient.
+*
* (10/05/2000) gkh
* -- Fixed bug with urb->dev not being set properly, now that the usb
* core needs it.
@@ -213,7 +223,7 @@
* - Following Documentation/DocBook/kernel-locking.pdf no spin locks
* are held when calling copy_to/from_user or printk.
*
-* $Id: digi_acceleport.c,v 1.80 2000/08/09 06:36:18 root Exp $
+* $Id: digi_acceleport.c,v 1.80.1.2 2000/11/02 05:45:08 root Exp $
*/
#include <linux/config.h>
@@ -411,6 +421,7 @@
int dp_in_buf_len;
unsigned char dp_in_buf[DIGI_IN_BUF_SIZE];
unsigned char dp_in_flag_buf[DIGI_IN_BUF_SIZE];
+ int dp_write_urb_in_use;
unsigned int dp_modem_signals;
wait_queue_head_t dp_modem_change_wait;
int dp_open_count; /* inc on open, dec on close */
@@ -461,15 +472,29 @@
/* Statics */
+static __devinitdata struct usb_device_id id_table_combined [] = {
+ { idVendor: DIGI_VENDOR_ID, idProduct: DIGI_2_ID },
+ { idVendor: DIGI_VENDOR_ID, idProduct: DIGI_4_ID },
+ { } /* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id id_table_2 [] = {
+ { idVendor: DIGI_VENDOR_ID, idProduct: DIGI_2_ID },
+ { } /* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id id_table_4 [] = {
+ { idVendor: DIGI_VENDOR_ID, idProduct: DIGI_4_ID },
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, id_table_combined);
+
/* device info needed for the Digi serial converter */
-static u16 digi_vendor_id = DIGI_VENDOR_ID;
-static u16 digi_product_2_id = DIGI_2_ID; /* USB 2 */
-static u16 digi_product_4_id = DIGI_4_ID; /* USB 4 */
static struct usb_serial_device_type digi_acceleport_2_device = {
name: "Digi USB",
- idVendor: &digi_vendor_id,
- idProduct: &digi_product_2_id,
+ id_table: id_table_2,
needs_interrupt_in: DONT_CARE,
needs_bulk_in: MUST_HAVE,
needs_bulk_out: MUST_HAVE,
@@ -495,8 +520,7 @@
static struct usb_serial_device_type digi_acceleport_4_device = {
name: "Digi USB",
- idVendor: &digi_vendor_id,
- idProduct: &digi_product_4_id,
+ id_table: id_table_4,
needs_interrupt_in: DONT_CARE,
needs_bulk_in: MUST_HAVE,
needs_bulk_out: MUST_HAVE,
@@ -629,7 +653,8 @@
while( count > 0 ) {
- while( oob_port->write_urb->status == -EINPROGRESS ) {
+ while( oob_port->write_urb->status == -EINPROGRESS
+ || oob_priv->dp_write_urb_in_use ) {
cond_wait_interruptible_timeout_irqrestore(
&oob_port->write_wait, DIGI_RETRY_TIMEOUT,
&oob_priv->dp_port_lock, flags );
@@ -647,8 +672,9 @@
memcpy( oob_port->write_urb->transfer_buffer, buf, len );
oob_port->write_urb->transfer_buffer_length = len;
oob_port->write_urb->dev = port->serial->dev;
-
+
if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) {
+ oob_priv->dp_write_urb_in_use = 1;
count -= len;
buf += len;
}
@@ -702,8 +728,8 @@
while( count > 0 && ret == 0 ) {
- while( port->write_urb->status == -EINPROGRESS
- && jiffies < timeout ) {
+ while( (port->write_urb->status == -EINPROGRESS
+ || priv->dp_write_urb_in_use) && jiffies < timeout ) {
cond_wait_interruptible_timeout_irqrestore(
&port->write_wait, DIGI_RETRY_TIMEOUT,
&priv->dp_port_lock, flags );
@@ -736,6 +762,7 @@
port->write_urb->dev = port->serial->dev;
if( (ret=usb_submit_urb(port->write_urb)) == 0 ) {
+ priv->dp_write_urb_in_use = 1;
priv->dp_out_buf_len = 0;
count -= len;
buf += len;
@@ -783,7 +810,8 @@
spin_lock_irqsave( &oob_priv->dp_port_lock, flags );
spin_lock( &port_priv->dp_port_lock );
- while( oob_port->write_urb->status == -EINPROGRESS ) {
+ while( oob_port->write_urb->status == -EINPROGRESS
+ || oob_priv->dp_write_urb_in_use ) {
spin_unlock( &port_priv->dp_port_lock );
cond_wait_interruptible_timeout_irqrestore(
&oob_port->write_wait, DIGI_RETRY_TIMEOUT,
@@ -811,6 +839,7 @@
oob_port->write_urb->dev = port->serial->dev;
if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) {
+ oob_priv->dp_write_urb_in_use = 1;
port_priv->dp_modem_signals =
(port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS))
| (modem_signals&(TIOCM_DTR|TIOCM_RTS));
@@ -1249,7 +1278,8 @@
spin_lock_irqsave( &priv->dp_port_lock, flags );
/* wait for urb status clear to submit another urb */
- if( port->write_urb->status == -EINPROGRESS ) {
+ if( port->write_urb->status == -EINPROGRESS
+ || priv->dp_write_urb_in_use ) {
/* buffer data if count is 1 (probably put_char) if possible */
if( count == 1 ) {
@@ -1292,6 +1322,7 @@
memcpy( data, from_user ? user_buf : buf, new_len );
if( (ret=usb_submit_urb(port->write_urb)) == 0 ) {
+ priv->dp_write_urb_in_use = 1;
ret = new_len;
priv->dp_out_buf_len = 0;
}
@@ -1337,6 +1368,7 @@
== ((digi_serial_t *)(serial->private))->ds_oob_port_num ) {
dbg( "digi_write_bulk_callback: oob callback" );
spin_lock( &priv->dp_port_lock );
+ priv->dp_write_urb_in_use = 0;
wake_up_interruptible( &port->write_wait );
spin_unlock( &priv->dp_port_lock );
return;
@@ -1349,6 +1381,7 @@
/* try to send any buffered data on this port, if it is open */
spin_lock( &priv->dp_port_lock );
+ priv->dp_write_urb_in_use = 0;
if( priv->dp_open_count && port->write_urb->status != -EINPROGRESS
&& priv->dp_out_buf_len > 0 ) {
@@ -1365,6 +1398,7 @@
priv->dp_out_buf_len );
if( (ret=usb_submit_urb(port->write_urb)) == 0 ) {
+ priv->dp_write_urb_in_use = 1;
priv->dp_out_buf_len = 0;
}
@@ -1397,7 +1431,8 @@
spin_lock_irqsave( &priv->dp_port_lock, flags );
- if( port->write_urb->status == -EINPROGRESS )
+ if( port->write_urb->status == -EINPROGRESS
+ || priv->dp_write_urb_in_use )
room = 0;
else
room = port->bulk_out_size - 2 - priv->dp_out_buf_len;
@@ -1416,7 +1451,8 @@
digi_port_t *priv = (digi_port_t *)(port->private);
- if( port->write_urb->status == -EINPROGRESS ) {
+ if( port->write_urb->status == -EINPROGRESS
+ || priv->dp_write_urb_in_use ) {
dbg( "digi_chars_in_buffer: port=%d, chars=%d", priv->dp_port_num, port->bulk_out_size - 2 );
/* return( port->bulk_out_size - 2 ); */
return( 256 );
@@ -1601,6 +1637,7 @@
spin_lock_irqsave( &priv->dp_port_lock, flags );
port->active = 0;
+ priv->dp_write_urb_in_use = 0;
priv->dp_in_close = 0;
--priv->dp_open_count;
MOD_DEC_USE_COUNT;
@@ -1641,7 +1678,6 @@
port = &serial->port[i];
- port->write_urb->transfer_flags |= USB_DISABLE_SPD;
port->write_urb->dev = port->serial->dev;
if( (ret=usb_submit_urb(port->read_urb)) != 0 ) {
@@ -1689,6 +1725,7 @@
priv->dp_port_num = i;
priv->dp_out_buf_len = 0;
priv->dp_in_buf_len = 0;
+ priv->dp_write_urb_in_use = 0;
priv->dp_modem_signals = 0;
init_waitqueue_head( &priv->dp_modem_change_wait );
priv->dp_open_count = 0;
@@ -2047,5 +2084,5 @@
MODULE_AUTHOR("Peter Berger <pberger@brimson.com>, Al Borchers <borchers@steinerpoint.com>");
-MODULE_DESCRIPTION("Digi AccelePort USB-4 Serial Converter driver");
+MODULE_DESCRIPTION("Digi AccelePort USB-2/USB-4 Serial Converter driver");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)