int status;
/* don't submit URBs during abort/disconnect processing */
- if (us->flags & DONT_SUBMIT)
+ if (us->flags & ABORTING_OR_DISCONNECTING)
return -EIO;
/* set up data structures for the wakeup system */
set_bit(US_FLIDX_URB_ACTIVE, &us->flags);
/* did an abort/disconnect occur during the submission? */
- if (us->flags & DONT_SUBMIT) {
+ if (us->flags & ABORTING_OR_DISCONNECTING) {
/* cancel the URB, if it hasn't been cancelled already */
if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) {
int result;
/* don't submit s-g requests during abort/disconnect processing */
- if (us->flags & DONT_SUBMIT)
+ if (us->flags & ABORTING_OR_DISCONNECTING)
return USB_STOR_XFER_ERROR;
/* initialize the scatter-gather request block */
set_bit(US_FLIDX_SG_ACTIVE, &us->flags);
/* did an abort/disconnect occur during the submission? */
- if (us->flags & DONT_SUBMIT) {
+ if (us->flags & ABORTING_OR_DISCONNECTING) {
/* cancel the request, if it hasn't been cancelled already */
if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
/* abort processing: the bulk-only transport requires a reset
* following an abort */
- Handle_Abort:
+ Handle_Abort:
srb->result = DID_ABORT << 16;
- if (us->protocol == US_PR_BULK) {
-
- /* permit the reset transfer to take place */
- clear_bit(US_FLIDX_ABORTING, &us->flags);
+ if (us->protocol == US_PR_BULK)
us->transport_reset(us);
- }
}
/* Stop the current URB transfer */
USB_RECIP_INTERFACE,
0, us->ifnum, us->iobuf, 1, HZ);
+ /*
+ * 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) {
+ usb_stor_clear_halt(us, us->recv_bulk_pipe);
+ usb_stor_clear_halt(us, us->send_bulk_pipe);
+ }
+
US_DEBUGP("GetMaxLUN command result is %d, data is %d\n",
result, us->iobuf[0]);
{
int result;
int result2;
+ int rc = FAILED;
- /* Let the SCSI layer know we are doing a reset */
+ /* Let the SCSI layer know we are doing a reset, set the
+ * RESETTING bit, and clear the ABORTING bit so that the reset
+ * may proceed.
+ */
+ scsi_lock(us->host);
usb_stor_report_device_reset(us);
+ set_bit(US_FLIDX_RESETTING, &us->flags);
+ clear_bit(US_FLIDX_ABORTING, &us->flags);
+ scsi_unlock(us->host);
/* A 20-second timeout may seem rather long, but a LaCie
- * StudioDrive USB2 device takes 16+ seconds to get going
- * following a powerup or USB attach event. */
-
+ * StudioDrive USB2 device takes 16+ seconds to get going
+ * following a powerup or USB attach event.
+ */
result = usb_stor_control_msg(us, us->send_ctrl_pipe,
request, requesttype, value, index, data, size,
20*HZ);
if (result < 0) {
US_DEBUGP("Soft reset failed: %d\n", result);
- return FAILED;
+ goto Done;
}
/* long wait for reset, so unlock to allow disconnects */
up(&us->dev_semaphore);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ*6);
+ msleep(6000);
down(&us->dev_semaphore);
if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
US_DEBUGP("Reset interrupted by disconnect\n");
- return FAILED;
+ goto Done;
}
- /* permit the clear-halt transfers to take place */
- clear_bit(US_FLIDX_ABORTING, &us->flags);
-
US_DEBUGP("Soft reset: clearing bulk-in endpoint halt\n");
result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
/* return a result code based on the result of the control message */
if (result < 0 || result2 < 0) {
US_DEBUGP("Soft reset failed\n");
- return FAILED;
+ goto Done;
}
US_DEBUGP("Soft reset done\n");
- return SUCCESS;
+ rc = SUCCESS;
+
+ Done:
+ clear_bit(US_FLIDX_RESETTING, &us->flags);
+ return rc;
}
/* This issues a CB[I] Reset to the device in question