Date: Mon, 25 Nov 2002 16:45:51 +0300 From: Yar Tikhiy <yar@freebsd.org> To: freebsd-hackers@freebsd.org Subject: Review by USB wizard wanted Message-ID: <20021125164551.A26800@comp.chem.msu.su>
next in thread | raw e-mail | index | archive | help
Hi folks, I'm playing with a Sony USB memory stick reader/writer. It's a pretty slow device, so it triggers some bugs in the FreeBSD USB code unnoticed before. I'm new to USB programming, so I submit my notes to a discussion or review. First, sometimes (especially, if twitching a memory stick out of the reader while the device is being detected) a transfer to the umass device is initiated *after* the device is already gone. System panic follows. The transfer is initiated when destroying the default pipe to the device. Indeed, the current usb_subr.c code will detach child devices first and destroy the default pipe then. Reverting this order eliminates the panic. Second, twitching a memory stick can cause CAM jam. That happens because the umass detach routine won't wake up the upper layer when processing a device with a pending transfer on it. Patches addressing the above problems are attached below. -- Yar --- usb_subr.c.orig Sat Nov 16 12:07:50 2002 +++ usb_subr.c Fri Nov 22 15:45:35 2002 @@ -1292,8 +1292,6 @@ { int ifcidx, nifc; - if (dev->default_pipe != NULL) - usbd_kill_pipe(dev->default_pipe); if (dev->ifaces != NULL) { nifc = dev->cdesc->bNumInterface; for (ifcidx = 0; ifcidx < nifc; ifcidx++) @@ -1340,6 +1338,9 @@ return; } #endif + + if (dev->default_pipe != NULL) + usbd_kill_pipe(dev->default_pipe); if (dev->subdevs != NULL) { DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n")); --- umass.c.orig Sat Nov 16 12:07:50 2002 +++ umass.c Fri Nov 22 21:42:10 2002 @@ -1033,6 +1033,13 @@ /* detach the device from the SCSI host controller (SIM) */ err = umass_cam_detach(sc); + /* if upper layer is waiting for a transfer to finish, wake it up */ + if (sc->transfer_state != TSTATE_IDLE) { + sc->transfer_state = TSTATE_IDLE; + sc->transfer_cb(sc, sc->transfer_priv, + sc->transfer_datalen, STATUS_WIRE_FAILED); + } + for (i = 0; i < XFER_NR; i++) if (sc->transfer_xfer[i]) usbd_free_xfer(sc->transfer_xfer[i]); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021125164551.A26800>