ChangeSet 1.1254.1.77, 2003/06/01 23:00:01-07:00, [EMAIL PROTECTED]

[PATCH] USB: usb-storage: usb_stor_control_msg() and stuff

This patch replaces usb_control_msg() with usb_stor_control_msg() everywhere,
which allows better abort/disconnect processing.

Some comments are fixed-up.

The GetMaxLUN function is moved later so URBs are initialized (now that it
uses the new control_msg() ).

There is also some locking cleanup during reset.


 drivers/usb/storage/freecom.c      |    6 ++---
 drivers/usb/storage/initializers.c |    2 -
 drivers/usb/storage/initializers.h |    1 
 drivers/usb/storage/scsiglue.c     |   40 +++++++++++++++++++++++--------------
 drivers/usb/storage/transport.c    |   11 ++++------
 drivers/usb/storage/usb.c          |   13 ++++++++----
 6 files changed, 44 insertions(+), 29 deletions(-)


diff -Nru a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
--- a/drivers/usb/storage/freecom.c     Mon Jun  2 11:20:17 2003
+++ b/drivers/usb/storage/freecom.c     Mon Jun  2 11:20:17 2003
@@ -399,7 +399,7 @@
                }
        }
 
-       result = usb_control_msg(us->pusb_dev, us->recv_ctrl_pipe,
+       result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
                        0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20, 3*HZ);
        buffer[32] = '\0';
        US_DEBUGP("String returned from FC init is: %s\n", buffer);
@@ -411,7 +411,7 @@
         */
 
        /* send reset */
-       result = usb_control_msg(us->pusb_dev, us->send_ctrl_pipe,
+       result = usb_stor_control_msg(us, us->send_ctrl_pipe,
                        0x4d, 0x40, 0x24d8, 0x0, NULL, 0x0, 3*HZ);
        US_DEBUGP("result from activate reset is %d\n", result);
 
@@ -419,7 +419,7 @@
        mdelay(250);
 
        /* clear reset */
-       result = usb_control_msg(us->pusb_dev, us->send_ctrl_pipe,
+       result = usb_stor_control_msg(us, us->send_ctrl_pipe,
                        0x4d, 0x40, 0x24f8, 0x0, NULL, 0x0, 3*HZ);
        US_DEBUGP("result from clear reset is %d\n", result);
 
diff -Nru a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c
--- a/drivers/usb/storage/initializers.c        Mon Jun  2 11:20:17 2003
+++ b/drivers/usb/storage/initializers.c        Mon Jun  2 11:20:17 2003
@@ -50,7 +50,7 @@
        int result;
 
        US_DEBUGP("Attempting to init eUSCSI bridge...\n");
-       result = usb_control_msg(us->pusb_dev, us->send_ctrl_pipe,
+       result = usb_stor_control_msg(us, us->send_ctrl_pipe,
                        0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR,
                        0x01, 0x0, &data, 0x1, 5*HZ);
        US_DEBUGP("-- result is %d\n", result);
diff -Nru a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h
--- a/drivers/usb/storage/initializers.h        Mon Jun  2 11:20:17 2003
+++ b/drivers/usb/storage/initializers.h        Mon Jun  2 11:20:17 2003
@@ -39,6 +39,7 @@
 
 #include <linux/config.h>
 #include "usb.h"
+#include "transport.h"
 
 /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
  * mode */
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c    Mon Jun  2 11:20:17 2003
+++ b/drivers/usb/storage/scsiglue.c    Mon Jun  2 11:20:17 2003
@@ -219,7 +219,7 @@
        int state = atomic_read(&us->sm_state);
        int result;
 
-       US_DEBUGP("device_reset() called\n" );
+       US_DEBUGP("%s called\n", __FUNCTION__);
        if (state != US_STATE_IDLE) {
                printk(KERN_ERR USB_STORAGE "Error in %s: "
                        "invalid state %d\n", __FUNCTION__, state);
@@ -245,39 +245,49 @@
        return result;
 }
 
-/* This resets the device port */
+/* This resets the device's USB port. */
 /* It refuses to work if there's more than one interface in
-   this device, so that other users are not affected. */
+ * the device, so that other users are not affected. */
 /* This is always called with scsi_lock(srb->host) held */
-
 static int usb_storage_bus_reset( Scsi_Cmnd *srb )
 {
-       struct us_data *us;
+       struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
+       int state = atomic_read(&us->sm_state);
        int result;
 
-       /* we use the usb_reset_device() function to handle this for us */
-       US_DEBUGP("bus_reset() called\n");
+       US_DEBUGP("%s called\n", __FUNCTION__);
+       if (state != US_STATE_IDLE) {
+               printk(KERN_ERR USB_STORAGE "Error in %s: "
+                       "invalid state %d\n", __FUNCTION__, state);
+               return FAILED;
+       }
+
+       /* set the state and release the lock */
+       atomic_set(&us->sm_state, US_STATE_RESETTING);
        scsi_unlock(srb->device->host);
-       us = (struct us_data *)srb->device->host->hostdata[0];
 
        /* The USB subsystem doesn't handle synchronisation between
           a device's several drivers. Therefore we reset only devices
-          with one interface which we of course own.
+          with just one interface, which we of course own.
        */
-       
+
        //FIXME: needs locking against config changes
-       
-       if ( us->pusb_dev->actconfig->desc.bNumInterfaces == 1) {
-               /* attempt to reset the port */
+
+       if (us->pusb_dev->actconfig->desc.bNumInterfaces == 1) {
+
+               /* lock the device and attempt to reset the port */
+               down(&(us->dev_semaphore));
                result = usb_reset_device(us->pusb_dev);
+               up(&(us->dev_semaphore));
                US_DEBUGP("usb_reset_device returns %d\n", result);
        } else {
                result = -EBUSY;
-               US_DEBUGP("cannot reset a multiinterface device. failing to reset.\n");
+               US_DEBUGP("Refusing to reset a multi-interface device\n");
        }
 
-       US_DEBUGP("bus_reset() complete\n");
+       /* lock access to the state and clear it */
        scsi_lock(srb->device->host);
+       atomic_set(&us->sm_state, US_STATE_IDLE);
        return result < 0 ? FAILED : SUCCESS;
 }
 
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c   Mon Jun  2 11:20:17 2003
+++ b/drivers/usb/storage/transport.c   Mon Jun  2 11:20:17 2003
@@ -875,11 +875,8 @@
        unsigned char data;
        int result;
 
-       /* Issue the command -- use usb_control_msg() because this is
-        * not a scsi queued-command.  Also note that at this point the
-        * cached pipe values have not yet been stored. */
-       result = usb_control_msg(us->pusb_dev,
-                                usb_rcvctrlpipe(us->pusb_dev, 0),
+       /* issue the command */
+       result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
                                 US_BULK_GET_MAX_LUN, 
                                 USB_DIR_IN | USB_TYPE_CLASS | 
                                 USB_RECIP_INTERFACE,
@@ -1027,10 +1024,12 @@
                return FAILED;
        }
 
-       /* long wait for reset */
+       /* long wait for reset, so unlock to allow disconnects */
+       up(&us->dev_semaphore);
        set_current_state(TASK_UNINTERRUPTIBLE);
        schedule_timeout(HZ*6);
        set_current_state(TASK_RUNNING);
+       down(&us->dev_semaphore);
 
        US_DEBUGP("Soft reset: clearing bulk-in endpoint halt\n");
        result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c Mon Jun  2 11:20:17 2003
+++ b/drivers/usb/storage/usb.c Mon Jun  2 11:20:17 2003
@@ -412,9 +412,11 @@
                        US_DEBUGP("scsi command aborted\n");
                }
 
-               /* in case an abort request was received after the command
-                * completed, we must use a separate test to see whether
-                * we need to signal that the abort has finished */
+               /* If an abort request was received we need to signal that
+                * the abort has finished.  The proper test for this is
+                * sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT,
+                * because an abort request might be received after all the
+                * USB processing was complete. */
                if (atomic_read(&us->sm_state) == US_STATE_ABORTING)
                        complete(&(us->notify));
 
@@ -715,7 +717,6 @@
                us->transport_name = "Bulk";
                us->transport = usb_stor_Bulk_transport;
                us->transport_reset = usb_stor_Bulk_reset;
-               us->max_lun = usb_stor_Bulk_max_lun(us);
                break;
 
 #ifdef CONFIG_USB_STORAGE_HP8200e
@@ -841,6 +842,10 @@
        /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
        if (usb_stor_allocate_urbs(us))
                goto BadDevice;
+
+       /* For bulk-only devices, determine the max LUN value */
+       if (us->protocol == US_PR_BULK)
+               us->max_lun = usb_stor_Bulk_max_lun(us);
 
        /*
         * Since this is a new device, we need to generate a scsi 



-------------------------------------------------------
This SF.net email is sponsored by: eBay
Get office equipment for less on eBay!
http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to