Abort any active transfers when the device detaches. This fixes a
few situations where we used to crash, but by no means all of them.
This commit is contained in:
parent
0f68b77a1a
commit
142aa8a840
@ -1133,6 +1133,15 @@ USB_DETACH(umass)
|
||||
|
||||
sc->flags |= UMASS_FLAGS_GONE;
|
||||
|
||||
/* abort all the pipes in case there are transfers active. */
|
||||
usbd_abort_default_pipe(sc->sc_udev);
|
||||
if (sc->bulkout_pipe)
|
||||
usbd_abort_pipe(sc->bulkout_pipe);
|
||||
if (sc->bulkin_pipe)
|
||||
usbd_abort_pipe(sc->bulkin_pipe);
|
||||
if (sc->intrin_pipe)
|
||||
usbd_abort_pipe(sc->intrin_pipe);
|
||||
|
||||
usb_uncallout_drain(sc->cam_scsi_rescan_ch, umass_cam_rescan, sc);
|
||||
if ((sc->proto & UMASS_PROTO_SCSI) ||
|
||||
(sc->proto & UMASS_PROTO_ATAPI) ||
|
||||
@ -1444,6 +1453,14 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
|
||||
USBDEVNAME(sc->sc_dev), sc->transfer_state,
|
||||
states[sc->transfer_state], xfer, usbd_errstr(err)));
|
||||
|
||||
/* Give up if the device has detached. */
|
||||
if (sc->flags & UMASS_FLAGS_GONE) {
|
||||
sc->transfer_state = TSTATE_IDLE;
|
||||
sc->transfer_cb(sc, sc->transfer_priv, sc->transfer_datalen,
|
||||
STATUS_CMD_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sc->transfer_state) {
|
||||
|
||||
/***** Bulk Transfer *****/
|
||||
@ -1897,6 +1914,14 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
|
||||
USBDEVNAME(sc->sc_dev), sc->transfer_state,
|
||||
states[sc->transfer_state], xfer, usbd_errstr(err)));
|
||||
|
||||
/* Give up if the device has detached. */
|
||||
if (sc->flags & UMASS_FLAGS_GONE) {
|
||||
sc->transfer_state = TSTATE_IDLE;
|
||||
sc->transfer_cb(sc, sc->transfer_priv, sc->transfer_datalen,
|
||||
STATUS_CMD_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sc->transfer_state) {
|
||||
|
||||
/***** CBI Transfer *****/
|
||||
@ -2608,6 +2633,13 @@ umass_cam_cb(struct umass_softc *sc, void *priv, int residue, int status)
|
||||
union ccb *ccb = (union ccb *) priv;
|
||||
struct ccb_scsiio *csio = &ccb->csio; /* deref union */
|
||||
|
||||
/* If the device is gone, just fail the request. */
|
||||
if (sc->flags & UMASS_FLAGS_GONE) {
|
||||
ccb->ccb_h.status = CAM_TID_INVALID;
|
||||
xpt_done(ccb);
|
||||
return;
|
||||
}
|
||||
|
||||
csio->resid = residue;
|
||||
|
||||
switch (status) {
|
||||
@ -2685,6 +2717,12 @@ umass_cam_sense_cb(struct umass_softc *sc, void *priv, int residue, int status)
|
||||
unsigned char *rcmd;
|
||||
int rcmdlen;
|
||||
|
||||
if (sc->flags & UMASS_FLAGS_GONE) {
|
||||
ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
|
||||
xpt_done(ccb);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case STATUS_CMD_OK:
|
||||
case STATUS_CMD_UNKNOWN:
|
||||
@ -2778,6 +2816,12 @@ umass_cam_quirk_cb(struct umass_softc *sc, void *priv, int residue, int status)
|
||||
|
||||
DPRINTF(UDMASS_SCSI, ("%s: Test unit ready returned status %d\n",
|
||||
USBDEVNAME(sc->sc_dev), status));
|
||||
|
||||
if (sc->flags & UMASS_FLAGS_GONE) {
|
||||
ccb->ccb_h.status = CAM_TID_INVALID;
|
||||
xpt_done(ccb);
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user