On 8/12/2020 11:34 AM, Wesley Cheng wrote: >> >> awesome, thanks a lot for this :-) It's a considerable increase in your >> setup. My only fear here is that we may end up creating a situation >> where we can't allocate enough FIFO for all endpoints. This is, of >> course, a consequence of the fact that we enable one endpoint at a >> time. >> >> Perhaps we could envision a way where function driver requests endpoints >> in bulk, i.e. combines all endpoint requirements into a single method >> call for gadget framework and, consequently, for UDC. >> > Hi Felipe, > > I agree...Resizing the txfifo is not as straightforward as it sounds :). > Would be interesting to see how this affects tput on other platforms as > well. We had a few discussions within our team, and came up with the > logic implemented in this patch to reserve at least 1 txfifo per > endpoint. Then we allocate any additional fifo space requests based on > the remaining space left. That way we could avoid over allocating, but > the trade off is that we may have unused EPs taking up fifo space. > > I didn't consider branching out to changing the gadget framework, so let > me take a look at your suggestion to see how it turns out. > Hi Felipe, Instead of catching the out of FIFO memory issue during the ep enable stage, I was thinking if we could do it somewhere during the bind. Then this would allow for at least failing the bind instead of having an enumerated device which doesn't work. (will happen if we bail out during ep enable phase) The idea I had was the following: Introduce a new USB gadget function pointer, say usb_gadget_check_config(struct usb_gadget *gadget, unsigned long ep_map) The purpose for the ep_map is to carry information about the endpoints the configuration requires, since each function driver will define the endpoint descriptor(s) it will advertise to the host. We have access to these ep desc after the bind() routine is executed for the function driver, so we can update this map after every bind. The configfs driver will call the check config API every time a configuration is added. static int configfs_composite_bind(struct usb_gadget *gadget, struct usb_gadget_driver *gdriver) { ... /* Go through all configs, attach all functions */ list_for_each_entry(c, &gi->cdev.configs, list) { ... list_for_each_entry_safe(f, tmp, &cfg->func_list, list) { ... if (f->ss_descriptors) { struct usb_descriptor_header **descriptors; descriptors = f->ss_descriptors; for (; *descriptors; ++descriptors) { struct usb_endpoint_descriptor *ep; int addr; if ((*descriptors)->bDescriptorType != USB_DT_ENDPOINT) continue; ep = (struct usb_endpoint_descriptor *)*descriptors; addr = ((ep->bEndpointAddress & 0x80) >> 3) | (ep->bEndpointAddress & 0x0f); set_bit(addr, &ep_map); } } usb_gadget_check_config(cdev->gadget, ep_map); What it'll allow us to do is to decode the ep_map in the dwc3/udc driver to determine if we have enough fifo space. Also, if we wanted to utilize this ep map for the actual resizing stage, we could eliminate the issue of not knowing how many EPs will be enabled, and allocating potentially unused fifos due to unused eps. Thanks Wesley -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project