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

Reply via email to