aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/storage/uas.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 1d10d5b8204c..4bbaf6e150e4 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -125,29 +125,38 @@ struct uas_cmd_info {
125/* I hate forward declarations, but I actually have a loop */ 125/* I hate forward declarations, but I actually have a loop */
126static int uas_submit_urbs(struct scsi_cmnd *cmnd, 126static int uas_submit_urbs(struct scsi_cmnd *cmnd,
127 struct uas_dev_info *devinfo, gfp_t gfp); 127 struct uas_dev_info *devinfo, gfp_t gfp);
128static void uas_do_work(struct work_struct *work);
128 129
130static DECLARE_WORK(uas_work, uas_do_work);
129static DEFINE_SPINLOCK(uas_work_lock); 131static DEFINE_SPINLOCK(uas_work_lock);
130static LIST_HEAD(uas_work_list); 132static LIST_HEAD(uas_work_list);
131 133
132static void uas_do_work(struct work_struct *work) 134static void uas_do_work(struct work_struct *work)
133{ 135{
134 struct uas_cmd_info *cmdinfo; 136 struct uas_cmd_info *cmdinfo;
137 struct uas_cmd_info *temp;
135 struct list_head list; 138 struct list_head list;
139 int err;
136 140
137 spin_lock_irq(&uas_work_lock); 141 spin_lock_irq(&uas_work_lock);
138 list_replace_init(&uas_work_list, &list); 142 list_replace_init(&uas_work_list, &list);
139 spin_unlock_irq(&uas_work_lock); 143 spin_unlock_irq(&uas_work_lock);
140 144
141 list_for_each_entry(cmdinfo, &list, list) { 145 list_for_each_entry_safe(cmdinfo, temp, &list, list) {
142 struct scsi_pointer *scp = (void *)cmdinfo; 146 struct scsi_pointer *scp = (void *)cmdinfo;
143 struct scsi_cmnd *cmnd = container_of(scp, 147 struct scsi_cmnd *cmnd = container_of(scp,
144 struct scsi_cmnd, SCp); 148 struct scsi_cmnd, SCp);
145 uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO); 149 err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO);
150 if (err) {
151 list_del(&cmdinfo->list);
152 spin_lock_irq(&uas_work_lock);
153 list_add_tail(&cmdinfo->list, &uas_work_list);
154 spin_unlock_irq(&uas_work_lock);
155 schedule_work(&uas_work);
156 }
146 } 157 }
147} 158}
148 159
149static DECLARE_WORK(uas_work, uas_do_work);
150
151static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) 160static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)
152{ 161{
153 struct sense_iu *sense_iu = urb->transfer_buffer; 162 struct sense_iu *sense_iu = urb->transfer_buffer;