From 669d9046a932e070a7e83b671a4d484ca6c1a11e Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 11 Apr 2011 08:23:27 +0000 Subject: [PATCH] Rework change made at r203146. Instead of reporting all wire errors as SCSI status errors to CAM (that was wrong, as it too often turned retriable wire errors into non-retriable REQUEST SENSE errors), do it only for STALL errors on control pipe of the CBI devices. STALL on control pipe is just a one of the ways to report error for CBI devices. PR: usb/150401, usb/154593. Reviewed by: hselasky MFC after: 1 week --- sys/dev/usb/storage/umass.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index 208616ee9df..de6ad9da9a9 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -1849,9 +1849,23 @@ umass_t_cbi_command_callback(struct usb_xfer *xfer, usb_error_t error) break; default: /* Error */ - umass_tr_error(xfer, error); - /* skip reset */ - sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; + /* + * STALL on the control pipe can be result of the command error. + * Attempt to clear this STALL same as for bulk pipe also + * results in command completion interrupt, but ASC/ASCQ there + * look like not always valid, so don't bother about it. + */ + if ((error == USB_ERR_STALLED) || + (sc->sc_transfer.callback == &umass_cam_cb)) { + sc->sc_transfer.ccb = NULL; + (sc->sc_transfer.callback) + (sc, ccb, sc->sc_transfer.data_len, + STATUS_CMD_UNKNOWN); + } else { + umass_tr_error(xfer, error); + /* skip reset */ + sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; + } break; } } @@ -2605,17 +2619,9 @@ umass_cam_cb(struct umass_softc *sc, union ccb *ccb, uint32_t residue, /* * The wire protocol failed and will hopefully have * recovered. We return an error to CAM and let CAM - * retry the command if necessary. In case of SCSI IO - * commands we ask the CAM layer to check the - * condition first. This is a quick hack to make - * certain devices work. + * retry the command if necessary. */ - if (ccb->ccb_h.func_code == XPT_SCSI_IO) { - ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; - ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; - } else { - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - } + ccb->ccb_h.status = CAM_REQ_CMP_ERR; xpt_done(ccb); break; }