Hi!

Here I have this patch ported from a 2.4 verison of a patch by guy at
Dell ([EMAIL PROTECTED]), that uses the serialize semaphore in devio.c
and in usb-storage.

This is needed on storage devices, where even sending a harmless
GET_DESCRIPTOR command at the wrong time will lead to a STALL condition,
and make the device unusable.

Because many a hotplug script does exactly that, it's rather easy to get
a non-working device.

I hope this use of the serialize semaphore is correct - at least it
looks OK to me.

diff -urN linux-2.6.5/drivers/usb/core/devio.c 
linux-2.6.5-dell/drivers/usb/core/devio.c
--- linux-2.6.5/drivers/usb/core/devio.c        2004-05-20 15:05:10.000000000 +0200
+++ linux-2.6.5-dell/drivers/usb/core/devio.c   2004-05-20 15:13:33.000000000 +0200
@@ -1205,6 +1205,12 @@
                up_read(&ps->devsem);
                return -ENODEV;
        }
+       /*
+        * grab device's serialize mutex to prevent driver from
+        * using this device while it is being accessed by us
+        */
+       down (&(ps->dev->serialize));
+
        switch (cmd) {
        case USBDEVFS_CONTROL:
                ret = proc_control(ps, (void __user *)arg);
@@ -1284,6 +1290,7 @@
                ret = proc_ioctl(ps, (void __user *) arg);
                break;
        }
+       up (&(ps->dev->serialize));
        up_read(&ps->devsem);
        if (ret >= 0)
                inode->i_atime = CURRENT_TIME;
diff -urN linux-2.6.5/drivers/usb/storage/transport.c 
linux-2.6.5-dell/drivers/usb/storage/transport.c
--- linux-2.6.5/drivers/usb/storage/transport.c 2004-05-20 15:05:08.000000000 +0200
+++ linux-2.6.5-dell/drivers/usb/storage/transport.c    2004-05-20 15:16:07.000000000 
+0200
@@ -527,9 +527,18 @@
        int need_auto_sense;
        int result;
 
+       /*
+        * Grab device's serialize mutex to prevent /usbfs and others from
+        * sending out a command in the middle of ours (if libusb sends a
+        * get_descriptor or something on pipe 0 after our CBW and before
+        * our CSW, and then we get a stall, we have trouble)
+        */
+
        /* send the command to the transport layer */
+       down (&(us->pusb_dev->serialize));
        srb->resid = 0;
        result = us->transport(srb, us);
+       up (&(us->pusb_dev->serialize));
 
        /* if the command gets aborted by the higher layers, we need to
         * short-circuit all other processing
@@ -648,9 +657,11 @@
                srb->serial_number ^= 0x80000000;
 
                /* issue the auto-sense command */
+               down (&(us->pusb_dev->serialize));
                old_resid = srb->resid;
                srb->resid = 0;
                temp_result = us->transport(us->srb, us);
+               up (&(us->pusb_dev->serialize));
 
                /* let's clean up right away */
                srb->resid = old_resid;


-- 
Vojtech Pavlik
SuSE Labs, SuSE CR


-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. 
Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&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