ChangeSet 1.1504.2.29, 2003/12/09 17:48:19-08:00, [EMAIL PROTECTED] [PATCH] USB: sleeping problems in cyberjack driver
this driver has locking problems. Here's the first round of fixes for the obvious cases. - it makes clear differences between completion handlers and task context - it fixes cases of sleeping in interrupt drivers/usb/serial/cyberjack.c | 25 +++++++++++-------------- 1 files changed, 11 insertions(+), 14 deletions(-) diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c --- a/drivers/usb/serial/cyberjack.c Mon Dec 29 14:23:45 2003 +++ b/drivers/usb/serial/cyberjack.c Mon Dec 29 14:23:45 2003 @@ -295,7 +295,6 @@ { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); - unsigned long flags; struct usb_serial *serial; unsigned char *data = urb->transfer_buffer; int result; @@ -323,13 +322,13 @@ /* This is a announcement of coming bulk_ins. */ unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3; - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); old_rdtodo = priv->rdtodo; if( (old_rdtodo+size)<(old_rdtodo) ) { dbg( "To many bulk_in urbs to do." ); - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); goto resubmit; } @@ -338,11 +337,11 @@ dbg("%s - rdtodo: %d", __FUNCTION__, priv->rdtodo); - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); if( !old_rdtodo ) { port->read_urb->dev = port->serial->dev; - result = usb_submit_urb(port->read_urb, GFP_KERNEL); + result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if( result ) err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); dbg("%s - usb_submit_urb(read urb)", __FUNCTION__); @@ -351,7 +350,7 @@ resubmit: port->interrupt_in_urb->dev = port->serial->dev; - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result) err(" usb_submit_urb(read int) failed"); dbg("%s - usb_submit_urb(int urb)", __FUNCTION__); @@ -361,7 +360,6 @@ { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); - unsigned long flags; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; @@ -397,7 +395,7 @@ tty_flip_buffer_push(tty); } - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); /* Reduce urbs to do by one. */ priv->rdtodo-=urb->actual_length; @@ -405,14 +403,14 @@ if ( priv->rdtodo<0 ) priv->rdtodo = 0; todo = priv->rdtodo; - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); dbg("%s - rdtodo: %d", __FUNCTION__, todo); /* Continue to read if we have still urbs to do. */ if( todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) { port->read_urb->dev = port->serial->dev; - result = usb_submit_urb(port->read_urb, GFP_KERNEL); + result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); dbg("%s - usb_submit_urb(read urb)", __FUNCTION__); @@ -423,7 +421,6 @@ { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); - unsigned long flags; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); dbg("%s - port %d", __FUNCTION__, port->number); @@ -438,7 +435,7 @@ return; } - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); /* only do something if we have more data to send */ if( priv->wrfilled ) { @@ -446,7 +443,7 @@ if (port->write_urb->status == -EINPROGRESS) { dbg("%s - already writing", __FUNCTION__); - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); return; } @@ -492,7 +489,7 @@ } exit: - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); schedule_work(&port->work); } ------------------------------------------------------- This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id78&alloc_id371&op=click _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel