HEADSUP!!! USB MFC committed..
Barry Bouwsma
freebsd-misuser at remove-NOSPAM-to-reply.NOSPAM.dyndns.dk
Wed Jun 9 20:16:21 GMT 2004
Yesterday I wrote:
> What I'd done is to both try to merge in the diff mentioned earlier
> into the -stable umass.c code, and also to try to take the latest
> -current umass.c code and massage it to play nicely with -stable.
....
> As mentioned, my other approach was to take the RELENG_4 umass.c code
> and merge in the hacks from the earlier-mentioned diff.
> This includes quirks I seemed to need to add to get my digital camera
> to be found, as well as an in-progress snapshot against a card reader
> which never wanted to completely cooperate with 4.x code.
> [ AIEEE. This diff is littered with in-progress clutter.
> I'll spare you this until I clean it up for presentation.
> Sorry. ]
> (I'll post cleaned patches based on -stable umass.c sometime)
Here you are.
Note: I haven't applied *this* against 4.10/RELENG_4 and tried
to build it -- I just made this diff after stripping out all the
unneeded crud from my 4.x-based umass.c. It *should* work but I
make no promises (my unclean version ``worked'').
As I noted, this doesn't work quite as well as the patch against
-current I posted earlier, with -stable. However, for those who
prefer to stay with patches against -stable, I'm happy to provide
this, based on a diff long ago, and also against -current when
necessary. (This *is* a patch against RELENG_4 as of 26.May, and
should apply fairly cleanly to 4.10.)
See the last message in the References: header for further
clarification of what is to be found in this hack. The primary
intent of this is to get the various slots in an x-in-one card
reader to all appear at attachment, instead of just the first.
--- /stand/FreeBSD4-src/source-hacks/sys/dev/usb/umass.c-4.10-ORIG Wed May 26 21:18:30 2004
+++ umass.c Wed Jun 9 21:47:19 2004
@@ -175,14 +175,7 @@
* The SIM is the highest target number. This makes sure that umass0 corresponds
* to target 0 on the USB SCSI bus.
*/
-#ifndef USB_DEBUG
-#define UMASS_SCSIID_MAX 32 /* maximum number of drives expected */
-#else
-/* while debugging avoid unnecessary clutter in the output at umass_cam_rescan
- * (XPT_PATH_INQ)
- */
-#define UMASS_SCSIID_MAX 3 /* maximum number of drives expected */
-#endif
+#define UMASS_SCSIID_MAX 1 /* maximum number of drives expected */
#define UMASS_SCSIID_HOST UMASS_SCSIID_MAX
#define UMASS_SIM_UNIT 0 /* we use one sim for all drives */
@@ -277,6 +270,8 @@
USBBASEDEVICE sc_dev; /* base device */
usbd_device_handle sc_udev; /* USB device */
+ struct cam_sim *umass_sim; /* SCSI Interface Module */
+
unsigned char flags; /* various device flags */
# define UMASS_FLAGS_GONE 0x01 /* devices is no more */
@@ -310,6 +305,11 @@
# define WRONG_CSWSIG 0x10
/* The device can't count and gets the residue of transfers wrong */
# define IGNORE_RESIDUE 0x80
+/* XXX HACK */
+ /* Some devices take a while to fail the MAX LUN query. It will
+ take me longer to hack this in than the total time I've
+ waited, so I'll do it anyway and see if I can get it right. */
+# define NO_MAXLUN 0x40
unsigned int proto;
@@ -524,10 +524,9 @@
(struct cam_periph *periph,union ccb *ccb);
Static void umass_cam_rescan (struct umass_softc *sc);
-Static int umass_cam_attach_sim (void);
+Static int umass_cam_attach_sim (struct umass_softc *sc);
Static int umass_cam_attach (struct umass_softc *sc);
-Static int umass_cam_detach_sim (void);
-Static int umass_cam_detach (struct umass_softc *sc);
+Static int umass_cam_detach_sim (struct umass_softc *sc);
/* SCSI specific functions */
@@ -623,6 +622,30 @@
sc->drive = SHUTTLE_EUSB;
}
+/* XXXX HACKS */
+ if (UGETW(dd->idVendor) == 0x0784) /* JENOPTIK */ {
+ sc->quirks |= NO_TEST_UNIT_READY | FORCE_SHORT_INQUIRY;
+ }
+/* XXX END HACK */
+
+/* XXX HACK OTi (tevion) cardreader seems to take a while to be
+ found with this -stable code; try a few quirk entries to
+ see if I can speed things up a bit... */
+ if (UGETW(dd->idVendor) == 0x0ea0 /* OTi */
+ && UGETW(dd->idProduct) == 0x2126) /* 7-in-1 Card Reader */ {
+/* quiets things, still hangs at replug... sc->quirks |= NO_TEST_UNIT_READY ; */
+/* Hmmm. first plug gets BBB Reset; following ones don't and go quickly... sc->quirks |= NO_TEST_UNIT_READY | NO_START_STOP ; */
+/* Well. Seems like NO_START_STOP... sc->quirks |= NO_TEST_UNIT_READY | FORCE_SHORT_INQUIRY ; */
+ sc->quirks |= NO_TEST_UNIT_READY | FORCE_SHORT_INQUIRY | NO_START_STOP ;
+ }
+
+/* XXX Another hack, try to speed up MAX_LUN probing */
+ if (UGETW(dd->idVendor) == 0x0d49 /* Maxtor */
+ && UGETW(dd->idProduct) == 0x5000) /* 5000XT */ {
+ /* printf("Adding QUIRKS for Maxtor drive...\n"); */
+ sc->quirks |= NO_MAXLUN;
+ }
+
/*
* The Pentax Optio cameras require RS_NO_CLEAR_UA
* PR: kern/46369, kern/50271
@@ -1018,7 +1041,8 @@
/* Get the maximum LUN supported by the device.
*/
- if ((sc->proto & UMASS_PROTO_WIRE) == UMASS_PROTO_BBB)
+ if ((sc->proto & UMASS_PROTO_WIRE) == UMASS_PROTO_BBB &&
+ !(sc->quirks & NO_MAXLUN) )
sc->maxlun = umass_bbb_get_max_lun(sc);
else
sc->maxlun = 0;
@@ -1031,18 +1055,16 @@
sc->cam_scsi_sense.opcode = REQUEST_SENSE;
sc->cam_scsi_test_unit_ready.opcode = TEST_UNIT_READY;
- /* If this is the first device register the SIM */
- if (umass_sim == NULL) {
- err = umass_cam_attach_sim();
- if (err) {
- umass_detach(self);
- USB_ATTACH_ERROR_RETURN;
- }
+ /* register the SIM */
+ err = umass_cam_attach_sim(sc);
+ if (err) {
+ umass_detach(self);
+ USB_ATTACH_ERROR_RETURN;
}
-
- /* Attach the new device to our SCSI host controller (SIM) */
+ /* scan the new sim */
err = umass_cam_attach(sc);
if (err) {
+ umass_cam_detach_sim(sc);
umass_detach(self);
USB_ATTACH_ERROR_RETURN;
}
@@ -1071,8 +1093,8 @@
(sc->proto & UMASS_PROTO_ATAPI) ||
(sc->proto & UMASS_PROTO_UFI) ||
(sc->proto & UMASS_PROTO_RBC))
- /* detach the device from the SCSI host controller (SIM) */
- err = umass_cam_detach(sc);
+ /* detach the SCSI host controller (SIM) */
+ err = umass_cam_detach_sim(sc);
for (i = 0; i < XFER_NR; i++)
if (sc->transfer_xfer[i])
@@ -1354,6 +1376,10 @@
struct umass_softc *sc = (struct umass_softc *) priv;
usbd_xfer_handle next_xfer;
+/* XXX HACK */
+ int Residue;
+/* HACK */
+
KASSERT(sc->proto & UMASS_PROTO_BBB,
("sc->proto == 0x%02x wrong for umass_bbb_state\n",sc->proto));
@@ -1525,6 +1551,11 @@
UGETDW(sc->csw.dCSWSignature) == CSWSIGNATURE_OLYMPUS_C1)
USETDW(sc->csw.dCSWSignature, CSWSIGNATURE);
+ Residue = UGETDW(sc->csw.dCSWDataResidue);
+ if (Residue == 0 &&
+ sc->transfer_datalen - sc->transfer_actlen != 0)
+ Residue = sc->transfer_datalen - sc->transfer_actlen;
+
/* Check CSW and handle any error */
if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) {
/* Invalid CSW: Wrong signature or wrong tag might
@@ -1558,8 +1589,7 @@
return;
} else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) {
printf("%s: Phase Error, residue = %d\n",
- USBDEVNAME(sc->sc_dev),
- UGETDW(sc->csw.dCSWDataResidue));
+ USBDEVNAME(sc->sc_dev), Residue);
umass_bbb_reset(sc, STATUS_WIRE_FAILED);
return;
@@ -2085,7 +2115,7 @@
*/
Static int
-umass_cam_attach_sim()
+umass_cam_attach_sim(struct umass_softc *sc)
{
struct cam_devq *devq; /* Per device Queue */
@@ -2099,17 +2129,20 @@
if (devq == NULL)
return(ENOMEM);
- umass_sim = cam_sim_alloc(umass_cam_action, umass_cam_poll, DEVNAME_SIM,
- NULL /*priv*/, UMASS_SIM_UNIT /*unit number*/,
+ sc->umass_sim = cam_sim_alloc(umass_cam_action, umass_cam_poll,
+ DEVNAME_SIM,
+ sc /*priv*/,
+ USBDEVUNIT(sc->sc_dev) /*unit number*/,
1 /*maximum device openings*/,
0 /*maximum tagged device openings*/,
devq);
- if (umass_sim == NULL) {
+ if (sc->umass_sim == NULL) {
cam_simq_free(devq);
return(ENOMEM);
}
- if(xpt_bus_register(umass_sim, UMASS_SCSI_BUS) != CAM_SUCCESS)
+ if(xpt_bus_register(sc->umass_sim, USBDEVUNIT(sc->sc_dev)) !=
+ CAM_SUCCESS)
return(ENOMEM);
return(0);
@@ -2120,12 +2153,12 @@
{
#ifdef USB_DEBUG
if (ccb->ccb_h.status != CAM_REQ_CMP) {
- DPRINTF(UDMASS_SCSI, ("scbus%d: Rescan failed, 0x%04x\n",
- cam_sim_path(umass_sim),
+ DPRINTF(UDMASS_SCSI, ("%s:%d Rescan failed, 0x%04x\n",
+ periph->periph_name, periph->unit_number,
ccb->ccb_h.status));
} else {
- DPRINTF(UDMASS_SCSI, ("scbus%d: Rescan succeeded\n",
- cam_sim_path(umass_sim)));
+ DPRINTF(UDMASS_SCSI, ("%s%d: Rescan succeeded\n",
+ periph->periph_name, periph->unit_number));
}
#endif
@@ -2142,11 +2175,11 @@
memset(ccb, 0, sizeof(union ccb));
DPRINTF(UDMASS_SCSI, ("scbus%d: scanning for %s:%d:%d:%d\n",
- cam_sim_path(umass_sim),
- USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
+ cam_sim_path(sc->umass_sim),
+ USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
USBDEVUNIT(sc->sc_dev), CAM_LUN_WILDCARD));
- if (xpt_create_path(&path, xpt_periph, cam_sim_path(umass_sim),
+ if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->umass_sim),
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)
!= CAM_REQ_CMP)
return;
@@ -2163,27 +2196,13 @@
Static int
umass_cam_attach(struct umass_softc *sc)
{
- /* SIM already attached at module load. The device is a target on the
- * one SIM we registered: target device_get_unit(self).
- */
-
- /* The artificial limit UMASS_SCSIID_MAX is there because CAM expects
- * a limit to the number of targets that are present on a SIM.
- */
- if (device_get_unit(sc->sc_dev) >= UMASS_SCSIID_MAX) {
- printf("scbus%d: Increase UMASS_SCSIID_MAX (currently %d) in %s"
- " and try again.\n",
- cam_sim_path(umass_sim), UMASS_SCSIID_MAX, __FILE__);
- return(1);
- }
-
#ifndef USB_DEBUG
if (bootverbose)
#endif
- printf("%s:%d:%d:%d: Attached to scbus%d as device %d\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
- USBDEVUNIT(sc->sc_dev), CAM_LUN_WILDCARD,
- cam_sim_path(umass_sim), USBDEVUNIT(sc->sc_dev));
+ printf("%s:%d:%d:%d: Attached to scbus%d\n",
+ USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
+ USBDEVUNIT(sc->sc_dev), CAM_LUN_WILDCARD,
+ cam_sim_path(sc->umass_sim));
if (!cold) {
/* Notify CAM of the new device. Any failure is benign, as the
@@ -2203,45 +2222,20 @@
*/
Static int
-umass_cam_detach_sim()
+umass_cam_detach_sim(struct umass_softc *sc)
{
- if (umass_sim)
- return(EBUSY); /* XXX CAM can't handle disappearing SIMs yet */
-
- if (umass_sim) {
- if (xpt_bus_deregister(cam_sim_path(umass_sim)))
- cam_sim_free(umass_sim, /*free_devq*/TRUE);
+ if (sc->umass_sim) {
+ if (xpt_bus_deregister(cam_sim_path(sc->umass_sim)))
+ cam_sim_free(sc->umass_sim, /*free_devq*/TRUE);
else
return(EBUSY);
- umass_sim = NULL;
+ sc->umass_sim = NULL;
}
return(0);
}
-Static int
-umass_cam_detach(struct umass_softc *sc)
-{
- struct cam_path *path;
-
- if (umass_sim) {
- /* detach of sim not done until module unload */
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d: losing CAM device entry\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
- USBDEVUNIT(sc->sc_dev), CAM_LUN_WILDCARD));
-
- if (xpt_create_path(&path, NULL, cam_sim_path(umass_sim),
- USBDEVUNIT(sc->sc_dev), CAM_LUN_WILDCARD)
- != CAM_REQ_CMP)
- return(ENOMEM);
-
- xpt_async(AC_LOST_DEVICE, path, NULL);
- xpt_free_path(path);
- }
-
- return(0);
-}
@@ -2252,8 +2246,7 @@
Static void
umass_cam_action(struct cam_sim *sim, union ccb *ccb)
{
- struct umass_softc *sc = devclass_get_softc(umass_devclass,
- ccb->ccb_h.target_id);
+ struct umass_softc *sc = (struct umass_softc *)sim->softc;
/* The softc is still there, but marked as going away. umass_cam_detach
* has not yet notified CAM of the lost device however.
@@ -2261,7 +2254,7 @@
if (sc && (sc->flags & UMASS_FLAGS_GONE)) {
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
"Invalid target (gone)\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
+ USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
ccb->ccb_h.func_code));
ccb->ccb_h.status = CAM_TID_INVALID;
@@ -2286,7 +2279,7 @@
if (sc == NULL) {
printf("%s:%d:%d:%d:func_code 0x%04x: "
"Invalid target (target needed)\n",
- DEVNAME_SIM, cam_sim_path(umass_sim),
+ DEVNAME_SIM, cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
ccb->ccb_h.func_code);
@@ -2304,7 +2297,7 @@
if (sc == NULL && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
"Invalid target (no wildcard)\n",
- DEVNAME_SIM, cam_sim_path(umass_sim),
+ DEVNAME_SIM, cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
ccb->ccb_h.func_code));
@@ -2331,7 +2324,7 @@
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SCSI_IO: "
"cmd: 0x%02x, flags: 0x%02x, "
"%db cmd/%db data/%db sense\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
+ USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
csio->cdb_io.cdb_bytes[0],
ccb->ccb_h.flags & CAM_DIR_MASK,
@@ -2349,7 +2342,7 @@
if (sc->transfer_state != TSTATE_IDLE) {
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SCSI_IO: "
"I/O requested while busy (state %d, %s)\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
+ USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
sc->transfer_state,states[sc->transfer_state]));
ccb->ccb_h.status = CAM_SCSI_BUSY;
@@ -2409,7 +2402,7 @@
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_PATH_INQ:.\n",
(sc == NULL? DEVNAME_SIM:USBDEVNAME(sc->sc_dev)),
- cam_sim_path(umass_sim),
+ cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
/* host specific information */
@@ -2428,7 +2421,7 @@
strncpy(cpi->hba_vid, "USB SCSI", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
cpi->unit_number = cam_sim_unit(sim);
- cpi->bus_id = UMASS_SCSI_BUS;
+ cpi->bus_id = USBDEVUNIT(sc->sc_dev);
if (sc)
cpi->base_transfer_speed = sc->transfer_speed;
@@ -2439,7 +2432,7 @@
case XPT_RESET_DEV:
{
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_RESET_DEV:.\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
+ USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
ccb->ccb_h.status = CAM_REQ_INPROG;
@@ -2451,7 +2444,7 @@
struct ccb_trans_settings *cts = &ccb->cts;
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_GET_TRAN_SETTINGS:.\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
+ USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
cts->valid = 0;
@@ -2464,7 +2457,7 @@
case XPT_SET_TRAN_SETTINGS:
{
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SET_TRAN_SETTINGS:.\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
+ USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
@@ -2525,7 +2518,7 @@
{
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_NOOP:.\n",
(sc == NULL? DEVNAME_SIM:USBDEVNAME(sc->sc_dev)),
- cam_sim_path(umass_sim),
+ cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
ccb->ccb_h.status = CAM_REQ_CMP;
@@ -2536,7 +2529,7 @@
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
"Not implemented\n",
(sc == NULL? DEVNAME_SIM:USBDEVNAME(sc->sc_dev)),
- cam_sim_path(umass_sim),
+ cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
ccb->ccb_h.func_code));
@@ -2739,20 +2732,9 @@
Static int
umass_driver_load(module_t mod, int what, void *arg)
{
- int err;
-
switch (what) {
case MOD_UNLOAD:
- err = umass_cam_detach_sim();
- if (err)
- return(err);
- return(usbd_driver_load(mod, what, arg));
case MOD_LOAD:
- /* We don't attach to CAM at this point, because it will try
- * and malloc memory for it. This is not possible when the
- * boot loader loads umass as a module before the kernel
- * has been bootstrapped.
- */
default:
return(usbd_driver_load(mod, what, arg));
}
barry bouwsma
More information about the freebsd-stable
mailing list