uas_unlink_data_urbs uses this to make sure the the scsi command is
not released while looking at it.  This will be needed when we start
calling uas_unlink_data_urbs in the request cancel code paths.

Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
---
 drivers/usb/storage/uas.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index c348afa..1ebe974 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -66,6 +66,7 @@ enum {
        DATA_OUT_URB_INFLIGHT   = (1 << 10),
        COMMAND_COMPLETED       = (1 << 11),
        COMMAND_ABORTED         = (1 << 12),
+       UNLINK_DATA_URBS        = (1 << 13),
 };
 
 /* Overrides scsi_pointer */
@@ -92,7 +93,13 @@ static void uas_unlink_data_urbs(struct uas_dev_info 
*devinfo,
 {
        unsigned long flags;
 
+       /*
+        * The UNLINK_DATA_URBS flag makes sure uas_try_complete
+        * (called by urb completion) doesn't release cmdinfo
+        * underneath us.
+        */
        spin_lock_irqsave(&devinfo->lock, flags);
+       cmdinfo->state |= UNLINK_DATA_URBS;
        if (cmdinfo->state & DATA_IN_URB_INFLIGHT) {
                spin_unlock_irqrestore(&devinfo->lock, flags);
                usb_unlink_urb(cmdinfo->data_in_urb);
@@ -103,6 +110,7 @@ static void uas_unlink_data_urbs(struct uas_dev_info 
*devinfo,
                usb_unlink_urb(cmdinfo->data_out_urb);
                spin_lock_irqsave(&devinfo->lock, flags);
        }
+       cmdinfo->state &= ~UNLINK_DATA_URBS;
        spin_unlock_irqrestore(&devinfo->lock, flags);
 }
 
@@ -187,7 +195,7 @@ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const 
char *caller)
        struct uas_cmd_info *ci = (void *)&cmnd->SCp;
 
        scmd_printk(KERN_INFO, cmnd, "%s %p tag %d, inflight:"
-                   "%s%s%s%s%s%s%s%s%s%s%s%s\n",
+                   "%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
                    caller, cmnd, cmnd->request->tag,
                    (ci->state & SUBMIT_STATUS_URB)     ? " s-st"  : "",
                    (ci->state & ALLOC_DATA_IN_URB)     ? " a-in"  : "",
@@ -200,7 +208,8 @@ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const 
char *caller)
                    (ci->state & DATA_IN_URB_INFLIGHT)  ? " IN"    : "",
                    (ci->state & DATA_OUT_URB_INFLIGHT) ? " OUT"   : "",
                    (ci->state & COMMAND_COMPLETED)     ? " done"  : "",
-                   (ci->state & COMMAND_ABORTED)       ? " abort" : "");
+                   (ci->state & COMMAND_ABORTED)       ? " abort" : "",
+                   (ci->state & UNLINK_DATA_URBS)      ? " unlink": "");
 }
 
 static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
@@ -211,7 +220,8 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const 
char *caller)
        WARN_ON(!spin_is_locked(&devinfo->lock));
        if (cmdinfo->state & (COMMAND_INFLIGHT |
                              DATA_IN_URB_INFLIGHT |
-                             DATA_OUT_URB_INFLIGHT))
+                             DATA_OUT_URB_INFLIGHT |
+                             UNLINK_DATA_URBS))
                return -EBUSY;
        BUG_ON(cmdinfo->state & COMMAND_COMPLETED);
        cmdinfo->state |= COMMAND_COMPLETED;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to