Minor updates to handle more hardware, and cleanups. Please merge. - Dave
Sync with the latest from 2.6, mostly OTG hooks (which probably won't be used on 2.4 without significant host side USB updates) and handling some new controllers, plus some minor cleanups (like NULL != 0).
Signed-off-by: David Brownell <[EMAIL PROTECTED]> --- a/drivers/usb/gadget/zero.c 2004-12-09 12:32:43 -08:00 +++ b/drivers/usb/gadget/zero.c 2004-12-09 12:32:44 -08:00 @@ -200,8 +200,13 @@ * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! * Instead: allocate your own, using normal USB-IF procedures. */ +#ifndef CONFIG_USB_ZERO_HNPTEST #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ #define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */ +#else +#define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */ +#define DRIVER_PRODUCT_NUM 0xbadd +#endif /*-------------------------------------------------------------------------*/ @@ -265,6 +270,14 @@ .bMaxPower = 1, /* self-powered */ }; +static struct usb_otg_descriptor +otg_descriptor = { + .bLength = sizeof otg_descriptor, + .bDescriptorType = USB_DT_OTG, + + .bmAttributes = USB_OTG_SRP, +}; + /* one interface in each configuration */ static const struct usb_interface_descriptor @@ -308,17 +321,19 @@ }; static const struct usb_descriptor_header *fs_source_sink_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &source_sink_intf, (struct usb_descriptor_header *) &fs_sink_desc, (struct usb_descriptor_header *) &fs_source_desc, - 0, + NULL, }; static const struct usb_descriptor_header *fs_loopback_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &loopback_intf, (struct usb_descriptor_header *) &fs_sink_desc, (struct usb_descriptor_header *) &fs_source_desc, - 0, + NULL, }; #ifdef CONFIG_USB_GADGET_DUALSPEED @@ -362,17 +377,19 @@ }; static const struct usb_descriptor_header *hs_source_sink_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &source_sink_intf, (struct usb_descriptor_header *) &hs_source_desc, (struct usb_descriptor_header *) &hs_sink_desc, - 0, + NULL, }; static const struct usb_descriptor_header *hs_loopback_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &loopback_intf, (struct usb_descriptor_header *) &hs_source_desc, (struct usb_descriptor_header *) &hs_sink_desc, - 0, + NULL, }; /* maxpacket and other transfer characteristics vary by speed. */ @@ -385,10 +402,10 @@ #endif /* !CONFIG_USB_GADGET_DUALSPEED */ -static char manufacturer [40]; +static char manufacturer [50]; static char serial [40]; -/* static strings, in iso 8859/1 */ +/* static strings, in UTF-8 */ static struct usb_string strings [] = { { STRING_MANUFACTURER, manufacturer, }, { STRING_PRODUCT, longname, }, @@ -450,6 +467,10 @@ ? fs_source_sink_function : fs_loopback_function; + /* for now, don't advertise srp-only devices */ + if (!gadget->is_otg) + function++; + len = usb_gadget_config_buf (is_source_sink ? &source_sink_config : &loopback_config, @@ -474,7 +495,7 @@ &req->dma, GFP_ATOMIC); if (!req->buf) { usb_ep_free_request (ep, req); - req = 0; + req = NULL; } } return req; @@ -491,7 +512,7 @@ /* optionally require specific source/sink data patterns */ -static inline int +static int check_read_data ( struct zero_dev *dev, struct usb_ep *ep, @@ -525,7 +546,7 @@ return 0; } -static inline void +static void reinit_write_data ( struct zero_dev *dev, struct usb_ep *ep, @@ -605,7 +626,7 @@ req = alloc_ep_req (ep, buflen); if (!req) - return 0; + return NULL; memset (req->buf, 0, req->length); req->complete = source_sink_complete; @@ -619,7 +640,7 @@ ERROR (dev, "start %s --> %d\n", ep->name, status); free_ep_req (ep, req); - req = 0; + req = NULL; } return req; @@ -810,13 +831,14 @@ */ if (dev->in_ep) { usb_ep_disable (dev->in_ep); - dev->in_ep = 0; + dev->in_ep = NULL; } if (dev->out_ep) { usb_ep_disable (dev->out_ep); - dev->out_ep = 0; + dev->out_ep = NULL; } dev->config = 0; + del_timer (&dev->resume); } /* change our operational config. this code must agree with the code @@ -908,6 +930,7 @@ /* usually this stores reply data in the pre-allocated ep0 buffer, * but config change events will reconfigure hardware. */ + req->zero = 0; switch (ctrl->bRequest) { case USB_REQ_GET_DESCRIPTOR: @@ -943,7 +966,8 @@ case USB_DT_STRING: /* wIndex == language code. * this driver only handles one language, you can - * add others even if they don't use iso8859/1 + * add string tables for other languages, using + * any UTF-8 characters */ value = usb_gadget_get_string (&stringtab, ctrl->wValue & 0xff, req->buf); @@ -957,6 +981,12 @@ case USB_REQ_SET_CONFIGURATION: if (ctrl->bRequestType != 0) goto unknown; + if (gadget->a_hnp_support) + DBG (dev, "HNP available\n"); + else if (gadget->a_alt_hnp_support) + DBG (dev, "HNP needs a different root port\n"); + else + VDBG (dev, "HNP inactive\n"); spin_lock (&dev->lock); value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC); spin_unlock (&dev->lock); @@ -1043,6 +1073,8 @@ /* respond with data transfer before status phase? */ if (value >= 0) { req->length = value; + req->zero = value < ctrl->wLength + && (value % gadget->ep0->maxpacket) == 0; value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); if (value < 0) { DBG (dev, "ep_queue --> %d\n", value); @@ -1084,8 +1116,10 @@ /* normally the host would be woken up for something * more significant than just a timer firing... */ - status = usb_gadget_wakeup (dev->gadget); - DBG (dev, "wakeup --> %d\n", status); + if (dev->gadget->speed != USB_SPEED_UNKNOWN) { + status = usb_gadget_wakeup (dev->gadget); + DBG (dev, "wakeup --> %d\n", status); + } } /*-------------------------------------------------------------------------*/ @@ -1102,7 +1136,7 @@ free_ep_req (gadget->ep0, dev->req); del_timer_sync (&dev->resume); kfree (dev); - set_gadget_data (gadget, 0); + set_gadget_data (gadget, NULL); } static int @@ -1158,6 +1192,12 @@ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207); } else if (gadget_is_omap (gadget)) { device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208); + } else if (gadget_is_lh7a40x(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209); + } else if (gadget_is_n9604(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210); + } else if (gadget_is_pxa27x(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211); } else { /* gadget zero is so simple (for now, no altsettings) that * it SHOULD NOT have problems with bulk-capable hardware. @@ -1202,6 +1242,18 @@ hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; #endif + + if (gadget->is_otg) { + otg_descriptor.bmAttributes |= USB_OTG_HNP, + source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } + + if (gadget->is_otg) { + otg_descriptor.bmAttributes |= USB_OTG_HNP, + source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } usb_gadget_set_selfpowered (gadget);