Hi David,

I think your patch will not always do the right thing.
The halt-bit in the ED-head-pointer indicates that the HC halts the ED
due to an error (including a short packet = DATAUNDERRUN).
If the transfer_buffer of a transfer is larger then 4KB (more then 1 TD)
then a DATAUNDERRUN needs not be an error and therefore a halt
of the endpoint would be wrong.
So an error or halt of the HC ED does not automatically 
mean that the endpoint itself
is also halted (=stalled). 
Even though, to halt the endpoint on any real error 
would be a good practise.


Roman


David Brownell wrote:
> 
> > 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]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to