On Sat, May 29, 2004 at 03:23:09PM +0200, Oliver Neukum wrote:

> > 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,

> It seems to me that you should hold the semaphore until after the reset
> of the error case. You are dropping it too early.
 
Ok, how about this one?

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR
[EMAIL PROTECTED], 2004-05-29 16:11:29+02:00, [EMAIL PROTECTED]
  usb: Based on a 2.4 patch from [EMAIL PROTECTED], this patch
       serializes usb storage and usbfs operation, so that usbfs
       cannot disturb storage by seemingly harmless control reads.
  
  Signed-off-by: Vojtech Pavlik <[EMAIL PROTECTED]>


 core/devio.c        |    3 +++
 storage/transport.c |   20 ++++++++++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)


diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c  2004-05-29 16:12:46 +02:00
+++ b/drivers/usb/core/devio.c  2004-05-29 16:12:46 +02:00
@@ -1184,6 +1184,8 @@
                return -ENODEV;
        }
 
+       down(&(ps->dev->serialize));
+
        switch (cmd) {
        case USBDEVFS_CONTROL:
                snoop(&dev->dev, "%s: CONTROL\n", __FUNCTION__);
@@ -1280,6 +1282,7 @@
                ret = proc_ioctl(ps, (void __user *) arg);
                break;
        }
+       up(&(ps->dev->serialize));
        up(&dev->serialize);
        if (ret >= 0)
                inode->i_atime = CURRENT_TIME;
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c   2004-05-29 16:12:46 +02:00
+++ b/drivers/usb/storage/transport.c   2004-05-29 16:12:46 +02:00
@@ -527,6 +527,15 @@
        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)
+        */
+
+       down (&(us->pusb_dev->serialize));
+
        /* send the command to the transport layer */
        srb->resid = 0;
        result = us->transport(srb, us);
@@ -544,13 +553,13 @@
                US_DEBUGP("-- transport indicates error, resetting\n");
                us->transport_reset(us);
                srb->result = DID_ERROR << 16;
-               return;
+               goto End_Transport;
        }
 
        /* if the transport provided its own sense data, don't auto-sense */
        if (result == USB_STOR_TRANSPORT_NO_SENSE) {
                srb->result = SAM_STAT_CHECK_CONDITION;
-               return;
+               goto End_Transport;
        }
 
        srb->result = SAM_STAT_GOOD;
@@ -676,7 +685,7 @@
                        if (!(us->flags & US_FL_SCM_MULT_TARG))
                                us->transport_reset(us);
                        srb->result = DID_ERROR << 16;
-                       return;
+                       goto End_Transport;
                }
 
                US_DEBUGP("-- Result from auto-sense is %d\n", temp_result);
@@ -708,7 +717,7 @@
                        srb->sense_buffer[0] = 0x0;
                }
        }
-       return;
+       goto End_Transport;
 
        /* abort processing: the bulk-only transport requires a reset
         * following an abort */
@@ -716,6 +725,9 @@
        srb->result = DID_ABORT << 16;
        if (us->protocol == US_PR_BULK)
                us->transport_reset(us);
+
+  End_Transport:
+       up(&(us->pusb_dev->serialize));
 }
 
 /* Stop the current URB transfer */
Signed-off-by: Vojtech Pavlik <[EMAIL PROTECTED]>

Reply via email to