Hi, Benjamin Herrenschmidt <[email protected]> writes: > Hi ! > > So for the aspeed virtual hub, I'm in a situation where I have up to 5 > devices sharing a pool of 15 "generic" endpoints (not counting EP0's, > those have dedicated HW). > > I was originally thinking of having some device-tree construct > assigning fixed number of EPs from the pool to the various devices, but > that sucks... > > I'm trying to figure out if I can do something more dynamic. > > My idea is to not put the EPs in the gadget ep_list at first, but > provide a match_ep() callback that effectively "allocates" an EP from > the pool.
but that's how the framework is implemented. Endpoints are kept in the
ep_list but they aren't allocated until an endpoint match happens.
> It looks from a cursory glance at the code that it might work, with a
> reasonable failure mode since running out of EPs would typically make
> functions fail at bind() time.
>
> However we're missing a "free" :-)
We don't need a free. Once a function is unbound, endpoints *must* be
free.
> I *think* (please correct me if I'm wrong) that adding a callback for
> that and plumbing it this way would work, let me know what you think.
I'm not entirely sure you need it.
> If you agree with the approach (and it ends up working once I'm done
> coding), I'll submit it as a pre-req patch to the driver.
>
> diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
> index e4516e9..f8d2135 100644
> --- a/include/linux/usb/gadget.h
> +++ b/include/linux/usb/gadget.h
> @@ -307,6 +307,7 @@ struct usb_gadget_ops {
> struct usb_ep *(*match_ep)(struct usb_gadget *,
> struct usb_endpoint_descriptor *,
> struct usb_ss_ep_comp_descriptor *);
> + void (*release_ep)(struct usb_gadget *, struct usb_ep *);
> };
>
> /**
> --- a/drivers/usb/gadget/epautoconf.c
> +++ b/drivers/usb/gadget/epautoconf.c
> @@ -185,6 +185,9 @@ void usb_ep_autoconfig_release(struct usb_ep *ep)
> {
> ep->claimed = false;
> ep->driver_data = NULL;
> +
> + if (gadget->ops->release_ep)
> + gadget->relase->release_ep(gadget, ep);
> }
> EXPORT_SYMBOL_GPL(usb_ep_autoconfig_release);
>
> @@ -201,10 +204,8 @@ void usb_ep_autoconfig_reset (struct usb_gadget *gadget)
> {
> struct usb_ep *ep;
>
> - list_for_each_entry (ep, &gadget->ep_list, ep_list) {
> - ep->claimed = false;
> - ep->driver_data = NULL;
> - }
> + list_for_each_entry_safe (ep, &gadget->ep_list, ep_list)
> + usb_ep_autoconfig_release(ep);
> gadget->in_epnum = 0;
> gadget->out_epnum = 0;
> }
I really don't see the difference.
--
balbi
signature.asc
Description: PGP signature
