From 6d258a4c42089229b855fd706622029decf316d6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 15 Mar 2012 16:37:18 +0200 Subject: [PATCH 01/36] usb: gadget: udc-core: stop UDC on device-initiated disconnect When we want to do device-initiated disconnect, let's make sure we stop the UDC in order to e.g. allow lower power states to be achieved by turning off unnecessary clocks and/or stoping PHYs. When reconnecting, call ->udc_start() again to make sure UDC is reinitialized. Cc: stable@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 56da49f31d6c..c261887e05ae 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -411,8 +411,12 @@ 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")) { + if (udc_is_newstyle(udc)) + usb_gadget_udc_start(udc->gadget, udc->driver); usb_gadget_connect(udc->gadget); } else if (sysfs_streq(buf, "disconnect")) { + if (udc_is_newstyle(udc)) + usb_gadget_udc_stop(udc->gadget, udc->driver); usb_gadget_disconnect(udc->gadget); } else { dev_err(dev, "unsupported command '%s'\n", buf); From 566ccdda07dc5898272b6fbad9c616fc44be305a Mon Sep 17 00:00:00 2001 From: Moiz Sonasath Date: Wed, 14 Mar 2012 00:44:56 -0500 Subject: [PATCH 02/36] usb: dwc3: ep0: Handle requests greater than wMaxPacketSize To allow ep0 out transfers of upto bounce buffer size instead of maxpacketsize, use the transfer size as multiple of ep0 maxpacket size. Cc: stable@vger.kernel.org Signed-off-by: Moiz Sonasath Signed-off-by: Partha Basak Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 25910e251c04..a40d3bb0f1c2 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -559,8 +559,12 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, length = trb->size & DWC3_TRB_SIZE_MASK; if (dwc->ep0_bounced) { + unsigned transfer_size = ur->length; + unsigned maxp = ep0->endpoint.maxpacket; + + transfer_size += (maxp - (transfer_size % maxp)); transferred = min_t(u32, ur->length, - ep0->endpoint.maxpacket - length); + transfer_size - length); memcpy(ur->buf, dwc->ep0_bounce, transferred); dwc->ep0_bounced = false; } else { From cd423dd3634a5232a3019eb372b144619a61cd16 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 21 Mar 2012 11:44:00 +0200 Subject: [PATCH 03/36] usb: dwc3: ep0: increment "actual" on bounced ep0 case due to a HW limitation we have a bounce buffer for ep0 out transfers which are not aligned with MaxPacketSize. On such case we were not increment r->actual as we should. This patch fixes that mistake. Cc: stable@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index a40d3bb0f1c2..da43131be0e7 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -569,9 +569,10 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, dwc->ep0_bounced = false; } else { transferred = ur->length - length; - ur->actual += transferred; } + ur->actual += transferred; + if ((epnum & 1) && ur->actual < ur->length) { /* for some reason we did not get everything out */ From ecb07797ffc1c2aaa2e58d1ba1b5deea44ea5b9e Mon Sep 17 00:00:00 2001 From: Gerard Cauvy Date: Fri, 16 Mar 2012 16:20:10 +0200 Subject: [PATCH 04/36] usb: dwc3: ep0: add a default case for SetFeature command Without this default case returning an error, thus replying with a stall, we would fail USB30CV TD 9.11 Bad Feature test case. Cc: stable@vger.kernel.org Signed-off-by: Gerard Cauvy Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index da43131be0e7..3584a169886f 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, dwc->test_mode_nr = wIndex >> 8; dwc->test_mode = true; + break; + default: + return -EINVAL; } break; From afb76df140823c57738598a876cd1d6568cd57c7 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 23 Dec 2011 18:37:18 +0200 Subject: [PATCH 05/36] usb: musb: fix oops on omap2430 module unload This change prevents runtime suspend and resume actual execution, if omap2430 controller driver is loaded after musb-hdrc, and therefore the controller isn't initialized properly. The problem is reproducible with 3.1.y and 3.2 kernels. Kernel configuration of musb: % cat .config | egrep 'MUSB|GADGET' CONFIG_USB_MUSB_HDRC=y # CONFIG_USB_MUSB_TUSB6010 is not set CONFIG_USB_MUSB_OMAP2PLUS=m # CONFIG_USB_MUSB_AM35X is not set CONFIG_MUSB_PIO_ONLY=y CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_DEBUG_FS is not set CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 CONFIG_USB_GADGET_MUSB_HDRC=m CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_GADGETFS=m # CONFIG_USB_MIDI_GADGET is not set Fixes the following oops on module unloading: Unable to handle kernel NULL pointer dereference at virtual address 00000220 ----8<---- [] (omap2430_runtime_resume+0x24/0x54 [omap2430]) from [] (pm_generic_runtime_resume+0x3c/0x50) [] (pm_generic_runtime_resume+0x3c/0x50) from [] (_od_runtime_resume+0x28/0x2c) [] (_od_runtime_resume+0x28/0x2c) from [] (__rpm_callback+0x60/0xa0) [] (__rpm_callback+0x60/0xa0) from [] (rpm_resume+0x3fc/0x6e4) [] (rpm_resume+0x3fc/0x6e4) from [] (__pm_runtime_resume+0x5c/0x90) [] (__pm_runtime_resume+0x5c/0x90) from [] (__device_release_driver+0x2c/0xd0) [] (__device_release_driver+0x2c/0xd0) from [] (driver_detach+0xe8/0xf4) [] (driver_detach+0xe8/0xf4) from [] (bus_remove_driver+0xa0/0x104) [] (bus_remove_driver+0xa0/0x104) from [] (driver_unregister+0x60/0x80) [] (driver_unregister+0x60/0x80) from [] (platform_driver_unregister+0x1c/0x20) [] (platform_driver_unregister+0x1c/0x20) from [] (omap2430_exit+0x14/0x1c [omap2430]) [] (omap2430_exit+0x14/0x1c [omap2430]) from [] (sys_delete_module+0x1f4/0x264) [] (sys_delete_module+0x1f4/0x264) from [] (ret_fast_syscall+0x0/0x30) Signed-off-by: Vladimir Zapolskiy Cc: Greg Kroah-Hartman Cc: stable@vger.kernel.org # 3.1 Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2ae0bb309994..11b571ec22f2 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -491,11 +491,13 @@ static int omap2430_runtime_suspend(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - musb->context.otg_interfsel = musb_readl(musb->mregs, - OTG_INTERFSEL); + if (musb) { + musb->context.otg_interfsel = musb_readl(musb->mregs, + OTG_INTERFSEL); - omap2430_low_level_exit(musb); - usb_phy_set_suspend(musb->xceiv, 1); + omap2430_low_level_exit(musb); + usb_phy_set_suspend(musb->xceiv, 1); + } return 0; } @@ -505,11 +507,13 @@ static int omap2430_runtime_resume(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - omap2430_low_level_init(musb); - musb_writel(musb->mregs, OTG_INTERFSEL, - musb->context.otg_interfsel); + if (musb) { + omap2430_low_level_init(musb); + musb_writel(musb->mregs, OTG_INTERFSEL, + musb->context.otg_interfsel); - usb_phy_set_suspend(musb->xceiv, 0); + usb_phy_set_suspend(musb->xceiv, 0); + } return 0; } From c04352a590538123f8c93bd87ef1d4bb9e3a64c7 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 4 Feb 2012 19:43:51 +0200 Subject: [PATCH 06/36] usb: musb: fix some runtime_pm issues When runtime_pm was originally added, it was done in rather confusing way: omap2430_musb_init() (called from musb_init_controller) would do runtime_pm_get_sync() and musb_init_controller() itself would do runtime_pm_put to balance it out. This is not only confusing but also wrong if non-omap2430 glue layer is used. This confusion resulted in commit 772aed45b604 "usb: musb: fix pm_runtime mismatch", that removed runtime_pm_put() from musb_init_controller as that looked unbalanced, and also happened to fix unrelated isp1704_charger crash. However this broke runtime PM functionality (musb is now always powered, even without gadget active). Avoid these confusing runtime pm dependences by making musb_init_controller() and omap2430_musb_init() do their own runtime get/put pairs; also cover error paths. Remove unneeded runtime_pm_put in omap2430_remove too. isp1704_charger crash that motivated 772aed45b604 will be fixed by following patch. Cc: Felipe Contreras Signed-off-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 9 ++++++++- drivers/usb/musb/omap2430.c | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0f8b82918a40..239214626ec5 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1904,7 +1904,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (!musb->isr) { status = -ENODEV; - goto fail3; + goto fail2; } if (!musb->xceiv->io_ops) { @@ -1912,6 +1912,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb->xceiv->io_ops = &musb_ulpi_access; } + pm_runtime_get_sync(musb->controller); + #ifndef CONFIG_MUSB_PIO_ONLY if (use_dma && dev->dma_mask) { struct dma_controller *c; @@ -2023,6 +2025,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail5; #endif + pm_runtime_put(musb->controller); + dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", ({char *s; switch (musb->board_mode) { @@ -2047,6 +2051,9 @@ fail4: musb_gadget_cleanup(musb); fail3: + pm_runtime_put_sync(musb->controller); + +fail2: if (musb->irq_wake) device_init_wakeup(dev, 0); musb_platform_exit(musb); diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 11b571ec22f2..3dfd122266f4 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -333,6 +333,7 @@ static int omap2430_musb_init(struct musb *musb) setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); + pm_runtime_put_noidle(musb->controller); return 0; err1: @@ -478,7 +479,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); - pm_runtime_put(&pdev->dev); kfree(glue); return 0; From f79a60b8785409f5a77767780315ce6d3ea04a44 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 29 Feb 2012 20:19:46 +0800 Subject: [PATCH 07/36] usb: fsl_udc_core: prime status stage once data stage has primed - For Control Read transfer, the ACK handshake on an IN transaction may be corrupted, so the device may not receive the ACK for data stage, the complete irq will not occur at this situation. Therefore, we need to move prime status stage from complete irq routine to the place where the data stage has just primed, or the host will never get ACK for status stage. The above issue has been described at USB2.0 spec chapter 8.5.3.3. - After adding prime status stage just after prime the data stage, there is a potential problem when the status dTD is added before the data stage has primed by hardware. The reason is the device's dTD descriptor has NO direction bit, if data stage (IN) prime hasn't finished, the status stage(OUT) dTD will be added at data stage dTD's Next dTD Pointer, so when the data stage transfer has finished, the status dTD will be primed as IN by hardware, then the host will never receive ACK from the device side for status stage. - Delete below code at fsl_ep_queue: /* Update ep0 state */ if ((ep_index(ep) == 0)) udc->ep0_state = DATA_STATE_XMIT; the udc->ep0_state will be updated again after udc->driver->setup finishes. It is tested at i.mx51 bbg board with g_mass_storage, g_ether, g_serial. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 5f94e79cd6b9..55abfb6bd612 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) : (1 << (ep_index(ep))); /* check if the pipe is empty */ - if (!(list_empty(&ep->queue))) { + if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) { /* Add td to the end */ struct fsl_req *lastreq; lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); @@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) return -ENOMEM; } - /* Update ep0 state */ - if ((ep_index(ep) == 0)) - udc->ep0_state = DATA_STATE_XMIT; - /* irq handler advances the queue */ if (req != NULL) list_add_tail(&req->queue, &ep->queue); @@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) udc->ep0_dir = USB_DIR_OUT; ep = &udc->eps[0]; - udc->ep0_state = WAIT_FOR_OUT_STATUS; + if (udc->ep0_state != DATA_STATE_XMIT) + udc->ep0_state = WAIT_FOR_OUT_STATUS; req->ep = ep; req->req.length = 0; @@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, list_add_tail(&req->queue, &ep->queue); udc->ep0_state = DATA_STATE_XMIT; + if (ep0_prime_status(udc, EP_DIR_OUT)) + ep0stall(udc); + return; stall: ep0stall(udc); @@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc, spin_lock(&udc->lock); udc->ep0_state = (setup->bRequestType & USB_DIR_IN) ? DATA_STATE_XMIT : DATA_STATE_RECV; + /* + * If the data stage is IN, send status prime immediately. + * See 2.0 Spec chapter 8.5.3.3 for detail. + */ + if (udc->ep0_state == DATA_STATE_XMIT) + if (ep0_prime_status(udc, EP_DIR_OUT)) + ep0stall(udc); + } else { /* No data phase, IN status from gadget */ udc->ep0_dir = USB_DIR_IN; @@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0, switch (udc->ep0_state) { case DATA_STATE_XMIT: - /* receive status phase */ - if (ep0_prime_status(udc, EP_DIR_OUT)) - ep0stall(udc); + /* already primed at setup_received_irq */ + udc->ep0_state = WAIT_FOR_OUT_STATUS; break; case DATA_STATE_RECV: /* send status phase */ From f7a83fe19336125d7eb26488788dc66c03f2c08e Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 14:05:49 +0900 Subject: [PATCH 08/36] usb: s3c-hsotg: Fix TX FIFOs allocation According to documentation, TX FIFO_number index starts from 1. For IN endpoint FIFO 0 we use GNPTXFSIZ register for programming the size and memory start address. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 69295ba9d99a..e3fe5fd795f0 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) /* currently we allocate TX FIFOs for all possible endpoints, * and assume that they are all the same size. */ - for (ep = 0; ep <= 15; ep++) { + for (ep = 1; ep <= 15; ep++) { val = addr; val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT; addr += size; From 659ad60cb9128345d0a6b9093dda9b0e366b7937 Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 14:07:29 +0900 Subject: [PATCH 09/36] usb: s3c-hsotg: Fix maximum patcket size setting for EP0 MPS field of DOEPCTL0 is read only. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index e3fe5fd795f0..03de169ab365 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg, reg |= mpsval; writel(reg, regs + S3C_DIEPCTL(ep)); - reg = readl(regs + S3C_DOEPCTL(ep)); - reg &= ~S3C_DxEPCTL_MPS_MASK; - reg |= mpsval; - writel(reg, regs + S3C_DOEPCTL(ep)); + if (ep) { + reg = readl(regs + S3C_DOEPCTL(ep)); + reg &= ~S3C_DxEPCTL_MPS_MASK; + reg |= mpsval; + writel(reg, regs + S3C_DOEPCTL(ep)); + } return; From 70fa030ffb652ace81dd5bcab01255b49723caec Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 14:08:29 +0900 Subject: [PATCH 10/36] usb: s3c-hsotg: Avoid TxFIFO corruption in DMA mode Writing to TxFIFO relates only to Slave mode and leads to TxFIFO corruption in DMA mode. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 03de169ab365..8db23660b5e2 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -1921,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, ints & S3C_DIEPMSK_TxFIFOEmpty) { dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n", __func__, idx); - s3c_hsotg_trytx(hsotg, hs_ep); + if (!using_dma(hsotg)) + s3c_hsotg_trytx(hsotg, hs_ep); } } } From db1d8ba36551bf55222c7961d9e9a1195a612fde Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 14:09:19 +0900 Subject: [PATCH 11/36] usb: s3c-hsotg: Fix big buffers transfer in DMA mode DMA address register shouldn't be updated manually if transfer size requires multiple packets. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 8db23660b5e2..105b206cd844 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, /* write size / packets */ writel(epsize, hsotg->regs + epsize_reg); - if (using_dma(hsotg)) { + if (using_dma(hsotg) && !continuing) { unsigned int dma_reg; /* write DMA address to control register, buffer already From 64b6c8a7019acc38cc6b37f8e72c1e915593b1bb Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 17:05:15 +0900 Subject: [PATCH 12/36] usb: dwc3: Free event buffers array Array should be freed together with event buffers, since it was allocated dynamically. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 7bd815a507e8..99b58d84553a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) for (i = 0; i < dwc->num_event_buffers; i++) { evt = dwc->ev_buffs[i]; - if (evt) { + if (evt) dwc3_free_one_event_buffer(dwc, evt); - dwc->ev_buffs[i] = NULL; - } } + + kfree(dwc->ev_buffs); } /** From e2190a97c6d493eef1f180b9dadfd5ffd4706051 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Mon, 12 Mar 2012 12:55:41 +0100 Subject: [PATCH 13/36] usb: gadget: FunctionFS: clear FFS_FL_BOUND flag on unbind (bugfix) clear FFS_FL_BOUND flag on unbind (bugfix) Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Kyungmin Park Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1cbba70836bc..d187ae73262b 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs) ffs->ep0req = NULL; ffs->gadget = NULL; ffs_data_put(ffs); + clear_bit(FFS_FL_BOUND, &ffs->flags); } } From 8545e6031a719675da9f3d21f1c8ce143dac7fe5 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Mon, 12 Mar 2012 12:55:42 +0100 Subject: [PATCH 14/36] usb: gadget: FunctionFS: make module init & exit __init & __exit make module init & exit __init & __exit Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Kyungmin Park Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/g_ffs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 331cd6729d3c..a85eaf40b948 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = { static struct ffs_data *gfs_ffs_data; static unsigned long gfs_registered; -static int gfs_init(void) +static int __init gfs_init(void) { ENTER(); @@ -169,7 +169,7 @@ static int gfs_init(void) } module_init(gfs_init); -static void gfs_exit(void) +static void __exit gfs_exit(void) { ENTER(); From 692933b2ccfce02400dc8360a97acde2846e8541 Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Wed, 14 Mar 2012 17:33:35 +0530 Subject: [PATCH 15/36] usb: musb: fix bug in musb_cleanup_urb Control transfers with data expected from device to host will use usb_rcvctrlpipe() for urb->pipe so for such urbs 'is_in' will be set causing control urb to fall into the first "if" condition in musb_cleanup_urb(). Fixed by adding logic to check for non control endpoints. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 79cb0af779fa..ef8d744800ac 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) } /* turn off DMA requests, discard state, stop polling ... */ - if (is_in) { + if (ep->epnum && is_in) { /* giveback saves bulk toggle */ csr = musb_h_flush_rxfifo(ep, 0); From bf070bc14178f1458e7eccd76316ac24f76f1890 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Wed, 21 Mar 2012 16:35:52 +0200 Subject: [PATCH 16/36] usb: musb: wake the device before ulpi transfers musb can be suspended at the time some other driver wants to do ulpi transfers using usb_phy_io_* functions, and that can cause data abort, as it happened with isp1704_charger: http://article.gmane.org/gmane.linux.kernel/1226122 Add pm_runtime to ulpi functions to rectify this. This also adds io_dev to usb_phy so that pm_runtime_* functions can be used. Cc: Felipe Contreras Signed-off-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 31 +++++++++++++++++++++++++------ include/linux/usb/otg.h | 1 + 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 239214626ec5..66aaccf04490 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) int i = 0; u8 r; u8 power; + int ret; + + pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) - return -ETIMEDOUT; + if (i == 10000) { + ret = -ETIMEDOUT; + goto out; + } } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); - return musb_readb(addr, MUSB_ULPI_REG_DATA); + ret = musb_readb(addr, MUSB_ULPI_REG_DATA); + +out: + pm_runtime_put(phy->io_dev); + + return ret; } static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) @@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) int i = 0; u8 r = 0; u8 power; + int ret = 0; + + pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) - return -ETIMEDOUT; + if (i == 10000) { + ret = -ETIMEDOUT; + goto out; + } } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); - return 0; +out: + pm_runtime_put(phy->io_dev); + + return ret; } #else #define musb_ulpi_read NULL @@ -1908,6 +1926,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) } if (!musb->xceiv->io_ops) { + musb->xceiv->io_dev = musb->controller; musb->xceiv->io_priv = musb->mregs; musb->xceiv->io_ops = &musb_ulpi_access; } diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index f67810f8f21b..38ab3f46346f 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -94,6 +94,7 @@ struct usb_phy { struct usb_otg *otg; + struct device *io_dev; struct usb_phy_io_ops *io_ops; void __iomem *io_priv; From 3006dc8c627d738693e910c159630e4368c9e86c Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Wed, 21 Mar 2012 21:30:20 +0530 Subject: [PATCH 17/36] usb: musb: omap: fix crash when musb glue (omap) gets initialized pm_runtime_enable is being called after omap2430_musb_init. Hence pm_runtime_get_sync in omap2430_musb_init does not have any effect (does not enable clocks) resulting in a crash during register access. It is fixed here. Cc: stable@vger.kernel.org # v3.0, v3.1, v3.2, v3.3 Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 3dfd122266f4..0fb4ce84d17e 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -453,14 +453,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev) goto err2; } + pm_runtime_enable(&pdev->dev); + ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); goto err2; } - pm_runtime_enable(&pdev->dev); - return 0; err2: From 8ae8090c82eb407267001f75b3d256b3bd4ae691 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Wed, 21 Mar 2012 21:34:30 +0530 Subject: [PATCH 18/36] usb: gadget: udc-core: fix asymmetric calls in remove_driver During modprobe of gadget driver, pullup is called after udc_start. In order to make the exit path symmetric when removing a gadget driver, call pullup before ->udc_stop. This is needed to avoid issues with PM where udc_stop disables the module completely (put IP in reset state, cut functional and interface clocks, and so on), which prevents us from accessing the IP's address space, thus creating the possibility of an abort exception when we try to access IP's address space after clocks are off. Cc: stable@vger.kernel.org Signed-off-by: Partha Basak Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index c261887e05ae..2fa9865babed 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -264,8 +264,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) if (udc_is_newstyle(udc)) { udc->driver->disconnect(udc->gadget); udc->driver->unbind(udc->gadget); - usb_gadget_udc_stop(udc->gadget, udc->driver); usb_gadget_disconnect(udc->gadget); + usb_gadget_udc_stop(udc->gadget, udc->driver); } else { usb_gadget_stop(udc->gadget, udc->driver); } From ad579699c4f0274bf522a9252ff9b20c72197e48 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Thu, 22 Mar 2012 12:48:06 +0530 Subject: [PATCH 19/36] usb: musb: omap: fix the error check for pm_runtime_get_sync pm_runtime_get_sync returns a signed integer. In case of errors it returns a negative value. This patch fixes the error check by making it signed instead of unsigned thus preventing register access if get_sync_fails. Also passes the error cause to the debug message. Cc: stable@vger.kernel.org Cc: Kishon Vijay Abraham I Signed-off-by: Shubhrajyoti D Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 0fb4ce84d17e..c7785e81254c 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work) static int omap2430_musb_init(struct musb *musb) { - u32 l, status = 0; + u32 l; + int status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; @@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb) status = pm_runtime_get_sync(dev); if (status < 0) { - dev_err(dev, "pm_runtime_get_sync FAILED"); + dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); goto err1; } From f135617224b4a1113b26b8ee5877e94f38e40d1e Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 10 Feb 2012 09:54:51 +0100 Subject: [PATCH 20/36] usb: gadget: rndis: fix Missing req->context assignment It is crucial to assign each req->context value to struct rndis. The problem happens for multi function gadget (g_multi) when multiple functions are calling common usb_composite_dev control request. It might happen that *_setup method from one usb function will alter some fields of this common request issued by other USB function. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_rndis.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 7b1cf18df5e3..52343654f5df 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) if (buf) { memcpy(req->buf, buf, n); req->complete = rndis_response_complete; + req->context = rndis; rndis_free_response(rndis->config, buf); value = n; } From 6190c79df861d2c78a7448fe6d4260e5fa53b9b9 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Fri, 23 Mar 2012 22:23:13 +0530 Subject: [PATCH 21/36] usb: gadget: uvc: Remove non-required locking from 'uvc_queue_next_buffer' routine This patch removes the non-required spinlock acquire/release calls on 'queue->irqlock' from 'uvc_queue_next_buffer' routine. This routine is called from 'video->encode' function (which translates to either 'uvc_video_encode_bulk' or 'uvc_video_encode_isoc') in 'uvc_video.c'. As, the 'video->encode' routines are called with 'queue->irqlock' already held, so acquiring a 'queue->irqlock' again in 'uvc_queue_next_buffer' routine causes a spin lock recursion. Signed-off-by: Bhupesh Sharma Acked-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc_queue.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c index d776adb2da67..0cdf89d32a15 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/uvc_queue.c @@ -543,11 +543,11 @@ done: return ret; } +/* called with queue->irqlock held.. */ static struct uvc_buffer * uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) { struct uvc_buffer *nextbuf; - unsigned long flags; if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && buf->buf.length != buf->buf.bytesused) { @@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) return buf; } - spin_lock_irqsave(&queue->irqlock, flags); list_del(&buf->queue); if (!list_empty(&queue->irqqueue)) nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, queue); else nextbuf = NULL; - spin_unlock_irqrestore(&queue->irqlock, flags); buf->buf.sequence = queue->sequence++; do_gettimeofday(&buf->buf.timestamp); From 92b0abf80c5c5f0e0d71d1309688a330fd74731b Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Wed, 28 Mar 2012 09:30:50 +0200 Subject: [PATCH 22/36] usb: gadget: eliminate NULL pointer dereference (bugfix) usb: gadget: eliminate NULL pointer dereference (bugfix) This patch fixes a bug which causes NULL pointer dereference in ffs_ep0_ioctl. The bug happens when the FunctionFS is not bound (either has not been bound yet or has been bound and then unbound) and can be reproduced with running the following commands: $ insmod g_ffs.ko $ mount -t functionfs func /dev/usbgadget $ ./null where null.c is: #include #include int main(void) { int fd = open("/dev/usbgadget/ep0", O_RDWR); ioctl(fd, FUNCTIONFS_CLEAR_HALT); return 0; } Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Kyungmin Park Cc: stable@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index d187ae73262b..f52cb1ae45d9 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) if (code == FUNCTIONFS_INTERFACE_REVMAP) { struct ffs_function *func = ffs->func; ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; - } else if (gadget->ops->ioctl) { + } else if (gadget && gadget->ops->ioctl) { ret = gadget->ops->ioctl(gadget, code, value); } else { ret = -ENOTTY; From 8963c487a80b4688c9e68dcc504a90074aacc145 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 17 Apr 2012 15:22:39 -0400 Subject: [PATCH 23/36] USB: fix deadlock in bConfigurationValue attribute method This patch (as154) fixes a self-deadlock that occurs when userspace writes to the bConfigurationValue sysfs attribute for a hub with children. The task tries to lock the bandwidth_mutex at a time when it already owns the lock: The attribute's method calls usb_set_configuration(), which calls usb_disable_device() with the bandwidth_mutex held. usb_disable_device() unregisters the existing interfaces, which causes the hub driver to be unbound. The hub_disconnect() routine calls hub_quiesce(), which calls usb_disconnect() for each of the hub's children. usb_disconnect() attempts to acquire the bandwidth_mutex around a call to usb_disable_device(). The solution is to make usb_disable_device() acquire the mutex for itself instead of requiring the caller to hold it. Then the mutex can cover only the bandwidth deallocation operation and not the region where the interfaces are unregistered. This has the potential to change system behavior slightly when a config change races with another config or altsetting change. Some of the bandwidth released from the old config might get claimed by the other config or altsetting, make it impossible to restore the old config in case of a failure. But since we don't try to recover from config-change failures anyway, this doesn't matter. [This should be marked for stable kernels that contain the commit fccf4e86200b8f5edd9a65da26f150e32ba79808 "USB: Free bandwidth when usb_disable_device is called." That commit was marked for stable kernels as old as 2.6.32.] Signed-off-by: Alan Stern Signed-off-by: Sarah Sharp Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 3 --- drivers/usb/core/message.c | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a2aa9d652c67..ec6c97dadbe4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev) { struct usb_device *udev = *pdev; int i; - struct usb_hcd *hcd = bus_to_hcd(udev->bus); /* mark the device as inactive, so any further urb submissions for * this device (and any of its children) will fail immediately. @@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev) * so that the hardware is now fully quiesced. */ dev_dbg (&udev->dev, "unregistering device\n"); - mutex_lock(hcd->bandwidth_mutex); usb_disable_device(udev, 0); - mutex_unlock(hcd->bandwidth_mutex); usb_hcd_synchronize_unlinks(udev); usb_remove_ep_devs(&udev->ep0); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index aed3e07942d4..ca717da3be95 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1136,8 +1136,6 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. - * - * Must be called with hcd->bandwidth_mutex held. */ void usb_disable_device(struct usb_device *dev, int skip_ep0) { @@ -1190,7 +1188,9 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) usb_disable_endpoint(dev, i + USB_DIR_IN, false); } /* Remove endpoints from the host controller internal state */ + mutex_lock(hcd->bandwidth_mutex); usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); + mutex_unlock(hcd->bandwidth_mutex); /* Second pass: remove endpoint pointers */ } for (i = skip_ep0; i < 16; ++i) { @@ -1750,7 +1750,6 @@ free_interfaces: /* if it's already configured, clear out old state first. * getting rid of old interfaces means unbinding their drivers. */ - mutex_lock(hcd->bandwidth_mutex); if (dev->state != USB_STATE_ADDRESS) usb_disable_device(dev, 1); /* Skip ep0 */ @@ -1763,6 +1762,7 @@ free_interfaces: * host controller will not allow submissions to dropped endpoints. If * this call fails, the device state is unchanged. */ + mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { mutex_unlock(hcd->bandwidth_mutex); From e65cdfae71cecec0fcd43a3f9ac8b5e4ae52db08 Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Mon, 9 Apr 2012 15:48:55 -0400 Subject: [PATCH 24/36] usb: usbtest: avoid integer overflow in test_ctrl_queue() Avoid overflowing context.count = param->sglen * param->iterations, where both `sglen' and `iterations' are from userspace. | test_ctrl_queue() | usbtest_ioctl() Keep -EOPNOTSUPP for error code. Signed-off-by: Xi Wang Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 959145baf3cf..967254afb6e8 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -904,6 +904,9 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param) struct ctrl_ctx context; int i; + if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen) + return -EOPNOTSUPP; + spin_lock_init(&context.lock); context.dev = dev; init_completion(&context.complete); @@ -1981,8 +1984,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) /* queued control messaging */ case 10: - if (param->sglen == 0) - break; retval = 0; dev_info(&intf->dev, "TEST 10: queue %d control calls, %d times\n", From 8bde9a62ee74afa89f593c563e926d163b1f6ada Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Mon, 9 Apr 2012 15:48:45 -0400 Subject: [PATCH 25/36] usb: usbtest: avoid integer overflow in alloc_sglist() A large `nents' from userspace could overflow the allocation size, leading to memory corruption. | alloc_sglist() | usbtest_ioctl() Use kmalloc_array() to avoid the overflow. Signed-off-by: Xi Wang Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 967254afb6e8..cac67dea2bac 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary) unsigned i; unsigned size = max; - sg = kmalloc(nents * sizeof *sg, GFP_KERNEL); + sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL); if (!sg) return NULL; sg_init_table(sg, nents); From 749541d19e70905e3971f2a08335a206a98e4d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 17 Apr 2012 21:37:29 +0200 Subject: [PATCH 26/36] USB: sierra: avoid QMI/wwan interface on MC77xx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These devices have a number of non serial interfaces as well. Use the existing "Direct IP" blacklist to prevent binding to interfaces which are handled by other drivers. We also extend the "Direct IP" blacklist with with interfaces only seen in "QMI" mode, assuming that these devices use the same interface numbers for serial interfaces both in "Direct IP" and in "QMI" mode. Signed-off-by: Bjørn Mork Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index fdd5aa2c8d82..8c8bf806f6fa 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = { }; /* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; +static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 }; static const struct sierra_iface_info direct_ip_interface_blacklist = { .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), .ifaceinfo = direct_ip_non_serial_ifaces, @@ -289,7 +289,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */ { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ - { USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */ /* Sierra Wireless C885 */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ @@ -299,6 +298,9 @@ static const struct usb_device_id id_table[] = { /* Sierra Wireless HSPA Non-Composite Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ + { USB_DEVICE(0x1199, 0x68A2), /* Sierra Wireless MC77xx in QMI mode */ + .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist + }, { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, From dc75ce9d929aabeb0843a6b1a4ab320e58ba1597 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 17 Apr 2012 15:24:15 -0400 Subject: [PATCH 27/36] EHCI: fix criterion for resuming the root hub This patch (as1542) changes the criterion ehci-hcd uses to tell when it needs to resume the controller's root hub. A resume is needed when a port status change is detected, obviously, but only if the root hub is currently suspended. Right now the driver tests whether the root hub is running, and that is not the correct test. In particular, if the controller has died then the root hub should not be restarted. In addition, some buggy hardware occasionally requires the root hub to be running and sending out SOF packets even while it is nominally supposed to be suspended. In the end, the test needs to be changed. Rather than checking whether the root hub is currently running, the driver will now check whether the root hub is currently suspended. This will yield the correct behavior in all cases. Signed-off-by: Alan Stern CC: Peter Chen Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 806cc95317aa..95ca07a8e1b5 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -910,7 +910,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) pcd_status = status; /* resume root hub? */ - if (!(cmd & CMD_RUN)) + if (ehci->rh_state == EHCI_RH_SUSPENDED) usb_hcd_resume_root_hub(hcd); /* get per-port change detect bits */ From 2fbe2bf1fd37f9d99950bd8d8093623cf22cf08b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 18 Apr 2012 11:33:00 -0400 Subject: [PATCH 28/36] EHCI: always clear the STS_FLR status bit This patch (as1544) fixes a problem affecting some EHCI controllers. They can generate interrupts whenever the STS_FLR status bit is turned on, even though that bit is masked out in the Interrupt Enable register. Since the driver doesn't use STS_FLR anyway, the patch changes the interrupt routine to clear that bit whenever it is set, rather than leaving it alone. Signed-off-by: Alan Stern Reported-and-tested-by: Tomoya MORINAGA Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 95ca07a8e1b5..4a3bc5b7a06f 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -858,8 +858,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) goto dead; } + /* + * We don't use STS_FLR, but some controllers don't like it to + * remain on, so mask it out along with the other status bits. + */ + masked_status = status & (INTR_MASK | STS_FLR); + /* Shared IRQ? */ - masked_status = status & INTR_MASK; if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { spin_unlock(&ehci->lock); return IRQ_NONE; From 9426cd05682745d1024dbabdec5631309bd2f480 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 16 Apr 2012 15:28:28 +0200 Subject: [PATCH 29/36] uwb: fix use of del_timer_sync() in interrupt del_timer_sync() cannot be used in interrupt. Replace it with del_timer() and a flag Signed-off-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/neh.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c index a269937be1b8..8cb71bb333c2 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c @@ -107,6 +107,7 @@ struct uwb_rc_neh { u8 evt_type; __le16 evt; u8 context; + u8 completed; uwb_rc_cmd_cb_f cb; void *arg; @@ -409,6 +410,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size struct device *dev = &rc->uwb_dev.dev; struct uwb_rc_neh *neh; struct uwb_rceb *notif; + unsigned long flags; if (rceb->bEventContext == 0) { notif = kmalloc(size, GFP_ATOMIC); @@ -422,7 +424,11 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size } else { neh = uwb_rc_neh_lookup(rc, rceb); if (neh) { - del_timer_sync(&neh->timer); + spin_lock_irqsave(&rc->neh_lock, flags); + /* to guard against a timeout */ + neh->completed = 1; + del_timer(&neh->timer); + spin_unlock_irqrestore(&rc->neh_lock, flags); uwb_rc_neh_cb(neh, rceb, size); } else dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", @@ -568,6 +574,10 @@ static void uwb_rc_neh_timer(unsigned long arg) unsigned long flags; spin_lock_irqsave(&rc->neh_lock, flags); + if (neh->completed) { + spin_unlock_irqrestore(&rc->neh_lock, flags); + return; + } if (neh->context) __uwb_rc_neh_rm(rc, neh); else From 5bd7b419ef2eb4989b207753e088c3437159618a Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 18 Apr 2012 10:05:55 +0200 Subject: [PATCH 30/36] uwb: fix error handling Fatal errors such as a device disconnect must not trigger error handling. The error returns must be checked. Signed-off-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/hwa-rc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 66797e9c5010..810c90ae2c55 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -645,7 +645,8 @@ void hwarc_neep_cb(struct urb *urb) dev_err(dev, "NEEP: URB error %d\n", urb->status); } result = usb_submit_urb(urb, GFP_ATOMIC); - if (result < 0) { + if (result < 0 && result != -ENODEV && result != -EPERM) { + /* ignoring unrecoverable errors */ dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", result); goto error; From f941f6922533316556d4dc6eee9c19d4a832c560 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 10 Apr 2012 10:48:11 +0200 Subject: [PATCH 31/36] USB: ehci-fsl: Fix kernel crash on mpc5121e Since commit 28c56ea1431421dec51b7b229369e991481453df (powerpc/usb: fix bug of kernel hang when initializing usb) the kernel crashes on mpc5121e. mpc5121e doesn't have system interface registers, accessing this register address space cause the machine check exception and a kernel crash: ... [ 1.294596] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 1.316491] fsl-ehci fsl-ehci.0: Freescale On-Chip EHCI Host Controller [ 1.337334] fsl-ehci fsl-ehci.0: new USB bus registered, assigned bus number 1 [ 1.358548] Machine check in kernel mode. [ 1.375917] Caused by (from SRR1=49030): Transfer error ack signal [ 1.395505] Oops: Machine check, sig: 7 [#1] [ 1.413113] MPC5121 ADS [ 1.428718] Modules linked in: [ 1.444841] NIP: c026efc4 LR: c0278b50 CTR: 00000000 [ 1.463342] REGS: df837ba0 TRAP: 0200 Not tainted (3.3.0-08839-gb5174fa) [ 1.484083] MSR: 00049030 CR: 42042022 XER: 20000000 [ 1.504099] TASK = df834000[1] 'swapper' THREAD: df836000 [ 1.509667] GPR00: 1c000000 df837c50 df834000 df9d74e0 00000003 00000010 00000000 00000000 [ 1.531650] GPR08: 00000020 00000000 c037cdd8 e1088000 22042028 1001a69c 00000000 00000000 [ 1.553762] GPR16: 1ffbce70 00000000 1fef5b28 1fef3e08 00000000 00000000 1ffcbc7c c045b264 [ 1.575824] GPR24: 0000008b 00000002 c04a7dd0 e1088000 df33c960 df9d74e0 00000000 df9d7400 [ 1.612295] NIP [c026efc4] ehci_fsl_setup_phy+0x110/0x124 [ 1.632454] LR [c0278b50] ehci_fsl_setup+0x29c/0x304 [ 1.652065] Call Trace: [ 1.668923] [df837c50] [c0278a40] ehci_fsl_setup+0x18c/0x304 (unreliable) [ 1.690332] [df837c70] [c025cba4] usb_add_hcd+0x1f0/0x66c [ 1.710377] [df837cb0] [c0277ab8] ehci_fsl_drv_probe+0x180/0x308 [ 1.731322] [df837ce0] [c01fc7a8] platform_drv_probe+0x20/0x30 [ 1.752202] [df837cf0] [c01fb0ac] driver_probe_device+0x8c/0x214 [ 1.773491] [df837d10] [c01f956c] bus_for_each_drv+0x6c/0xa8 [ 1.794279] [df837d40] [c01fafdc] device_attach+0xb4/0xd8 [ 1.814574] [df837d60] [c01fa44c] bus_probe_device+0xa4/0xb4 [ 1.835343] [df837d80] [c01f87a8] device_add+0x52c/0x5dc [ 1.855462] [df837dd0] [c01fcd58] platform_device_add+0x124/0x1d0 [ 1.876558] [df837df0] [c036dcec] fsl_usb2_device_register+0xa0/0xd4 [ 1.897512] [df837e10] [c036df28] fsl_usb2_mph_dr_of_probe+0x208/0x264 [ 1.918253] [df837e90] [c01fc7a8] platform_drv_probe+0x20/0x30 [ 1.938300] [df837ea0] [c01fb0ac] driver_probe_device+0x8c/0x214 [ 1.958511] [df837ec0] [c01fb2f0] __driver_attach+0xbc/0xc0 [ 1.978088] [df837ee0] [c01f9608] bus_for_each_dev+0x60/0x9c [ 1.997589] [df837f10] [c01fab88] driver_attach+0x24/0x34 [ 2.016757] [df837f20] [c01fa744] bus_add_driver+0x1ac/0x274 [ 2.036339] [df837f50] [c01fb898] driver_register+0x88/0x150 [ 2.056052] [df837f70] [c01fcabc] platform_driver_register+0x68/0x78 [ 2.076650] [df837f80] [c0446500] fsl_usb2_mph_dr_driver_init+0x18/0x28 [ 2.097734] [df837f90] [c0003988] do_one_initcall+0x148/0x1b0 [ 2.117934] [df837fc0] [c042d89c] kernel_init+0xfc/0x190 [ 2.137667] [df837ff0] [c000d2c4] kernel_thread+0x4c/0x68 [ 2.157240] Instruction dump: [ 2.174119] 90050004 4e800020 2f840003 419e0014 2f840004 409eff64 6400c000 4bffff5c [ 2.196000] 64001000 7c0004ac 812b0500 0c090000 <4c00012c> 61290200 7c0004ac 912b0500 [ 2.218100] ---[ end trace 21659aedb84ad816 ]--- [ 2.237089] [ 3.232940] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000007 [ 3.232954] [ 3.271575] Rebooting in 1 seconds.. Check pdata->have_sysif_regs flag before accessing system interface registers. Signed-off-by: Anatolij Gustschin Cc: Shengzhou Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 3e7345172e03..d0a84bd3f3eb 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, u32 portsc; struct usb_hcd *hcd = ehci_to_hcd(ehci); void __iomem *non_ehci = hcd->regs; + struct fsl_usb2_platform_data *pdata; + + pdata = hcd->self.controller->platform_data; portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); @@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, /* fall through */ case FSL_USB2_PHY_UTMI: /* enable UTMI PHY */ - setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); + if (pdata->have_sysif_regs) + setbits32(non_ehci + FSL_SOC_USB_CTRL, + CTRL_UTMI_PHY_EN); portsc |= PORT_PTS_UTMI; break; case FSL_USB2_PHY_NONE: From f4a728d09a96d6a83d9c3f39035b1aa7726892ea Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 25 Mar 2012 21:08:32 +0200 Subject: [PATCH 32/36] drivers/usb/misc/usbtest.c: add kfrees Free the two previously allocated buffers before exiting the function in an error case. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index cac67dea2bac..9dcb68f04f03 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2277,6 +2277,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id) if (status < 0) { WARNING(dev, "couldn't get endpoints, %d\n", status); + kfree(dev->buf); + kfree(dev); return status; } /* may find bulk or ISO pipes */ From 523fc5c14f6cad283e5a266eba0e343aed6e73d5 Mon Sep 17 00:00:00 2001 From: Tomoki Sekiyama Date: Fri, 30 Mar 2012 08:51:28 +0900 Subject: [PATCH 33/36] USB: yurex: Remove allocation of coherent buffer for setup-packet buffer Removes allocation of coherent buffer for the control-request setup-packet buffer from the yurex driver. Using coherent buffers for setup-packet is obsolete and does not work with some USB host implementations. Signed-off-by: Tomoki Sekiyama Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/yurex.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 897edda42270..a4a76fcd41cd 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -99,9 +99,7 @@ static void yurex_delete(struct kref *kref) usb_put_dev(dev->udev); if (dev->cntl_urb) { usb_kill_urb(dev->cntl_urb); - if (dev->cntl_req) - usb_free_coherent(dev->udev, YUREX_BUF_SIZE, - dev->cntl_req, dev->cntl_urb->setup_dma); + kfree(dev->cntl_req); if (dev->cntl_buffer) usb_free_coherent(dev->udev, YUREX_BUF_SIZE, dev->cntl_buffer, dev->cntl_urb->transfer_dma); @@ -234,9 +232,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ } /* allocate buffer for control req */ - dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, - GFP_KERNEL, - &dev->cntl_urb->setup_dma); + dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL); if (!dev->cntl_req) { err("Could not allocate cntl_req"); goto error; From 532f17b5d59bf0deb6f1ff9bc1fb27d5b5011c09 Mon Sep 17 00:00:00 2001 From: Tomoki Sekiyama Date: Fri, 30 Mar 2012 08:51:36 +0900 Subject: [PATCH 34/36] USB: yurex: Fix missing URB_NO_TRANSFER_DMA_MAP flag in urb Current probing code is setting URB_NO_TRANSFER_DMA_MAP flag into a wrong urb structure, and this causes BUG_ON with some USB host implementations. This patch fixes the issue. Signed-off-by: Tomoki Sekiyama Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/yurex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index a4a76fcd41cd..70201462e19c 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -282,7 +282,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr), dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt, dev, 1); - dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (usb_submit_urb(dev->urb, GFP_KERNEL)) { retval = -EIO; err("Could not submitting URB"); From 8034761c219ce545a9f4d3b23cfda47a0027cc8c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 18 Apr 2012 14:43:40 -0600 Subject: [PATCH 35/36] USB: ehci-tegra: don't call set_irq_flags(IRQF_VALID) This call is not needed; the IRQ controller should (and does) set up interrupts correctly. set_irq_flags() isn't exported to modules, to this also fixes compilation of ehci-tegra.c as a module. Signed-off-by: Stephen Warren Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-tegra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 73544bd440bd..86183366647f 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -731,7 +731,6 @@ static int tegra_ehci_probe(struct platform_device *pdev) err = -ENODEV; goto fail; } - set_irq_flags(irq, IRQF_VALID); #ifdef CONFIG_USB_OTG_UTILS if (pdata->operating_mode == TEGRA_USB_OTG) { From 2d5733fcd33dd451022d197cb6b476e970519ca7 Mon Sep 17 00:00:00 2001 From: Yuri Matylitski Date: Fri, 20 Apr 2012 12:38:32 +0300 Subject: [PATCH 36/36] USB: serial: cp210x: Fixed usb_control_msg timeout values Fixed too small hardcoded timeout values for usb_control_msg in driver for SiliconLabs cp210x-based usb-to-serial adapters. Replaced with USB_CTRL_GET_TIMEOUT/USB_CTRL_SET_TIMEOUT. Signed-off-by: Yuri Matylitski Acked-by: Kirill A. Shutemov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 0310e2df59f5..ec30f95ef399 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -287,7 +287,8 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - port_priv->bInterfaceNumber, buf, size, 300); + port_priv->bInterfaceNumber, buf, size, + USB_CTRL_GET_TIMEOUT); /* Convert data into an array of integers */ for (i = 0; i < length; i++) @@ -340,12 +341,14 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, 0x0000, - port_priv->bInterfaceNumber, buf, size, 300); + port_priv->bInterfaceNumber, buf, size, + USB_CTRL_SET_TIMEOUT); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, data[0], - port_priv->bInterfaceNumber, NULL, 0, 300); + port_priv->bInterfaceNumber, NULL, 0, + USB_CTRL_SET_TIMEOUT); } kfree(buf);