diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 07:30:48 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 07:30:48 +0400 |
commit | 5cc103506289de7ee0a0b526ae0381541990cad4 (patch) | |
tree | ae8a4958e70c6d1295030b40e333dcc007b3c074 /drivers/usb/gadget | |
parent | 73ecf3a6e3f0206bf56a0fefe3b3eda042fb7034 (diff) | |
parent | 92ca0dc5ee022e4c0e488177e1d8865a0778c6c2 (diff) | |
download | linux-5cc103506289de7ee0a0b526ae0381541990cad4.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (141 commits)
USB: mct_u232: fix broken close
USB: gadget: amd5536udc.c: fix error path
USB: imx21-hcd - fix off by one resource size calculation
usb: gadget: fix Kconfig warning
usb: r8a66597-udc: Add processing when USB was removed.
mxc_udc: add workaround for ENGcm09152 for i.MX35
USB: ftdi_sio: add device ids for ScienceScope
USB: musb: AM35x: Workaround for fifo read issue
USB: musb: add musb support for AM35x
USB: AM35x: Add musb support
usb: Fix linker errors with CONFIG_PM=n
USB: ohci-sh - use resource_size instead of defining its own resource_len macro
USB: isp1362-hcd - use resource_size instead of defining its own resource_len macro
USB: isp116x-hcd - use resource_size instead of defining its own resource_len macro
USB: xhci: Fix compile error when CONFIG_PM=n
USB: accept some invalid ep0-maxpacket values
USB: xHCI: PCI power management implementation
USB: xHCI: bus power management implementation
USB: xHCI: port remote wakeup implementation
USB: xHCI: port power management implementation
...
Manually fix up (non-data) conflict: the SCSI merge gad renamed the
'hw_sector_size' member to 'physical_block_size', and the USB tree
brought a new use of it.
Diffstat (limited to 'drivers/usb/gadget')
47 files changed, 1366 insertions, 1265 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index cd27f9bde2c8..b739ca814651 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -158,6 +158,7 @@ config USB_GADGET_FSL_USB2 boolean "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC select USB_GADGET_DUALSPEED + select USB_FSL_MPH_DR_OF help Some of Freescale PowerPC processors have a High Speed Dual-Role(DR) USB controller, which supports device mode. @@ -209,17 +210,6 @@ config USB_OMAP default USB_GADGET select USB_GADGET_SELECTED -config USB_OTG - boolean "OTG Support" - depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD - help - The most notable feature of USB OTG is support for a - "Dual-Role" device, which can act as either a device - or a host. The initial role choice can be changed - later, when two dual-role devices talk to each other. - - Select this only if your OMAP board has a Mini-AB connector. - config USB_GADGET_PXA25X boolean "PXA 25x or IXP 4xx" depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX @@ -716,8 +706,8 @@ config USB_FUNCTIONFS depends on EXPERIMENTAL select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS) help - The Function Filesystem (FunctioFS) lets one create USB - composite functions in user space in the same way as GadgetFS + The Function Filesystem (FunctionFS) lets one create USB + composite functions in user space in the same way GadgetFS lets one create USB gadgets in user space. This allows creation of composite gadgets such that some of the functions are implemented in kernel space (for instance Ethernet, serial or @@ -733,14 +723,14 @@ config USB_FUNCTIONFS_ETH bool "Include configuration with CDC ECM (Ethernet)" depends on USB_FUNCTIONFS && NET help - Include a configuration with CDC ECM funcion (Ethernet) and the - Funcion Filesystem. + Include a configuration with CDC ECM function (Ethernet) and the + Function Filesystem. config USB_FUNCTIONFS_RNDIS bool "Include configuration with RNDIS (Ethernet)" depends on USB_FUNCTIONFS && NET help - Include a configuration with RNDIS funcion (Ethernet) and the Filesystem. + Include a configuration with RNDIS function (Ethernet) and the Filesystem. config USB_FUNCTIONFS_GENERIC bool "Include 'pure' configuration" diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 27283df37d09..5780db42417b 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -1,9 +1,7 @@ # # USB peripheral controller drivers # -ifeq ($(CONFIG_USB_GADGET_DEBUG),y) - EXTRA_CFLAGS += -DDEBUG -endif +ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2280) += net2280.o @@ -18,10 +16,8 @@ obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o obj-$(CONFIG_USB_AT91) += at91_udc.o obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o -fsl_usb2_udc-objs := fsl_udc_core.o -ifeq ($(CONFIG_ARCH_MXC),y) -fsl_usb2_udc-objs += fsl_mxc_udc.o -endif +fsl_usb2_udc-y := fsl_udc_core.o +fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o obj-$(CONFIG_USB_M66592) += m66592-udc.o obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o @@ -32,21 +28,21 @@ obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o # # USB gadget drivers # -g_zero-objs := zero.o -g_audio-objs := audio.o -g_ether-objs := ether.o -g_serial-objs := serial.o -g_midi-objs := gmidi.o -gadgetfs-objs := inode.o -g_file_storage-objs := file_storage.o -g_mass_storage-objs := mass_storage.o -g_printer-objs := printer.o -g_cdc-objs := cdc2.o -g_multi-objs := multi.o -g_hid-objs := hid.o -g_dbgp-objs := dbgp.o -g_nokia-objs := nokia.o -g_webcam-objs := webcam.o +g_zero-y := zero.o +g_audio-y := audio.o +g_ether-y := ether.o +g_serial-y := serial.o +g_midi-y := gmidi.o +gadgetfs-y := inode.o +g_file_storage-y := file_storage.o +g_mass_storage-y := mass_storage.o +g_printer-y := printer.o +g_cdc-y := cdc2.o +g_multi-y := multi.o +g_hid-y := hid.o +g_dbgp-y := dbgp.o +g_nokia-y := nokia.o +g_webcam-y := webcam.o obj-$(CONFIG_USB_ZERO) += g_zero.o obj-$(CONFIG_USB_AUDIO) += g_audio.o @@ -64,4 +60,3 @@ obj-$(CONFIG_USB_G_DBGP) += g_dbgp.o obj-$(CONFIG_USB_G_MULTI) += g_multi.o obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o - diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 731150d4b1d9..9034e0344723 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -203,7 +203,7 @@ static void print_regs(struct udc *dev) DBG(dev, "DMA mode = PPBNDU (packet per buffer " "WITHOUT desc. update)\n"); dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBNDU"); - } else if (use_dma && use_dma_ppb_du && use_dma_ppb_du) { + } else if (use_dma && use_dma_ppb && use_dma_ppb_du) { DBG(dev, "DMA mode = PPBDU (packet per buffer " "WITH desc. update)\n"); dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBDU"); @@ -1954,13 +1954,14 @@ static int setup_ep0(struct udc *dev) } /* Called by gadget driver to register itself */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct udc *dev = udc; int retval; u32 tmp; - if (!driver || !driver->bind || !driver->setup + if (!driver || !bind || !driver->setup || driver->speed != USB_SPEED_HIGH) return -EINVAL; if (!dev) @@ -1972,7 +1973,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - retval = driver->bind(&dev->gadget); + retval = bind(&dev->gadget); /* Some gadget drivers use both ep0 directions. * NOTE: to gadget driver, ep0 is just one endpoint... @@ -2000,7 +2001,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) return 0; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); /* shutdown requests and disconnect from gadget */ static void @@ -3382,8 +3383,10 @@ static int udc_probe(struct udc *dev) udc = dev; retval = device_register(&dev->gadget.dev); - if (retval) + if (retval) { + put_device(&dev->gadget.dev); goto finished; + } /* timer init */ init_timer(&udc_timer); diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 93ead19507b6..387e503b9d14 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1628,7 +1628,8 @@ static void at91_vbus_timer(unsigned long data) schedule_work(&udc->vbus_timer_work); } -int usb_gadget_register_driver (struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct at91_udc *udc = &controller; int retval; @@ -1636,7 +1637,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) if (!driver || driver->speed < USB_SPEED_FULL - || !driver->bind + || !bind || !driver->setup) { DBG("bad parameter.\n"); return -EINVAL; @@ -1653,9 +1654,9 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) udc->enabled = 1; udc->selfpowered = 1; - retval = driver->bind(&udc->gadget); + retval = bind(&udc->gadget); if (retval) { - DBG("driver->bind() returned %d\n", retval); + DBG("bind() returned %d\n", retval); udc->driver = NULL; udc->gadget.dev.driver = NULL; dev_set_drvdata(&udc->gadget.dev, NULL); @@ -1671,7 +1672,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) DBG("bound to %s\n", driver->driver.name); return 0; } -EXPORT_SYMBOL (usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) { diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index d623c7bda1f6..b5e20e873cba 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1789,7 +1789,8 @@ out: return IRQ_HANDLED; } -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct usba_udc *udc = &the_udc; unsigned long flags; @@ -1812,7 +1813,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) clk_enable(udc->pclk); clk_enable(udc->hclk); - ret = driver->bind(&udc->gadget); + ret = bind(&udc->gadget); if (ret) { DBG(DBG_ERR, "Could not bind to driver %s: error %d\n", driver->driver.name, ret); @@ -1841,7 +1842,7 @@ err_driver_bind: udc->gadget.dev.driver = NULL; return ret; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { @@ -2014,6 +2015,9 @@ static int __init usba_udc_probe(struct platform_device *pdev) } else { disable_irq(gpio_to_irq(udc->vbus_pin)); } + } else { + /* gpio_request fail so use -EINVAL for gpio_is_valid */ + ubc->vbus_pin = -EINVAL; } } diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index b744ccd0f34d..93b999e49ef3 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -89,7 +89,7 @@ static const struct usb_descriptor_header *otg_desc[] = { /*-------------------------------------------------------------------------*/ -static int __ref audio_do_config(struct usb_configuration *c) +static int __init audio_do_config(struct usb_configuration *c) { /* FIXME alloc iConfiguration string, set it in c->strings */ @@ -105,7 +105,6 @@ static int __ref audio_do_config(struct usb_configuration *c) static struct usb_configuration audio_config_driver = { .label = DRIVER_DESC, - .bind = audio_do_config, .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, @@ -113,7 +112,7 @@ static struct usb_configuration audio_config_driver = { /*-------------------------------------------------------------------------*/ -static int __ref audio_bind(struct usb_composite_dev *cdev) +static int __init audio_bind(struct usb_composite_dev *cdev) { int gcnum; int status; @@ -145,7 +144,7 @@ static int __ref audio_bind(struct usb_composite_dev *cdev) strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; - status = usb_add_config(cdev, &audio_config_driver); + status = usb_add_config(cdev, &audio_config_driver, audio_do_config); if (status < 0) goto fail; @@ -166,13 +165,12 @@ static struct usb_composite_driver audio_driver = { .name = "g_audio", .dev = &device_desc, .strings = audio_strings, - .bind = audio_bind, .unbind = __exit_p(audio_unbind), }; static int __init init(void) { - return usb_composite_register(&audio_driver); + return usb_composite_probe(&audio_driver, audio_bind); } module_init(init); diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 1f5ba2fd4c1f..2720ab07ef1a 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -129,7 +129,7 @@ static u8 hostaddr[ETH_ALEN]; /* * We _always_ have both CDC ECM and CDC ACM functions. */ -static int __ref cdc_do_config(struct usb_configuration *c) +static int __init cdc_do_config(struct usb_configuration *c) { int status; @@ -151,7 +151,6 @@ static int __ref cdc_do_config(struct usb_configuration *c) static struct usb_configuration cdc_config_driver = { .label = "CDC Composite (ECM + ACM)", - .bind = cdc_do_config, .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, @@ -159,7 +158,7 @@ static struct usb_configuration cdc_config_driver = { /*-------------------------------------------------------------------------*/ -static int __ref cdc_bind(struct usb_composite_dev *cdev) +static int __init cdc_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; @@ -218,7 +217,7 @@ static int __ref cdc_bind(struct usb_composite_dev *cdev) device_desc.iProduct = status; /* register our configuration */ - status = usb_add_config(cdev, &cdc_config_driver); + status = usb_add_config(cdev, &cdc_config_driver, cdc_do_config); if (status < 0) goto fail1; @@ -245,7 +244,6 @@ static struct usb_composite_driver cdc_driver = { .name = "g_cdc", .dev = &device_desc, .strings = dev_strings, - .bind = cdc_bind, .unbind = __exit_p(cdc_unbind), }; @@ -255,7 +253,7 @@ MODULE_LICENSE("GPL"); static int __init init(void) { - return usb_composite_register(&cdc_driver); + return usb_composite_probe(&cdc_driver, cdc_bind); } module_init(init); diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 699695128e33..98b36fc88c77 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -2340,12 +2340,15 @@ static const struct usb_ep_ops usb_ep_ops = { static const struct usb_gadget_ops usb_gadget_ops; /** - * usb_gadget_register_driver: register a gadget driver + * usb_gadget_probe_driver: register a gadget driver + * @driver: the driver being registered + * @bind: the driver's bind callback * - * Check usb_gadget_register_driver() at "usb_gadget.h" for details - * Interrupts are enabled here + * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details. + * Interrupts are enabled here. */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct ci13xxx *udc = _udc; unsigned long i, k, flags; @@ -2354,7 +2357,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) trace("%p", driver); if (driver == NULL || - driver->bind == NULL || + bind == NULL || driver->unbind == NULL || driver->setup == NULL || driver->disconnect == NULL || @@ -2430,7 +2433,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) udc->gadget.dev.driver = &driver->driver; spin_unlock_irqrestore(udc->lock, flags); - retval = driver->bind(&udc->gadget); /* MAY SLEEP */ + retval = bind(&udc->gadget); /* MAY SLEEP */ spin_lock_irqsave(udc->lock, flags); if (retval) { @@ -2447,7 +2450,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) usb_gadget_unregister_driver(driver); return retval; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); /** * usb_gadget_unregister_driver: unregister a gadget driver @@ -2462,7 +2465,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) trace("%p", driver); if (driver == NULL || - driver->bind == NULL || driver->unbind == NULL || driver->setup == NULL || driver->disconnect == NULL || diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 1160c55de7f2..7b5cc16e4a0b 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -24,6 +24,7 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/device.h> +#include <linux/utsname.h> #include <linux/usb/composite.h> @@ -39,6 +40,7 @@ #define USB_BUFSIZ 1024 static struct usb_composite_driver *composite; +static int (*composite_gadget_bind)(struct usb_composite_dev *cdev); /* Some systems will need runtime overrides for the product identifers * published in the device descriptor, either numbers or strings or both. @@ -69,6 +71,8 @@ static char *iSerialNumber; module_param(iSerialNumber, charp, 0); MODULE_PARM_DESC(iSerialNumber, "SerialNumber string"); +static char composite_manufacturer[50]; + /*-------------------------------------------------------------------------*/ /** @@ -470,18 +474,20 @@ done: * usb_add_config() - add a configuration to a device. * @cdev: wraps the USB gadget * @config: the configuration, with bConfigurationValue assigned + * @bind: the configuration's bind function * Context: single threaded during gadget setup * - * One of the main tasks of a composite driver's bind() routine is to + * One of the main tasks of a composite @bind() routine is to * add each of the configurations it supports, using this routine. * - * This function returns the value of the configuration's bind(), which + * This function returns the value of the configuration's @bind(), which * is zero for success else a negative errno value. Binding configurations * assigns global resources including string IDs, and per-configuration * resources such as interface IDs and endpoints. */ int usb_add_config(struct usb_composite_dev *cdev, - struct usb_configuration *config) + struct usb_configuration *config, + int (*bind)(struct usb_configuration *)) { int status = -EINVAL; struct usb_configuration *c; @@ -490,7 +496,7 @@ int usb_add_config(struct usb_composite_dev *cdev, config->bConfigurationValue, config->label, config); - if (!config->bConfigurationValue || !config->bind) + if (!config->bConfigurationValue || !bind) goto done; /* Prevent duplicate configuration identifiers */ @@ -507,7 +513,7 @@ int usb_add_config(struct usb_composite_dev *cdev, INIT_LIST_HEAD(&config->functions); config->next_interface_id = 0; - status = config->bind(config); + status = bind(config); if (status < 0) { list_del(&config->list); config->cdev = NULL; @@ -533,7 +539,7 @@ int usb_add_config(struct usb_composite_dev *cdev, } } - /* set_alt(), or next config->bind(), sets up + /* set_alt(), or next bind(), sets up * ep->driver_data as needed. */ usb_ep_autoconfig_reset(cdev->gadget); @@ -599,6 +605,7 @@ static int get_string(struct usb_composite_dev *cdev, struct usb_configuration *c; struct usb_function *f; int len; + const char *str; /* Yes, not only is USB's I18N support probably more than most * folk will ever care about ... also, it's all supported here. @@ -638,9 +645,29 @@ static int get_string(struct usb_composite_dev *cdev, return s->bLength; } - /* Otherwise, look up and return a specified string. String IDs - * are device-scoped, so we look up each string table we're told - * about. These lookups are infrequent; simpler-is-better here. + /* Otherwise, look up and return a specified string. First + * check if the string has not been overridden. + */ + if (cdev->manufacturer_override == id) + str = iManufacturer ?: composite->iManufacturer ?: + composite_manufacturer; + else if (cdev->product_override == id) + str = iProduct ?: composite->iProduct; + else if (cdev->serial_override == id) + str = iSerialNumber; + else + str = NULL; + if (str) { + struct usb_gadget_strings strings = { + .language = language, + .strings = &(struct usb_string) { 0xff, str } + }; + return usb_gadget_get_string(&strings, 0xff, buf); + } + + /* String IDs are device-scoped, so we look up each string + * table we're told about. These lookups are infrequent; + * simpler-is-better here. */ if (composite->strings) { len = lookup_string(composite->strings, buf, language, id); @@ -901,7 +928,8 @@ unknown: */ switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_INTERFACE: - f = cdev->config->interface[intf]; + if (cdev->config) + f = cdev->config->interface[intf]; break; case USB_RECIP_ENDPOINT: @@ -1025,26 +1053,17 @@ composite_unbind(struct usb_gadget *gadget) composite = NULL; } -static void -string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s) +static u8 override_id(struct usb_composite_dev *cdev, u8 *desc) { - struct usb_string *str = tab->strings; - - for (str = tab->strings; str->s; str++) { - if (str->id == id) { - str->s = s; - return; - } + if (!*desc) { + int ret = usb_string_id(cdev); + if (unlikely(ret < 0)) + WARNING(cdev, "failed to override string ID\n"); + else + *desc = ret; } -} -static void -string_override(struct usb_gadget_strings **tab, u8 id, const char *s) -{ - while (*tab) { - string_override_one(*tab, id, s); - tab++; - } + return *desc; } static int composite_bind(struct usb_gadget *gadget) @@ -1074,7 +1093,13 @@ static int composite_bind(struct usb_gadget *gadget) cdev->bufsiz = USB_BUFSIZ; cdev->driver = composite; - usb_gadget_set_selfpowered(gadget); + /* + * As per USB compliance update, a device that is actively drawing + * more than 100mA from USB must report itself as bus-powered in + * the GetStatus(DEVICE) call. + */ + if (CONFIG_USB_GADGET_VBUS_DRAW <= USB_SELF_POWER_VBUS_MAX_DRAW) + usb_gadget_set_selfpowered(gadget); /* interface and string IDs start at zero via kzalloc. * we force endpoints to start unassigned; few controller @@ -1094,26 +1119,41 @@ static int composite_bind(struct usb_gadget *gadget) * serial number), register function drivers, potentially update * power state and consumption, etc */ - status = composite->bind(cdev); + status = composite_gadget_bind(cdev); if (status < 0) goto fail; cdev->desc = *composite->dev; cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; - /* strings can't be assigned before bind() allocates the - * releavnt identifiers - */ - if (cdev->desc.iManufacturer && iManufacturer) - string_override(composite->strings, - cdev->desc.iManufacturer, iManufacturer); - if (cdev->desc.iProduct && iProduct) - string_override(composite->strings, - cdev->desc.iProduct, iProduct); - if (cdev->desc.iSerialNumber && iSerialNumber) - string_override(composite->strings, - cdev->desc.iSerialNumber, iSerialNumber); + /* stirng overrides */ + if (iManufacturer || !cdev->desc.iManufacturer) { + if (!iManufacturer && !composite->iManufacturer && + !*composite_manufacturer) + snprintf(composite_manufacturer, + sizeof composite_manufacturer, + "%s %s with %s", + init_utsname()->sysname, + init_utsname()->release, + gadget->name); + + cdev->manufacturer_override = + override_id(cdev, &cdev->desc.iManufacturer); + } + + if (iProduct || (!cdev->desc.iProduct && composite->iProduct)) + cdev->product_override = + override_id(cdev, &cdev->desc.iProduct); + + if (iSerialNumber) + cdev->serial_override = + override_id(cdev, &cdev->desc.iSerialNumber); + + /* has userspace failed to provide a serial number? */ + if (composite->needs_serial && !cdev->desc.iSerialNumber) + WARNING(cdev, "userspace failed to provide iSerialNumber\n"); + /* finish up */ status = device_create_file(&gadget->dev, &dev_attr_suspended); if (status) goto fail; @@ -1177,7 +1217,6 @@ composite_resume(struct usb_gadget *gadget) static struct usb_gadget_driver composite_driver = { .speed = USB_SPEED_HIGH, - .bind = composite_bind, .unbind = composite_unbind, .setup = composite_setup, @@ -1192,8 +1231,12 @@ static struct usb_gadget_driver composite_driver = { }; /** - * usb_composite_register() - register a composite driver + * usb_composite_probe() - register a composite driver * @driver: the driver to register + * @bind: the callback used to allocate resources that are shared across the + * whole device, such as string IDs, and add its configurations using + * @usb_add_config(). This may fail by returning a negative errno + * value; it should return zero on successful initialization. * Context: single threaded during gadget setup * * This function is used to register drivers using the composite driver @@ -1206,18 +1249,22 @@ static struct usb_gadget_driver composite_driver = { * while it was binding. That would usually be done in order to wait for * some userspace participation. */ -int usb_composite_register(struct usb_composite_driver *driver) +extern int usb_composite_probe(struct usb_composite_driver *driver, + int (*bind)(struct usb_composite_dev *cdev)) { - if (!driver || !driver->dev || !driver->bind || composite) + if (!driver || !driver->dev || !bind || composite) return -EINVAL; + if (!driver->iProduct) + driver->iProduct = driver->name; if (!driver->name) driver->name = "composite"; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; composite = driver; + composite_gadget_bind = bind; - return usb_gadget_register_driver(&composite_driver); + return usb_gadget_probe_driver(&composite_driver, composite_bind); } /** diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index 0ed50a2c0a36..e5ac8a316fec 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c @@ -386,15 +386,13 @@ static int dbgp_setup(struct usb_gadget *gadget, } else goto fail; - if (len >= 0) { - req->length = min(length, len); - req->zero = len < req->length; - if (data && req->length) - memcpy(req->buf, data, req->length); - - req->complete = dbgp_setup_complete; - return usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); - } + req->length = min(length, len); + req->zero = len < req->length; + if (data && req->length) + memcpy(req->buf, data, req->length); + + req->complete = dbgp_setup_complete; + return usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); fail: dev_dbg(&dbgp.gadget->dev, @@ -405,7 +403,6 @@ fail: static struct usb_gadget_driver dbgp_driver = { .function = "dbgp", .speed = USB_SPEED_HIGH, - .bind = dbgp_bind, .unbind = dbgp_unbind, .setup = dbgp_setup, .disconnect = dbgp_disconnect, @@ -417,7 +414,7 @@ static struct usb_gadget_driver dbgp_driver = { static int __init dbgp_init(void) { - return usb_gadget_register_driver(&dbgp_driver); + return usb_gadget_probe_driver(&dbgp_driver, dbgp_bind); } static void __exit dbgp_exit(void) diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index dc6546248ed9..1d2a2abbfa80 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -748,7 +748,8 @@ static DEVICE_ATTR (function, S_IRUGO, show_function, NULL); */ int -usb_gadget_register_driver (struct usb_gadget_driver *driver) +usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct dummy *dum = the_controller; int retval, i; @@ -757,8 +758,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) return -EINVAL; if (dum->driver) return -EBUSY; - if (!driver->bind || !driver->setup - || driver->speed == USB_SPEED_UNKNOWN) + if (!bind || !driver->setup || driver->speed == USB_SPEED_UNKNOWN) return -EINVAL; /* @@ -796,7 +796,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) dum->gadget.dev.driver = &driver->driver; dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n", driver->driver.name); - retval = driver->bind(&dum->gadget); + retval = bind(&dum->gadget); if (retval) { dum->driver = NULL; dum->gadget.dev.driver = NULL; @@ -812,7 +812,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) usb_hcd_poll_rh_status (dummy_to_hcd (dum)); return 0; } -EXPORT_SYMBOL (usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) @@ -874,6 +874,8 @@ static int dummy_udc_probe (struct platform_device *pdev) struct dummy *dum = the_controller; int rc; + usb_get_hcd(dummy_to_hcd(dum)); + dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; dum->gadget.is_dualspeed = 1; @@ -885,10 +887,10 @@ static int dummy_udc_probe (struct platform_device *pdev) dum->gadget.dev.parent = &pdev->dev; dum->gadget.dev.release = dummy_gadget_release; rc = device_register (&dum->gadget.dev); - if (rc < 0) + if (rc < 0) { + put_device(&dum->gadget.dev); return rc; - - usb_get_hcd (dummy_to_hcd (dum)); + } platform_set_drvdata (pdev, dum); rc = device_create_file (&dum->gadget.dev, &dev_attr_function); diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 114fa024c22c..1690c9d68256 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -237,7 +237,7 @@ static u8 hostaddr[ETH_ALEN]; * the first one present. That's to make Microsoft's drivers happy, * and to follow DOCSIS 1.0 (cable modem standard). */ -static int __ref rndis_do_config(struct usb_configuration *c) +static int __init rndis_do_config(struct usb_configuration *c) { /* FIXME alloc iConfiguration string, set it in c->strings */ @@ -251,7 +251,6 @@ static int __ref rndis_do_config(struct usb_configuration *c) static struct usb_configuration rndis_config_driver = { .label = "RNDIS", - .bind = rndis_do_config, .bConfigurationValue = 2, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, @@ -270,7 +269,7 @@ MODULE_PARM_DESC(use_eem, "use CDC EEM mode"); /* * We _always_ have an ECM, CDC Subset, or EEM configuration. */ -static int __ref eth_do_config(struct usb_configuration *c) +static int __init eth_do_config(struct usb_configuration *c) { /* FIXME alloc iConfiguration string, set it in c->strings */ @@ -289,7 +288,6 @@ static int __ref eth_do_config(struct usb_configuration *c) static struct usb_configuration eth_config_driver = { /* .label = f(hardware) */ - .bind = eth_do_config, .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, @@ -297,7 +295,7 @@ static struct usb_configuration eth_config_driver = { /*-------------------------------------------------------------------------*/ -static int __ref eth_bind(struct usb_composite_dev *cdev) +static int __init eth_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; @@ -373,12 +371,13 @@ static int __ref eth_bind(struct usb_composite_dev *cdev) /* register our configuration(s); RNDIS first, if it's used */ if (has_rndis()) { - status = usb_add_config(cdev, &rndis_config_driver); + status = usb_add_config(cdev, &rndis_config_driver, + rndis_do_config); if (status < 0) goto fail; } - status = usb_add_config(cdev, ð_config_driver); + status = usb_add_config(cdev, ð_config_driver, eth_do_config); if (status < 0) goto fail; @@ -402,7 +401,6 @@ static struct usb_composite_driver eth_driver = { .name = "g_ether", .dev = &device_desc, .strings = dev_strings, - .bind = eth_bind, .unbind = __exit_p(eth_unbind), }; @@ -412,7 +410,7 @@ MODULE_LICENSE("GPL"); static int __init init(void) { - return usb_composite_register(ð_driver); + return usb_composite_probe(ð_driver, eth_bind); } module_init(init); diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index d47a123f15ab..bd6226cbae86 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -111,7 +111,7 @@ acm_iad_descriptor = { .bInterfaceCount = 2, // control + data .bFunctionClass = USB_CLASS_COMM, .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, - .bFunctionProtocol = USB_CDC_PROTO_NONE, + .bFunctionProtocol = USB_CDC_ACM_PROTO_AT_V25TER, /* .iFunction = DYNAMIC */ }; diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 43225879c3cd..b37960f9e753 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c @@ -324,7 +324,7 @@ static void loopback_disable(struct usb_function *f) /*-------------------------------------------------------------------------*/ -static int __ref loopback_bind_config(struct usb_configuration *c) +static int __init loopback_bind_config(struct usb_configuration *c) { struct f_loopback *loop; int status; @@ -346,10 +346,9 @@ static int __ref loopback_bind_config(struct usb_configuration *c) return status; } -static struct usb_configuration loopback_driver = { +static struct usb_configuration loopback_driver = { .label = "loopback", .strings = loopback_strings, - .bind = loopback_bind_config, .bConfigurationValue = 2, .bmAttributes = USB_CONFIG_ATT_SELFPOWER, /* .iConfiguration = DYNAMIC */ @@ -382,5 +381,5 @@ int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume) loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - return usb_add_config(cdev, &loopback_driver); + return usb_add_config(cdev, &loopback_driver, loopback_bind_config); } diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 32cce029f65c..838286b1cd14 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -73,6 +73,8 @@ * being removable. * ->cdrom Flag specifying that LUN shall be reported as * being a CD-ROM. + * ->nofua Flag specifying that FUA flag in SCSI WRITE(10,12) + * commands for this LUN shall be ignored. * * lun_name_format A printf-like format for names of the LUN * devices. This determines how the @@ -127,6 +129,8 @@ * Default true, boolean for removable media. * cdrom=b[,b...] Default false, boolean for whether to emulate * a CD-ROM drive. + * nofua=b[,b...] Default false, booleans for ignore FUA flag + * in SCSI WRITE(10,12) commands * luns=N Default N = number of filenames, number of * LUNs to support. * stall Default determined according to the type of @@ -409,6 +413,7 @@ struct fsg_config { char ro; char removable; char cdrom; + char nofua; } luns[FSG_MAX_LUNS]; const char *lun_name_format; @@ -736,7 +741,7 @@ static int do_read(struct fsg_common *common) /* Get the starting Logical Block Address and check that it's * not too big */ - if (common->cmnd[0] == SC_READ_6) + if (common->cmnd[0] == READ_6) lba = get_unaligned_be24(&common->cmnd[1]); else { lba = get_unaligned_be32(&common->cmnd[2]); @@ -874,7 +879,7 @@ static int do_write(struct fsg_common *common) /* Get the starting Logical Block Address and check that it's * not too big */ - if (common->cmnd[0] == SC_WRITE_6) + if (common->cmnd[0] == WRITE_6) lba = get_unaligned_be24(&common->cmnd[1]); else { lba = get_unaligned_be32(&common->cmnd[2]); @@ -887,7 +892,7 @@ static int do_write(struct fsg_common *common) curlun->sense_data = SS_INVALID_FIELD_IN_CDB; return -EINVAL; } - if (common->cmnd[1] & 0x08) { /* FUA */ + if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */ spin_lock(&curlun->filp->f_lock); curlun->filp->f_flags |= O_SYNC; spin_unlock(&curlun->filp->f_lock); @@ -1181,7 +1186,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh) return 36; } - buf[0] = curlun->cdrom ? TYPE_CDROM : TYPE_DISK; + buf[0] = curlun->cdrom ? TYPE_ROM : TYPE_DISK; buf[1] = curlun->removable ? 0x80 : 0; buf[2] = 2; /* ANSI SCSI level 2 */ buf[3] = 2; /* SCSI-2 INQUIRY data format */ @@ -1348,11 +1353,11 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) * The only variable value is the WriteProtect bit. We will fill in * the mode data length later. */ memset(buf, 0, 8); - if (mscmnd == SC_MODE_SENSE_6) { + if (mscmnd == MODE_SENSE) { buf[2] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */ buf += 4; limit = 255; - } else { /* SC_MODE_SENSE_10 */ + } else { /* MODE_SENSE_10 */ buf[3] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */ buf += 8; limit = 65535; /* Should really be FSG_BUFLEN */ @@ -1392,7 +1397,7 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) } /* Store the mode data length */ - if (mscmnd == SC_MODE_SENSE_6) + if (mscmnd == MODE_SENSE) buf0[0] = len - 1; else put_unaligned_be16(len - 2, buf0); @@ -1881,7 +1886,7 @@ static int check_command(struct fsg_common *common, int cmnd_size, if (common->lun >= 0 && common->lun < common->nluns) { curlun = &common->luns[common->lun]; common->curlun = curlun; - if (common->cmnd[0] != SC_REQUEST_SENSE) { + if (common->cmnd[0] != REQUEST_SENSE) { curlun->sense_data = SS_NO_SENSE; curlun->sense_data_info = 0; curlun->info_valid = 0; @@ -1893,8 +1898,8 @@ static int check_command(struct fsg_common *common, int cmnd_size, /* INQUIRY and REQUEST SENSE commands are explicitly allowed * to use unsupported LUNs; all others may not. */ - if (common->cmnd[0] != SC_INQUIRY && - common->cmnd[0] != SC_REQUEST_SENSE) { + if (common->cmnd[0] != INQUIRY && + common->cmnd[0] != REQUEST_SENSE) { DBG(common, "unsupported LUN %d\n", common->lun); return -EINVAL; } @@ -1903,8 +1908,8 @@ static int check_command(struct fsg_common *common, int cmnd_size, /* If a unit attention condition exists, only INQUIRY and * REQUEST SENSE commands are allowed; anything else must fail. */ if (curlun && curlun->unit_attention_data != SS_NO_SENSE && - common->cmnd[0] != SC_INQUIRY && - common->cmnd[0] != SC_REQUEST_SENSE) { + common->cmnd[0] != INQUIRY && + common->cmnd[0] != REQUEST_SENSE) { curlun->sense_data = curlun->unit_attention_data; curlun->unit_attention_data = SS_NO_SENSE; return -EINVAL; @@ -1955,7 +1960,7 @@ static int do_scsi_command(struct fsg_common *common) down_read(&common->filesem); /* We're using the backing file */ switch (common->cmnd[0]) { - case SC_INQUIRY: + case INQUIRY: common->data_size_from_cmnd = common->cmnd[4]; reply = check_command(common, 6, DATA_DIR_TO_HOST, (1<<4), 0, @@ -1964,7 +1969,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_inquiry(common, bh); break; - case SC_MODE_SELECT_6: + case MODE_SELECT: common->data_size_from_cmnd = common->cmnd[4]; reply = check_command(common, 6, DATA_DIR_FROM_HOST, (1<<1) | (1<<4), 0, @@ -1973,7 +1978,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_mode_select(common, bh); break; - case SC_MODE_SELECT_10: + case MODE_SELECT_10: common->data_size_from_cmnd = get_unaligned_be16(&common->cmnd[7]); reply = check_command(common, 10, DATA_DIR_FROM_HOST, @@ -1983,7 +1988,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_mode_select(common, bh); break; - case SC_MODE_SENSE_6: + case MODE_SENSE: common->data_size_from_cmnd = common->cmnd[4]; reply = check_command(common, 6, DATA_DIR_TO_HOST, (1<<1) | (1<<2) | (1<<4), 0, @@ -1992,7 +1997,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_mode_sense(common, bh); break; - case SC_MODE_SENSE_10: + case MODE_SENSE_10: common->data_size_from_cmnd = get_unaligned_be16(&common->cmnd[7]); reply = check_command(common, 10, DATA_DIR_TO_HOST, @@ -2002,7 +2007,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_mode_sense(common, bh); break; - case SC_PREVENT_ALLOW_MEDIUM_REMOVAL: + case ALLOW_MEDIUM_REMOVAL: common->data_size_from_cmnd = 0; reply = check_command(common, 6, DATA_DIR_NONE, (1<<4), 0, @@ -2011,7 +2016,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_prevent_allow(common); break; - case SC_READ_6: + case READ_6: i = common->cmnd[4]; common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; reply = check_command(common, 6, DATA_DIR_TO_HOST, @@ -2021,7 +2026,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_read(common); break; - case SC_READ_10: + case READ_10: common->data_size_from_cmnd = get_unaligned_be16(&common->cmnd[7]) << 9; reply = check_command(common, 10, DATA_DIR_TO_HOST, @@ -2031,7 +2036,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_read(common); break; - case SC_READ_12: + case READ_12: common->data_size_from_cmnd = get_unaligned_be32(&common->cmnd[6]) << 9; reply = check_command(common, 12, DATA_DIR_TO_HOST, @@ -2041,7 +2046,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_read(common); break; - case SC_READ_CAPACITY: + case READ_CAPACITY: common->data_size_from_cmnd = 8; reply = check_command(common, 10, DATA_DIR_TO_HOST, (0xf<<2) | (1<<8), 1, @@ -2050,7 +2055,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_read_capacity(common, bh); break; - case SC_READ_HEADER: + case READ_HEADER: if (!common->curlun || !common->curlun->cdrom) goto unknown_cmnd; common->data_size_from_cmnd = @@ -2062,7 +2067,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_read_header(common, bh); break; - case SC_READ_TOC: + case READ_TOC: if (!common->curlun || !common->curlun->cdrom) goto unknown_cmnd; common->data_size_from_cmnd = @@ -2074,7 +2079,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_read_toc(common, bh); break; - case SC_READ_FORMAT_CAPACITIES: + case READ_FORMAT_CAPACITIES: common->data_size_from_cmnd = get_unaligned_be16(&common->cmnd[7]); reply = check_command(common, 10, DATA_DIR_TO_HOST, @@ -2084,7 +2089,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_read_format_capacities(common, bh); break; - case SC_REQUEST_SENSE: + case REQUEST_SENSE: common->data_size_from_cmnd = common->cmnd[4]; reply = check_command(common, 6, DATA_DIR_TO_HOST, (1<<4), 0, @@ -2093,7 +2098,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_request_sense(common, bh); break; - case SC_START_STOP_UNIT: + case START_STOP: common->data_size_from_cmnd = 0; reply = check_command(common, 6, DATA_DIR_NONE, (1<<1) | (1<<4), 0, @@ -2102,7 +2107,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_start_stop(common); break; - case SC_SYNCHRONIZE_CACHE: + case SYNCHRONIZE_CACHE: common->data_size_from_cmnd = 0; reply = check_command(common, 10, DATA_DIR_NONE, (0xf<<2) | (3<<7), 1, @@ -2111,7 +2116,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_synchronize_cache(common); break; - case SC_TEST_UNIT_READY: + case TEST_UNIT_READY: common->data_size_from_cmnd = 0; reply = check_command(common, 6, DATA_DIR_NONE, 0, 1, @@ -2120,7 +2125,7 @@ static int do_scsi_command(struct fsg_common *common) /* Although optional, this command is used by MS-Windows. We * support a minimal version: BytChk must be 0. */ - case SC_VERIFY: + case VERIFY: common->data_size_from_cmnd = 0; reply = check_command(common, 10, DATA_DIR_NONE, (1<<1) | (0xf<<2) | (3<<7), 1, @@ -2129,7 +2134,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_verify(common); break; - case SC_WRITE_6: + case WRITE_6: i = common->cmnd[4]; common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; reply = check_command(common, 6, DATA_DIR_FROM_HOST, @@ -2139,7 +2144,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_write(common); break; - case SC_WRITE_10: + case WRITE_10: common->data_size_from_cmnd = get_unaligned_be16(&common->cmnd[7]) << 9; reply = check_command(common, 10, DATA_DIR_FROM_HOST, @@ -2149,7 +2154,7 @@ static int do_scsi_command(struct fsg_common *common) reply = do_write(common); break; - case SC_WRITE_12: + case WRITE_12: common->data_size_from_cmnd = get_unaligned_be32(&common->cmnd[6]) << 9; reply = check_command(common, 12, DATA_DIR_FROM_HOST, @@ -2163,10 +2168,10 @@ static int do_scsi_command(struct fsg_common *common) * They don't mean much in this setting. It's left as an exercise * for anyone interested to implement RESERVE and RELEASE in terms * of Posix locks. */ - case SC_FORMAT_UNIT: - case SC_RELEASE: - case SC_RESERVE: - case SC_SEND_DIAGNOSTIC: + case FORMAT_UNIT: + case RELEASE: + case RESERVE: + case SEND_DIAGNOSTIC: /* Fall through */ default: @@ -2662,6 +2667,7 @@ static int fsg_main_thread(void *common_) /* Write permission is checked per LUN in store_*() functions. */ static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro); +static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua); static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file); @@ -2768,6 +2774,9 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, rc = device_create_file(&curlun->dev, &dev_attr_file); if (rc) goto error_luns; + rc = device_create_file(&curlun->dev, &dev_attr_nofua); + if (rc) + goto error_luns; if (lcfg->filename) { rc = fsg_lun_open(curlun, lcfg->filename); @@ -2911,6 +2920,7 @@ static void fsg_common_release(struct kref *ref) /* In error recovery common->nluns may be zero. */ for (; i; --i, ++lun) { + device_remove_file(&lun->dev, &dev_attr_nofua); device_remove_file(&lun->dev, &dev_attr_ro); device_remove_file(&lun->dev, &dev_attr_file); fsg_lun_close(lun); @@ -3069,8 +3079,10 @@ struct fsg_module_parameters { int ro[FSG_MAX_LUNS]; int removable[FSG_MAX_LUNS]; int cdrom[FSG_MAX_LUNS]; + int nofua[FSG_MAX_LUNS]; unsigned int file_count, ro_count, removable_count, cdrom_count; + unsigned int nofua_count; unsigned int luns; /* nluns */ int stall; /* can_stall */ }; @@ -3096,6 +3108,8 @@ struct fsg_module_parameters { "true to simulate removable media"); \ _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \ "true to simulate CD-ROM instead of disk"); \ + _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool, \ + "true to ignore SCSI WRITE(10,12) FUA bit"); \ _FSG_MODULE_PARAM(prefix, params, luns, uint, \ "number of LUNs"); \ _FSG_MODULE_PARAM(prefix, params, stall, bool, \ diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 685d768f336e..e403a534dd55 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c @@ -404,7 +404,7 @@ static void sourcesink_disable(struct usb_function *f) /*-------------------------------------------------------------------------*/ -static int __ref sourcesink_bind_config(struct usb_configuration *c) +static int __init sourcesink_bind_config(struct usb_configuration *c) { struct f_sourcesink *ss; int status; @@ -498,7 +498,6 @@ unknown: static struct usb_configuration sourcesink_driver = { .label = "source/sink", .strings = sourcesink_strings, - .bind = sourcesink_bind_config, .setup = sourcesink_setup, .bConfigurationValue = 3, .bmAttributes = USB_CONFIG_ATT_SELFPOWER, @@ -532,5 +531,5 @@ int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume) sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - return usb_add_config(cdev, &sourcesink_driver); + return usb_add_config(cdev, &sourcesink_driver, sourcesink_bind_config); } diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a857b7ac238c..d4fdf65fb925 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -89,6 +89,7 @@ * Required if "removable" is not set, names of * the files or block devices used for * backing storage + * serial=HHHH... Required serial number (string of hex chars) * ro=b[,b...] Default false, booleans for read-only access * removable Default false, boolean for removable media * luns=N Default N = number of filenames, number of @@ -108,12 +109,11 @@ * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID * release=0xRRRR Override the USB release number (bcdDevice) - * serial=HHHH... Override serial number (string of hex chars) * buflen=N Default N=16384, buffer size used (will be * rounded down to a multiple of * PAGE_CACHE_SIZE) * - * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro", + * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "serial", "ro", * "removable", "luns", "nofua", "stall", and "cdrom" options are available; * default values are used for everything else. * @@ -273,13 +273,10 @@ #define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_NAME "g_file_storage" -/* DRIVER_VERSION must be at least 6 characters long, as it is used - * to generate a fallback serial number. */ -#define DRIVER_VERSION "20 November 2008" +#define DRIVER_VERSION "1 September 2010" static char fsg_string_manufacturer[64]; static const char fsg_string_product[] = DRIVER_DESC; -static char fsg_string_serial[13]; static const char fsg_string_config[] = "Self-powered"; static const char fsg_string_interface[] = "Mass Storage"; @@ -305,6 +302,7 @@ MODULE_LICENSE("Dual BSD/GPL"); static struct { char *file[FSG_MAX_LUNS]; + char *serial; int ro[FSG_MAX_LUNS]; int nofua[FSG_MAX_LUNS]; unsigned int num_filenames; @@ -321,7 +319,6 @@ static struct { unsigned short vendor; unsigned short product; unsigned short release; - char *serial; unsigned int buflen; int transport_type; @@ -346,6 +343,9 @@ module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames, S_IRUGO); MODULE_PARM_DESC(file, "names of backing files or devices"); +module_param_named(serial, mod_data.serial, charp, S_IRUGO); +MODULE_PARM_DESC(serial, "USB serial number"); + module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); MODULE_PARM_DESC(ro, "true to force read-only"); @@ -365,9 +365,6 @@ MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO); MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk"); -module_param_named(serial, mod_data.serial, charp, S_IRUGO); -MODULE_PARM_DESC(serial, "USB serial number"); - /* In the non-TEST version, only the module parameters listed above * are available. */ #ifdef CONFIG_USB_FILE_STORAGE_TEST @@ -786,7 +783,7 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) { struct usb_request *req = fsg->ep0req; static u8 cbi_reset_cmnd[6] = { - SC_SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff}; + SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff}; /* Error in command transfer? */ if (req->status || req->length != req->actual || @@ -1138,7 +1135,7 @@ static int do_read(struct fsg_dev *fsg) /* Get the starting Logical Block Address and check that it's * not too big */ - if (fsg->cmnd[0] == SC_READ_6) + if (fsg->cmnd[0] == READ_6) lba = get_unaligned_be24(&fsg->cmnd[1]); else { lba = get_unaligned_be32(&fsg->cmnd[2]); @@ -1273,7 +1270,7 @@ static int do_write(struct fsg_dev *fsg) /* Get the starting Logical Block Address and check that it's * not too big */ - if (fsg->cmnd[0] == SC_WRITE_6) + if (fsg->cmnd[0] == WRITE_6) lba = get_unaligned_be24(&fsg->cmnd[1]); else { lba = get_unaligned_be32(&fsg->cmnd[2]); @@ -1581,7 +1578,7 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh) } memset(buf, 0, 8); - buf[0] = (mod_data.cdrom ? TYPE_CDROM : TYPE_DISK); + buf[0] = (mod_data.cdrom ? TYPE_ROM : TYPE_DISK); if (mod_data.removable) buf[1] = 0x80; buf[2] = 2; // ANSI SCSI level 2 @@ -1750,11 +1747,11 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) * The only variable value is the WriteProtect bit. We will fill in * the mode data length later. */ memset(buf, 0, 8); - if (mscmnd == SC_MODE_SENSE_6) { + if (mscmnd == MODE_SENSE) { buf[2] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA buf += 4; limit = 255; - } else { // SC_MODE_SENSE_10 + } else { // MODE_SENSE_10 buf[3] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA buf += 8; limit = 65535; // Should really be mod_data.buflen @@ -1794,7 +1791,7 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) } /* Store the mode data length */ - if (mscmnd == SC_MODE_SENSE_6) + if (mscmnd == MODE_SENSE) buf0[0] = len - 1; else put_unaligned_be16(len - 2, buf0); @@ -2319,7 +2316,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, /* Check the LUN */ if (fsg->lun >= 0 && fsg->lun < fsg->nluns) { fsg->curlun = curlun = &fsg->luns[fsg->lun]; - if (fsg->cmnd[0] != SC_REQUEST_SENSE) { + if (fsg->cmnd[0] != REQUEST_SENSE) { curlun->sense_data = SS_NO_SENSE; curlun->sense_data_info = 0; curlun->info_valid = 0; @@ -2330,8 +2327,8 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, /* INQUIRY and REQUEST SENSE commands are explicitly allowed * to use unsupported LUNs; all others may not. */ - if (fsg->cmnd[0] != SC_INQUIRY && - fsg->cmnd[0] != SC_REQUEST_SENSE) { + if (fsg->cmnd[0] != INQUIRY && + fsg->cmnd[0] != REQUEST_SENSE) { DBG(fsg, "unsupported LUN %d\n", fsg->lun); return -EINVAL; } @@ -2340,8 +2337,8 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, /* If a unit attention condition exists, only INQUIRY and * REQUEST SENSE commands are allowed; anything else must fail. */ if (curlun && curlun->unit_attention_data != SS_NO_SENSE && - fsg->cmnd[0] != SC_INQUIRY && - fsg->cmnd[0] != SC_REQUEST_SENSE) { + fsg->cmnd[0] != INQUIRY && + fsg->cmnd[0] != REQUEST_SENSE) { curlun->sense_data = curlun->unit_attention_data; curlun->unit_attention_data = SS_NO_SENSE; return -EINVAL; @@ -2391,7 +2388,7 @@ static int do_scsi_command(struct fsg_dev *fsg) down_read(&fsg->filesem); // We're using the backing file switch (fsg->cmnd[0]) { - case SC_INQUIRY: + case INQUIRY: fsg->data_size_from_cmnd = fsg->cmnd[4]; if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, (1<<4), 0, @@ -2399,7 +2396,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_inquiry(fsg, bh); break; - case SC_MODE_SELECT_6: + case MODE_SELECT: fsg->data_size_from_cmnd = fsg->cmnd[4]; if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, (1<<1) | (1<<4), 0, @@ -2407,7 +2404,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_mode_select(fsg, bh); break; - case SC_MODE_SELECT_10: + case MODE_SELECT_10: fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, (1<<1) | (3<<7), 0, @@ -2415,7 +2412,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_mode_select(fsg, bh); break; - case SC_MODE_SENSE_6: + case MODE_SENSE: fsg->data_size_from_cmnd = fsg->cmnd[4]; if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, (1<<1) | (1<<2) | (1<<4), 0, @@ -2423,7 +2420,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_mode_sense(fsg, bh); break; - case SC_MODE_SENSE_10: + case MODE_SENSE_10: fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, (1<<1) | (1<<2) | (3<<7), 0, @@ -2431,7 +2428,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_mode_sense(fsg, bh); break; - case SC_PREVENT_ALLOW_MEDIUM_REMOVAL: + case ALLOW_MEDIUM_REMOVAL: fsg->data_size_from_cmnd = 0; if ((reply = check_command(fsg, 6, DATA_DIR_NONE, (1<<4), 0, @@ -2439,7 +2436,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_prevent_allow(fsg); break; - case SC_READ_6: + case READ_6: i = fsg->cmnd[4]; fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, @@ -2448,7 +2445,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_read(fsg); break; - case SC_READ_10: + case READ_10: fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]) << 9; if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, @@ -2457,7 +2454,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_read(fsg); break; - case SC_READ_12: + case READ_12: fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]) << 9; if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, @@ -2466,7 +2463,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_read(fsg); break; - case SC_READ_CAPACITY: + case READ_CAPACITY: fsg->data_size_from_cmnd = 8; if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, (0xf<<2) | (1<<8), 1, @@ -2474,7 +2471,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_read_capacity(fsg, bh); break; - case SC_READ_HEADER: + case READ_HEADER: if (!mod_data.cdrom) goto unknown_cmnd; fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); @@ -2484,7 +2481,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_read_header(fsg, bh); break; - case SC_READ_TOC: + case READ_TOC: if (!mod_data.cdrom) goto unknown_cmnd; fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); @@ -2494,7 +2491,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_read_toc(fsg, bh); break; - case SC_READ_FORMAT_CAPACITIES: + case READ_FORMAT_CAPACITIES: fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, (3<<7), 1, @@ -2502,7 +2499,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_read_format_capacities(fsg, bh); break; - case SC_REQUEST_SENSE: + case REQUEST_SENSE: fsg->data_size_from_cmnd = fsg->cmnd[4]; if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, (1<<4), 0, @@ -2510,7 +2507,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_request_sense(fsg, bh); break; - case SC_START_STOP_UNIT: + case START_STOP: fsg->data_size_from_cmnd = 0; if ((reply = check_command(fsg, 6, DATA_DIR_NONE, (1<<1) | (1<<4), 0, @@ -2518,7 +2515,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_start_stop(fsg); break; - case SC_SYNCHRONIZE_CACHE: + case SYNCHRONIZE_CACHE: fsg->data_size_from_cmnd = 0; if ((reply = check_command(fsg, 10, DATA_DIR_NONE, (0xf<<2) | (3<<7), 1, @@ -2526,7 +2523,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_synchronize_cache(fsg); break; - case SC_TEST_UNIT_READY: + case TEST_UNIT_READY: fsg->data_size_from_cmnd = 0; reply = check_command(fsg, 6, DATA_DIR_NONE, 0, 1, @@ -2535,7 +2532,7 @@ static int do_scsi_command(struct fsg_dev *fsg) /* Although optional, this command is used by MS-Windows. We * support a minimal version: BytChk must be 0. */ - case SC_VERIFY: + case VERIFY: fsg->data_size_from_cmnd = 0; if ((reply = check_command(fsg, 10, DATA_DIR_NONE, (1<<1) | (0xf<<2) | (3<<7), 1, @@ -2543,7 +2540,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_verify(fsg); break; - case SC_WRITE_6: + case WRITE_6: i = fsg->cmnd[4]; fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, @@ -2552,7 +2549,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_write(fsg); break; - case SC_WRITE_10: + case WRITE_10: fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]) << 9; if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, @@ -2561,7 +2558,7 @@ static int do_scsi_command(struct fsg_dev *fsg) reply = do_write(fsg); break; - case SC_WRITE_12: + case WRITE_12: fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]) << 9; if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, @@ -2574,10 +2571,10 @@ static int do_scsi_command(struct fsg_dev *fsg) * They don't mean much in this setting. It's left as an exercise * for anyone interested to implement RESERVE and RELEASE in terms * of Posix locks. */ - case SC_FORMAT_UNIT: - case SC_RELEASE: - case SC_RESERVE: - case SC_SEND_DIAGNOSTIC: + case FORMAT_UNIT: + case RELEASE: + case RESERVE: + case SEND_DIAGNOSTIC: // Fall through default: @@ -3178,6 +3175,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) for (i = 0; i < fsg->nluns; ++i) { curlun = &fsg->luns[i]; if (curlun->registered) { + device_remove_file(&curlun->dev, &dev_attr_nofua); device_remove_file(&curlun->dev, &dev_attr_ro); device_remove_file(&curlun->dev, &dev_attr_file); fsg_lun_close(curlun); @@ -3213,7 +3211,6 @@ static int __init check_parameters(struct fsg_dev *fsg) { int prot; int gcnum; - int i; /* Store the default values */ mod_data.transport_type = USB_PR_BULK; @@ -3309,45 +3306,29 @@ static int __init check_parameters(struct fsg_dev *fsg) if ((*ch < '0' || *ch > '9') && (*ch < 'A' || *ch > 'F')) { /* not uppercase hex */ WARNING(fsg, - "Invalid serial string character: %c; " - "Failing back to default\n", + "Invalid serial string character: %c\n", *ch); - goto fill_serial; + goto no_serial; } } if (len > 126 || (mod_data.transport_type == USB_PR_BULK && len < 12) || (mod_data.transport_type != USB_PR_BULK && len > 12)) { - WARNING(fsg, - "Invalid serial string length; " - "Failing back to default\n"); - goto fill_serial; + WARNING(fsg, "Invalid serial string length!\n"); + goto no_serial; } fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial; } else { - WARNING(fsg, - "Userspace failed to provide serial number; " - "Failing back to default\n"); -fill_serial: - /* Serial number not specified or invalid, make our own. - * We just encode it from the driver version string, - * 12 characters to comply with both CB[I] and BBB spec. - * Warning : Two devices running the same kernel will have - * the same fallback serial number. */ - for (i = 0; i < 12; i += 2) { - unsigned char c = DRIVER_VERSION[i / 2]; - - if (!c) - break; - sprintf(&fsg_string_serial[i], "%02X", c); - } + WARNING(fsg, "No serial-number string provided!\n"); + no_serial: + device_desc.iSerialNumber = 0; } return 0; } -static int __ref fsg_bind(struct usb_gadget *gadget) +static int __init fsg_bind(struct usb_gadget *gadget) { struct fsg_dev *fsg = the_fsg; int rc; @@ -3607,7 +3588,6 @@ static struct usb_gadget_driver fsg_driver = { .speed = USB_SPEED_FULL, #endif .function = (char *) fsg_string_product, - .bind = fsg_bind, .unbind = fsg_unbind, .disconnect = fsg_disconnect, .setup = fsg_setup, @@ -3649,7 +3629,7 @@ static int __init fsg_init(void) if ((rc = fsg_alloc()) != 0) return rc; fsg = the_fsg; - if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) + if ((rc = usb_gadget_probe_driver(&fsg_driver, fsg_bind)) != 0) kref_put(&fsg->ref, fsg_release); return rc; } diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c index eafa6d2c5ed7..5bdbfe619853 100644 --- a/drivers/usb/gadget/fsl_mxc_udc.c +++ b/drivers/usb/gadget/fsl_mxc_udc.c @@ -22,6 +22,10 @@ static struct clk *mxc_ahb_clk; static struct clk *mxc_usb_clk; +/* workaround ENGcm09152 for i.MX35 */ +#define USBPHYCTRL_OTGBASE_OFFSET 0x608 +#define USBPHYCTRL_EVDO (1 << 23) + int fsl_udc_clk_init(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata; @@ -84,6 +88,17 @@ eenahb: void fsl_udc_clk_finalize(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; +#if defined(CONFIG_ARCH_MX35) + unsigned int v; + + /* workaround ENGcm09152 for i.MX35 */ + if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) { + v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR + + USBPHYCTRL_OTGBASE_OFFSET)); + writel(v | USBPHYCTRL_EVDO, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR + + USBPHYCTRL_OTGBASE_OFFSET)); + } +#endif /* ULPI transceivers don't need usbpll */ if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index a5ea2c1d8c93..792d5ef40137 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2302,9 +2302,10 @@ static irqreturn_t qe_udc_irq(int irq, void *_udc) } /*------------------------------------------------------------------------- - Gadget driver register and unregister. + Gadget driver probe and unregister. --------------------------------------------------------------------------*/ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { int retval; unsigned long flags = 0; @@ -2315,8 +2316,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) if (!driver || (driver->speed != USB_SPEED_FULL && driver->speed != USB_SPEED_HIGH) - || !driver->bind || !driver->disconnect - || !driver->setup) + || !bind || !driver->disconnect || !driver->setup) return -EINVAL; if (udc_controller->driver) @@ -2332,7 +2332,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed); spin_unlock_irqrestore(&udc_controller->lock, flags); - retval = driver->bind(&udc_controller->gadget); + retval = bind(&udc_controller->gadget); if (retval) { dev_err(udc_controller->dev, "bind to %s --> %d", driver->driver.name, retval); @@ -2353,7 +2353,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) udc_controller->gadget.name, driver->driver.name); return 0; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 08a9a62a39e3..c16b402a876b 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1765,7 +1765,8 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) * Hook to gadget drivers * Called by initialization code of gadget drivers *----------------------------------------------------------------*/ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { int retval = -ENODEV; unsigned long flags = 0; @@ -1775,8 +1776,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) if (!driver || (driver->speed != USB_SPEED_FULL && driver->speed != USB_SPEED_HIGH) - || !driver->bind || !driver->disconnect - || !driver->setup) + || !bind || !driver->disconnect || !driver->setup) return -EINVAL; if (udc_controller->driver) @@ -1792,7 +1792,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) spin_unlock_irqrestore(&udc_controller->lock, flags); /* bind udc driver to gadget driver */ - retval = driver->bind(&udc_controller->gadget); + retval = bind(&udc_controller->gadget); if (retval) { VDBG("bind to %s --> %d", driver->driver.name, retval); udc_controller->gadget.dev.driver = NULL; @@ -1814,7 +1814,7 @@ out: retval); return retval; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); /* Disconnect from gadget driver */ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index a9474f8d5325..af75e3620849 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -52,9 +52,8 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Michal Nazarewicz"); MODULE_LICENSE("GPL"); - -static unsigned short gfs_vendor_id = 0x0525; /* XXX NetChip */ -static unsigned short gfs_product_id = 0xa4ac; /* XXX */ +#define GFS_VENDOR_ID 0x1d6b /* Linux Foundation */ +#define GFS_PRODUCT_ID 0x0105 /* FunctionFS Gadget */ static struct usb_device_descriptor gfs_dev_desc = { .bLength = sizeof gfs_dev_desc, @@ -63,29 +62,16 @@ static struct usb_device_descriptor gfs_dev_desc = { .bcdUSB = cpu_to_le16(0x0200), .bDeviceClass = USB_CLASS_PER_INTERFACE, - /* Vendor and product id can be overridden by module parameters. */ - /* .idVendor = cpu_to_le16(gfs_vendor_id), */ - /* .idProduct = cpu_to_le16(gfs_product_id), */ - /* .bcdDevice = f(hardware) */ - /* .iManufacturer = DYNAMIC */ - /* .iProduct = DYNAMIC */ - /* NO SERIAL NUMBER */ - .bNumConfigurations = 1, + .idVendor = cpu_to_le16(GFS_VENDOR_ID), + .idProduct = cpu_to_le16(GFS_PRODUCT_ID), }; -#define GFS_MODULE_PARAM_DESC(name, field) \ - MODULE_PARM_DESC(name, "Value of the " #field " field of the device descriptor sent to the host. Takes effect only prior to the user-space driver registering to the FunctionFS.") - -module_param_named(usb_class, gfs_dev_desc.bDeviceClass, byte, 0644); -GFS_MODULE_PARAM_DESC(usb_class, bDeviceClass); -module_param_named(usb_subclass, gfs_dev_desc.bDeviceSubClass, byte, 0644); -GFS_MODULE_PARAM_DESC(usb_subclass, bDeviceSubClass); -module_param_named(usb_protocol, gfs_dev_desc.bDeviceProtocol, byte, 0644); -GFS_MODULE_PARAM_DESC(usb_protocol, bDeviceProtocol); -module_param_named(usb_vendor, gfs_vendor_id, ushort, 0644); -GFS_MODULE_PARAM_DESC(usb_vendor, idVendor); -module_param_named(usb_product, gfs_product_id, ushort, 0644); -GFS_MODULE_PARAM_DESC(usb_product, idProduct); +module_param_named(bDeviceClass, gfs_dev_desc.bDeviceClass, byte, 0644); +MODULE_PARM_DESC(bDeviceClass, "USB Device class"); +module_param_named(bDeviceSubClass, gfs_dev_desc.bDeviceSubClass, byte, 0644); +MODULE_PARM_DESC(bDeviceSubClass, "USB Device subclass"); +module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte, 0644); +MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol"); @@ -95,8 +81,10 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = { .bLength = sizeof(struct usb_otg_descriptor), .bDescriptorType = USB_DT_OTG, - /* REVISIT SRP-only hardware is possible, although - * it would not be called "OTG" ... */ + /* + * REVISIT SRP-only hardware is possible, although + * it would not be called "OTG" ... + */ .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, }, @@ -105,19 +93,7 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = { /* string IDs are assigned dynamically */ -enum { - GFS_STRING_MANUFACTURER_IDX, - GFS_STRING_PRODUCT_IDX, - GFS_STRING_FIRST_CONFIG_IDX, -}; - -static char gfs_manufacturer[50]; -static const char gfs_driver_desc[] = DRIVER_DESC; -static const char gfs_short_name[] = DRIVER_NAME; - static struct usb_string gfs_strings[] = { - [GFS_STRING_MANUFACTURER_IDX].s = gfs_manufacturer, - [GFS_STRING_PRODUCT_IDX].s = gfs_driver_desc, #ifdef CONFIG_USB_FUNCTIONFS_RNDIS { .s = "FunctionFS + RNDIS" }, #endif @@ -168,11 +144,11 @@ static int gfs_unbind(struct usb_composite_dev *cdev); static int gfs_do_config(struct usb_configuration *c); static struct usb_composite_driver gfs_driver = { - .name = gfs_short_name, + .name = DRIVER_NAME, .dev = &gfs_dev_desc, .strings = gfs_dev_strings, - .bind = gfs_bind, .unbind = gfs_unbind, + .iProduct = DRIVER_DESC, }; @@ -210,7 +186,7 @@ static int functionfs_ready_callback(struct ffs_data *ffs) return -EBUSY; gfs_ffs_data = ffs; - ret = usb_composite_register(&gfs_driver); + ret = usb_composite_probe(&gfs_driver, gfs_bind); if (unlikely(ret < 0)) clear_bit(0, &gfs_registered); return ret; @@ -245,20 +221,10 @@ static int gfs_bind(struct usb_composite_dev *cdev) if (unlikely(ret < 0)) goto error_quick; - gfs_dev_desc.idVendor = cpu_to_le16(gfs_vendor_id); - gfs_dev_desc.idProduct = cpu_to_le16(gfs_product_id); - - snprintf(gfs_manufacturer, sizeof gfs_manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - cdev->gadget->name); - ret = usb_string_ids_tab(cdev, gfs_strings); if (unlikely(ret < 0)) goto error; - gfs_dev_desc.iManufacturer = gfs_strings[GFS_STRING_MANUFACTURER_IDX].id; - gfs_dev_desc.iProduct = gfs_strings[GFS_STRING_PRODUCT_IDX].id; - ret = functionfs_bind(gfs_ffs_data, cdev); if (unlikely(ret < 0)) goto error; @@ -266,14 +232,12 @@ static int gfs_bind(struct usb_composite_dev *cdev) for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) { struct gfs_configuration *c = gfs_configurations + i; - ret = GFS_STRING_FIRST_CONFIG_IDX + i; - c->c.label = gfs_strings[ret].s; - c->c.iConfiguration = gfs_strings[ret].id; - c->c.bind = gfs_do_config; + c->c.label = gfs_strings[i].s; + c->c.iConfiguration = gfs_strings[i].id; c->c.bConfigurationValue = 1 + i; c->c.bmAttributes = USB_CONFIG_ATT_SELFPOWER; - ret = usb_add_config(cdev, &c->c); + ret = usb_add_config(cdev, &c->c, gfs_do_config); if (unlikely(ret < 0)) goto error_unbind; } @@ -293,13 +257,14 @@ static int gfs_unbind(struct usb_composite_dev *cdev) { ENTER(); - /* We may have been called in an error recovery frem + /* + * We may have been called in an error recovery from * composite_bind() after gfs_unbind() failure so we need to * check if gfs_ffs_data is not NULL since gfs_bind() handles * all error recovery itself. I'd rather we werent called * from composite on orror recovery, but what you're gonna - * do...? */ - + * do...? + */ if (gfs_ffs_data) { gether_cleanup(); functionfs_unbind(gfs_ffs_data); @@ -334,14 +299,16 @@ static int gfs_do_config(struct usb_configuration *c) if (unlikely(ret < 0)) return ret; - /* After previous do_configs there may be some invalid + /* + * After previous do_configs there may be some invalid * pointers in c->interface array. This happens every time * a user space function with fewer interfaces than a user * space function that was run before the new one is run. The * compasit's set_config() assumes that if there is no more * then MAX_CONFIG_INTERFACES interfaces in a configuration * then there is a NULL pointer after the last interface in - * c->interface array. We need to make sure this is true. */ + * c->interface array. We need to make sure this is true. + */ if (c->next_interface_id < ARRAY_SIZE(c->interface)) c->interface[c->next_interface_id] = NULL; @@ -350,10 +317,12 @@ static int gfs_do_config(struct usb_configuration *c) #ifdef CONFIG_USB_FUNCTIONFS_ETH + static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) { return can_support_ecm(c->cdev->gadget) ? ecm_bind_config(c, ethaddr) : geth_bind_config(c, ethaddr); } + #endif diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 1b413a5cc3f6..0ab7e141d494 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -1157,7 +1157,7 @@ fail: /* * Creates an output endpoint, and initializes output ports. */ -static int __ref gmidi_bind(struct usb_gadget *gadget) +static int __init gmidi_bind(struct usb_gadget *gadget) { struct gmidi_device *dev; struct usb_ep *in_ep, *out_ep; @@ -1292,7 +1292,6 @@ static void gmidi_resume(struct usb_gadget *gadget) static struct usb_gadget_driver gmidi_driver = { .speed = USB_SPEED_FULL, .function = (char *)longname, - .bind = gmidi_bind, .unbind = gmidi_unbind, .setup = gmidi_setup, @@ -1309,7 +1308,7 @@ static struct usb_gadget_driver gmidi_driver = { static int __init gmidi_init(void) { - return usb_gadget_register_driver(&gmidi_driver); + return usb_gadget_probe_driver(&gmidi_driver, gmidi_bind); } module_init(gmidi_init); diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 1088d08c7ed8..48a760220baf 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1343,14 +1343,15 @@ static struct goku_udc *the_controller; * disconnect is reported. then a host may connect again, or * the driver might get unbound. */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct goku_udc *dev = the_controller; int retval; if (!driver || driver->speed < USB_SPEED_FULL - || !driver->bind + || !bind || !driver->disconnect || !driver->setup) return -EINVAL; @@ -1363,7 +1364,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - retval = driver->bind(&dev->gadget); + retval = bind(&dev->gadget); if (retval) { DBG(dev, "bind to driver %s --> error %d\n", driver->driver.name, retval); @@ -1380,7 +1381,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) DBG(dev, "registered gadget driver '%s'\n", driver->driver.name); return 0; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); static void stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver) @@ -1744,7 +1745,8 @@ static void goku_remove(struct pci_dev *pdev) pci_resource_len (pdev, 0)); if (dev->enabled) pci_disable_device(pdev); - device_unregister(&dev->gadget.dev); + if (dev->registered) + device_unregister(&dev->gadget.dev); pci_set_drvdata(pdev, NULL); dev->regs = NULL; @@ -1774,7 +1776,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (!pdev->irq) { printk(KERN_ERR "Check PCI %s IRQ setup!\n", pci_name(pdev)); retval = -ENODEV; - goto done; + goto err; } /* alloc, and start init */ @@ -1782,7 +1784,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (dev == NULL){ pr_debug("enomem %s\n", pci_name(pdev)); retval = -ENOMEM; - goto done; + goto err; } spin_lock_init(&dev->lock); @@ -1800,7 +1802,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) retval = pci_enable_device(pdev); if (retval < 0) { DBG(dev, "can't enable, %d\n", retval); - goto done; + goto err; } dev->enabled = 1; @@ -1809,7 +1811,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (!request_mem_region(resource, len, driver_name)) { DBG(dev, "controller already in use\n"); retval = -EBUSY; - goto done; + goto err; } dev->got_region = 1; @@ -1817,7 +1819,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (base == NULL) { DBG(dev, "can't map memory\n"); retval = -EFAULT; - goto done; + goto err; } dev->regs = (struct goku_udc_regs __iomem *) base; @@ -1833,7 +1835,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) driver_name, dev) != 0) { DBG(dev, "request interrupt %d failed\n", pdev->irq); retval = -EBUSY; - goto done; + goto err; } dev->got_irq = 1; if (use_dma) @@ -1844,13 +1846,16 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev); #endif - /* done */ the_controller = dev; retval = device_register(&dev->gadget.dev); - if (retval == 0) - return 0; + if (retval) { + put_device(&dev->gadget.dev); + goto err; + } + dev->registered = 1; + return 0; -done: +err: if (dev) goku_remove (pdev); return retval; diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 735495bf8411..2523e54097bd 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -127,7 +127,7 @@ static struct usb_gadget_strings *dev_strings[] = { /****************************** Configurations ******************************/ -static int __ref do_config(struct usb_configuration *c) +static int __init do_config(struct usb_configuration *c) { struct hidg_func_node *e; int func = 0, status = 0; @@ -148,7 +148,6 @@ static int __ref do_config(struct usb_configuration *c) static struct usb_configuration config_driver = { .label = "HID Gadget", - .bind = do_config, .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, @@ -156,7 +155,7 @@ static struct usb_configuration config_driver = { /****************************** Gadget Bind ******************************/ -static int __ref hid_bind(struct usb_composite_dev *cdev) +static int __init hid_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct list_head *tmp; @@ -201,7 +200,7 @@ static int __ref hid_bind(struct usb_composite_dev *cdev) device_desc.iProduct = status; /* register our configuration */ - status = usb_add_config(cdev, &config_driver); + status = usb_add_config(cdev, &config_driver, do_config); if (status < 0) return status; @@ -256,7 +255,6 @@ static struct usb_composite_driver hidg_driver = { .name = "g_hid", .dev = &device_desc, .strings = dev_strings, - .bind = hid_bind, .unbind = __exit_p(hid_unbind), }; @@ -282,7 +280,7 @@ static int __init hidg_init(void) if (status < 0) return status; - status = usb_composite_register(&hidg_driver); + status = usb_composite_probe(&hidg_driver, hid_bind); if (status < 0) platform_driver_unregister(&hidg_plat_driver); diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index e743122fcd93..ed0266462c57 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -1319,14 +1319,15 @@ static struct imx_udc_struct controller = { * USB gadged driver functions ******************************************************************************* */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct imx_udc_struct *imx_usb = &controller; int retval; if (!driver || driver->speed < USB_SPEED_FULL - || !driver->bind + || !bind || !driver->disconnect || !driver->setup) return -EINVAL; @@ -1342,7 +1343,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) retval = device_add(&imx_usb->gadget.dev); if (retval) goto fail; - retval = driver->bind(&imx_usb->gadget); + retval = bind(&imx_usb->gadget); if (retval) { D_ERR(imx_usb->dev, "<%s> bind to driver %s --> error %d\n", __func__, driver->driver.name, retval); @@ -1362,7 +1363,7 @@ fail: imx_usb->gadget.dev.driver = NULL; return retval; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 3f1d771c8be5..d1d72d946b04 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1774,7 +1774,6 @@ static struct usb_gadget_driver gadgetfs_driver = { .speed = USB_SPEED_FULL, #endif .function = (char *) driver_desc, - .bind = gadgetfs_bind, .unbind = gadgetfs_unbind, .setup = gadgetfs_setup, .disconnect = gadgetfs_disconnect, @@ -1797,7 +1796,6 @@ static int gadgetfs_probe (struct usb_gadget *gadget) static struct usb_gadget_driver probe_driver = { .speed = USB_SPEED_HIGH, - .bind = gadgetfs_probe, .unbind = gadgetfs_nop, .setup = (void *)gadgetfs_nop, .disconnect = gadgetfs_nop, @@ -1907,7 +1905,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) /* triggers gadgetfs_bind(); then we can enumerate. */ spin_unlock_irq (&dev->lock); - value = usb_gadget_register_driver (&gadgetfs_driver); + value = usb_gadget_probe_driver(&gadgetfs_driver, gadgetfs_bind); if (value != 0) { kfree (dev->buf); dev->buf = NULL; @@ -2046,7 +2044,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) return -ESRCH; /* fake probe to determine $CHIP */ - (void) usb_gadget_register_driver (&probe_driver); + (void) usb_gadget_probe_driver(&probe_driver, gadgetfs_probe); if (!CHIP) return -ENODEV; diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index c2d2a201f84b..b8ec954c0692 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c @@ -19,7 +19,7 @@ /* #undef DEBUG */ -/* #undef VERBOSE */ +/* #undef VERBOSE_DEBUG */ #if defined(CONFIG_USB_LANGWELL_OTG) #define OTG_TRANSCEIVER @@ -77,141 +77,110 @@ langwell_ep0_desc = { /*-------------------------------------------------------------------------*/ /* debugging */ -#ifdef DEBUG -#define DBG(dev, fmt, args...) \ - pr_debug("%s %s: " fmt , driver_name, \ - pci_name(dev->pdev), ## args) -#else -#define DBG(dev, fmt, args...) \ - do { } while (0) -#endif /* DEBUG */ - - -#ifdef VERBOSE -#define VDBG DBG -#else -#define VDBG(dev, fmt, args...) \ - do { } while (0) -#endif /* VERBOSE */ - - -#define ERROR(dev, fmt, args...) \ - pr_err("%s %s: " fmt , driver_name, \ - pci_name(dev->pdev), ## args) - -#define WARNING(dev, fmt, args...) \ - pr_warning("%s %s: " fmt , driver_name, \ - pci_name(dev->pdev), ## args) - -#define INFO(dev, fmt, args...) \ - pr_info("%s %s: " fmt , driver_name, \ - pci_name(dev->pdev), ## args) - - -#ifdef VERBOSE +#ifdef VERBOSE_DEBUG static inline void print_all_registers(struct langwell_udc *dev) { int i; /* Capability Registers */ - printk(KERN_DEBUG "Capability Registers (offset: " - "0x%04x, length: 0x%08x)\n", - CAP_REG_OFFSET, - (u32)sizeof(struct langwell_cap_regs)); - printk(KERN_DEBUG "caplength=0x%02x\n", + dev_dbg(&dev->pdev->dev, + "Capability Registers (offset: 0x%04x, length: 0x%08x)\n", + CAP_REG_OFFSET, (u32)sizeof(struct langwell_cap_regs)); + dev_dbg(&dev->pdev->dev, "caplength=0x%02x\n", readb(&dev->cap_regs->caplength)); - printk(KERN_DEBUG "hciversion=0x%04x\n", + dev_dbg(&dev->pdev->dev, "hciversion=0x%04x\n", readw(&dev->cap_regs->hciversion)); - printk(KERN_DEBUG "hcsparams=0x%08x\n", + dev_dbg(&dev->pdev->dev, "hcsparams=0x%08x\n", readl(&dev->cap_regs->hcsparams)); - printk(KERN_DEBUG "hccparams=0x%08x\n", + dev_dbg(&dev->pdev->dev, "hccparams=0x%08x\n", readl(&dev->cap_regs->hccparams)); - printk(KERN_DEBUG "dciversion=0x%04x\n", + dev_dbg(&dev->pdev->dev, "dciversion=0x%04x\n", readw(&dev->cap_regs->dciversion)); - printk(KERN_DEBUG "dccparams=0x%08x\n", + dev_dbg(&dev->pdev->dev, "dccparams=0x%08x\n", readl(&dev->cap_regs->dccparams)); /* Operational Registers */ - printk(KERN_DEBUG "Operational Registers (offset: " - "0x%04x, length: 0x%08x)\n", - OP_REG_OFFSET, - (u32)sizeof(struct langwell_op_regs)); - printk(KERN_DEBUG "extsts=0x%08x\n", + dev_dbg(&dev->pdev->dev, + "Operational Registers (offset: 0x%04x, length: 0x%08x)\n", + OP_REG_OFFSET, (u32)sizeof(struct langwell_op_regs)); + dev_dbg(&dev->pdev->dev, "extsts=0x%08x\n", readl(&dev->op_regs->extsts)); - printk(KERN_DEBUG "extintr=0x%08x\n", + dev_dbg(&dev->pdev->dev, "extintr=0x%08x\n", readl(&dev->op_regs->extintr)); - printk(KERN_DEBUG "usbcmd=0x%08x\n", + dev_dbg(&dev->pdev->dev, "usbcmd=0x%08x\n", readl(&dev->op_regs->usbcmd)); - printk(KERN_DEBUG "usbsts=0x%08x\n", + dev_dbg(&dev->pdev->dev, "usbsts=0x%08x\n", readl(&dev->op_regs->usbsts)); - printk(KERN_DEBUG "usbintr=0x%08x\n", + dev_dbg(&dev->pdev->dev, "usbintr=0x%08x\n", readl(&dev->op_regs->usbintr)); - printk(KERN_DEBUG "frindex=0x%08x\n", + dev_dbg(&dev->pdev->dev, "frindex=0x%08x\n", readl(&dev->op_regs->frindex)); - printk(KERN_DEBUG "ctrldssegment=0x%08x\n", + dev_dbg(&dev->pdev->dev, "ctrldssegment=0x%08x\n", readl(&dev->op_regs->ctrldssegment)); - printk(KERN_DEBUG "deviceaddr=0x%08x\n", + dev_dbg(&dev->pdev->dev, "deviceaddr=0x%08x\n", readl(&dev->op_regs->deviceaddr)); - printk(KERN_DEBUG "endpointlistaddr=0x%08x\n", + dev_dbg(&dev->pdev->dev, "endpointlistaddr=0x%08x\n", readl(&dev->op_regs->endpointlistaddr)); - printk(KERN_DEBUG "ttctrl=0x%08x\n", + dev_dbg(&dev->pdev->dev, "ttctrl=0x%08x\n", readl(&dev->op_regs->ttctrl)); - printk(KERN_DEBUG "burstsize=0x%08x\n", + dev_dbg(&dev->pdev->dev, "burstsize=0x%08x\n", readl(&dev->op_regs->burstsize)); - printk(KERN_DEBUG "txfilltuning=0x%08x\n", + dev_dbg(&dev->pdev->dev, "txfilltuning=0x%08x\n", readl(&dev->op_regs->txfilltuning)); - printk(KERN_DEBUG "txttfilltuning=0x%08x\n", + dev_dbg(&dev->pdev->dev, "txttfilltuning=0x%08x\n", readl(&dev->op_regs->txttfilltuning)); - printk(KERN_DEBUG "ic_usb=0x%08x\n", + dev_dbg(&dev->pdev->dev, "ic_usb=0x%08x\n", readl(&dev->op_regs->ic_usb)); - printk(KERN_DEBUG "ulpi_viewport=0x%08x\n", + dev_dbg(&dev->pdev->dev, "ulpi_viewport=0x%08x\n", readl(&dev->op_regs->ulpi_viewport)); - printk(KERN_DEBUG "configflag=0x%08x\n", + dev_dbg(&dev->pdev->dev, "configflag=0x%08x\n", readl(&dev->op_regs->configflag)); - printk(KERN_DEBUG "portsc1=0x%08x\n", + dev_dbg(&dev->pdev->dev, "portsc1=0x%08x\n", readl(&dev->op_regs->portsc1)); - printk(KERN_DEBUG "devlc=0x%08x\n", + dev_dbg(&dev->pdev->dev, "devlc=0x%08x\n", readl(&dev->op_regs->devlc)); - printk(KERN_DEBUG "otgsc=0x%08x\n", + dev_dbg(&dev->pdev->dev, "otgsc=0x%08x\n", readl(&dev->op_regs->otgsc)); - printk(KERN_DEBUG "usbmode=0x%08x\n", + dev_dbg(&dev->pdev->dev, "usbmode=0x%08x\n", readl(&dev->op_regs->usbmode)); - printk(KERN_DEBUG "endptnak=0x%08x\n", + dev_dbg(&dev->pdev->dev, "endptnak=0x%08x\n", readl(&dev->op_regs->endptnak)); - printk(KERN_DEBUG "endptnaken=0x%08x\n", + dev_dbg(&dev->pdev->dev, "endptnaken=0x%08x\n", readl(&dev->op_regs->endptnaken)); - printk(KERN_DEBUG "endptsetupstat=0x%08x\n", + dev_dbg(&dev->pdev->dev, "endptsetupstat=0x%08x\n", readl(&dev->op_regs->endptsetupstat)); - printk(KERN_DEBUG "endptprime=0x%08x\n", + dev_dbg(&dev->pdev->dev, "endptprime=0x%08x\n", readl(&dev->op_regs->endptprime)); - printk(KERN_DEBUG "endptflush=0x%08x\n", + dev_dbg(&dev->pdev->dev, "endptflush=0x%08x\n", readl(&dev->op_regs->endptflush)); - printk(KERN_DEBUG "endptstat=0x%08x\n", + dev_dbg(&dev->pdev->dev, "endptstat=0x%08x\n", readl(&dev->op_regs->endptstat)); - printk(KERN_DEBUG "endptcomplete=0x%08x\n", + dev_dbg(&dev->pdev->dev, "endptcomplete=0x%08x\n", readl(&dev->op_regs->endptcomplete)); for (i = 0; i < dev->ep_max / 2; i++) { - printk(KERN_DEBUG "endptctrl[%d]=0x%08x\n", + dev_dbg(&dev->pdev->dev, "endptctrl[%d]=0x%08x\n", i, readl(&dev->op_regs->endptctrl[i])); } } -#endif /* VERBOSE */ +#else + +#define print_all_registers(dev) do { } while (0) + +#endif /* VERBOSE_DEBUG */ /*-------------------------------------------------------------------------*/ -#define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") +#define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \ + USB_DIR_IN) : (usb_endpoint_dir_in((ep)->desc))) -#define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \ - USB_DIR_IN) : ((ep)->desc->bEndpointAddress \ - & USB_DIR_IN) == USB_DIR_IN) +#define DIR_STRING(ep) (is_in(ep) ? "in" : "out") -#ifdef DEBUG -static char *type_string(u8 bmAttributes) +static char *type_string(const struct usb_endpoint_descriptor *desc) { - switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) { + switch (usb_endpoint_type(desc)) { case USB_ENDPOINT_XFER_BULK: return "bulk"; case USB_ENDPOINT_XFER_ISOC: @@ -222,7 +191,6 @@ static char *type_string(u8 bmAttributes) return "control"; } -#endif /* configure endpoint control registers */ @@ -233,7 +201,7 @@ static void ep_reset(struct langwell_ep *ep, unsigned char ep_num, u32 endptctrl; dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); endptctrl = readl(&dev->op_regs->endptctrl[ep_num]); if (is_in) { /* TX */ @@ -250,7 +218,7 @@ static void ep_reset(struct langwell_ep *ep, unsigned char ep_num, writel(endptctrl, &dev->op_regs->endptctrl[ep_num]); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -260,7 +228,7 @@ static void ep0_reset(struct langwell_udc *dev) struct langwell_ep *ep; int i; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); /* ep0 in and out */ for (i = 0; i < 2; i++) { @@ -274,17 +242,18 @@ static void ep0_reset(struct langwell_udc *dev) ep->dqh->dqh_ios = 1; ep->dqh->dqh_mpl = EP0_MAX_PKT_SIZE; - /* FIXME: enable ep0-in HW zero length termination select */ + /* enable ep0-in HW zero length termination select */ if (is_in(ep)) ep->dqh->dqh_zlt = 0; ep->dqh->dqh_mult = 0; + ep->dqh->dtd_next = DTD_TERM; + /* configure ep0 control registers */ ep_reset(&dev->ep[0], 0, i, USB_ENDPOINT_XFER_CONTROL); } - VDBG(dev, "<--- %s()\n", __func__); - return; + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -300,12 +269,12 @@ static int langwell_ep_enable(struct usb_ep *_ep, struct langwell_ep *ep; u16 max = 0; unsigned long flags; - int retval = 0; + int i, retval = 0; unsigned char zlt, ios = 0, mult = 0; ep = container_of(_ep, struct langwell_ep, ep); dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (!_ep || !desc || ep->desc || desc->bDescriptorType != USB_DT_ENDPOINT) @@ -326,7 +295,7 @@ static int langwell_ep_enable(struct usb_ep *_ep, * sanity check type, direction, address, and then * initialize the endpoint capabilities fields in dQH */ - switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + switch (usb_endpoint_type(desc)) { case USB_ENDPOINT_XFER_CONTROL: ios = 1; break; @@ -386,33 +355,36 @@ static int langwell_ep_enable(struct usb_ep *_ep, spin_lock_irqsave(&dev->lock, flags); - /* configure endpoint capabilities in dQH */ - ep->dqh->dqh_ios = ios; - ep->dqh->dqh_mpl = cpu_to_le16(max); - ep->dqh->dqh_zlt = zlt; - ep->dqh->dqh_mult = mult; - ep->ep.maxpacket = max; ep->desc = desc; ep->stopped = 0; - ep->ep_num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep->ep_num = usb_endpoint_num(desc); /* ep_type */ - ep->ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + ep->ep_type = usb_endpoint_type(desc); /* configure endpoint control registers */ ep_reset(ep, ep->ep_num, is_in(ep), ep->ep_type); - DBG(dev, "enabled %s (ep%d%s-%s), max %04x\n", + /* configure endpoint capabilities in dQH */ + i = ep->ep_num * 2 + is_in(ep); + ep->dqh = &dev->ep_dqh[i]; + ep->dqh->dqh_ios = ios; + ep->dqh->dqh_mpl = cpu_to_le16(max); + ep->dqh->dqh_zlt = zlt; + ep->dqh->dqh_mult = mult; + ep->dqh->dtd_next = DTD_TERM; + + dev_dbg(&dev->pdev->dev, "enabled %s (ep%d%s-%s), max %04x\n", _ep->name, ep->ep_num, - DIR_STRING(desc->bEndpointAddress), - type_string(desc->bmAttributes), + DIR_STRING(ep), + type_string(desc), max); spin_unlock_irqrestore(&dev->lock, flags); done: - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return retval; } @@ -428,7 +400,7 @@ static void done(struct langwell_ep *ep, struct langwell_request *req, struct langwell_dtd *curr_dtd, *next_dtd; int i; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); /* remove the req from ep->queue */ list_del_init(&req->queue); @@ -448,7 +420,8 @@ static void done(struct langwell_ep *ep, struct langwell_request *req, } if (req->mapped) { - dma_unmap_single(&dev->pdev->dev, req->req.dma, req->req.length, + dma_unmap_single(&dev->pdev->dev, + req->req.dma, req->req.length, is_in(ep) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); req->req.dma = DMA_ADDR_INVALID; req->mapped = 0; @@ -458,9 +431,10 @@ static void done(struct langwell_ep *ep, struct langwell_request *req, is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); if (status != -ESHUTDOWN) - DBG(dev, "complete %s, req %p, stat %d, len %u/%u\n", - ep->ep.name, &req->req, status, - req->req.actual, req->req.length); + dev_dbg(&dev->pdev->dev, + "complete %s, req %p, stat %d, len %u/%u\n", + ep->ep.name, &req->req, status, + req->req.actual, req->req.length); /* don't modify queue heads during completion callback */ ep->stopped = 1; @@ -473,7 +447,7 @@ static void done(struct langwell_ep *ep, struct langwell_request *req, spin_lock(&dev->lock); ep->stopped = stopped; - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -511,7 +485,7 @@ static int langwell_ep_disable(struct usb_ep *_ep) ep = container_of(_ep, struct langwell_ep, ep); dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (!_ep || !ep->desc) return -EINVAL; @@ -535,8 +509,8 @@ static int langwell_ep_disable(struct usb_ep *_ep) spin_unlock_irqrestore(&dev->lock, flags); - DBG(dev, "disabled %s\n", _ep->name); - VDBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "disabled %s\n", _ep->name); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -555,7 +529,7 @@ static struct usb_request *langwell_alloc_request(struct usb_ep *_ep, ep = container_of(_ep, struct langwell_ep, ep); dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); req = kzalloc(sizeof(*req), gfp_flags); if (!req) @@ -564,8 +538,8 @@ static struct usb_request *langwell_alloc_request(struct usb_ep *_ep, req->req.dma = DMA_ADDR_INVALID; INIT_LIST_HEAD(&req->queue); - VDBG(dev, "alloc request for %s\n", _ep->name); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "alloc request for %s\n", _ep->name); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return &req->req; } @@ -580,7 +554,7 @@ static void langwell_free_request(struct usb_ep *_ep, ep = container_of(_ep, struct langwell_ep, ep); dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (!_ep || !_req) return; @@ -591,8 +565,8 @@ static void langwell_free_request(struct usb_ep *_ep, if (_req) kfree(req); - VDBG(dev, "free request for %s\n", _ep->name); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "free request for %s\n", _ep->name); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -608,23 +582,24 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req) struct langwell_udc *dev; dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); i = ep->ep_num * 2 + is_in(ep); dqh = &dev->ep_dqh[i]; if (ep->ep_num) - VDBG(dev, "%s\n", ep->name); + dev_vdbg(&dev->pdev->dev, "%s\n", ep->name); else /* ep0 */ - VDBG(dev, "%s-%s\n", ep->name, is_in(ep) ? "in" : "out"); + dev_vdbg(&dev->pdev->dev, "%s-%s\n", ep->name, DIR_STRING(ep)); - VDBG(dev, "ep_dqh[%d] addr: 0x%08x\n", i, (u32)&(dev->ep_dqh[i])); + dev_vdbg(&dev->pdev->dev, "ep_dqh[%d] addr: 0x%08x\n", + i, (u32)&(dev->ep_dqh[i])); bit_mask = is_in(ep) ? (1 << (ep->ep_num + 16)) : (1 << (ep->ep_num)); - VDBG(dev, "bit_mask = 0x%08x\n", bit_mask); + dev_vdbg(&dev->pdev->dev, "bit_mask = 0x%08x\n", bit_mask); /* check if the pipe is empty */ if (!(list_empty(&ep->queue))) { @@ -665,14 +640,17 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req) /* clear active and halt bit */ dtd_status = (u8) ~(DTD_STS_ACTIVE | DTD_STS_HALTED); dqh->dtd_status &= dtd_status; - VDBG(dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status); + dev_vdbg(&dev->pdev->dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status); + + /* ensure that updates to the dQH will occure before priming */ + wmb(); /* write 1 to endptprime register to PRIME endpoint */ bit_mask = is_in(ep) ? (1 << (ep->ep_num + 16)) : (1 << ep->ep_num); - VDBG(dev, "endprime bit_mask = 0x%08x\n", bit_mask); + dev_vdbg(&dev->pdev->dev, "endprime bit_mask = 0x%08x\n", bit_mask); writel(bit_mask, &dev->op_regs->endptprime); out: - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -687,7 +665,7 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req, int i; dev = req->ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); /* the maximum transfer length, up to 16k bytes */ *length = min(req->req.length - req->req.actual, @@ -708,7 +686,7 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req, /* fill in total bytes with transfer size */ dtd->dtd_total = cpu_to_le16(*length); - VDBG(dev, "dtd->dtd_total = %d\n", dtd->dtd_total); + dev_vdbg(&dev->pdev->dev, "dtd->dtd_total = %d\n", dtd->dtd_total); /* set is_last flag if req->req.zero is set or not */ if (req->req.zero) { @@ -722,7 +700,7 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req, *is_last = 0; if (*is_last == 0) - VDBG(dev, "multi-dtd request!\n"); + dev_vdbg(&dev->pdev->dev, "multi-dtd request!\n"); /* set interrupt on complete bit for the last dTD */ if (*is_last && !req->req.no_interrupt) @@ -733,10 +711,12 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req, /* set the active bit of status field to 1 */ dtd->dtd_status = DTD_STS_ACTIVE; - VDBG(dev, "dtd->dtd_status = 0x%02x\n", dtd->dtd_status); + dev_vdbg(&dev->pdev->dev, "dtd->dtd_status = 0x%02x\n", + dtd->dtd_status); - VDBG(dev, "length = %d, dma addr= 0x%08x\n", *length, (int)*dma); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "length = %d, dma addr= 0x%08x\n", + *length, (int)*dma); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return dtd; } @@ -751,7 +731,7 @@ static int req_to_dtd(struct langwell_request *req) dma_addr_t dma; dev = req->ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); do { dtd = build_dtd(req, &count, &dma, &is_last); if (dtd == NULL) @@ -773,7 +753,7 @@ static int req_to_dtd(struct langwell_request *req) req->tail = dtd; - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -803,9 +783,9 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req, dev = ep->dev; req->ep = ep; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); - if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { + if (usb_endpoint_xfer_isoc(ep->desc)) { if (req->req.length > ep->ep.maxpacket) return -EMSGSIZE; is_iso = 1; @@ -818,7 +798,7 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req, if (_req->dma == DMA_ADDR_INVALID) { /* WORKAROUND: WARN_ON(size == 0) */ if (_req->length == 0) { - VDBG(dev, "req->length: 0->1\n"); + dev_vdbg(&dev->pdev->dev, "req->length: 0->1\n"); zlflag = 1; _req->length++; } @@ -827,24 +807,25 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req, _req->buf, _req->length, is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); if (zlflag && (_req->length == 1)) { - VDBG(dev, "req->length: 1->0\n"); + dev_vdbg(&dev->pdev->dev, "req->length: 1->0\n"); zlflag = 0; _req->length = 0; } req->mapped = 1; - VDBG(dev, "req->mapped = 1\n"); + dev_vdbg(&dev->pdev->dev, "req->mapped = 1\n"); } else { dma_sync_single_for_device(&dev->pdev->dev, _req->dma, _req->length, is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); req->mapped = 0; - VDBG(dev, "req->mapped = 0\n"); + dev_vdbg(&dev->pdev->dev, "req->mapped = 0\n"); } - DBG(dev, "%s queue req %p, len %u, buf %p, dma 0x%08llx\n", - _ep->name, - _req, _req->length, _req->buf, (unsigned long long)_req->dma); + dev_dbg(&dev->pdev->dev, + "%s queue req %p, len %u, buf %p, dma 0x%08x\n", + _ep->name, + _req, _req->length, _req->buf, (int)_req->dma); _req->status = -EINPROGRESS; _req->actual = 0; @@ -866,12 +847,12 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req, if (likely(req != NULL)) { list_add_tail(&req->queue, &ep->queue); - VDBG(dev, "list_add_tail() \n"); + dev_vdbg(&dev->pdev->dev, "list_add_tail()\n"); } spin_unlock_irqrestore(&dev->lock, flags); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -888,7 +869,7 @@ static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) ep = container_of(_ep, struct langwell_ep, ep); dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (!_ep || !ep->desc || !_req) return -EINVAL; @@ -924,7 +905,7 @@ static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) /* queue head may be partially complete. */ if (ep->queue.next == &req->queue) { - DBG(dev, "unlink (%s) dma\n", _ep->name); + dev_dbg(&dev->pdev->dev, "unlink (%s) dma\n", _ep->name); _req->status = -ECONNRESET; langwell_ep_fifo_flush(&ep->ep); @@ -963,7 +944,7 @@ done: ep->stopped = stopped; spin_unlock_irqrestore(&dev->lock, flags); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return retval; } @@ -976,7 +957,7 @@ static void ep_set_halt(struct langwell_ep *ep, int value) u32 endptctrl = 0; int ep_num; struct langwell_udc *dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); ep_num = ep->ep_num; endptctrl = readl(&dev->op_regs->endptctrl[ep_num]); @@ -1001,7 +982,7 @@ static void ep_set_halt(struct langwell_ep *ep, int value) writel(endptctrl, &dev->op_regs->endptctrl[ep_num]); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -1016,7 +997,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value) ep = container_of(_ep, struct langwell_ep, ep); dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (!_ep || !ep->desc) return -EINVAL; @@ -1024,8 +1005,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value) if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) return -ESHUTDOWN; - if (ep->desc && (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_ISOC) + if (usb_endpoint_xfer_isoc(ep->desc)) return -EOPNOTSUPP; spin_lock_irqsave(&dev->lock, flags); @@ -1036,7 +1016,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value) */ if (!list_empty(&ep->queue) && is_in(ep) && value) { /* IN endpoint FIFO holds bytes */ - DBG(dev, "%s FIFO holds bytes\n", _ep->name); + dev_dbg(&dev->pdev->dev, "%s FIFO holds bytes\n", _ep->name); retval = -EAGAIN; goto done; } @@ -1050,8 +1030,9 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value) } done: spin_unlock_irqrestore(&dev->lock, flags); - DBG(dev, "%s %s halt\n", _ep->name, value ? "set" : "clear"); - VDBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "%s %s halt\n", + _ep->name, value ? "set" : "clear"); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return retval; } @@ -1065,12 +1046,12 @@ static int langwell_ep_set_wedge(struct usb_ep *_ep) ep = container_of(_ep, struct langwell_ep, ep); dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (!_ep || !ep->desc) return -EINVAL; - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return usb_ep_set_halt(_ep); } @@ -1086,15 +1067,16 @@ static void langwell_ep_fifo_flush(struct usb_ep *_ep) ep = container_of(_ep, struct langwell_ep, ep); dev = ep->dev; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (!_ep || !ep->desc) { - VDBG(dev, "ep or ep->desc is NULL\n"); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "ep or ep->desc is NULL\n"); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return; } - VDBG(dev, "%s-%s fifo flush\n", _ep->name, is_in(ep) ? "in" : "out"); + dev_vdbg(&dev->pdev->dev, "%s-%s fifo flush\n", + _ep->name, DIR_STRING(ep)); /* flush endpoint buffer */ if (ep->ep_num == 0) @@ -1110,14 +1092,14 @@ static void langwell_ep_fifo_flush(struct usb_ep *_ep) writel(flush_bit, &dev->op_regs->endptflush); while (readl(&dev->op_regs->endptflush)) { if (time_after(jiffies, timeout)) { - ERROR(dev, "ep flush timeout\n"); + dev_err(&dev->pdev->dev, "ep flush timeout\n"); goto done; } cpu_relax(); } } while (readl(&dev->op_regs->endptstat) & flush_bit); done: - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -1167,31 +1149,59 @@ static int langwell_get_frame(struct usb_gadget *_gadget) return -ENODEV; dev = container_of(_gadget, struct langwell_udc, gadget); - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); retval = readl(&dev->op_regs->frindex) & FRINDEX_MASK; - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return retval; } +/* enter or exit PHY low power state */ +static void langwell_phy_low_power(struct langwell_udc *dev, bool flag) +{ + u32 devlc; + u8 devlc_byte2; + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); + + devlc = readl(&dev->op_regs->devlc); + dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc); + + if (flag) + devlc |= LPM_PHCD; + else + devlc &= ~LPM_PHCD; + + /* FIXME: workaround for Langwell A1/A2/A3 sighting */ + devlc_byte2 = (devlc >> 16) & 0xff; + writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2); + + devlc = readl(&dev->op_regs->devlc); + dev_vdbg(&dev->pdev->dev, + "%s PHY low power suspend, devlc = 0x%08x\n", + flag ? "enter" : "exit", devlc); +} + + /* tries to wake up the host connected to this gadget */ static int langwell_wakeup(struct usb_gadget *_gadget) { struct langwell_udc *dev; - u32 portsc1, devlc; - unsigned long flags; + u32 portsc1; + unsigned long flags; if (!_gadget) return 0; dev = container_of(_gadget, struct langwell_udc, gadget); - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); - /* Remote Wakeup feature not enabled by host */ - if (!dev->remote_wakeup) + /* remote wakeup feature not enabled by host */ + if (!dev->remote_wakeup) { + dev_info(&dev->pdev->dev, "remote wakeup is disabled\n"); return -ENOTSUPP; + } spin_lock_irqsave(&dev->lock, flags); @@ -1201,27 +1211,23 @@ static int langwell_wakeup(struct usb_gadget *_gadget) return 0; } - /* LPM L1 to L0, remote wakeup */ - if (dev->lpm && dev->lpm_state == LPM_L1) { - portsc1 |= PORTS_SLP; - writel(portsc1, &dev->op_regs->portsc1); - } - - /* force port resume */ - if (dev->usb_state == USB_STATE_SUSPENDED) { - portsc1 |= PORTS_FPR; - writel(portsc1, &dev->op_regs->portsc1); - } + /* LPM L1 to L0 or legacy remote wakeup */ + if (dev->lpm && dev->lpm_state == LPM_L1) + dev_info(&dev->pdev->dev, "LPM L1 to L0 remote wakeup\n"); + else + dev_info(&dev->pdev->dev, "device remote wakeup\n"); /* exit PHY low power suspend */ - devlc = readl(&dev->op_regs->devlc); - VDBG(dev, "devlc = 0x%08x\n", devlc); - devlc &= ~LPM_PHCD; - writel(devlc, &dev->op_regs->devlc); + if (dev->pdev->device != 0x0829) + langwell_phy_low_power(dev, 0); + + /* force port resume */ + portsc1 |= PORTS_FPR; + writel(portsc1, &dev->op_regs->portsc1); spin_unlock_irqrestore(&dev->lock, flags); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -1231,16 +1237,17 @@ static int langwell_vbus_session(struct usb_gadget *_gadget, int is_active) { struct langwell_udc *dev; unsigned long flags; - u32 usbcmd; + u32 usbcmd; if (!_gadget) return -ENODEV; dev = container_of(_gadget, struct langwell_udc, gadget); - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); spin_lock_irqsave(&dev->lock, flags); - VDBG(dev, "VBUS status: %s\n", is_active ? "on" : "off"); + dev_vdbg(&dev->pdev->dev, "VBUS status: %s\n", + is_active ? "on" : "off"); dev->vbus_active = (is_active != 0); if (dev->driver && dev->softconnected && dev->vbus_active) { @@ -1255,7 +1262,7 @@ static int langwell_vbus_session(struct usb_gadget *_gadget, int is_active) spin_unlock_irqrestore(&dev->lock, flags); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -1269,15 +1276,15 @@ static int langwell_vbus_draw(struct usb_gadget *_gadget, unsigned mA) return -ENODEV; dev = container_of(_gadget, struct langwell_udc, gadget); - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (dev->transceiver) { - VDBG(dev, "otg_set_power\n"); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "otg_set_power\n"); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return otg_set_power(dev->transceiver, mA); } - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return -ENOTSUPP; } @@ -1286,15 +1293,15 @@ static int langwell_vbus_draw(struct usb_gadget *_gadget, unsigned mA) static int langwell_pullup(struct usb_gadget *_gadget, int is_on) { struct langwell_udc *dev; - u32 usbcmd; - unsigned long flags; + u32 usbcmd; + unsigned long flags; if (!_gadget) return -ENODEV; dev = container_of(_gadget, struct langwell_udc, gadget); - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); spin_lock_irqsave(&dev->lock, flags); dev->softconnected = (is_on != 0); @@ -1310,7 +1317,7 @@ static int langwell_pullup(struct usb_gadget *_gadget, int is_on) } spin_unlock_irqrestore(&dev->lock, flags); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -1346,12 +1353,13 @@ static const struct usb_gadget_ops langwell_ops = { static int langwell_udc_reset(struct langwell_udc *dev) { u32 usbcmd, usbmode, devlc, endpointlistaddr; + u8 devlc_byte0, devlc_byte2; unsigned long timeout; if (!dev) return -EINVAL; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); /* set controller to stop state */ usbcmd = readl(&dev->op_regs->usbcmd); @@ -1367,7 +1375,7 @@ static int langwell_udc_reset(struct langwell_udc *dev) timeout = jiffies + RESET_TIMEOUT; while (readl(&dev->op_regs->usbcmd) & CMD_RST) { if (time_after(jiffies, timeout)) { - ERROR(dev, "device reset timeout\n"); + dev_err(&dev->pdev->dev, "device reset timeout\n"); return -ETIMEDOUT; } cpu_relax(); @@ -1382,7 +1390,7 @@ static int langwell_udc_reset(struct langwell_udc *dev) writel(usbmode, &dev->op_regs->usbmode); usbmode = readl(&dev->op_regs->usbmode); - VDBG(dev, "usbmode=0x%08x\n", usbmode); + dev_vdbg(&dev->pdev->dev, "usbmode=0x%08x\n", usbmode); /* Write-Clear setup status */ writel(0, &dev->op_regs->usbsts); @@ -1390,9 +1398,17 @@ static int langwell_udc_reset(struct langwell_udc *dev) /* if support USB LPM, ACK all LPM token */ if (dev->lpm) { devlc = readl(&dev->op_regs->devlc); + dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc); + /* FIXME: workaround for Langwell A1/A2/A3 sighting */ devlc &= ~LPM_STL; /* don't STALL LPM token */ devlc &= ~LPM_NYT_ACK; /* ACK LPM token */ - writel(devlc, &dev->op_regs->devlc); + devlc_byte0 = devlc & 0xff; + devlc_byte2 = (devlc >> 16) & 0xff; + writeb(devlc_byte0, (u8 *)&dev->op_regs->devlc); + writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2); + devlc = readl(&dev->op_regs->devlc); + dev_vdbg(&dev->pdev->dev, + "ACK LPM token, devlc = 0x%08x\n", devlc); } /* fill endpointlistaddr register */ @@ -1400,10 +1416,11 @@ static int langwell_udc_reset(struct langwell_udc *dev) endpointlistaddr &= ENDPOINTLISTADDR_MASK; writel(endpointlistaddr, &dev->op_regs->endpointlistaddr); - VDBG(dev, "dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n", - dev->ep_dqh, endpointlistaddr, - readl(&dev->op_regs->endpointlistaddr)); - DBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, + "dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n", + dev->ep_dqh, endpointlistaddr, + readl(&dev->op_regs->endpointlistaddr)); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -1415,7 +1432,7 @@ static int eps_reinit(struct langwell_udc *dev) char name[14]; int i; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); /* initialize ep0 */ ep = &dev->ep[0]; @@ -1449,11 +1466,9 @@ static int eps_reinit(struct langwell_udc *dev) INIT_LIST_HEAD(&ep->queue); list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list); - - ep->dqh = &dev->ep_dqh[i]; } - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -1462,7 +1477,7 @@ static int eps_reinit(struct langwell_udc *dev) static void langwell_udc_start(struct langwell_udc *dev) { u32 usbintr, usbcmd; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); /* enable interrupts */ usbintr = INTR_ULPIE /* ULPI */ @@ -1485,8 +1500,7 @@ static void langwell_udc_start(struct langwell_udc *dev) usbcmd |= CMD_RUNSTOP; writel(usbcmd, &dev->op_regs->usbcmd); - DBG(dev, "<--- %s()\n", __func__); - return; + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -1495,7 +1509,7 @@ static void langwell_udc_stop(struct langwell_udc *dev) { u32 usbcmd; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); /* disable all interrupts */ writel(0, &dev->op_regs->usbintr); @@ -1508,8 +1522,7 @@ static void langwell_udc_stop(struct langwell_udc *dev) usbcmd &= ~CMD_RUNSTOP; writel(usbcmd, &dev->op_regs->usbcmd); - DBG(dev, "<--- %s()\n", __func__); - return; + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -1518,7 +1531,7 @@ static void stop_activity(struct langwell_udc *dev, struct usb_gadget_driver *driver) { struct langwell_ep *ep; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); nuke(&dev->ep[0], -ESHUTDOWN); @@ -1533,7 +1546,7 @@ static void stop_activity(struct langwell_udc *dev, spin_lock(&dev->lock); } - DBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -1659,13 +1672,15 @@ static ssize_t show_langwell_udc(struct device *_dev, "Over-current Change: %s\n" "Port Enable/Disable Change: %s\n" "Port Enabled/Disabled: %s\n" - "Current Connect Status: %s\n\n", + "Current Connect Status: %s\n" + "LPM Suspend Status: %s\n\n", (tmp_reg & PORTS_PR) ? "Reset" : "Not Reset", (tmp_reg & PORTS_SUSP) ? "Suspend " : "Not Suspend", (tmp_reg & PORTS_OCC) ? "Detected" : "No", (tmp_reg & PORTS_PEC) ? "Changed" : "Not Changed", (tmp_reg & PORTS_PE) ? "Enable" : "Not Correct", - (tmp_reg & PORTS_CCS) ? "Attached" : "Not Attached"); + (tmp_reg & PORTS_CCS) ? "Attached" : "Not Attached", + (tmp_reg & PORTS_SLP) ? "LPM L1" : "LPM L0"); size -= t; next += t; @@ -1676,7 +1691,7 @@ static ssize_t show_langwell_udc(struct device *_dev, "Serial Transceiver : %d\n" "Port Speed: %s\n" "Port Force Full Speed Connenct: %s\n" - "PHY Low Power Suspend Clock Disable: %s\n" + "PHY Low Power Suspend Clock: %s\n" "BmAttributes: %d\n\n", LPM_PTS(tmp_reg), (tmp_reg & LPM_STS) ? 1 : 0, @@ -1797,6 +1812,36 @@ static ssize_t show_langwell_udc(struct device *_dev, static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL); +/* device "remote_wakeup" sysfs attribute file */ +static ssize_t store_remote_wakeup(struct device *_dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct langwell_udc *dev = the_controller; + unsigned long flags; + ssize_t rc = count; + + if (count > 2) + return -EINVAL; + + if (count > 0 && buf[count-1] == '\n') + ((char *) buf)[count-1] = 0; + + if (buf[0] != '1') + return -EINVAL; + + /* force remote wakeup enabled in case gadget driver doesn't support */ + spin_lock_irqsave(&dev->lock, flags); + dev->remote_wakeup = 1; + dev->dev_status |= (1 << USB_DEVICE_REMOTE_WAKEUP); + spin_unlock_irqrestore(&dev->lock, flags); + + langwell_wakeup(&dev->gadget); + + return rc; +} +static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup); + + /*-------------------------------------------------------------------------*/ /* @@ -1807,7 +1852,8 @@ static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL); * the driver might get unbound. */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct langwell_udc *dev = the_controller; unsigned long flags; @@ -1816,7 +1862,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) if (!dev) return -ENODEV; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); if (dev->driver) return -EBUSY; @@ -1830,9 +1876,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) spin_unlock_irqrestore(&dev->lock, flags); - retval = driver->bind(&dev->gadget); + retval = bind(&dev->gadget); if (retval) { - DBG(dev, "bind to driver %s --> %d\n", + dev_dbg(&dev->pdev->dev, "bind to driver %s --> %d\n", driver->driver.name, retval); dev->driver = NULL; dev->gadget.dev.driver = NULL; @@ -1851,13 +1897,13 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) if (dev->got_irq) langwell_udc_start(dev); - VDBG(dev, "After langwell_udc_start(), print all registers:\n"); -#ifdef VERBOSE + dev_vdbg(&dev->pdev->dev, + "After langwell_udc_start(), print all registers:\n"); print_all_registers(dev); -#endif - INFO(dev, "register driver: %s\n", driver->driver.name); - VDBG(dev, "<--- %s()\n", __func__); + dev_info(&dev->pdev->dev, "register driver: %s\n", + driver->driver.name); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; err_unbind: @@ -1865,10 +1911,10 @@ err_unbind: dev->gadget.dev.driver = NULL; dev->driver = NULL; - DBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); return retval; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); /* unregister gadget driver */ @@ -1880,11 +1926,15 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (!dev) return -ENODEV; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); - if (unlikely(!driver || !driver->bind || !driver->unbind)) + if (unlikely(!driver || !driver->unbind)) return -EINVAL; + /* exit PHY low power suspend */ + if (dev->pdev->device != 0x0829) + langwell_phy_low_power(dev, 0); + /* unbind OTG transceiver */ if (dev->transceiver) (void)otg_set_peripheral(dev->transceiver, 0); @@ -1910,8 +1960,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) device_remove_file(&dev->pdev->dev, &dev_attr_function); - INFO(dev, "unregistered driver '%s'\n", driver->driver.name); - DBG(dev, "<--- %s()\n", __func__); + dev_info(&dev->pdev->dev, "unregistered driver '%s'\n", + driver->driver.name); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } EXPORT_SYMBOL(usb_gadget_unregister_driver); @@ -1930,7 +1981,7 @@ static void setup_tripwire(struct langwell_udc *dev) unsigned long timeout; struct langwell_dqh *dqh; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); /* ep0 OUT dQH */ dqh = &dev->ep_dqh[EP_DIR_OUT]; @@ -1943,7 +1994,7 @@ static void setup_tripwire(struct langwell_udc *dev) timeout = jiffies + SETUPSTAT_TIMEOUT; while (readl(&dev->op_regs->endptsetupstat)) { if (time_after(jiffies, timeout)) { - ERROR(dev, "setup_tripwire timeout\n"); + dev_err(&dev->pdev->dev, "setup_tripwire timeout\n"); break; } cpu_relax(); @@ -1963,7 +2014,7 @@ static void setup_tripwire(struct langwell_udc *dev) usbcmd = readl(&dev->op_regs->usbcmd); writel(usbcmd & ~CMD_SUTW, &dev->op_regs->usbcmd); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -1972,7 +2023,7 @@ static void ep0_stall(struct langwell_udc *dev) { u32 endptctrl; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); /* set TX and RX to stall */ endptctrl = readl(&dev->op_regs->endptctrl[0]); @@ -1983,7 +2034,7 @@ static void ep0_stall(struct langwell_udc *dev) dev->ep0_state = WAIT_FOR_SETUP; dev->ep0_dir = USB_DIR_OUT; - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -1994,7 +2045,7 @@ static int prime_status_phase(struct langwell_udc *dev, int dir) struct langwell_ep *ep; int status = 0; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (dir == EP_DIR_IN) dev->ep0_dir = USB_DIR_IN; @@ -2019,11 +2070,11 @@ static int prime_status_phase(struct langwell_udc *dev, int dir) return -ENOMEM; if (status) - ERROR(dev, "can't queue ep0 status request\n"); + dev_err(&dev->pdev->dev, "can't queue ep0 status request\n"); list_add_tail(&req->queue, &ep->queue); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return status; } @@ -2032,11 +2083,11 @@ static int prime_status_phase(struct langwell_udc *dev, int dir) static void set_address(struct langwell_udc *dev, u16 value, u16 index, u16 length) { - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); /* save the new address to device struct */ dev->dev_addr = (u8) value; - VDBG(dev, "dev->dev_addr = %d\n", dev->dev_addr); + dev_vdbg(&dev->pdev->dev, "dev->dev_addr = %d\n", dev->dev_addr); /* update usb state */ dev->usb_state = USB_STATE_ADDRESS; @@ -2045,7 +2096,7 @@ static void set_address(struct langwell_udc *dev, u16 value, if (prime_status_phase(dev, EP_DIR_IN)) ep0_stall(dev); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -2054,7 +2105,7 @@ static struct langwell_ep *get_ep_by_windex(struct langwell_udc *dev, u16 wIndex) { struct langwell_ep *ep; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0) return &dev->ep[0]; @@ -2073,7 +2124,7 @@ static struct langwell_ep *get_ep_by_windex(struct langwell_udc *dev, return ep; } - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return NULL; } @@ -2085,7 +2136,7 @@ static int ep_is_stall(struct langwell_ep *ep) u32 endptctrl; int retval; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); endptctrl = readl(&dev->op_regs->endptctrl[ep->ep_num]); if (is_in(ep)) @@ -2093,7 +2144,7 @@ static int ep_is_stall(struct langwell_ep *ep) else retval = endptctrl & EPCTRL_RXS ? 1 : 0; - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return retval; } @@ -2107,14 +2158,13 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value, u16 status_data = 0; /* 16 bits cpu view status data */ int status = 0; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); ep = &dev->ep[0]; if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { /* get device status */ - status_data = 1 << USB_DEVICE_SELF_POWERED; - status_data |= dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP; + status_data = dev->dev_status; } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { /* get interface status */ status_data = 0; @@ -2129,6 +2179,8 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value, status_data = ep_is_stall(epn) << USB_ENDPOINT_HALT; } + dev_dbg(&dev->pdev->dev, "get status data: 0x%04x\n", status_data); + dev->ep0_dir = USB_DIR_IN; /* borrow the per device status_req */ @@ -2150,18 +2202,19 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value, goto stall; if (status) { - ERROR(dev, "response error on GET_STATUS request\n"); + dev_err(&dev->pdev->dev, + "response error on GET_STATUS request\n"); goto stall; } list_add_tail(&req->queue, &ep->queue); dev->ep0_state = DATA_STATE_XMIT; - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return; stall: ep0_stall(dev); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -2173,12 +2226,12 @@ static void handle_setup_packet(struct langwell_udc *dev, u16 wIndex = le16_to_cpu(setup->wIndex); u16 wLength = le16_to_cpu(setup->wLength); - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); /* ep0 fifo flush */ nuke(&dev->ep[0], -ESHUTDOWN); - DBG(dev, "SETUP %02x.%02x v%04x i%04x l%04x\n", + dev_dbg(&dev->pdev->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n", setup->bRequestType, setup->bRequest, wValue, wIndex, wLength); @@ -2197,7 +2250,7 @@ static void handle_setup_packet(struct langwell_udc *dev, /* We process some stardard setup requests here */ switch (setup->bRequest) { case USB_REQ_GET_STATUS: - DBG(dev, "SETUP: USB_REQ_GET_STATUS\n"); + dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_GET_STATUS\n"); /* get status, DATA and STATUS phase */ if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) != (USB_DIR_IN | USB_TYPE_STANDARD)) @@ -2206,7 +2259,7 @@ static void handle_setup_packet(struct langwell_udc *dev, goto end; case USB_REQ_SET_ADDRESS: - DBG(dev, "SETUP: USB_REQ_SET_ADDRESS\n"); + dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_SET_ADDRESS\n"); /* STATUS phase */ if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) @@ -2220,9 +2273,11 @@ static void handle_setup_packet(struct langwell_udc *dev, { int rc = -EOPNOTSUPP; if (setup->bRequest == USB_REQ_SET_FEATURE) - DBG(dev, "SETUP: USB_REQ_SET_FEATURE\n"); + dev_dbg(&dev->pdev->dev, + "SETUP: USB_REQ_SET_FEATURE\n"); else if (setup->bRequest == USB_REQ_CLEAR_FEATURE) - DBG(dev, "SETUP: USB_REQ_CLEAR_FEATURE\n"); + dev_dbg(&dev->pdev->dev, + "SETUP: USB_REQ_CLEAR_FEATURE\n"); if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { @@ -2240,13 +2295,29 @@ static void handle_setup_packet(struct langwell_udc *dev, spin_unlock(&dev->lock); rc = langwell_ep_set_halt(&epn->ep, - (setup->bRequest == USB_REQ_SET_FEATURE) - ? 1 : 0); + (setup->bRequest == USB_REQ_SET_FEATURE) + ? 1 : 0); spin_lock(&dev->lock); } else if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) == (USB_RECIP_DEVICE | USB_TYPE_STANDARD)) { + rc = 0; + switch (wValue) { + case USB_DEVICE_REMOTE_WAKEUP: + if (setup->bRequest == USB_REQ_SET_FEATURE) { + dev->remote_wakeup = 1; + dev->dev_status |= (1 << wValue); + } else { + dev->remote_wakeup = 0; + dev->dev_status &= ~(1 << wValue); + } + break; + default: + rc = -EOPNOTSUPP; + break; + } + if (!gadget_is_otg(&dev->gadget)) break; else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) { @@ -2262,7 +2333,6 @@ static void handle_setup_packet(struct langwell_udc *dev, dev->gadget.a_alt_hnp_support = 1; else break; - rc = 0; } else break; @@ -2274,31 +2344,38 @@ static void handle_setup_packet(struct langwell_udc *dev, } case USB_REQ_GET_DESCRIPTOR: - DBG(dev, "SETUP: USB_REQ_GET_DESCRIPTOR\n"); + dev_dbg(&dev->pdev->dev, + "SETUP: USB_REQ_GET_DESCRIPTOR\n"); goto delegate; case USB_REQ_SET_DESCRIPTOR: - DBG(dev, "SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n"); + dev_dbg(&dev->pdev->dev, + "SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n"); goto delegate; case USB_REQ_GET_CONFIGURATION: - DBG(dev, "SETUP: USB_REQ_GET_CONFIGURATION\n"); + dev_dbg(&dev->pdev->dev, + "SETUP: USB_REQ_GET_CONFIGURATION\n"); goto delegate; case USB_REQ_SET_CONFIGURATION: - DBG(dev, "SETUP: USB_REQ_SET_CONFIGURATION\n"); + dev_dbg(&dev->pdev->dev, + "SETUP: USB_REQ_SET_CONFIGURATION\n"); goto delegate; case USB_REQ_GET_INTERFACE: - DBG(dev, "SETUP: USB_REQ_GET_INTERFACE\n"); + dev_dbg(&dev->pdev->dev, + "SETUP: USB_REQ_GET_INTERFACE\n"); goto delegate; case USB_REQ_SET_INTERFACE: - DBG(dev, "SETUP: USB_REQ_SET_INTERFACE\n"); + dev_dbg(&dev->pdev->dev, + "SETUP: USB_REQ_SET_INTERFACE\n"); goto delegate; case USB_REQ_SYNCH_FRAME: - DBG(dev, "SETUP: USB_REQ_SYNCH_FRAME unsupported\n"); + dev_dbg(&dev->pdev->dev, + "SETUP: USB_REQ_SYNCH_FRAME unsupported\n"); goto delegate; default: @@ -2310,7 +2387,8 @@ delegate: /* DATA phase from gadget, STATUS phase from udc */ dev->ep0_dir = (setup->bRequestType & USB_DIR_IN) ? USB_DIR_IN : USB_DIR_OUT; - VDBG(dev, "dev->ep0_dir = 0x%x, wLength = %d\n", + dev_vdbg(&dev->pdev->dev, + "dev->ep0_dir = 0x%x, wLength = %d\n", dev->ep0_dir, wLength); spin_unlock(&dev->lock); if (dev->driver->setup(&dev->gadget, @@ -2322,7 +2400,8 @@ delegate: } else { /* no DATA phase, IN STATUS phase from gadget */ dev->ep0_dir = USB_DIR_IN; - VDBG(dev, "dev->ep0_dir = 0x%x, wLength = %d\n", + dev_vdbg(&dev->pdev->dev, + "dev->ep0_dir = 0x%x, wLength = %d\n", dev->ep0_dir, wLength); spin_unlock(&dev->lock); if (dev->driver->setup(&dev->gadget, @@ -2334,8 +2413,7 @@ delegate: break; } end: - VDBG(dev, "<--- %s()\n", __func__); - return; + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -2359,23 +2437,27 @@ static int process_ep_req(struct langwell_udc *dev, int index, td_complete = 0; actual = curr_req->req.length; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); for (i = 0; i < curr_req->dtd_count; i++) { - remaining_length = le16_to_cpu(curr_dtd->dtd_total); - actual -= remaining_length; /* command execution states by dTD */ dtd_status = curr_dtd->dtd_status; + barrier(); + remaining_length = le16_to_cpu(curr_dtd->dtd_total); + actual -= remaining_length; + if (!dtd_status) { /* transfers completed successfully */ if (!remaining_length) { td_complete++; - VDBG(dev, "dTD transmitted successfully\n"); + dev_vdbg(&dev->pdev->dev, + "dTD transmitted successfully\n"); } else { if (dir) { - VDBG(dev, "TX dTD remains data\n"); + dev_vdbg(&dev->pdev->dev, + "TX dTD remains data\n"); retval = -EPROTO; break; @@ -2387,27 +2469,32 @@ static int process_ep_req(struct langwell_udc *dev, int index, } else { /* transfers completed with errors */ if (dtd_status & DTD_STS_ACTIVE) { - DBG(dev, "request not completed\n"); + dev_dbg(&dev->pdev->dev, + "dTD status ACTIVE dQH[%d]\n", index); retval = 1; return retval; } else if (dtd_status & DTD_STS_HALTED) { - ERROR(dev, "dTD error %08x dQH[%d]\n", - dtd_status, index); + dev_err(&dev->pdev->dev, + "dTD error %08x dQH[%d]\n", + dtd_status, index); /* clear the errors and halt condition */ curr_dqh->dtd_status = 0; retval = -EPIPE; break; } else if (dtd_status & DTD_STS_DBE) { - DBG(dev, "data buffer (overflow) error\n"); + dev_dbg(&dev->pdev->dev, + "data buffer (overflow) error\n"); retval = -EPROTO; break; } else if (dtd_status & DTD_STS_TRE) { - DBG(dev, "transaction(ISO) error\n"); + dev_dbg(&dev->pdev->dev, + "transaction(ISO) error\n"); retval = -EILSEQ; break; } else - ERROR(dev, "unknown error (0x%x)!\n", - dtd_status); + dev_err(&dev->pdev->dev, + "unknown error (0x%x)!\n", + dtd_status); } if (i != curr_req->dtd_count - 1) @@ -2420,7 +2507,7 @@ static int process_ep_req(struct langwell_udc *dev, int index, curr_req->req.actual = actual; - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -2430,7 +2517,7 @@ static void ep0_req_complete(struct langwell_udc *dev, struct langwell_ep *ep0, struct langwell_request *req) { u32 new_addr; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (dev->usb_state == USB_STATE_ADDRESS) { /* set the new address */ @@ -2438,7 +2525,7 @@ static void ep0_req_complete(struct langwell_udc *dev, writel(new_addr << USBADR_SHIFT, &dev->op_regs->deviceaddr); new_addr = USBADR(readl(&dev->op_regs->deviceaddr)); - VDBG(dev, "new_addr = %d\n", new_addr); + dev_vdbg(&dev->pdev->dev, "new_addr = %d\n", new_addr); } done(ep0, req, 0); @@ -2458,14 +2545,14 @@ static void ep0_req_complete(struct langwell_udc *dev, dev->ep0_state = WAIT_FOR_SETUP; break; case WAIT_FOR_SETUP: - ERROR(dev, "unexpect ep0 packets\n"); + dev_err(&dev->pdev->dev, "unexpect ep0 packets\n"); break; default: ep0_stall(dev); break; } - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -2477,16 +2564,17 @@ static void handle_trans_complete(struct langwell_udc *dev) struct langwell_ep *epn; struct langwell_request *curr_req, *temp_req; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); complete_bits = readl(&dev->op_regs->endptcomplete); - VDBG(dev, "endptcomplete register: 0x%08x\n", complete_bits); + dev_vdbg(&dev->pdev->dev, "endptcomplete register: 0x%08x\n", + complete_bits); /* Write-Clear the bits in endptcomplete register */ writel(complete_bits, &dev->op_regs->endptcomplete); if (!complete_bits) { - DBG(dev, "complete_bits = 0\n"); + dev_dbg(&dev->pdev->dev, "complete_bits = 0\n"); goto done; } @@ -2506,23 +2594,25 @@ static void handle_trans_complete(struct langwell_udc *dev) epn = &dev->ep[i]; if (epn->name == NULL) { - WARNING(dev, "invalid endpoint\n"); + dev_warn(&dev->pdev->dev, "invalid endpoint\n"); continue; } if (i < 2) /* ep0 in and out */ - DBG(dev, "%s-%s transfer completed\n", + dev_dbg(&dev->pdev->dev, "%s-%s transfer completed\n", epn->name, is_in(epn) ? "in" : "out"); else - DBG(dev, "%s transfer completed\n", epn->name); + dev_dbg(&dev->pdev->dev, "%s transfer completed\n", + epn->name); /* process the req queue until an uncomplete request */ list_for_each_entry_safe(curr_req, temp_req, &epn->queue, queue) { status = process_ep_req(dev, i, curr_req); - VDBG(dev, "%s req status: %d\n", epn->name, status); + dev_vdbg(&dev->pdev->dev, "%s req status: %d\n", + epn->name, status); if (status) break; @@ -2540,8 +2630,7 @@ static void handle_trans_complete(struct langwell_udc *dev) } } done: - VDBG(dev, "<--- %s()\n", __func__); - return; + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -2551,14 +2640,14 @@ static void handle_port_change(struct langwell_udc *dev) u32 portsc1, devlc; u32 speed; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (dev->bus_reset) dev->bus_reset = 0; portsc1 = readl(&dev->op_regs->portsc1); devlc = readl(&dev->op_regs->devlc); - VDBG(dev, "portsc1 = 0x%08x, devlc = 0x%08x\n", + dev_vdbg(&dev->pdev->dev, "portsc1 = 0x%08x, devlc = 0x%08x\n", portsc1, devlc); /* bus reset is finished */ @@ -2579,25 +2668,22 @@ static void handle_port_change(struct langwell_udc *dev) dev->gadget.speed = USB_SPEED_UNKNOWN; break; } - VDBG(dev, "speed = %d, dev->gadget.speed = %d\n", + dev_vdbg(&dev->pdev->dev, + "speed = %d, dev->gadget.speed = %d\n", speed, dev->gadget.speed); } /* LPM L0 to L1 */ if (dev->lpm && dev->lpm_state == LPM_L0) if (portsc1 & PORTS_SUSP && portsc1 & PORTS_SLP) { - INFO(dev, "LPM L0 to L1\n"); - dev->lpm_state = LPM_L1; + dev_info(&dev->pdev->dev, "LPM L0 to L1\n"); + dev->lpm_state = LPM_L1; } /* LPM L1 to L0, force resume or remote wakeup finished */ if (dev->lpm && dev->lpm_state == LPM_L1) if (!(portsc1 & PORTS_SUSP)) { - if (portsc1 & PORTS_SLP) - INFO(dev, "LPM L1 to L0, force resume\n"); - else - INFO(dev, "LPM L1 to L0, remote wakeup\n"); - + dev_info(&dev->pdev->dev, "LPM L1 to L0\n"); dev->lpm_state = LPM_L0; } @@ -2605,7 +2691,7 @@ static void handle_port_change(struct langwell_udc *dev) if (!dev->resume_state) dev->usb_state = USB_STATE_DEFAULT; - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -2617,7 +2703,7 @@ static void handle_usb_reset(struct langwell_udc *dev) endptcomplete; unsigned long timeout; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); /* Write-Clear the device address */ deviceaddr = readl(&dev->op_regs->deviceaddr); @@ -2634,7 +2720,10 @@ static void handle_usb_reset(struct langwell_udc *dev) dev->ep0_dir = USB_DIR_OUT; dev->ep0_state = WAIT_FOR_SETUP; - dev->remote_wakeup = 0; /* default to 0 on reset */ + + /* remote wakeup reset to 0 when the device is reset */ + dev->remote_wakeup = 0; + dev->dev_status = 1 << USB_DEVICE_SELF_POWERED; dev->gadget.b_hnp_enable = 0; dev->gadget.a_hnp_support = 0; dev->gadget.a_alt_hnp_support = 0; @@ -2651,7 +2740,7 @@ static void handle_usb_reset(struct langwell_udc *dev) timeout = jiffies + PRIME_TIMEOUT; while (readl(&dev->op_regs->endptprime)) { if (time_after(jiffies, timeout)) { - ERROR(dev, "USB reset timeout\n"); + dev_err(&dev->pdev->dev, "USB reset timeout\n"); break; } cpu_relax(); @@ -2661,7 +2750,7 @@ static void handle_usb_reset(struct langwell_udc *dev) writel((u32) ~0, &dev->op_regs->endptflush); if (readl(&dev->op_regs->portsc1) & PORTS_PR) { - VDBG(dev, "USB bus reset\n"); + dev_vdbg(&dev->pdev->dev, "USB bus reset\n"); /* bus is reseting */ dev->bus_reset = 1; @@ -2669,7 +2758,7 @@ static void handle_usb_reset(struct langwell_udc *dev) stop_activity(dev, dev->driver); dev->usb_state = USB_STATE_DEFAULT; } else { - VDBG(dev, "device controller reset\n"); + dev_vdbg(&dev->pdev->dev, "device controller reset\n"); /* controller reset */ langwell_udc_reset(dev); @@ -2691,15 +2780,14 @@ static void handle_usb_reset(struct langwell_udc *dev) dev->lotg->hsm.b_hnp_enable = 0; #endif - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } /* USB bus suspend/resume interrupt */ static void handle_bus_suspend(struct langwell_udc *dev) { - u32 devlc; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); dev->resume_state = dev->usb_state; dev->usb_state = USB_STATE_SUSPENDED; @@ -2733,33 +2821,29 @@ static void handle_bus_suspend(struct langwell_udc *dev) spin_unlock(&dev->lock); dev->driver->suspend(&dev->gadget); spin_lock(&dev->lock); - DBG(dev, "suspend %s\n", dev->driver->driver.name); + dev_dbg(&dev->pdev->dev, "suspend %s\n", + dev->driver->driver.name); } } /* enter PHY low power suspend */ - devlc = readl(&dev->op_regs->devlc); - VDBG(dev, "devlc = 0x%08x\n", devlc); - devlc |= LPM_PHCD; - writel(devlc, &dev->op_regs->devlc); + if (dev->pdev->device != 0x0829) + langwell_phy_low_power(dev, 0); - DBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); } static void handle_bus_resume(struct langwell_udc *dev) { - u32 devlc; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); dev->usb_state = dev->resume_state; dev->resume_state = 0; /* exit PHY low power suspend */ - devlc = readl(&dev->op_regs->devlc); - VDBG(dev, "devlc = 0x%08x\n", devlc); - devlc &= ~LPM_PHCD; - writel(devlc, &dev->op_regs->devlc); + if (dev->pdev->device != 0x0829) + langwell_phy_low_power(dev, 0); #ifdef OTG_TRANSCEIVER if (dev->lotg->otg.default_a == 0) @@ -2772,11 +2856,12 @@ static void handle_bus_resume(struct langwell_udc *dev) spin_unlock(&dev->lock); dev->driver->resume(&dev->gadget); spin_lock(&dev->lock); - DBG(dev, "resume %s\n", dev->driver->driver.name); + dev_dbg(&dev->pdev->dev, "resume %s\n", + dev->driver->driver.name); } } - DBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -2789,11 +2874,11 @@ static irqreturn_t langwell_irq(int irq, void *_dev) irq_sts, portsc1; - VDBG(dev, "---> %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); if (dev->stopped) { - VDBG(dev, "handle IRQ_NONE\n"); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n"); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return IRQ_NONE; } @@ -2806,12 +2891,13 @@ static irqreturn_t langwell_irq(int irq, void *_dev) usbintr = readl(&dev->op_regs->usbintr); irq_sts = usbsts & usbintr; - VDBG(dev, "usbsts = 0x%08x, usbintr = 0x%08x, irq_sts = 0x%08x\n", + dev_vdbg(&dev->pdev->dev, + "usbsts = 0x%08x, usbintr = 0x%08x, irq_sts = 0x%08x\n", usbsts, usbintr, irq_sts); if (!irq_sts) { - VDBG(dev, "handle IRQ_NONE\n"); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n"); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); spin_unlock(&dev->lock); return IRQ_NONE; } @@ -2827,12 +2913,13 @@ static irqreturn_t langwell_irq(int irq, void *_dev) /* USB interrupt */ if (irq_sts & STS_UI) { - VDBG(dev, "USB interrupt\n"); + dev_vdbg(&dev->pdev->dev, "USB interrupt\n"); /* setup packet received from ep0 */ if (readl(&dev->op_regs->endptsetupstat) & EP0SETUPSTAT_MASK) { - VDBG(dev, "USB SETUP packet received interrupt\n"); + dev_vdbg(&dev->pdev->dev, + "USB SETUP packet received interrupt\n"); /* setup tripwire semaphone */ setup_tripwire(dev); handle_setup_packet(dev, &dev->local_setup_buff); @@ -2840,7 +2927,8 @@ static irqreturn_t langwell_irq(int irq, void *_dev) /* USB transfer completion */ if (readl(&dev->op_regs->endptcomplete)) { - VDBG(dev, "USB transfer completion interrupt\n"); + dev_vdbg(&dev->pdev->dev, + "USB transfer completion interrupt\n"); handle_trans_complete(dev); } } @@ -2848,36 +2936,36 @@ static irqreturn_t langwell_irq(int irq, void *_dev) /* SOF received interrupt (for ISO transfer) */ if (irq_sts & STS_SRI) { /* FIXME */ - /* VDBG(dev, "SOF received interrupt\n"); */ + /* dev_vdbg(&dev->pdev->dev, "SOF received interrupt\n"); */ } /* port change detect interrupt */ if (irq_sts & STS_PCI) { - VDBG(dev, "port change detect interrupt\n"); + dev_vdbg(&dev->pdev->dev, "port change detect interrupt\n"); handle_port_change(dev); } /* suspend interrrupt */ if (irq_sts & STS_SLI) { - VDBG(dev, "suspend interrupt\n"); + dev_vdbg(&dev->pdev->dev, "suspend interrupt\n"); handle_bus_suspend(dev); } /* USB reset interrupt */ if (irq_sts & STS_URI) { - VDBG(dev, "USB reset interrupt\n"); + dev_vdbg(&dev->pdev->dev, "USB reset interrupt\n"); handle_usb_reset(dev); } /* USB error or system error interrupt */ if (irq_sts & (STS_UEI | STS_SEI)) { /* FIXME */ - WARNING(dev, "error IRQ, irq_sts: %x\n", irq_sts); + dev_warn(&dev->pdev->dev, "error IRQ, irq_sts: %x\n", irq_sts); } spin_unlock(&dev->lock); - VDBG(dev, "<--- %s()\n", __func__); + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return IRQ_HANDLED; } @@ -2889,15 +2977,59 @@ static void gadget_release(struct device *_dev) { struct langwell_udc *dev = the_controller; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); complete(dev->done); - DBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); kfree(dev); } +/* enable SRAM caching if SRAM detected */ +static void sram_init(struct langwell_udc *dev) +{ + struct pci_dev *pdev = dev->pdev; + + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); + + dev->sram_addr = pci_resource_start(pdev, 1); + dev->sram_size = pci_resource_len(pdev, 1); + dev_info(&dev->pdev->dev, "Found private SRAM at %x size:%x\n", + dev->sram_addr, dev->sram_size); + dev->got_sram = 1; + + if (pci_request_region(pdev, 1, kobject_name(&pdev->dev.kobj))) { + dev_warn(&dev->pdev->dev, "SRAM request failed\n"); + dev->got_sram = 0; + } else if (!dma_declare_coherent_memory(&pdev->dev, dev->sram_addr, + dev->sram_addr, dev->sram_size, DMA_MEMORY_MAP)) { + dev_warn(&dev->pdev->dev, "SRAM DMA declare failed\n"); + pci_release_region(pdev, 1); + dev->got_sram = 0; + } + + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); +} + + +/* release SRAM caching */ +static void sram_deinit(struct langwell_udc *dev) +{ + struct pci_dev *pdev = dev->pdev; + + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); + + dma_release_declared_memory(&pdev->dev); + pci_release_region(pdev, 1); + + dev->got_sram = 0; + + dev_info(&dev->pdev->dev, "release SRAM caching\n"); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); +} + + /* tear down the binding between this driver and the pci device */ static void langwell_udc_remove(struct pci_dev *pdev) { @@ -2906,23 +3038,29 @@ static void langwell_udc_remove(struct pci_dev *pdev) DECLARE_COMPLETION(done); BUG_ON(dev->driver); - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); dev->done = &done; - /* free memory allocated in probe */ +#ifndef OTG_TRANSCEIVER + /* free dTD dma_pool and dQH */ if (dev->dtd_pool) dma_pool_destroy(dev->dtd_pool); + if (dev->ep_dqh) + dma_free_coherent(&pdev->dev, dev->ep_dqh_size, + dev->ep_dqh, dev->ep_dqh_dma); + + /* release SRAM caching */ + if (dev->has_sram && dev->got_sram) + sram_deinit(dev); +#endif + if (dev->status_req) { kfree(dev->status_req->req.buf); kfree(dev->status_req); } - if (dev->ep_dqh) - dma_free_coherent(&pdev->dev, dev->ep_dqh_size, - dev->ep_dqh, dev->ep_dqh_dma); - kfree(dev->ep); /* diable IRQ handler */ @@ -2949,11 +3087,12 @@ static void langwell_udc_remove(struct pci_dev *pdev) dev->cap_regs = NULL; - INFO(dev, "unbind\n"); - DBG(dev, "<--- %s()\n", __func__); + dev_info(&dev->pdev->dev, "unbind\n"); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); device_unregister(&dev->gadget.dev); device_remove_file(&pdev->dev, &dev_attr_langwell_udc); + device_remove_file(&pdev->dev, &dev_attr_remote_wakeup); #ifndef OTG_TRANSCEIVER pci_set_drvdata(pdev, NULL); @@ -2997,7 +3136,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, spin_lock_init(&dev->lock); dev->pdev = pdev; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); #ifdef OTG_TRANSCEIVER /* PCI device is already enabled by otg_transceiver driver */ @@ -3022,7 +3161,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, resource = pci_resource_start(pdev, 0); len = pci_resource_len(pdev, 0); if (!request_mem_region(resource, len, driver_name)) { - ERROR(dev, "controller already in use\n"); + dev_err(&dev->pdev->dev, "controller already in use\n"); retval = -EBUSY; goto error; } @@ -3031,33 +3170,43 @@ static int langwell_udc_probe(struct pci_dev *pdev, base = ioremap_nocache(resource, len); #endif if (base == NULL) { - ERROR(dev, "can't map memory\n"); + dev_err(&dev->pdev->dev, "can't map memory\n"); retval = -EFAULT; goto error; } dev->cap_regs = (struct langwell_cap_regs __iomem *) base; - VDBG(dev, "dev->cap_regs: %p\n", dev->cap_regs); + dev_vdbg(&dev->pdev->dev, "dev->cap_regs: %p\n", dev->cap_regs); dev->op_regs = (struct langwell_op_regs __iomem *) (base + OP_REG_OFFSET); - VDBG(dev, "dev->op_regs: %p\n", dev->op_regs); + dev_vdbg(&dev->pdev->dev, "dev->op_regs: %p\n", dev->op_regs); /* irq setup after old hardware is cleaned up */ if (!pdev->irq) { - ERROR(dev, "No IRQ. Check PCI setup!\n"); + dev_err(&dev->pdev->dev, "No IRQ. Check PCI setup!\n"); retval = -ENODEV; goto error; } + dev->has_sram = 1; + dev->got_sram = 0; + dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram); + #ifndef OTG_TRANSCEIVER - INFO(dev, "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n", + /* enable SRAM caching if detected */ + if (dev->has_sram && !dev->got_sram) + sram_init(dev); + + dev_info(&dev->pdev->dev, + "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n", pdev->irq, resource, len, base); /* enables bus-mastering for device dev */ pci_set_master(pdev); if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED, driver_name, dev) != 0) { - ERROR(dev, "request interrupt %d failed\n", pdev->irq); + dev_err(&dev->pdev->dev, + "request interrupt %d failed\n", pdev->irq); retval = -EBUSY; goto error; } @@ -3071,32 +3220,34 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->lpm = (readl(&dev->cap_regs->hccparams) & HCC_LEN) ? 1 : 0; dev->dciversion = readw(&dev->cap_regs->dciversion); dev->devcap = (readl(&dev->cap_regs->dccparams) & DEVCAP) ? 1 : 0; - VDBG(dev, "dev->lpm: %d\n", dev->lpm); - VDBG(dev, "dev->dciversion: 0x%04x\n", dev->dciversion); - VDBG(dev, "dccparams: 0x%08x\n", readl(&dev->cap_regs->dccparams)); - VDBG(dev, "dev->devcap: %d\n", dev->devcap); + dev_vdbg(&dev->pdev->dev, "dev->lpm: %d\n", dev->lpm); + dev_vdbg(&dev->pdev->dev, "dev->dciversion: 0x%04x\n", + dev->dciversion); + dev_vdbg(&dev->pdev->dev, "dccparams: 0x%08x\n", + readl(&dev->cap_regs->dccparams)); + dev_vdbg(&dev->pdev->dev, "dev->devcap: %d\n", dev->devcap); if (!dev->devcap) { - ERROR(dev, "can't support device mode\n"); + dev_err(&dev->pdev->dev, "can't support device mode\n"); retval = -ENODEV; goto error; } /* a pair of endpoints (out/in) for each address */ dev->ep_max = DEN(readl(&dev->cap_regs->dccparams)) * 2; - VDBG(dev, "dev->ep_max: %d\n", dev->ep_max); + dev_vdbg(&dev->pdev->dev, "dev->ep_max: %d\n", dev->ep_max); /* allocate endpoints memory */ dev->ep = kzalloc(sizeof(struct langwell_ep) * dev->ep_max, GFP_KERNEL); if (!dev->ep) { - ERROR(dev, "allocate endpoints memory failed\n"); + dev_err(&dev->pdev->dev, "allocate endpoints memory failed\n"); retval = -ENOMEM; goto error; } /* allocate device dQH memory */ size = dev->ep_max * sizeof(struct langwell_dqh); - VDBG(dev, "orig size = %d\n", size); + dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size); if (size < DQH_ALIGNMENT) size = DQH_ALIGNMENT; else if ((size % DQH_ALIGNMENT) != 0) { @@ -3106,17 +3257,18 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size, &dev->ep_dqh_dma, GFP_KERNEL); if (!dev->ep_dqh) { - ERROR(dev, "allocate dQH memory failed\n"); + dev_err(&dev->pdev->dev, "allocate dQH memory failed\n"); retval = -ENOMEM; goto error; } dev->ep_dqh_size = size; - VDBG(dev, "ep_dqh_size = %d\n", dev->ep_dqh_size); + dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size); /* initialize ep0 status request structure */ dev->status_req = kzalloc(sizeof(struct langwell_request), GFP_KERNEL); if (!dev->status_req) { - ERROR(dev, "allocate status_req memory failed\n"); + dev_err(&dev->pdev->dev, + "allocate status_req memory failed\n"); retval = -ENOMEM; goto error; } @@ -3129,7 +3281,10 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->resume_state = USB_STATE_NOTATTACHED; dev->usb_state = USB_STATE_POWERED; dev->ep0_dir = USB_DIR_OUT; - dev->remote_wakeup = 0; /* default to 0 on reset */ + + /* remote wakeup reset to 0 when the device is reset */ + dev->remote_wakeup = 0; + dev->dev_status = 1 << USB_DEVICE_SELF_POWERED; #ifndef OTG_TRANSCEIVER /* reset device controller */ @@ -3174,18 +3329,20 @@ static int langwell_udc_probe(struct pci_dev *pdev, } /* done */ - INFO(dev, "%s\n", driver_desc); - INFO(dev, "irq %d, pci mem %p\n", pdev->irq, base); - INFO(dev, "Driver version: " DRIVER_VERSION "\n"); - INFO(dev, "Support (max) %d endpoints\n", dev->ep_max); - INFO(dev, "Device interface version: 0x%04x\n", dev->dciversion); - INFO(dev, "Controller mode: %s\n", dev->devcap ? "Device" : "Host"); - INFO(dev, "Support USB LPM: %s\n", dev->lpm ? "Yes" : "No"); - - VDBG(dev, "After langwell_udc_probe(), print all registers:\n"); -#ifdef VERBOSE + dev_info(&dev->pdev->dev, "%s\n", driver_desc); + dev_info(&dev->pdev->dev, "irq %d, pci mem %p\n", pdev->irq, base); + dev_info(&dev->pdev->dev, "Driver version: " DRIVER_VERSION "\n"); + dev_info(&dev->pdev->dev, "Support (max) %d endpoints\n", dev->ep_max); + dev_info(&dev->pdev->dev, "Device interface version: 0x%04x\n", + dev->dciversion); + dev_info(&dev->pdev->dev, "Controller mode: %s\n", + dev->devcap ? "Device" : "Host"); + dev_info(&dev->pdev->dev, "Support USB LPM: %s\n", + dev->lpm ? "Yes" : "No"); + + dev_vdbg(&dev->pdev->dev, + "After langwell_udc_probe(), print all registers:\n"); print_all_registers(dev); -#endif the_controller = dev; @@ -3197,12 +3354,18 @@ static int langwell_udc_probe(struct pci_dev *pdev, if (retval) goto error; - VDBG(dev, "<--- %s()\n", __func__); + retval = device_create_file(&pdev->dev, &dev_attr_remote_wakeup); + if (retval) + goto error_attr1; + + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; +error_attr1: + device_remove_file(&pdev->dev, &dev_attr_langwell_udc); error: if (dev) { - DBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); langwell_udc_remove(pdev); } @@ -3214,9 +3377,8 @@ error: static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) { struct langwell_udc *dev = the_controller; - u32 devlc; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); /* disable interrupt and set controller to stop state */ langwell_udc_stop(dev); @@ -3226,20 +3388,34 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) free_irq(pdev->irq, dev); dev->got_irq = 0; - /* save PCI state */ pci_save_state(pdev); + spin_lock_irq(&dev->lock); + /* stop all usb activities */ + stop_activity(dev, dev->driver); + spin_unlock_irq(&dev->lock); + + /* free dTD dma_pool and dQH */ + if (dev->dtd_pool) + dma_pool_destroy(dev->dtd_pool); + + if (dev->ep_dqh) + dma_free_coherent(&pdev->dev, dev->ep_dqh_size, + dev->ep_dqh, dev->ep_dqh_dma); + + /* release SRAM caching */ + if (dev->has_sram && dev->got_sram) + sram_deinit(dev); + /* set device power state */ pci_set_power_state(pdev, PCI_D3hot); /* enter PHY low power suspend */ - devlc = readl(&dev->op_regs->devlc); - VDBG(dev, "devlc = 0x%08x\n", devlc); - devlc |= LPM_PHCD; - writel(devlc, &dev->op_regs->devlc); + if (dev->pdev->device != 0x0829) + langwell_phy_low_power(dev, 1); - DBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -3248,27 +3424,58 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) static int langwell_udc_resume(struct pci_dev *pdev) { struct langwell_udc *dev = the_controller; - u32 devlc; + size_t size; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); /* exit PHY low power suspend */ - devlc = readl(&dev->op_regs->devlc); - VDBG(dev, "devlc = 0x%08x\n", devlc); - devlc &= ~LPM_PHCD; - writel(devlc, &dev->op_regs->devlc); + if (dev->pdev->device != 0x0829) + langwell_phy_low_power(dev, 0); /* set device D0 power state */ pci_set_power_state(pdev, PCI_D0); + /* enable SRAM caching if detected */ + if (dev->has_sram && !dev->got_sram) + sram_init(dev); + + /* allocate device dQH memory */ + size = dev->ep_max * sizeof(struct langwell_dqh); + dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size); + if (size < DQH_ALIGNMENT) + size = DQH_ALIGNMENT; + else if ((size % DQH_ALIGNMENT) != 0) { + size += DQH_ALIGNMENT + 1; + size &= ~(DQH_ALIGNMENT - 1); + } + dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size, + &dev->ep_dqh_dma, GFP_KERNEL); + if (!dev->ep_dqh) { + dev_err(&dev->pdev->dev, "allocate dQH memory failed\n"); + return -ENOMEM; + } + dev->ep_dqh_size = size; + dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size); + + /* create dTD dma_pool resource */ + dev->dtd_pool = dma_pool_create("langwell_dtd", + &dev->pdev->dev, + sizeof(struct langwell_dtd), + DTD_ALIGNMENT, + DMA_BOUNDARY); + + if (!dev->dtd_pool) + return -ENOMEM; + /* restore PCI state */ pci_restore_state(pdev); /* enable IRQ handler */ - if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED, driver_name, dev) - != 0) { - ERROR(dev, "request interrupt %d failed\n", pdev->irq); - return -1; + if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED, + driver_name, dev) != 0) { + dev_err(&dev->pdev->dev, "request interrupt %d failed\n", + pdev->irq); + return -EBUSY; } dev->got_irq = 1; @@ -3290,7 +3497,7 @@ static int langwell_udc_resume(struct pci_dev *pdev) dev->ep0_state = WAIT_FOR_SETUP; dev->ep0_dir = USB_DIR_OUT; - DBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } @@ -3301,15 +3508,15 @@ static void langwell_udc_shutdown(struct pci_dev *pdev) struct langwell_udc *dev = the_controller; u32 usbmode; - DBG(dev, "---> %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); /* reset controller mode to IDLE */ usbmode = readl(&dev->op_regs->usbmode); - DBG(dev, "usbmode = 0x%08x\n", usbmode); + dev_dbg(&dev->pdev->dev, "usbmode = 0x%08x\n", usbmode); usbmode &= (~3 | MODE_IDLE); writel(usbmode, &dev->op_regs->usbmode); - DBG(dev, "<--- %s()\n", __func__); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); } /*-------------------------------------------------------------------------*/ @@ -3324,7 +3531,6 @@ static const struct pci_device_id pci_ids[] = { { }, { /* end: all zeroes */ } }; - MODULE_DEVICE_TABLE(pci, pci_ids); @@ -3343,12 +3549,6 @@ static struct pci_driver langwell_pci_driver = { }; -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>"); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - - static int __init init(void) { #ifdef OTG_TRANSCEIVER @@ -3370,3 +3570,9 @@ static void __exit cleanup(void) } module_exit(cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>"); +MODULE_VERSION(DRIVER_VERSION); +MODULE_LICENSE("GPL"); + diff --git a/drivers/usb/gadget/langwell_udc.h b/drivers/usb/gadget/langwell_udc.h index 9719934e1c08..f1d9c1bb04f3 100644 --- a/drivers/usb/gadget/langwell_udc.h +++ b/drivers/usb/gadget/langwell_udc.h @@ -18,11 +18,7 @@ */ #include <linux/usb/langwell_udc.h> - -#if defined(CONFIG_USB_LANGWELL_OTG) #include <linux/usb/langwell_otg.h> -#endif - /*-------------------------------------------------------------------------*/ @@ -199,7 +195,9 @@ struct langwell_udc { vbus_active:1, suspended:1, stopped:1, - lpm:1; /* LPM capability */ + lpm:1, /* LPM capability */ + has_sram:1, /* SRAM caching */ + got_sram:1; /* pci state used to access those endpoints */ struct pci_dev *pdev; @@ -224,5 +222,12 @@ struct langwell_udc { /* make sure release() is done */ struct completion *done; + + /* for private SRAM caching */ + unsigned int sram_addr; + unsigned int sram_size; + + /* device status data for get_status request */ + u16 dev_status; }; diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index fded3fca793b..6b58bd8ce623 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c @@ -408,7 +408,8 @@ static void udc_enable(struct lh7a40x_udc *dev) /* Register entry point for the peripheral controller driver. */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct lh7a40x_udc *dev = the_controller; int retval; @@ -417,7 +418,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) if (!driver || driver->speed != USB_SPEED_FULL - || !driver->bind + || !bind || !driver->disconnect || !driver->setup) return -EINVAL; @@ -431,7 +432,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) dev->gadget.dev.driver = &driver->driver; device_add(&dev->gadget.dev); - retval = driver->bind(&dev->gadget); + retval = bind(&dev->gadget); if (retval) { printk(KERN_WARNING "%s: bind to driver %s --> error %d\n", dev->gadget.name, driver->driver.name, retval); @@ -453,8 +454,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) return 0; } - -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); /* Unregister entry point for the peripheral controller driver. diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index e03058fe23cb..51b19f3027e7 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1454,14 +1454,15 @@ static struct usb_ep_ops m66592_ep_ops = { /*-------------------------------------------------------------------------*/ static struct m66592 *the_controller; -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct m66592 *m66592 = the_controller; int retval; if (!driver || driver->speed != USB_SPEED_HIGH - || !driver->bind + || !bind || !driver->setup) return -EINVAL; if (!m66592) @@ -1480,7 +1481,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) goto error; } - retval = driver->bind (&m66592->gadget); + retval = bind(&m66592->gadget); if (retval) { pr_err("bind to driver error (%d)\n", retval); device_del(&m66592->gadget.dev); @@ -1505,7 +1506,7 @@ error: return retval; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 585f2559484d..0769179dbdb0 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -75,10 +75,6 @@ static struct usb_device_descriptor msg_device_desc = { /* Vendor and product id can be overridden by module parameters. */ .idVendor = cpu_to_le16(FSG_VENDOR_ID), .idProduct = cpu_to_le16(FSG_PRODUCT_ID), - /* .bcdDevice = f(hardware) */ - /* .iManufacturer = DYNAMIC */ - /* .iProduct = DYNAMIC */ - /* NO SERIAL NUMBER */ .bNumConfigurations = 1, }; @@ -86,7 +82,8 @@ static struct usb_otg_descriptor otg_descriptor = { .bLength = sizeof otg_descriptor, .bDescriptorType = USB_DT_OTG, - /* REVISIT SRP-only hardware is possible, although + /* + * REVISIT SRP-only hardware is possible, although * it would not be called "OTG" ... */ .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, @@ -98,33 +95,6 @@ static const struct usb_descriptor_header *otg_desc[] = { }; -/* string IDs are assigned dynamically */ - -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 -#define STRING_CONFIGURATION_IDX 2 - -static char manufacturer[50]; - -static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer, - [STRING_PRODUCT_IDX].s = DRIVER_DESC, - [STRING_CONFIGURATION_IDX].s = "Self Powered", - { } /* end of list */ -}; - -static struct usb_gadget_strings stringtab_dev = { - .language = 0x0409, /* en-us */ - .strings = strings_dev, -}; - -static struct usb_gadget_strings *dev_strings[] = { - &stringtab_dev, - NULL, -}; - - - /****************************** Configurations ******************************/ static struct fsg_module_parameters mod_data = { @@ -141,7 +111,7 @@ static int msg_thread_exits(struct fsg_common *common) return 0; } -static int __ref msg_do_config(struct usb_configuration *c) +static int __init msg_do_config(struct usb_configuration *c) { static const struct fsg_operations ops = { .thread_exits = msg_thread_exits, @@ -171,54 +141,23 @@ static int __ref msg_do_config(struct usb_configuration *c) static struct usb_configuration msg_config_driver = { .label = "Linux File-Backed Storage", - .bind = msg_do_config, .bConfigurationValue = 1, - /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; - /****************************** Gadget Bind ******************************/ - -static int __ref msg_bind(struct usb_composite_dev *cdev) +static int __init msg_bind(struct usb_composite_dev *cdev) { - struct usb_gadget *gadget = cdev->gadget; int status; - /* Allocate string descriptor numbers ... note that string - * contents can be overridden by the composite_dev glue. - */ - - /* device descriptor strings: manufacturer, product */ - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); - status = usb_string_id(cdev); + status = usb_add_config(cdev, &msg_config_driver, msg_do_config); if (status < 0) return status; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - msg_device_desc.iManufacturer = status; - status = usb_string_id(cdev); - if (status < 0) - return status; - strings_dev[STRING_PRODUCT_IDX].id = status; - msg_device_desc.iProduct = status; - - status = usb_string_id(cdev); - if (status < 0) - return status; - strings_dev[STRING_CONFIGURATION_IDX].id = status; - msg_config_driver.iConfiguration = status; - - /* register our second configuration */ - status = usb_add_config(cdev, &msg_config_driver); - if (status < 0) - return status; - - dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); + dev_info(&cdev->gadget->dev, + DRIVER_DESC ", version: " DRIVER_VERSION "\n"); set_bit(0, &msg_registered); return 0; } @@ -226,12 +165,11 @@ static int __ref msg_bind(struct usb_composite_dev *cdev) /****************************** Some noise ******************************/ - static struct usb_composite_driver msg_driver = { .name = "g_mass_storage", .dev = &msg_device_desc, - .strings = dev_strings, - .bind = msg_bind, + .iProduct = DRIVER_DESC, + .needs_serial = 1, }; MODULE_DESCRIPTION(DRIVER_DESC); @@ -240,7 +178,7 @@ MODULE_LICENSE("GPL"); static int __init msg_init(void) { - return usb_composite_register(&msg_driver); + return usb_composite_probe(&msg_driver, msg_bind); } module_init(msg_init); diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 795d76232167..d9feced348e3 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -74,8 +74,8 @@ MODULE_LICENSE("GPL"); /***************************** Device Descriptor ****************************/ -#define MULTI_VENDOR_NUM 0x0525 /* XXX NetChip */ -#define MULTI_PRODUCT_NUM 0xa4ab /* XXX */ +#define MULTI_VENDOR_NUM 0x1d6b /* Linux Foundation */ +#define MULTI_PRODUCT_NUM 0x0104 /* Multifunction Composite Gadget */ enum { @@ -121,8 +121,6 @@ static const struct usb_descriptor_header *otg_desc[] = { enum { - MULTI_STRING_MANUFACTURER_IDX, - MULTI_STRING_PRODUCT_IDX, #ifdef CONFIG_USB_G_MULTI_RNDIS MULTI_STRING_RNDIS_CONFIG_IDX, #endif @@ -131,11 +129,7 @@ enum { #endif }; -static char manufacturer[50]; - static struct usb_string strings_dev[] = { - [MULTI_STRING_MANUFACTURER_IDX].s = manufacturer, - [MULTI_STRING_PRODUCT_IDX].s = DRIVER_DESC, #ifdef CONFIG_USB_G_MULTI_RNDIS [MULTI_STRING_RNDIS_CONFIG_IDX].s = "Multifunction with RNDIS", #endif @@ -170,7 +164,7 @@ static u8 hostaddr[ETH_ALEN]; #ifdef USB_ETH_RNDIS -static __ref int rndis_do_config(struct usb_configuration *c) +static __init int rndis_do_config(struct usb_configuration *c) { int ret; @@ -197,7 +191,6 @@ static __ref int rndis_do_config(struct usb_configuration *c) static int rndis_config_register(struct usb_composite_dev *cdev) { static struct usb_configuration config = { - .bind = rndis_do_config, .bConfigurationValue = MULTI_RNDIS_CONFIG_NUM, .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; @@ -205,7 +198,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev) config.label = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].s; config.iConfiguration = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].id; - return usb_add_config(cdev, &config); + return usb_add_config(cdev, &config, rndis_do_config); } #else @@ -222,7 +215,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev) #ifdef CONFIG_USB_G_MULTI_CDC -static __ref int cdc_do_config(struct usb_configuration *c) +static __init int cdc_do_config(struct usb_configuration *c) { int ret; @@ -249,7 +242,6 @@ static __ref int cdc_do_config(struct usb_configuration *c) static int cdc_config_register(struct usb_composite_dev *cdev) { static struct usb_configuration config = { - .bind = cdc_do_config, .bConfigurationValue = MULTI_CDC_CONFIG_NUM, .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; @@ -257,7 +249,7 @@ static int cdc_config_register(struct usb_composite_dev *cdev) config.label = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].s; config.iConfiguration = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].id; - return usb_add_config(cdev, &config); + return usb_add_config(cdev, &config, cdc_do_config); } #else @@ -314,20 +306,11 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); } - /* allocate string descriptor numbers */ - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); - + /* allocate string IDs */ status = usb_string_ids_tab(cdev, strings_dev); if (unlikely(status < 0)) goto fail2; - device_desc.iManufacturer = - strings_dev[MULTI_STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = - strings_dev[MULTI_STRING_PRODUCT_IDX].id; - /* register configurations */ status = rndis_config_register(cdev); if (unlikely(status < 0)) @@ -368,14 +351,15 @@ static struct usb_composite_driver multi_driver = { .name = "g_multi", .dev = &device_desc, .strings = dev_strings, - .bind = multi_bind, .unbind = __exit_p(multi_unbind), + .iProduct = DRIVER_DESC, + .needs_serial = 1, }; static int __init multi_init(void) { - return usb_composite_register(&multi_driver); + return usb_composite_probe(&multi_driver, multi_bind); } module_init(multi_init); diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 9498be87a724..d09155b25d73 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -1929,7 +1929,8 @@ static void ep0_start (struct net2280 *dev) * disconnect is reported. then a host may connect again, or * the driver might get unbound. */ -int usb_gadget_register_driver (struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct net2280 *dev = the_controller; int retval; @@ -1941,8 +1942,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) */ if (!driver || driver->speed != USB_SPEED_HIGH - || !driver->bind - || !driver->setup) + || !bind || !driver->setup) return -EINVAL; if (!dev) return -ENODEV; @@ -1957,7 +1957,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - retval = driver->bind (&dev->gadget); + retval = bind(&dev->gadget); if (retval) { DEBUG (dev, "bind to driver %s --> %d\n", driver->driver.name, retval); @@ -1993,7 +1993,7 @@ err_unbind: dev->driver = NULL; return retval; } -EXPORT_SYMBOL (usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); static void stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver) diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index 7d6b66a85724..b5364f9d7cd2 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -135,7 +135,6 @@ static int __init nokia_bind_config(struct usb_configuration *c) static struct usb_configuration nokia_config_500ma_driver = { .label = "Bus Powered", - .bind = nokia_bind_config, .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_ONE, @@ -144,7 +143,6 @@ static struct usb_configuration nokia_config_500ma_driver = { static struct usb_configuration nokia_config_100ma_driver = { .label = "Self Powered", - .bind = nokia_bind_config, .bConfigurationValue = 2, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, @@ -206,11 +204,13 @@ static int __init nokia_bind(struct usb_composite_dev *cdev) } /* finaly register the configuration */ - status = usb_add_config(cdev, &nokia_config_500ma_driver); + status = usb_add_config(cdev, &nokia_config_500ma_driver, + nokia_bind_config); if (status < 0) goto err_usb; - status = usb_add_config(cdev, &nokia_config_100ma_driver); + status = usb_add_config(cdev, &nokia_config_100ma_driver, + nokia_bind_config); if (status < 0) goto err_usb; @@ -241,13 +241,12 @@ static struct usb_composite_driver nokia_driver = { .name = "g_nokia", .dev = &device_desc, .strings = dev_strings, - .bind = nokia_bind, .unbind = __exit_p(nokia_unbind), }; static int __init nokia_init(void) { - return usb_composite_register(&nokia_driver); + return usb_composite_probe(&nokia_driver, nokia_bind); } module_init(nokia_init); diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index f81e4f025f23..61d3ca6619bb 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2102,7 +2102,8 @@ static inline int machine_without_vbus_sense(void) ); } -int usb_gadget_register_driver (struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { int status = -ENODEV; struct omap_ep *ep; @@ -2114,8 +2115,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) if (!driver // FIXME if otg, check: driver->is_otg || driver->speed < USB_SPEED_FULL - || !driver->bind - || !driver->setup) + || !bind || !driver->setup) return -EINVAL; spin_lock_irqsave(&udc->lock, flags); @@ -2145,7 +2145,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) if (udc->dc_clk != NULL) omap_udc_enable_clock(1); - status = driver->bind (&udc->gadget); + status = bind(&udc->gadget); if (status) { DBG("bind to %s --> %d\n", driver->driver.name, status); udc->gadget.dev.driver = NULL; @@ -2186,7 +2186,7 @@ done: omap_udc_enable_clock(0); return status; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) { diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 327a92a137b4..2fc8636316c5 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -1348,7 +1348,7 @@ printer_unbind(struct usb_gadget *gadget) set_gadget_data(gadget, NULL); } -static int __ref +static int __init printer_bind(struct usb_gadget *gadget) { struct printer_dev *dev; @@ -1544,7 +1544,6 @@ static struct usb_gadget_driver printer_driver = { .speed = DEVSPEED, .function = (char *) driver_desc, - .bind = printer_bind, .unbind = printer_unbind, .setup = printer_setup, @@ -1580,11 +1579,11 @@ init(void) return status; } - status = usb_gadget_register_driver(&printer_driver); + status = usb_gadget_probe_driver(&printer_driver, printer_bind); if (status) { class_destroy(usb_gadget_class); unregister_chrdev_region(g_printer_devno, 1); - DBG(dev, "usb_gadget_register_driver %x\n", status); + DBG(dev, "usb_gadget_probe_driver %x\n", status); } return status; diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index be5fb34d9602..b37f92cb71bc 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -1280,14 +1280,15 @@ static void udc_enable (struct pxa25x_udc *dev) * disconnect is reported. then a host may connect again, or * the driver might get unbound. */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct pxa25x_udc *dev = the_controller; int retval; if (!driver || driver->speed < USB_SPEED_FULL - || !driver->bind + || !bind || !driver->disconnect || !driver->setup) return -EINVAL; @@ -1308,7 +1309,7 @@ fail: dev->gadget.dev.driver = NULL; return retval; } - retval = driver->bind(&dev->gadget); + retval = bind(&dev->gadget); if (retval) { DMSG("bind to driver %s --> error %d\n", driver->driver.name, retval); @@ -1338,7 +1339,7 @@ fail: bind_fail: return retval; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); static void stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 980762453a9c..027d66f81620 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1792,8 +1792,9 @@ static void udc_enable(struct pxa_udc *udc) } /** - * usb_gadget_register_driver - Register gadget driver + * usb_gadget_probe_driver - Register gadget driver * @driver: gadget driver + * @bind: bind function * * When a driver is successfully registered, it will receive control requests * including set_configuration(), which enables non-control requests. Then @@ -1805,12 +1806,13 @@ static void udc_enable(struct pxa_udc *udc) * * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct pxa_udc *udc = the_controller; int retval; - if (!driver || driver->speed < USB_SPEED_FULL || !driver->bind + if (!driver || driver->speed < USB_SPEED_FULL || !bind || !driver->disconnect || !driver->setup) return -EINVAL; if (!udc) @@ -1828,7 +1830,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) dev_err(udc->dev, "device_add error %d\n", retval); goto add_fail; } - retval = driver->bind(&udc->gadget); + retval = bind(&udc->gadget); if (retval) { dev_err(udc->dev, "bind to driver %s --> error %d\n", driver->driver.name, retval); @@ -1859,7 +1861,7 @@ add_fail: udc->gadget.dev.driver = NULL; return retval; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); /** diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 2456ccd9965e..20d43da319ae 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -42,6 +42,7 @@ static const char *r8a66597_ep_name[] = { "ep8", "ep9", }; +static void init_controller(struct r8a66597 *r8a66597); static void disable_controller(struct r8a66597 *r8a66597); static void irq_ep0_write(struct r8a66597_ep *ep, struct r8a66597_request *req); static void irq_packet_write(struct r8a66597_ep *ep, @@ -104,6 +105,8 @@ __acquires(r8a66597->lock) spin_lock(&r8a66597->lock); disable_controller(r8a66597); + init_controller(r8a66597); + r8a66597_bset(r8a66597, VBSE, INTENB0); INIT_LIST_HEAD(&r8a66597->ep[0].queue); } @@ -274,7 +277,7 @@ static int pipe_buffer_setting(struct r8a66597 *r8a66597, } if (buf_bsize && ((bufnum + 16) >= R8A66597_MAX_BUFNUM)) { - pr_err(KERN_ERR "r8a66597 pipe memory is insufficient\n"); + pr_err("r8a66597 pipe memory is insufficient\n"); return -ENOMEM; } @@ -1405,14 +1408,15 @@ static struct usb_ep_ops r8a66597_ep_ops = { /*-------------------------------------------------------------------------*/ static struct r8a66597 *the_controller; -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct r8a66597 *r8a66597 = the_controller; int retval; if (!driver || driver->speed != USB_SPEED_HIGH - || !driver->bind + || !bind || !driver->setup) return -EINVAL; if (!r8a66597) @@ -1431,7 +1435,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) goto error; } - retval = driver->bind(&r8a66597->gadget); + retval = bind(&r8a66597->gadget); if (retval) { printk(KERN_ERR "bind to driver error (%d)\n", retval); device_del(&r8a66597->gadget.dev); @@ -1456,7 +1460,7 @@ error: return retval; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h index f763b5190afa..5fc22e09a0f1 100644 --- a/drivers/usb/gadget/r8a66597-udc.h +++ b/drivers/usb/gadget/r8a66597-udc.h @@ -136,7 +136,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, int len) { void __iomem *fifoaddr = r8a66597->reg + offset; - unsigned int data; + unsigned int data = 0; int i; if (r8a66597->pdata->on_chip) { diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 972d5ddd1e18..5b314041dfa9 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -61,17 +61,17 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging"); #define RNDIS_MAX_CONFIGS 1 -static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS]; +static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS]; /* Driver Version */ -static const __le32 rndis_driver_version = cpu_to_le32 (1); +static const __le32 rndis_driver_version = cpu_to_le32(1); /* Function Prototypes */ -static rndis_resp_t *rndis_add_response (int configNr, u32 length); +static rndis_resp_t *rndis_add_response(int configNr, u32 length); /* supported OIDs */ -static const u32 oid_supported_list [] = +static const u32 oid_supported_list[] = { /* the general stuff */ OID_GEN_SUPPORTED_LIST, @@ -161,21 +161,20 @@ static const u32 oid_supported_list [] = /* NDIS Functions */ -static int -gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, - rndis_resp_t *r) +static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, + unsigned buf_len, rndis_resp_t *r) { - int retval = -ENOTSUPP; - u32 length = 4; /* usually */ - __le32 *outbuf; - int i, count; - rndis_query_cmplt_type *resp; - struct net_device *net; + int retval = -ENOTSUPP; + u32 length = 4; /* usually */ + __le32 *outbuf; + int i, count; + rndis_query_cmplt_type *resp; + struct net_device *net; struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *stats; if (!r) return -ENOMEM; - resp = (rndis_query_cmplt_type *) r->buf; + resp = (rndis_query_cmplt_type *)r->buf; if (!resp) return -ENOMEM; @@ -191,8 +190,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, } /* response goes here, right after the header */ - outbuf = (__le32 *) &resp[1]; - resp->InformationBufferOffset = cpu_to_le32 (16); + outbuf = (__le32 *)&resp[1]; + resp->InformationBufferOffset = cpu_to_le32(16); net = rndis_per_dev_params[configNr].dev; stats = dev_get_stats(net, &temp); @@ -204,10 +203,10 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_SUPPORTED_LIST: pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__); - length = sizeof (oid_supported_list); - count = length / sizeof (u32); + length = sizeof(oid_supported_list); + count = length / sizeof(u32); for (i = 0; i < count; i++) - outbuf[i] = cpu_to_le32 (oid_supported_list[i]); + outbuf[i] = cpu_to_le32(oid_supported_list[i]); retval = 0; break; @@ -220,14 +219,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, * reddite ergo quae sunt Caesaris Caesari * et quae sunt Dei Deo! */ - *outbuf = cpu_to_le32 (0); + *outbuf = cpu_to_le32(0); retval = 0; break; /* mandatory */ case OID_GEN_MEDIA_SUPPORTED: pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__); - *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); + *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); retval = 0; break; @@ -235,16 +234,16 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, case OID_GEN_MEDIA_IN_USE: pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__); /* one medium, one transport... (maybe you do it better) */ - *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); + *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); retval = 0; break; /* mandatory */ case OID_GEN_MAXIMUM_FRAME_SIZE: pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); - if (rndis_per_dev_params [configNr].dev) { - *outbuf = cpu_to_le32 ( - rndis_per_dev_params [configNr].dev->mtu); + if (rndis_per_dev_params[configNr].dev) { + *outbuf = cpu_to_le32( + rndis_per_dev_params[configNr].dev->mtu); retval = 0; } break; @@ -253,21 +252,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, case OID_GEN_LINK_SPEED: if (rndis_debug > 1) pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__); - if (rndis_per_dev_params [configNr].media_state + if (rndis_per_dev_params[configNr].media_state == NDIS_MEDIA_STATE_DISCONNECTED) - *outbuf = cpu_to_le32 (0); + *outbuf = cpu_to_le32(0); else - *outbuf = cpu_to_le32 ( - rndis_per_dev_params [configNr].speed); + *outbuf = cpu_to_le32( + rndis_per_dev_params[configNr].speed); retval = 0; break; /* mandatory */ case OID_GEN_TRANSMIT_BLOCK_SIZE: pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); - if (rndis_per_dev_params [configNr].dev) { - *outbuf = cpu_to_le32 ( - rndis_per_dev_params [configNr].dev->mtu); + if (rndis_per_dev_params[configNr].dev) { + *outbuf = cpu_to_le32( + rndis_per_dev_params[configNr].dev->mtu); retval = 0; } break; @@ -275,9 +274,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_RECEIVE_BLOCK_SIZE: pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); - if (rndis_per_dev_params [configNr].dev) { - *outbuf = cpu_to_le32 ( - rndis_per_dev_params [configNr].dev->mtu); + if (rndis_per_dev_params[configNr].dev) { + *outbuf = cpu_to_le32( + rndis_per_dev_params[configNr].dev->mtu); retval = 0; } break; @@ -285,18 +284,20 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_VENDOR_ID: pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__); - *outbuf = cpu_to_le32 ( - rndis_per_dev_params [configNr].vendorID); + *outbuf = cpu_to_le32( + rndis_per_dev_params[configNr].vendorID); retval = 0; break; /* mandatory */ case OID_GEN_VENDOR_DESCRIPTION: pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); - if ( rndis_per_dev_params [configNr].vendorDescr ) { - length = strlen (rndis_per_dev_params [configNr].vendorDescr); - memcpy (outbuf, - rndis_per_dev_params [configNr].vendorDescr, length); + if (rndis_per_dev_params[configNr].vendorDescr) { + length = strlen(rndis_per_dev_params[configNr]. + vendorDescr); + memcpy(outbuf, + rndis_per_dev_params[configNr].vendorDescr, + length); } else { outbuf[0] = 0; } @@ -313,7 +314,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_CURRENT_PACKET_FILTER: pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__); - *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter); + *outbuf = cpu_to_le32(*rndis_per_dev_params[configNr].filter); retval = 0; break; @@ -328,14 +329,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, case OID_GEN_MEDIA_CONNECT_STATUS: if (rndis_debug > 1) pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); - *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + *outbuf = cpu_to_le32(rndis_per_dev_params[configNr] .media_state); retval = 0; break; case OID_GEN_PHYSICAL_MEDIUM: pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); - *outbuf = cpu_to_le32 (0); + *outbuf = cpu_to_le32(0); retval = 0; break; @@ -409,10 +410,10 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_PERMANENT_ADDRESS: pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__); - if (rndis_per_dev_params [configNr].dev) { + if (rndis_per_dev_params[configNr].dev) { length = ETH_ALEN; - memcpy (outbuf, - rndis_per_dev_params [configNr].host_mac, + memcpy(outbuf, + rndis_per_dev_params[configNr].host_mac, length); retval = 0; } @@ -421,9 +422,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_CURRENT_ADDRESS: pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__); - if (rndis_per_dev_params [configNr].dev) { + if (rndis_per_dev_params[configNr].dev) { length = ETH_ALEN; - memcpy (outbuf, + memcpy(outbuf, rndis_per_dev_params [configNr].host_mac, length); retval = 0; @@ -434,7 +435,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, case OID_802_3_MULTICAST_LIST: pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); /* Multicast base address only */ - *outbuf = cpu_to_le32 (0xE0000000); + *outbuf = cpu_to_le32(0xE0000000); retval = 0; break; @@ -442,7 +443,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, case OID_802_3_MAXIMUM_LIST_SIZE: pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); /* Multicast base address only */ - *outbuf = cpu_to_le32 (1); + *outbuf = cpu_to_le32(1); retval = 0; break; @@ -466,14 +467,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_XMIT_ONE_COLLISION: pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); - *outbuf = cpu_to_le32 (0); + *outbuf = cpu_to_le32(0); retval = 0; break; /* mandatory */ case OID_802_3_XMIT_MORE_COLLISIONS: pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); - *outbuf = cpu_to_le32 (0); + *outbuf = cpu_to_le32(0); retval = 0; break; @@ -484,22 +485,22 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, if (retval < 0) length = 0; - resp->InformationBufferLength = cpu_to_le32 (length); - r->length = length + sizeof *resp; - resp->MessageLength = cpu_to_le32 (r->length); + resp->InformationBufferLength = cpu_to_le32(length); + r->length = length + sizeof(*resp); + resp->MessageLength = cpu_to_le32(r->length); return retval; } -static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, - rndis_resp_t *r) +static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len, + rndis_resp_t *r) { - rndis_set_cmplt_type *resp; - int i, retval = -ENOTSUPP; - struct rndis_params *params; + rndis_set_cmplt_type *resp; + int i, retval = -ENOTSUPP; + struct rndis_params *params; if (!r) return -ENOMEM; - resp = (rndis_set_cmplt_type *) r->buf; + resp = (rndis_set_cmplt_type *)r->buf; if (!resp) return -ENOMEM; @@ -514,7 +515,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, } } - params = &rndis_per_dev_params [configNr]; + params = &rndis_per_dev_params[configNr]; switch (OID) { case OID_GEN_CURRENT_PACKET_FILTER: @@ -537,11 +538,11 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, params->state = RNDIS_DATA_INITIALIZED; netif_carrier_on(params->dev); if (netif_running(params->dev)) - netif_wake_queue (params->dev); + netif_wake_queue(params->dev); } else { params->state = RNDIS_INITIALIZED; - netif_carrier_off (params->dev); - netif_stop_queue (params->dev); + netif_carrier_off(params->dev); + netif_stop_queue(params->dev); } break; @@ -563,48 +564,47 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, * Response Functions */ -static int rndis_init_response (int configNr, rndis_init_msg_type *buf) +static int rndis_init_response(int configNr, rndis_init_msg_type *buf) { - rndis_init_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; + rndis_init_cmplt_type *resp; + rndis_resp_t *r; + struct rndis_params *params = rndis_per_dev_params + configNr; if (!params->dev) return -ENOTSUPP; - r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type)); + r = rndis_add_response(configNr, sizeof(rndis_init_cmplt_type)); if (!r) return -ENOMEM; - resp = (rndis_init_cmplt_type *) r->buf; + resp = (rndis_init_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32 ( - REMOTE_NDIS_INITIALIZE_CMPLT); - resp->MessageLength = cpu_to_le32 (52); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_INITIALIZE_CMPLT); + resp->MessageLength = cpu_to_le32(52); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); - resp->MajorVersion = cpu_to_le32 (RNDIS_MAJOR_VERSION); - resp->MinorVersion = cpu_to_le32 (RNDIS_MINOR_VERSION); - resp->DeviceFlags = cpu_to_le32 (RNDIS_DF_CONNECTIONLESS); - resp->Medium = cpu_to_le32 (RNDIS_MEDIUM_802_3); - resp->MaxPacketsPerTransfer = cpu_to_le32 (1); - resp->MaxTransferSize = cpu_to_le32 ( + resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); + resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION); + resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION); + resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS); + resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3); + resp->MaxPacketsPerTransfer = cpu_to_le32(1); + resp->MaxTransferSize = cpu_to_le32( params->dev->mtu - + sizeof (struct ethhdr) - + sizeof (struct rndis_packet_msg_type) + + sizeof(struct ethhdr) + + sizeof(struct rndis_packet_msg_type) + 22); - resp->PacketAlignmentFactor = cpu_to_le32 (0); - resp->AFListOffset = cpu_to_le32 (0); - resp->AFListSize = cpu_to_le32 (0); + resp->PacketAlignmentFactor = cpu_to_le32(0); + resp->AFListOffset = cpu_to_le32(0); + resp->AFListSize = cpu_to_le32(0); params->resp_avail(params->v); return 0; } -static int rndis_query_response (int configNr, rndis_query_msg_type *buf) +static int rndis_query_response(int configNr, rndis_query_msg_type *buf) { rndis_query_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; + rndis_resp_t *r; + struct rndis_params *params = rndis_per_dev_params + configNr; /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */ if (!params->dev) @@ -616,47 +616,46 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) * rndis_query_cmplt_type followed by data. * oid_supported_list is the largest data reply */ - r = rndis_add_response (configNr, - sizeof (oid_supported_list) + sizeof(rndis_query_cmplt_type)); + r = rndis_add_response(configNr, + sizeof(oid_supported_list) + sizeof(rndis_query_cmplt_type)); if (!r) return -ENOMEM; - resp = (rndis_query_cmplt_type *) r->buf; + resp = (rndis_query_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_QUERY_CMPLT); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID), + if (gen_ndis_query_resp(configNr, le32_to_cpu(buf->OID), le32_to_cpu(buf->InformationBufferOffset) - + 8 + (u8 *) buf, + + 8 + (u8 *)buf, le32_to_cpu(buf->InformationBufferLength), r)) { /* OID not supported */ - resp->Status = cpu_to_le32 ( - RNDIS_STATUS_NOT_SUPPORTED); - resp->MessageLength = cpu_to_le32 (sizeof *resp); - resp->InformationBufferLength = cpu_to_le32 (0); - resp->InformationBufferOffset = cpu_to_le32 (0); + resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); + resp->MessageLength = cpu_to_le32(sizeof *resp); + resp->InformationBufferLength = cpu_to_le32(0); + resp->InformationBufferOffset = cpu_to_le32(0); } else - resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); + resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); params->resp_avail(params->v); return 0; } -static int rndis_set_response (int configNr, rndis_set_msg_type *buf) +static int rndis_set_response(int configNr, rndis_set_msg_type *buf) { - u32 BufLength, BufOffset; - rndis_set_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; + u32 BufLength, BufOffset; + rndis_set_cmplt_type *resp; + rndis_resp_t *r; + struct rndis_params *params = rndis_per_dev_params + configNr; - r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); + r = rndis_add_response(configNr, sizeof(rndis_set_cmplt_type)); if (!r) return -ENOMEM; - resp = (rndis_set_cmplt_type *) r->buf; + resp = (rndis_set_cmplt_type *)r->buf; - BufLength = le32_to_cpu (buf->InformationBufferLength); - BufOffset = le32_to_cpu (buf->InformationBufferOffset); + BufLength = le32_to_cpu(buf->InformationBufferLength); + BufOffset = le32_to_cpu(buf->InformationBufferOffset); #ifdef VERBOSE_DEBUG pr_debug("%s: Length: %d\n", __func__, BufLength); @@ -670,59 +669,59 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) pr_debug("\n"); #endif - resp->MessageType = cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); - resp->MessageLength = cpu_to_le32 (16); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_SET_CMPLT); + resp->MessageLength = cpu_to_le32(16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID), - ((u8 *) buf) + 8 + BufOffset, BufLength, r)) - resp->Status = cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); + if (gen_ndis_set_resp(configNr, le32_to_cpu(buf->OID), + ((u8 *)buf) + 8 + BufOffset, BufLength, r)) + resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); else - resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); + resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); params->resp_avail(params->v); return 0; } -static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf) +static int rndis_reset_response(int configNr, rndis_reset_msg_type *buf) { - rndis_reset_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; + rndis_reset_cmplt_type *resp; + rndis_resp_t *r; + struct rndis_params *params = rndis_per_dev_params + configNr; - r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type)); + r = rndis_add_response(configNr, sizeof(rndis_reset_cmplt_type)); if (!r) return -ENOMEM; - resp = (rndis_reset_cmplt_type *) r->buf; + resp = (rndis_reset_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); - resp->MessageLength = cpu_to_le32 (16); - resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_RESET_CMPLT); + resp->MessageLength = cpu_to_le32(16); + resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); /* resent information */ - resp->AddressingReset = cpu_to_le32 (1); + resp->AddressingReset = cpu_to_le32(1); params->resp_avail(params->v); return 0; } -static int rndis_keepalive_response (int configNr, - rndis_keepalive_msg_type *buf) +static int rndis_keepalive_response(int configNr, + rndis_keepalive_msg_type *buf) { - rndis_keepalive_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; + rndis_keepalive_cmplt_type *resp; + rndis_resp_t *r; + struct rndis_params *params = rndis_per_dev_params + configNr; /* host "should" check only in RNDIS_DATA_INITIALIZED state */ - r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type)); + r = rndis_add_response(configNr, sizeof(rndis_keepalive_cmplt_type)); if (!r) return -ENOMEM; - resp = (rndis_keepalive_cmplt_type *) r->buf; + resp = (rndis_keepalive_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32 ( + resp->MessageType = cpu_to_le32( REMOTE_NDIS_KEEPALIVE_CMPLT); - resp->MessageLength = cpu_to_le32 (16); + resp->MessageLength = cpu_to_le32(16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); + resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); params->resp_avail(params->v); return 0; @@ -732,86 +731,85 @@ static int rndis_keepalive_response (int configNr, /* * Device to Host Comunication */ -static int rndis_indicate_status_msg (int configNr, u32 status) +static int rndis_indicate_status_msg(int configNr, u32 status) { - rndis_indicate_status_msg_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; + rndis_indicate_status_msg_type *resp; + rndis_resp_t *r; + struct rndis_params *params = rndis_per_dev_params + configNr; if (params->state == RNDIS_UNINITIALIZED) return -ENOTSUPP; - r = rndis_add_response (configNr, - sizeof (rndis_indicate_status_msg_type)); + r = rndis_add_response(configNr, + sizeof(rndis_indicate_status_msg_type)); if (!r) return -ENOMEM; - resp = (rndis_indicate_status_msg_type *) r->buf; + resp = (rndis_indicate_status_msg_type *)r->buf; - resp->MessageType = cpu_to_le32 ( - REMOTE_NDIS_INDICATE_STATUS_MSG); - resp->MessageLength = cpu_to_le32 (20); - resp->Status = cpu_to_le32 (status); - resp->StatusBufferLength = cpu_to_le32 (0); - resp->StatusBufferOffset = cpu_to_le32 (0); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_INDICATE_STATUS_MSG); + resp->MessageLength = cpu_to_le32(20); + resp->Status = cpu_to_le32(status); + resp->StatusBufferLength = cpu_to_le32(0); + resp->StatusBufferOffset = cpu_to_le32(0); params->resp_avail(params->v); return 0; } -int rndis_signal_connect (int configNr) +int rndis_signal_connect(int configNr) { - rndis_per_dev_params [configNr].media_state + rndis_per_dev_params[configNr].media_state = NDIS_MEDIA_STATE_CONNECTED; - return rndis_indicate_status_msg (configNr, + return rndis_indicate_status_msg(configNr, RNDIS_STATUS_MEDIA_CONNECT); } -int rndis_signal_disconnect (int configNr) +int rndis_signal_disconnect(int configNr) { - rndis_per_dev_params [configNr].media_state + rndis_per_dev_params[configNr].media_state = NDIS_MEDIA_STATE_DISCONNECTED; - return rndis_indicate_status_msg (configNr, + return rndis_indicate_status_msg(configNr, RNDIS_STATUS_MEDIA_DISCONNECT); } -void rndis_uninit (int configNr) +void rndis_uninit(int configNr) { u8 *buf; u32 length; if (configNr >= RNDIS_MAX_CONFIGS) return; - rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED; + rndis_per_dev_params[configNr].state = RNDIS_UNINITIALIZED; /* drain the response queue */ while ((buf = rndis_get_next_response(configNr, &length))) rndis_free_response(configNr, buf); } -void rndis_set_host_mac (int configNr, const u8 *addr) +void rndis_set_host_mac(int configNr, const u8 *addr) { - rndis_per_dev_params [configNr].host_mac = addr; + rndis_per_dev_params[configNr].host_mac = addr; } /* * Message Parser */ -int rndis_msg_parser (u8 configNr, u8 *buf) +int rndis_msg_parser(u8 configNr, u8 *buf) { u32 MsgType, MsgLength; __le32 *tmp; - struct rndis_params *params; + struct rndis_params *params; if (!buf) return -ENOMEM; - tmp = (__le32 *) buf; + tmp = (__le32 *)buf; MsgType = get_unaligned_le32(tmp++); MsgLength = get_unaligned_le32(tmp++); if (configNr >= RNDIS_MAX_CONFIGS) return -ENOTSUPP; - params = &rndis_per_dev_params [configNr]; + params = &rndis_per_dev_params[configNr]; /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for * rx/tx statistics and link status, in addition to KEEPALIVE traffic @@ -822,41 +820,41 @@ int rndis_msg_parser (u8 configNr, u8 *buf) switch (MsgType) { case REMOTE_NDIS_INITIALIZE_MSG: pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n", - __func__ ); + __func__); params->state = RNDIS_INITIALIZED; - return rndis_init_response (configNr, - (rndis_init_msg_type *) buf); + return rndis_init_response(configNr, + (rndis_init_msg_type *)buf); case REMOTE_NDIS_HALT_MSG: pr_debug("%s: REMOTE_NDIS_HALT_MSG\n", - __func__ ); + __func__); params->state = RNDIS_UNINITIALIZED; if (params->dev) { - netif_carrier_off (params->dev); - netif_stop_queue (params->dev); + netif_carrier_off(params->dev); + netif_stop_queue(params->dev); } return 0; case REMOTE_NDIS_QUERY_MSG: - return rndis_query_response (configNr, - (rndis_query_msg_type *) buf); + return rndis_query_response(configNr, + (rndis_query_msg_type *)buf); case REMOTE_NDIS_SET_MSG: - return rndis_set_response (configNr, - (rndis_set_msg_type *) buf); + return rndis_set_response(configNr, + (rndis_set_msg_type *)buf); case REMOTE_NDIS_RESET_MSG: pr_debug("%s: REMOTE_NDIS_RESET_MSG\n", - __func__ ); - return rndis_reset_response (configNr, - (rndis_reset_msg_type *) buf); + __func__); + return rndis_reset_response(configNr, + (rndis_reset_msg_type *)buf); case REMOTE_NDIS_KEEPALIVE_MSG: /* For USB: host does this every 5 seconds */ if (rndis_debug > 1) pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", - __func__ ); - return rndis_keepalive_response (configNr, + __func__); + return rndis_keepalive_response(configNr, (rndis_keepalive_msg_type *) buf); @@ -866,7 +864,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) * suspending itself. */ pr_warning("%s: unknown RNDIS message 0x%08X len %d\n", - __func__ , MsgType, MsgLength); + __func__, MsgType, MsgLength); { unsigned i; for (i = 0; i < MsgLength; i += 16) { @@ -901,10 +899,10 @@ int rndis_register(void (*resp_avail)(void *v), void *v) return -EINVAL; for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { - if (!rndis_per_dev_params [i].used) { - rndis_per_dev_params [i].used = 1; - rndis_per_dev_params [i].resp_avail = resp_avail; - rndis_per_dev_params [i].v = v; + if (!rndis_per_dev_params[i].used) { + rndis_per_dev_params[i].used = 1; + rndis_per_dev_params[i].resp_avail = resp_avail; + rndis_per_dev_params[i].v = v; pr_debug("%s: configNr = %d\n", __func__, i); return i; } @@ -914,12 +912,12 @@ int rndis_register(void (*resp_avail)(void *v), void *v) return -ENODEV; } -void rndis_deregister (int configNr) +void rndis_deregister(int configNr) { - pr_debug("%s: \n", __func__); + pr_debug("%s:\n", __func__); if (configNr >= RNDIS_MAX_CONFIGS) return; - rndis_per_dev_params [configNr].used = 0; + rndis_per_dev_params[configNr].used = 0; return; } @@ -931,76 +929,76 @@ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) return -EINVAL; if (configNr >= RNDIS_MAX_CONFIGS) return -1; - rndis_per_dev_params [configNr].dev = dev; - rndis_per_dev_params [configNr].filter = cdc_filter; + rndis_per_dev_params[configNr].dev = dev; + rndis_per_dev_params[configNr].filter = cdc_filter; return 0; } -int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr) +int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) { pr_debug("%s:\n", __func__); if (!vendorDescr) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; - rndis_per_dev_params [configNr].vendorID = vendorID; - rndis_per_dev_params [configNr].vendorDescr = vendorDescr; + rndis_per_dev_params[configNr].vendorID = vendorID; + rndis_per_dev_params[configNr].vendorDescr = vendorDescr; return 0; } -int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed) +int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) { pr_debug("%s: %u %u\n", __func__, medium, speed); if (configNr >= RNDIS_MAX_CONFIGS) return -1; - rndis_per_dev_params [configNr].medium = medium; - rndis_per_dev_params [configNr].speed = speed; + rndis_per_dev_params[configNr].medium = medium; + rndis_per_dev_params[configNr].speed = speed; return 0; } -void rndis_add_hdr (struct sk_buff *skb) +void rndis_add_hdr(struct sk_buff *skb) { - struct rndis_packet_msg_type *header; + struct rndis_packet_msg_type *header; if (!skb) return; - header = (void *) skb_push (skb, sizeof *header); - memset (header, 0, sizeof *header); + header = (void *)skb_push(skb, sizeof(*header)); + memset(header, 0, sizeof *header); header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG); header->MessageLength = cpu_to_le32(skb->len); - header->DataOffset = cpu_to_le32 (36); - header->DataLength = cpu_to_le32(skb->len - sizeof *header); + header->DataOffset = cpu_to_le32(36); + header->DataLength = cpu_to_le32(skb->len - sizeof(*header)); } -void rndis_free_response (int configNr, u8 *buf) +void rndis_free_response(int configNr, u8 *buf) { - rndis_resp_t *r; - struct list_head *act, *tmp; + rndis_resp_t *r; + struct list_head *act, *tmp; - list_for_each_safe (act, tmp, - &(rndis_per_dev_params [configNr].resp_queue)) + list_for_each_safe(act, tmp, + &(rndis_per_dev_params[configNr].resp_queue)) { - r = list_entry (act, rndis_resp_t, list); + r = list_entry(act, rndis_resp_t, list); if (r && r->buf == buf) { - list_del (&r->list); - kfree (r); + list_del(&r->list); + kfree(r); } } } -u8 *rndis_get_next_response (int configNr, u32 *length) +u8 *rndis_get_next_response(int configNr, u32 *length) { - rndis_resp_t *r; - struct list_head *act, *tmp; + rndis_resp_t *r; + struct list_head *act, *tmp; if (!length) return NULL; - list_for_each_safe (act, tmp, - &(rndis_per_dev_params [configNr].resp_queue)) + list_for_each_safe(act, tmp, + &(rndis_per_dev_params[configNr].resp_queue)) { - r = list_entry (act, rndis_resp_t, list); + r = list_entry(act, rndis_resp_t, list); if (!r->send) { r->send = 1; *length = r->length; @@ -1011,20 +1009,20 @@ u8 *rndis_get_next_response (int configNr, u32 *length) return NULL; } -static rndis_resp_t *rndis_add_response (int configNr, u32 length) +static rndis_resp_t *rndis_add_response(int configNr, u32 length) { - rndis_resp_t *r; + rndis_resp_t *r; - /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */ - r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC); + /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */ + r = kmalloc(sizeof(rndis_resp_t) + length, GFP_ATOMIC); if (!r) return NULL; - r->buf = (u8 *) (r + 1); + r->buf = (u8 *)(r + 1); r->length = length; r->send = 0; - list_add_tail (&r->list, - &(rndis_per_dev_params [configNr].resp_queue)); + list_add_tail(&r->list, + &(rndis_per_dev_params[configNr].resp_queue)); return r; } @@ -1033,7 +1031,7 @@ int rndis_rm_hdr(struct gether *port, struct sk_buff_head *list) { /* tmp points to a struct rndis_packet_msg_type */ - __le32 *tmp = (void *) skb->data; + __le32 *tmp = (void *)skb->data; /* MessageType, MessageLength */ if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG) @@ -1054,7 +1052,7 @@ int rndis_rm_hdr(struct gether *port, return 0; } -#ifdef CONFIG_USB_GADGET_DEBUG_FILES +#ifdef CONFIG_USB_GADGET_DEBUG_FILES static int rndis_proc_show(struct seq_file *m, void *v) { @@ -1087,7 +1085,7 @@ static int rndis_proc_show(struct seq_file *m, void *v) } static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { rndis_params *p = PDE(file->f_path.dentry->d_inode)->data; u32 speed = 0; @@ -1109,11 +1107,11 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, case '8': case '9': fl_speed = 1; - speed = speed*10 + c - '0'; + speed = speed * 10 + c - '0'; break; case 'C': case 'c': - rndis_signal_connect (p->confignr); + rndis_signal_connect(p->confignr); break; case 'D': case 'd': @@ -1145,11 +1143,11 @@ static const struct file_operations rndis_proc_fops = { .write = rndis_proc_write, }; -#define NAME_TEMPLATE "driver/rndis-%03d" +#define NAME_TEMPLATE "driver/rndis-%03d" static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; -#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ +#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ int rndis_init(void) @@ -1160,42 +1158,40 @@ int rndis_init(void) #ifdef CONFIG_USB_GADGET_DEBUG_FILES char name [20]; - sprintf (name, NAME_TEMPLATE, i); - if (!(rndis_connect_state [i] - = proc_create_data(name, 0660, NULL, + sprintf(name, NAME_TEMPLATE, i); + rndis_connect_state[i] = proc_create_data(name, 0660, NULL, &rndis_proc_fops, - (void *)(rndis_per_dev_params + i)))) - { - pr_debug("%s :remove entries", __func__); + (void *)(rndis_per_dev_params + i)); + if (!rndis_connect_state[i]) { + pr_debug("%s: remove entries", __func__); while (i) { - sprintf (name, NAME_TEMPLATE, --i); - remove_proc_entry (name, NULL); + sprintf(name, NAME_TEMPLATE, --i); + remove_proc_entry(name, NULL); } pr_debug("\n"); return -EIO; } #endif - rndis_per_dev_params [i].confignr = i; - rndis_per_dev_params [i].used = 0; - rndis_per_dev_params [i].state = RNDIS_UNINITIALIZED; - rndis_per_dev_params [i].media_state + rndis_per_dev_params[i].confignr = i; + rndis_per_dev_params[i].used = 0; + rndis_per_dev_params[i].state = RNDIS_UNINITIALIZED; + rndis_per_dev_params[i].media_state = NDIS_MEDIA_STATE_DISCONNECTED; - INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue)); + INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue)); } return 0; } -void rndis_exit (void) +void rndis_exit(void) { -#ifdef CONFIG_USB_GADGET_DEBUG_FILES +#ifdef CONFIG_USB_GADGET_DEBUG_FILES u8 i; - char name [20]; + char name[20]; for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { - sprintf (name, NAME_TEMPLATE, i); - remove_proc_entry (name, NULL); + sprintf(name, NAME_TEMPLATE, i); + remove_proc_entry(name, NULL); } #endif } - diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index a229744a8c7d..ef825c3baed9 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2523,7 +2523,8 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) return 0; } -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct s3c_hsotg *hsotg = our_hsotg; int ret; @@ -2543,7 +2544,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) dev_err(hsotg->dev, "%s: bad speed\n", __func__); } - if (!driver->bind || !driver->setup) { + if (!bind || !driver->setup) { dev_err(hsotg->dev, "%s: missing entry points\n", __func__); return -EINVAL; } @@ -2562,7 +2563,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) goto err; } - ret = driver->bind(&hsotg->gadget); + ret = bind(&hsotg->gadget); if (ret) { dev_err(hsotg->dev, "failed bind %s\n", driver->driver.name); @@ -2687,7 +2688,7 @@ err: hsotg->gadget.dev.driver = NULL; return ret; } -EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index ea2b3c7ebee5..c2448950a8d8 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1632,15 +1632,15 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev) } /* - * usb_gadget_register_driver + * usb_gadget_probe_driver */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) { struct s3c2410_udc *udc = the_controller; int retval; - dprintk(DEBUG_NORMAL, "usb_gadget_register_driver() '%s'\n", - driver->driver.name); + dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name); /* Sanity checks */ if (!udc) @@ -1649,10 +1649,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) if (udc->driver) return -EBUSY; - if (!driver->bind || !driver->setup - || driver->speed < USB_SPEED_FULL) { + if (!bind || !driver->setup || driver->speed < USB_SPEED_FULL) { printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n", - driver->bind, driver->setup, driver->speed); + bind, driver->setup, driver->speed); return -EINVAL; } #if defined(MODULE) @@ -1675,7 +1674,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n", driver->driver.name); - if ((retval = driver->bind (&udc->gadget)) != 0) { + if ((retval = bind(&udc->gadget)) != 0) { device_del(&udc->gadget.dev); goto register_error; } @@ -1690,6 +1689,7 @@ register_error: udc->gadget.dev.driver = NULL; return retval; } +EXPORT_SYMBOL(usb_gadget_probe_driver); /* * usb_gadget_unregister_driver @@ -2049,7 +2049,6 @@ static void __exit udc_exit(void) } EXPORT_SYMBOL(usb_gadget_unregister_driver); -EXPORT_SYMBOL(usb_gadget_register_driver); module_init(udc_init); module_exit(udc_exit); diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index b22eedbc7dc5..1ac57a973aa9 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -137,7 +137,7 @@ MODULE_PARM_DESC(n_ports, "number of ports to create, default=1"); /*-------------------------------------------------------------------------*/ -static int __ref serial_bind_config(struct usb_configuration *c) +static int __init serial_bind_config(struct usb_configuration *c) { unsigned i; int status = 0; @@ -155,13 +155,12 @@ static int __ref serial_bind_config(struct usb_configuration *c) static struct usb_configuration serial_config_driver = { /* .label = f(use_acm) */ - .bind = serial_bind_config, /* .bConfigurationValue = f(use_acm) */ /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; -static int __ref gs_bind(struct usb_composite_dev *cdev) +static int __init gs_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; @@ -225,7 +224,8 @@ static int __ref gs_bind(struct usb_composite_dev *cdev) } /* register our configuration */ - status = usb_add_config(cdev, &serial_config_driver); + status = usb_add_config(cdev, &serial_config_driver, + serial_bind_config); if (status < 0) goto fail; @@ -242,7 +242,6 @@ static struct usb_composite_driver gserial_driver = { .name = "g_serial", .dev = &device_desc, .strings = dev_strings, - .bind = gs_bind, }; static int __init init(void) @@ -271,7 +270,7 @@ static int __init init(void) } strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label; - return usb_composite_register(&gserial_driver); + return usb_composite_probe(&gserial_driver, gs_bind); } module_init(init); diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 484acfb1a7c5..3b513bafaf2a 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -26,7 +26,6 @@ * be defined (each of type pointer to char): * - fsg_string_manufacturer -- name of the manufacturer * - fsg_string_product -- name of the product - * - fsg_string_serial -- product's serial * - fsg_string_config -- name of the configuration * - fsg_string_interface -- name of the interface * The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS @@ -54,6 +53,8 @@ */ +#include <linux/usb/storage.h> +#include <scsi/scsi.h> #include <asm/unaligned.h> @@ -153,23 +154,6 @@ /*-------------------------------------------------------------------------*/ -/* SCSI device types */ -#define TYPE_DISK 0x00 -#define TYPE_CDROM 0x05 - -/* USB protocol value = the transport method */ -#define USB_PR_CBI 0x00 /* Control/Bulk/Interrupt */ -#define USB_PR_CB 0x01 /* Control/Bulk w/o interrupt */ -#define USB_PR_BULK 0x50 /* Bulk-only */ - -/* USB subclass value = the protocol encapsulation */ -#define USB_SC_RBC 0x01 /* Reduced Block Commands (flash) */ -#define USB_SC_8020 0x02 /* SFF-8020i, MMC-2, ATAPI (CD-ROM) */ -#define USB_SC_QIC 0x03 /* QIC-157 (tape) */ -#define USB_SC_UFI 0x04 /* UFI (floppy) */ -#define USB_SC_8070 0x05 /* SFF-8070i (removable) */ -#define USB_SC_SCSI 0x06 /* Transparent SCSI */ - /* Bulk-only data structures */ /* Command Block Wrapper */ @@ -221,33 +205,6 @@ struct interrupt_data { /* Length of a SCSI Command Data Block */ #define MAX_COMMAND_SIZE 16 -/* SCSI commands that we recognize */ -#define SC_FORMAT_UNIT 0x04 -#define SC_INQUIRY 0x12 -#define SC_MODE_SELECT_6 0x15 -#define SC_MODE_SELECT_10 0x55 -#define SC_MODE_SENSE_6 0x1a -#define SC_MODE_SENSE_10 0x5a -#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e -#define SC_READ_6 0x08 -#define SC_READ_10 0x28 -#define SC_READ_12 0xa8 -#define SC_READ_CAPACITY 0x25 -#define SC_READ_FORMAT_CAPACITIES 0x23 -#define SC_READ_HEADER 0x44 -#define SC_READ_TOC 0x43 -#define SC_RELEASE 0x17 -#define SC_REQUEST_SENSE 0x03 -#define SC_RESERVE 0x16 -#define SC_SEND_DIAGNOSTIC 0x1d -#define SC_START_STOP_UNIT 0x1b -#define SC_SYNCHRONIZE_CACHE 0x35 -#define SC_TEST_UNIT_READY 0x00 -#define SC_VERIFY 0x2f -#define SC_WRITE_6 0x0a -#define SC_WRITE_10 0x2a -#define SC_WRITE_12 0xaa - /* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ #define SS_NO_SENSE 0 #define SS_COMMUNICATION_FAILURE 0x040800 @@ -552,7 +509,7 @@ static struct usb_string fsg_strings[] = { #ifndef FSG_NO_DEVICE_STRINGS {FSG_STRING_MANUFACTURER, fsg_string_manufacturer}, {FSG_STRING_PRODUCT, fsg_string_product}, - {FSG_STRING_SERIAL, fsg_string_serial}, + {FSG_STRING_SERIAL, ""}, {FSG_STRING_CONFIG, fsg_string_config}, #endif {FSG_STRING_INTERFACE, fsg_string_interface}, diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index de1deb7a3c63..a5a0fdb808c7 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -308,7 +308,7 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { * USB configuration */ -static int __ref +static int __init webcam_config_bind(struct usb_configuration *c) { return uvc_bind_config(c, uvc_control_cls, uvc_fs_streaming_cls, @@ -317,7 +317,6 @@ webcam_config_bind(struct usb_configuration *c) static struct usb_configuration webcam_config_driver = { .label = webcam_config_label, - .bind = webcam_config_bind, .bConfigurationValue = 1, .iConfiguration = 0, /* dynamic */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, @@ -330,7 +329,7 @@ webcam_unbind(struct usb_composite_dev *cdev) return 0; } -static int __ref +static int __init webcam_bind(struct usb_composite_dev *cdev) { int ret; @@ -354,7 +353,8 @@ webcam_bind(struct usb_composite_dev *cdev) webcam_config_driver.iConfiguration = ret; /* Register our configuration. */ - if ((ret = usb_add_config(cdev, &webcam_config_driver)) < 0) + if ((ret = usb_add_config(cdev, &webcam_config_driver, + webcam_config_bind)) < 0) goto error; INFO(cdev, "Webcam Video Gadget\n"); @@ -373,14 +373,13 @@ static struct usb_composite_driver webcam_driver = { .name = "g_webcam", .dev = &webcam_device_descriptor, .strings = webcam_device_strings, - .bind = webcam_bind, .unbind = webcam_unbind, }; static int __init webcam_init(void) { - return usb_composite_register(&webcam_driver); + return usb_composite_probe(&webcam_driver, webcam_bind); } static void __exit diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index cf353920bb1c..6d16db9d9d2d 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -264,7 +264,7 @@ static void zero_resume(struct usb_composite_dev *cdev) /*-------------------------------------------------------------------------*/ -static int __ref zero_bind(struct usb_composite_dev *cdev) +static int __init zero_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; @@ -340,7 +340,6 @@ static struct usb_composite_driver zero_driver = { .name = "zero", .dev = &device_desc, .strings = dev_strings, - .bind = zero_bind, .unbind = zero_unbind, .suspend = zero_suspend, .resume = zero_resume, @@ -351,7 +350,7 @@ MODULE_LICENSE("GPL"); static int __init init(void) { - return usb_composite_register(&zero_driver); + return usb_composite_probe(&zero_driver, zero_bind); } module_init(init); |