On Fri, Aug 21, 2015 at 10:16:30AM -0400, Alan Stern wrote:
> On Fri, 21 Aug 2015, Peter Chen wrote:
>
> > Thanks, Alan and Felipe.
> >
> > My problem should be the chipidea udc driver does not support functional
> > stall well, it fixes the handling between functional and protocol stall.
> >
> > My understanding for these two stalls:
> >
> > - Functional stall, the host stalls the endpoints through SET_FEATURE
> > by ep0, the ep0 does not recommend to support functional stall from
> > the spec. The device should always set stall for this endpoint, and
> > return success for it.
>
> That's almost right. I just checked the USB spec to make sure (section
> 8.4.5). A functional stall occurs whenever the endpoint's HALT feature
> is set. This could be caused the host sending a Set-Halt request, _or_
> it could be caused by the device's firmware (for example, by a call to
> usb_ep_set_halt()). Either way, the endpoint continues to stall until
> the host sends a Clear-Halt request.
>
> (And yes, the spec recommends that devices should not set the HALT
> feature for ep0. If they do, it is undefined whether the device will
> respond to a Clear-Halt request!)
>
> > - Protocol stall, if the endpoint doesn't support one request, it can
> > stall itself. If there is an IN request on this endpoint, it should
> > not do stall, and return error.
>
> Protocol stalls occur only on control endpoints; they indicate the
> device does not understand or cannot carry out a control request. They
> are automatically cleared the next time a Setup packet arrives.
>
> So if you're talking about a bulk/interrupt endpoint, the only kind of
> stall you have to worry about is a functional stall. The host can
> cause a functional stall at any time by sending Set-Halt. The gadget
> driver can also cause a functional stall, but it makes no sense to do
> so while it is in the middle of transferring data to/from the host.
> For this reason, usb_ep_set_halt() always returns an error if the
> endpoint queue or the FIFO is non-empty.
>
Thanks, that's much clear.
At udc driver:
__set_halt(struct usb_ep *ep, int value, bool may_fail)
{
if (may_fail && ep queue is not empty) {
return false
} else {
do stall;
return true;
}
}
gadget_ops:
.set_halt = ep_set_halt,
ep_set_halt(struct usb_ep *ep, int value)
{
__set_halt(ep, value, true);
}
And call __set_halt(ep, value, false) at below conditions:
- SET(CLEAR)_FEATURE for Set(Clear)-Halt
- If ep0 request has failed
Do we need to update kernel doc for usb_ep_set_halt that
say it should only for bulk and interrupt endpoints?
--
Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html