From 72c973dd2b01b212a159faa330a2bc641a3ed809 Mon Sep 17 00:00:00 2001 From: Tatyana Brokhman Date: Tue, 28 Jun 2011 16:33:48 +0300 Subject: usb: gadget: add usb_endpoint_descriptor to struct usb_ep Change usb_ep_enable() prototype to use endpoint descriptor from usb_ep. This optimization spares the FDs from saving the endpoint chosen descriptor. This optimization is not full though. To fully exploit this change, one needs to update all the UDCs as well since in the current implementation each of them saves the endpoint descriptor in it's internal (and extended) endpoint structure. Signed-off-by: Tatyana Brokhman Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/printer.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers/usb/gadget/printer.c') diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 271ef94..00e5f19 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -89,8 +89,7 @@ struct printer_dev { u8 config; s8 interface; struct usb_ep *in_ep, *out_ep; - const struct usb_endpoint_descriptor - *in, *out; + struct list_head rx_reqs; /* List of free RX structs */ struct list_head rx_reqs_active; /* List of Active RX xfers */ struct list_head rx_buffers; /* List of completed xfers */ @@ -895,19 +894,20 @@ set_printer_interface(struct printer_dev *dev) { int result = 0; - dev->in = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc); + dev->in_ep->desc = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc); dev->in_ep->driver_data = dev; - dev->out = ep_desc(dev->gadget, &hs_ep_out_desc, &fs_ep_out_desc); + dev->out_ep->desc = ep_desc(dev->gadget, &hs_ep_out_desc, + &fs_ep_out_desc); dev->out_ep->driver_data = dev; - result = usb_ep_enable(dev->in_ep, dev->in); + result = usb_ep_enable(dev->in_ep); if (result != 0) { DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); goto done; } - result = usb_ep_enable(dev->out_ep, dev->out); + result = usb_ep_enable(dev->out_ep); if (result != 0) { DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); goto done; @@ -918,8 +918,8 @@ done: if (result != 0) { (void) usb_ep_disable(dev->in_ep); (void) usb_ep_disable(dev->out_ep); - dev->in = NULL; - dev->out = NULL; + dev->in_ep->desc = NULL; + dev->out_ep->desc = NULL; } /* caller is responsible for cleanup on error */ @@ -933,12 +933,14 @@ static void printer_reset_interface(struct printer_dev *dev) DBG(dev, "%s\n", __func__); - if (dev->in) + if (dev->in_ep->desc) usb_ep_disable(dev->in_ep); - if (dev->out) + if (dev->out_ep->desc) usb_ep_disable(dev->out_ep); + dev->in_ep->desc = NULL; + dev->out_ep->desc = NULL; dev->interface = -1; } @@ -1104,9 +1106,9 @@ static void printer_soft_reset(struct printer_dev *dev) list_add(&req->list, &dev->tx_reqs); } - if (usb_ep_enable(dev->in_ep, dev->in)) + if (usb_ep_enable(dev->in_ep)) DBG(dev, "Failed to enable USB in_ep\n"); - if (usb_ep_enable(dev->out_ep, dev->out)) + if (usb_ep_enable(dev->out_ep)) DBG(dev, "Failed to enable USB out_ep\n"); wake_up_interruptible(&dev->rx_wait); -- cgit v1.1 From 765f5b830e547229bb752e7b232ee83e2b3d49d5 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 23 Jun 2011 14:26:11 +0200 Subject: 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 Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/printer.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/usb/gadget/printer.c') 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) { -- cgit v1.1