From: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> maxpacket is set by the udc driver for ep0 very early. This value is copied by the function gadget used later for the USB_DT_DEVICE and USB_DT_DEVICE_QUALIFIER query. This seems to work fine so far. For USB3 we need set a different value here. In SS speed it is 2^x with x=9 and in HS we set something <= 64. If the UDC starts in SS and continues in HS after the cable has been plugged it will report a too small value. There setting of this value is defered and taken automaticly from the ep0 pointer where the UDC driver can update it according to the speed it detected _after_ a cable has been plugged. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> Signed-off-by: Felipe Balbi <balbi@xxxxxx> --- drivers/usb/gadget/composite.c | 3 +-- drivers/usb/gadget/dbgp.c | 2 +- drivers/usb/gadget/file_storage.c | 10 ++++++---- drivers/usb/gadget/gmidi.c | 3 +-- drivers/usb/gadget/inode.c | 5 ++--- drivers/usb/gadget/printer.c | 14 +++++++++----- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index c5abe27..5ef8779 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -573,7 +573,7 @@ static void device_qual(struct usb_composite_dev *cdev) qual->bDeviceSubClass = cdev->desc.bDeviceSubClass; qual->bDeviceProtocol = cdev->desc.bDeviceProtocol; /* ASSUME same EP0 fifo size at both speeds */ - qual->bMaxPacketSize0 = cdev->desc.bMaxPacketSize0; + qual->bMaxPacketSize0 = cdev->gadget->ep0->maxpacket; qual->bNumConfigurations = count_configs(cdev, USB_DT_DEVICE_QUALIFIER); qual->bRESERVED = 0; } @@ -1450,7 +1450,6 @@ static int composite_bind(struct usb_gadget *gadget) goto fail; cdev->desc = *composite->dev; - cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; /* standardized runtime overrides for device ID data */ if (idVendor) diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index 052209e..8beefdd 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c @@ -314,7 +314,6 @@ static int __init dbgp_bind(struct usb_gadget *gadget) dbgp.req->length = DBGP_REQ_EP0_LEN; gadget->ep0->driver_data = gadget; - device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; #ifdef CONFIG_USB_G_DBGP_SERIAL dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL); @@ -365,6 +364,7 @@ static int dbgp_setup(struct usb_gadget *gadget, dev_dbg(&dbgp.gadget->dev, "setup: desc device\n"); len = sizeof device_desc; data = &device_desc; + device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; break; case USB_DT_DEBUG: dev_dbg(&dbgp.gadget->dev, "setup: desc debug\n"); diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 738591a..639e14a 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -929,6 +929,7 @@ static int standard_setup_req(struct fsg_dev *fsg, case USB_DT_DEVICE: VDBG(fsg, "get device descriptor\n"); + device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket; value = sizeof device_desc; memcpy(req->buf, &device_desc, value); break; @@ -936,6 +937,11 @@ static int standard_setup_req(struct fsg_dev *fsg, VDBG(fsg, "get device qualifier\n"); if (!gadget_is_dualspeed(fsg->gadget)) break; + /* + * Assume ep0 uses the same maxpacket value for both + * speeds + */ + dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; value = sizeof dev_qualifier; memcpy(req->buf, &dev_qualifier, value); break; @@ -3417,7 +3423,6 @@ static int __init fsg_bind(struct usb_gadget *gadget) } /* Fix up the descriptors */ - device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket; device_desc.idVendor = cpu_to_le16(mod_data.vendor); device_desc.idProduct = cpu_to_le16(mod_data.product); device_desc.bcdDevice = cpu_to_le16(mod_data.release); @@ -3431,9 +3436,6 @@ static int __init fsg_bind(struct usb_gadget *gadget) if (gadget_is_dualspeed(gadget)) { fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL; - /* Assume ep0 uses the same maxpacket value for both speeds */ - dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; - /* Assume endpoint addresses are the same for both speeds */ fsg_hs_bulk_in_desc.bEndpointAddress = fsg_fs_bulk_in_desc.bEndpointAddress; diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 4f40f14..8b9220e 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -695,6 +695,7 @@ static int gmidi_setup(struct usb_gadget *gadget, switch (w_value >> 8) { case USB_DT_DEVICE: + device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; value = min(w_length, (u16) sizeof(device_desc)); memcpy(req->buf, &device_desc, value); break; @@ -1249,8 +1250,6 @@ autoconf_fail: dev->req->complete = gmidi_setup_complete; - device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; - gadget->ep0->driver_data = dev; INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname); diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index a9a4556..1b24099 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1347,7 +1347,7 @@ static void make_qualifier (struct dev_data *dev) qual.bDeviceProtocol = desc->bDeviceProtocol; /* assumes ep0 uses the same value for both speeds ... */ - qual.bMaxPacketSize0 = desc->bMaxPacketSize0; + qual.bMaxPacketSize0 = dev->gadget->ep0->maxpacket; qual.bNumConfigurations = 1; qual.bRESERVED = 0; @@ -1404,7 +1404,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) } dev->state = STATE_DEV_CONNECTED; - dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; INFO (dev, "connected\n"); event = next_event (dev, GADGETFS_CONNECT); @@ -1432,6 +1431,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_DT_DEVICE: value = min (w_length, (u16) sizeof *dev->dev); + dev->dev->bMaxPacketSize0 = dev->gadget->ep0->maxpacket; req->buf = dev->dev; break; #ifdef CONFIG_USB_GADGET_DUALSPEED @@ -1712,7 +1712,6 @@ gadgetfs_bind (struct usb_gadget *gadget) set_gadget_data (gadget, dev); dev->gadget = gadget; gadget->ep0->driver_data = dev; - dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; /* preallocate control response and buffer */ dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL); diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 00e5f19..d5df8dd 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -1148,6 +1148,8 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) switch (wValue >> 8) { case USB_DT_DEVICE: + device_desc.bMaxPacketSize0 = + gadget->ep0->maxpacket; value = min(wLength, (u16) sizeof device_desc); memcpy(req->buf, &device_desc, value); break; @@ -1155,6 +1157,12 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_DT_DEVICE_QUALIFIER: if (!gadget->is_dualspeed) break; + /* + * assumes ep0 uses the same value for both + * speeds + */ + dev_qualifier.bMaxPacketSize0 = + gadget->ep0->maxpacket; value = min(wLength, (u16) sizeof dev_qualifier); memcpy(req->buf, &dev_qualifier, value); @@ -1450,15 +1458,11 @@ autoconf_fail: out_ep->driver_data = out_ep; /* claim */ #ifdef CONFIG_USB_GADGET_DUALSPEED - /* assumes ep0 uses the same value for both speeds ... */ - dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; - - /* and that all endpoints are dual-speed */ + /* assumes that all endpoints are dual-speed */ hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; #endif /* DUALSPEED */ - device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; usb_gadget_set_selfpowered(gadget); if (gadget->is_otg) { -- 1.7.6 -- 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