--- umass.c	2005-07-24 06:50:30.000000000 +0000
+++ umass.c-ed	2005-07-23 12:54:30.000000000 +0000
@@ -31,10 +31,10 @@
 
 /*
  * Universal Serial Bus Mass Storage Class specs:
- * http://www.usb.org/developers/data/devclass/usbmassover_11.pdf
- * http://www.usb.org/developers/data/devclass/usbmassbulk_10.pdf
- * http://www.usb.org/developers/data/devclass/usbmass-cbi10.pdf
- * http://www.usb.org/developers/data/devclass/usbmass-ufi10.pdf
+ * http://www.usb.org/developers/devclass_docs/usb_msc_overview_1.2.pdf
+ * http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
+ * http://www.usb.org/developers/devclass_docs/usb_msc_cbi_1.1.pdf
+ * http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
  */
 
 /*
@@ -156,7 +156,9 @@ SYSCTL_INT(_hw_usb_umass, OID_AUTO, debu
 #define DEVNAME_SIM	"umass-sim"
 
 #define UMASS_MAX_TRANSFER_SIZE		65536
-#define UMASS_DEFAULT_TRANSFER_SPEED	1000
+/* Approximate maximum transfer speeds (assumes 33% overhead). */
+#define UMASS_FULL_TRANSFER_SPEED       1000
+#define UMASS_HIGH_TRANSFER_SPEED       40000
 #define UMASS_FLOPPY_TRANSFER_SPEED	20
 
 #define UMASS_TIMEOUT			5000 /* msecs */
@@ -242,7 +244,7 @@ typedef void (*transfer_cb_f)	(struct um
 typedef void (*wire_reset_f)	(struct umass_softc *sc, int status);
 typedef void (*wire_transfer_f)	(struct umass_softc *sc, int lun,
 				void *cmd, int cmdlen, void *data, int datalen,
-				int dir, transfer_cb_f cb, void *priv);
+				int dir, u_int timeout, transfer_cb_f cb, void *priv);
 typedef void (*wire_state_f)	(usbd_xfer_handle xfer,
 				usbd_private_handle priv, usbd_status err);
 
@@ -321,6 +323,10 @@ Static struct umass_devdescr_t umass_dev
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
 	},
+	{ USB_VENDOR_GENESYS,  USB_PRODUCT_GENESYS_GL641USB2IDE_2, RID_WILDCARD,
+	  UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
+	  FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
+ 	},
 	{ USB_VENDOR_GENESYS,  USB_PRODUCT_GENESYS_GL641USB, RID_WILDCARD,
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
@@ -337,12 +343,24 @@ Static struct umass_devdescr_t umass_dev
 	  UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
 	  NO_TEST_UNIT_READY | NO_START_STOP | ALT_IFACE_1
 	},
+  	{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_IU_CD2, RID_WILDCARD,
+ 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ 	  NO_QUIRKS
+ 	},
+	{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_DVR_UEH8, RID_WILDCARD,
+ 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ 	  NO_QUIRKS
+	},
 	{ USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100, RID_WILDCARD,
 	  /* XXX This is not correct as there are Zip drives that use ATAPI.
 	   */
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  NO_TEST_UNIT_READY
 	},
+ 	{ USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443SU2, RID_WILDCARD,
+ 	  UMASS_PROTO_SCSI,
+ 	  NO_QUIRKS
+	},
 	{ USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443U2, RID_WILDCARD,
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  NO_QUIRKS
@@ -363,10 +381,18 @@ Static struct umass_devdescr_t umass_dev
 	  UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
 	  NO_QUIRKS
 	},
+	{ USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260, RID_WILDCARD,
+ 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ 	  FORCE_SHORT_INQUIRY
+ 	},
 	{ USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1, RID_WILDCARD,
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  WRONG_CSWSIG
 	},
+        { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_UCF100, RID_WILDCARD,
+	  UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
+          NO_INQUIRY | NO_GETMAXLUN
+	},
 	{ USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB20AN, RID_WILDCARD,
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  NO_QUIRKS
@@ -375,13 +401,21 @@ Static struct umass_devdescr_t umass_dev
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  NO_QUIRKS
 	},
+ 	{ USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U, RID_WILDCARD,
+ 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ 	  NO_TEST_UNIT_READY
+	},
 	{ USB_VENDOR_PEN, USB_PRODUCT_PEN_ATTACHE, RID_WILDCARD,
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  IGNORE_RESIDUE
 	},
+	{ USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256, RID_WILDCARD,
+	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ 	  IGNORE_RESIDUE
+ 	},
 	{ USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R, RID_WILDCARD,
-	  UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
-	  NO_QUIRKS
+	  UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
+	  NO_INQUIRY
 	},
 	{ USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, RID_WILDCARD,
 	  UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
@@ -391,10 +425,18 @@ Static struct umass_devdescr_t umass_dev
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  SHUTTLE_INIT
 	},
+	{ USB_VENDOR_SIIG, USB_PRODUCT_SIIG_WINTERREADER, RID_WILDCARD,
+          UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ 	  IGNORE_RESIDUE
+ 	},
 	{ USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, RID_WILDCARD,
 	  UMASS_PROTO_RBC | UMASS_PROTO_CBI,
 	  NO_QUIRKS
 	},
+	{ USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM, RID_WILDCARD,
+          UMASS_PROTO_RBC | UMASS_PROTO_CBI,
+          NO_QUIRKS
+ 	},
 	{ USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC, RID_WILDCARD,
 	  UMASS_PROTO_RBC | UMASS_PROTO_CBI,
 	  NO_QUIRKS
@@ -403,6 +445,18 @@ Static struct umass_devdescr_t umass_dev
           UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
 	  IGNORE_RESIDUE
 	},
+	{ USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_C3310, RID_WILDCARD,
+          UMASS_PROTO_UFI | UMASS_PROTO_CBI,
+          NO_QUIRKS
+        },
+	{ USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_MDIV, RID_WILDCARD,
+          UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ 	  NO_QUIRKS
+ 	},
+	{ USB_VENDOR_WESTERN,  USB_PRODUCT_WESTERN_EXTHDD, RID_WILDCARD,
+          UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+          FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
+        },
 	{ USB_VENDOR_YANO,  USB_PRODUCT_YANO_U640MO, RID_WILDCARD,
 	  UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
 	  FORCE_SHORT_INQUIRY
@@ -527,6 +581,9 @@ struct umass_softc {
 	unsigned char 		cam_scsi_command2[CAM_MAX_CDBLEN];
 	struct scsi_sense	cam_scsi_sense;
 	struct scsi_sense	cam_scsi_test_unit_ready;
+	usb_callout_t           cam_scsi_rescan_ch;
+
+	int                     timeout;                /* in msecs */
 
 	int			maxlun;			/* maximum LUN number */
 	struct callout		rescan_timeout;
@@ -593,7 +650,7 @@ Static void umass_reset		(struct umass_s
 Static void umass_bbb_reset	(struct umass_softc *sc, int status);
 Static void umass_bbb_transfer	(struct umass_softc *sc, int lun,
 				void *cmd, int cmdlen,
-		    		void *data, int datalen, int dir,
+				void *data, int datalen, int dir, u_int timeout,
 				transfer_cb_f cb, void *priv);
 Static void umass_bbb_state	(usbd_xfer_handle xfer,
 				usbd_private_handle priv,
@@ -608,7 +665,7 @@ Static int umass_cbi_adsc	(struct umass_
 Static void umass_cbi_reset	(struct umass_softc *sc, int status);
 Static void umass_cbi_transfer	(struct umass_softc *sc, int lun,
 				void *cmd, int cmdlen,
-		    		void *data, int datalen, int dir,
+		    		void *data, int datalen, int dir, u_int timeout,
 				transfer_cb_f cb, void *priv);
 Static void umass_cbi_state	(usbd_xfer_handle xfer,
 				usbd_private_handle priv, usbd_status err);
@@ -699,7 +756,7 @@ umass_match_proto(struct umass_softc *sc
 	if (UGETW(dd->idVendor) == USB_VENDOR_YEDATA
 	    && UGETW(dd->idProduct) == USB_PRODUCT_YEDATA_FLASHBUSTERU) {
 
-		/* Revisions < 1.28 do not handle the inerrupt endpoint
+		/* Revisions < 1.28 do not handle the interrupt endpoint
 		 * very well.
 		 */
 		if (UGETW(dd->bcdDevice) < 0x128) {
@@ -824,6 +881,7 @@ USB_ATTACH(umass)
 
 	sc->iface = uaa->iface;
 	sc->ifaceno = uaa->ifaceno;
+	usb_callout_init(sc->cam_scsi_rescan_ch);
 
 	/* initialise the proto and drive values in the umass_softc (again) */
 	(void) umass_match_proto(sc, sc->iface, uaa->device);
@@ -877,7 +935,7 @@ USB_ATTACH(umass)
 #endif
 
 	if (sc->quirks & ALT_IFACE_1) {
-		err = usbd_set_interface(0, 1);
+		err = usbd_set_interface(uaa->iface, 1);
 		if (err) {
 			DPRINTF(UDMASS_USB, ("%s: could not switch to "
 				"Alt Interface %d\n",
@@ -954,14 +1012,14 @@ USB_ATTACH(umass)
 	}
 	/* Open the intr-in pipe if the protocol is CBI with CCI.
 	 * Note: early versions of the Zip drive do have an interrupt pipe, but
-	 * this pipe is unused
+	 * this pipe is unused.
 	 *
 	 * We do not open the interrupt pipe as an interrupt pipe, but as a
 	 * normal bulk endpoint. We send an IN transfer down the wire at the
 	 * appropriate time, because we know exactly when to expect data on
 	 * that endpoint. This saves bandwidth, but more important, makes the
 	 * code for handling the data on that endpoint simpler. No data
-	 * arriving concurently.
+	 * arriving concurrently.
 	 */
 	if (sc->proto & UMASS_PROTO_CBI_I) {
 		err = usbd_open_pipe(sc->iface, sc->intrin,
@@ -1078,12 +1136,14 @@ USB_DETACH(umass)
 	 */
 	sc->flags |= UMASS_FLAGS_GONE;
 
+	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);
 
 	/*
 	 * Wait until we go idle to make sure that all of our xfer requests
@@ -1102,7 +1162,6 @@ USB_DETACH(umass)
 		}
 		to += hz;
 	}
-
 	if ((sc->proto & UMASS_PROTO_SCSI) ||
 	    (sc->proto & UMASS_PROTO_ATAPI) ||
 	    (sc->proto & UMASS_PROTO_UFI) ||
@@ -1158,10 +1217,10 @@ umass_setup_transfer(struct umass_softc 
 {
 	usbd_status err;
 
-	/* Initialiase a USB transfer and then schedule it */
+	/* Initialise a USB transfer and then schedule it */
 
 	(void) usbd_setup_xfer(xfer, pipe, (void *) sc, buffer, buflen, flags,
-			UMASS_TIMEOUT, sc->state);
+			sc->timeout, sc->state);
 
 	err = usbd_transfer(xfer);
 	if (err && err != USBD_IN_PROGRESS) {
@@ -1182,10 +1241,10 @@ umass_setup_ctrl_transfer(struct umass_s
 {
 	usbd_status err;
 
-	/* Initialiase a USB control transfer and then schedule it */
+	/* Initialise a USB control transfer and then schedule it */
 
 	(void) usbd_setup_default_xfer(xfer, udev, (void *) sc,
-			UMASS_TIMEOUT, req, buffer, buflen, flags, sc->state);
+			sc->timeout, req, buffer, buflen, flags, sc->state);
 
 	err = usbd_transfer(xfer);
 	if (err && err != USBD_IN_PROGRESS) {
@@ -1282,12 +1341,14 @@ umass_bbb_reset(struct umass_softc *sc, 
 
 Static void
 umass_bbb_transfer(struct umass_softc *sc, int lun, void *cmd, int cmdlen,
-		    void *data, int datalen, int dir,
+		    void *data, int datalen, int dir, u_int timeout,
 		    transfer_cb_f cb, void *priv)
 {
 	KASSERT(sc->proto & UMASS_PROTO_BBB,
 		("%s: umass_bbb_transfer: wrong sc->proto 0x%02x\n",
 			USBDEVNAME(sc->sc_dev), sc->proto));
+	
+	sc->timeout = timeout + UMASS_TIMEOUT;
 
 	/*
 	 * Do a Bulk-Only transfer with cmdlen bytes from cmd, possibly
@@ -1404,13 +1465,20 @@ umass_bbb_state(usbd_xfer_handle xfer, u
 	 * Annex A of the Bulk-Only specification.
 	 * Each state first does the error handling of the previous transfer
 	 * and then prepares the next transfer.
-	 * Each transfer is done asynchroneously so after the request/transfer
+	 * Each transfer is done asynchronously so after the request/transfer
 	 * has been submitted you will find a 'return;'.
 	 */
 
 	DPRINTF(UDMASS_BBB, ("%s: Handling BBB state %d (%s), xfer=%p, %s\n",
 		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) {
 
@@ -1760,7 +1828,7 @@ umass_cbi_reset(struct umass_softc *sc, 
 	 *
 	 * First send a reset request to the device. Then clear
 	 * any possibly stalled bulk endpoints.
-
+	 *
 	 * This is done in 3 steps, states:
 	 * TSTATE_CBI_RESET1
 	 * TSTATE_CBI_RESET2
@@ -1791,18 +1859,20 @@ umass_cbi_reset(struct umass_softc *sc, 
 
 	umass_cbi_adsc(sc, sc->cbl, SEND_DIAGNOSTIC_CMDLEN,
 		       sc->transfer_xfer[XFER_CBI_RESET1]);
-	/* XXX if the command fails we should reset the port on the bub */
+	/* XXX if the command fails we should reset the port on the hub */
 }
 
 Static void
 umass_cbi_transfer(struct umass_softc *sc, int lun,
 		void *cmd, int cmdlen, void *data, int datalen, int dir,
-		transfer_cb_f cb, void *priv)
+		u_int timeout, transfer_cb_f cb, void *priv)
 {
 	KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
 		("%s: umass_cbi_transfer: wrong sc->proto 0x%02x\n",
 			USBDEVNAME(sc->sc_dev), sc->proto));
 
+	sc->timeout = timeout + UMASS_TIMEOUT;
+
 	/*
 	 * Do a CBI transfer with cmdlen bytes from cmd, possibly
 	 * a data phase of datalen bytes from/to the device and finally a
@@ -1864,6 +1934,13 @@ umass_cbi_state(usbd_xfer_handle xfer, u
 		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 *****/
@@ -2189,6 +2266,8 @@ umass_cam_rescan(void *addr)
 	union ccb *ccb;
 
 	ccb = malloc(sizeof(union ccb), M_USBDEV, M_INTWAIT|M_ZERO);
+	if (ccb == NULL)
+	   return;
 
 	DPRINTF(UDMASS_SCSI, ("scbus%d: scanning for %s:%d:%d:%d\n",
 		cam_sim_path(sc->umass_sim),
@@ -2197,7 +2276,10 @@ umass_cam_rescan(void *addr)
 
 	if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->umass_sim),
 			    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)
-	    != CAM_REQ_CMP)
+	    != CAM_REQ_CMP) {
+  	       free(ccb, M_USBDEV);
+               return;
+ 	    }
 		return;
 
 	xpt_setup_ccb(&ccb->ccb_h, path, 5/*priority (low)*/);
@@ -2436,7 +2518,7 @@ umass_cam_action(struct cam_sim *sim, un
 			}
 			sc->transfer(sc, ccb->ccb_h.target_lun, rcmd, rcmdlen,
 				     csio->data_ptr,
-				     csio->dxfer_len, dir,
+				     csio->dxfer_len, dir, ccb->ccb_h.timeout,
 				     umass_cam_cb, (void *) ccb);
 		} else {
 			ccb->ccb_h.status = CAM_REQ_INVALID;
@@ -2473,9 +2555,11 @@ umass_cam_action(struct cam_sim *sim, un
 			cpi->max_lun = 0;
 		} else {
 			if (sc->quirks & FLOPPY_SPEED) {
-			    cpi->base_transfer_speed = UMASS_FLOPPY_TRANSFER_SPEED;
+			   cpi->base_transfer_speed = UMASS_FLOPPY_TRANSFER_SPEED;
+ 	                } else if (usbd_get_speed(sc->sc_udev) == USB_SPEED_HIGH) {
+ 	                          cpi->base_transfer_speed = UMASS_HIGH_TRANSFER_SPEED;
 			} else {
-			    cpi->base_transfer_speed = UMASS_DEFAULT_TRANSFER_SPEED;
+			    cpi->base_transfer_speed = UMASS_FULL_TRANSFER_SPEED;
 			}
 			cpi->max_lun = sc->maxlun;
 		}
@@ -2578,6 +2662,13 @@ umass_cam_cb(struct umass_softc *sc, voi
 	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) {
@@ -2614,7 +2705,7 @@ umass_cam_cb(struct umass_softc *sc, voi
 				sc->transfer(sc, ccb->ccb_h.target_lun,
 					     rcmd, rcmdlen,
 					     &csio->sense_data,
-					     csio->sense_len, DIR_IN,
+					     csio->sense_len, DIR_IN, ccb->ccb_h.timeout,
 					     umass_cam_sense_cb, (void *) ccb);
 			} else {
 				panic("transform(REQUEST_SENSE) failed");
@@ -2655,6 +2746,12 @@ umass_cam_sense_cb(struct umass_softc *s
 	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:
@@ -2714,7 +2811,7 @@ umass_cam_sense_cb(struct umass_softc *s
 					&rcmd, &rcmdlen)) {
 				sc->transfer(sc, ccb->ccb_h.target_lun,
 					     rcmd, rcmdlen,
-					     NULL, 0, DIR_NONE,
+					     NULL, 0, DIR_NONE, ccb->ccb_h.timeout,
 					     umass_cam_quirk_cb, (void *) ccb);
 			} else {
 				panic("transform(TEST_UNIT_READY) failed");
@@ -2748,6 +2845,13 @@ umass_cam_quirk_cb(struct umass_softc *s
 
 	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
@@ -2877,6 +2981,7 @@ umass_ufi_transform(struct umass_softc *
 
 	case REZERO_UNIT:
 	case REQUEST_SENSE:
+	case FORMAT_UNIT:
 	case INQUIRY:
 	case START_STOP_UNIT:
 	case SEND_DIAGNOSTIC:
@@ -2885,18 +2990,16 @@ umass_ufi_transform(struct umass_softc *
 	case READ_10:
 	case WRITE_10:
 	case POSITION_TO_ELEMENT:	/* SEEK_10 */
+	case WRITE_AND_VERIFY:
+	case VERIFY:
 	case MODE_SELECT_10:
 	case MODE_SENSE_10:
 	case READ_12:
 	case WRITE_12:
+	case READ_FORMAT_CAPACITIES:
 		memcpy(*rcmd, cmd, cmdlen);
 		return 1;
 
-	/* Other UFI commands: FORMAT_UNIT, READ_FORMAT_CAPACITY,
-	 * VERIFY, WRITE_AND_VERIFY.
-	 * These should be checked whether they somehow can be made to fit.
-	 */
-
 	default:
 		printf("%s: Unsupported UFI command 0x%02x\n",
 			USBDEVNAME(sc->sc_dev), cmd[0]);
@@ -2956,6 +3059,22 @@ umass_atapi_transform(struct umass_softc
 	case SYNCHRONIZE_CACHE:
 	case MODE_SELECT_10:
 	case MODE_SENSE_10:
+	case READ_BUFFER:
+ 	case 0x42: /* READ_SUBCHANNEL */
+ 	case 0x43: /* READ_TOC */
+ 	case 0x44: /* READ_HEADER */
+ 	case 0x51: /* READ_DISK_INFO */
+ 	case 0x52: /* READ_TRACK_INFO */
+ 	case 0x54: /* SEND_OPC */
+ 	case 0x59: /* READ_MASTER_CUE */
+ 	case 0x5b: /* CLOSE_TR_SESSION */
+ 	case 0x5c: /* READ_BUFFER_CAP */
+ 	case 0x5d: /* SEND_CUE_SHEET */
+ 	case 0xa1: /* BLANK */
+ 	case 0xa6: /* EXCHANGE_MEDIUM */
+ 	case 0xad: /* READ_DVD_STRUCTURE */
+ 	case 0xbb: /* SET_CD_SPEED */
+ 	case 0xe5: /* READ_TRACK_INFO_PHILIPS */
 		memcpy(*rcmd, cmd, cmdlen);
 		return 1;
 
