Skip to content

Commit

Permalink
Revert "usb/uas: one only one status URB/host on stream-less connection"
Browse files Browse the repository at this point in the history
This reverts commit ceb3f91.

IMO the real bug is assigning status urbs to scsi requests.  First there
is no such link in the non-stream case.  Also there isn't nessesarely a
scsi request in the first place, for example when submitting task
management requests.

This patch just papers over the real bug and introduces different status
urb handling in the stream/non-stream case for no good reason.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Gerd Hoffmann authored and Greg Kroah-Hartman committed Jun 25, 2012
1 parent c621a81 commit db32de1
Showing 1 changed file with 10 additions and 60 deletions.
70 changes: 10 additions & 60 deletions drivers/usb/storage/uas.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ struct uas_dev_info {
unsigned use_streams:1;
unsigned uas_sense_old:1;
struct scsi_cmnd *cmnd;
struct urb *status_urb; /* used only if stream support is available */
};

enum {
Expand All @@ -65,7 +64,6 @@ struct uas_cmd_info {
unsigned int state;
unsigned int stream;
struct urb *cmd_urb;
/* status_urb is used only if stream support isn't available */
struct urb *status_urb;
struct urb *data_in_urb;
struct urb *data_out_urb;
Expand Down Expand Up @@ -129,6 +127,7 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)

cmnd->result = sense_iu->status;
cmnd->scsi_done(cmnd);
usb_free_urb(urb);
}

static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
Expand All @@ -153,6 +152,7 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)

cmnd->result = sense_iu->status;
cmnd->scsi_done(cmnd);
usb_free_urb(urb);
}

static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
Expand All @@ -161,7 +161,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
int err;

cmdinfo->state = direction;
cmdinfo->state = direction | SUBMIT_STATUS_URB;
err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
if (err) {
spin_lock(&uas_work_lock);
Expand All @@ -178,12 +178,10 @@ static void uas_stat_cmplt(struct urb *urb)
struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
struct scsi_cmnd *cmnd;
u16 tag;
int ret;

if (urb->status) {
dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status);
if (devinfo->use_streams)
usb_free_urb(urb);
usb_free_urb(urb);
return;
}

Expand All @@ -193,13 +191,7 @@ static void uas_stat_cmplt(struct urb *urb)
else
cmnd = scsi_host_find_tag(shost, tag - 1);
if (!cmnd) {
if (devinfo->use_streams) {
usb_free_urb(urb);
return;
}
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret)
dev_err(&urb->dev->dev, "failed submit status urb\n");
usb_free_urb(urb);
return;
}

Expand All @@ -225,15 +217,6 @@ static void uas_stat_cmplt(struct urb *urb)
scmd_printk(KERN_ERR, cmnd,
"Bogus IU (%d) received on status pipe\n", iu->iu_id);
}

if (devinfo->use_streams) {
usb_free_urb(urb);
return;
}

ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret)
dev_err(&urb->dev->dev, "failed submit status urb\n");
}

static void uas_data_cmplt(struct urb *urb)
Expand Down Expand Up @@ -264,7 +247,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
}

static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
struct Scsi_Host *shost, u16 stream_id)
struct scsi_cmnd *cmnd, u16 stream_id)
{
struct usb_device *udev = devinfo->udev;
struct urb *urb = usb_alloc_urb(0, gfp);
Expand All @@ -278,7 +261,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
goto free;

usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu),
uas_stat_cmplt, shost);
uas_stat_cmplt, cmnd->device->host);
urb->stream_id = stream_id;
urb->transfer_flags |= URB_FREE_BUFFER;
out:
Expand Down Expand Up @@ -340,8 +323,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;

if (cmdinfo->state & ALLOC_STATUS_URB) {
cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp,
cmnd->device->host, cmdinfo->stream);
cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd,
cmdinfo->stream);
if (!cmdinfo->status_urb)
return SCSI_MLQUEUE_DEVICE_BUSY;
cmdinfo->state &= ~ALLOC_STATUS_URB;
Expand Down Expand Up @@ -450,8 +433,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
}

if (!devinfo->use_streams) {
cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB |
ALLOC_STATUS_URB | SUBMIT_STATUS_URB);
cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
cmdinfo->stream = 0;
}

Expand Down Expand Up @@ -662,29 +644,6 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo)
}
}

static int uas_alloc_status_urb(struct uas_dev_info *devinfo,
struct Scsi_Host *shost)
{
if (devinfo->use_streams) {
devinfo->status_urb = NULL;
return 0;
}

devinfo->status_urb = uas_alloc_sense_urb(devinfo, GFP_KERNEL,
shost, 0);
if (!devinfo->status_urb)
goto err_s_urb;

if (usb_submit_urb(devinfo->status_urb, GFP_KERNEL))
goto err_submit_urb;

return 0;
err_submit_urb:
usb_free_urb(devinfo->status_urb);
err_s_urb:
return -ENOMEM;
}

static void uas_free_streams(struct uas_dev_info *devinfo)
{
struct usb_device *udev = devinfo->udev;
Expand Down Expand Up @@ -739,17 +698,10 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)

shost->hostdata[0] = (unsigned long)devinfo;

result = uas_alloc_status_urb(devinfo, shost);
if (result)
goto err_alloc_status;

scsi_scan_host(shost);
usb_set_intfdata(intf, shost);
return result;

err_alloc_status:
scsi_remove_host(shost);
shost = NULL;
deconfig_eps:
uas_free_streams(devinfo);
free:
Expand Down Expand Up @@ -777,8 +729,6 @@ static void uas_disconnect(struct usb_interface *intf)
struct uas_dev_info *devinfo = (void *)shost->hostdata[0];

scsi_remove_host(shost);
usb_kill_urb(devinfo->status_urb);
usb_free_urb(devinfo->status_urb);
uas_free_streams(devinfo);
kfree(devinfo);
}
Expand Down

0 comments on commit db32de1

Please sign in to comment.