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