diff options
Diffstat (limited to 'drivers/usb/storage/uas.c')
-rw-r--r-- | drivers/usb/storage/uas.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 6974f4bed2fd..e2386e8c7678 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -98,6 +98,7 @@ struct uas_dev_info { | |||
98 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; | 98 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; |
99 | unsigned use_streams:1; | 99 | unsigned use_streams:1; |
100 | unsigned uas_sense_old:1; | 100 | unsigned uas_sense_old:1; |
101 | struct scsi_cmnd *cmnd; | ||
101 | }; | 102 | }; |
102 | 103 | ||
103 | enum { | 104 | enum { |
@@ -178,8 +179,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) | |||
178 | } | 179 | } |
179 | 180 | ||
180 | cmnd->result = sense_iu->status; | 181 | cmnd->result = sense_iu->status; |
181 | if (sdev->current_cmnd) | ||
182 | sdev->current_cmnd = NULL; | ||
183 | cmnd->scsi_done(cmnd); | 182 | cmnd->scsi_done(cmnd); |
184 | usb_free_urb(urb); | 183 | usb_free_urb(urb); |
185 | } | 184 | } |
@@ -205,8 +204,6 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) | |||
205 | } | 204 | } |
206 | 205 | ||
207 | cmnd->result = sense_iu->status; | 206 | cmnd->result = sense_iu->status; |
208 | if (sdev->current_cmnd) | ||
209 | sdev->current_cmnd = NULL; | ||
210 | cmnd->scsi_done(cmnd); | 207 | cmnd->scsi_done(cmnd); |
211 | usb_free_urb(urb); | 208 | usb_free_urb(urb); |
212 | } | 209 | } |
@@ -230,8 +227,8 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, | |||
230 | static void uas_stat_cmplt(struct urb *urb) | 227 | static void uas_stat_cmplt(struct urb *urb) |
231 | { | 228 | { |
232 | struct iu *iu = urb->transfer_buffer; | 229 | struct iu *iu = urb->transfer_buffer; |
233 | struct scsi_device *sdev = urb->context; | 230 | struct Scsi_Host *shost = urb->context; |
234 | struct uas_dev_info *devinfo = sdev->hostdata; | 231 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; |
235 | struct scsi_cmnd *cmnd; | 232 | struct scsi_cmnd *cmnd; |
236 | u16 tag; | 233 | u16 tag; |
237 | 234 | ||
@@ -242,10 +239,10 @@ static void uas_stat_cmplt(struct urb *urb) | |||
242 | } | 239 | } |
243 | 240 | ||
244 | tag = be16_to_cpup(&iu->tag) - 1; | 241 | tag = be16_to_cpup(&iu->tag) - 1; |
245 | if (sdev->current_cmnd) | 242 | if (tag == 0) |
246 | cmnd = sdev->current_cmnd; | 243 | cmnd = devinfo->cmnd; |
247 | else | 244 | else |
248 | cmnd = scsi_find_tag(sdev, tag); | 245 | cmnd = scsi_host_find_tag(shost, tag - 1); |
249 | if (!cmnd) { | 246 | if (!cmnd) { |
250 | usb_free_urb(urb); | 247 | usb_free_urb(urb); |
251 | return; | 248 | return; |
@@ -253,6 +250,9 @@ static void uas_stat_cmplt(struct urb *urb) | |||
253 | 250 | ||
254 | switch (iu->iu_id) { | 251 | switch (iu->iu_id) { |
255 | case IU_ID_STATUS: | 252 | case IU_ID_STATUS: |
253 | if (devinfo->cmnd == cmnd) | ||
254 | devinfo->cmnd = NULL; | ||
255 | |||
256 | if (urb->actual_length < 16) | 256 | if (urb->actual_length < 16) |
257 | devinfo->uas_sense_old = 1; | 257 | devinfo->uas_sense_old = 1; |
258 | if (devinfo->uas_sense_old) | 258 | if (devinfo->uas_sense_old) |
@@ -314,7 +314,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
314 | goto free; | 314 | goto free; |
315 | 315 | ||
316 | usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), | 316 | usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), |
317 | uas_stat_cmplt, cmnd->device); | 317 | uas_stat_cmplt, cmnd->device->host); |
318 | urb->stream_id = stream_id; | 318 | urb->stream_id = stream_id; |
319 | urb->transfer_flags |= URB_FREE_BUFFER; | 319 | urb->transfer_flags |= URB_FREE_BUFFER; |
320 | out: | 320 | out: |
@@ -346,7 +346,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
346 | 346 | ||
347 | iu->iu_id = IU_ID_COMMAND; | 347 | iu->iu_id = IU_ID_COMMAND; |
348 | if (blk_rq_tagged(cmnd->request)) | 348 | if (blk_rq_tagged(cmnd->request)) |
349 | iu->tag = cpu_to_be16(cmnd->request->tag + 1); | 349 | iu->tag = cpu_to_be16(cmnd->request->tag + 2); |
350 | else | 350 | else |
351 | iu->tag = cpu_to_be16(1); | 351 | iu->tag = cpu_to_be16(1); |
352 | iu->prio_attr = UAS_SIMPLE_TAG; | 352 | iu->prio_attr = UAS_SIMPLE_TAG; |
@@ -458,13 +458,13 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
458 | 458 | ||
459 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); | 459 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); |
460 | 460 | ||
461 | if (!cmdinfo->status_urb && sdev->current_cmnd) | 461 | if (devinfo->cmnd) |
462 | return SCSI_MLQUEUE_DEVICE_BUSY; | 462 | return SCSI_MLQUEUE_DEVICE_BUSY; |
463 | 463 | ||
464 | if (blk_rq_tagged(cmnd->request)) { | 464 | if (blk_rq_tagged(cmnd->request)) { |
465 | cmdinfo->stream = cmnd->request->tag + 1; | 465 | cmdinfo->stream = cmnd->request->tag + 2; |
466 | } else { | 466 | } else { |
467 | sdev->current_cmnd = cmnd; | 467 | devinfo->cmnd = cmnd; |
468 | cmdinfo->stream = 1; | 468 | cmdinfo->stream = 1; |
469 | } | 469 | } |
470 | 470 | ||
@@ -565,7 +565,7 @@ static int uas_slave_configure(struct scsi_device *sdev) | |||
565 | { | 565 | { |
566 | struct uas_dev_info *devinfo = sdev->hostdata; | 566 | struct uas_dev_info *devinfo = sdev->hostdata; |
567 | scsi_set_tag_type(sdev, MSG_ORDERED_TAG); | 567 | scsi_set_tag_type(sdev, MSG_ORDERED_TAG); |
568 | scsi_activate_tcq(sdev, devinfo->qdepth - 1); | 568 | scsi_activate_tcq(sdev, devinfo->qdepth - 2); |
569 | return 0; | 569 | return 0; |
570 | } | 570 | } |
571 | 571 | ||
@@ -633,6 +633,7 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) | |||
633 | unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints; | 633 | unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints; |
634 | 634 | ||
635 | devinfo->uas_sense_old = 0; | 635 | devinfo->uas_sense_old = 0; |
636 | devinfo->cmnd = NULL; | ||
636 | 637 | ||
637 | for (i = 0; i < n_endpoints; i++) { | 638 | for (i = 0; i < n_endpoints; i++) { |
638 | unsigned char *extra = endpoint[i].extra; | 639 | unsigned char *extra = endpoint[i].extra; |
@@ -728,7 +729,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
728 | devinfo->udev = udev; | 729 | devinfo->udev = udev; |
729 | uas_configure_endpoints(devinfo); | 730 | uas_configure_endpoints(devinfo); |
730 | 731 | ||
731 | result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 1); | 732 | result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2); |
732 | if (result) | 733 | if (result) |
733 | goto free; | 734 | goto free; |
734 | 735 | ||