/* Command timeout and abort */ static int command_abort(struct scsi_cmnd *srb) { struct us_data *us = host_to_us(srb->device->host); US_DEBUGP("%s called\n", __FUNCTION__); /* us->srb together with the TIMED_OUT, RESETTING, and ABORTING * bits are protected by the host lock. */ scsi_lock(us_to_host(us)); /* Is this command still active? */ if (us->srb != srb) { scsi_unlock(us_to_host(us)); US_DEBUGP ("-- nothing to abort\n"); return FAILED; } /* Set the TIMED_OUT bit. Also set the ABORTING bit, but only if * a device reset isn't already in progress (to avoid interfering * with the reset). Note that we must retain the host lock while * calling usb_stor_stop_transport(); otherwise it might interfere * with an auto-reset that begins as soon as we release the lock. */ set_bit(US_FLIDX_TIMED_OUT, &us->flags); if (!test_bit(US_FLIDX_RESETTING, &us->flags)) { set_bit(US_FLIDX_ABORTING, &us->flags); usb_stor_stop_transport(us); } scsi_unlock(us_to_host(us)); /* Wait for the aborted command to finish */ wait_for_completion(&us->notify); return SUCCESS; }
/* This is always called with scsi_lock(host) held */ static int command_abort(struct scsi_cmnd *srb) { struct us_data *us = host_to_us(srb->device->host); US_DEBUGP("%s called\n", __FUNCTION__); /* Is this command still active? */ if (us->srb != srb) { US_DEBUGP ("-- nothing to abort\n"); return FAILED; } /* Set the TIMED_OUT bit. Also set the ABORTING bit, but only if * a device reset isn't already in progress (to avoid interfering * with the reset). To prevent races with auto-reset, we must * stop any ongoing USB transfers while still holding the host * lock. */ set_bit(US_FLIDX_TIMED_OUT, &us->flags); if (!test_bit(US_FLIDX_RESETTING, &us->flags)) { set_bit(US_FLIDX_ABORTING, &us->flags); usb_stor_stop_transport(us); } /* Wait for the aborted command to finish */ wait_for_completion(&us->notify); /* Reacquire the lock and allow USB transfers to resume */ clear_bit(US_FLIDX_ABORTING, &us->flags); clear_bit(US_FLIDX_TIMED_OUT, &us->flags); return SUCCESS; }
/* This is always called with scsi_lock(srb->host) held */ static int command_abort(struct scsi_cmnd *srb ) { struct us_data *us = host_to_us(srb->device->host); US_DEBUGP("%s called\n", __FUNCTION__); /* Is this command still active? */ if (us->srb != srb) { US_DEBUGP ("-- nothing to abort\n"); return FAILED; } /* Normally the current state is RUNNING. If the control thread * hasn't even started processing this command, the state will be * IDLE. Anything else is a bug. */ if (us->sm_state != US_STATE_RUNNING && us->sm_state != US_STATE_IDLE) { printk(KERN_ERR USB_STORAGE "Error in %s: " "invalid state %d\n", __FUNCTION__, us->sm_state); return FAILED; } /* Set state to ABORTING and set the ABORTING bit, but only if * a device reset isn't already in progress (to avoid interfering * with the reset). To prevent races with auto-reset, we must * stop any ongoing USB transfers while still holding the host * lock. */ us->sm_state = US_STATE_ABORTING; if (!test_bit(US_FLIDX_RESETTING, &us->flags)) { set_bit(US_FLIDX_ABORTING, &us->flags); usb_stor_stop_transport(us); } scsi_unlock(us_to_host(us)); /* Wait for the aborted command to finish */ wait_for_completion(&us->notify); /* Reacquire the lock and allow USB transfers to resume */ scsi_lock(us_to_host(us)); clear_bit(US_FLIDX_ABORTING, &us->flags); return SUCCESS; }