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