usb: gadget: defer setting maxpacket till ->setup()
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@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
193ab2a607
Коммит
765f5b830e
|
@ -573,7 +573,7 @@ static void device_qual(struct usb_composite_dev *cdev)
|
||||||
qual->bDeviceSubClass = cdev->desc.bDeviceSubClass;
|
qual->bDeviceSubClass = cdev->desc.bDeviceSubClass;
|
||||||
qual->bDeviceProtocol = cdev->desc.bDeviceProtocol;
|
qual->bDeviceProtocol = cdev->desc.bDeviceProtocol;
|
||||||
/* ASSUME same EP0 fifo size at both speeds */
|
/* 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->bNumConfigurations = count_configs(cdev, USB_DT_DEVICE_QUALIFIER);
|
||||||
qual->bRESERVED = 0;
|
qual->bRESERVED = 0;
|
||||||
}
|
}
|
||||||
|
@ -1450,7 +1450,6 @@ static int composite_bind(struct usb_gadget *gadget)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
cdev->desc = *composite->dev;
|
cdev->desc = *composite->dev;
|
||||||
cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
|
|
||||||
|
|
||||||
/* standardized runtime overrides for device ID data */
|
/* standardized runtime overrides for device ID data */
|
||||||
if (idVendor)
|
if (idVendor)
|
||||||
|
|
|
@ -314,7 +314,6 @@ static int __init dbgp_bind(struct usb_gadget *gadget)
|
||||||
|
|
||||||
dbgp.req->length = DBGP_REQ_EP0_LEN;
|
dbgp.req->length = DBGP_REQ_EP0_LEN;
|
||||||
gadget->ep0->driver_data = gadget;
|
gadget->ep0->driver_data = gadget;
|
||||||
device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
|
|
||||||
|
|
||||||
#ifdef CONFIG_USB_G_DBGP_SERIAL
|
#ifdef CONFIG_USB_G_DBGP_SERIAL
|
||||||
dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL);
|
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");
|
dev_dbg(&dbgp.gadget->dev, "setup: desc device\n");
|
||||||
len = sizeof device_desc;
|
len = sizeof device_desc;
|
||||||
data = &device_desc;
|
data = &device_desc;
|
||||||
|
device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
|
||||||
break;
|
break;
|
||||||
case USB_DT_DEBUG:
|
case USB_DT_DEBUG:
|
||||||
dev_dbg(&dbgp.gadget->dev, "setup: desc debug\n");
|
dev_dbg(&dbgp.gadget->dev, "setup: desc debug\n");
|
||||||
|
|
|
@ -929,6 +929,7 @@ static int standard_setup_req(struct fsg_dev *fsg,
|
||||||
|
|
||||||
case USB_DT_DEVICE:
|
case USB_DT_DEVICE:
|
||||||
VDBG(fsg, "get device descriptor\n");
|
VDBG(fsg, "get device descriptor\n");
|
||||||
|
device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
|
||||||
value = sizeof device_desc;
|
value = sizeof device_desc;
|
||||||
memcpy(req->buf, &device_desc, value);
|
memcpy(req->buf, &device_desc, value);
|
||||||
break;
|
break;
|
||||||
|
@ -936,6 +937,11 @@ static int standard_setup_req(struct fsg_dev *fsg,
|
||||||
VDBG(fsg, "get device qualifier\n");
|
VDBG(fsg, "get device qualifier\n");
|
||||||
if (!gadget_is_dualspeed(fsg->gadget))
|
if (!gadget_is_dualspeed(fsg->gadget))
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
|
* Assume ep0 uses the same maxpacket value for both
|
||||||
|
* speeds
|
||||||
|
*/
|
||||||
|
dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
|
||||||
value = sizeof dev_qualifier;
|
value = sizeof dev_qualifier;
|
||||||
memcpy(req->buf, &dev_qualifier, value);
|
memcpy(req->buf, &dev_qualifier, value);
|
||||||
break;
|
break;
|
||||||
|
@ -3417,7 +3423,6 @@ static int __init fsg_bind(struct usb_gadget *gadget)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix up the descriptors */
|
/* Fix up the descriptors */
|
||||||
device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
|
|
||||||
device_desc.idVendor = cpu_to_le16(mod_data.vendor);
|
device_desc.idVendor = cpu_to_le16(mod_data.vendor);
|
||||||
device_desc.idProduct = cpu_to_le16(mod_data.product);
|
device_desc.idProduct = cpu_to_le16(mod_data.product);
|
||||||
device_desc.bcdDevice = cpu_to_le16(mod_data.release);
|
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)) {
|
if (gadget_is_dualspeed(gadget)) {
|
||||||
fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
|
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 */
|
/* Assume endpoint addresses are the same for both speeds */
|
||||||
fsg_hs_bulk_in_desc.bEndpointAddress =
|
fsg_hs_bulk_in_desc.bEndpointAddress =
|
||||||
fsg_fs_bulk_in_desc.bEndpointAddress;
|
fsg_fs_bulk_in_desc.bEndpointAddress;
|
||||||
|
|
|
@ -695,6 +695,7 @@ static int gmidi_setup(struct usb_gadget *gadget,
|
||||||
switch (w_value >> 8) {
|
switch (w_value >> 8) {
|
||||||
|
|
||||||
case USB_DT_DEVICE:
|
case USB_DT_DEVICE:
|
||||||
|
device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
|
||||||
value = min(w_length, (u16) sizeof(device_desc));
|
value = min(w_length, (u16) sizeof(device_desc));
|
||||||
memcpy(req->buf, &device_desc, value);
|
memcpy(req->buf, &device_desc, value);
|
||||||
break;
|
break;
|
||||||
|
@ -1249,8 +1250,6 @@ autoconf_fail:
|
||||||
|
|
||||||
dev->req->complete = gmidi_setup_complete;
|
dev->req->complete = gmidi_setup_complete;
|
||||||
|
|
||||||
device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
|
|
||||||
|
|
||||||
gadget->ep0->driver_data = dev;
|
gadget->ep0->driver_data = dev;
|
||||||
|
|
||||||
INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname);
|
INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname);
|
||||||
|
|
|
@ -1347,7 +1347,7 @@ static void make_qualifier (struct dev_data *dev)
|
||||||
qual.bDeviceProtocol = desc->bDeviceProtocol;
|
qual.bDeviceProtocol = desc->bDeviceProtocol;
|
||||||
|
|
||||||
/* assumes ep0 uses the same value for both speeds ... */
|
/* assumes ep0 uses the same value for both speeds ... */
|
||||||
qual.bMaxPacketSize0 = desc->bMaxPacketSize0;
|
qual.bMaxPacketSize0 = dev->gadget->ep0->maxpacket;
|
||||||
|
|
||||||
qual.bNumConfigurations = 1;
|
qual.bNumConfigurations = 1;
|
||||||
qual.bRESERVED = 0;
|
qual.bRESERVED = 0;
|
||||||
|
@ -1404,7 +1404,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->state = STATE_DEV_CONNECTED;
|
dev->state = STATE_DEV_CONNECTED;
|
||||||
dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket;
|
|
||||||
|
|
||||||
INFO (dev, "connected\n");
|
INFO (dev, "connected\n");
|
||||||
event = next_event (dev, GADGETFS_CONNECT);
|
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:
|
case USB_DT_DEVICE:
|
||||||
value = min (w_length, (u16) sizeof *dev->dev);
|
value = min (w_length, (u16) sizeof *dev->dev);
|
||||||
|
dev->dev->bMaxPacketSize0 = dev->gadget->ep0->maxpacket;
|
||||||
req->buf = dev->dev;
|
req->buf = dev->dev;
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
||||||
|
@ -1712,7 +1712,6 @@ gadgetfs_bind (struct usb_gadget *gadget)
|
||||||
set_gadget_data (gadget, dev);
|
set_gadget_data (gadget, dev);
|
||||||
dev->gadget = gadget;
|
dev->gadget = gadget;
|
||||||
gadget->ep0->driver_data = dev;
|
gadget->ep0->driver_data = dev;
|
||||||
dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket;
|
|
||||||
|
|
||||||
/* preallocate control response and buffer */
|
/* preallocate control response and buffer */
|
||||||
dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
|
dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
|
||||||
|
|
|
@ -1148,6 +1148,8 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||||
switch (wValue >> 8) {
|
switch (wValue >> 8) {
|
||||||
|
|
||||||
case USB_DT_DEVICE:
|
case USB_DT_DEVICE:
|
||||||
|
device_desc.bMaxPacketSize0 =
|
||||||
|
gadget->ep0->maxpacket;
|
||||||
value = min(wLength, (u16) sizeof device_desc);
|
value = min(wLength, (u16) sizeof device_desc);
|
||||||
memcpy(req->buf, &device_desc, value);
|
memcpy(req->buf, &device_desc, value);
|
||||||
break;
|
break;
|
||||||
|
@ -1155,6 +1157,12 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||||
case USB_DT_DEVICE_QUALIFIER:
|
case USB_DT_DEVICE_QUALIFIER:
|
||||||
if (!gadget->is_dualspeed)
|
if (!gadget->is_dualspeed)
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
|
* assumes ep0 uses the same value for both
|
||||||
|
* speeds
|
||||||
|
*/
|
||||||
|
dev_qualifier.bMaxPacketSize0 =
|
||||||
|
gadget->ep0->maxpacket;
|
||||||
value = min(wLength,
|
value = min(wLength,
|
||||||
(u16) sizeof dev_qualifier);
|
(u16) sizeof dev_qualifier);
|
||||||
memcpy(req->buf, &dev_qualifier, value);
|
memcpy(req->buf, &dev_qualifier, value);
|
||||||
|
@ -1450,15 +1458,11 @@ autoconf_fail:
|
||||||
out_ep->driver_data = out_ep; /* claim */
|
out_ep->driver_data = out_ep; /* claim */
|
||||||
|
|
||||||
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
||||||
/* assumes ep0 uses the same value for both speeds ... */
|
/* assumes that all endpoints are dual-speed */
|
||||||
dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
|
|
||||||
|
|
||||||
/* and that all endpoints are dual-speed */
|
|
||||||
hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
|
hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
|
||||||
hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
|
hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
|
||||||
#endif /* DUALSPEED */
|
#endif /* DUALSPEED */
|
||||||
|
|
||||||
device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
|
|
||||||
usb_gadget_set_selfpowered(gadget);
|
usb_gadget_set_selfpowered(gadget);
|
||||||
|
|
||||||
if (gadget->is_otg) {
|
if (gadget->is_otg) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче