kern/58649: [patch] USB CD-R writing patch

SAKIYAMA Nobuo sakichan at sakichan.org
Tue Oct 28 12:50:17 PST 2003


>Number:         58649
>Category:       kern
>Synopsis:       [patch] USB CD-R writing patch
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 28 12:50:14 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     SAKIYAMA Nobuo <sakichan at sakichan.org>
>Release:        FreeBSD 5.1-CURRENT i386
>Organization:
>Environment:
System: FreeBSD castor.sakichan.org 5.1-CURRENT FreeBSD 5.1-CURRENT #41: Wed Oct 29 04:24:21 JST 2003 root at castor.sakichan.org:/usr/obj/usr/src/sys/CASTOR i386


>Description:
	Problem 1. CD-R writing software such as cdrtools cannot write to ATAPI-based USB CD-R drives.
	Problem 2. CD-R writing software fails to fixate for USB CD-R drives.
>How-To-Repeat:
	Problem 1. install cdrtools port, and use cdrecord for ATAPI-based USB CD-R.
	Then you'll get several "Unsupported ATAPI command" errors from kernel and fail.
	Problem 2. use cdrecord for USB CD-R. Then, you'll get "BBB reset failed, TIMEOUT"
	from the umass device and fail to fixate.
>Fix:
	Problem 1. is because umass_atapi_transform() does not pass ATAPI MMC commands.
	Problem 2. is because timeout for wire transfer is not properly set.

	Below is a patch for both problems. The part of the timeout fix is very similar to
	the code of NetBSD-current. I've tested the patch with TEAC CD-W28E.

--- umass_cdr_writing.patch begins here ---
Index: sys/dev/usb/umass.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/umass.c,v
retrieving revision 1.91
diff -u -r1.91 umass.c
--- sys/dev/usb/umass.c	20 Sep 2003 08:18:16 -0000	1.91
+++ sys/dev/usb/umass.c	28 Oct 2003 19:10:06 -0000
@@ -241,7 +241,7 @@
 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);
 
@@ -507,6 +507,8 @@
 	struct scsi_sense	cam_scsi_sense;
 	struct scsi_sense	cam_scsi_test_unit_ready;
 
+	int			timeout;		/* in msecs */
+
 	int			maxlun;			/* maximum LUN number */
 };
 
@@ -571,7 +573,7 @@
 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,
@@ -586,7 +588,7 @@
 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);
@@ -1105,7 +1107,7 @@
 	/* Initialiase 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) {
@@ -1129,7 +1131,7 @@
 	/* Initialiase 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) {
@@ -1226,13 +1228,16 @@
 
 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));
 
+	/* Be a little generous. */
+	sc->timeout = timeout + UMASS_TIMEOUT;
+
 	/*
 	 * Do a Bulk-Only transfer with cmdlen bytes from cmd, possibly
 	 * a data phase of datalen bytes from/to the device and finally a
@@ -1739,12 +1744,15 @@
 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));
 
+	/* Be a little generous. */
+	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
@@ -2371,7 +2379,7 @@
 			}
 			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;
@@ -2549,7 +2557,7 @@
 				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");
@@ -2649,7 +2657,7 @@
 					&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");
@@ -2891,6 +2899,22 @@
 	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 0xa6: /* EXCHANGE_MEDIUM */
+	case 0xbb: /* SET_CD_SPEED */
+	case 0xad: /* READ_DVD_STRUCTURE */
+	case 0xa1: /* BLANK */
+	case 0xe5: /* READ_TRACK_INFO_PHILIPS */
 		memcpy(*rcmd, cmd, cmdlen);
 		return 1;
 
--- umass_cdr_writing.patch ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list