X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fstorage%2Ftransport.c;h=232155854fba924a807d633c036f71c42e224ee1;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=e42c59a1be5a6969f0e400e7be33f679ad5ff8ea;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index e42c59a1b..232155854 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -708,6 +708,12 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) srb->sense_buffer[0] = 0x0; } } + + /* Did we transfer less than the minimum amount required? */ + if (srb->result == SAM_STAT_GOOD && + srb->request_bufflen - srb->resid < srb->underflow) + srb->result = (DID_ERROR << 16) | (SUGGEST_RETRY << 24); + return; /* abort processing: the bulk-only transport requires a reset @@ -908,26 +914,29 @@ int usb_stor_Bulk_max_lun(struct us_data *us) USB_RECIP_INTERFACE, 0, us->ifnum, us->iobuf, 1, HZ); + US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", + result, us->iobuf[0]); + + /* if we have a successful request, return the result */ + if (result == 1) + return us->iobuf[0]; + /* * Some devices (i.e. Iomega Zip100) need this -- apparently * the bulk pipes get STALLed when the GetMaxLUN request is * processed. This is, in theory, harmless to all other devices * (regardless of if they stall or not). */ - if (result < 0) { + if (result == -EPIPE) { usb_stor_clear_halt(us, us->recv_bulk_pipe); usb_stor_clear_halt(us, us->send_bulk_pipe); + /* return the default -- no LUNs */ + return 0; } - US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", - result, us->iobuf[0]); - - /* if we have a successful request, return the result */ - if (result == 1) - return us->iobuf[0]; - - /* return the default -- no LUNs */ - return 0; + /* An answer or a STALL are the only valid responses. If we get + * something else, return an indication of error */ + return -1; } int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) @@ -1110,10 +1119,11 @@ static int usb_stor_reset_common(struct us_data *us, goto Done; } - /* long wait for reset, so unlock to allow disconnects */ - up(&us->dev_semaphore); - msleep(6000); - down(&us->dev_semaphore); + /* Give the device some time to recover from the reset, + * but don't delay disconnect processing. */ + wait_event_interruptible_timeout(us->dev_reset_wait, + test_bit(US_FLIDX_DISCONNECTING, &us->flags), + HZ*6); if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { US_DEBUGP("Reset interrupted by disconnect\n"); goto Done;