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
Attachment:
signature.asc
Description: Digital signature