summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorn_hibma <n_hibma@FreeBSD.org>1999-06-20 15:46:13 +0000
committern_hibma <n_hibma@FreeBSD.org>1999-06-20 15:46:13 +0000
commit1c9d24db05f217c3166c020142180d81282e8414 (patch)
tree23c87c2a5fdd13d5f7208d34e04de3dfb7cbca2d
parent788bc0cf602a4339422fb952290bf85f5e320e07 (diff)
downloadFreeBSD-src-1c9d24db05f217c3166c020142180d81282e8414.zip
FreeBSD-src-1c9d24db05f217c3166c020142180d81282e8414.tar.gz
1) Do not include usbdivar.h and access the interface descriptor through
usbd_get_interface_descriptor 2) remove soft reset. It's been dropped from the USB Mass Storage Bulk-Only Specification 3) move the clear feature halt to the reset routine.
-rw-r--r--sys/dev/usb/umass.c127
1 files changed, 39 insertions, 88 deletions
diff --git a/sys/dev/usb/umass.c b/sys/dev/usb/umass.c
index c7e4ad9..6e943d7 100644
--- a/sys/dev/usb/umass.c
+++ b/sys/dev/usb/umass.c
@@ -56,7 +56,6 @@
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
#include <dev/usb/usbdi_util.h>
#include <cam/cam.h>
@@ -87,13 +86,6 @@ typedef struct umass_softc {
struct cam_sim *sim; /* SCSI Interface Module */
struct cam_path *path; /* XPT path */
-
- /* we count the number of soft retries that failed. If 5 have failed,
- * the device does not support them for example, we revert to hard
- * resets.
- */
- int soft_tries; /* retries to do soft reset */
-# define MAX_SOFT_TRIES 5
} umass_softc_t;
#define USBD_COMMAND_FAILED USBD_INVAL /* redefine some errors for */
@@ -109,8 +101,6 @@ typedef struct umass_softc {
/* Bulk-Only specific request */
#define UR_RESET 0xff
-#define URESET_HARD 0x00
-#define URESET_SOFT 0x01
/* Bulk-Only Mass Storage features */
/* Command Block Wrapper */
@@ -151,7 +141,7 @@ usbd_status umass_usb_transfer __P((usbd_interface_handle iface,
int flags, int *xfer_size));
/* Bulk-Only related functions */
-usbd_status umass_bulk_reset __P((umass_softc_t *sc, int flag));
+usbd_status umass_bulk_reset __P((umass_softc_t *sc));
usbd_status umass_bulk_transfer __P((umass_softc_t *sc, int lun,
void *cmd, int cmdlen,
void *data, int datalen,
@@ -197,7 +187,6 @@ USB_ATTACH(umass)
sc->sc_iface = uaa->iface;
sc->sc_bulkout_pipe = NULL;
sc->sc_bulkin_pipe = NULL;
- sc->soft_tries = 0;
usbd_devinfo(uaa->device, 0, devinfo);
USB_ATTACH_SETUP;
@@ -336,83 +325,52 @@ umass_usb_transfer(usbd_interface_handle iface, usbd_pipe_handle pipe,
-/*
- * USB Mass Storage Bulk-Only specific request
- */
-
-/*
- * The Reset request shall be sent via the Control endpoint to the device.
- *
- * There are two types of Bulk-Only Mass Storage Resets; soft and hard.
- * Implementation of the soft is optional. If the soft one fails, the hard one
- * is immediately tried.
- *
- * Soft reset shall clear all buffers and reset the interface to the device
- * without affecting the state of the device itself.
- * Hard reset shall clear all buffers and reset the interface and the
- * device without changing STALL or toggle conditions.
- */
-
-/*
- * XXX Pat LaVarre <LAVARRE@iomega.com> says that soft reset has been removed
- * from current versions of the spec. We can remove it once that checks out.
- */
-
usbd_status
-umass_bulk_reset(umass_softc_t *sc, int flag)
+umass_bulk_reset(umass_softc_t *sc)
{
usbd_device_handle dev;
usb_device_request_t req;
usbd_status err;
+ usb_interface_descriptor_t *id;
- DPRINTF(UDMASS_BULK, ("%s: %s reset\n",
- USBDEVNAME(sc->sc_dev),
- (flag == URESET_SOFT? "Soft":"Hard")));
-
- /* Avoid useless attempts at soft-resetting the drive
- * XXX Could be done with a quirk entry somewhere as well.
+ /*
+ * Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
+ *
+ * For Reset Recovery the host shall issue in the following order:
+ * a) a Bulk-Only Mass Storage Reset
+ * b) a Clear Feature HALT to the Bulk-In endpoint
+ * c) a Clear Feature HALT to the Bulk-Out endpoint
*/
- if (flag == URESET_SOFT && sc->soft_tries > MAX_SOFT_TRIES)
- flag = URESET_HARD;
+
+ DPRINTF(UDMASS_BULK, ("%s: Reset\n",
+ USBDEVNAME(sc->sc_dev)));
usbd_interface2device_handle(sc->sc_iface, &dev);
+ id = usbd_get_interface_descriptor(sc->sc_iface);
/* the reset command is a class specific interface request */
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_RESET;
- USETW(req.wValue, flag); /* type of reset: hard/soft */
- USETW(req.wIndex, sc->sc_iface->idesc->bInterfaceNumber);
- USETW(req.wLength, 0); /* no data stage */
+ USETW(req.wValue, 0);
+ USETW(req.wIndex, id->bInterfaceNumber);
+ USETW(req.wLength, 0);
err = usbd_do_request(dev, &req, 0);
if (err) {
- if (flag == URESET_SOFT) {
- /* reset again, but now hard. Soft reset is optional in the
- * Bulk-Only spec.
- */
- sc->soft_tries++;
- DPRINTF(UDMASS_USB, ("%s: Soft reset failed (%d), %s\n",
- USBDEVNAME(sc->sc_dev),
- sc->soft_tries, usbd_errstr(err)));
- return(umass_bulk_reset(sc, URESET_HARD));
- } else {
- printf("%s: Hard reset failed, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- /* XXX we should port_reset the device */
- return(err);
- }
+ printf("%s: Reset failed, %s\n",
+ USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ /* XXX we should port_reset the device */
+ return(err);
}
- /* we do not need to wait for the device to finish the reset.
- * From the Bulk-Only spec (5.3.3):
- * "For either Bulk-Only Mass Storage Reset, hard, or soft, the device
- * shall NAK the status stage of Control request until the reset is
- * complete."
- *
- * XXX (Iomega Zip 100) For some reason we get timeouts if we don't. :-(
- * The 2.5sec. is a guessed value.
+ usbd_clear_endpoint_stall(sc->sc_bulkout_pipe);
+ usbd_clear_endpoint_stall(sc->sc_bulkin_pipe);
+
+ /*
+ * XXX we should convert this into a more friendly delay.
+ * Perhaps a tsleep (or is this routine run from int context?)
*/
-
+
DELAY(2500000 /*us*/);
return(USBD_NORMAL_COMPLETION);
@@ -513,11 +471,10 @@ umass_bulk_transfer(umass_softc_t *sc, int lun, void *cmd, int cmdlen,
DPRINTF(UDMASS_BULK, ("%s: failed to send CBW\n",
USBDEVNAME(sc->sc_dev)));
/* If the device detects that the CBW is invalid, then the
- * device shall STALL both bulk endpoints and require a
- * Bulk-Only MS Reset (hard)
+ * device may STALL both bulk endpoints and require a
+ * Bulk-Only MS Reset
*/
- umass_bulk_reset(sc, URESET_HARD);
- usbd_clear_endpoint_stall(sc->sc_bulkout_pipe);
+ umass_bulk_reset(sc);
return(USBD_IOERROR);
}
@@ -573,8 +530,7 @@ umass_bulk_transfer(umass_softc_t *sc, int lun, void *cmd, int cmdlen,
*/
/* Invalid CSW: Wrong signature or wrong tag might indicate
- * that the device is confused -> reset it hard, to remove
- * all its state.
+ * that the device is confused -> reset it.
* Other fatal errors: STALL on read of CSW and Phase error
* or unknown status.
*/
@@ -599,9 +555,7 @@ umass_bulk_transfer(umass_softc_t *sc, int lun, void *cmd, int cmdlen,
UGETDW(csw.dCSWSignature),
UGETDW(csw.dCSWTag), UGETDW(cbw.dCBWTag));
}
- umass_bulk_reset(sc, URESET_HARD);
- usbd_clear_endpoint_stall(sc->sc_bulkout_pipe);
- usbd_clear_endpoint_stall(sc->sc_bulkin_pipe);
+ umass_bulk_reset(sc);
return(USBD_IOERROR);
}
@@ -610,18 +564,15 @@ umass_bulk_transfer(umass_softc_t *sc, int lun, void *cmd, int cmdlen,
"residue = %d, n = %d\n",
USBDEVNAME(sc->sc_dev),
UGETDW(csw.dCSWDataResidue), n));
- /*
- * According to Pat LaVarre <LAVARRE@iomega.com> on the linux-usb
- * mailing list this reset is not necessary at all. It looks like
- * I have an old revision of the spec.
- */
-
- /* umass_bulk_reset(sc, URESET_SOFT); */
-
*residue = UGETDW(csw.dCSWDataResidue);
return(USBD_COMMAND_FAILED);
}
+ /*
+ * XXX a residue not equal to 0 might indicate that something
+ * is wrong. Does CAM high level drivers check this for us?
+ */
+
return(USBD_NORMAL_COMPLETION);
}
@@ -782,7 +733,7 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
DPRINTF(UDMASS_CAM, ("%s: XPT_RESET_{BUS,DEV}\n",
USBDEVNAME(sc->sc_dev)));
- err = umass_bulk_reset(sc, URESET_HARD);
+ err = umass_bulk_reset(sc);
if (err)
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
else
OpenPOWER on IntegriCloud