X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fgadget%2Fzero.c;h=68e3d8f5da8947cb8d28cf17c2056b8829d04190;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=a415a33ed117506b7e6d26ac4e4fb6f7be03a4e2;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index a415a33ed..68e3d8f5d 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -75,8 +75,7 @@ #include #include #include -#include -#include +#include #include #include @@ -166,8 +165,8 @@ static unsigned buflen = 4096; static unsigned qlen = 32; static unsigned pattern = 0; -module_param (buflen, uint, S_IRUGO|S_IWUSR); -module_param (qlen, uint, S_IRUGO|S_IWUSR); +module_param (buflen, uint, S_IRUGO); +module_param (qlen, uint, S_IRUGO); module_param (pattern, uint, S_IRUGO|S_IWUSR); /* @@ -396,7 +395,7 @@ static const struct usb_descriptor_header *hs_loopback_function [] = { #endif /* !CONFIG_USB_GADGET_DUALSPEED */ -static char manufacturer [40]; +static char manufacturer [50]; static char serial [40]; /* static strings, in UTF-8 */ @@ -573,9 +572,10 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) switch (status) { case 0: /* normal completion? */ - if (ep == dev->out_ep) + if (ep == dev->out_ep) { check_read_data (dev, ep, req); - else + memset (req->buf, 0x55, req->length); + } else reinit_write_data (dev, ep, req); break; @@ -613,7 +613,7 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) } static struct usb_request * -source_sink_start_ep (struct usb_ep *ep, int gfp_flags) +source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) { struct usb_request *req; int status; @@ -627,6 +627,8 @@ source_sink_start_ep (struct usb_ep *ep, int gfp_flags) if (strcmp (ep->name, EP_IN_NAME) == 0) reinit_write_data (ep->driver_data, ep, req); + else + memset (req->buf, 0x55, req->length); status = usb_ep_queue (ep, req, gfp_flags); if (status) { @@ -641,7 +643,7 @@ source_sink_start_ep (struct usb_ep *ep, int gfp_flags) } static int -set_source_sink_config (struct zero_dev *dev, int gfp_flags) +set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) { int result = 0; struct usb_ep *ep; @@ -745,7 +747,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) } static int -set_loopback_config (struct zero_dev *dev, int gfp_flags) +set_loopback_config (struct zero_dev *dev, gfp_t gfp_flags) { int result = 0; struct usb_ep *ep; @@ -846,7 +848,7 @@ static void zero_reset_config (struct zero_dev *dev) * by limiting configuration choices (like the pxa2xx). */ static int -zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags) +zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags) { int result = 0; struct usb_gadget *gadget = dev->gadget; @@ -920,6 +922,9 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) struct zero_dev *dev = get_gadget_data (gadget); struct usb_request *req = dev->req; int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl->wIndex); + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 w_length = le16_to_cpu(ctrl->wLength); /* usually this stores reply data in the pre-allocated ep0 buffer, * but config change events will reconfigure hardware. @@ -930,17 +935,17 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_REQ_GET_DESCRIPTOR: if (ctrl->bRequestType != USB_DIR_IN) goto unknown; - switch (ctrl->wValue >> 8) { + switch (w_value >> 8) { case USB_DT_DEVICE: - value = min (ctrl->wLength, (u16) sizeof device_desc); + value = min (w_length, (u16) sizeof device_desc); memcpy (req->buf, &device_desc, value); break; #ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER: if (!gadget->is_dualspeed) break; - value = min (ctrl->wLength, (u16) sizeof dev_qualifier); + value = min (w_length, (u16) sizeof dev_qualifier); memcpy (req->buf, &dev_qualifier, value); break; @@ -951,10 +956,10 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) #endif /* CONFIG_USB_GADGET_DUALSPEED */ case USB_DT_CONFIG: value = config_buf (gadget, req->buf, - ctrl->wValue >> 8, - ctrl->wValue & 0xff); + w_value >> 8, + w_value & 0xff); if (value >= 0) - value = min (ctrl->wLength, (u16) value); + value = min (w_length, (u16) value); break; case USB_DT_STRING: @@ -964,9 +969,9 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) * any UTF-8 characters */ value = usb_gadget_get_string (&stringtab, - ctrl->wValue & 0xff, req->buf); + w_value & 0xff, req->buf); if (value >= 0) - value = min (ctrl->wLength, (u16) value); + value = min (w_length, (u16) value); break; } break; @@ -982,14 +987,14 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) else VDBG (dev, "HNP inactive\n"); spin_lock (&dev->lock); - value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC); + value = zero_set_config (dev, w_value, GFP_ATOMIC); spin_unlock (&dev->lock); break; case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != USB_DIR_IN) goto unknown; *(u8 *)req->buf = dev->config; - value = min (ctrl->wLength, (u16) 1); + value = min (w_length, (u16) 1); break; /* until we add altsetting support, or other interfaces, @@ -1000,7 +1005,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (ctrl->bRequestType != USB_RECIP_INTERFACE) goto unknown; spin_lock (&dev->lock); - if (dev->config && ctrl->wIndex == 0 && ctrl->wValue == 0) { + if (dev->config && w_index == 0 && w_value == 0) { u8 config = dev->config; /* resets interface configuration, forgets about @@ -1021,12 +1026,12 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) goto unknown; if (!dev->config) break; - if (ctrl->wIndex != 0) { + if (w_index != 0) { value = -EDOM; break; } *(u8 *)req->buf = 0; - value = min (ctrl->wLength, (u16) 1); + value = min (w_length, (u16) 1); break; /* @@ -1037,23 +1042,23 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case 0x5b: /* control WRITE test -- fill the buffer */ if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR)) goto unknown; - if (ctrl->wValue || ctrl->wIndex) + if (w_value || w_index) break; /* just read that many bytes into the buffer */ - if (ctrl->wLength > USB_BUFSIZ) + if (w_length > USB_BUFSIZ) break; - value = ctrl->wLength; + value = w_length; break; case 0x5c: /* control READ test -- return the buffer */ if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR)) goto unknown; - if (ctrl->wValue || ctrl->wIndex) + if (w_value || w_index) break; /* expect those bytes are still in the buffer; send back */ - if (ctrl->wLength > USB_BUFSIZ - || ctrl->wLength != req->length) + if (w_length > USB_BUFSIZ + || w_length != req->length) break; - value = ctrl->wLength; + value = w_length; break; default: @@ -1061,14 +1066,13 @@ unknown: VDBG (dev, "unknown control req%02x.%02x v%04x i%04x l%d\n", ctrl->bRequestType, ctrl->bRequest, - ctrl->wValue, ctrl->wIndex, ctrl->wLength); + w_value, w_index, w_length); } /* respond with data transfer before status phase? */ if (value >= 0) { req->length = value; - req->zero = value < ctrl->wLength - && (value % gadget->ep0->maxpacket) == 0; + req->zero = value < w_length; value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); if (value < 0) { DBG (dev, "ep_queue --> %d\n", value); @@ -1118,7 +1122,7 @@ zero_autoresume (unsigned long _dev) /*-------------------------------------------------------------------------*/ -static void +static void __exit zero_unbind (struct usb_gadget *gadget) { struct zero_dev *dev = get_gadget_data (gadget); @@ -1126,18 +1130,27 @@ zero_unbind (struct usb_gadget *gadget) DBG (dev, "unbind\n"); /* we've already been disconnected ... no i/o is active */ - if (dev->req) + if (dev->req) { + dev->req->length = USB_BUFSIZ; free_ep_req (gadget->ep0, dev->req); + } del_timer_sync (&dev->resume); kfree (dev); set_gadget_data (gadget, NULL); } -static int +static int __init zero_bind (struct usb_gadget *gadget) { struct zero_dev *dev; struct usb_ep *ep; + int gcnum; + + /* FIXME this can't yet work right with SH ... it has only + * one configuration, numbered one. + */ + if (gadget_is_sh(gadget)) + return -ENODEV; /* Bulk-only drivers like this one SHOULD be able to * autoconfigure on any sane usb controller driver, @@ -1160,35 +1173,10 @@ autoconf_fail: EP_OUT_NAME = ep->name; ep->driver_data = ep; /* claim */ - - /* - * DRIVER POLICY CHOICE: you may want to do this differently. - * One thing to avoid is reusing a bcdDevice revision code - * with different host-visible configurations or behavior - * restrictions -- using ep1in/ep2out vs ep1out/ep3in, etc - */ - if (gadget_is_net2280 (gadget)) { - device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201); - } else if (gadget_is_pxa (gadget)) { - device_desc.bcdDevice = __constant_cpu_to_le16 (0x0203); -#if 0 - } else if (gadget_is_sh(gadget)) { - device_desc.bcdDevice = __constant_cpu_to_le16 (0x0204); - /* SH has only one configuration; see "loopdefault" */ - device_desc.bNumConfigurations = 1; - /* FIXME make 1 == default.bConfigurationValue */ -#endif - } else if (gadget_is_sa1100 (gadget)) { - device_desc.bcdDevice = __constant_cpu_to_le16 (0x0205); - } else if (gadget_is_goku (gadget)) { - device_desc.bcdDevice = __constant_cpu_to_le16 (0x0206); - } else if (gadget_is_mq11xx (gadget)) { - 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 { + gcnum = usb_gadget_controller_number (gadget); + if (gcnum >= 0) + device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum); + else { /* gadget zero is so simple (for now, no altsettings) that * it SHOULD NOT have problems with bulk-capable hardware. * so warn about unrcognized controllers, don't panic. @@ -1203,10 +1191,9 @@ autoconf_fail: /* ok, we made sense of the hardware ... */ - dev = kmalloc (sizeof *dev, SLAB_KERNEL); + dev = kzalloc(sizeof(*dev), SLAB_KERNEL); if (!dev) return -ENOMEM; - memset (dev, 0, sizeof *dev); spin_lock_init (&dev->lock); dev->gadget = gadget; set_gadget_data (gadget, dev); @@ -1239,12 +1226,6 @@ autoconf_fail: 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); init_timer (&dev->resume); @@ -1261,8 +1242,8 @@ autoconf_fail: INFO (dev, "using %s, OUT %s IN %s\n", gadget->name, EP_OUT_NAME, EP_IN_NAME); - snprintf (manufacturer, sizeof manufacturer, - UTS_SYSNAME " " UTS_RELEASE " with %s", + snprintf (manufacturer, sizeof manufacturer, "%s %s with %s", + system_utsname.sysname, system_utsname.release, gadget->name); return 0; @@ -1309,7 +1290,7 @@ static struct usb_gadget_driver zero_driver = { #endif .function = (char *) longname, .bind = zero_bind, - .unbind = zero_unbind, + .unbind = __exit_p(zero_unbind), .setup = zero_setup, .disconnect = zero_disconnect, @@ -1319,9 +1300,7 @@ static struct usb_gadget_driver zero_driver = { .driver = { .name = (char *) shortname, - // .shutdown = ... - // .suspend = ... - // .resume = ... + .owner = THIS_MODULE, }, };