> Apparently, when using usb-ohci with an interrupt endpoint and you
> disconnect the device physically, the interrupt callback is called one
> more time before the _disconnect() function is called.
The experiments I just tried (keyboard) showed _lots_ of completion
callbacks, all with 110/ETIMEDOUT. As seems right: each time
the controller tried to poll the device, it didn't respond. And whatever
got those callbacks didn't unlink the URB, so the next poll failed too.
After a while, the (root) hub noticed it the port was gone, and then
called disconnect().
> Using a UHCI driver, the 'state' field of the callback is set to -ENOENT.
Callback -- or the code that unlinks the URB? I found a case where there
was a clear driver difference, but it was the unlinking case.
> However, with usb-ohci, this is set to -110 (I think that's -ETIMEDOUT).
> I think this should be -ENOENT. At the very least the UHCI and OHCI
> drivers should show the same behavior.
Please try the enclosed patch. It does three things to improve consistency
of the (three) drivers:
* Makes unlinking active URBs return ENOENT. I hope this will do what
you mentioned above, but I can't test it.
* When it notices endpoints the controller marked as halted (and which are
haltable -- e.g. no control endpoints) it flags them as halted. It didn't
do
this correctly before, it missed most halts including
"DeviceNotResponding"
which caused the ETIMEDOUT.
* Submitting URBs against halted endpoints get EPIPEs (like the UHCIs).
I think mass storage is the main driver that'll check for halted endpoints,
so
if that second change turns up any problems, you'll be most likely to
notice.
- Dave
p.s. I hope outlook doesn't mangle this patch; Netscape died a horrible
death, even new installations coredump on startup, and I'm digging
out from under the mess that left me. Sigh. What I see below has no
tabs and probably has carriage returns too.
p.p.s. I generated this against pre4 or so, since I can't boot current
kernels,
but I don't remember these parts of the OHCI driver changing much.
--- linux/drivers/usb/usb-ohci.c-orig Fri Apr 14 14:32:46 2000
+++ linux/drivers/usb/usb-ohci.c Fri Apr 14 21:00:16 2000
@@ -414,9 +414,10 @@
if (urb->hcpriv) return -EINVAL; /* urb already in use */
-// if(usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe), usb_pipeout
(pipe)))
-// return -EPIPE;
-
+ if (usb_endpoint_halted (urb->dev,
+ usb_pipeendpoint (pipe), usb_pipeout (pipe)))
+ return -EPIPE;
+
usb_inc_dev_use (urb->dev);
ohci = (ohci_t *) urb->dev->bus->hcpriv;
@@ -554,6 +555,7 @@
remove_wait_queue (&op_wakeup, &wait);
else
err("unlink URB timeout!");
+ urb->status = USB_ST_URB_KILLED;
} else
urb_rm_priv (urb);
usb_dec_dev_use (urb->dev);
@@ -1097,8 +1099,21 @@
if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) {
urb_priv = (urb_priv_t *) td_list->urb->hcpriv;
dbg(" USB-error/status: %x : %p",
- TD_CC_GET (le32_to_cpup (&td_list->hwINFO)), td_list);
+ TD_CC_GET (le32_to_cpup (&td_list->hwINFO)),
+ td_list);
+
+ // did the controller halt the endpoint?
if (td_list->ed->hwHeadP & cpu_to_le32 (0x1)) {
+ urb_t *urb = td_list->urb;
+ int type = usb_pipetype (urb->pipe);
+
+ // iso and control can't really halt
+ if (type != PIPE_ISOCHRONOUS
+ && type != PIPE_CONTROL)
+ usb_endpoint_halt (urb->dev,
+ usb_pipeendpoint (urb->pipe),
+ usb_pipeout (urb->pipe));
+
if (urb_priv && ((td_list->index + 1) < urb_priv->length)) {
td_list->ed->hwHeadP =
(urb_priv->td[urb_priv->length - 1]->hwNextTD & cpu_to_le32
(0xfffffff0)) |
@@ -1243,7 +1258,6 @@
}
/* error code of transfer */
cc = TD_CC_GET (tdINFO);
- if( cc == TD_CC_STALL) usb_endpoint_halt(urb->dev,
usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc ==
TD_DATAUNDERRUN))
cc = TD_CC_NOERROR;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]