Re: Linux USB file storage gadget with new UDC
Hi, >> > you should an interrupt handler to handle interrupts from your device. >> > Also, there are way too many mistakes on your driver, run checkpatch.pl, >> > compile it with sparse, don't hardcode addresses, don't reimplement a >> > bunch of infrastructure the kernel already gives you and check your >> > list_head usage! >> >> I have run checkpatch.pl and read the linux/usb/gadget.h. The Soc >> interrupt controller has problem, so i use a kernel thread to read >> from USB controller directly. >> >> > don't reimplement a bunch of infrastructure the kernel already gives you >> i don't understand this. please kindly show an example. > > #define IO_OFFSET 0x5500 > #define __IO_ADDRESS(x) ((x) + IO_OFFSET) > > #define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa)) > > #ifdef IOMEM // Override asm/io.h > #undef IOMEM > #endif // IOMEM > #ifdef __ASSEMBLER__ > #define IOMEM(x)x > #else > #define IOMEM(x)((void __force __iomem *)(x)) > #endif > > none of this should be in the driver. this can be removed. >> > Also, you shouldn't requeue the request yourself, gadget driver owns the >> > request. >> which request do i requeue? please kindly point that out. Thanks! > > look at your code. Look what you do after you call complete. is it this code? i will remove the redundant code after complete. ka_ep_p->req.complete(&ka_ep_p->ep, &req->req); if (num == 0) { ka_ep_p->req.length = 0; usb_ep_queue(&ka_ep_p->ep, &req->req, 0); ka_ep_p->desc = &ep0_in_desc; } i read the net2272.c, the net2272_enable() is called by gadget driver enable_endpoint(). When i run the gadget driver, enable_endpoint() is called for fsg->bulk_in and fsg->bulk_out. The enable_endpoint() of fsg->intr_in is not called because transport_is_cbi() is false. So how can the endpoint 0 be enabled? thanks, victor -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: USB subsystem stops working
On Thu, Jan 24, 2013 at 2:19 PM, Peter Chen wrote: > > My puzzle is after calling usb_autopm_get_interface_no_resume() at kick_khubd > the dev->power.usage_count is 1, when the hub's suspend will be called? usb_autopm_put_interface() will decrease the counter and trigger auto-suspend, then hub_suspend() is called. Thanks, -- Ming Lei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 00/20] OMAP USB Host cleanup
On 01/23/2013 05:26 PM, Alan Stern wrote: > On Wed, 23 Jan 2013, Roger Quadros wrote: > >> Hi Samuel, >> >> I think this series is in a pretty good shape to pull now :). I've added >> Reviewed-by and Acked-by tags. You can please pull from below. >> >> NOTE: the first patch is a stable fix so Greg KH might want to pick it up >> for 3.8-rc. >> >> The following changes since commit 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619: >> >> Linux 3.8-rc4 (2013-01-17 19:25:45 -0800) >> >> are available in the git repository at: >> git://github.com/rogerq/linux.git linux-usbhost14-part >> >> This patchset addresses the following >> >> - Consolidate USB Host platform data. >> - Avoid addressing clocks one by one by name and use a for loop + bunch >> of cleanups. >> - Get number of channels/ports dynamically either from revision register >> or from platform data. Avoids getting clocks that are not present. >> - Add OMAP5 and HSIC mode (Not tested). > > Roger: > > I haven't yet submitted the patch splitting ehci-omap apart from > ehci-hcd. Will this interfere with your work? Or is it a > prerequisite? No Alan, it shouldn't be a problem for this series. > > How would you like to handle this? I'm sending another series that takes care of moving PHY management code out of omap-ehci. I can include your ehci-omap split patch in that series if you like. cheers, -roger -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 20/20] mdf: omap-usb-host: get rid of build warning
On 01/24/2013 01:36 AM, Mike Turquette wrote: > Quoting Roger Quadros (2013-01-23 02:38:12) >> Fixes the below build warning when driver is built-in. >> >> drivers/mfd/omap-usb-host.c:750:12: warning: >> ‘usbhs_omap_remove’ defined but not used [-Wunused-function] >> >> Signed-off-by: Roger Quadros >> Reviewed-by: Felipe Balbi > > Hi Roger, > > I just noticed that $SUBJECT says "mdf" instead of "mfd" ;) > Thanks Mike. I've fixed it in the pull request and i'll mail a patch as well. cheers, -roger. > >> --- >> drivers/mfd/omap-usb-host.c |2 +- >> 1 files changed, 1 insertions(+), 1 deletions(-) >> >> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c >> index b21ca76..6b5edf6 100644 >> --- a/drivers/mfd/omap-usb-host.c >> +++ b/drivers/mfd/omap-usb-host.c >> @@ -791,7 +791,7 @@ static struct platform_driver usbhs_omap_driver = { >> .owner = THIS_MODULE, >> .pm = &usbhsomap_dev_pm_ops, >> }, >> - .remove = __exit_p(usbhs_omap_remove), >> + .remove = usbhs_omap_remove, >> }; >> >> MODULE_AUTHOR("Keshava Munegowda "); >> -- >> 1.7.4.1 >> >> >> ___ >> linux-arm-kernel mailing list >> linux-arm-ker...@lists.infradead.org >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/8] usb: gadget: adm5536udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/amd5536udc.c | 59 ++--- drivers/usb/gadget/amd5536udc.h | 2 ++ 2 files changed, 16 insertions(+), 45 deletions(-) diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index fc0ec5e..3dac001 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -1400,15 +1400,16 @@ static int udc_wakeup(struct usb_gadget *gadget) return 0; } -static int amd5536_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int amd5536_stop(struct usb_gadget_driver *driver); +static int amd5536_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int amd5536_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); /* gadget operations */ static const struct usb_gadget_ops udc_ops = { .wakeup = udc_wakeup, .get_frame = udc_get_frame, - .start = amd5536_start, - .stop = amd5536_stop, + .udc_start = amd5536_udc_start, + .udc_stop = amd5536_udc_stop, }; /* Setups endpoint parameters, adds endpoints to linked list */ @@ -1913,41 +1914,22 @@ static int setup_ep0(struct udc *dev) } /* Called by gadget driver to register itself */ -static int amd5536_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int amd5536_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct udc *dev = udc; - int retval; + struct udc *dev = to_amd5536_udc(g); u32 tmp; - if (!driver || !bind || !driver->setup - || driver->max_speed < USB_SPEED_HIGH) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; - driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - retval = bind(&dev->gadget, driver); - /* Some gadget drivers use both ep0 directions. * NOTE: to gadget driver, ep0 is just one endpoint... */ dev->ep[UDC_EP0OUT_IX].ep.driver_data = dev->ep[UDC_EP0IN_IX].ep.driver_data; - if (retval) { - DBG(dev, "binding to %s returning %d\n", - driver->driver.name, retval); - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - /* get ready for ep0 traffic */ setup_ep0(dev); @@ -1969,14 +1951,9 @@ __acquires(dev->lock) { int tmp; - if (dev->gadget.speed != USB_SPEED_UNKNOWN) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - /* empty queues and init hardware */ udc_basic_init(dev); + for (tmp = 0; tmp < UDC_EP_NUM; tmp++) empty_req_queue(&dev->ep[tmp]); @@ -1984,23 +1961,18 @@ __acquires(dev->lock) } /* Called by gadget driver to unregister itself */ -static int amd5536_stop(struct usb_gadget_driver *driver) +static int amd5536_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct udc *dev = udc; - unsigned long flags; + struct udc *dev = to_amd5536_udc(g); + unsigned long flags; u32 tmp; - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; - spin_lock_irqsave(&dev->lock, flags); udc_mask_unused_interrupts(dev); shutdown(dev, driver); spin_unlock_irqrestore(&dev->lock, flags); - driver->unbind(&dev->gadget); dev->gadget.dev.driver = NULL; dev->driver = NULL; @@ -2009,9 +1981,6 @@ static int amd5536_stop(struct usb_gadget_driver *driver) tmp |= AMD_BIT(UDC_DEVCTL_SD); writel(tmp, &dev->regs->ctl); - - DBG(dev, "%s: unregistered\n", driver->driver.name); - return 0; } diff --git a/drivers/usb/gadget/amd5536udc.h b/drivers/usb/gadget/amd5536udc.h index 14af87d..f1bf32e 100644 --- a/drivers/usb/gadget/amd5536udc.h +++ b/drivers/usb/gadget/amd5536udc.h @@ -563,6 +563,8 @@ struct udc { u16 cur_alt; }; +#define to_amd5536_udc(g) (container_of((g), struct udc, gadget)) + /* setup request data */ union udc_setup_data { u32 data[2]; -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.
[PATCH 2/8] usb: gadget: fusb300_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fusb300_udc.c | 65 +++- drivers/usb/gadget/fusb300_udc.h | 2 ++ 2 files changed, 20 insertions(+), 47 deletions(-) diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 72cd5e6..8c2372f 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1308,65 +1308,28 @@ static void init_controller(struct fusb300 *fusb300) iowrite32(0xcf9f, fusb300->reg + FUSB300_OFFSET_IGER1); } /**/ -static struct fusb300 *the_controller; - -static int fusb300_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int fusb300_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct fusb300 *fusb300 = the_controller; - int retval; - - if (!driver - || driver->max_speed < USB_SPEED_FULL - || !bind - || !driver->setup) - return -EINVAL; - - if (!fusb300) - return -ENODEV; - - if (fusb300->driver) - return -EBUSY; + struct fusb300 *fusb300 = to_fusb300(g); /* hook up the driver */ driver->driver.bus = NULL; fusb300->driver = driver; fusb300->gadget.dev.driver = &driver->driver; - retval = device_add(&fusb300->gadget.dev); - if (retval) { - pr_err("device_add error (%d)\n", retval); - goto error; - } - - retval = bind(&fusb300->gadget, driver); - if (retval) { - pr_err("bind to driver error (%d)\n", retval); - device_del(&fusb300->gadget.dev); - goto error; - } - return 0; - -error: - fusb300->driver = NULL; - fusb300->gadget.dev.driver = NULL; - - return retval; } -static int fusb300_udc_stop(struct usb_gadget_driver *driver) +static int fusb300_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct fusb300 *fusb300 = the_controller; - - if (driver != fusb300->driver || !driver->unbind) - return -EINVAL; + struct fusb300 *fusb300 = to_fusb300(g); driver->unbind(&fusb300->gadget); fusb300->gadget.dev.driver = NULL; init_controller(fusb300); - device_del(&fusb300->gadget.dev); fusb300->driver = NULL; return 0; @@ -1380,8 +1343,8 @@ static int fusb300_udc_pullup(struct usb_gadget *_gadget, int is_active) static struct usb_gadget_ops fusb300_gadget_ops = { .pullup = fusb300_udc_pullup, - .start = fusb300_udc_start, - .stop = fusb300_udc_stop, + .udc_start = fusb300_udc_start, + .udc_stop = fusb300_udc_stop, }; static int __exit fusb300_remove(struct platform_device *pdev) @@ -1505,8 +1468,6 @@ static int __init fusb300_probe(struct platform_device *pdev) fusb300->gadget.ep0 = &fusb300->ep[0]->ep; INIT_LIST_HEAD(&fusb300->gadget.ep0->ep_list); - the_controller = fusb300; - fusb300->ep0_req = fusb300_alloc_request(&fusb300->ep[0]->ep, GFP_KERNEL); if (fusb300->ep0_req == NULL) @@ -1517,9 +1478,19 @@ static int __init fusb300_probe(struct platform_device *pdev) if (ret) goto err_add_udc; + ret = device_add(&fusb300->gadget.dev); + if (ret) { + pr_err("device_add error (%d)\n", ret); + goto err_add_device; + } + dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); return 0; + +err_add_device: + usb_del_gadget_udc(&fusb300->gadget); + err_add_udc: fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); diff --git a/drivers/usb/gadget/fusb300_udc.h b/drivers/usb/gadget/fusb300_udc.h index 542cd83..6ba444a 100644 --- a/drivers/usb/gadget/fusb300_udc.h +++ b/drivers/usb/gadget/fusb300_udc.h @@ -673,4 +673,6 @@ struct fusb300 { u8 reenum; /* if re-enumeration */ }; +#define to_fusb300(g) (container_of((g), struct fusb300, gadget)) + #endif -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/8] usb: gadget: goku_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/goku_udc.c | 70 +-- drivers/usb/gadget/goku_udc.h | 1 + 2 files changed, 15 insertions(+), 56 deletions(-) diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 51037cb..85742d4 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -993,14 +993,15 @@ static int goku_get_frame(struct usb_gadget *_gadget) return -EOPNOTSUPP; } -static int goku_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int goku_stop(struct usb_gadget_driver *driver); +static int goku_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int goku_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops goku_ops = { .get_frame = goku_get_frame, - .start = goku_start, - .stop = goku_stop, + .udc_start = goku_udc_start, + .udc_stop = goku_udc_stop, // no remote wakeup // not selfpowered }; @@ -1339,50 +1340,28 @@ static void udc_enable(struct goku_udc *dev) * - one function driver, initted second */ -static struct goku_udc *the_controller; - /* when a driver is successfully registered, it will receive * control requests including set_configuration(), which enables * non-control requests. then usb traffic follows until a * disconnect is reported. then a host may connect again, or * the driver might get unbound. */ -static int goku_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int goku_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct goku_udc *dev = the_controller; - int retval; - - if (!driver - || driver->max_speed < USB_SPEED_FULL - || !bind - || !driver->disconnect - || !driver->setup) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; + struct goku_udc *dev = to_goku_udc(g); /* hook up the driver */ driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - retval = bind(&dev->gadget, driver); - if (retval) { - DBG(dev, "bind to driver %s --> error %d\n", - driver->driver.name, retval); - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - /* then enable host detection and ep0; and we're ready + /* +* then enable host detection and ep0; and we're ready * for set_configuration as well as eventual disconnect. */ udc_enable(dev); - DBG(dev, "registered gadget driver '%s'\n", driver->driver.name); return 0; } @@ -1400,35 +1379,23 @@ stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver) udc_reset (dev); for (i = 0; i < 4; i++) nuke(&dev->ep [i], -ESHUTDOWN); - if (driver) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } if (dev->driver) udc_enable(dev); } -static int goku_stop(struct usb_gadget_driver *driver) +static int goku_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct goku_udc *dev = the_controller; + struct goku_udc *dev = to_goku_udc(g); unsigned long flags; - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; - spin_lock_irqsave(&dev->lock, flags); dev->driver = NULL; stop_activity(dev, driver); spin_unlock_irqrestore(&dev->lock, flags); - - driver->unbind(&dev->gadget); dev->gadget.dev.driver = NULL; - DBG(dev, "unregistered driver '%s'\n", driver->driver.name); return 0; } @@ -1754,7 +1721,6 @@ static void goku_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); dev->regs = NULL; - the_controller = NULL; INFO(dev, "unbind\n"); } @@ -1770,13 +1736,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) void __iomem*base = NULL; int retval; - /* if you want to support more than one controller in a system, -* usb_gadget_driver_{register,unregister}() must change. -
[PATCH 4/8] usb: gadget: fsl_udc_core: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 58 --- 1 file changed, 11 insertions(+), 47 deletions(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index c19f7f1..49642d4 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1254,9 +1254,10 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) return 0; } -static int fsl_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int fsl_stop(struct usb_gadget_driver *driver); +static int fsl_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int fsl_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); /* defined in gadget.h */ static struct usb_gadget_ops fsl_gadget_ops = { .get_frame = fsl_get_frame, @@ -1265,8 +1266,8 @@ static struct usb_gadget_ops fsl_gadget_ops = { .vbus_session = fsl_vbus_session, .vbus_draw = fsl_vbus_draw, .pullup = fsl_pullup, - .start = fsl_start, - .stop = fsl_stop, + .udc_start = fsl_udc_start, + .udc_stop = fsl_udc_stop, }; /* Set protocol stall on ep0, protocol stall will automatically be cleared @@ -1950,22 +1951,12 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) * Hook to gadget drivers * Called by initialization code of gadget drivers **/ -static int fsl_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int fsl_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - int retval = -ENODEV; + int retval = 0; unsigned long flags = 0; - if (!udc_controller) - return -ENODEV; - - if (!driver || driver->max_speed < USB_SPEED_FULL - || !bind || !driver->disconnect || !driver->setup) - return -EINVAL; - - if (udc_controller->driver) - return -EBUSY; - /* lock is needed but whether should use this lock or another */ spin_lock_irqsave(&udc_controller->lock, flags); @@ -1975,15 +1966,6 @@ static int fsl_start(struct usb_gadget_driver *driver, udc_controller->gadget.dev.driver = &driver->driver; spin_unlock_irqrestore(&udc_controller->lock, flags); - /* bind udc driver to gadget driver */ - retval = bind(&udc_controller->gadget, driver); - if (retval) { - VDBG("bind to %s --> %d", driver->driver.name, retval); - udc_controller->gadget.dev.driver = NULL; - udc_controller->driver = NULL; - goto out; - } - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { /* Suspend the controller until OTG enable it */ udc_controller->stopped = 1; @@ -2009,28 +1991,17 @@ static int fsl_start(struct usb_gadget_driver *driver, udc_controller->ep0_state = WAIT_FOR_SETUP; udc_controller->ep0_dir = 0; } - printk(KERN_INFO "%s: bind to driver %s\n", - udc_controller->gadget.name, driver->driver.name); -out: - if (retval) - printk(KERN_WARNING "gadget driver register failed %d\n", - retval); return retval; } /* Disconnect from gadget driver */ -static int fsl_stop(struct usb_gadget_driver *driver) +static int fsl_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { struct fsl_ep *loop_ep; unsigned long flags; - if (!udc_controller) - return -ENODEV; - - if (!driver || driver != udc_controller->driver || !driver->unbind) - return -EINVAL; - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) otg_set_peripheral(udc_controller->transceiver->otg, NULL); @@ -2051,16 +2022,9 @@ static int fsl_stop(struct usb_gadget_driver *driver) nuke(loop_ep, -ESHUTDOWN); spin_unlock_irqrestore(&udc_controller->lock, flags); - /* report disconnect; the controller is already quiesced */ - driver->disconnect(&udc_controller->gadget); - - /* unbind gadget and unhook driver. */ - driver->unbind(&udc_controller->gadget); udc_controller->gadget.dev.driver = NULL; udc_controller->driver = NULL; - printk(KERN_WARNING "unregistered gadget driver '%s'\n", - driver->driver.name); return 0; } -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http:/
[PATCH 5/8] usb: gadget: m66592-udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/m66592-udc.c | 70 +++-- drivers/usb/gadget/m66592-udc.h | 1 + 2 files changed, 20 insertions(+), 51 deletions(-) diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index b6401f1..0a35db1 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1463,42 +1463,16 @@ static struct usb_ep_ops m66592_ep_ops = { }; /*-*/ -static struct m66592 *the_controller; - -static int m66592_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int m66592_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct m66592 *m66592 = the_controller; - int retval; - - if (!driver - || driver->max_speed < USB_SPEED_HIGH - || !bind - || !driver->setup) - return -EINVAL; - if (!m66592) - return -ENODEV; - if (m66592->driver) - return -EBUSY; + struct m66592 *m66592 = to_m66592(g); /* hook up the driver */ driver->driver.bus = NULL; m66592->driver = driver; m66592->gadget.dev.driver = &driver->driver; - retval = device_add(&m66592->gadget.dev); - if (retval) { - pr_err("device_add error (%d)\n", retval); - goto error; - } - - retval = bind(&m66592->gadget, driver); - if (retval) { - pr_err("bind to driver error (%d)\n", retval); - device_del(&m66592->gadget.dev); - goto error; - } - m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); if (m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS) { m66592_start_xclock(m66592); @@ -1510,26 +1484,12 @@ static int m66592_start(struct usb_gadget_driver *driver, } return 0; - -error: - m66592->driver = NULL; - m66592->gadget.dev.driver = NULL; - - return retval; } -static int m66592_stop(struct usb_gadget_driver *driver) +static int m66592_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct m66592 *m66592 = the_controller; - unsigned long flags; - - if (driver != m66592->driver || !driver->unbind) - return -EINVAL; - - spin_lock_irqsave(&m66592->lock, flags); - if (m66592->gadget.speed != USB_SPEED_UNKNOWN) - m66592_usb_disconnect(m66592); - spin_unlock_irqrestore(&m66592->lock, flags); + struct m66592 *m66592 = to_m66592(g); m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); @@ -1539,8 +1499,8 @@ static int m66592_stop(struct usb_gadget_driver *driver) init_controller(m66592); disable_controller(m66592); - device_del(&m66592->gadget.dev); m66592->driver = NULL; + return 0; } @@ -1568,8 +1528,8 @@ static int m66592_pullup(struct usb_gadget *gadget, int is_on) static struct usb_gadget_ops m66592_gadget_ops = { .get_frame = m66592_get_frame, - .start = m66592_start, - .stop = m66592_stop, + .udc_start = m66592_udc_start, + .udc_stop = m66592_udc_stop, .pullup = m66592_pullup, }; @@ -1578,6 +1538,7 @@ static int __exit m66592_remove(struct platform_device *pdev) struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); usb_del_gadget_udc(&m66592->gadget); + device_del(&m66592->gadget.dev); del_timer_sync(&m66592->timer); iounmap(m66592->reg); @@ -1706,8 +1667,6 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->pipenum2ep[0] = &m66592->ep[0]; m66592->epaddr2ep[0] = &m66592->ep[0]; - the_controller = m66592; - m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); if (m66592->ep0_req == NULL) goto clean_up3; @@ -1715,6 +1674,12 @@ static int __init m66592_probe(struct platform_device *pdev) init_controller(m66592); + ret = device_add(&m66592->gadget.dev); + if (ret) { + pr_err("device_add error (%d)\n", ret); + goto err_device_add; + } + ret = usb_add_gadget_udc(&pdev->dev, &m66592->gadget); if (ret) goto err_add_udc; @@ -1723,6 +1688,9 @@ static int __init m66592_probe(struct platform_device *pdev) return 0; err_add_udc: + device_del(&m66592->gadget.dev); + +err_device_add: m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); clea
[PATCH 7/8] usb: gadget: pch_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 67 +--- 1 file changed, 14 insertions(+), 53 deletions(-) diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 6490c00..a787a8e 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -375,6 +375,7 @@ struct pch_udc_dev { struct pch_udc_cfg_data cfg_data; struct pch_vbus_gpio_data vbus_gpio; }; +#define to_pch_udc(g) (container_of((g), struct pch_udc_dev, gadget)) #define PCH_UDC_PCI_BAR1 #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 @@ -384,7 +385,6 @@ struct pch_udc_dev { static const char ep0_string[] = "ep0in"; static DEFINE_SPINLOCK(udc_stall_spinlock);/* stall spin lock */ -struct pch_udc_dev *pch_udc; /* pointer to device object */ static bool speed_fs; module_param_named(speed_fs, speed_fs, bool, S_IRUGO); MODULE_PARM_DESC(speed_fs, "true for Full speed operation"); @@ -1235,9 +1235,10 @@ static int pch_udc_pcd_vbus_draw(struct usb_gadget *gadget, unsigned int mA) return -EOPNOTSUPP; } -static int pch_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int pch_udc_stop(struct usb_gadget_driver *driver); +static int pch_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int pch_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops pch_udc_ops = { .get_frame = pch_udc_pcd_get_frame, .wakeup = pch_udc_pcd_wakeup, @@ -1245,8 +1246,8 @@ static const struct usb_gadget_ops pch_udc_ops = { .pullup = pch_udc_pcd_pullup, .vbus_session = pch_udc_pcd_vbus_session, .vbus_draw = pch_udc_pcd_vbus_draw, - .start = pch_udc_start, - .stop = pch_udc_stop, + .udc_start = pch_udc_start, + .udc_stop = pch_udc_stop, }; /** @@ -2981,40 +2982,15 @@ static int init_dma_pools(struct pch_udc_dev *dev) return 0; } -static int pch_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int pch_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pch_udc_dev *dev = pch_udc; - int retval; - - if (!driver || (driver->max_speed == USB_SPEED_UNKNOWN) || !bind || - !driver->setup || !driver->unbind || !driver->disconnect) { - dev_err(&dev->pdev->dev, - "%s: invalid driver parameter\n", __func__); - return -EINVAL; - } + struct pch_udc_dev *dev = to_pch_udc(g); - if (!dev) - return -ENODEV; - - if (dev->driver) { - dev_err(&dev->pdev->dev, "%s: already bound\n", __func__); - return -EBUSY; - } driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - /* Invoke the bind routine of the gadget driver */ - retval = bind(&dev->gadget, driver); - - if (retval) { - dev_err(&dev->pdev->dev, "%s: binding to %s returning %d\n", - __func__, driver->driver.name, retval); - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } /* get ready for ep0 traffic */ pch_udc_setup_ep0(dev); @@ -3026,30 +3002,21 @@ static int pch_udc_start(struct usb_gadget_driver *driver, return 0; } -static int pch_udc_stop(struct usb_gadget_driver *driver) +static int pch_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pch_udc_dev *dev = pch_udc; - - if (!dev) - return -ENODEV; - - if (!driver || (driver != dev->driver)) { - dev_err(&dev->pdev->dev, - "%s: invalid driver parameter\n", __func__); - return -EINVAL; - } + struct pch_udc_dev *dev = to_pch_udc(g); pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); /* Assures that there are no pending requests with this driver */ - driver->disconnect(&dev->gadget); - driver->unbind(&dev->gadget); dev->gadget.dev.driver = NULL; dev->driver = NULL; dev->connected = 0; /* set SD */ pch_udc_set_disconnect(dev); + return 0; } @@ -3164,11 +3131,6 @@ static int pch_udc_probe(struct pci_dev *pdev, int retval; struct pch_udc_dev *dev; - /* one udc only */ - if (pch_udc) { - pr_err("%s: already probed\n", __func__); - return -E
[PATCH 8/8] usb: gadget: completely remove ->start/->stop
Those have been deprecated for a long time and previous patches just converted all remaining users of those. Since there are no in-tree users and we don't want any new users for them, let's obliterate every piece of code related to those calls. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 89 +++ include/linux/usb/gadget.h| 6 --- 2 files changed, 14 insertions(+), 81 deletions(-) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index e7c5916..2a9cd36 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -102,28 +102,6 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); /* - */ /** - * usb_gadget_start - tells usb device controller to start up - * @gadget: The gadget we want to get started - * @driver: The driver we want to bind to @gadget - * @bind: The bind function for @driver - * - * This call is issued by the UDC Class driver when it's about - * to register a gadget driver to the device controller, before - * calling gadget driver's bind() method. - * - * It allows the controller to be powered off until strictly - * necessary to have it powered on. - * - * Returns zero on success, else negative errno. - */ -static inline int usb_gadget_start(struct usb_gadget *gadget, - struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) -{ - return gadget->ops->start(driver, bind); -} - -/** * usb_gadget_udc_start - tells usb device controller to start up * @gadget: The gadget we want to get started * @driver: The driver we want to bind to @gadget @@ -144,24 +122,6 @@ static inline int usb_gadget_udc_start(struct usb_gadget *gadget, } /** - * usb_gadget_stop - tells usb device controller we don't need it anymore - * @gadget: The device we want to stop activity - * @driver: The driver to unbind from @gadget - * - * This call is issued by the UDC Class driver after calling - * gadget driver's unbind() method. - * - * The details are implementation specific, but it can go as - * far as powering off UDC completely and disable its data - * line pullups. - */ -static inline void usb_gadget_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) -{ - gadget->ops->stop(driver); -} - -/** * usb_gadget_udc_stop - tells usb device controller we don't need it anymore * @gadget: The device we want to stop activity * @driver: The driver to unbind from @gadget @@ -246,14 +206,6 @@ err1: } EXPORT_SYMBOL_GPL(usb_add_gadget_udc); -static int udc_is_newstyle(struct usb_udc *udc) -{ - if (udc->gadget->ops->udc_start && udc->gadget->ops->udc_stop) - return 1; - return 0; -} - - static void usb_gadget_remove_driver(struct usb_udc *udc) { dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", @@ -261,14 +213,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); - if (udc_is_newstyle(udc)) { - usb_gadget_disconnect(udc->gadget); - udc->driver->disconnect(udc->gadget); - udc->driver->unbind(udc->gadget); - usb_gadget_udc_stop(udc->gadget, udc->driver); - } else { - usb_gadget_stop(udc->gadget, udc->driver); - } + usb_gadget_disconnect(udc->gadget); + udc->driver->disconnect(udc->gadget); + udc->driver->unbind(udc->gadget); + usb_gadget_udc_stop(udc->gadget, udc->driver); udc->driver = NULL; udc->dev.driver = NULL; @@ -321,22 +269,15 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri udc->driver = driver; udc->dev.driver = &driver->driver; - if (udc_is_newstyle(udc)) { - ret = driver->bind(udc->gadget, driver); - if (ret) - goto err1; - ret = usb_gadget_udc_start(udc->gadget, driver); - if (ret) { - driver->unbind(udc->gadget); - goto err1; - } - usb_gadget_connect(udc->gadget); - } else { - - ret = usb_gadget_start(udc->gadget, driver, driver->bind); - if (ret) - goto err1; + ret = driver->bind(udc->gadget, driver); + if (ret) + goto err1; + ret = usb_gadget_udc_start(udc->gadget, driver); + if (ret) { + driver->unbind(udc->gadget); + goto err1; } + usb_gadget_connect(udc->gadget); kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); return 0; @@ -440,13 +381,11 @@ static ssize_t usb_udc_softconn_store(struct device *dev, struct usb_udc *udc = container_of(dev, struct usb_udc, dev); if (sysfs_streq(buf, "connect")) { -
[PATCH 6/8] usb: gadget: omap_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 49 +++ 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 8bfe990..d0c87b1 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -1309,9 +1309,10 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on) return 0; } -static int omap_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int omap_udc_stop(struct usb_gadget_driver *driver); +static int omap_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) +static int omap_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static struct usb_gadget_ops omap_gadget_ops = { .get_frame = omap_get_frame, @@ -1320,8 +1321,8 @@ static struct usb_gadget_ops omap_gadget_ops = { .vbus_session = omap_vbus_session, .vbus_draw = omap_vbus_draw, .pullup = omap_pullup, - .start = omap_udc_start, - .stop = omap_udc_stop, + .udc_start = omap_udc_start, + .udc_stop = omap_udc_stop, }; /*-*/ @@ -2041,28 +2042,15 @@ static inline int machine_without_vbus_sense(void) || cpu_is_omap7xx(); } -static int omap_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int omap_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { int status = -ENODEV; struct omap_ep *ep; unsigned long flags; - /* basic sanity tests */ - if (!udc) - return -ENODEV; - if (!driver - /* FIXME if otg, check: driver->is_otg */ - || driver->max_speed < USB_SPEED_FULL - || !bind || !driver->setup) - return -EINVAL; spin_lock_irqsave(&udc->lock, flags); - if (udc->driver) { - spin_unlock_irqrestore(&udc->lock, flags); - return -EBUSY; - } - /* reset state */ list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { ep->irqs = 0; @@ -2084,15 +2072,6 @@ static int omap_udc_start(struct usb_gadget_driver *driver, if (udc->dc_clk != NULL) omap_udc_enable_clock(1); - status = bind(&udc->gadget, driver); - if (status) { - DBG("bind to %s --> %d\n", driver->driver.name, status); - udc->gadget.dev.driver = NULL; - udc->driver = NULL; - goto done; - } - DBG("bound to driver %s\n", driver->driver.name); - omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC); /* connect to bus through transceiver */ @@ -2124,19 +2103,16 @@ static int omap_udc_start(struct usb_gadget_driver *driver, done: if (udc->dc_clk != NULL) omap_udc_enable_clock(0); + return status; } -static int omap_udc_stop(struct usb_gadget_driver *driver) +static int omap_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { unsigned long flags; int status = -ENODEV; - if (!udc) - return -ENODEV; - if (!driver || driver != udc->driver || !driver->unbind) - return -EINVAL; - if (udc->dc_clk != NULL) omap_udc_enable_clock(1); @@ -2152,13 +2128,12 @@ static int omap_udc_stop(struct usb_gadget_driver *driver) udc_quiesce(udc); spin_unlock_irqrestore(&udc->lock, flags); - driver->unbind(&udc->gadget); udc->gadget.dev.driver = NULL; udc->driver = NULL; if (udc->dc_clk != NULL) omap_udc_enable_clock(0); - DBG("unregistered driver '%s'\n", driver->driver.name); + return status; } -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Linux USB file storage gadget with new UDC
Hi, On Thu, Jan 24, 2013 at 04:25:24PM +0800, victor yeo wrote: > Hi, > > >> > you should an interrupt handler to handle interrupts from your device. > >> > Also, there are way too many mistakes on your driver, run checkpatch.pl, > >> > compile it with sparse, don't hardcode addresses, don't reimplement a > >> > bunch of infrastructure the kernel already gives you and check your > >> > list_head usage! > >> > >> I have run checkpatch.pl and read the linux/usb/gadget.h. The Soc > >> interrupt controller has problem, so i use a kernel thread to read > >> from USB controller directly. > >> > >> > don't reimplement a bunch of infrastructure the kernel already gives you > >> i don't understand this. please kindly show an example. > > > > #define IO_OFFSET 0x5500 > > #define __IO_ADDRESS(x) ((x) + IO_OFFSET) > > > > #define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa)) > > > > #ifdef IOMEM // Override asm/io.h > > #undef IOMEM > > #endif // IOMEM > > #ifdef __ASSEMBLER__ > > #define IOMEM(x)x > > #else > > #define IOMEM(x)((void __force __iomem *)(x)) > > #endif > > > > none of this should be in the driver. > > this can be removed. > > >> > Also, you shouldn't requeue the request yourself, gadget driver owns the > >> > request. > >> which request do i requeue? please kindly point that out. Thanks! > > > > look at your code. Look what you do after you call complete. > > is it this code? i will remove the redundant code after complete. > > ka_ep_p->req.complete(&ka_ep_p->ep, &req->req); > if (num == 0) { > ka_ep_p->req.length = 0; > usb_ep_queue(&ka_ep_p->ep, &req->req, 0); > ka_ep_p->desc = &ep0_in_desc; > } you should delete the request from your list. Whatever you do, has to be undone. > i read the net2272.c, the net2272_enable() is called by gadget driver > enable_endpoint(). When i run the gadget driver, enable_endpoint() is > called for fsg->bulk_in and fsg->bulk_out. The enable_endpoint() of > fsg->intr_in is not called because transport_is_cbi() is false. So > how can the endpoint 0 be enabled? endpoint 0 has to be always enabled by the UDC driver. Gadget driver expects endpoint 0 to be ready. -- balbi signature.asc Description: Digital signature
[PATCH v10 20/20] mfd: omap-usb-host: get rid of build warning
Fixes the below build warning when driver is built-in. drivers/mfd/omap-usb-host.c:750:12: warning: ‘usbhs_omap_remove’ defined but not used [-Wunused-function] Signed-off-by: Roger Quadros Reviewed-by: Felipe Balbi --- drivers/mfd/omap-usb-host.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index b21ca76..6b5edf6 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -791,7 +791,7 @@ static struct platform_driver usbhs_omap_driver = { .owner = THIS_MODULE, .pm = &usbhsomap_dev_pm_ops, }, - .remove = __exit_p(usbhs_omap_remove), + .remove = usbhs_omap_remove, }; MODULE_AUTHOR("Keshava Munegowda "); -- 1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [V5 PATCH 07/26] usb: gadget: mv_udc: make mv_udc depends on ARCH_MMP or ARCH_PXA
Hi, On Thu, Jan 24, 2013 at 01:38:31AM -0500, Chao Xie wrote: > Only ARCH_PXA and ARCH_MMP will use mv_udc. > > Signed-off-by: Chao Xie NAK, you should fix your transceiver dependency. I want these gadget drivers to compile cleanly on all arches so we make proper use of linux-next. I have applied up to previous patch in this series and I won't go any further. The rest will be delayed for v3.10 sorry -- balbi signature.asc Description: Digital signature
Re: Need review for chipidea driver
On 24 January 2013 05:15, Chen Peter-B29397 wrote: > Sorry, forget to cc the list > >> >> Hi Greg, >> >> Alex has no response for chipidea driver review for long time >> (more than 1 month), below are some links about patchset. >> Does anyone else can help do it? Sorry for that. Looking into it asap. Regards, -- Alex -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/6] support other fsl SoCs with usbmisc + small fixes
Peter Chen writes: > On Tue, Nov 27, 2012 at 05:16:55PM +0100, Michael Grzeschik wrote: >> Nearly every SoC from Freescale has this non-core usb registers. This series >> adds support for more users of this driver. >> >> This series is based on Peter Chen's work. Its needed to merge his master >> branch >> before applying this series: >> >> https://github.com/hzpeterchen/linux-usb.git > > I have tested it at i.mx6q sabrelite board, it works good. > > I have pushed your commit to my git, please cc me > your coming chipidea patches, thanks. > > Alex, please add: > > Reviewed-by: Peter Chen > Tested-by: Peter Chen Looks good, queueing this one for submission. Regards, -- Alex -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: dwc3: gadget: change HIRD threshold to 12
First of all, that 28 value makes no sense as HIRD threshold is a 4-bit value, second of all it's causing issues for OMAP5. Using 12 because commit cbc725b3 (usb: dwc3: keep default hird threshold value as 4b1100) had the intention of setting the maximum allowed value of 0xc. Also, original code has been wrong forever, so this should be backported as far back as possible. Cc: Signed-off-by: Felipe Balbi --- It's getting late for v3.8-rc cycle, so I'll send this on v3.9 merge window with backport for stable tree. drivers/usb/dwc3/gadget.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 38e8d3e..77a0013 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2225,8 +2225,11 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN); - /* TODO: This should be configurable */ - reg |= DWC3_DCTL_HIRD_THRES(28); + /* +* TODO: This should be configurable. For now using +* maximum allowed HIRD threshold value of 0b1100 +*/ + reg |= DWC3_DCTL_HIRD_THRES(12); dwc3_writel(dwc->regs, DWC3_DCTL, reg); } -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH] uvc_v4l2: reset connection on uvc open
The current implementation of the composite framework connects the gadget function to the device-controller at kernel boottime. It's possible that the userspace application, which handles the enumeration requests of the gadget, starts with high latency when the host did already gave up to detect the gadget. In that case the gadget-application will not work in the first case. To ensure that the device acts properly with application start, we reset the connection on device open, so the host restarts its enumeration requests for the gadget. Signed-off-by: Michael Grzeschik --- Another approach could be, to connect the composite to the device-controller only at open of the v4l2 device. As the composite framework is generic, this could probably not be true for every function. drivers/usb/gadget/uvc_v4l2.c |5 + 1 file changed, 5 insertions(+) diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index 2ca9386..068d6a7 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -122,6 +123,7 @@ uvc_v4l2_open(struct file *file) struct video_device *vdev = video_devdata(file); struct uvc_device *uvc = video_get_drvdata(vdev); struct uvc_file_handle *handle; + struct usb_composite_dev *cdev = uvc->func.config->cdev; handle = kzalloc(sizeof(*handle), GFP_KERNEL); if (handle == NULL) @@ -130,6 +132,9 @@ uvc_v4l2_open(struct file *file) v4l2_fh_init(&handle->vfh, vdev); v4l2_fh_add(&handle->vfh); + usb_gadget_disconnect(cdev->gadget); + usb_gadget_connect(cdev->gadget); + handle->device = &uvc->video; file->private_data = &handle->vfh; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Linux USB file storage gadget with new UDC
Hi, >> >> > Also, you shouldn't requeue the request yourself, gadget driver owns the >> >> > request. >> >> which request do i requeue? please kindly point that out. Thanks! >> > >> > look at your code. Look what you do after you call complete. >> >> is it this code? i will remove the redundant code after complete. >> >> ka_ep_p->req.complete(&ka_ep_p->ep, &req->req); >> if (num == 0) { >> ka_ep_p->req.length = 0; >> usb_ep_queue(&ka_ep_p->ep, &req->req, 0); >> ka_ep_p->desc = &ep0_in_desc; >> } > > you should delete the request from your list. Whatever you do, has to be > undone. got it. i add list_del_init() to delete the request from the list. >> i read the net2272.c, the net2272_enable() is called by gadget driver >> enable_endpoint(). When i run the gadget driver, enable_endpoint() is >> called for fsg->bulk_in and fsg->bulk_out. The enable_endpoint() of >> fsg->intr_in is not called because transport_is_cbi() is false. So >> how can the endpoint 0 be enabled? > > endpoint 0 has to be always enabled by the UDC driver. Gadget driver > expects endpoint 0 to be ready. i read through the net2272.c, i do not see where the endpoint 0 is enabled. I blindly enable my endpoint zero. i think my code is wrong. kagen2_ep_enable(&ka_ep->ep, &ep0_in_desc); kagen2_ep_enable(&ka_ep->ep, &ep0_out_desc); thanks, victor -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] usb: host: tegra: make use of PHY pointer of HCD
As pointer to PHY structure can be stored in struct usb_hcd making use of it, to call Tegra PHY APIs. Call to usb_phy_shutdown() is moved up in tegra_ehci_remove(), so that to avoid dereferencing of hcd after its freed up. Signed-off-by: Venu Byravarasu --- First version of patch can be found at http://marc.info/?l=linux-kernel&m=135581479020213&w=2. As it was not yet applied, sending v2 of the patch. delta from v1: Modified all Tegra PHY APIs to use standard 'structu usb_phy *' as their parameter instead of proprietary parameter of type 'struct tegra_usb_phy *'. drivers/usb/host/ehci-tegra.c | 27 +-- drivers/usb/phy/tegra_usb_phy.c | 16 include/linux/usb/tegra_usb_phy.h |8 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index b02622a..568aecc 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -56,7 +56,7 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd) struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); clk_prepare_enable(tegra->clk); - usb_phy_set_suspend(&tegra->phy->u_phy, 0); + usb_phy_set_suspend(hcd->phy, 0); tegra->host_resumed = 1; } @@ -65,7 +65,7 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd) struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); tegra->host_resumed = 0; - usb_phy_set_suspend(&tegra->phy->u_phy, 1); + usb_phy_set_suspend(hcd->phy, 1); clk_disable_unprepare(tegra->clk); } @@ -159,7 +159,7 @@ static int tegra_ehci_hub_control( if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { /* Resume completed, re-enable disconnect detection */ tegra->port_resuming = 0; - tegra_usb_phy_postresume(tegra->phy); + tegra_usb_phy_postresume(hcd->phy); } } @@ -212,7 +212,7 @@ static int tegra_ehci_hub_control( goto done; /* Disable disconnect detection during port resume */ - tegra_usb_phy_preresume(tegra->phy); + tegra_usb_phy_preresume(hcd->phy); ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); @@ -476,7 +476,7 @@ static int controller_resume(struct device *dev) } /* Force the phy to keep data lines in suspend state */ - tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); + tegra_ehci_phy_restore_start(hcd->phy, tegra->port_speed); /* Enable host mode */ tdi_reset(ehci); @@ -543,17 +543,17 @@ static int controller_resume(struct device *dev) } } - tegra_ehci_phy_restore_end(tegra->phy); + tegra_ehci_phy_restore_end(hcd->phy); goto done; restart: if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) - tegra_ehci_phy_restore_end(tegra->phy); + tegra_ehci_phy_restore_end(hcd->phy); tegra_ehci_restart(hcd); done: - tegra_usb_phy_preresume(tegra->phy); + tegra_usb_phy_preresume(hcd->phy); tegra->port_resuming = 1; return 0; } @@ -740,9 +740,9 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto fail_io; } - usb_phy_init(&tegra->phy->u_phy); - hcd->phy = u_phy = &tegra->phy->u_phy; + usb_phy_init(hcd->phy); + u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), GFP_KERNEL); if (!u_phy->otg) { @@ -752,7 +752,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) } u_phy->otg->host = hcd_to_bus(hcd); - err = usb_phy_set_suspend(&tegra->phy->u_phy, 0); + err = usb_phy_set_suspend(hcd->phy, 0); if (err) { dev_err(&pdev->dev, "Failed to power on the phy\n"); goto fail; @@ -798,7 +798,7 @@ fail: if (!IS_ERR_OR_NULL(tegra->transceiver)) otg_set_host(tegra->transceiver->otg, NULL); #endif - usb_phy_shutdown(&tegra->phy->u_phy); + usb_phy_shutdown(hcd->phy); fail_io: clk_disable_unprepare(tegra->clk); fail_clk: @@ -820,11 +820,10 @@ static int tegra_ehci_remove(struct platform_device *pdev) otg_set_host(tegra->transceiver->otg, NULL); #endif + usb_phy_shutdown(hcd->phy); usb_remove_hcd(hcd); usb_put_hcd(hcd); - usb_phy_shutdown(&tegra->phy->u_phy); - clk_disable_unprepare(tegra->clk); return 0; diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c index d465704..5487d38 100644 --- a/drivers/usb/phy/tegra_usb_phy.c +++ b/drivers/usb/phy/tegra_usb_phy.c @@ -759,30 +759,38 @@ err0: } EXPORT_SYMBOL_GPL(tegra_usb_phy_open); -void tegra_usb_phy_preresume(struct
[RFC] net: usbnet: prevent buggy devices from killing us
A device sending 0 length frames as fast as it can has been observed killing the host system due to the resulting memory pressure. We handle the done queue as fast as we can, so if this queue is filling up then that is an indication that we are under too heavy pressure. Refusing further allocations until the done queue is handled prevents the buggy device from taking the system down. Signed-off-by: Bjørn Mork --- Hello Oliver, The MBIM firmware for the Sierra Wireless MC7710 is a nice source of "interesting" device issues. One of the uglier ones is that it under certain conditions will start flooding us with frames having length 0 as fast as it can. And that is pretty fast... My older laptop dies immediately under this. It just cannot keep up with the infinite allocations usbnet will do when the done queue first starts growing beyond reason. I really do not have a clue how to handle this problem, but this patch seems to do the job for me without affecting normal devices. The queue limit is just a number which Works For Me, leaving the system running with the buggy device and not kicking in under normal load. What do you think? Is there some other way this should be solved? Bjørn drivers/net/usb/usbnet.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index f34b2eb..85c7ffd 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -380,6 +380,14 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) unsigned long lockflags; size_t size = dev->rx_urb_size; + /* Do not let a device flood us to death! */ + if (dev->done.qlen > 1024) { + netif_dbg(dev, rx_err, dev->net, "done queue filling up (%u) - throttling\n", dev->done.qlen); + usbnet_defer_kevent (dev, EVENT_RX_MEMORY); + usb_free_urb (urb); + return -ENOMEM; + } + skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); if (!skb) { netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); -- 1.7.2.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv1 0/9] usb: chipidea: clean up debuggery
This patchset cleans up the remaining debugging bits in the driver by either conventing them to trace points or moving to debugfs, all the while getting rid of home-grown tracing facilities. Trace events are accessible through perf tool. If you don't yet have it in your testing environment, now is the good time. Alexander Shishkin (8): usb: chipidea: drop redundant includes usb: chipidea: trim include list in udc code usb: chipidea: trim include list in the core usb: chipidea: convert events to tracepoints usb: chipidea: replace interrupt accounting with tracepoints usb: chipidea: convert debug entries in sysfs to debugfs usb: chipidea: move role to debugfs usb: chipidea: move debug files creation/removal to the core Dan Carpenter (1): usb: chipidea: fix precedence bug in ci_requests_show() drivers/usb/chipidea/ci.h | 15 + drivers/usb/chipidea/core.c | 50 +-- drivers/usb/chipidea/debug.c| 888 +-- drivers/usb/chipidea/debug.h| 34 +- drivers/usb/chipidea/udc.c | 74 ++-- drivers/usb/chipidea/udc.h |2 - include/trace/events/chipidea.h | 151 +++ 7 files changed, 399 insertions(+), 815 deletions(-) create mode 100644 include/trace/events/chipidea.h -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/9] usb: chipidea: drop redundant includes
debug.c is carrying a lot of includes that aren't needed there, drop them. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/debug.c | 17 +++-- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 3bc244d..117910f 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -1,20 +1,9 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include +#include +#include +#include #include #include -#include -#include #include "ci.h" #include "udc.h" -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/9] usb: chipidea: trim include list in udc code
Some headers included in udc core code are not actually needed, remove them. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/udc.c |8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 2f45bba..aea09d2 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -13,14 +13,8 @@ #include #include #include -#include #include -#include -#include -#include -#include -#include -#include +#include #include #include #include -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/9] usb: chipidea: convert events to tracepoints
As part of the legacy from the original driver design, we retain home-grown tracing infrastructure, complete with own ring buffer and timestamps. While it is useful for debugging certain cases, it's a lot of extra code, which these days is rather redundant. This patch replaces local tracing functionality with kernel tracepoints, thus getting rid of the ring buffer and all the maintenance code, while making use of standard kernel infrastructure. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/ci.h | 13 +++ drivers/usb/chipidea/core.c |2 + drivers/usb/chipidea/debug.c| 202 +-- drivers/usb/chipidea/debug.h| 20 drivers/usb/chipidea/udc.c | 46 - drivers/usb/chipidea/udc.h |2 - include/trace/events/chipidea.h | 135 ++ 7 files changed, 169 insertions(+), 251 deletions(-) create mode 100644 include/trace/events/chipidea.h diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index e25d126..f67d101 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -23,6 +23,8 @@ */ #define CI13XXX_PAGE_SIZE 4096ul /* page size for TD's */ #define ENDPT_MAX 32 +#define RX0 /* similar to USB_DIR_OUT but can be used as an index */ +#define TX1 /* similar to USB_DIR_IN but can be used as an index */ /** * STRUCTURES @@ -59,6 +61,15 @@ struct ci13xxx_ep { struct dma_pool *td_pool; }; +/** + * ci_ep_addr: calculates endpoint address from direction & number + * @ep: endpoint + */ +static inline u8 ci_ep_addr(struct ci13xxx_ep *ep) +{ + return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num; +} + enum ci_role { CI_ROLE_HOST = 0, CI_ROLE_GADGET, @@ -313,4 +324,6 @@ int hw_port_test_set(struct ci13xxx *ci, u8 mode); u8 hw_port_test_get(struct ci13xxx *ci); +#include + #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */ diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 77963b6..d0aa172 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -65,6 +65,8 @@ #include #include +#define CREATE_TRACE_POINTS + #include "ci.h" #include "udc.h" #include "bits.h" diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 117910f..9e9caa8 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -196,200 +196,6 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL); -/* Maximum event message length */ -#define DBG_DATA_MSG 64UL - -/* Maximum event messages */ -#define DBG_DATA_MAX 128UL - -/* Event buffer descriptor */ -static struct { - char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */ - unsigned idx; /* index */ - unsigned tty; /* print to console? */ - rwlock_t lck; /* lock */ -} dbg_data = { - .idx = 0, - .tty = 0, - .lck = __RW_LOCK_UNLOCKED(lck) -}; - -/** - * dbg_dec: decrements debug event index - * @idx: buffer index - */ -static void dbg_dec(unsigned *idx) -{ - *idx = (*idx - 1) & (DBG_DATA_MAX-1); -} - -/** - * dbg_inc: increments debug event index - * @idx: buffer index - */ -static void dbg_inc(unsigned *idx) -{ - *idx = (*idx + 1) & (DBG_DATA_MAX-1); -} - -/** - * dbg_print: prints the common part of the event - * @addr: endpoint address - * @name: event name - * @status: status - * @extra: extra information - */ -static void dbg_print(u8 addr, const char *name, int status, const char *extra) -{ - struct timeval tval; - unsigned int stamp; - unsigned long flags; - - write_lock_irqsave(&dbg_data.lck, flags); - - do_gettimeofday(&tval); - stamp = tval.tv_sec & 0x; /* 2^32 = 4294967296. Limit to 4096s */ - stamp = stamp * 100 + tval.tv_usec; - - scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG, - "%04X\t? %02X %-7.7s %4i ?\t%s\n", - stamp, addr, name, status, extra); - - dbg_inc(&dbg_data.idx); - - write_unlock_irqrestore(&dbg_data.lck, flags); - - if (dbg_data.tty != 0) - pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n", - stamp, addr, name, status, extra); -} - -/** - * dbg_done: prints a DONE event - * @addr: endpoint address - * @td: transfer descriptor - * @status: status - */ -void dbg_done(u8 addr, const u32 token, int status) -{ - char msg[DBG_DATA_MSG]; - - scnprintf(msg, sizeof(msg), "%d %02X", - (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES), - (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS)); - dbg_print(addr, "DONE", status, msg); -} - -/
[PATCH 3/9] usb: chipidea: trim include list in the core
Some headers included in the chipidea controller core are not needed, remove them. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/core.c |3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 57cae1f..77963b6 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -51,15 +51,12 @@ */ #include #include -#include #include -#include #include #include #include #include #include -#include #include #include #include -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/9] usb: chipidea: replace interrupt accounting with tracepoints
The driver also has interrupt counters and another ring buffer for keeping track of the order in which they arrive. This patch converts these counters to trace points. Userspace tools such as perf can provide information on both order and stats of the interrupts. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/debug.c| 160 +-- drivers/usb/chipidea/debug.h|5 -- drivers/usb/chipidea/udc.c | 11 ++- include/trace/events/chipidea.h | 18 - 4 files changed, 26 insertions(+), 168 deletions(-) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 9e9caa8..898aca5 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -10,46 +10,6 @@ #include "bits.h" #include "debug.h" -/* Interrupt statistics */ -#define ISR_MASK 0x1F -static struct isr_statistics { - u32 test; - u32 ui; - u32 uei; - u32 pci; - u32 uri; - u32 sli; - u32 none; - struct { - u32 cnt; - u32 buf[ISR_MASK+1]; - u32 idx; - } hndl; -} isr_statistics; - -void dbg_interrupt(u32 intmask) -{ - if (!intmask) { - isr_statistics.none++; - return; - } - - isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intmask; - isr_statistics.hndl.idx &= ISR_MASK; - isr_statistics.hndl.cnt++; - - if (USBi_URI & intmask) - isr_statistics.uri++; - if (USBi_PCI & intmask) - isr_statistics.pci++; - if (USBi_UEI & intmask) - isr_statistics.uei++; - if (USBi_UI & intmask) - isr_statistics.ui++; - if (USBi_SLI & intmask) - isr_statistics.sli++; -} - /** * hw_register_read: reads all device registers (execute without interruption) * @buf: destination buffer @@ -197,118 +157,6 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL); /** - * show_inters: interrupt status, enable status and historic - * - * Check "device.h" for details - */ -static ssize_t show_inters(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); - unsigned long flags; - u32 intr; - unsigned i, j, n = 0; - - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "[%s] EINVAL\n", __func__); - return 0; - } - - spin_lock_irqsave(&ci->lock, flags); - - /*n += scnprintf(buf + n, PAGE_SIZE - n, - "status = %08x\n", hw_read_intr_status(ci)); - n += scnprintf(buf + n, PAGE_SIZE - n, - "enable = %08x\n", hw_read_intr_enable(ci));*/ - - n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n", - isr_statistics.test); - n += scnprintf(buf + n, PAGE_SIZE - n, "? ui = %d\n", - isr_statistics.ui); - n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n", - isr_statistics.uei); - n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n", - isr_statistics.pci); - n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n", - isr_statistics.uri); - n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n", - isr_statistics.sli); - n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n", - isr_statistics.none); - n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n", - isr_statistics.hndl.cnt); - - for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) { - i &= ISR_MASK; - intr = isr_statistics.hndl.buf[i]; - - if (USBi_UI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "ui "); - intr &= ~USBi_UI; - if (USBi_UEI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "uei "); - intr &= ~USBi_UEI; - if (USBi_PCI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "pci "); - intr &= ~USBi_PCI; - if (USBi_URI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "uri "); - intr &= ~USBi_URI; - if (USBi_SLI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "sli "); - intr &= ~USBi_SLI; - if (intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "??? "); - if (isr_statistics.hndl.buf[i]) - n += scnprintf(buf + n, PAGE_SIZE - n, "\n"); - } - - spin_unlock_irqrestore(&ci->lock, flags); - - return n; -} - -/** - * store_inters: enable & force or disable an individual interrutps - *
[PATCH 7/9] usb: chipidea: move role to debugfs
Manual role switching function is there for debugging purposes, so has to move to debugfs. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/core.c | 39 -- drivers/usb/chipidea/debug.c | 54 ++ 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index d0aa172..ab7861d 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -282,38 +282,6 @@ static void ci_role_work(struct work_struct *work) } } -static ssize_t show_role(struct device *dev, struct device_attribute *attr, -char *buf) -{ - struct ci13xxx *ci = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", ci_role(ci)->name); -} - -static ssize_t store_role(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct ci13xxx *ci = dev_get_drvdata(dev); - enum ci_role role; - int ret; - - for (role = CI_ROLE_HOST; role < CI_ROLE_END; role++) - if (ci->roles[role] && !strcmp(buf, ci->roles[role]->name)) - break; - - if (role == CI_ROLE_END || role == ci->role) - return -EINVAL; - - ci_role_stop(ci); - ret = ci_role_start(ci, role); - if (ret) - return ret; - - return count; -} - -static DEVICE_ATTR(role, S_IRUSR | S_IWUSR, show_role, store_role); - static irqreturn_t ci_irq(int irq, void *data) { struct ci13xxx *ci = data; @@ -488,17 +456,11 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (ret) goto stop; - ret = device_create_file(dev, &dev_attr_role); - if (ret) - goto rm_attr; - if (ci->is_otg) hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE); return ret; -rm_attr: - device_remove_file(dev, &dev_attr_role); stop: ci_role_stop(ci); rm_wq: @@ -514,7 +476,6 @@ static int ci_hdrc_remove(struct platform_device *pdev) flush_workqueue(ci->wq); destroy_workqueue(ci->wq); - device_remove_file(ci->dev, &dev_attr_role); free_irq(ci->irq, ci); ci_role_stop(ci); diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 057ae09..5738079 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -199,6 +199,55 @@ static const struct file_operations ci_requests_fops = { .release= single_release, }; +static int ci_role_show(struct seq_file *s, void *data) +{ + struct ci13xxx *ci = s->private; + + seq_printf(s, "%s\n", ci_role(ci)->name); + + return 0; +} + +static ssize_t ci_role_write(struct file *file, const char __user *ubuf, +size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct ci13xxx *ci = s->private; + enum ci_role role; + char buf[8]; + int ret; + + if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + for (role = CI_ROLE_HOST; role < CI_ROLE_END; role++) + if (ci->roles[role] && + !strncmp(buf, ci->roles[role]->name, +strlen(ci->roles[role]->name))) + break; + + if (role == CI_ROLE_END || role == ci->role) + return -EINVAL; + + ci_role_stop(ci); + ret = ci_role_start(ci, role); + + return ret ? ret : count; +} + +static int ci_role_open(struct inode *inode, struct file *file) +{ + return single_open(file, ci_role_show, inode->i_private); +} + +static const struct file_operations ci_role_fops = { + .open = ci_role_open, + .write = ci_role_write, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, +}; + /** * dbg_create_files: initializes the attribute interface * @ci: device @@ -230,6 +279,11 @@ int dbg_create_files(struct ci13xxx *ci) dent = debugfs_create_file("requests", S_IRUGO, ci->debugfs, ci, &ci_requests_fops); + if (!dent) + goto err; + + dent = debugfs_create_file("role", S_IRUGO | S_IWUSR, ci->debugfs, ci, + &ci_role_fops); if (dent) return 0; err: -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 8/9] usb: chipidea: move debug files creation/removal to the core
Create and remove debugfs entries in hdrc probe/remove instead of start/stop of the device controller. Gadget specific will not export anything while the controller is in host mode. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/core.c |6 +- drivers/usb/chipidea/udc.c |9 + 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index ab7861d..8f1b083 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -459,8 +459,11 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (ci->is_otg) hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE); - return ret; + ret = dbg_create_files(ci); + if (!ret) + return 0; + free_irq(ci->irq, ci); stop: ci_role_stop(ci); rm_wq: @@ -474,6 +477,7 @@ static int ci_hdrc_remove(struct platform_device *pdev) { struct ci13xxx *ci = platform_get_drvdata(pdev); + dbg_remove_files(ci); flush_workqueue(ci->wq); destroy_workqueue(ci->wq); free_irq(ci->irq, ci); diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 6527f5c..58c8164 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1756,15 +1756,11 @@ static int udc_start(struct ci13xxx *ci) goto put_transceiver; } - retval = dbg_create_files(ci); - if (retval) - goto unreg_device; - if (!IS_ERR_OR_NULL(ci->transceiver)) { retval = otg_set_peripheral(ci->transceiver->otg, &ci->gadget); if (retval) - goto remove_dbg; + goto unreg_device; } retval = usb_add_gadget_udc(dev, &ci->gadget); @@ -1784,8 +1780,6 @@ remove_trans: } dev_err(dev, "error = %i\n", retval); -remove_dbg: - dbg_remove_files(ci); unreg_device: device_unregister(&ci->gadget.dev); put_transceiver: @@ -1825,7 +1819,6 @@ static void udc_stop(struct ci13xxx *ci) if (ci->global_phy) usb_put_phy(ci->transceiver); } - dbg_remove_files(ci); device_unregister(&ci->gadget.dev); /* my kobject is dynamic, I swear! */ memset(&ci->gadget, 0, sizeof(ci->gadget)); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/9] usb: chipidea: convert debug entries in sysfs to debugfs
Currently, we have a bunch of files in sysfs that display all sorts of debugging information for the device controller, so they have to move to debugfs where they belong. The "registers" interface have been removed, since it doesn't fit into the current driver design as is and it's hardly a good idea to touch the registers from userspace anyway. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/ci.h|2 + drivers/usb/chipidea/debug.c | 469 +- drivers/usb/chipidea/debug.h |9 +- drivers/usb/chipidea/udc.c |6 +- 4 files changed, 151 insertions(+), 335 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index f67d101..fc8fc06 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -140,6 +140,7 @@ struct hw_bank { * @vbus_active: is VBUS active * @transceiver: pointer to USB PHY, if any * @hcd: pointer to usb_hcd for ehci host driver + * @debugfs: root dentry for this controller in debugfs */ struct ci13xxx { struct device *dev; @@ -176,6 +177,7 @@ struct ci13xxx { boolglobal_phy; struct usb_phy *transceiver; struct usb_hcd *hcd; + struct dentry *debugfs; }; static inline struct ci_role_driver *ci_role(struct ci13xxx *ci) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 898aca5..057ae09 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -2,6 +2,9 @@ #include #include #include +#include +#include +#include #include #include @@ -11,223 +14,113 @@ #include "debug.h" /** - * hw_register_read: reads all device registers (execute without interruption) - * @buf: destination buffer - * @size: buffer size - * - * This function returns number of registers read + * ci_device_show: prints information about device capabilities and status */ -static size_t hw_register_read(struct ci13xxx *ci, u32 *buf, size_t size) +static int ci_device_show(struct seq_file *s, void *data) { - unsigned i; - - if (size > ci->hw_bank.size) - size = ci->hw_bank.size; - - for (i = 0; i < size; i++) - buf[i] = hw_read(ci, i * sizeof(u32), ~0); - - return size; -} - -/** - * hw_register_write: writes to register - * @addr: register address - * @data: register value - * - * This function returns an error code - */ -static int hw_register_write(struct ci13xxx *ci, u16 addr, u32 data) -{ - /* align */ - addr /= sizeof(u32); + struct ci13xxx *ci = s->private; + struct usb_gadget *gadget = &ci->gadget; - if (addr >= ci->hw_bank.size) - return -EINVAL; + seq_printf(s, "speed = %d\n", gadget->speed); + seq_printf(s, "max_speed = %d\n", gadget->max_speed); + seq_printf(s, "is_otg= %d\n", gadget->is_otg); + seq_printf(s, "is_a_peripheral = %d\n", gadget->is_a_peripheral); + seq_printf(s, "b_hnp_enable = %d\n", gadget->b_hnp_enable); + seq_printf(s, "a_hnp_support = %d\n", gadget->a_hnp_support); + seq_printf(s, "a_alt_hnp_support = %d\n", gadget->a_alt_hnp_support); + seq_printf(s, "name = %s\n", + (gadget->name ? gadget->name : "")); + + if (!ci->driver) + return 0; - /* align */ - addr *= sizeof(u32); + seq_printf(s, "gadget function = %s\n", + (ci->driver->function ? ci->driver->function : "")); + seq_printf(s, "gadget max speed = %d\n", ci->driver->max_speed); - hw_write(ci, addr, ~0, data); return 0; } -/** - * hw_intr_clear: disables interrupt & clears interrupt status (execute without - *interruption) - * @n: interrupt bit - * - * This function returns an error code - */ -static int hw_intr_clear(struct ci13xxx *ci, int n) +static int ci_device_open(struct inode *inode, struct file *file) { - if (n >= REG_BITS) - return -EINVAL; - - hw_write(ci, OP_USBINTR, BIT(n), 0); - hw_write(ci, OP_USBSTS, BIT(n), BIT(n)); - return 0; + return single_open(file, ci_device_show, inode->i_private); } -/** - * hw_intr_force: enables interrupt & forces interrupt status (execute without - *interruption) - * @n: interrupt bit - * - * This function returns an error code - */ -static int hw_intr_force(struct ci13xxx *ci, int n) -{ - if (n >= REG_BITS) - return -EINVAL; - - hw_write(ci, CAP_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE); - hw_write(ci, OP_USBINTR, BIT(n), BIT(n)); - hw_write(ci, OP_USBSTS, BIT(n), BIT(n)); - hw_write(ci, CAP_TESTMODE, TESTMODE_FORCE, 0); - return 0; -} - -/** - * show_device: prints information about device capabilities and status - * - * Check "device.h" for deta
[PATCH 9/9] usb: chipidea: fix precedence bug in ci_requests_show()
From: Dan Carpenter The intent here was to have parenthesis around the (ci->hw_ep_max / 2) so that it counts like "0 1 2 0 1 2". In the current code, the mod operation happens first so it counts like "0 0 1 1 2 2". Signed-off-by: Dan Carpenter [rebased on top of debug.c changes] Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/debug.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 5738079..36a7063 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -175,7 +175,7 @@ static int ci_requests_show(struct seq_file *s, void *data) req = list_entry(ptr, struct ci13xxx_req, queue); seq_printf(s, "EP=%02i: TD=%08X %s\n", - i % ci->hw_ep_max/2, (u32)req->dma, + i % (ci->hw_ep_max / 2), (u32)req->dma, ((i < ci->hw_ep_max/2) ? "RX" : "TX")); for (j = 0; j < qsize; j++) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Linux USB file storage gadget with new UDC
Hi, On Thu, Jan 24, 2013 at 06:23:08PM +0800, victor yeo wrote: > Hi, > > >> >> > Also, you shouldn't requeue the request yourself, gadget driver owns > >> >> > the > >> >> > request. > >> >> which request do i requeue? please kindly point that out. Thanks! > >> > > >> > look at your code. Look what you do after you call complete. > >> > >> is it this code? i will remove the redundant code after complete. > >> > >> ka_ep_p->req.complete(&ka_ep_p->ep, &req->req); > >> if (num == 0) { > >> ka_ep_p->req.length = 0; > >> usb_ep_queue(&ka_ep_p->ep, &req->req, 0); > >> ka_ep_p->desc = &ep0_in_desc; > >> } > > > > you should delete the request from your list. Whatever you do, has to be > > undone. > > got it. i add list_del_init() to delete the request from the list. _init() is unnecessary > > >> i read the net2272.c, the net2272_enable() is called by gadget driver > >> enable_endpoint(). When i run the gadget driver, enable_endpoint() is > >> called for fsg->bulk_in and fsg->bulk_out. The enable_endpoint() of > >> fsg->intr_in is not called because transport_is_cbi() is false. So > >> how can the endpoint 0 be enabled? > > > > endpoint 0 has to be always enabled by the UDC driver. Gadget driver > > expects endpoint 0 to be ready. > > i read through the net2272.c, i do not see where the endpoint 0 is > enabled. I blindly enable my endpoint zero. i think my code is wrong. > kagen2_ep_enable(&ka_ep->ep, &ep0_in_desc); > kagen2_ep_enable(&ka_ep->ep, &ep0_out_desc); yeah, you need to enabled it during driver initialization -- balbi signature.asc Description: Digital signature
Re: [RFC] net: usbnet: prevent buggy devices from killing us
On Thursday 24 January 2013 11:25:52 Bjørn Mork wrote: > The MBIM firmware for the Sierra Wireless MC7710 is a nice source > of "interesting" device issues. One of the uglier ones is that > it under certain conditions will start flooding us with frames > having length 0 as fast as it can. And that is pretty fast... If you can tell that those frames are bogus, why not count them as opposed to generic qlen? Say, if you see 20 among the last 30 are of this type, throttle. Regards Oliver -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] net: usbnet: prevent buggy devices from killing us
Bjørn Mork writes: > A device sending 0 length frames as fast as it can has been > observed killing the host system due to the resulting memory > pressure. We handle the done queue as fast as we can, so > if this queue is filling up then that is an indication that we > are under too heavy pressure. Refusing further allocations > until the done queue is handled prevents the buggy device > from taking the system down. > > Signed-off-by: Bjørn Mork > --- > Hello Oliver, > > The MBIM firmware for the Sierra Wireless MC7710 is a nice source > of "interesting" device issues. One of the uglier ones is that > it under certain conditions will start flooding us with frames > having length 0 as fast as it can. And that is pretty fast... > > My older laptop dies immediately under this. It just cannot keep > up with the infinite allocations usbnet will do when the done > queue first starts growing beyond reason. > > I really do not have a clue how to handle this problem, but this > patch seems to do the job for me without affecting normal devices. > The queue limit is just a number which Works For Me, leaving the > system running with the buggy device and not kicking in under > normal load. > > What do you think? Is there some other way this should be solved? To illustrate the problem, this the start and stop debug output for such a buggy device session *with* the RFC patch applied: Jan 24 11:16:23 nemi kernel: [ 3187.624164] qmi_wwan 8-4:1.8 wwan0: open: enable queueing (rx 60, tx 60) mtu 1500 simple framing Jan 24 11:16:38 nemi kernel: [ 3202.536921] qmi_wwan 8-4:1.8 wwan0: stop stats: rx/tx 1/11, errs 738980/0 I believe the stats tell the full story... I do not have any logs without the throttling patch, as that takes down everything on my laptop including the ahci driver and keyboard. Not even the magic sysrq is working then. If anyone is interested in the full debug log (211KB compressed) from the above session, then I've put it on http://www.mork.no/~bjorn/usbnet-zero-packet-fix.log.gz It is mostly full of "rx length 0" lines, but with an occasional sequence of Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1025) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: rx length 0 Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1026) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: rx length 0 Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1027) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: rx length 0 Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1028) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: rx length 0 Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1029) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: rx length 0 Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1030) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: rx length 0 Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1031) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: rx length 0 Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1032) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: rx length 0 Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1033) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: rx length 0 Jan 24 11:16:23 nemi kernel: [ 3187.682669] qmi_wwan 8-4:1.8 wwan0: done queue filling up (1034) - throttling Jan 24 11:16:23 nemi kernel: [ 3187.697826] qmi_wwan 8-4:1.8 wwan0: rxqlen 0 --> 10 showing that the throttling is kicking in and doing its job. Bjørn -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [V5 PATCH 24/26] usb: gadget: mv_udc: add device tree support
Hello, On Thu, Jan 24, 2013 at 06:38:48AM +, Chao Xie wrote: > In original driver, we have callbacks in platform data, and some > dynamically allocations variables in platform data. > Now, these blocks are removed, the device tree support is easier > now. Please could you also add a binding document? See Documentation/devicetree/bindings/usb for examples of existing bindings. Also, please Cc devicetree-discuss when introducing a new binding as you are doing here. > > Signed-off-by: Chao Xie > --- > drivers/usb/gadget/mv_udc.h |5 +- > drivers/usb/gadget/mv_udc_core.c | 106 > ++ > 2 files changed, 86 insertions(+), 25 deletions(-) > > diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/mv_udc.h > index 50ae7c7..de84722 100644 > --- a/drivers/usb/gadget/mv_udc.h > +++ b/drivers/usb/gadget/mv_udc.h > @@ -179,6 +179,7 @@ struct mv_udc { > int irq; > > unsigned intextern_attr; > + unsigned intmode; > struct notifier_block notifier; > > struct mv_cap_regs __iomem *cap_regs; > @@ -222,11 +223,9 @@ struct mv_udc { > struct mv_usb2_phy *phy; > struct usb_phy *transceiver; > > - struct mv_usb_platform_data *pdata; > - > /* some SOC has mutiple clock sources for USB*/ > unsigned intclknum; > - struct clk *clk[0]; > + struct clk **clk; > }; > > /* endpoint data structure */ > diff --git a/drivers/usb/gadget/mv_udc_core.c > b/drivers/usb/gadget/mv_udc_core.c > index 2e5907f..a4ee9a1 100644 > --- a/drivers/usb/gadget/mv_udc_core.c > +++ b/drivers/usb/gadget/mv_udc_core.c > @@ -34,6 +34,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -2153,21 +2154,57 @@ static int mv_udc_remove(struct platform_device *pdev) > return 0; > } > > +static int mv_udc_parse_dt(struct platform_device *pdev, > + struct mv_udc *udc) > +{ > + struct device_node *np = pdev->dev.of_node; > + unsigned int clks_num; > + int i, ret; > + const char *clk_name; > + > + if (!np) > + return 1; > + > + clks_num = of_property_count_strings(np, "clocks"); > + if (clks_num < 0) > + return clks_num; > + > + udc->clk = devm_kzalloc(&pdev->dev, > + sizeof(struct clk *) * clks_num, GFP_KERNEL); > + if (udc->clk == NULL) > + return -ENOMEM; > + > + for (i = 0; i < clks_num; i++) { > + ret = of_property_read_string_index(np, "clocks", i, > + &clk_name); > + if (ret) > + return ret; > + udc->clk[i] = devm_clk_get(&pdev->dev, clk_name); > + if (IS_ERR(udc->clk[i])) > + return PTR_ERR(udc->clk[i]); I was going to ask if you couldn't use of_clk_get, but I see you want to use the devm_* functions to handle cleanup. It seems a shame there's not a standard devm_of_clk_get. > + } > + > + udc->clknum = clks_num; > + > + ret = of_property_read_u32(np, "extern_attr", &udc->extern_attr); > + if (ret) > + return ret; This looks like a *very* bad idea. The udc::extern_attr field seems to be a set of flags, which this could reads in directly (without any sanity checking), effectively making it an undocumented ABI. This might be better as a set of valueless properties. Will unsigned int be the same as u32 on all platforms this could be used on? If not, you're passing the wrong type into of_property_read_u32. Additionally, in devicetree, '-' is used in preference of '_' in compatible and property names. > + > + ret = of_property_read_u32(np, "mode", &udc->mode); > + if (ret) > + return ret; If I've understood correctly, this property will either be MV_USB_MODE_OTG (0) or MV_USB_MODE_OTG (1). Again, I don't think this is good to be exported as an ABI, especially as nothing in the enum definition points out that this affects anything outside the kernel. If this isn't something that wants to be changed at runtime, this should probably be a string property, with "host" and "otg" as valid values. Looking in Documentation/devicetree, the nvidia,tegra20-ehci binding uses similar strings in its dr_mode property. There may be other (undocumented) precedents. > + > + return 0; > +} > + > static int mv_udc_probe(struct platform_device *pdev) > { > - struct mv_usb_platform_data *pdata = pdev->dev.platform_data; > struct mv_udc *udc; > int retval = 0; > - int clk_i = 0; > struct resource *r; > size_t size; > > - if (pdata == NULL) { > - dev_err(&pdev->dev, "missing platform_data\n"); > - return -ENODEV; > - } > - > - size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum; > + size = sizeof(*udc); > udc = devm_kzallo
Re: [patch v2] usb: gadget: precedence bug in show_requests()
Dan Carpenter writes: > The intent here was to have parenthesis around the (ci->hw_ep_max / 2) > so that it counts like "0 1 2 0 1 2". In the current code, the mod > operation happens first so it counts like "0 0 1 1 2 2". > > Signed-off-by: Dan Carpenter Thanks, I added this one on top of my debug cleanup patchset [1]. [1] http://marc.info/?l=linux-usb&m=135902438408860&w=2 Regards, -- Alex -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] net: usbnet: prevent buggy devices from killing us
Oliver Neukum writes: > On Thursday 24 January 2013 11:25:52 Bjørn Mork wrote: >> The MBIM firmware for the Sierra Wireless MC7710 is a nice source >> of "interesting" device issues. One of the uglier ones is that >> it under certain conditions will start flooding us with frames >> having length 0 as fast as it can. And that is pretty fast... > > If you can tell that those frames are bogus, why not count them > as opposed to generic qlen? Say, if you see 20 among the last 30 > are of this type, throttle. Sounds like a good idea, but where do I add/get that statistics? Bjørn -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH] uvc_v4l2: reset connection on uvc open
Hi Michael, On Thursday 24 January 2013 11:22:02 Michael Grzeschik wrote: > The current implementation of the composite framework connects the > gadget function to the device-controller at kernel boottime. > > It's possible that the userspace application, which handles the > enumeration requests of the gadget, starts with high latency when the > host did already gave up to detect the gadget. In that case the > gadget-application will not work in the first case. This shouldn't happen, as the UVC gadget driver should start disconnected (it calls usb_function_deactive() in uvc_function_bind()). If the host can enumerate the gadget before the application starts it would then likely be a device controller driver bug, not a UVC gadget driver bug. > To ensure that the device acts properly with application start, we reset > the connection on device open, so the host restarts its enumeration > requests for the gadget. > > Signed-off-by: Michael Grzeschik > --- > > Another approach could be, to connect the composite to the > device-controller only at open of the v4l2 device. As the composite > framework is generic, this could probably not be true for every > function. > > drivers/usb/gadget/uvc_v4l2.c |5 + > 1 file changed, 5 insertions(+) > > diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c > index 2ca9386..068d6a7 100644 > --- a/drivers/usb/gadget/uvc_v4l2.c > +++ b/drivers/usb/gadget/uvc_v4l2.c > @@ -16,6 +16,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -122,6 +123,7 @@ uvc_v4l2_open(struct file *file) > struct video_device *vdev = video_devdata(file); > struct uvc_device *uvc = video_get_drvdata(vdev); > struct uvc_file_handle *handle; > + struct usb_composite_dev *cdev = uvc->func.config->cdev; > > handle = kzalloc(sizeof(*handle), GFP_KERNEL); > if (handle == NULL) > @@ -130,6 +132,9 @@ uvc_v4l2_open(struct file *file) > v4l2_fh_init(&handle->vfh, vdev); > v4l2_fh_add(&handle->vfh); > > + usb_gadget_disconnect(cdev->gadget); > + usb_gadget_connect(cdev->gadget); > + > handle->device = &uvc->video; > file->private_data = &handle->vfh; -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [V5 PATCH 25/26] usb: otg: mv_otg: add device tree support
On Thu, Jan 24, 2013 at 06:38:49AM +, Chao Xie wrote: > All blocks are removed. Add the device tree support for otg. As with mv_udc, this binding should be documented. Please Cc devicetree-discuss when you have one. > > Signed-off-by: Chao Xie > --- > drivers/usb/otg/mv_otg.c | 128 + > drivers/usb/otg/mv_otg.h |6 +- > 2 files changed, 108 insertions(+), 26 deletions(-) > > diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c > index 379df92..3aa7fdc 100644 > --- a/drivers/usb/otg/mv_otg.c > +++ b/drivers/usb/otg/mv_otg.c > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -333,7 +334,7 @@ static void mv_otg_update_inputs(struct mv_otg *mvotg) > else > otg_ctrl->id = !!(otgsc & OTGSC_STS_USB_ID); > > - if (mvotg->pdata->otg_force_a_bus_req && !otg_ctrl->id) > + if (mvotg->otg_force_a_bus_req && !otg_ctrl->id) > otg_ctrl->a_bus_req = 1; > > otg_ctrl->a_sess_vld = !!(otgsc & OTGSC_STS_A_SESSION_VALID); > @@ -690,21 +691,69 @@ int mv_otg_remove(struct platform_device *pdev) > return 0; > } > > +static int mv_otg_parse_dt(struct platform_device *pdev, > + struct mv_otg *mvotg) > +{ > + struct device_node *np = pdev->dev.of_node; > + unsigned int clks_num; > + unsigned int val; > + int i, ret; > + const char *clk_name; > + > + if (!np) > + return 1; > + > + clks_num = of_property_count_strings(np, "clocks"); > + if (clks_num < 0) > + return clks_num; > + > + mvotg->clk = devm_kzalloc(&pdev->dev, > + sizeof(struct clk *) * clks_num, GFP_KERNEL); > + if (mvotg->clk == NULL) > + return -ENOMEM; > + > + for (i = 0; i < clks_num; i++) { > + ret = of_property_read_string_index(np, "clocks", i, > + &clk_name); > + if (ret) > + return ret; > + mvotg->clk[i] = devm_clk_get(&pdev->dev, clk_name); > + if (IS_ERR(mvotg->clk[i])) > + return PTR_ERR(mvotg->clk[i]); > + } Again, it seems a shame there's no devm_of_clk_get. > + > + mvotg->clknum = clks_num; > + > + ret = of_property_read_u32(np, "extern_attr", &mvotg->extern_attr); > + if (ret) > + return ret; > + > + ret = of_property_read_u32(np, "mode", &mvotg->mode); > + if (ret) > + return ret; I *really* don't like this, for the same reasons I stated in reply to the mv_udc patch. > + > + ret = of_property_read_u32(np, "force_a_bus_req", &val); > + if (ret) > + return ret; > + mvotg->otg_force_a_bus_req = !!val; In devicetree, the typical way to handle a boolean case like this would be to have a valueless property. If present, the property is true, if not present it's considered to default to false: device@4000 { compatible = "manufacturer,some-device"; reg = <0x4000, 0x1000>; manufacturer,boolean-property; /* no value, true if present */ }; Properties which may only have a meaning on one manufacturer's devices are also typically prefixed with the manufacturer similarly to compatible strings, e.g. "mrvl,force-a-bus-req". There may also be a better name for this property. > + > + ret = of_property_read_u32(np, "disable_clock_gating", &val); > + if (ret) > + return ret; > + mvotg->clock_gating = !val; You can do the same here, but with the logic inverted. > + > + return 0; > +} > + > static int mv_otg_probe(struct platform_device *pdev) > { > - struct mv_usb_platform_data *pdata = pdev->dev.platform_data; > struct mv_otg *mvotg; > struct usb_otg *otg; > struct resource *r; > - int retval = 0, clk_i, i; > + int retval = 0, i; > size_t size; > > - if (pdata == NULL) { > - dev_err(&pdev->dev, "failed to get platform data\n"); > - return -ENODEV; > - } > - > - size = sizeof(*mvotg) + sizeof(struct clk *) * pdata->clknum; > + size = sizeof(*mvotg); > mvotg = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); > if (!mvotg) { > dev_err(&pdev->dev, "failed to allocate memory!\n"); > @@ -718,17 +767,45 @@ static int mv_otg_probe(struct platform_device *pdev) > platform_set_drvdata(pdev, mvotg); > > mvotg->pdev = pdev; > - mvotg->extern_attr = pdata->extern_attr; > - mvotg->pdata = pdata; > > - mvotg->clknum = pdata->clknum; > - for (clk_i = 0; clk_i < mvotg->clknum; clk_i++) { > - mvotg->clk[clk_i] = devm_clk_get(&pdev->dev, > + retval = mv_otg_parse_dt(pdev, mvotg); > + if (retval > 0) { > + struct mv_usb_platform_data *pdata = pdev->dev.platform_data; > + /* no CONFIG_OF */ > + int clk_i = 0; > + > + if (pdata == NULL) { > +
Re: [RFC] net: usbnet: prevent buggy devices from killing us
On Thursday 24 January 2013 11:52:22 Bjørn Mork wrote: > Oliver Neukum writes: > > > On Thursday 24 January 2013 11:25:52 Bjørn Mork wrote: > >> The MBIM firmware for the Sierra Wireless MC7710 is a nice source > >> of "interesting" device issues. One of the uglier ones is that > >> it under certain conditions will start flooding us with frames > >> having length 0 as fast as it can. And that is pretty fast... > > > > If you can tell that those frames are bogus, why not count them > > as opposed to generic qlen? Say, if you see 20 among the last 30 > > are of this type, throttle. > > Sounds like a good idea, but where do I add/get that statistics? rx_complete It need not be very accurate. Regards Oliver -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [V5 PATCH 26/26] usb: ehci: ehci-mv: add device tree support
On Thu, Jan 24, 2013 at 06:38:50AM +, Chao Xie wrote: > All blocks are removed. Add the device tree support for ehci. Similarly to the last two patches, could you please add a binding document? > Signed-off-by: Chao Xie > Acked-by: Alan Stern > --- > drivers/usb/host/ehci-mv.c | 105 +-- > 1 files changed, 80 insertions(+), 25 deletions(-) > > diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c > index 171e145..79eca0c 100644 > --- a/drivers/usb/host/ehci-mv.c > +++ b/drivers/usb/host/ehci-mv.c > @@ -13,6 +13,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -32,11 +33,9 @@ struct ehci_hcd_mv { > > struct usb_phy *otg; > > - struct mv_usb_platform_data *pdata; > - > /* clock source and total clock number */ > unsigned int clknum; > - struct clk *clk[0]; > + struct clk **clk; > }; > > static void ehci_clock_enable(struct ehci_hcd_mv *ehci_mv) > @@ -138,22 +137,55 @@ static const struct hc_driver mv_ehci_hc_driver = { > .bus_resume = ehci_bus_resume, > }; > > +static int mv_ehci_parse_dt(struct platform_device *pdev, > + struct ehci_hcd_mv *ehci_mv) > +{ > + struct device_node *np = pdev->dev.of_node; > + unsigned int clks_num; > + int i, ret; > + const char *clk_name; > + > + if (!np) > + return 1; Perhaps -ENODEV? > + > + clks_num = of_property_count_strings(np, "clocks"); > + if (clks_num < 0) > + return clks_num; > + > + ehci_mv->clk = devm_kzalloc(&pdev->dev, > + sizeof(struct clk *) * clks_num, GFP_KERNEL); > + if (ehci_mv->clk == NULL) > + return -ENOMEM; > + > + for (i = 0; i < clks_num; i++) { > + ret = of_property_read_string_index(np, "clocks", i, > + &clk_name); > + if (ret) > + return ret; > + ehci_mv->clk[i] = clk_get(NULL, clk_name); > + if (IS_ERR(ehci_mv->clk[i])) > + return PTR_ERR(ehci_mv->clk[i]); > + } > + > + ehci_mv->clknum = clks_num; > + > + ret = of_property_read_u32(np, "mode", &ehci_mv->mode); > + if (ret) > + return ret; Again, this is a bad idea. > + > + return 0; > +} > + > static int mv_ehci_probe(struct platform_device *pdev) > { > - struct mv_usb_platform_data *pdata = pdev->dev.platform_data; > struct usb_hcd *hcd; > struct ehci_hcd *ehci; > struct ehci_hcd_mv *ehci_mv; > struct resource *r; > - int clk_i, retval = -ENODEV; > + int retval = -ENODEV; > u32 offset; > size_t size; > > - if (!pdata) { > - dev_err(&pdev->dev, "missing platform_data\n"); > - return -ENODEV; > - } > - > if (usb_disabled()) > return -ENODEV; > > @@ -161,7 +193,7 @@ static int mv_ehci_probe(struct platform_device *pdev) > if (!hcd) > return -ENOMEM; > > - size = sizeof(*ehci_mv) + sizeof(struct clk *) * pdata->clknum; > + size = sizeof(*ehci_mv); > ehci_mv = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); > if (ehci_mv == NULL) { > dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n"); > @@ -170,19 +202,36 @@ static int mv_ehci_probe(struct platform_device *pdev) > } > > platform_set_drvdata(pdev, ehci_mv); > - ehci_mv->pdata = pdata; > ehci_mv->hcd = hcd; > > - ehci_mv->clknum = pdata->clknum; > - for (clk_i = 0; clk_i < ehci_mv->clknum; clk_i++) { > - ehci_mv->clk[clk_i] = > - devm_clk_get(&pdev->dev, pdata->clkname[clk_i]); > - if (IS_ERR(ehci_mv->clk[clk_i])) { > - dev_err(&pdev->dev, "error get clck \"%s\"\n", > - pdata->clkname[clk_i]); > - retval = PTR_ERR(ehci_mv->clk[clk_i]); > - goto err_clear_drvdata; > + retval = mv_ehci_parse_dt(pdev, ehci_mv); > + if (retval > 0) { Is this why you returned 1 from mv_ehci_parse_dt? So you only do this if you don't have a dt node? If so, why not rip the check (and positive error code) out of mv_ehci_parse_dt, and then here: if (pdev->dev.of_node) { retval = mv_ehci_parse_dt(pdev, ehci_mv); } else fall back to mv_usb_platform_data ... } That makes it obvious that one side depends on dt and the other's a fallback, and doesn't rely on nonstandard return code behaviour. Also, why not return immediately if mv_ehci_parse_dt fails? [...] Thanks, Mark. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] net: usbnet: prevent buggy devices from killing us
Oliver Neukum writes: > On Thursday 24 January 2013 11:52:22 Bjørn Mork wrote: >> Oliver Neukum writes: >> >> > On Thursday 24 January 2013 11:25:52 Bjørn Mork wrote: >> >> The MBIM firmware for the Sierra Wireless MC7710 is a nice source >> >> of "interesting" device issues. One of the uglier ones is that >> >> it under certain conditions will start flooding us with frames >> >> having length 0 as fast as it can. And that is pretty fast... >> > >> > If you can tell that those frames are bogus, why not count them >> > as opposed to generic qlen? Say, if you see 20 among the last 30 >> > are of this type, throttle. >> >> Sounds like a good idea, but where do I add/get that statistics? > > rx_complete > > It need not be very accurate. Sorry for being daft, but how do I code the "20 among the last 30" part there? Bjørn -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] net: usbnet: prevent buggy devices from killing us
On Thursday 24 January 2013 12:22:54 Bjørn Mork wrote: > Oliver Neukum writes: > > > On Thursday 24 January 2013 11:52:22 Bjørn Mork wrote: > >> Oliver Neukum writes: > >> > >> > On Thursday 24 January 2013 11:25:52 Bjørn Mork wrote: > >> >> The MBIM firmware for the Sierra Wireless MC7710 is a nice source > >> >> of "interesting" device issues. One of the uglier ones is that > >> >> it under certain conditions will start flooding us with frames > >> >> having length 0 as fast as it can. And that is pretty fast... > >> > > >> > If you can tell that those frames are bogus, why not count them > >> > as opposed to generic qlen? Say, if you see 20 among the last 30 > >> > are of this type, throttle. > >> > >> Sounds like a good idea, but where do I add/get that statistics? > > > > rx_complete > > > > It need not be very accurate. > > Sorry for being daft, but how do I code the "20 among the last 30" part > there? Just by agreeing that you can live with false negatives but not false positives if (++counter > 30) { counter = bogus = 0; } else { if (is_bogus(packet) bogus++; if (bogus > counter/2) throttle(); } Regards Oliver -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v1 0/6] USB: Add support for multiple PHYs of same type
Hi Kishon, On Wed, Jan 23, 2013 at 19:56:37, ABRAHAM, KISHON VIJAY wrote: > On Wednesday 23 January 2013 07:28 PM, Mohammed, Afzal wrote: > > USB first instance of am335x works in mainline as of now. > Can you check if this series indeed breaks am335x? > > Thanks for your help. Do you have a tree having these changes, it would be easier for me. Regards Afzal
Re: Linux USB file storage gadget with new UDC
Hi, >> >> is it this code? i will remove the redundant code after complete. >> >> >> >> ka_ep_p->req.complete(&ka_ep_p->ep, &req->req); >> >> if (num == 0) { >> >> ka_ep_p->req.length = 0; >> >> usb_ep_queue(&ka_ep_p->ep, &req->req, 0); >> >> ka_ep_p->desc = &ep0_in_desc; >> >> } >> > >> > you should delete the request from your list. Whatever you do, has to be >> > undone. >> >> got it. i add list_del_init() to delete the request from the list. > > _init() is unnecessary > >> >> >> i read the net2272.c, the net2272_enable() is called by gadget driver >> >> enable_endpoint(). When i run the gadget driver, enable_endpoint() is >> >> called for fsg->bulk_in and fsg->bulk_out. The enable_endpoint() of >> >> fsg->intr_in is not called because transport_is_cbi() is false. So >> >> how can the endpoint 0 be enabled? >> > >> > endpoint 0 has to be always enabled by the UDC driver. Gadget driver >> > expects endpoint 0 to be ready. >> >> i read through the net2272.c, i do not see where the endpoint 0 is >> enabled. I blindly enable my endpoint zero. i think my code is wrong. >> kagen2_ep_enable(&ka_ep->ep, &ep0_in_desc); >> kagen2_ep_enable(&ka_ep->ep, &ep0_out_desc); > > yeah, you need to enabled it during driver initialization In the udc driver, i can't assign a single ep0 descriptor to both ep0_in_desc and ep0_out_desc. i think i should skip ep0_out_desc. Bear in mind that i only define 3 endpoints in udc driver: ep0, ep1 bulk in, ep1 bulk out. Will it cause any problem to gadget driver? thanks, victor -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Linux USB file storage gadget with new UDC
Hi, On Thu, Jan 24, 2013 at 08:14:25PM +0800, victor yeo wrote: > Hi, > > >> >> is it this code? i will remove the redundant code after complete. > >> >> > >> >> ka_ep_p->req.complete(&ka_ep_p->ep, &req->req); > >> >> if (num == 0) { > >> >> ka_ep_p->req.length = 0; > >> >> usb_ep_queue(&ka_ep_p->ep, &req->req, 0); > >> >> ka_ep_p->desc = &ep0_in_desc; > >> >> } > >> > > >> > you should delete the request from your list. Whatever you do, has to be > >> > undone. > >> > >> got it. i add list_del_init() to delete the request from the list. > > > > _init() is unnecessary > > > >> > >> >> i read the net2272.c, the net2272_enable() is called by gadget driver > >> >> enable_endpoint(). When i run the gadget driver, enable_endpoint() is > >> >> called for fsg->bulk_in and fsg->bulk_out. The enable_endpoint() of > >> >> fsg->intr_in is not called because transport_is_cbi() is false. So > >> >> how can the endpoint 0 be enabled? > >> > > >> > endpoint 0 has to be always enabled by the UDC driver. Gadget driver > >> > expects endpoint 0 to be ready. > >> > >> i read through the net2272.c, i do not see where the endpoint 0 is > >> enabled. I blindly enable my endpoint zero. i think my code is wrong. > >> kagen2_ep_enable(&ka_ep->ep, &ep0_in_desc); > >> kagen2_ep_enable(&ka_ep->ep, &ep0_out_desc); > > > > yeah, you need to enabled it during driver initialization > > In the udc driver, i can't assign a single ep0 descriptor to both > ep0_in_desc and ep0_out_desc. i think i should skip ep0_out_desc. Bear > in mind that i only define 3 endpoints in udc driver: ep0, ep1 bulk > in, ep1 bulk out. Will it cause any problem to gadget driver? depends on the gadget driver. If you have the endpoints gadget driver needs, there shouldn't be any issues. -- balbi signature.asc Description: Digital signature
Re: [RFC] net: usbnet: prevent buggy devices from killing us
Hello. On 24-01-2013 14:25, Bjørn Mork wrote: A device sending 0 length frames as fast as it can has been observed killing the host system due to the resulting memory pressure. We handle the done queue as fast as we can, so if this queue is filling up then that is an indication that we are under too heavy pressure. Refusing further allocations until the done queue is handled prevents the buggy device from taking the system down. Signed-off-by: Bjørn Mork [...] drivers/net/usb/usbnet.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index f34b2eb..85c7ffd 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -380,6 +380,14 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) unsigned long lockflags; size_t size = dev->rx_urb_size; + /* Do not let a device flood us to death! */ + if (dev->done.qlen > 1024) { + netif_dbg(dev, rx_err, dev->net, "done queue filling up (%u) - throttling\n", dev->done.qlen); + usbnet_defer_kevent (dev, EVENT_RX_MEMORY); + usb_free_urb (urb); Run your patch thru scripts/checkpatch.pl please -- spaces before parens are not allowed. WBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Linux USB file storage gadget with new UDC
Hi, >> i do not see where req->length is checked in gadget >> driver. > > It isn't _checked_; it is _set_ in set_bulk_out_req_length(). > req->actual is checked in received_cbw(). > >> g_file_storage gadget: ep0-setup, length 8: >> : 00 09 01 00 00 00 00 00 >> g_file_storage gadget: set configuration >> g_file_storage gadget: ep0-setup, length 8: >> : a1 fe 00 00 00 00 01 00 >> g_file_storage gadget: get max LUN >> g_file_storage gadget: ep0-in, length 1: >> : 00 >> g_file_storage gadget: bulk-out, length 31: >> : 55 53 42 43 a8 48 ed 86 24 00 00 00 80 00 06 12 >> 0010: 00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 >> g_file_storage gadget: bulk_out_complete --> 0, 31/0 > > Why is the bulk_out_intended_length field set to 0? Doesn't > set_bulk_out_req_length() work right? today i changed my udc driver code, now the set_bulk_out_req_length() sets the bulk_out_intended_length to 512 byte. thanks, victor -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/9] usb: chipidea: drop redundant includes
Hello. On 24-01-2013 14:46, Alexander Shishkin wrote: debug.c is carrying a lot of includes that aren't needed there, drop them. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/debug.c | 17 +++-- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 3bc244d..117910f 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -1,20 +1,9 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include +#include +#include +#include But you also add some #include's, and don't document this in the changelog. WBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/9] usb: chipidea: trim include list in udc code
On 24-01-2013 14:46, Alexander Shishkin wrote: Some headers included in udc core code are not actually needed, remove them. Signed-off-by: Alexander Shishkin --- drivers/usb/chipidea/udc.c |8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 2f45bba..aea09d2 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -13,14 +13,8 @@ #include #include #include -#include #include -#include -#include -#include -#include -#include -#include +#include Same comment as in previous patch. WBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] net: usbnet: prevent buggy devices from killing us
Oliver Neukum writes: > On Thursday 24 January 2013 12:22:54 Bjørn Mork wrote: > >> Sorry for being daft, but how do I code the "20 among the last 30" part >> there? > > Just by agreeing that you can live with false negatives but not false > positives > > if (++counter > 30) { > counter = bogus = 0; > } else { > if (is_bogus(packet) > bogus++; > if (bogus > counter/2) > throttle(); > } So, add two new counters to struct usbnet for this? That seems a little overkill to me, but I don't see how else to implement anything like that. It is still not completely clear to me how the throttling/unthrottling should be done. It tested with static counters (to avoid having to rebuild everything for this test) and a new EVENT_RX_THROTTLE flag. Still on top of my previous patch just for safety while testing, as I am fed up of having to reboot all the time :-) Doing the flag test in rx_submit seems simpler than trying to track all the places this is called. Still checking the dev->done.qlen to be able to unthrottle. Was this along the lines you thought? diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 85c7ffd..e3a1d63 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -380,6 +382,13 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) unsigned long lockflags; size_t size = dev->rx_urb_size; + + if (test_bit(EVENT_RX_THROTTLE, &dev->flags) && dev->done.qlen > 0) { + netif_dbg(dev, rx_err, dev->net, "%s: EVENT_RX_THROTTLE: (done.qlen=%u)\n", __func__, dev->done.qlen); + usb_free_urb(urb); + return -ENOLINK; + } + /* Do not let a device flood us to death! */ if (dev->done.qlen > 1024) { netif_dbg(dev, rx_err, dev->net, "done queue filling up (%u) - throttling\n", dev->done.qlen); @@ -482,6 +491,7 @@ static void rx_complete (struct urb *urb) struct usbnet *dev = entry->dev; int urb_status = urb->status; enum skb_state state; + static int counter, bogus; skb_put (skb, urb->actual_length); state = rx_done; @@ -547,6 +557,17 @@ block: break; } + /* keep track of bogus packet ratio */ + if (++counter > 30) { + counter = bogus = 0; + clear_bit(EVENT_RX_THROTTLE, &dev->flags); + } else { + if (state == rx_cleanup) + bogus++; + if (bogus > counter/2) + set_bit(EVENT_RX_THROTTLE, &dev->flags); + } + state = defer_bh(dev, skb, &dev->rxq, state); if (urb) { -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] net: usbnet: prevent buggy devices from killing us
On Thu, 2013-01-24 at 16:39 +0400, Sergei Shtylyov wrote: > On 24-01-2013 14:25, Bjørn Mork wrote: > > A device sending 0 length frames as fast as it can has been > > observed killing the host system due to the resulting memory > > pressure. [] > > diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c [] > > + /* Do not let a device flood us to death! */ > > + if (dev->done.qlen > 1024) { > > + netif_dbg(dev, rx_err, dev->net, "done queue filling up (%u) - > > throttling\n", dev->done.qlen); > > + usbnet_defer_kevent (dev, EVENT_RX_MEMORY); > > + usb_free_urb (urb); > > Run your patch thru scripts/checkpatch.pl please And maybe ratelimit the netif_dbg -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/9] usb: chipidea: drop redundant includes
Sergei Shtylyov writes: >But you also add some #include's, and don't document this in the changelog. Nice catch, thanks! Regards, -- Alex -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] net: usbnet: prevent buggy devices from killing us
On Thursday 24 January 2013 13:47:40 Bjørn Mork wrote: > Oliver Neukum writes: > > On Thursday 24 January 2013 12:22:54 Bjørn Mork wrote: > > > >> Sorry for being daft, but how do I code the "20 among the last 30" part > >> there? > > > > Just by agreeing that you can live with false negatives but not false > > positives > > > > if (++counter > 30) { > > counter = bogus = 0; > > } else { > > if (is_bogus(packet) > > bogus++; > > if (bogus > counter/2) Should probably be something like bogus > counter/2 + 10 > > throttle(); > > } > > So, add two new counters to struct usbnet for this? That seems a little > overkill to me, but I don't see how else to implement anything like that. Memory is cheap. > It is still not completely clear to me how the throttling/unthrottling > should be done. It tested with static counters (to avoid having to > rebuild everything for this test) and a new EVENT_RX_THROTTLE flag. > Still on top of my previous patch just for safety while testing, as I am > fed up of having to reboot all the time :-) > > Doing the flag test in rx_submit seems simpler than trying to track all > the places this is called. Still checking the dev->done.qlen to be able > to unthrottle. Ideally we would do some error handling. Does the device keep spewing zero packets for all eternity? Regards Oliver -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/2] usb: exynos: Fix compatible strings used for device
Using chip specific compatible string as it should be. So fixing this for ehci-s5p, ohci-exynos and dwc3-exynos which till now used a generic 'exynos' in their compatible strings. Changes from v1: - Changing compatible string from "samsung,exynos5250-dwc3" to "samsung,exynos5250-dwusb3" as per discussion happened in thread: [PATCH 0/2] usb: exynos: Fix compatible strings used for device. Vivek Gautam (2): usb: ehci-s5p/ohci-exynos: Fix compatible strings for the device usb: dwc3-exynos: Fix compatible strings for the device drivers/usb/dwc3/dwc3-exynos.c |2 +- drivers/usb/host/ehci-s5p.c|2 +- drivers/usb/host/ohci-exynos.c |2 +- 3 files changed, 3 insertions(+), 3 deletions(-) -- 1.7.6.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/2] usb: ehci-s5p/ohci-exynos: Fix compatible strings for the device
Using specific chip in compatible strings. Newer SOCs can claim device by using older string in the compatible list. Signed-off-by: Vivek Gautam Acked-by: Grant Likely Reviewed-by: Doug Anderson --- drivers/usb/host/ehci-s5p.c|2 +- drivers/usb/host/ohci-exynos.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 319dcfa..f18e6ac 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -266,7 +266,7 @@ static const struct dev_pm_ops s5p_ehci_pm_ops = { #ifdef CONFIG_OF static const struct of_device_id exynos_ehci_match[] = { - { .compatible = "samsung,exynos-ehci" }, + { .compatible = "samsung,exynos4210-ehci" }, {}, }; MODULE_DEVICE_TABLE(of, exynos_ehci_match); diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index aa3b884..77f2017 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -267,7 +267,7 @@ static const struct dev_pm_ops exynos_ohci_pm_ops = { #ifdef CONFIG_OF static const struct of_device_id exynos_ohci_match[] = { - { .compatible = "samsung,exynos-ohci" }, + { .compatible = "samsung,exynos4210-ohci" }, {}, }; MODULE_DEVICE_TABLE(of, exynos_ohci_match); -- 1.7.6.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/2] usb: dwc3-exynos: Fix compatible strings for the device
Using specific chip in compatible strings. Newer SOCs can claim device by using older string in the compatible list. Signed-off-by: Vivek Gautam Acked-by: Grant Likely Reviewed-by: Doug Anderson --- drivers/usb/dwc3/dwc3-exynos.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index aae5328..e2207a6 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -188,7 +188,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev) #ifdef CONFIG_OF static const struct of_device_id exynos_dwc3_match[] = { - { .compatible = "samsung,exynos-dwc3" }, + { .compatible = "samsung,exynos5250-dwusb3" }, {}, }; MODULE_DEVICE_TABLE(of, exynos_dwc3_match); -- 1.7.6.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] net: usbnet: prevent buggy devices from killing us
Oliver Neukum writes: > On Thursday 24 January 2013 13:47:40 Bjørn Mork wrote: >> Oliver Neukum writes: >> > On Thursday 24 January 2013 12:22:54 Bjørn Mork wrote: >> > >> >> Sorry for being daft, but how do I code the "20 among the last 30" part >> >> there? >> > >> > Just by agreeing that you can live with false negatives but not false >> > positives >> > >> > if (++counter > 30) { >> >counter = bogus = 0; >> > } else { >> >if (is_bogus(packet) >> >bogus++; >> >if (bogus > counter/2) > > Should probably be something like bogus > counter/2 + 10 right >> >throttle(); >> > } >> >> So, add two new counters to struct usbnet for this? That seems a little >> overkill to me, but I don't see how else to implement anything like that. > > Memory is cheap. OK >> It is still not completely clear to me how the throttling/unthrottling >> should be done. It tested with static counters (to avoid having to >> rebuild everything for this test) and a new EVENT_RX_THROTTLE flag. >> Still on top of my previous patch just for safety while testing, as I am >> fed up of having to reboot all the time :-) >> >> Doing the flag test in rx_submit seems simpler than trying to track all >> the places this is called. Still checking the dev->done.qlen to be able >> to unthrottle. > > Ideally we would do some error handling. Does the device keep spewing > zero packets for all eternity? Yes. The only way to get rid of the bug once it has triggered seems to be powering the device off/on. So unthrottling is not important for this device. But I guess it will be for other devices with more temporary problems. Bjørn -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH] uvc_v4l2: reset connection on uvc open
On Thu, Jan 24, 2013 at 12:02:12PM +0100, Laurent Pinchart wrote: > Hi Michael, > > On Thursday 24 January 2013 11:22:02 Michael Grzeschik wrote: > > The current implementation of the composite framework connects the > > gadget function to the device-controller at kernel boottime. > > > > It's possible that the userspace application, which handles the > > enumeration requests of the gadget, starts with high latency when the > > host did already gave up to detect the gadget. In that case the > > gadget-application will not work in the first case. > > This shouldn't happen, as the UVC gadget driver should start disconnected (it > calls usb_function_deactive() in uvc_function_bind()). If the host can > enumerate the gadget before the application starts it would then likely be a > device controller driver bug, not a UVC gadget driver bug. Unlikely this is not the case, as usb_gadget_probe_driver triggers an usb_gadget_connect() right after driver->bind() was called. That is not a device controller bug. Regards, Michael -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: usb device removed from sysfs before input children devices
On Tue, 2013-01-15 at 20:27 +, Karl Relton wrote: > > The end result (for the user) is that even when the bluetooth > > mouse/keyboard is re-added, Xorg ignores it - thinking it is some > hoax > > duplicate device. The keyboard/mouse is then non-operational. > > > > Instrumenting the code suggests that the issue arises in a race > between: > > hidp_session() in bluetooth/hidp/core.c > > and > > hci_unregister_dev() in bluetooth/hci_core.c > > > Basically hci_unregister_dev() does a hci_dev_do_close() which in turn > shuts down the hidp connection. This causes hidp_session() running in > another thread to go into its cleanup phase, which is where the input > children devices are unregistered. > > HOWEVER: > 1) For some reason input_unregister_device() seems to stall some 3-5 > seconds on my system before removing the input device > 2) In parallel hci_unregister_dev() ploughs on, and progresses to > remove > its hdev (hci device) regardless, without waiting for > hidp_session() > to complete. > > I can't figure out why there is such a delay for > input_unregister_device(). The power_supply system seems to be triggering a lookup of battery 'capacity' in the input device. This calls into the driver, which deep down invokes more code in the 'hidp' module: hidp_get_raw_report() This function tries to communicate with the bluetooth device (keyboard in my case), but because the device is being 'torn down' such communication fails. Accordingly hidp_get_raw_report has a 5 second timeout ... so this function stalls for 5 seconds until that timeout occurs. I would guess that for some reason, removing the 'hid' or associated 'input' device is leading to the power_supply code wanting to lookup the battery capacity which introduces a 5 second wait. This would delay hidp_session by 5 seconds ... in the mean time allowing hci_unregister_dev() to win the race and hence the hci device is removed before the input & hid devices. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 0/2] usb: exynos: Fix compatible strings used for device
On Thu, Jan 24, 2013 at 7:15 PM, Vivek Gautam wrote: > Using chip specific compatible string as it should be. > So fixing this for ehci-s5p, ohci-exynos and dwc3-exynos > which till now used a generic 'exynos' in their compatible strings. > > Changes from v1: > - Changing compatible string from "samsung,exynos5250-dwc3" to > "samsung,exynos5250-dwusb3" as per discussion happened in thread: > [PATCH 0/2] usb: exynos: Fix compatible strings used for device. > Based on 'usb-next' branch. > Vivek Gautam (2): > usb: ehci-s5p/ohci-exynos: Fix compatible strings for the device > usb: dwc3-exynos: Fix compatible strings for the device > > drivers/usb/dwc3/dwc3-exynos.c |2 +- > drivers/usb/host/ehci-s5p.c|2 +- > drivers/usb/host/ohci-exynos.c |2 +- > 3 files changed, 3 insertions(+), 3 deletions(-) > > -- > 1.7.6.5 > -- Thanks & Regards Vivek -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] usb: host: tegra: make use of PHY pointer of HCD
Hi, On Thu, Jan 24, 2013 at 03:57:03PM +0530, Venu Byravarasu wrote: > As pointer to PHY structure can be stored in struct usb_hcd > making use of it, to call Tegra PHY APIs. > > Call to usb_phy_shutdown() is moved up in tegra_ehci_remove(), > so that to avoid dereferencing of hcd after its freed up. > > Signed-off-by: Venu Byravarasu > --- > First version of patch can be found at > http://marc.info/?l=linux-kernel&m=135581479020213&w=2. As it was not > yet applied, sending v2 of the patch. > > delta from v1: > Modified all Tegra PHY APIs to use standard 'structu usb_phy *' as > their parameter instead of proprietary parameter of type 'struct > tegra_usb_phy *'. I would like to see those tegra-specific functions vanish from the driver. Can that be done for v3.10 merge window ? -- balbi signature.asc Description: Digital signature
Re: [RESEND PATCH v5 3/7] usb: chipidea: add otg id switch and vbus connect/disconnect detect
Peter Chen writes: > The main design flow is the same with msm otg driver, that is the id and > vbus interrupt are handled at core driver, others are handled by > individual drivers. > > - At former design, when switch usb role from device->host, it will call > udc_stop, it will remove the gadget driver, so when switch role > from host->device, it can't add gadget driver any more. > At new design, when role switch occurs, the gadget just calls > usb_gadget_vbus_disconnect/usb_gadget_vbus_connect as well as > reset controller, it will not free any device/gadget structure > > - Add vbus connect and disconnect to core interrupt handler, it can > notify udc driver by calling usb_gadget_vbus_disconnect > /usb_gadget_vbus_connect. > > Signed-off-by: Peter Chen A few comments below. > --- > drivers/usb/chipidea/bits.h | 10 +++ > drivers/usb/chipidea/ci.h |8 ++- > drivers/usb/chipidea/core.c | 177 ++ > drivers/usb/chipidea/otg.c | 28 +--- > drivers/usb/chipidea/otg.h |3 + > drivers/usb/chipidea/udc.c |2 + > 6 files changed, 200 insertions(+), 28 deletions(-) > > diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h > index 050de85..ba9c6ef 100644 > --- a/drivers/usb/chipidea/bits.h > +++ b/drivers/usb/chipidea/bits.h > @@ -65,11 +65,21 @@ > #define OTGSC_ASVISBIT(18) > #define OTGSC_BSVISBIT(19) > #define OTGSC_BSEISBIT(20) > +#define OTGSC_1MSISBIT(21) > +#define OTGSC_DPIS BIT(22) > #define OTGSC_IDIE BIT(24) > #define OTGSC_AVVIEBIT(25) > #define OTGSC_ASVIEBIT(26) > #define OTGSC_BSVIEBIT(27) > #define OTGSC_BSEIEBIT(28) > +#define OTGSC_1MSIEBIT(29) > +#define OTGSC_DPIE BIT(30) > +#define OTGSC_INT_EN_BITS(OTGSC_IDIE | OTGSC_AVVIE | OTGSC_ASVIE \ > + | OTGSC_BSVIE | OTGSC_BSEIE | OTGSC_1MSIE \ > + | OTGSC_DPIE) > +#define OTGSC_INT_STATUS_BITS(OTGSC_IDIS | OTGSC_AVVIS | OTGSC_ASVIS > \ > + | OTGSC_BSVIS | OTGSC_BSEIS | OTGSC_1MSIS \ > + | OTGSC_DPIS) > > /* USBMODE */ > #define USBMODE_CM(0x03UL << 0) > diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h > index 8702871..325d790 100644 > --- a/drivers/usb/chipidea/ci.h > +++ b/drivers/usb/chipidea/ci.h > @@ -130,6 +130,7 @@ struct hw_bank { > * @transceiver: pointer to USB PHY, if any > * @hcd: pointer to usb_hcd for ehci host driver > * @otg: for otg support > + * @events: events for otg, and handled at ci_role_work > */ > struct ci13xxx { > struct device *dev; > @@ -140,6 +141,7 @@ struct ci13xxx { > enum ci_rolerole; > boolis_otg; > struct work_struct work; > + struct delayed_work dwork; > struct workqueue_struct *wq; > > struct dma_pool *qh_pool; > @@ -165,7 +167,9 @@ struct ci13xxx { > boolglobal_phy; > struct usb_phy *transceiver; > struct usb_hcd *hcd; > - struct usb_otg otg; > + struct usb_otg otg; > + boolid_event; > + boolb_sess_valid_event; > }; > > static inline struct ci_role_driver *ci_role(struct ci13xxx *ci) > @@ -314,4 +318,6 @@ int hw_port_test_set(struct ci13xxx *ci, u8 mode); > > u8 hw_port_test_get(struct ci13xxx *ci); > > +void ci_handle_vbus_change(struct ci13xxx *ci); > + > #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */ > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c > index aebf695..f8f8484 100644 > --- a/drivers/usb/chipidea/core.c > +++ b/drivers/usb/chipidea/core.c > @@ -73,6 +73,7 @@ > #include "bits.h" > #include "host.h" > #include "debug.h" > +#include "otg.h" > > /* Controller register map */ > static uintptr_t ci_regs_nolpm[] = { > @@ -199,6 +200,14 @@ static int hw_device_init(struct ci13xxx *ci, void > __iomem *base) > if (ci->hw_ep_max > ENDPT_MAX) > return -ENODEV; > > + /* Disable all interrupts bits */ > + hw_write(ci, OP_USBINTR, 0x, 0); > + ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS); > + > + /* Clear all interrupts status bits*/ > + hw_write(ci, OP_USBSTS, 0x, 0x); > + ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS); > + > dev_dbg(ci->dev, "ChipIdea HDRC found, lpm: %d; cap: %p op: %p\n", > ci->hw_bank.lpm, ci->hw_bank.cap, ci->hw_bank.op); > > @@ -265,24 +274,124 @@ static enum ci_role ci_otg_role(struct ci13xxx *ci) > } > > /** > - * ci_role_work - perform role changing based on ID pin > - * @work: work struct > + * hw_wait_reg: wait the register value > + * > + * Sometimes, it needs to wa
Re: [RFC PATCH] uvc_v4l2: reset connection on uvc open
Hi Michael, On Thursday 24 January 2013 14:54:01 Michael Grzeschik wrote: > On Thu, Jan 24, 2013 at 12:02:12PM +0100, Laurent Pinchart wrote: > > On Thursday 24 January 2013 11:22:02 Michael Grzeschik wrote: > > > The current implementation of the composite framework connects the > > > gadget function to the device-controller at kernel boottime. > > > > > > It's possible that the userspace application, which handles the > > > enumeration requests of the gadget, starts with high latency when the > > > host did already gave up to detect the gadget. In that case the > > > gadget-application will not work in the first case. > > > > This shouldn't happen, as the UVC gadget driver should start disconnected > > (it calls usb_function_deactive() in uvc_function_bind()). If the host > > can enumerate the gadget before the application starts it would then > > likely be a device controller driver bug, not a UVC gadget driver bug. > > Unlikely this is not the case, as usb_gadget_probe_driver triggers an > usb_gadget_connect() right after driver->bind() was called. Indeed, for new-style UDC that's correct. Isn't that an issue with the framework ? I would expect gadget drivers to be able to start disconnected. > That is not a device controller bug. -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RESEND PATCH v5 4/7] usb: chipidea: consolidate ci_role_driver's API for both roles
Peter Chen writes: > - Create init/destroy API for probe and remove > - start/stop API are only used otg id switch process > - Create the gadget at ci_hdrc_probe if the gadget is supported > at that port, the main purpose for this is to avoid gadget module > load fail at init.rc I don't think it's necessary to mention android-specific init scripts here in our patches. > Signed-off-by: Peter Chen > --- > drivers/usb/chipidea/ci.h | 19 +++- > drivers/usb/chipidea/core.c | 65 ++ > drivers/usb/chipidea/host.c |2 + > drivers/usb/chipidea/udc.c | 33 - > 4 files changed, 78 insertions(+), 41 deletions(-) > > diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h > index 325d790..00939e6 100644 > --- a/drivers/usb/chipidea/ci.h > +++ b/drivers/usb/chipidea/ci.h > @@ -67,14 +67,18 @@ enum ci_role { > > /** > * struct ci_role_driver - host/gadget role driver > - * start: start this role > - * stop: stop this role > + * init: init this role (used at module probe) > + * start: start this role (used at id switch) > + * stop: stop this role (used at id switch) > + * destroy: destroy this role (used at module remove) > * irq: irq handler for this role > * name: role name string (host/gadget) > */ > struct ci_role_driver { > + int (*init)(struct ci13xxx *); > int (*start)(struct ci13xxx *); > void(*stop)(struct ci13xxx *); > + void(*destroy)(struct ci13xxx *); > irqreturn_t (*irq)(struct ci13xxx *); > const char *name; > }; > @@ -206,6 +210,17 @@ static inline void ci_role_stop(struct ci13xxx *ci) > ci->roles[role]->stop(ci); > } > > +static inline void ci_role_destroy(struct ci13xxx *ci) > +{ > + enum ci_role role = ci->role; > + > + if (role == CI_ROLE_END) > + return; > + > + ci->role = CI_ROLE_END; > + > + ci->roles[role]->destroy(ci); > +} What does this do? It should take role an a parameter, at least. Or it can be called ci_roles_destroy() and, well, destroy all the roles. Now we're in a situation where we destroy one. The idea is that, with this api, we can (and should) have both roles allocated all the time, but only one role start()'ed. What we can do here is move the udc's .init() code to ci_hdrc_gadget_init() and add a complementary ci_hdrc_gadget_destroy(), which we call in ci_hdrc_remove() and probe's error path. And we can probably do something similar for the host, or just leave it as it is now. Seems simpler to me. > > /** > * REGISTERS > > */ > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c > index f8f8484..a5adf1a 100644 > --- a/drivers/usb/chipidea/core.c > +++ b/drivers/usb/chipidea/core.c > @@ -315,27 +315,16 @@ static void ci_handle_id_switch(struct ci13xxx *ci) > ci_role(ci)->name, ci->roles[role]->name); > > /* 1. Finish the current role */ > - if (ci->role == CI_ROLE_GADGET) { > - usb_gadget_vbus_disconnect(&ci->gadget); > - /* host doesn't care B_SESSION_VALID event */ > - ci_clear_otg_interrupt(ci, OTGSC_BSVIS); > - ci_disable_otg_interrupt(ci, OTGSC_BSVIE); > - ci->role = CI_ROLE_END; > - /* reset controller */ > - hw_device_reset(ci, USBMODE_CM_IDLE); > - } else if (ci->role == CI_ROLE_HOST) { > - ci_role_stop(ci); > - /* reset controller */ > - hw_device_reset(ci, USBMODE_CM_IDLE); > - } > + ci_role_stop(ci); > + hw_device_reset(ci, USBMODE_CM_IDLE); > > /* 2. Turn on/off vbus according to coming role */ > - if (ci_otg_role(ci) == CI_ROLE_GADGET) { > + if (role == CI_ROLE_GADGET) { > otg_set_vbus(&ci->otg, false); > /* wait vbus lower than OTGSC_BSV */ > hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0, > CI_VBUS_STABLE_TIMEOUT); > - } else if (ci_otg_role(ci) == CI_ROLE_HOST) { > + } else if (role == CI_ROLE_HOST) { > otg_set_vbus(&ci->otg, true); > /* wait vbus higher than OTGSC_AVV */ > hw_wait_reg(ci, OP_OTGSC, OTGSC_AVV, OTGSC_AVV, > @@ -343,13 +332,7 @@ static void ci_handle_id_switch(struct ci13xxx *ci) > } > > /* 3. Begin the new role */ > - if (ci_otg_role(ci) == CI_ROLE_GADGET) { > - ci->role = role; > - ci_clear_otg_interrupt(ci, OTGSC_BSVIS); > -
Re: [RFC PATCH] uvc_v4l2: reset connection on uvc open
On Thu, Jan 24, 2013 at 03:21:37PM +0100, Laurent Pinchart wrote: > Hi Michael, > > On Thursday 24 January 2013 14:54:01 Michael Grzeschik wrote: > > On Thu, Jan 24, 2013 at 12:02:12PM +0100, Laurent Pinchart wrote: > > > On Thursday 24 January 2013 11:22:02 Michael Grzeschik wrote: > > > > The current implementation of the composite framework connects the > > > > gadget function to the device-controller at kernel boottime. > > > > > > > > It's possible that the userspace application, which handles the > > > > enumeration requests of the gadget, starts with high latency when the > > > > host did already gave up to detect the gadget. In that case the > > > > gadget-application will not work in the first case. > > > > > > This shouldn't happen, as the UVC gadget driver should start disconnected > > > (it calls usb_function_deactive() in uvc_function_bind()). If the host > > > can enumerate the gadget before the application starts it would then > > > likely be a device controller driver bug, not a UVC gadget driver bug. > > > > Unlikely this is not the case, as usb_gadget_probe_driver triggers an > > usb_gadget_connect() right after driver->bind() was called. > > Indeed, for new-style UDC that's correct. > > Isn't that an issue with the framework ? I would expect gadget drivers to be > able to start disconnected. That probably is. But it might only be a problem for gadgets with userspace components which handle ep0 requests. For other gadgets, which are not as dynamic as an webcam, it might be enough to have its enumeration handled in kernel and start right on. That needs further discussion. Therefore my patch is an RFC and a simple solution to ship arround that issue. Should we take it though? -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH] uvc_v4l2: reset connection on uvc open
On Thu, Jan 24, 2013 at 03:35:58PM +0100, Michael Grzeschik wrote: > On Thu, Jan 24, 2013 at 03:21:37PM +0100, Laurent Pinchart wrote: > > Hi Michael, > > > > On Thursday 24 January 2013 14:54:01 Michael Grzeschik wrote: > > > On Thu, Jan 24, 2013 at 12:02:12PM +0100, Laurent Pinchart wrote: > > > > On Thursday 24 January 2013 11:22:02 Michael Grzeschik wrote: > > > > > The current implementation of the composite framework connects the > > > > > gadget function to the device-controller at kernel boottime. > > > > > > > > > > It's possible that the userspace application, which handles the > > > > > enumeration requests of the gadget, starts with high latency when the > > > > > host did already gave up to detect the gadget. In that case the > > > > > gadget-application will not work in the first case. > > > > > > > > This shouldn't happen, as the UVC gadget driver should start > > > > disconnected > > > > (it calls usb_function_deactive() in uvc_function_bind()). If the host > > > > can enumerate the gadget before the application starts it would then > > > > likely be a device controller driver bug, not a UVC gadget driver bug. > > > > > > Unlikely this is not the case, as usb_gadget_probe_driver triggers an > > > usb_gadget_connect() right after driver->bind() was called. > > > > Indeed, for new-style UDC that's correct. > > > > Isn't that an issue with the framework ? I would expect gadget drivers to > > be > > able to start disconnected. > > That probably is. But it might only be a problem for gadgets with > userspace components which handle ep0 requests. For other gadgets, which > are not as dynamic as an webcam, it might be enough to have its > enumeration handled in kernel and start right on. > > That needs further discussion. Therefore my patch is an RFC and a simple > solution to ship arround that issue. Should we take it though? Framework will take care of it, but other controllers need to be fixed up first so they don't connect their pullup directly. We're getting close to that, though. Give me another merge window and gadget drivers will be required to manage pullup. -- balbi signature.asc Description: Digital signature
Re: [PATCH] usb: Prevent dead ports when xhci is not enabled
On Wed, Jan 23, 2013 at 10:19:49PM -0800, David Moore wrote: > From: David Moore > > When the xHCI driver is not available, actively switch the ports to EHCI > mode since some BIOSes leave them in xHCI mode where they would > otherwise appear dead. > > Signed-off-by: David Moore > --- > drivers/usb/host/pci-quirks.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c > index eb5563a..7893351 100644 > --- a/drivers/usb/host/pci-quirks.c > +++ b/drivers/usb/host/pci-quirks.c > @@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) > "defaulting to EHCI.\n"); > dev_warn(&xhci_pdev->dev, > "USB 3.0 devices will work at USB 2.0 > speeds.\n"); > + usb_disable_xhci_ports(xhci_pdev); Any specifics as to exactly what hardware types need this patch? I'm guessing this should also go to the stable kernel releases as well? thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH] uvc_v4l2: reset connection on uvc open
Hi Felipe, On Thursday 24 January 2013 16:42:50 Felipe Balbi wrote: > On Thu, Jan 24, 2013 at 03:35:58PM +0100, Michael Grzeschik wrote: > > On Thu, Jan 24, 2013 at 03:21:37PM +0100, Laurent Pinchart wrote: > > > On Thursday 24 January 2013 14:54:01 Michael Grzeschik wrote: > > > > On Thu, Jan 24, 2013 at 12:02:12PM +0100, Laurent Pinchart wrote: > > > > > On Thursday 24 January 2013 11:22:02 Michael Grzeschik wrote: > > > > > > The current implementation of the composite framework connects the > > > > > > gadget function to the device-controller at kernel boottime. > > > > > > > > > > > > It's possible that the userspace application, which handles the > > > > > > enumeration requests of the gadget, starts with high latency when > > > > > > the host did already gave up to detect the gadget. In that case > > > > > > the gadget-application will not work in the first case. > > > > > > > > > > This shouldn't happen, as the UVC gadget driver should start > > > > > disconnected (it calls usb_function_deactive() in > > > > > uvc_function_bind()). If the host can enumerate the gadget before > > > > > the application starts it would then likely be a device controller > > > > > driver bug, not a UVC gadget driver bug. > > > > > > > > Unlikely this is not the case, as usb_gadget_probe_driver triggers an > > > > usb_gadget_connect() right after driver->bind() was called. > > > > > > Indeed, for new-style UDC that's correct. > > > > > > Isn't that an issue with the framework ? I would expect gadget drivers > > > to be able to start disconnected. > > > > That probably is. But it might only be a problem for gadgets with > > userspace components which handle ep0 requests. For other gadgets, which > > are not as dynamic as an webcam, it might be enough to have its > > enumeration handled in kernel and start right on. > > > > That needs further discussion. Therefore my patch is an RFC and a simple > > solution to ship arround that issue. Should we take it though? > > Framework will take care of it, but other controllers need to be fixed > up first so they don't connect their pullup directly. > > We're getting close to that, though. Give me another merge window and > gadget drivers will be required to manage pullup. Thanks :-) -- Regards, Laurent Pinchart signature.asc Description: This is a digitally signed message part.
Re: [PATCH 2/2 v2] drivers/usb/host/uhci-*: beautify source code
On Thu, 24 Jan 2013, Chen Gang wrote: > get rid of the line breaks in string constants. > let comments within 80 with limitation. > delete ' \' at the end of a statement. > > Signed-off-by: Chen Gang Acked-by: Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/8] usb: gadget: adm5536udc: convert to udc_start/udc_stop
HI, On Thu, Jan 24, 2013 at 11:01:24AM +0200, Felipe Balbi wrote: > Mechanical change making use of the new (can we > still call it new ?) interface for registering > UDC drivers. > > Signed-off-by: Felipe Balbi I'll resend this series, my grep missed pxa folks. -- balbi signature.asc Description: Digital signature
Re: [RESEND PATCH v5 3/7] usb: chipidea: add otg id switch and vbus connect/disconnect detect
Peter Chen writes: > The main design flow is the same with msm otg driver, that is the id and > vbus interrupt are handled at core driver, others are handled by > individual drivers. > > - At former design, when switch usb role from device->host, it will call > udc_stop, it will remove the gadget driver, so when switch role > from host->device, it can't add gadget driver any more. > At new design, when role switch occurs, the gadget just calls > usb_gadget_vbus_disconnect/usb_gadget_vbus_connect as well as > reset controller, it will not free any device/gadget structure > > - Add vbus connect and disconnect to core interrupt handler, it can > notify udc driver by calling usb_gadget_vbus_disconnect > /usb_gadget_vbus_connect. > > Signed-off-by: Peter Chen [snip] > @@ -483,6 +614,17 @@ static int ci_hdrc_probe(struct platform_device *pdev) > goto rm_wq; > } > > + otgsc = hw_read(ci, OP_OTGSC, ~0); > + /* > + * if it is device mode: > + * - Enable vbus detect > + * - If it has already connected to host, notify udc > + */ > + if (ci->role == CI_ROLE_GADGET) { > + ci_enable_otg_interrupt(ci, OTGSC_BSVIE); > + ci_handle_vbus_change(ci); > + } > + Actually, this doesn't work, neither here, nor in udc_start(), where the next patch moves it. If you start in host role with A plug, unplug it, plug B and load a gadget module, it won't start till you replug the cable, which is where vbus detection happens. So, when you say that vbus detection is "fully tested", what is the test case set that you're using? One obvious fix is to move ci_handle_vbus_change() call to ci13xxx_start(), but I need to think about the whole thing a bit more. Regards, -- Alex -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/11] usb: gadget: adm5536udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/amd5536udc.c | 59 ++--- drivers/usb/gadget/amd5536udc.h | 2 ++ 2 files changed, 16 insertions(+), 45 deletions(-) diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index fc0ec5e..3dac001 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -1400,15 +1400,16 @@ static int udc_wakeup(struct usb_gadget *gadget) return 0; } -static int amd5536_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int amd5536_stop(struct usb_gadget_driver *driver); +static int amd5536_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int amd5536_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); /* gadget operations */ static const struct usb_gadget_ops udc_ops = { .wakeup = udc_wakeup, .get_frame = udc_get_frame, - .start = amd5536_start, - .stop = amd5536_stop, + .udc_start = amd5536_udc_start, + .udc_stop = amd5536_udc_stop, }; /* Setups endpoint parameters, adds endpoints to linked list */ @@ -1913,41 +1914,22 @@ static int setup_ep0(struct udc *dev) } /* Called by gadget driver to register itself */ -static int amd5536_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int amd5536_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct udc *dev = udc; - int retval; + struct udc *dev = to_amd5536_udc(g); u32 tmp; - if (!driver || !bind || !driver->setup - || driver->max_speed < USB_SPEED_HIGH) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; - driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - retval = bind(&dev->gadget, driver); - /* Some gadget drivers use both ep0 directions. * NOTE: to gadget driver, ep0 is just one endpoint... */ dev->ep[UDC_EP0OUT_IX].ep.driver_data = dev->ep[UDC_EP0IN_IX].ep.driver_data; - if (retval) { - DBG(dev, "binding to %s returning %d\n", - driver->driver.name, retval); - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - /* get ready for ep0 traffic */ setup_ep0(dev); @@ -1969,14 +1951,9 @@ __acquires(dev->lock) { int tmp; - if (dev->gadget.speed != USB_SPEED_UNKNOWN) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - /* empty queues and init hardware */ udc_basic_init(dev); + for (tmp = 0; tmp < UDC_EP_NUM; tmp++) empty_req_queue(&dev->ep[tmp]); @@ -1984,23 +1961,18 @@ __acquires(dev->lock) } /* Called by gadget driver to unregister itself */ -static int amd5536_stop(struct usb_gadget_driver *driver) +static int amd5536_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct udc *dev = udc; - unsigned long flags; + struct udc *dev = to_amd5536_udc(g); + unsigned long flags; u32 tmp; - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; - spin_lock_irqsave(&dev->lock, flags); udc_mask_unused_interrupts(dev); shutdown(dev, driver); spin_unlock_irqrestore(&dev->lock, flags); - driver->unbind(&dev->gadget); dev->gadget.dev.driver = NULL; dev->driver = NULL; @@ -2009,9 +1981,6 @@ static int amd5536_stop(struct usb_gadget_driver *driver) tmp |= AMD_BIT(UDC_DEVCTL_SD); writel(tmp, &dev->regs->ctl); - - DBG(dev, "%s: unregistered\n", driver->driver.name); - return 0; } diff --git a/drivers/usb/gadget/amd5536udc.h b/drivers/usb/gadget/amd5536udc.h index 14af87d..f1bf32e 100644 --- a/drivers/usb/gadget/amd5536udc.h +++ b/drivers/usb/gadget/amd5536udc.h @@ -563,6 +563,8 @@ struct udc { u16 cur_alt; }; +#define to_amd5536_udc(g) (container_of((g), struct udc, gadget)) + /* setup request data */ union udc_setup_data { u32 data[2]; -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.
[PATCH 02/11] usb: gadget: fusb300_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fusb300_udc.c | 65 +++- drivers/usb/gadget/fusb300_udc.h | 2 ++ 2 files changed, 20 insertions(+), 47 deletions(-) diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 72cd5e6..8c2372f 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1308,65 +1308,28 @@ static void init_controller(struct fusb300 *fusb300) iowrite32(0xcf9f, fusb300->reg + FUSB300_OFFSET_IGER1); } /**/ -static struct fusb300 *the_controller; - -static int fusb300_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int fusb300_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct fusb300 *fusb300 = the_controller; - int retval; - - if (!driver - || driver->max_speed < USB_SPEED_FULL - || !bind - || !driver->setup) - return -EINVAL; - - if (!fusb300) - return -ENODEV; - - if (fusb300->driver) - return -EBUSY; + struct fusb300 *fusb300 = to_fusb300(g); /* hook up the driver */ driver->driver.bus = NULL; fusb300->driver = driver; fusb300->gadget.dev.driver = &driver->driver; - retval = device_add(&fusb300->gadget.dev); - if (retval) { - pr_err("device_add error (%d)\n", retval); - goto error; - } - - retval = bind(&fusb300->gadget, driver); - if (retval) { - pr_err("bind to driver error (%d)\n", retval); - device_del(&fusb300->gadget.dev); - goto error; - } - return 0; - -error: - fusb300->driver = NULL; - fusb300->gadget.dev.driver = NULL; - - return retval; } -static int fusb300_udc_stop(struct usb_gadget_driver *driver) +static int fusb300_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct fusb300 *fusb300 = the_controller; - - if (driver != fusb300->driver || !driver->unbind) - return -EINVAL; + struct fusb300 *fusb300 = to_fusb300(g); driver->unbind(&fusb300->gadget); fusb300->gadget.dev.driver = NULL; init_controller(fusb300); - device_del(&fusb300->gadget.dev); fusb300->driver = NULL; return 0; @@ -1380,8 +1343,8 @@ static int fusb300_udc_pullup(struct usb_gadget *_gadget, int is_active) static struct usb_gadget_ops fusb300_gadget_ops = { .pullup = fusb300_udc_pullup, - .start = fusb300_udc_start, - .stop = fusb300_udc_stop, + .udc_start = fusb300_udc_start, + .udc_stop = fusb300_udc_stop, }; static int __exit fusb300_remove(struct platform_device *pdev) @@ -1505,8 +1468,6 @@ static int __init fusb300_probe(struct platform_device *pdev) fusb300->gadget.ep0 = &fusb300->ep[0]->ep; INIT_LIST_HEAD(&fusb300->gadget.ep0->ep_list); - the_controller = fusb300; - fusb300->ep0_req = fusb300_alloc_request(&fusb300->ep[0]->ep, GFP_KERNEL); if (fusb300->ep0_req == NULL) @@ -1517,9 +1478,19 @@ static int __init fusb300_probe(struct platform_device *pdev) if (ret) goto err_add_udc; + ret = device_add(&fusb300->gadget.dev); + if (ret) { + pr_err("device_add error (%d)\n", ret); + goto err_add_device; + } + dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); return 0; + +err_add_device: + usb_del_gadget_udc(&fusb300->gadget); + err_add_udc: fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); diff --git a/drivers/usb/gadget/fusb300_udc.h b/drivers/usb/gadget/fusb300_udc.h index 542cd83..6ba444a 100644 --- a/drivers/usb/gadget/fusb300_udc.h +++ b/drivers/usb/gadget/fusb300_udc.h @@ -673,4 +673,6 @@ struct fusb300 { u8 reenum; /* if re-enumeration */ }; +#define to_fusb300(g) (container_of((g), struct fusb300, gadget)) + #endif -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/11] usb: gadget: goku_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/goku_udc.c | 70 +-- drivers/usb/gadget/goku_udc.h | 1 + 2 files changed, 15 insertions(+), 56 deletions(-) diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 51037cb..85742d4 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -993,14 +993,15 @@ static int goku_get_frame(struct usb_gadget *_gadget) return -EOPNOTSUPP; } -static int goku_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int goku_stop(struct usb_gadget_driver *driver); +static int goku_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int goku_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops goku_ops = { .get_frame = goku_get_frame, - .start = goku_start, - .stop = goku_stop, + .udc_start = goku_udc_start, + .udc_stop = goku_udc_stop, // no remote wakeup // not selfpowered }; @@ -1339,50 +1340,28 @@ static void udc_enable(struct goku_udc *dev) * - one function driver, initted second */ -static struct goku_udc *the_controller; - /* when a driver is successfully registered, it will receive * control requests including set_configuration(), which enables * non-control requests. then usb traffic follows until a * disconnect is reported. then a host may connect again, or * the driver might get unbound. */ -static int goku_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int goku_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct goku_udc *dev = the_controller; - int retval; - - if (!driver - || driver->max_speed < USB_SPEED_FULL - || !bind - || !driver->disconnect - || !driver->setup) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; + struct goku_udc *dev = to_goku_udc(g); /* hook up the driver */ driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - retval = bind(&dev->gadget, driver); - if (retval) { - DBG(dev, "bind to driver %s --> error %d\n", - driver->driver.name, retval); - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - /* then enable host detection and ep0; and we're ready + /* +* then enable host detection and ep0; and we're ready * for set_configuration as well as eventual disconnect. */ udc_enable(dev); - DBG(dev, "registered gadget driver '%s'\n", driver->driver.name); return 0; } @@ -1400,35 +1379,23 @@ stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver) udc_reset (dev); for (i = 0; i < 4; i++) nuke(&dev->ep [i], -ESHUTDOWN); - if (driver) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } if (dev->driver) udc_enable(dev); } -static int goku_stop(struct usb_gadget_driver *driver) +static int goku_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct goku_udc *dev = the_controller; + struct goku_udc *dev = to_goku_udc(g); unsigned long flags; - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; - spin_lock_irqsave(&dev->lock, flags); dev->driver = NULL; stop_activity(dev, driver); spin_unlock_irqrestore(&dev->lock, flags); - - driver->unbind(&dev->gadget); dev->gadget.dev.driver = NULL; - DBG(dev, "unregistered driver '%s'\n", driver->driver.name); return 0; } @@ -1754,7 +1721,6 @@ static void goku_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); dev->regs = NULL; - the_controller = NULL; INFO(dev, "unbind\n"); } @@ -1770,13 +1736,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) void __iomem*base = NULL; int retval; - /* if you want to support more than one controller in a system, -* usb_gadget_driver_{register,unregister}() must change. -
[PATCH 04/11] usb: gadget: fsl_udc_core: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 58 --- 1 file changed, 11 insertions(+), 47 deletions(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index c19f7f1..49642d4 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1254,9 +1254,10 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) return 0; } -static int fsl_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int fsl_stop(struct usb_gadget_driver *driver); +static int fsl_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int fsl_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); /* defined in gadget.h */ static struct usb_gadget_ops fsl_gadget_ops = { .get_frame = fsl_get_frame, @@ -1265,8 +1266,8 @@ static struct usb_gadget_ops fsl_gadget_ops = { .vbus_session = fsl_vbus_session, .vbus_draw = fsl_vbus_draw, .pullup = fsl_pullup, - .start = fsl_start, - .stop = fsl_stop, + .udc_start = fsl_udc_start, + .udc_stop = fsl_udc_stop, }; /* Set protocol stall on ep0, protocol stall will automatically be cleared @@ -1950,22 +1951,12 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) * Hook to gadget drivers * Called by initialization code of gadget drivers **/ -static int fsl_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int fsl_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - int retval = -ENODEV; + int retval = 0; unsigned long flags = 0; - if (!udc_controller) - return -ENODEV; - - if (!driver || driver->max_speed < USB_SPEED_FULL - || !bind || !driver->disconnect || !driver->setup) - return -EINVAL; - - if (udc_controller->driver) - return -EBUSY; - /* lock is needed but whether should use this lock or another */ spin_lock_irqsave(&udc_controller->lock, flags); @@ -1975,15 +1966,6 @@ static int fsl_start(struct usb_gadget_driver *driver, udc_controller->gadget.dev.driver = &driver->driver; spin_unlock_irqrestore(&udc_controller->lock, flags); - /* bind udc driver to gadget driver */ - retval = bind(&udc_controller->gadget, driver); - if (retval) { - VDBG("bind to %s --> %d", driver->driver.name, retval); - udc_controller->gadget.dev.driver = NULL; - udc_controller->driver = NULL; - goto out; - } - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { /* Suspend the controller until OTG enable it */ udc_controller->stopped = 1; @@ -2009,28 +1991,17 @@ static int fsl_start(struct usb_gadget_driver *driver, udc_controller->ep0_state = WAIT_FOR_SETUP; udc_controller->ep0_dir = 0; } - printk(KERN_INFO "%s: bind to driver %s\n", - udc_controller->gadget.name, driver->driver.name); -out: - if (retval) - printk(KERN_WARNING "gadget driver register failed %d\n", - retval); return retval; } /* Disconnect from gadget driver */ -static int fsl_stop(struct usb_gadget_driver *driver) +static int fsl_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { struct fsl_ep *loop_ep; unsigned long flags; - if (!udc_controller) - return -ENODEV; - - if (!driver || driver != udc_controller->driver || !driver->unbind) - return -EINVAL; - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) otg_set_peripheral(udc_controller->transceiver->otg, NULL); @@ -2051,16 +2022,9 @@ static int fsl_stop(struct usb_gadget_driver *driver) nuke(loop_ep, -ESHUTDOWN); spin_unlock_irqrestore(&udc_controller->lock, flags); - /* report disconnect; the controller is already quiesced */ - driver->disconnect(&udc_controller->gadget); - - /* unbind gadget and unhook driver. */ - driver->unbind(&udc_controller->gadget); udc_controller->gadget.dev.driver = NULL; udc_controller->driver = NULL; - printk(KERN_WARNING "unregistered gadget driver '%s'\n", - driver->driver.name); return 0; } -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http:/
[PATCH 05/11] usb: gadget: m66592-udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/m66592-udc.c | 70 +++-- drivers/usb/gadget/m66592-udc.h | 1 + 2 files changed, 20 insertions(+), 51 deletions(-) diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index b6401f1..0a35db1 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1463,42 +1463,16 @@ static struct usb_ep_ops m66592_ep_ops = { }; /*-*/ -static struct m66592 *the_controller; - -static int m66592_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int m66592_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct m66592 *m66592 = the_controller; - int retval; - - if (!driver - || driver->max_speed < USB_SPEED_HIGH - || !bind - || !driver->setup) - return -EINVAL; - if (!m66592) - return -ENODEV; - if (m66592->driver) - return -EBUSY; + struct m66592 *m66592 = to_m66592(g); /* hook up the driver */ driver->driver.bus = NULL; m66592->driver = driver; m66592->gadget.dev.driver = &driver->driver; - retval = device_add(&m66592->gadget.dev); - if (retval) { - pr_err("device_add error (%d)\n", retval); - goto error; - } - - retval = bind(&m66592->gadget, driver); - if (retval) { - pr_err("bind to driver error (%d)\n", retval); - device_del(&m66592->gadget.dev); - goto error; - } - m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); if (m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS) { m66592_start_xclock(m66592); @@ -1510,26 +1484,12 @@ static int m66592_start(struct usb_gadget_driver *driver, } return 0; - -error: - m66592->driver = NULL; - m66592->gadget.dev.driver = NULL; - - return retval; } -static int m66592_stop(struct usb_gadget_driver *driver) +static int m66592_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct m66592 *m66592 = the_controller; - unsigned long flags; - - if (driver != m66592->driver || !driver->unbind) - return -EINVAL; - - spin_lock_irqsave(&m66592->lock, flags); - if (m66592->gadget.speed != USB_SPEED_UNKNOWN) - m66592_usb_disconnect(m66592); - spin_unlock_irqrestore(&m66592->lock, flags); + struct m66592 *m66592 = to_m66592(g); m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); @@ -1539,8 +1499,8 @@ static int m66592_stop(struct usb_gadget_driver *driver) init_controller(m66592); disable_controller(m66592); - device_del(&m66592->gadget.dev); m66592->driver = NULL; + return 0; } @@ -1568,8 +1528,8 @@ static int m66592_pullup(struct usb_gadget *gadget, int is_on) static struct usb_gadget_ops m66592_gadget_ops = { .get_frame = m66592_get_frame, - .start = m66592_start, - .stop = m66592_stop, + .udc_start = m66592_udc_start, + .udc_stop = m66592_udc_stop, .pullup = m66592_pullup, }; @@ -1578,6 +1538,7 @@ static int __exit m66592_remove(struct platform_device *pdev) struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); usb_del_gadget_udc(&m66592->gadget); + device_del(&m66592->gadget.dev); del_timer_sync(&m66592->timer); iounmap(m66592->reg); @@ -1706,8 +1667,6 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->pipenum2ep[0] = &m66592->ep[0]; m66592->epaddr2ep[0] = &m66592->ep[0]; - the_controller = m66592; - m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); if (m66592->ep0_req == NULL) goto clean_up3; @@ -1715,6 +1674,12 @@ static int __init m66592_probe(struct platform_device *pdev) init_controller(m66592); + ret = device_add(&m66592->gadget.dev); + if (ret) { + pr_err("device_add error (%d)\n", ret); + goto err_device_add; + } + ret = usb_add_gadget_udc(&pdev->dev, &m66592->gadget); if (ret) goto err_add_udc; @@ -1723,6 +1688,9 @@ static int __init m66592_probe(struct platform_device *pdev) return 0; err_add_udc: + device_del(&m66592->gadget.dev); + +err_device_add: m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); clea
[PATCH 06/11] usb: gadget: omap_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 49 +++ 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 8bfe990..d0c87b1 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -1309,9 +1309,10 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on) return 0; } -static int omap_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int omap_udc_stop(struct usb_gadget_driver *driver); +static int omap_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) +static int omap_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static struct usb_gadget_ops omap_gadget_ops = { .get_frame = omap_get_frame, @@ -1320,8 +1321,8 @@ static struct usb_gadget_ops omap_gadget_ops = { .vbus_session = omap_vbus_session, .vbus_draw = omap_vbus_draw, .pullup = omap_pullup, - .start = omap_udc_start, - .stop = omap_udc_stop, + .udc_start = omap_udc_start, + .udc_stop = omap_udc_stop, }; /*-*/ @@ -2041,28 +2042,15 @@ static inline int machine_without_vbus_sense(void) || cpu_is_omap7xx(); } -static int omap_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int omap_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { int status = -ENODEV; struct omap_ep *ep; unsigned long flags; - /* basic sanity tests */ - if (!udc) - return -ENODEV; - if (!driver - /* FIXME if otg, check: driver->is_otg */ - || driver->max_speed < USB_SPEED_FULL - || !bind || !driver->setup) - return -EINVAL; spin_lock_irqsave(&udc->lock, flags); - if (udc->driver) { - spin_unlock_irqrestore(&udc->lock, flags); - return -EBUSY; - } - /* reset state */ list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { ep->irqs = 0; @@ -2084,15 +2072,6 @@ static int omap_udc_start(struct usb_gadget_driver *driver, if (udc->dc_clk != NULL) omap_udc_enable_clock(1); - status = bind(&udc->gadget, driver); - if (status) { - DBG("bind to %s --> %d\n", driver->driver.name, status); - udc->gadget.dev.driver = NULL; - udc->driver = NULL; - goto done; - } - DBG("bound to driver %s\n", driver->driver.name); - omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC); /* connect to bus through transceiver */ @@ -2124,19 +2103,16 @@ static int omap_udc_start(struct usb_gadget_driver *driver, done: if (udc->dc_clk != NULL) omap_udc_enable_clock(0); + return status; } -static int omap_udc_stop(struct usb_gadget_driver *driver) +static int omap_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { unsigned long flags; int status = -ENODEV; - if (!udc) - return -ENODEV; - if (!driver || driver != udc->driver || !driver->unbind) - return -EINVAL; - if (udc->dc_clk != NULL) omap_udc_enable_clock(1); @@ -2152,13 +2128,12 @@ static int omap_udc_stop(struct usb_gadget_driver *driver) udc_quiesce(udc); spin_unlock_irqrestore(&udc->lock, flags); - driver->unbind(&udc->gadget); udc->gadget.dev.driver = NULL; udc->driver = NULL; if (udc->dc_clk != NULL) omap_udc_enable_clock(0); - DBG("unregistered driver '%s'\n", driver->driver.name); + return status; } -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/11] usb: gadget: pch_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 67 +--- 1 file changed, 14 insertions(+), 53 deletions(-) diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 6490c00..a787a8e 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -375,6 +375,7 @@ struct pch_udc_dev { struct pch_udc_cfg_data cfg_data; struct pch_vbus_gpio_data vbus_gpio; }; +#define to_pch_udc(g) (container_of((g), struct pch_udc_dev, gadget)) #define PCH_UDC_PCI_BAR1 #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 @@ -384,7 +385,6 @@ struct pch_udc_dev { static const char ep0_string[] = "ep0in"; static DEFINE_SPINLOCK(udc_stall_spinlock);/* stall spin lock */ -struct pch_udc_dev *pch_udc; /* pointer to device object */ static bool speed_fs; module_param_named(speed_fs, speed_fs, bool, S_IRUGO); MODULE_PARM_DESC(speed_fs, "true for Full speed operation"); @@ -1235,9 +1235,10 @@ static int pch_udc_pcd_vbus_draw(struct usb_gadget *gadget, unsigned int mA) return -EOPNOTSUPP; } -static int pch_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int pch_udc_stop(struct usb_gadget_driver *driver); +static int pch_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int pch_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops pch_udc_ops = { .get_frame = pch_udc_pcd_get_frame, .wakeup = pch_udc_pcd_wakeup, @@ -1245,8 +1246,8 @@ static const struct usb_gadget_ops pch_udc_ops = { .pullup = pch_udc_pcd_pullup, .vbus_session = pch_udc_pcd_vbus_session, .vbus_draw = pch_udc_pcd_vbus_draw, - .start = pch_udc_start, - .stop = pch_udc_stop, + .udc_start = pch_udc_start, + .udc_stop = pch_udc_stop, }; /** @@ -2981,40 +2982,15 @@ static int init_dma_pools(struct pch_udc_dev *dev) return 0; } -static int pch_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int pch_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pch_udc_dev *dev = pch_udc; - int retval; - - if (!driver || (driver->max_speed == USB_SPEED_UNKNOWN) || !bind || - !driver->setup || !driver->unbind || !driver->disconnect) { - dev_err(&dev->pdev->dev, - "%s: invalid driver parameter\n", __func__); - return -EINVAL; - } + struct pch_udc_dev *dev = to_pch_udc(g); - if (!dev) - return -ENODEV; - - if (dev->driver) { - dev_err(&dev->pdev->dev, "%s: already bound\n", __func__); - return -EBUSY; - } driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - /* Invoke the bind routine of the gadget driver */ - retval = bind(&dev->gadget, driver); - - if (retval) { - dev_err(&dev->pdev->dev, "%s: binding to %s returning %d\n", - __func__, driver->driver.name, retval); - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } /* get ready for ep0 traffic */ pch_udc_setup_ep0(dev); @@ -3026,30 +3002,21 @@ static int pch_udc_start(struct usb_gadget_driver *driver, return 0; } -static int pch_udc_stop(struct usb_gadget_driver *driver) +static int pch_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pch_udc_dev *dev = pch_udc; - - if (!dev) - return -ENODEV; - - if (!driver || (driver != dev->driver)) { - dev_err(&dev->pdev->dev, - "%s: invalid driver parameter\n", __func__); - return -EINVAL; - } + struct pch_udc_dev *dev = to_pch_udc(g); pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); /* Assures that there are no pending requests with this driver */ - driver->disconnect(&dev->gadget); - driver->unbind(&dev->gadget); dev->gadget.dev.driver = NULL; dev->driver = NULL; dev->connected = 0; /* set SD */ pch_udc_set_disconnect(dev); + return 0; } @@ -3164,11 +3131,6 @@ static int pch_udc_probe(struct pci_dev *pdev, int retval; struct pch_udc_dev *dev; - /* one udc only */ - if (pch_udc) { - pr_err("%s: already probed\n", __func__); - return -E
[PATCH 08/11] usb: gadget: pxa25x_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.c | 62 ++--- drivers/usb/gadget/pxa25x_udc.h | 1 + 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index d4ca9f1..fa9c344 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -996,9 +996,10 @@ static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) return -EOPNOTSUPP; } -static int pxa25x_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int pxa25x_stop(struct usb_gadget_driver *driver); +static int pxa25x_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int pxa25x_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops pxa25x_udc_ops = { .get_frame = pxa25x_udc_get_frame, @@ -1006,8 +1007,8 @@ static const struct usb_gadget_ops pxa25x_udc_ops = { .vbus_session = pxa25x_udc_vbus_session, .pullup = pxa25x_udc_pullup, .vbus_draw = pxa25x_udc_vbus_draw, - .start = pxa25x_start, - .stop = pxa25x_stop, + .udc_start = pxa25x_udc_start, + .udc_stop = pxa25x_udc_stop, }; /*-*/ @@ -1254,23 +1255,12 @@ static void udc_enable (struct pxa25x_udc *dev) * disconnect is reported. then a host may connect again, or * the driver might get unbound. */ -static int pxa25x_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int pxa25x_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pxa25x_udc *dev = the_controller; + struct pxa25x_udc *dev = to_pxa25x(g); int retval; - if (!driver - || driver->max_speed < USB_SPEED_FULL - || !bind - || !driver->disconnect - || !driver->setup) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; - /* first hook up the driver ... */ dev->driver = driver; dev->gadget.dev.driver = &driver->driver; @@ -1278,34 +1268,20 @@ static int pxa25x_start(struct usb_gadget_driver *driver, retval = device_add (&dev->gadget.dev); if (retval) { -fail: dev->driver = NULL; dev->gadget.dev.driver = NULL; return retval; } - retval = bind(&dev->gadget, driver); - if (retval) { - DMSG("bind to driver %s --> error %d\n", - driver->driver.name, retval); - device_del (&dev->gadget.dev); - goto fail; - } /* ... then enable host detection and ep0; and we're ready * for set_configuration as well as eventual disconnect. */ - DMSG("registered gadget driver '%s'\n", driver->driver.name); - /* connect to bus through transceiver */ if (!IS_ERR_OR_NULL(dev->transceiver)) { retval = otg_set_peripheral(dev->transceiver->otg, &dev->gadget); - if (retval) { - DMSG("can't bind to transceiver\n"); - if (driver->unbind) - driver->unbind(&dev->gadget); + if (retval) goto bind_fail; - } } pullup(dev); @@ -1334,22 +1310,14 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) } del_timer_sync(&dev->timer); - /* report disconnect; the driver is already quiesced */ - if (driver) - driver->disconnect(&dev->gadget); - /* re-init driver-visible data structures */ udc_reinit(dev); } -static int pxa25x_stop(struct usb_gadget_driver *driver) +static int pxa25x_udc_stop(struct usb_gadget*g, + struct usb_gadget_driver *driver) { - struct pxa25x_udc *dev = the_controller; - - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; + struct pxa25x_udc *dev = to_pxa25x(g); local_irq_disable(); dev->pullup = 0; @@ -1360,14 +1328,12 @@ static int pxa25x_stop(struct usb_gadget_driver *driver) if (!IS_ERR_OR_NULL(dev->transceiver)) (void) otg_set_peripheral(dev->transceiver->otg, NULL); -
[PATCH 09/11] usb: gadget: pxa27x_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa27x_udc.c | 58 +++-- drivers/usb/gadget/pxa27x_udc.h | 1 + 2 files changed, 16 insertions(+), 43 deletions(-) diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 2b3b01d..169e42f 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1671,9 +1671,10 @@ static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) return -EOPNOTSUPP; } -static int pxa27x_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int pxa27x_udc_stop(struct usb_gadget_driver *driver); +static int pxa27x_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int pxa27x_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops pxa_udc_ops = { .get_frame = pxa_udc_get_frame, @@ -1681,8 +1682,8 @@ static const struct usb_gadget_ops pxa_udc_ops = { .pullup = pxa_udc_pullup, .vbus_session = pxa_udc_vbus_session, .vbus_draw = pxa_udc_vbus_draw, - .start = pxa27x_udc_start, - .stop = pxa27x_udc_stop, + .udc_start = pxa27x_udc_start, + .udc_stop = pxa27x_udc_stop, }; /** @@ -1802,20 +1803,12 @@ static void udc_enable(struct pxa_udc *udc) * * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise */ -static int pxa27x_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int pxa27x_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pxa_udc *udc = the_controller; + struct pxa_udc *udc = to_pxa(g); int retval; - if (!driver || driver->max_speed < USB_SPEED_FULL || !bind - || !driver->disconnect || !driver->setup) - return -EINVAL; - if (!udc) - return -ENODEV; - if (udc->driver) - return -EBUSY; - /* first hook up the driver ... */ udc->driver = driver; udc->gadget.dev.driver = &driver->driver; @@ -1824,23 +1817,14 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver, retval = device_add(&udc->gadget.dev); if (retval) { dev_err(udc->dev, "device_add error %d\n", retval); - goto add_fail; - } - retval = bind(&udc->gadget, driver); - if (retval) { - dev_err(udc->dev, "bind to driver %s --> error %d\n", - driver->driver.name, retval); - goto bind_fail; + goto fail; } - dev_dbg(udc->dev, "registered gadget driver '%s'\n", - driver->driver.name); - if (!IS_ERR_OR_NULL(udc->transceiver)) { retval = otg_set_peripheral(udc->transceiver->otg, &udc->gadget); if (retval) { dev_err(udc->dev, "can't bind to transceiver\n"); - goto transceiver_fail; + goto fail; } } @@ -1848,12 +1832,7 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver, udc_enable(udc); return 0; -transceiver_fail: - if (driver->unbind) - driver->unbind(&udc->gadget); -bind_fail: - device_del(&udc->gadget.dev); -add_fail: +fail: udc->driver = NULL; udc->gadget.dev.driver = NULL; return retval; @@ -1889,25 +1868,18 @@ static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) * * Returns 0 if no error, -ENODEV, -EINVAL otherwise */ -static int pxa27x_udc_stop(struct usb_gadget_driver *driver) +static int pxa27x_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pxa_udc *udc = the_controller; - - if (!udc) - return -ENODEV; - if (!driver || driver != udc->driver || !driver->unbind) - return -EINVAL; + struct pxa_udc *udc = to_pxa(g); stop_activity(udc, driver); udc_disable(udc); dplus_pullup(udc, 0); - driver->unbind(&udc->gadget); udc->driver = NULL; device_del(&udc->gadget.dev); - dev_info(udc->dev, "unregistered gadget driver '%s'\n", -driver->driver.name); if (!IS_ERR_OR_NULL(udc->transceiver)) return otg_set_peripheral(udc->transceiver->otg, NULL); diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h index 79d81a4..28f2b53 100644 --- a/drivers/usb/gadget/pxa27x_udc.h +++ b/drivers/usb/gadget/pxa2
[PATCH 10/11] usb: gadget: s3c2410: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 65 drivers/usb/gadget/s3c2410_udc.h | 1 + 2 files changed, 13 insertions(+), 53 deletions(-) diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index a2fa6e1..fc07b43 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1538,9 +1538,10 @@ static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma) return -ENOTSUPP; } -static int s3c2410_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int s3c2410_udc_stop(struct usb_gadget_driver *driver); +static int s3c2410_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int s3c2410_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops s3c2410_ops = { .get_frame = s3c2410_udc_get_frame, @@ -1549,8 +1550,8 @@ static const struct usb_gadget_ops s3c2410_ops = { .pullup = s3c2410_udc_pullup, .vbus_session = s3c2410_udc_vbus_session, .vbus_draw = s3c2410_vbus_draw, - .start = s3c2410_udc_start, - .stop = s3c2410_udc_stop, + .udc_start = s3c2410_udc_start, + .udc_stop = s3c2410_udc_stop, }; static void s3c2410_udc_command(enum s3c2410_udc_cmd_e cmd) @@ -1664,33 +1665,14 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev) s3c2410_udc_command(S3C2410_UDC_P_ENABLE); } -static int s3c2410_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int s3c2410_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct s3c2410_udc *udc = the_controller; + struct s3c2410_udc *udc = to_s3c2410(g) int retval; dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name); - /* Sanity checks */ - if (!udc) - return -ENODEV; - - if (udc->driver) - return -EBUSY; - - if (!bind || !driver->setup || driver->max_speed < USB_SPEED_FULL) { - dev_err(&udc->gadget.dev, "Invalid driver: bind %p setup %p speed %d\n", - bind, driver->setup, driver->max_speed); - return -EINVAL; - } -#if defined(MODULE) - if (!driver->unbind) { - dev_err(&udc->gadget.dev, "Invalid driver: no unbind method\n"); - return -EINVAL; - } -#endif - /* Hook the driver */ udc->driver = driver; udc->gadget.dev.driver = &driver->driver; @@ -1702,15 +1684,6 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver, goto register_error; } - dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n", - driver->driver.name); - - retval = bind(&udc->gadget, driver); - if (retval) { - device_del(&udc->gadget.dev); - goto register_error; - } - /* Enable udc */ s3c2410_udc_enable(udc); @@ -1722,24 +1695,10 @@ register_error: return retval; } -static int s3c2410_udc_stop(struct usb_gadget_driver *driver) +static int s3c2410_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct s3c2410_udc *udc = the_controller; - - if (!udc) - return -ENODEV; - - if (!driver || driver != udc->driver || !driver->unbind) - return -EINVAL; - - dprintk(DEBUG_NORMAL, "usb_gadget_unregister_driver() '%s'\n", - driver->driver.name); - - /* report disconnect */ - if (driver->disconnect) - driver->disconnect(&udc->gadget); - - driver->unbind(&udc->gadget); + struct s3c2410_udc *udc = to_s3c2410(g); device_del(&udc->gadget.dev); udc->driver = NULL; diff --git a/drivers/usb/gadget/s3c2410_udc.h b/drivers/usb/gadget/s3c2410_udc.h index 3e80fd5..93bf225 100644 --- a/drivers/usb/gadget/s3c2410_udc.h +++ b/drivers/usb/gadget/s3c2410_udc.h @@ -95,5 +95,6 @@ struct s3c2410_udc { u8 vbus; struct dentry *regs_info; }; +#define to_s3c2410(g) (container_of((g), struct s3c2410_udc, gadget)) #endif -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/11] usb: gadget: completely remove ->start/->stop
Those have been deprecated for a long time and previous patches just converted all remaining users of those. Since there are no in-tree users and we don't want any new users for them, let's obliterate every piece of code related to those calls. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 89 +++ include/linux/usb/gadget.h| 6 --- 2 files changed, 14 insertions(+), 81 deletions(-) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index e7c5916..2a9cd36 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -102,28 +102,6 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); /* - */ /** - * usb_gadget_start - tells usb device controller to start up - * @gadget: The gadget we want to get started - * @driver: The driver we want to bind to @gadget - * @bind: The bind function for @driver - * - * This call is issued by the UDC Class driver when it's about - * to register a gadget driver to the device controller, before - * calling gadget driver's bind() method. - * - * It allows the controller to be powered off until strictly - * necessary to have it powered on. - * - * Returns zero on success, else negative errno. - */ -static inline int usb_gadget_start(struct usb_gadget *gadget, - struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) -{ - return gadget->ops->start(driver, bind); -} - -/** * usb_gadget_udc_start - tells usb device controller to start up * @gadget: The gadget we want to get started * @driver: The driver we want to bind to @gadget @@ -144,24 +122,6 @@ static inline int usb_gadget_udc_start(struct usb_gadget *gadget, } /** - * usb_gadget_stop - tells usb device controller we don't need it anymore - * @gadget: The device we want to stop activity - * @driver: The driver to unbind from @gadget - * - * This call is issued by the UDC Class driver after calling - * gadget driver's unbind() method. - * - * The details are implementation specific, but it can go as - * far as powering off UDC completely and disable its data - * line pullups. - */ -static inline void usb_gadget_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) -{ - gadget->ops->stop(driver); -} - -/** * usb_gadget_udc_stop - tells usb device controller we don't need it anymore * @gadget: The device we want to stop activity * @driver: The driver to unbind from @gadget @@ -246,14 +206,6 @@ err1: } EXPORT_SYMBOL_GPL(usb_add_gadget_udc); -static int udc_is_newstyle(struct usb_udc *udc) -{ - if (udc->gadget->ops->udc_start && udc->gadget->ops->udc_stop) - return 1; - return 0; -} - - static void usb_gadget_remove_driver(struct usb_udc *udc) { dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", @@ -261,14 +213,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); - if (udc_is_newstyle(udc)) { - usb_gadget_disconnect(udc->gadget); - udc->driver->disconnect(udc->gadget); - udc->driver->unbind(udc->gadget); - usb_gadget_udc_stop(udc->gadget, udc->driver); - } else { - usb_gadget_stop(udc->gadget, udc->driver); - } + usb_gadget_disconnect(udc->gadget); + udc->driver->disconnect(udc->gadget); + udc->driver->unbind(udc->gadget); + usb_gadget_udc_stop(udc->gadget, udc->driver); udc->driver = NULL; udc->dev.driver = NULL; @@ -321,22 +269,15 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri udc->driver = driver; udc->dev.driver = &driver->driver; - if (udc_is_newstyle(udc)) { - ret = driver->bind(udc->gadget, driver); - if (ret) - goto err1; - ret = usb_gadget_udc_start(udc->gadget, driver); - if (ret) { - driver->unbind(udc->gadget); - goto err1; - } - usb_gadget_connect(udc->gadget); - } else { - - ret = usb_gadget_start(udc->gadget, driver, driver->bind); - if (ret) - goto err1; + ret = driver->bind(udc->gadget, driver); + if (ret) + goto err1; + ret = usb_gadget_udc_start(udc->gadget, driver); + if (ret) { + driver->unbind(udc->gadget); + goto err1; } + usb_gadget_connect(udc->gadget); kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); return 0; @@ -440,13 +381,11 @@ static ssize_t usb_udc_softconn_store(struct device *dev, struct usb_udc *udc = container_of(dev, struct usb_udc, dev); if (sysfs_streq(buf, "connect")) { -
[PATCH v2] usb: gadget: pxa27x_udc: convert to udc_start/udc_stop
Mechanical change making use of the new (can we still call it new ?) interface for registering UDC drivers. Signed-off-by: Felipe Balbi --- Had missed a trailing gadget->disconnect() call. drivers/usb/gadget/pxa27x_udc.c | 61 ++--- drivers/usb/gadget/pxa27x_udc.h | 1 + 2 files changed, 16 insertions(+), 46 deletions(-) diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 2b3b01d..f7d2579 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1671,9 +1671,10 @@ static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) return -EOPNOTSUPP; } -static int pxa27x_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int pxa27x_udc_stop(struct usb_gadget_driver *driver); +static int pxa27x_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int pxa27x_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops pxa_udc_ops = { .get_frame = pxa_udc_get_frame, @@ -1681,8 +1682,8 @@ static const struct usb_gadget_ops pxa_udc_ops = { .pullup = pxa_udc_pullup, .vbus_session = pxa_udc_vbus_session, .vbus_draw = pxa_udc_vbus_draw, - .start = pxa27x_udc_start, - .stop = pxa27x_udc_stop, + .udc_start = pxa27x_udc_start, + .udc_stop = pxa27x_udc_stop, }; /** @@ -1802,20 +1803,12 @@ static void udc_enable(struct pxa_udc *udc) * * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise */ -static int pxa27x_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int pxa27x_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pxa_udc *udc = the_controller; + struct pxa_udc *udc = to_pxa(g); int retval; - if (!driver || driver->max_speed < USB_SPEED_FULL || !bind - || !driver->disconnect || !driver->setup) - return -EINVAL; - if (!udc) - return -ENODEV; - if (udc->driver) - return -EBUSY; - /* first hook up the driver ... */ udc->driver = driver; udc->gadget.dev.driver = &driver->driver; @@ -1824,23 +1817,14 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver, retval = device_add(&udc->gadget.dev); if (retval) { dev_err(udc->dev, "device_add error %d\n", retval); - goto add_fail; + goto fail; } - retval = bind(&udc->gadget, driver); - if (retval) { - dev_err(udc->dev, "bind to driver %s --> error %d\n", - driver->driver.name, retval); - goto bind_fail; - } - dev_dbg(udc->dev, "registered gadget driver '%s'\n", - driver->driver.name); - if (!IS_ERR_OR_NULL(udc->transceiver)) { retval = otg_set_peripheral(udc->transceiver->otg, &udc->gadget); if (retval) { dev_err(udc->dev, "can't bind to transceiver\n"); - goto transceiver_fail; + goto fail; } } @@ -1848,12 +1832,7 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver, udc_enable(udc); return 0; -transceiver_fail: - if (driver->unbind) - driver->unbind(&udc->gadget); -bind_fail: - device_del(&udc->gadget.dev); -add_fail: +fail: udc->driver = NULL; udc->gadget.dev.driver = NULL; return retval; @@ -1878,9 +1857,6 @@ static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) for (i = 0; i < NR_USB_ENDPOINTS; i++) pxa_ep_disable(&udc->udc_usb_ep[i].usb_ep); - - if (driver) - driver->disconnect(&udc->gadget); } /** @@ -1889,25 +1865,18 @@ static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) * * Returns 0 if no error, -ENODEV, -EINVAL otherwise */ -static int pxa27x_udc_stop(struct usb_gadget_driver *driver) +static int pxa27x_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pxa_udc *udc = the_controller; - - if (!udc) - return -ENODEV; - if (!driver || driver != udc->driver || !driver->unbind) - return -EINVAL; + struct pxa_udc *udc = to_pxa(g); stop_activity(udc, driver); udc_disable(udc); dplus_pullup(udc, 0); - driver->unbind(&udc->gadget); udc->driver = NULL; device_del(&udc->gadget.dev); - dev_info(udc->dev, "unregistered gadget driver
Re: [RFC PATCH] uvc_v4l2: reset connection on uvc open
On Thu, Jan 24, 2013 at 04:05:16PM +0100, Laurent Pinchart wrote: > Hi Felipe, > > On Thursday 24 January 2013 16:42:50 Felipe Balbi wrote: > > On Thu, Jan 24, 2013 at 03:35:58PM +0100, Michael Grzeschik wrote: > > > On Thu, Jan 24, 2013 at 03:21:37PM +0100, Laurent Pinchart wrote: > > > > On Thursday 24 January 2013 14:54:01 Michael Grzeschik wrote: > > > > > On Thu, Jan 24, 2013 at 12:02:12PM +0100, Laurent Pinchart wrote: > > > > > > On Thursday 24 January 2013 11:22:02 Michael Grzeschik wrote: > > > > > > > The current implementation of the composite framework connects the > > > > > > > gadget function to the device-controller at kernel boottime. > > > > > > > > > > > > > > It's possible that the userspace application, which handles the > > > > > > > enumeration requests of the gadget, starts with high latency when > > > > > > > the host did already gave up to detect the gadget. In that case > > > > > > > the gadget-application will not work in the first case. > > > > > > > > > > > > This shouldn't happen, as the UVC gadget driver should start > > > > > > disconnected (it calls usb_function_deactive() in > > > > > > uvc_function_bind()). If the host can enumerate the gadget before > > > > > > the application starts it would then likely be a device controller > > > > > > driver bug, not a UVC gadget driver bug. > > > > > > > > > > Unlikely this is not the case, as usb_gadget_probe_driver triggers an > > > > > usb_gadget_connect() right after driver->bind() was called. > > > > > > > > Indeed, for new-style UDC that's correct. > > > > > > > > Isn't that an issue with the framework ? I would expect gadget drivers > > > > to be able to start disconnected. > > > > > > That probably is. But it might only be a problem for gadgets with > > > userspace components which handle ep0 requests. For other gadgets, which > > > are not as dynamic as an webcam, it might be enough to have its > > > enumeration handled in kernel and start right on. > > > > > > That needs further discussion. Therefore my patch is an RFC and a simple > > > solution to ship arround that issue. Should we take it though? > > > > Framework will take care of it, but other controllers need to be fixed > > up first so they don't connect their pullup directly. > > > > We're getting close to that, though. Give me another merge window and > > gadget drivers will be required to manage pullup. > > Thanks :-) no problem ;-) -- balbi signature.asc Description: Digital signature
Re: Linux USB file storage gadget with new UDC
On Thu, 24 Jan 2013, victor yeo wrote: > In the udc driver, i can't assign a single ep0 descriptor to both > ep0_in_desc and ep0_out_desc. i think i should skip ep0_out_desc. Bear > in mind that i only define 3 endpoints in udc driver: ep0, ep1 bulk > in, ep1 bulk out. Will it cause any problem to gadget driver? There is no such thing as an ep0 descriptor. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 01/32] usb: gadget: udc-core: allow udc class register gadget device
Currently all UDC drivers are calling device_register() before calling usb_add_gadget_udc(). In order to avoid code duplication, we can allow udc-core.c register that device. However that would become a really large patch, so to cope with the meanwhile and allow us to write bite-sized patches, we're adding a flag which will be set by UDC driver once it removes the code for registering the gadget device. Once all are converted, the new flag will be removed. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 23 +++ include/linux/usb/gadget.h| 4 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 2a9cd36..9195054 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -173,6 +173,14 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) if (!udc) goto err1; + if (gadget->register_my_device) { + dev_set_name(&gadget->dev, "gadget"); + + ret = device_register(&gadget->dev); + if (ret) + goto err2; + } + device_initialize(&udc->dev); udc->dev.release = usb_udc_release; udc->dev.class = udc_class; @@ -180,7 +188,7 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) udc->dev.parent = parent; ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj)); if (ret) - goto err2; + goto err3; udc->gadget = gadget; @@ -189,18 +197,22 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) ret = device_add(&udc->dev); if (ret) - goto err3; + goto err4; mutex_unlock(&udc_lock); return 0; -err3: + +err4: list_del(&udc->list); mutex_unlock(&udc_lock); -err2: +err3: put_device(&udc->dev); +err2: + if (gadget->register_my_device) + put_device(&gadget->dev); err1: return ret; } @@ -254,6 +266,9 @@ found: kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); device_unregister(&udc->dev); + + if (gadget->register_my_device) + device_unregister(&gadget->dev); } EXPORT_SYMBOL_GPL(usb_del_gadget_udc); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 2e297e8..fcd9ef8 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -494,6 +494,9 @@ struct usb_gadget_ops { * only supports HNP on a different root port. * @b_hnp_enable: OTG device feature flag, indicating that the A-Host * enabled HNP support. + * @register_my_device: Flag telling udc-core that UDC driver didn't + * register the gadget device to the driver model. Temporary until + * all UDC drivers are fixed up properly. * @name: Identifies the controller hardware type. Used in diagnostics * and sometimes configuration. * @dev: Driver model state for this abstract device. @@ -531,6 +534,7 @@ struct usb_gadget { unsignedb_hnp_enable:1; unsigneda_hnp_support:1; unsigneda_alt_hnp_support:1; + unsignedregister_my_device:1; const char *name; struct device dev; unsignedout_epnum; -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 03/32] usb: musb: gadget: let udc-core manage gadget-dev
By simply setting a flag, we can delete a little boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 10 +- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 8767874..1c4a8e8 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1871,12 +1871,11 @@ int musb_gadget_setup(struct musb *musb) musb->g.speed = USB_SPEED_UNKNOWN; /* this "gadget" abstracts/virtualizes the controller */ - dev_set_name(&musb->g.dev, "gadget"); musb->g.dev.parent = musb->controller; musb->g.dev.dma_mask = musb->controller->dma_mask; musb->g.dev.release = musb_gadget_release; musb->g.name = musb_driver_name; - + musb->g.register_my_device = true; musb->g.is_otg = 1; musb_g_init_endpoints(musb); @@ -1884,11 +1883,6 @@ int musb_gadget_setup(struct musb *musb) musb->is_active = 0; musb_platform_try_idle(musb, 0); - status = device_register(&musb->g.dev); - if (status != 0) { - put_device(&musb->g.dev); - return status; - } status = usb_add_gadget_udc(musb->controller, &musb->g); if (status) goto err; @@ -1903,8 +1897,6 @@ err: void musb_gadget_cleanup(struct musb *musb) { usb_del_gadget_udc(&musb->g); - if (musb->g.dev.parent) - device_unregister(&musb->g.dev); } /* -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 04/32] usb: gadget: omap_udc: let udc-core manage gadget->dev
By simply setting a flag, we drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index d0c87b1..234e82b 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2631,10 +2631,9 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) udc->gadget.max_speed = USB_SPEED_FULL; udc->gadget.name = driver_name; - device_initialize(&udc->gadget.dev); - dev_set_name(&udc->gadget.dev, "gadget"); udc->gadget.dev.release = omap_udc_release; udc->gadget.dev.parent = &odev->dev; + udc->gadget.register_my_device = true; if (use_dma) udc->gadget.dev.dma_mask = odev->dev.dma_mask; @@ -2911,14 +2910,12 @@ bad_on_1710: } create_proc_file(); - status = device_add(&udc->gadget.dev); + status = usb_add_gadget_udc(&pdev->dev, &udc->gadget); if (status) goto cleanup4; - status = usb_add_gadget_udc(&pdev->dev, &udc->gadget); - if (!status) - return status; - /* If fail, fall through */ + return 0; + cleanup4: remove_proc_file(); @@ -2989,7 +2986,6 @@ static int omap_udc_remove(struct platform_device *pdev) release_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); - device_unregister(&udc->gadget.dev); wait_for_completion(&done); return 0; -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 08/32] usb: gadget: bcm63xx_udc: let udc-core manage gadget->dev
By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/bcm63xx_udc.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index 47a4993..10b0475 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -2367,13 +2367,13 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) spin_lock_init(&udc->lock); INIT_WORK(&udc->ep0_wq, bcm63xx_ep0_process); - dev_set_name(&udc->gadget.dev, "gadget"); udc->gadget.ops = &bcm63xx_udc_ops; udc->gadget.name = dev_name(dev); udc->gadget.dev.parent = dev; udc->gadget.dev.release = bcm63xx_udc_gadget_release; udc->gadget.dev.dma_mask = dev->dma_mask; + udc->gadget.register_my_device = true; if (!pd->use_fullspeed && !use_fullspeed) udc->gadget.max_speed = USB_SPEED_HIGH; @@ -2413,10 +2413,6 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) } } - rc = device_register(&udc->gadget.dev); - if (rc) - goto out_uninit; - bcm63xx_udc_init_debugfs(udc); rc = usb_add_gadget_udc(dev, &udc->gadget); if (!rc) @@ -2439,7 +2435,6 @@ static int bcm63xx_udc_remove(struct platform_device *pdev) bcm63xx_udc_cleanup_debugfs(udc); usb_del_gadget_udc(&udc->gadget); - device_unregister(&udc->gadget.dev); BUG_ON(udc->driver); platform_set_drvdata(pdev, NULL); -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 06/32] usb: gadget: at91_udc: let udc-core manage gadget->dev
By simply setting a flag, we can remove some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/at91_udc.c | 13 ++--- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 10f45fa..177b56d 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1726,6 +1726,7 @@ static int at91udc_probe(struct platform_device *pdev) /* init software state */ udc = &controller; + udc->gadget.register_my_device = true; udc->gadget.dev.parent = dev; if (pdev->dev.of_node) at91udc_of_init(udc, pdev->dev.of_node); @@ -1780,13 +1781,7 @@ static int at91udc_probe(struct platform_device *pdev) DBG("clocks missing\n"); retval = -ENODEV; /* NOTE: we "know" here that refcounts on these are NOPs */ - goto fail0b; - } - - retval = device_register(&udc->gadget.dev); - if (retval < 0) { - put_device(&udc->gadget.dev); - goto fail0b; + goto fail1; } /* don't do anything until we have both gadget driver and VBUS */ @@ -1857,8 +1852,6 @@ fail3: fail2: free_irq(udc->udp_irq, udc); fail1: - device_unregister(&udc->gadget.dev); -fail0b: iounmap(udc->udp_baseaddr); fail0a: if (cpu_is_at91rm9200()) @@ -1892,8 +1885,6 @@ static int __exit at91udc_remove(struct platform_device *pdev) gpio_free(udc->board.vbus_pin); } free_irq(udc->udp_irq, udc); - device_unregister(&udc->gadget.dev); - iounmap(udc->udp_baseaddr); if (cpu_is_at91rm9200()) -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 02/32] usb: dwc3: gadget: let udc-core manage gadget->dev
We don't need to register that device ourselves if we simply set gadget->register_my_device. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 17 ++--- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 2e43b33..7002cf6 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2412,8 +2412,6 @@ int dwc3_gadget_init(struct dwc3 *dwc) goto err3; } - dev_set_name(&dwc->gadget.dev, "gadget"); - dwc->gadget.ops = &dwc3_gadget_ops; dwc->gadget.max_speed = USB_SPEED_SUPER; dwc->gadget.speed = USB_SPEED_UNKNOWN; @@ -2425,6 +2423,7 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc->gadget.dev.dma_parms = dwc->dev->dma_parms; dwc->gadget.dev.dma_mask= dwc->dev->dma_mask; dwc->gadget.dev.release = dwc3_gadget_release; + dwc->gadget.register_my_device = true; dwc->gadget.name= "dwc3-gadget"; /* @@ -2480,24 +2479,14 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc3_gadget_usb3_phy_suspend(dwc, false); } - ret = device_register(&dwc->gadget.dev); - if (ret) { - dev_err(dwc->dev, "failed to register gadget device\n"); - put_device(&dwc->gadget.dev); - goto err6; - } - ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); if (ret) { dev_err(dwc->dev, "failed to register udc\n"); - goto err7; + goto err6; } return 0; -err7: - device_unregister(&dwc->gadget.dev); - err6: dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); free_irq(irq, dwc); @@ -2546,6 +2535,4 @@ void dwc3_gadget_exit(struct dwc3 *dwc) dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req), dwc->ctrl_req, dwc->ctrl_req_addr); - - device_unregister(&dwc->gadget.dev); } -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 00/32] usb: refactor gadget->dev registration
Hi folks, Please comment on this series as I need help testing it on all UDC controllers so we can send it for v3.10 merge window. NOTE: I will queue this series for v3.10 merge window, so make sure to test and comment. cheers Felipe Balbi (32): usb: gadget: udc-core: allow udc class register gadget device usb: dwc3: gadget: let udc-core manage gadget->dev usb: musb: gadget: let udc-core manage gadget-dev usb: gadget: omap_udc: let udc-core manage gadget->dev usb: gadget: amd5536udc: let udc-core manage gadget->dev usb: gadget: at91_udc: let udc-core manage gadget->dev usb: gadget: atmel_usba_udc: let udc-core manage gadget->dev usb: gadget: bcm63xx_udc: let udc-core manage gadget->dev usb: gadget: dummy_hcd: let udc-core manage gadget->dev usb: gadget: fsl_qe_udc: let udc-core manage gadget->dev usb: gadget: fsl_udc_core: let udc-core manage gadget->dev usb: gadget: fusb300_udc: let udc-core manage gadget->dev usb: gadget: goku_udc: let udc-core manage gadget->dev usb: gadget: imx_udc: let udc-core manage gadget->dev usb: gadget: lpc32xx_udc: let udc-core manage gadget->dev usb: gadget: m66592-udc: let udc-core manage gadget->dev usb: gadget: mv_u3d_core: let udc-core manage gadget->dev usb: gadget: mv_u3d_core: fix a compile warning usb: gadget: mv_udc_core: let udc-core manage gadget->dev usb: gadget: net2272: let udc-core manage gadget->dev usb: gadget: net2280: let udc-core manage gadget->dev usb: gadget: pch_udc: let udc-core manage gadget->dev usb: gadget: r8a66597-udc: let udc-core manage gadget->dev usb: gadget: s3c-hsotg: let udc-core manage gadget->dev usb: gadget: s3c-hsudc: let udc-core manage gadget->dev usb: gadget: s3c2410_udc: let udc-core manage gadget->dev usb: renesas_usbhs: gadget: let udc-core manage gadget->dev usb: gadget: pxa25x_udc: let udc-core manage gadget->dev usb: gadget: pxa27x_udc: let udc-core manage gadget->dev usb: chipidea: register debugging syfs on our device usb: chipidea: let udc-core manage gadget->dev usb: gadget: drop now unnecessary flag drivers/usb/chipidea/udc.c | 18 -- drivers/usb/dwc3/gadget.c | 16 +--- drivers/usb/gadget/amd5536udc.c| 8 drivers/usb/gadget/at91_udc.c | 12 +--- drivers/usb/gadget/atmel_usba_udc.c| 12 drivers/usb/gadget/bcm63xx_udc.c | 6 -- drivers/usb/gadget/dummy_hcd.c | 9 - drivers/usb/gadget/fsl_qe_udc.c| 14 +- drivers/usb/gadget/fsl_udc_core.c | 8 +--- drivers/usb/gadget/fusb300_udc.c | 13 - drivers/usb/gadget/goku_udc.c | 9 - drivers/usb/gadget/goku_udc.h | 3 +-- drivers/usb/gadget/imx_udc.c | 12 drivers/usb/gadget/lpc32xx_udc.c | 10 -- drivers/usb/gadget/m66592-udc.c| 12 drivers/usb/gadget/mv_u3d_core.c | 11 +-- drivers/usb/gadget/mv_udc_core.c | 11 +-- drivers/usb/gadget/net2272.c | 9 + drivers/usb/gadget/net2280.c | 4 drivers/usb/gadget/omap_udc.c | 11 +++ drivers/usb/gadget/pch_udc.c | 9 - drivers/usb/gadget/pxa25x_udc.c| 9 - drivers/usb/gadget/pxa27x_udc.c| 8 drivers/usb/gadget/r8a66597-udc.c | 11 +-- drivers/usb/gadget/s3c-hsotg.c | 13 - drivers/usb/gadget/s3c-hsudc.c | 10 -- drivers/usb/gadget/s3c2410_udc.c | 9 - drivers/usb/gadget/udc-core.c | 20 drivers/usb/musb/musb_gadget.c | 9 - drivers/usb/renesas_usbhs/mod_gadget.c | 10 +- 30 files changed, 33 insertions(+), 283 deletions(-) -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 05/32] usb: gadget: amd5536udc: let udc-core manage gadget->dev
By simply setting a flag, we drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/amd5536udc.c | 9 + 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 3dac001..1827d4c 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -3080,7 +3080,6 @@ static void udc_pci_remove(struct pci_dev *pdev) if (dev->active) pci_disable_device(pdev); - device_unregister(&dev->gadget.dev); pci_set_drvdata(pdev, NULL); udc_remove(dev); @@ -3276,6 +3275,7 @@ static int udc_probe(struct udc *dev) dev->gadget.dev.release = gadget_release; dev->gadget.name = name; dev->gadget.max_speed = USB_SPEED_HIGH; + dev->gadget.register_my_device = true; /* init registers, interrupts, ... */ startup_registers(dev); @@ -3301,13 +3301,6 @@ static int udc_probe(struct udc *dev) if (retval) goto finished; - retval = device_register(&dev->gadget.dev); - if (retval) { - usb_del_gadget_udc(&dev->gadget); - put_device(&dev->gadget.dev); - goto finished; - } - /* timer init */ init_timer(&udc_timer); udc_timer.function = udc_timer_function; -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 10/32] usb: gadget: fsl_qe_udc: let udc-core manage gadget->dev
By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_qe_udc.c | 15 ++- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index ec50f18..08c8432 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2523,13 +2523,9 @@ static int qe_udc_probe(struct platform_device *ofdev) /* name: Identifies the controller hardware type. */ udc->gadget.name = driver_name; - - device_initialize(&udc->gadget.dev); - - dev_set_name(&udc->gadget.dev, "gadget"); - udc->gadget.dev.release = qe_udc_release; udc->gadget.dev.parent = &ofdev->dev; + udc->gadget.register_my_device = true; /* initialize qe_ep struct */ for (i = 0; i < USB_MAX_ENDPOINTS ; i++) { @@ -2592,13 +2588,9 @@ static int qe_udc_probe(struct platform_device *ofdev) goto err5; } - ret = device_add(&udc->gadget.dev); - if (ret) - goto err6; - ret = usb_add_gadget_udc(&ofdev->dev, &udc->gadget); if (ret) - goto err7; + goto err6; dev_set_drvdata(&ofdev->dev, udc); dev_info(udc->dev, @@ -2606,8 +2598,6 @@ static int qe_udc_probe(struct platform_device *ofdev) (udc->soc_type == PORT_QE) ? "QE" : "CPM"); return 0; -err7: - device_unregister(&udc->gadget.dev); err6: free_irq(udc->usb_irq, udc); err5: @@ -2702,7 +2692,6 @@ static int qe_udc_remove(struct platform_device *ofdev) iounmap(udc->usb_regs); - device_unregister(&udc->gadget.dev); /* wait for release() of gadget.dev to free udc */ wait_for_completion(&done); -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 11/32] usb: gadget: fsl_udc_core: let udc-core manage gadget->dev
By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 49642d4..b78b734 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2526,9 +2526,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) udc_controller->gadget.dev.release = fsl_udc_release; udc_controller->gadget.dev.parent = &pdev->dev; udc_controller->gadget.dev.of_node = pdev->dev.of_node; - ret = device_register(&udc_controller->gadget.dev); - if (ret < 0) - goto err_free_irq; + udc_controller->gadget.register_my_device = true; if (!IS_ERR_OR_NULL(udc_controller->transceiver)) udc_controller->gadget.is_otg = 1; @@ -2561,7 +2559,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) DTD_ALIGNMENT, UDC_DMA_BOUNDARY); if (udc_controller->td_pool == NULL) { ret = -ENOMEM; - goto err_unregister; + goto err_free_irq; } ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget); @@ -2573,8 +2571,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev) err_del_udc: dma_pool_destroy(udc_controller->td_pool); -err_unregister: - device_unregister(&udc_controller->gadget.dev); err_free_irq: free_irq(udc_controller->irq, udc_controller); err_iounmap: @@ -2624,7 +2620,6 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) if (pdata->operating_mode == FSL_USB2_DR_DEVICE) release_mem_region(res->start, resource_size(res)); - device_unregister(&udc_controller->gadget.dev); /* free udc --wait for the release() finished */ wait_for_completion(&done); -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 07/32] usb: gadget: atmel_usba_udc: let udc-core manage gadget->dev
By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.c | 13 + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index a7aed84..f0f9423 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1900,9 +1900,9 @@ static int __init usba_udc_probe(struct platform_device *pdev) dev_info(&pdev->dev, "FIFO at 0x%08lx mapped at %p\n", (unsigned long)fifo->start, udc->fifo); - device_initialize(&udc->gadget.dev); udc->gadget.dev.parent = &pdev->dev; udc->gadget.dev.dma_mask = pdev->dev.dma_mask; + udc->gadget.register_my_device = true; platform_set_drvdata(pdev, udc); @@ -1962,12 +1962,6 @@ static int __init usba_udc_probe(struct platform_device *pdev) } udc->irq = irq; - ret = device_add(&udc->gadget.dev); - if (ret) { - dev_dbg(&pdev->dev, "Could not add gadget: %d\n", ret); - goto err_device_add; - } - if (gpio_is_valid(pdata->vbus_pin)) { if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) { udc->vbus_pin = pdata->vbus_pin; @@ -2007,9 +2001,6 @@ err_add_udc: gpio_free(udc->vbus_pin); } - device_unregister(&udc->gadget.dev); - -err_device_add: free_irq(irq, udc); err_request_irq: kfree(usba_ep); @@ -2053,8 +2044,6 @@ static int __exit usba_udc_remove(struct platform_device *pdev) clk_put(udc->hclk); clk_put(udc->pclk); - device_unregister(&udc->gadget.dev); - return 0; } -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 12/32] usb: gadget: fusb300_udc: let udc-core manage gadget->dev
By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fusb300_udc.c | 14 +- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 8c2372f..798a25b 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1422,15 +1422,12 @@ static int __init fusb300_probe(struct platform_device *pdev) fusb300->gadget.ops = &fusb300_gadget_ops; - device_initialize(&fusb300->gadget.dev); - - dev_set_name(&fusb300->gadget.dev, "gadget"); - fusb300->gadget.max_speed = USB_SPEED_HIGH; fusb300->gadget.dev.parent = &pdev->dev; fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; fusb300->gadget.dev.release = pdev->dev.release; fusb300->gadget.name = udc_name; + fusb300->gadget.register_my_device = true; fusb300->reg = reg; ret = request_irq(ires->start, fusb300_irq, IRQF_SHARED, @@ -1478,19 +1475,10 @@ static int __init fusb300_probe(struct platform_device *pdev) if (ret) goto err_add_udc; - ret = device_add(&fusb300->gadget.dev); - if (ret) { - pr_err("device_add error (%d)\n", ret); - goto err_add_device; - } - dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); return 0; -err_add_device: - usb_del_gadget_udc(&fusb300->gadget); - err_add_udc: fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 15/32] usb: gadget: lpc32xx_udc: let udc-core manage gadget->dev
By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 11 +-- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index dd1c9b1..077e021 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -3090,6 +3090,7 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) /* init software state */ udc->gadget.dev.parent = dev; + udc->gadget.register_my_device = true; udc->pdev = pdev; udc->dev = &pdev->dev; udc->enabled = 0; @@ -3248,12 +3249,6 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) udc_disable(udc); udc_reinit(udc); - retval = device_register(&udc->gadget.dev); - if (retval < 0) { - dev_err(udc->dev, "Device registration failure\n"); - goto dev_register_fail; - } - /* Request IRQs - low and high priority USB device IRQs are routed to * the same handler, while the DMA interrupt is routed elsewhere */ retval = request_irq(udc->udp_irq[IRQ_USB_LP], lpc32xx_usb_lp_irq, @@ -3320,8 +3315,6 @@ irq_dev_fail: irq_hp_fail: free_irq(udc->udp_irq[IRQ_USB_LP], udc); irq_lp_fail: - device_unregister(&udc->gadget.dev); -dev_register_fail: dma_pool_destroy(udc->dd_cache); dma_alloc_fail: dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, @@ -3376,8 +3369,6 @@ static int lpc32xx_udc_remove(struct platform_device *pdev) free_irq(udc->udp_irq[IRQ_USB_HP], udc); free_irq(udc->udp_irq[IRQ_USB_LP], udc); - device_unregister(&udc->gadget.dev); - clk_disable(udc->usb_otg_clk); clk_put(udc->usb_otg_clk); clk_disable(udc->usb_slv_clk); -- 1.8.1.rc1.5.g7e0651a -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html