currently, composite.c tries to make sure all functions will start on Alternate Setting zero when a configuration is set. I've been considering if that's necessary and even correct, provided f->set_alt() will, essentially, initialize all endpoints for that particular interface. This will generate a small issue when the proper SetInterface request comes through. Because all our endpoints are already enabled, we must disable them all and complete all their requests with -ECONNRESET, just to reenable them again and requeue same requests. It will also generate user-visible errors such as "spurious" SIGHUP on fd-based functions (like all serial gadgets) because we break the pipe. I couldn't find anywhere in the USB Specification where it requires us to make sure all interfaces start on Alternate Setting zero. IMHO, we should consider initial state as UNKNOWN and not rely on that being zero or anything. Cc: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Signed-off-by: Felipe Balbi <balbi@xxxxxx> --- Note that this will cause a regression on dwc3 due to its need for a fifo resize (at least on OMAP5), but that's my problem anyway and I'm ok taking the heat of fixing it. drivers/usb/gadget/composite.c | 57 ------------------------------------------ 1 file changed, 57 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 2cb1030..5b53440 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -630,63 +630,6 @@ static int set_config(struct usb_composite_dev *cdev, cdev->config = c; - /* Initialize all interfaces by setting them to altsetting zero. */ - for (tmp = 0; tmp < MAX_CONFIG_INTERFACES; tmp++) { - struct usb_function *f = c->interface[tmp]; - struct usb_descriptor_header **descriptors; - - if (!f) - break; - - /* - * Record which endpoints are used by the function. This is used - * to dispatch control requests targeted at that endpoint to the - * function's setup callback instead of the current - * configuration's setup callback. - */ - switch (gadget->speed) { - case USB_SPEED_SUPER: - descriptors = f->ss_descriptors; - break; - case USB_SPEED_HIGH: - descriptors = f->hs_descriptors; - break; - default: - descriptors = f->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, f->endpoints); - } - - result = f->set_alt(f, tmp, 0); - if (result < 0) { - DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n", - tmp, f->name, f, result); - - reset_config(cdev); - goto done; - } - - if (result == USB_GADGET_DELAYED_STATUS) { - DBG(cdev, - "%s: interface %d (%s) requested delayed status\n", - __func__, tmp, f->name); - cdev->delayed_status++; - DBG(cdev, "delayed_status count %d\n", - cdev->delayed_status); - } - } - /* when we return, be sure our power usage is valid */ power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; done: -- 1.7.12.rc2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html