On Mon, Aug 24, 2015 at 10:51:04AM -0400, Alan Stern wrote:
> On Mon, 24 Aug 2015, Peter Chen wrote:
>
> > 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
>
> Yes, that should work. In fact, when a control request fails, you
> could even call ep_set_halt instead of __set_halt, because the ep0
> queue will certainly be empty.but you'll already hold controller's lock. ->set_halt() expects lock to be held. Since you only know of a failing request from within EP0 IRQ handler (well, you could defer to a tasklet or workqueue, or whatever), you'll already hold controller's lock and you'd end up with recursive locking errors. -- balbi
signature.asc
Description: Digital signature
