]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/usb/storage/uas.c
uas: task_mgmt: Kill the sense-urb if we fail to submit the cmd urb
[mirror_ubuntu-zesty-kernel.git] / drivers / usb / storage / uas.c
CommitLineData
115bb1ff
MW
1/*
2 * USB Attached SCSI
3 * Note that this is not the same as the USB Mass Storage driver
4 *
5 * Copyright Matthew Wilcox for Intel Corp, 2010
6 * Copyright Sarah Sharp for Intel Corp, 2010
7 *
8 * Distributed under the terms of the GNU GPL, version two.
9 */
10
11#include <linux/blkdev.h>
12#include <linux/slab.h>
13#include <linux/types.h>
6eb0de82 14#include <linux/module.h>
115bb1ff 15#include <linux/usb.h>
79b4c061 16#include <linux/usb_usual.h>
c898add5 17#include <linux/usb/hcd.h>
115bb1ff 18#include <linux/usb/storage.h>
348748b0 19#include <linux/usb/uas.h>
115bb1ff
MW
20
21#include <scsi/scsi.h>
4de7a373 22#include <scsi/scsi_eh.h>
115bb1ff
MW
23#include <scsi/scsi_dbg.h>
24#include <scsi/scsi_cmnd.h>
25#include <scsi/scsi_device.h>
26#include <scsi/scsi_host.h>
27#include <scsi/scsi_tcq.h>
28
82aa0387
HG
29#include "uas-detect.h"
30
115bb1ff
MW
31/*
32 * The r00-r01c specs define this version of the SENSE IU data structure.
33 * It's still in use by several different firmware releases.
34 */
35struct sense_iu_old {
36 __u8 iu_id;
37 __u8 rsvd1;
38 __be16 tag;
39 __be16 len;
40 __u8 status;
41 __u8 service_response;
42 __u8 sense[SCSI_SENSE_BUFFERSIZE];
43};
44
115bb1ff
MW
45struct uas_dev_info {
46 struct usb_interface *intf;
47 struct usb_device *udev;
a0e39e34 48 struct usb_anchor cmd_urbs;
bdd000fb
GH
49 struct usb_anchor sense_urbs;
50 struct usb_anchor data_urbs;
023b515e 51 int qdepth, resetting;
e52e0314 52 struct response_iu response;
115bb1ff
MW
53 unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe;
54 unsigned use_streams:1;
55 unsigned uas_sense_old:1;
22188f4a 56 struct scsi_cmnd *cmnd;
e0648520 57 spinlock_t lock;
1bf8198e
GH
58 struct work_struct work;
59 struct list_head work_list;
326349f8 60 struct list_head dead_list;
115bb1ff
MW
61};
62
63enum {
92a3f767 64 SUBMIT_STATUS_URB = (1 << 1),
115bb1ff
MW
65 ALLOC_DATA_IN_URB = (1 << 2),
66 SUBMIT_DATA_IN_URB = (1 << 3),
67 ALLOC_DATA_OUT_URB = (1 << 4),
68 SUBMIT_DATA_OUT_URB = (1 << 5),
69 ALLOC_CMD_URB = (1 << 6),
70 SUBMIT_CMD_URB = (1 << 7),
b1d67693
GH
71 COMMAND_INFLIGHT = (1 << 8),
72 DATA_IN_URB_INFLIGHT = (1 << 9),
73 DATA_OUT_URB_INFLIGHT = (1 << 10),
74 COMMAND_COMPLETED = (1 << 11),
ef018cc9 75 COMMAND_ABORTED = (1 << 12),
b06e48af 76 UNLINK_DATA_URBS = (1 << 13),
efefecf3 77 IS_IN_WORK_LIST = (1 << 14),
115bb1ff
MW
78};
79
80/* Overrides scsi_pointer */
81struct uas_cmd_info {
82 unsigned int state;
83 unsigned int stream;
84 struct urb *cmd_urb;
115bb1ff
MW
85 struct urb *data_in_urb;
86 struct urb *data_out_urb;
1bf8198e 87 struct list_head work;
326349f8 88 struct list_head dead;
115bb1ff
MW
89};
90
91/* I hate forward declarations, but I actually have a loop */
92static int uas_submit_urbs(struct scsi_cmnd *cmnd,
93 struct uas_dev_info *devinfo, gfp_t gfp);
ea9da1c7 94static void uas_do_work(struct work_struct *work);
4c456971 95static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller);
d89bd835 96static void uas_free_streams(struct uas_dev_info *devinfo);
326349f8 97static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller);
115bb1ff 98
7e50e0be 99/* Must be called with devinfo->lock held, will temporary unlock the lock */
aa8f6123 100static void uas_unlink_data_urbs(struct uas_dev_info *devinfo,
7e50e0be
HG
101 struct uas_cmd_info *cmdinfo,
102 unsigned long *lock_flags)
aa8f6123 103{
b06e48af
GH
104 /*
105 * The UNLINK_DATA_URBS flag makes sure uas_try_complete
106 * (called by urb completion) doesn't release cmdinfo
107 * underneath us.
108 */
b06e48af 109 cmdinfo->state |= UNLINK_DATA_URBS;
7e50e0be 110 spin_unlock_irqrestore(&devinfo->lock, *lock_flags);
b06e48af 111
aa8f6123
GH
112 if (cmdinfo->data_in_urb)
113 usb_unlink_urb(cmdinfo->data_in_urb);
114 if (cmdinfo->data_out_urb)
115 usb_unlink_urb(cmdinfo->data_out_urb);
b06e48af 116
7e50e0be 117 spin_lock_irqsave(&devinfo->lock, *lock_flags);
b06e48af 118 cmdinfo->state &= ~UNLINK_DATA_URBS;
aa8f6123
GH
119}
120
115bb1ff
MW
121static void uas_do_work(struct work_struct *work)
122{
1bf8198e
GH
123 struct uas_dev_info *devinfo =
124 container_of(work, struct uas_dev_info, work);
115bb1ff 125 struct uas_cmd_info *cmdinfo;
ea9da1c7 126 struct uas_cmd_info *temp;
e0648520 127 unsigned long flags;
ea9da1c7 128 int err;
115bb1ff 129
1bf8198e
GH
130 spin_lock_irqsave(&devinfo->lock, flags);
131 list_for_each_entry_safe(cmdinfo, temp, &devinfo->work_list, work) {
115bb1ff 132 struct scsi_pointer *scp = (void *)cmdinfo;
1bf8198e
GH
133 struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd,
134 SCp);
e0648520 135 err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
1bf8198e 136 if (!err) {
efefecf3 137 cmdinfo->state &= ~IS_IN_WORK_LIST;
1bf8198e
GH
138 list_del(&cmdinfo->work);
139 } else {
140 schedule_work(&devinfo->work);
ea9da1c7 141 }
115bb1ff 142 }
1bf8198e 143 spin_unlock_irqrestore(&devinfo->lock, flags);
115bb1ff
MW
144}
145
4c456971
GH
146static void uas_abort_work(struct uas_dev_info *devinfo)
147{
148 struct uas_cmd_info *cmdinfo;
149 struct uas_cmd_info *temp;
4c456971
GH
150 unsigned long flags;
151
4c456971 152 spin_lock_irqsave(&devinfo->lock, flags);
1bf8198e 153 list_for_each_entry_safe(cmdinfo, temp, &devinfo->work_list, work) {
4c456971 154 struct scsi_pointer *scp = (void *)cmdinfo;
1bf8198e
GH
155 struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd,
156 SCp);
326349f8 157 uas_log_cmd_state(cmnd, __func__);
f491ecbb 158 WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED);
1bf8198e
GH
159 cmdinfo->state |= COMMAND_ABORTED;
160 cmdinfo->state &= ~IS_IN_WORK_LIST;
1bf8198e 161 list_del(&cmdinfo->work);
326349f8 162 list_add_tail(&cmdinfo->dead, &devinfo->dead_list);
4c456971
GH
163 }
164 spin_unlock_irqrestore(&devinfo->lock, flags);
165}
166
1bf8198e
GH
167static void uas_add_work(struct uas_cmd_info *cmdinfo)
168{
169 struct scsi_pointer *scp = (void *)cmdinfo;
170 struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
171 struct uas_dev_info *devinfo = cmnd->device->hostdata;
172
f491ecbb 173 WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
1bf8198e
GH
174 list_add_tail(&cmdinfo->work, &devinfo->work_list);
175 cmdinfo->state |= IS_IN_WORK_LIST;
176 schedule_work(&devinfo->work);
177}
178
326349f8
GH
179static void uas_zap_dead(struct uas_dev_info *devinfo)
180{
181 struct uas_cmd_info *cmdinfo;
182 struct uas_cmd_info *temp;
183 unsigned long flags;
184
185 spin_lock_irqsave(&devinfo->lock, flags);
186 list_for_each_entry_safe(cmdinfo, temp, &devinfo->dead_list, dead) {
187 struct scsi_pointer *scp = (void *)cmdinfo;
188 struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd,
189 SCp);
190 uas_log_cmd_state(cmnd, __func__);
f491ecbb 191 WARN_ON_ONCE(!(cmdinfo->state & COMMAND_ABORTED));
326349f8
GH
192 /* all urbs are killed, clear inflight bits */
193 cmdinfo->state &= ~(COMMAND_INFLIGHT |
194 DATA_IN_URB_INFLIGHT |
195 DATA_OUT_URB_INFLIGHT);
196 uas_try_complete(cmnd, __func__);
197 }
198 spin_unlock_irqrestore(&devinfo->lock, flags);
199}
200
115bb1ff
MW
201static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)
202{
203 struct sense_iu *sense_iu = urb->transfer_buffer;
204 struct scsi_device *sdev = cmnd->device;
205
206 if (urb->actual_length > 16) {
207 unsigned len = be16_to_cpup(&sense_iu->len);
208 if (len + 16 != urb->actual_length) {
209 int newlen = min(len + 16, urb->actual_length) - 16;
210 if (newlen < 0)
211 newlen = 0;
212 sdev_printk(KERN_INFO, sdev, "%s: urb length %d "
213 "disagrees with IU sense data length %d, "
214 "using %d bytes of sense data\n", __func__,
215 urb->actual_length, len, newlen);
216 len = newlen;
217 }
218 memcpy(cmnd->sense_buffer, sense_iu->sense, len);
219 }
220
221 cmnd->result = sense_iu->status;
115bb1ff
MW
222}
223
224static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
225{
226 struct sense_iu_old *sense_iu = urb->transfer_buffer;
227 struct scsi_device *sdev = cmnd->device;
228
229 if (urb->actual_length > 8) {
230 unsigned len = be16_to_cpup(&sense_iu->len) - 2;
231 if (len + 8 != urb->actual_length) {
232 int newlen = min(len + 8, urb->actual_length) - 8;
233 if (newlen < 0)
234 newlen = 0;
235 sdev_printk(KERN_INFO, sdev, "%s: urb length %d "
236 "disagrees with IU sense data length %d, "
237 "using %d bytes of sense data\n", __func__,
238 urb->actual_length, len, newlen);
239 len = newlen;
240 }
241 memcpy(cmnd->sense_buffer, sense_iu->sense, len);
242 }
243
244 cmnd->result = sense_iu->status;
b1d67693
GH
245}
246
247static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller)
248{
249 struct uas_cmd_info *ci = (void *)&cmnd->SCp;
250
251 scmd_printk(KERN_INFO, cmnd, "%s %p tag %d, inflight:"
efefecf3 252 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
b1d67693
GH
253 caller, cmnd, cmnd->request->tag,
254 (ci->state & SUBMIT_STATUS_URB) ? " s-st" : "",
255 (ci->state & ALLOC_DATA_IN_URB) ? " a-in" : "",
256 (ci->state & SUBMIT_DATA_IN_URB) ? " s-in" : "",
257 (ci->state & ALLOC_DATA_OUT_URB) ? " a-out" : "",
258 (ci->state & SUBMIT_DATA_OUT_URB) ? " s-out" : "",
259 (ci->state & ALLOC_CMD_URB) ? " a-cmd" : "",
260 (ci->state & SUBMIT_CMD_URB) ? " s-cmd" : "",
261 (ci->state & COMMAND_INFLIGHT) ? " CMD" : "",
262 (ci->state & DATA_IN_URB_INFLIGHT) ? " IN" : "",
263 (ci->state & DATA_OUT_URB_INFLIGHT) ? " OUT" : "",
ef018cc9 264 (ci->state & COMMAND_COMPLETED) ? " done" : "",
b06e48af 265 (ci->state & COMMAND_ABORTED) ? " abort" : "",
efefecf3
GH
266 (ci->state & UNLINK_DATA_URBS) ? " unlink": "",
267 (ci->state & IS_IN_WORK_LIST) ? " work" : "");
b1d67693
GH
268}
269
270static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
271{
272 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
e0648520 273 struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
b1d67693 274
f491ecbb 275 WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
b1d67693
GH
276 if (cmdinfo->state & (COMMAND_INFLIGHT |
277 DATA_IN_URB_INFLIGHT |
b06e48af
GH
278 DATA_OUT_URB_INFLIGHT |
279 UNLINK_DATA_URBS))
b1d67693 280 return -EBUSY;
f491ecbb 281 WARN_ON_ONCE(cmdinfo->state & COMMAND_COMPLETED);
b1d67693
GH
282 cmdinfo->state |= COMMAND_COMPLETED;
283 usb_free_urb(cmdinfo->data_in_urb);
284 usb_free_urb(cmdinfo->data_out_urb);
0871d7d8
GH
285 if (cmdinfo->state & COMMAND_ABORTED) {
286 scmd_printk(KERN_INFO, cmnd, "abort completed\n");
287 cmnd->result = DID_ABORT << 16;
326349f8 288 list_del(&cmdinfo->dead);
0871d7d8 289 }
c621a81e 290 cmnd->scsi_done(cmnd);
b1d67693 291 return 0;
115bb1ff
MW
292}
293
294static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
b1d67693 295 unsigned direction)
115bb1ff
MW
296{
297 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
298 int err;
299
b1d67693 300 cmdinfo->state |= direction | SUBMIT_STATUS_URB;
115bb1ff
MW
301 err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
302 if (err) {
1bf8198e 303 uas_add_work(cmdinfo);
115bb1ff
MW
304 }
305}
306
307static void uas_stat_cmplt(struct urb *urb)
308{
309 struct iu *iu = urb->transfer_buffer;
22188f4a
SAS
310 struct Scsi_Host *shost = urb->context;
311 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
115bb1ff 312 struct scsi_cmnd *cmnd;
b1d67693 313 struct uas_cmd_info *cmdinfo;
e0648520 314 unsigned long flags;
115bb1ff
MW
315 u16 tag;
316
317 if (urb->status) {
326349f8
GH
318 if (urb->status == -ENOENT) {
319 dev_err(&urb->dev->dev, "stat urb: killed, stream %d\n",
320 urb->stream_id);
321 } else {
322 dev_err(&urb->dev->dev, "stat urb: status %d\n",
323 urb->status);
324 }
db32de11 325 usb_free_urb(urb);
115bb1ff
MW
326 return;
327 }
328
023b515e
GH
329 if (devinfo->resetting) {
330 usb_free_urb(urb);
331 return;
332 }
333
e0648520 334 spin_lock_irqsave(&devinfo->lock, flags);
115bb1ff 335 tag = be16_to_cpup(&iu->tag) - 1;
22188f4a
SAS
336 if (tag == 0)
337 cmnd = devinfo->cmnd;
115bb1ff 338 else
22188f4a 339 cmnd = scsi_host_find_tag(shost, tag - 1);
e0423dee 340
96c1eb98 341 if (!cmnd) {
e0423dee
GH
342 if (iu->iu_id == IU_ID_RESPONSE) {
343 /* store results for uas_eh_task_mgmt() */
344 memcpy(&devinfo->response, iu, sizeof(devinfo->response));
023b515e 345 }
e0423dee
GH
346 usb_free_urb(urb);
347 spin_unlock_irqrestore(&devinfo->lock, flags);
348 return;
96c1eb98 349 }
115bb1ff 350
e0423dee 351 cmdinfo = (void *)&cmnd->SCp;
115bb1ff
MW
352 switch (iu->iu_id) {
353 case IU_ID_STATUS:
22188f4a
SAS
354 if (devinfo->cmnd == cmnd)
355 devinfo->cmnd = NULL;
356
115bb1ff
MW
357 if (urb->actual_length < 16)
358 devinfo->uas_sense_old = 1;
359 if (devinfo->uas_sense_old)
360 uas_sense_old(urb, cmnd);
361 else
362 uas_sense(urb, cmnd);
8aac863e
GH
363 if (cmnd->result != 0) {
364 /* cancel data transfers on error */
7e50e0be 365 uas_unlink_data_urbs(devinfo, cmdinfo, &flags);
8aac863e 366 }
b1d67693
GH
367 cmdinfo->state &= ~COMMAND_INFLIGHT;
368 uas_try_complete(cmnd, __func__);
115bb1ff
MW
369 break;
370 case IU_ID_READ_READY:
371 uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB);
372 break;
373 case IU_ID_WRITE_READY:
374 uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB);
375 break;
376 default:
377 scmd_printk(KERN_ERR, cmnd,
378 "Bogus IU (%d) received on status pipe\n", iu->iu_id);
379 }
e9bd7e1a 380 usb_free_urb(urb);
e0648520 381 spin_unlock_irqrestore(&devinfo->lock, flags);
115bb1ff
MW
382}
383
c621a81e 384static void uas_data_cmplt(struct urb *urb)
115bb1ff 385{
b1d67693
GH
386 struct scsi_cmnd *cmnd = urb->context;
387 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
e0648520 388 struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
b1d67693 389 struct scsi_data_buffer *sdb = NULL;
e0648520 390 unsigned long flags;
b1d67693 391
e0648520 392 spin_lock_irqsave(&devinfo->lock, flags);
b1d67693
GH
393 if (cmdinfo->data_in_urb == urb) {
394 sdb = scsi_in(cmnd);
395 cmdinfo->state &= ~DATA_IN_URB_INFLIGHT;
396 } else if (cmdinfo->data_out_urb == urb) {
397 sdb = scsi_out(cmnd);
398 cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT;
399 }
f491ecbb
GH
400 if (sdb == NULL) {
401 WARN_ON_ONCE(1);
402 } else if (urb->status) {
8aac863e
GH
403 /* error: no data transfered */
404 sdb->resid = sdb->length;
405 } else {
406 sdb->resid = sdb->length - urb->actual_length;
407 }
b1d67693 408 uas_try_complete(cmnd, __func__);
e0648520 409 spin_unlock_irqrestore(&devinfo->lock, flags);
115bb1ff
MW
410}
411
412static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
b1d67693
GH
413 unsigned int pipe, u16 stream_id,
414 struct scsi_cmnd *cmnd,
415 enum dma_data_direction dir)
115bb1ff
MW
416{
417 struct usb_device *udev = devinfo->udev;
418 struct urb *urb = usb_alloc_urb(0, gfp);
b1d67693
GH
419 struct scsi_data_buffer *sdb = (dir == DMA_FROM_DEVICE)
420 ? scsi_in(cmnd) : scsi_out(cmnd);
115bb1ff
MW
421
422 if (!urb)
423 goto out;
b1d67693
GH
424 usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length,
425 uas_data_cmplt, cmnd);
c621a81e
GH
426 if (devinfo->use_streams)
427 urb->stream_id = stream_id;
115bb1ff
MW
428 urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0;
429 urb->sg = sdb->table.sgl;
430 out:
431 return urb;
432}
433
434static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
e9bd7e1a 435 struct Scsi_Host *shost, u16 stream_id)
115bb1ff
MW
436{
437 struct usb_device *udev = devinfo->udev;
438 struct urb *urb = usb_alloc_urb(0, gfp);
439 struct sense_iu *iu;
440
441 if (!urb)
442 goto out;
443
ac563cfd 444 iu = kzalloc(sizeof(*iu), gfp);
115bb1ff
MW
445 if (!iu)
446 goto free;
447
448 usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu),
e9bd7e1a 449 uas_stat_cmplt, shost);
115bb1ff
MW
450 urb->stream_id = stream_id;
451 urb->transfer_flags |= URB_FREE_BUFFER;
452 out:
453 return urb;
454 free:
455 usb_free_urb(urb);
456 return NULL;
457}
458
459static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
a887cd36 460 struct scsi_cmnd *cmnd)
115bb1ff
MW
461{
462 struct usb_device *udev = devinfo->udev;
463 struct scsi_device *sdev = cmnd->device;
464 struct urb *urb = usb_alloc_urb(0, gfp);
465 struct command_iu *iu;
466 int len;
467
468 if (!urb)
469 goto out;
470
471 len = cmnd->cmd_len - 16;
472 if (len < 0)
473 len = 0;
474 len = ALIGN(len, 4);
ac563cfd 475 iu = kzalloc(sizeof(*iu) + len, gfp);
115bb1ff
MW
476 if (!iu)
477 goto free;
478
479 iu->iu_id = IU_ID_COMMAND;
9eb44541 480 if (blk_rq_tagged(cmnd->request))
22188f4a 481 iu->tag = cpu_to_be16(cmnd->request->tag + 2);
9eb44541
SS
482 else
483 iu->tag = cpu_to_be16(1);
02e031cb 484 iu->prio_attr = UAS_SIMPLE_TAG;
115bb1ff
MW
485 iu->len = len;
486 int_to_scsilun(sdev->lun, &iu->lun);
487 memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len);
488
489 usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu) + len,
490 usb_free_urb, NULL);
491 urb->transfer_flags |= URB_FREE_BUFFER;
492 out:
493 return urb;
494 free:
495 usb_free_urb(urb);
496 return NULL;
497}
498
023b515e
GH
499static int uas_submit_task_urb(struct scsi_cmnd *cmnd, gfp_t gfp,
500 u8 function, u16 stream_id)
501{
502 struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
503 struct usb_device *udev = devinfo->udev;
504 struct urb *urb = usb_alloc_urb(0, gfp);
505 struct task_mgmt_iu *iu;
506 int err = -ENOMEM;
507
508 if (!urb)
509 goto err;
510
511 iu = kzalloc(sizeof(*iu), gfp);
512 if (!iu)
513 goto err;
514
515 iu->iu_id = IU_ID_TASK_MGMT;
516 iu->tag = cpu_to_be16(stream_id);
517 int_to_scsilun(cmnd->device->lun, &iu->lun);
518
519 iu->function = function;
520 switch (function) {
521 case TMF_ABORT_TASK:
522 if (blk_rq_tagged(cmnd->request))
523 iu->task_tag = cpu_to_be16(cmnd->request->tag + 2);
524 else
525 iu->task_tag = cpu_to_be16(1);
526 break;
527 }
528
529 usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu),
530 usb_free_urb, NULL);
531 urb->transfer_flags |= URB_FREE_BUFFER;
532
d5f808d3 533 usb_anchor_urb(urb, &devinfo->cmd_urbs);
023b515e 534 err = usb_submit_urb(urb, gfp);
d5f808d3
HG
535 if (err) {
536 usb_unanchor_urb(urb);
023b515e 537 goto err;
d5f808d3 538 }
023b515e
GH
539
540 return 0;
541
542err:
543 usb_free_urb(urb);
544 return err;
545}
546
115bb1ff
MW
547/*
548 * Why should I request the Status IU before sending the Command IU? Spec
549 * says to, but also says the device may receive them in any order. Seems
550 * daft to me.
551 */
552
70cf0fba
HG
553static struct urb *uas_submit_sense_urb(struct Scsi_Host *shost,
554 gfp_t gfp, unsigned int stream)
115bb1ff 555{
e9bd7e1a
GH
556 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
557 struct urb *urb;
115bb1ff 558
e9bd7e1a
GH
559 urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream);
560 if (!urb)
70cf0fba 561 return NULL;
d5f808d3 562 usb_anchor_urb(urb, &devinfo->sense_urbs);
e9bd7e1a 563 if (usb_submit_urb(urb, gfp)) {
d5f808d3 564 usb_unanchor_urb(urb);
e9bd7e1a
GH
565 shost_printk(KERN_INFO, shost,
566 "sense urb submission failure\n");
567 usb_free_urb(urb);
70cf0fba 568 return NULL;
115bb1ff 569 }
70cf0fba 570 return urb;
e9bd7e1a
GH
571}
572
573static int uas_submit_urbs(struct scsi_cmnd *cmnd,
574 struct uas_dev_info *devinfo, gfp_t gfp)
575{
576 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
70cf0fba 577 struct urb *urb;
115bb1ff 578
f491ecbb 579 WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
92a3f767 580 if (cmdinfo->state & SUBMIT_STATUS_URB) {
70cf0fba 581 urb = uas_submit_sense_urb(cmnd->device->host, gfp,
e9bd7e1a 582 cmdinfo->stream);
70cf0fba
HG
583 if (!urb)
584 return SCSI_MLQUEUE_DEVICE_BUSY;
92a3f767 585 cmdinfo->state &= ~SUBMIT_STATUS_URB;
115bb1ff
MW
586 }
587
588 if (cmdinfo->state & ALLOC_DATA_IN_URB) {
589 cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp,
c621a81e 590 devinfo->data_in_pipe, cmdinfo->stream,
b1d67693 591 cmnd, DMA_FROM_DEVICE);
115bb1ff
MW
592 if (!cmdinfo->data_in_urb)
593 return SCSI_MLQUEUE_DEVICE_BUSY;
594 cmdinfo->state &= ~ALLOC_DATA_IN_URB;
595 }
596
597 if (cmdinfo->state & SUBMIT_DATA_IN_URB) {
d5f808d3 598 usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs);
115bb1ff 599 if (usb_submit_urb(cmdinfo->data_in_urb, gfp)) {
d5f808d3 600 usb_unanchor_urb(cmdinfo->data_in_urb);
115bb1ff
MW
601 scmd_printk(KERN_INFO, cmnd,
602 "data in urb submission failure\n");
603 return SCSI_MLQUEUE_DEVICE_BUSY;
604 }
605 cmdinfo->state &= ~SUBMIT_DATA_IN_URB;
b1d67693 606 cmdinfo->state |= DATA_IN_URB_INFLIGHT;
115bb1ff
MW
607 }
608
609 if (cmdinfo->state & ALLOC_DATA_OUT_URB) {
610 cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp,
c621a81e 611 devinfo->data_out_pipe, cmdinfo->stream,
b1d67693 612 cmnd, DMA_TO_DEVICE);
115bb1ff
MW
613 if (!cmdinfo->data_out_urb)
614 return SCSI_MLQUEUE_DEVICE_BUSY;
615 cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
616 }
617
618 if (cmdinfo->state & SUBMIT_DATA_OUT_URB) {
d5f808d3 619 usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs);
115bb1ff 620 if (usb_submit_urb(cmdinfo->data_out_urb, gfp)) {
d5f808d3 621 usb_unanchor_urb(cmdinfo->data_out_urb);
115bb1ff
MW
622 scmd_printk(KERN_INFO, cmnd,
623 "data out urb submission failure\n");
624 return SCSI_MLQUEUE_DEVICE_BUSY;
625 }
626 cmdinfo->state &= ~SUBMIT_DATA_OUT_URB;
b1d67693 627 cmdinfo->state |= DATA_OUT_URB_INFLIGHT;
115bb1ff
MW
628 }
629
630 if (cmdinfo->state & ALLOC_CMD_URB) {
a887cd36 631 cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd);
115bb1ff
MW
632 if (!cmdinfo->cmd_urb)
633 return SCSI_MLQUEUE_DEVICE_BUSY;
634 cmdinfo->state &= ~ALLOC_CMD_URB;
635 }
636
637 if (cmdinfo->state & SUBMIT_CMD_URB) {
d5f808d3 638 usb_anchor_urb(cmdinfo->cmd_urb, &devinfo->cmd_urbs);
115bb1ff 639 if (usb_submit_urb(cmdinfo->cmd_urb, gfp)) {
d5f808d3 640 usb_unanchor_urb(cmdinfo->cmd_urb);
115bb1ff
MW
641 scmd_printk(KERN_INFO, cmnd,
642 "cmd urb submission failure\n");
643 return SCSI_MLQUEUE_DEVICE_BUSY;
644 }
a0e39e34 645 cmdinfo->cmd_urb = NULL;
115bb1ff 646 cmdinfo->state &= ~SUBMIT_CMD_URB;
b1d67693 647 cmdinfo->state |= COMMAND_INFLIGHT;
115bb1ff
MW
648 }
649
650 return 0;
651}
652
f281233d 653static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
115bb1ff
MW
654 void (*done)(struct scsi_cmnd *))
655{
656 struct scsi_device *sdev = cmnd->device;
657 struct uas_dev_info *devinfo = sdev->hostdata;
658 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
e0648520 659 unsigned long flags;
115bb1ff
MW
660 int err;
661
662 BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer));
663
f8be6bfc
GH
664 if (devinfo->resetting) {
665 cmnd->result = DID_ERROR << 16;
666 cmnd->scsi_done(cmnd);
667 return 0;
668 }
669
e0648520
GH
670 spin_lock_irqsave(&devinfo->lock, flags);
671 if (devinfo->cmnd) {
672 spin_unlock_irqrestore(&devinfo->lock, flags);
115bb1ff 673 return SCSI_MLQUEUE_DEVICE_BUSY;
e0648520 674 }
115bb1ff
MW
675
676 if (blk_rq_tagged(cmnd->request)) {
22188f4a 677 cmdinfo->stream = cmnd->request->tag + 2;
115bb1ff 678 } else {
22188f4a 679 devinfo->cmnd = cmnd;
115bb1ff
MW
680 cmdinfo->stream = 1;
681 }
682
683 cmnd->scsi_done = done;
684
e9bd7e1a 685 cmdinfo->state = SUBMIT_STATUS_URB |
115bb1ff
MW
686 ALLOC_CMD_URB | SUBMIT_CMD_URB;
687
688 switch (cmnd->sc_data_direction) {
689 case DMA_FROM_DEVICE:
690 cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
691 break;
692 case DMA_BIDIRECTIONAL:
693 cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
694 case DMA_TO_DEVICE:
695 cmdinfo->state |= ALLOC_DATA_OUT_URB | SUBMIT_DATA_OUT_URB;
696 case DMA_NONE:
697 break;
698 }
699
700 if (!devinfo->use_streams) {
db32de11 701 cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
115bb1ff
MW
702 cmdinfo->stream = 0;
703 }
704
705 err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
706 if (err) {
707 /* If we did nothing, give up now */
92a3f767 708 if (cmdinfo->state & SUBMIT_STATUS_URB) {
e0648520 709 spin_unlock_irqrestore(&devinfo->lock, flags);
115bb1ff
MW
710 return SCSI_MLQUEUE_DEVICE_BUSY;
711 }
1bf8198e 712 uas_add_work(cmdinfo);
115bb1ff
MW
713 }
714
e0648520 715 spin_unlock_irqrestore(&devinfo->lock, flags);
115bb1ff
MW
716 return 0;
717}
718
f281233d
JG
719static DEF_SCSI_QCMD(uas_queuecommand)
720
023b515e
GH
721static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd,
722 const char *fname, u8 function)
115bb1ff 723{
023b515e
GH
724 struct Scsi_Host *shost = cmnd->device->host;
725 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
d3f7c156 726 u16 tag = devinfo->qdepth;
e0648520 727 unsigned long flags;
70cf0fba 728 struct urb *sense_urb;
115bb1ff 729
e0648520 730 spin_lock_irqsave(&devinfo->lock, flags);
023b515e 731 memset(&devinfo->response, 0, sizeof(devinfo->response));
70cf0fba
HG
732 sense_urb = uas_submit_sense_urb(shost, GFP_ATOMIC, tag);
733 if (!sense_urb) {
023b515e
GH
734 shost_printk(KERN_INFO, shost,
735 "%s: %s: submit sense urb failed\n",
736 __func__, fname);
1994ff40 737 spin_unlock_irqrestore(&devinfo->lock, flags);
023b515e
GH
738 return FAILED;
739 }
e0648520 740 if (uas_submit_task_urb(cmnd, GFP_ATOMIC, function, tag)) {
023b515e
GH
741 shost_printk(KERN_INFO, shost,
742 "%s: %s: submit task mgmt urb failed\n",
743 __func__, fname);
1994ff40 744 spin_unlock_irqrestore(&devinfo->lock, flags);
70cf0fba 745 usb_kill_urb(sense_urb);
023b515e
GH
746 return FAILED;
747 }
e0648520
GH
748 spin_unlock_irqrestore(&devinfo->lock, flags);
749
750 if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 3000) == 0) {
023b515e
GH
751 shost_printk(KERN_INFO, shost,
752 "%s: %s timed out\n", __func__, fname);
753 return FAILED;
754 }
755 if (be16_to_cpu(devinfo->response.tag) != tag) {
756 shost_printk(KERN_INFO, shost,
757 "%s: %s failed (wrong tag %d/%d)\n", __func__,
758 fname, be16_to_cpu(devinfo->response.tag), tag);
759 return FAILED;
760 }
761 if (devinfo->response.response_code != RC_TMF_COMPLETE) {
762 shost_printk(KERN_INFO, shost,
763 "%s: %s failed (rc 0x%x)\n", __func__,
764 fname, devinfo->response.response_code);
765 return FAILED;
766 }
767 return SUCCESS;
115bb1ff
MW
768}
769
023b515e 770static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
115bb1ff 771{
023b515e 772 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
e0648520
GH
773 struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
774 unsigned long flags;
023b515e 775 int ret;
115bb1ff 776
023b515e 777 uas_log_cmd_state(cmnd, __func__);
e0648520 778 spin_lock_irqsave(&devinfo->lock, flags);
f491ecbb 779 WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED);
ef018cc9 780 cmdinfo->state |= COMMAND_ABORTED;
326349f8 781 list_add_tail(&cmdinfo->dead, &devinfo->dead_list);
5d390403 782 if (cmdinfo->state & IS_IN_WORK_LIST) {
1bf8198e 783 list_del(&cmdinfo->work);
5d390403 784 cmdinfo->state &= ~IS_IN_WORK_LIST;
5d390403
GH
785 }
786 if (cmdinfo->state & COMMAND_INFLIGHT) {
787 spin_unlock_irqrestore(&devinfo->lock, flags);
788 ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK);
789 } else {
7e50e0be 790 uas_unlink_data_urbs(devinfo, cmdinfo, &flags);
5d390403
GH
791 uas_try_complete(cmnd, __func__);
792 spin_unlock_irqrestore(&devinfo->lock, flags);
793 ret = SUCCESS;
794 }
023b515e 795 return ret;
115bb1ff
MW
796}
797
023b515e 798static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd)
115bb1ff 799{
023b515e
GH
800 sdev_printk(KERN_INFO, cmnd->device, "%s\n", __func__);
801 return uas_eh_task_mgmt(cmnd, "LOGICAL UNIT RESET",
802 TMF_LOGICAL_UNIT_RESET);
115bb1ff
MW
803}
804
805static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd)
806{
807 struct scsi_device *sdev = cmnd->device;
808 struct uas_dev_info *devinfo = sdev->hostdata;
809 struct usb_device *udev = devinfo->udev;
023b515e 810 int err;
115bb1ff 811
be326f4c
HG
812 err = usb_lock_device_for_reset(udev, devinfo->intf);
813 if (err) {
814 shost_printk(KERN_ERR, sdev->host,
815 "%s FAILED to get lock err %d\n", __func__, err);
816 return FAILED;
817 }
818
326349f8 819 shost_printk(KERN_INFO, sdev->host, "%s start\n", __func__);
023b515e 820 devinfo->resetting = 1;
4c456971 821 uas_abort_work(devinfo);
a0e39e34 822 usb_kill_anchored_urbs(&devinfo->cmd_urbs);
023b515e
GH
823 usb_kill_anchored_urbs(&devinfo->sense_urbs);
824 usb_kill_anchored_urbs(&devinfo->data_urbs);
326349f8 825 uas_zap_dead(devinfo);
023b515e
GH
826 err = usb_reset_device(udev);
827 devinfo->resetting = 0;
115bb1ff 828
be326f4c
HG
829 usb_unlock_device(udev);
830
023b515e
GH
831 if (err) {
832 shost_printk(KERN_INFO, sdev->host, "%s FAILED\n", __func__);
833 return FAILED;
834 }
115bb1ff 835
023b515e
GH
836 shost_printk(KERN_INFO, sdev->host, "%s success\n", __func__);
837 return SUCCESS;
115bb1ff
MW
838}
839
840static int uas_slave_alloc(struct scsi_device *sdev)
841{
842 sdev->hostdata = (void *)sdev->host->hostdata[0];
843 return 0;
844}
845
846static int uas_slave_configure(struct scsi_device *sdev)
847{
848 struct uas_dev_info *devinfo = sdev->hostdata;
849 scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
d3f7c156 850 scsi_activate_tcq(sdev, devinfo->qdepth - 2);
115bb1ff
MW
851 return 0;
852}
853
854static struct scsi_host_template uas_host_template = {
855 .module = THIS_MODULE,
856 .name = "uas",
857 .queuecommand = uas_queuecommand,
858 .slave_alloc = uas_slave_alloc,
859 .slave_configure = uas_slave_configure,
860 .eh_abort_handler = uas_eh_abort_handler,
861 .eh_device_reset_handler = uas_eh_device_reset_handler,
115bb1ff
MW
862 .eh_bus_reset_handler = uas_eh_bus_reset_handler,
863 .can_queue = 65536, /* Is there a limit on the _host_ ? */
864 .this_id = -1,
865 .sg_tablesize = SG_NONE,
866 .cmd_per_lun = 1, /* until we override it */
867 .skip_settle_delay = 1,
868 .ordered_tag = 1,
869};
870
79b4c061
HG
871#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
872 vendorName, productName, useProtocol, useTransport, \
873 initFunction, flags) \
874{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
875 .driver_info = (flags) }
876
115bb1ff 877static struct usb_device_id uas_usb_ids[] = {
79b4c061 878# include "unusual_uas.h"
115bb1ff
MW
879 { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_BULK) },
880 { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_UAS) },
881 /* 0xaa is a prototype device I happen to have access to */
882 { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, 0xaa) },
883 { }
884};
885MODULE_DEVICE_TABLE(usb, uas_usb_ids);
886
79b4c061
HG
887#undef UNUSUAL_DEV
888
e1be067b
HG
889static int uas_switch_interface(struct usb_device *udev,
890 struct usb_interface *intf)
891{
892 int alt;
893
894 alt = uas_find_uas_alt_setting(intf);
895 if (alt < 0)
896 return alt;
897
898 return usb_set_interface(udev,
899 intf->altsetting[0].desc.bInterfaceNumber, alt);
900}
901
58d51444 902static int uas_configure_endpoints(struct uas_dev_info *devinfo)
34f11e59
HG
903{
904 struct usb_host_endpoint *eps[4] = { };
905 struct usb_device *udev = devinfo->udev;
906 int r;
907
908 devinfo->uas_sense_old = 0;
909 devinfo->cmnd = NULL;
910
911 r = uas_find_endpoints(devinfo->intf->cur_altsetting, eps);
74d71aec
HG
912 if (r)
913 return r;
914
915 devinfo->cmd_pipe = usb_sndbulkpipe(udev,
916 usb_endpoint_num(&eps[0]->desc));
917 devinfo->status_pipe = usb_rcvbulkpipe(udev,
918 usb_endpoint_num(&eps[1]->desc));
919 devinfo->data_in_pipe = usb_rcvbulkpipe(udev,
920 usb_endpoint_num(&eps[2]->desc));
921 devinfo->data_out_pipe = usb_sndbulkpipe(udev,
922 usb_endpoint_num(&eps[3]->desc));
115bb1ff 923
58d51444 924 if (udev->speed != USB_SPEED_SUPER) {
115bb1ff
MW
925 devinfo->qdepth = 256;
926 devinfo->use_streams = 0;
927 } else {
58d51444
HG
928 devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1,
929 3, 256, GFP_KERNEL);
930 if (devinfo->qdepth < 0)
931 return devinfo->qdepth;
115bb1ff
MW
932 devinfo->use_streams = 1;
933 }
58d51444
HG
934
935 return 0;
115bb1ff
MW
936}
937
dae51546
SAS
938static void uas_free_streams(struct uas_dev_info *devinfo)
939{
940 struct usb_device *udev = devinfo->udev;
941 struct usb_host_endpoint *eps[3];
942
943 eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
944 eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
945 eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
946 usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL);
947}
948
115bb1ff
MW
949/*
950 * XXX: What I'd like to do here is register a SCSI host for each USB host in
951 * the system. Follow usb-storage's design of registering a SCSI host for
952 * each USB device for the moment. Can implement this by walking up the
953 * USB hierarchy until we find a USB host.
954 */
955static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
956{
6ce8213b
HG
957 int result = -ENOMEM;
958 struct Scsi_Host *shost = NULL;
115bb1ff
MW
959 struct uas_dev_info *devinfo;
960 struct usb_device *udev = interface_to_usbdev(intf);
961
79b4c061
HG
962 if (!uas_use_uas_driver(intf, id))
963 return -ENODEV;
964
89dc2905
MW
965 if (uas_switch_interface(udev, intf))
966 return -ENODEV;
115bb1ff
MW
967
968 devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL);
969 if (!devinfo)
6ce8213b 970 goto set_alt0;
115bb1ff 971
115bb1ff
MW
972 shost = scsi_host_alloc(&uas_host_template, sizeof(void *));
973 if (!shost)
6ce8213b 974 goto set_alt0;
115bb1ff
MW
975
976 shost->max_cmd_len = 16 + 252;
977 shost->max_id = 1;
bde027b4
GH
978 shost->max_lun = 256;
979 shost->max_channel = 0;
115bb1ff
MW
980 shost->sg_tablesize = udev->bus->sg_tablesize;
981
115bb1ff
MW
982 devinfo->intf = intf;
983 devinfo->udev = udev;
023b515e 984 devinfo->resetting = 0;
a0e39e34 985 init_usb_anchor(&devinfo->cmd_urbs);
bdd000fb
GH
986 init_usb_anchor(&devinfo->sense_urbs);
987 init_usb_anchor(&devinfo->data_urbs);
e0648520 988 spin_lock_init(&devinfo->lock);
1bf8198e
GH
989 INIT_WORK(&devinfo->work, uas_do_work);
990 INIT_LIST_HEAD(&devinfo->work_list);
326349f8 991 INIT_LIST_HEAD(&devinfo->dead_list);
58d51444
HG
992
993 result = uas_configure_endpoints(devinfo);
994 if (result)
995 goto set_alt0;
115bb1ff 996
d3f7c156 997 result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2);
115bb1ff 998 if (result)
6ce8213b 999 goto free_streams;
dae51546
SAS
1000
1001 result = scsi_add_host(shost, &intf->dev);
1002 if (result)
6ce8213b 1003 goto free_streams;
dae51546 1004
115bb1ff
MW
1005 shost->hostdata[0] = (unsigned long)devinfo;
1006
115bb1ff
MW
1007 scsi_scan_host(shost);
1008 usb_set_intfdata(intf, shost);
1009 return result;
dae51546 1010
6ce8213b 1011free_streams:
dae51546 1012 uas_free_streams(devinfo);
6ce8213b
HG
1013set_alt0:
1014 usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
115bb1ff
MW
1015 kfree(devinfo);
1016 if (shost)
1017 scsi_host_put(shost);
1018 return result;
1019}
1020
1021static int uas_pre_reset(struct usb_interface *intf)
1022{
4de7a373
HG
1023 struct Scsi_Host *shost = usb_get_intfdata(intf);
1024 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
1025 unsigned long flags;
1026
1027 /* Block new requests */
1028 spin_lock_irqsave(shost->host_lock, flags);
1029 scsi_block_requests(shost);
1030 spin_unlock_irqrestore(shost->host_lock, flags);
1031
1032 /* Wait for any pending requests to complete */
1033 flush_work(&devinfo->work);
1034 if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 5000) == 0) {
1035 shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__);
1036 return 1;
1037 }
1038
1039 uas_free_streams(devinfo);
1040
115bb1ff
MW
1041 return 0;
1042}
1043
1044static int uas_post_reset(struct usb_interface *intf)
1045{
4de7a373
HG
1046 struct Scsi_Host *shost = usb_get_intfdata(intf);
1047 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
1048 unsigned long flags;
1049
58d51444
HG
1050 if (uas_configure_endpoints(devinfo) != 0) {
1051 shost_printk(KERN_ERR, shost,
1052 "%s: alloc streams error after reset", __func__);
1053 return 1;
1054 }
4de7a373
HG
1055
1056 spin_lock_irqsave(shost->host_lock, flags);
1057 scsi_report_bus_reset(shost, 0);
1058 spin_unlock_irqrestore(shost->host_lock, flags);
1059
1060 scsi_unblock_requests(shost);
1061
115bb1ff
MW
1062 return 0;
1063}
1064
1065static void uas_disconnect(struct usb_interface *intf)
1066{
115bb1ff
MW
1067 struct Scsi_Host *shost = usb_get_intfdata(intf);
1068 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
1069
4c456971 1070 devinfo->resetting = 1;
1bf8198e 1071 cancel_work_sync(&devinfo->work);
4c456971 1072 uas_abort_work(devinfo);
a0e39e34 1073 usb_kill_anchored_urbs(&devinfo->cmd_urbs);
bdd000fb
GH
1074 usb_kill_anchored_urbs(&devinfo->sense_urbs);
1075 usb_kill_anchored_urbs(&devinfo->data_urbs);
326349f8 1076 uas_zap_dead(devinfo);
4c456971 1077 scsi_remove_host(shost);
dae51546 1078 uas_free_streams(devinfo);
115bb1ff
MW
1079 kfree(devinfo);
1080}
1081
115bb1ff
MW
1082static struct usb_driver uas_driver = {
1083 .name = "uas",
1084 .probe = uas_probe,
1085 .disconnect = uas_disconnect,
1086 .pre_reset = uas_pre_reset,
1087 .post_reset = uas_post_reset,
1088 .id_table = uas_usb_ids,
1089};
1090
65db4305 1091module_usb_driver(uas_driver);
115bb1ff
MW
1092
1093MODULE_LICENSE("GPL");
1094MODULE_AUTHOR("Matthew Wilcox and Sarah Sharp");