From 820234c86b982205aeeebde1ad71ccfe6bc4cc80 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:19 +0300 Subject: usb: gadget: atmel_usba_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index e23bf7984aaf..9a9bced813ed 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -599,12 +599,6 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) spin_lock_irqsave(&ep->udc->lock, flags); - if (ep->ep.desc) { - spin_unlock_irqrestore(&ep->udc->lock, flags); - DBG(DBG_ERR, "ep%d already enabled\n", ep->index); - return -EBUSY; - } - ep->ep.desc = desc; ep->ep.maxpacket = maxpacket; -- cgit v1.2.3-59-g8ed1b From fc065a09524991a5138835c6499e895d6be14049 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:20 +0300 Subject: usb: gadget: fsl_qe_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_qe_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 51881f3bd07a..b09452d6f33a 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -1596,7 +1596,7 @@ static int qe_ep_enable(struct usb_ep *_ep, ep = container_of(_ep, struct qe_ep, ep); /* catch various bogus parameters */ - if (!_ep || !desc || ep->ep.desc || _ep->name == ep_name[0] || + if (!_ep || !desc || _ep->name == ep_name[0] || (desc->bDescriptorType != USB_DT_ENDPOINT)) return -EINVAL; -- cgit v1.2.3-59-g8ed1b From 1fa75972c7b9f165af102022aa0090fe0a3a6c16 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:21 +0300 Subject: usb: gadget: fsl_udc_core: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 28316858208b..799841821982 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -567,7 +567,7 @@ static int fsl_ep_enable(struct usb_ep *_ep, ep = container_of(_ep, struct fsl_ep, ep); /* catch various bogus parameters */ - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || (desc->bDescriptorType != USB_DT_ENDPOINT)) return -EINVAL; -- cgit v1.2.3-59-g8ed1b From aedaa44dd3214886d70fad92197b98a0ba286cb8 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:22 +0300 Subject: usb: gadget: goku_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/goku_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index b241e6c6a7f2..3d28fb976c78 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -102,7 +102,7 @@ goku_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) unsigned long flags; ep = container_of(_ep, struct goku_ep, ep); - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; dev = ep->dev; -- cgit v1.2.3-59-g8ed1b From e0f4f9d4c9138c40738104f80bd5008517fc712d Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:24 +0300 Subject: usb: gadget: mv_udc_core: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Acked-by: Yu Xu Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index dbcd1329495e..117a4bba1b8c 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -464,7 +464,7 @@ static int mv_ep_enable(struct usb_ep *_ep, ep = container_of(_ep, struct mv_ep, ep); udc = ep->udc; - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; -- cgit v1.2.3-59-g8ed1b From 77964b3ce862262e4a22d4e5093c158f72439a0b Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:25 +0300 Subject: usb: gadget: omap_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 7ba32469c5bd..a460e8c204f4 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -153,7 +153,7 @@ static int omap_ep_enable(struct usb_ep *_ep, u16 maxp; /* catch various bogus parameters */ - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT || ep->bEndpointAddress != desc->bEndpointAddress || ep->maxpacket < usb_endpoint_maxp(desc)) { -- cgit v1.2.3-59-g8ed1b From 3ba0b31aed94167998defadfbf17d2196db05814 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:26 +0300 Subject: usb: gadget: pxa25x_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index d7c8cb3bf759..f7ff9e8e746a 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -218,7 +218,7 @@ static int pxa25x_ep_enable (struct usb_ep *_ep, struct pxa25x_udc *dev; ep = container_of (_ep, struct pxa25x_ep, ep); - if (!_ep || !desc || ep->ep.desc || _ep->name == ep0name + if (!_ep || !desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || ep->bEndpointAddress != desc->bEndpointAddress || ep->fifo_size < usb_endpoint_maxp (desc)) { -- cgit v1.2.3-59-g8ed1b From 0561ed440fbab943e1c881cab626bd7019647385 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:27 +0300 Subject: usb: gadget: s3c2410_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 3de71d37d75e..f2e51f50e528 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1062,7 +1062,7 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep, ep = to_s3c2410_ep(_ep); - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; -- cgit v1.2.3-59-g8ed1b From 109f0f718375e12bfdee53f025d85d94efed32a3 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:28 +0300 Subject: usb: gadget: s3c-hsudc.c: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Acked-by: Heiko Stuebner Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 36c6836eeb0f..236b271871a0 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -760,7 +760,7 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep, u32 ecr = 0; hsep = our_ep(_ep); - if (!_ep || !desc || hsep->ep.desc || _ep->name == ep0name + if (!_ep || !desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || hsep->bEndpointAddress != desc->bEndpointAddress || ep_maxpacket(hsep) < usb_endpoint_maxp(desc)) -- cgit v1.2.3-59-g8ed1b From 80e91fd59bc5291c6fe322551f644a58cf2c5e98 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Mon, 4 Jun 2012 17:24:03 +0200 Subject: usb: gadget: regression fix - usage of usb_ep This patch removes redundant pointer to struct usb_endpoint_descriptor which were missed in commit 79149b8: usb: gadget: Update fsl_udc_core to use usb_endpoint_descriptor inside the struct usb_ep Due to clock framework regressions, this patch is only compile tested! Signed-off-by: Christoph Fritz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 2 +- drivers/usb/gadget/fsl_usb2_udc.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 799841821982..bc6f9bb9994a 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2575,7 +2575,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) /* for ep0: the desc defined here; * for other eps, gadget layer called ep_enable with defined desc */ - udc_controller->eps[0].desc = &fsl_ep0_desc; + udc_controller->eps[0].ep.desc = &fsl_ep0_desc; udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; /* setup the udc->eps[] for non-control endpoints and link diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 5cd7b7e7ddb4..f61a967f7082 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h @@ -568,10 +568,10 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length) /* * ### internal used help routines. */ -#define ep_index(EP) ((EP)->desc->bEndpointAddress&0xF) +#define ep_index(EP) ((EP)->ep.desc->bEndpointAddress&0xF) #define ep_maxpacket(EP) ((EP)->ep.maxpacket) #define ep_is_in(EP) ( (ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ - USB_DIR_IN ):((EP)->desc->bEndpointAddress \ + USB_DIR_IN) : ((EP)->ep.desc->bEndpointAddress \ & USB_DIR_IN)==USB_DIR_IN) #define get_ep_by_pipe(udc, pipe) ((pipe == 1)? &udc->eps[0]: \ &udc->eps[pipe]) -- cgit v1.2.3-59-g8ed1b From 6594b2d7b1ef8260e6e36ddc96bd37a40e39ba80 Mon Sep 17 00:00:00 2001 From: Jon Povey Date: Fri, 25 May 2012 10:50:18 +0900 Subject: usb: musb: davinci: Fix build breakage This appears to have been broken by commit 5cfb19ac604a68c030b245561f575c2d1bac1d49 (ARM: davinci: streamline sysmod access) For now, fix by hardcoding USB_PHY_CTRL and DM355_DEEPSLEEP Tested on DM365 with defconfig changes. Signed-off-by: Jon Povey Acked-by: Sekhar Nori CC: Felipe Balbi Cc: # v3.4.x Signed-off-by: Felipe Balbi --- drivers/usb/musb/davinci.c | 1 + drivers/usb/musb/davinci.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 768b4b55c816..9d63ba4d10d6 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -34,6 +34,7 @@ #include #include +#include #include diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h index 046c84433cad..371baa0ee509 100644 --- a/drivers/usb/musb/davinci.h +++ b/drivers/usb/musb/davinci.h @@ -15,7 +15,7 @@ */ /* Integrated highspeed/otg PHY */ -#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) +#define USBPHY_CTL_PADDR 0x01c40034 #define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */ #define USBPHY_PHYCLKGD BIT(8) #define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */ @@ -27,7 +27,7 @@ #define USBPHY_OTGPDWN BIT(1) #define USBPHY_PHYPDWN BIT(0) -#define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48) +#define DM355_DEEPSLEEP_PADDR 0x01c40048 #define DRVVBUS_FORCE BIT(2) #define DRVVBUS_OVERRIDE BIT(1) -- cgit v1.2.3-59-g8ed1b From 08f75bf14fadaa81fe362d5acda9b77b113dd0a2 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 26 May 2012 00:21:33 +0300 Subject: usb: musb_gadget: fix crash caused by dangling pointer usb_ep_ops.disable must clear external copy of the endpoint descriptor, otherwise musb crashes after loading/unloading several gadget modules in a row: Unable to handle kernel paging request at virtual address bf013730 pgd = c0004000 [bf013730] *pgd=8f26d811, *pte=00000000, *ppte=00000000 Internal error: Oops: 7 [#1] Modules linked in: g_cdc [last unloaded: g_file_storage] CPU: 0 Not tainted (3.2.17 #647) PC is at musb_gadget_enable+0x4c/0x24c LR is at _raw_spin_lock_irqsave+0x4c/0x58 [] (musb_gadget_enable+0x4c/0x24c) from [] (gether_connect+0x3c/0x19c [g_cdc]) [] (gether_connect+0x3c/0x19c [g_cdc]) from [] (ecm_set_alt+0x15c/0x180 [g_cdc]) [] (ecm_set_alt+0x15c/0x180 [g_cdc]) from [] (composite_setup+0x85c/0xac4 [g_cdc]) [] (composite_setup+0x85c/0xac4 [g_cdc]) from [] (musb_g_ep0_irq+0x844/0x924) [] (musb_g_ep0_irq+0x844/0x924) from [] (musb_interrupt+0x79c/0x864) [] (musb_interrupt+0x79c/0x864) from [] (generic_interrupt+0x64/0x7c) [] (generic_interrupt+0x64/0x7c) from [] (handle_irq_event_percpu+0x28/0x178) ... Cc: stable@vger.kernel.org # v3.1+ Signed-off-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index f42c29b11f71..95918dacc99a 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1232,6 +1232,7 @@ static int musb_gadget_disable(struct usb_ep *ep) } musb_ep->desc = NULL; + musb_ep->end_point.desc = NULL; /* abort all pending DMA and requests */ nuke(musb_ep, -ESHUTDOWN); -- cgit v1.2.3-59-g8ed1b From de102ef41f24a4c251c4a3838796bb27557d4d93 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Sat, 19 May 2012 19:19:48 +0200 Subject: USB: cdc-wdm: Add Vodafone/Huawei K5005 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested-by: Thomas Schäfer Signed-off-by: Bjørn Mork Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index ea8b304f0e85..8fd398dffced 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -55,6 +55,15 @@ static const struct usb_device_id wdm_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */ }, + { + /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 57, /* NOTE: CDC ECM control interface! */ + }, { } }; -- cgit v1.2.3-59-g8ed1b From 4cbbb039a9719fb3bba73d255c6a95bc6dc6428b Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Sat, 19 May 2012 19:20:50 +0200 Subject: USB: option: Add Vodafone/Huawei K5005 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested-by: Thomas Schäfer Signed-off-by: Bjørn Mork Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 1aae9028cd0b..f3e4a470fea1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -150,6 +150,7 @@ static void option_instat_callback(struct urb *urb); #define HUAWEI_PRODUCT_E14AC 0x14AC #define HUAWEI_PRODUCT_K3806 0x14AE #define HUAWEI_PRODUCT_K4605 0x14C6 +#define HUAWEI_PRODUCT_K5005 0x14C8 #define HUAWEI_PRODUCT_K3770 0x14C9 #define HUAWEI_PRODUCT_K3771 0x14CA #define HUAWEI_PRODUCT_K4510 0x14CB @@ -666,6 +667,9 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, -- cgit v1.2.3-59-g8ed1b From c41444ccfa33a1c20efa319e554cb531576e64a2 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Thu, 24 May 2012 11:19:04 +0200 Subject: USB: qcserial: Add Sierra Wireless device IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some additional IDs found in the BSD/GPL licensed out-of-tree GobiSerial driver from Sierra Wireless. Signed-off-by: Bjørn Mork Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 0d5fe59ebb9e..996015c5f1ac 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -105,7 +105,13 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE(0x1410, 0xa021)}, /* Novatel Gobi 3000 Composite */ {USB_DEVICE(0x413c, 0x8193)}, /* Dell Gobi 3000 QDL */ {USB_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */ + {USB_DEVICE(0x1199, 0x9010)}, /* Sierra Wireless Gobi 3000 QDL */ + {USB_DEVICE(0x1199, 0x9012)}, /* Sierra Wireless Gobi 3000 QDL */ {USB_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ + {USB_DEVICE(0x1199, 0x9014)}, /* Sierra Wireless Gobi 3000 QDL */ + {USB_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ + {USB_DEVICE(0x1199, 0x9018)}, /* Sierra Wireless Gobi 3000 QDL */ + {USB_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ {USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */ {USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */ { } /* Terminating entry */ -- cgit v1.2.3-59-g8ed1b From e00a54d772210d450e5c1a801534c3c8a448549f Mon Sep 17 00:00:00 2001 From: Evan McNabb Date: Fri, 25 May 2012 22:46:14 -0400 Subject: USB: ftdi-sio: Add support for RT Systems USB-RTS01 serial adapter Add support for RT Systems USB-RTS01 USB to Serial adapter: http://www.rtsystemsinc.com/Photos/USBRTS01.html Tested by controlling Icom IC-718 amateur radio transceiver via hamlib. Signed-off-by: Evan McNabb Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8c084ea34e26..bc912e5a3beb 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -737,6 +737,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index f3c7c78ede33..5661c7e2d415 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -784,6 +784,7 @@ #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ #define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ #define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */ +#define RTSYSTEMS_RTS01_PID 0x9e57 /* USB-RTS01 Radio Cable */ /* -- cgit v1.2.3-59-g8ed1b From 5bbfa6f427c1d7244a5ee154ab8fa37265a5e049 Mon Sep 17 00:00:00 2001 From: Mikko Tuumanen Date: Fri, 1 Jun 2012 11:28:55 +0300 Subject: USB: serial: cp210x: add Optris MS Pro usb id Signed-off-by: Mikko Tuumanen Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 1b1926200ba7..73d25cd8cba5 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -82,6 +82,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ { USB_DEVICE(0x10C4, 0x806F) }, /* IMS USB to RS422 Converter Cable */ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ + { USB_DEVICE(0x10C4, 0x80C4) }, /* Cygnal Integrated Products, Inc., Optris infrared thermometer */ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ -- cgit v1.2.3-59-g8ed1b From 19a3dd1575e954e8c004413bee3e12d3962f2525 Mon Sep 17 00:00:00 2001 From: Tom Cassidy Date: Wed, 6 Jun 2012 17:08:48 +1000 Subject: USB: serial: sierra: Add support for Sierra Wireless AirCard 320U modem Add support for Sierra Wireless AirCard 320U modem Signed-off-by: Tomas Cassidy Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index ba54a0a8235c..d423d36acc04 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -294,6 +294,10 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, + /* AT&T Direct IP LTE modems */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), + .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist + }, { USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, -- cgit v1.2.3-59-g8ed1b From 42ca7da1c2363dbef4ba1b6917c4c02274b6a5e2 Mon Sep 17 00:00:00 2001 From: Andrew Bird Date: Mon, 28 May 2012 12:43:06 +0100 Subject: USB: option: Updated Huawei K4605 has better id Later firmwares for this device now have proper subclass and protocol info so we can identify it nicely without needing to use the blacklist. I'm not removing the old 0xff matching as there may be devices in the field that still need that. Signed-off-by: Andrew Bird Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f3e4a470fea1..d9cb5526368c 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -667,6 +667,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, -- cgit v1.2.3-59-g8ed1b From 1aa3c63cf0a79153ee13c8f82e4eb6c40b66a161 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 22 May 2012 20:45:13 +0100 Subject: USB: mct_u232: Fix incorrect TIOCMSET return The low level helper returns 1 on success. The ioctl should however return 0. As this is the only user of the helper return, make the helper return 0 or an error code. Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=43009 Signed-off-by: Alan Cox Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mct_u232.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index d0ec1aa52719..a71fa0aa0406 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -309,13 +309,16 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial, MCT_U232_SET_REQUEST_TYPE, 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE, WDR_TIMEOUT); - if (rc < 0) - dev_err(&serial->dev->dev, - "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); + kfree(buf); + dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); - kfree(buf); - return rc; + if (rc < 0) { + dev_err(&serial->dev->dev, + "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); + return rc; + } + return 0; } /* mct_u232_set_modem_ctrl */ static int mct_u232_get_modem_stat(struct usb_serial *serial, -- cgit v1.2.3-59-g8ed1b From 4273f9878b0a8271df055e3c8f2e7f08c6a4a2f4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 May 2012 17:57:52 +0200 Subject: USB: option: fix port-data abuse Commit 8b4c6a3ab596961b78465 ("USB: option: Use generic USB wwan code") moved option port-data allocation to usb_wwan_startup but still cast the port data to the old struct... Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d9cb5526368c..9c2f7b28e254 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1265,35 +1265,6 @@ static struct usb_serial_driver * const serial_drivers[] = { static bool debug; -/* per port private data */ - -#define N_IN_URB 4 -#define N_OUT_URB 4 -#define IN_BUFLEN 4096 -#define OUT_BUFLEN 4096 - -struct option_port_private { - /* Input endpoints and buffer for this port */ - struct urb *in_urbs[N_IN_URB]; - u8 *in_buffer[N_IN_URB]; - /* Output endpoints and buffer for this port */ - struct urb *out_urbs[N_OUT_URB]; - u8 *out_buffer[N_OUT_URB]; - unsigned long out_busy; /* Bit vector of URBs in use */ - int opened; - struct usb_anchor delayed; - - /* Settings for the port */ - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - - unsigned long tx_start_time[N_OUT_URB]; -}; - module_usb_serial_driver(serial_drivers, option_ids); static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, @@ -1367,7 +1338,8 @@ static void option_instat_callback(struct urb *urb) int err; int status = urb->status; struct usb_serial_port *port = urb->context; - struct option_port_private *portdata = usb_get_serial_port_data(port); + struct usb_wwan_port_private *portdata = + usb_get_serial_port_data(port); dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); @@ -1427,7 +1399,7 @@ static int option_send_setup(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct usb_wwan_intf_private *intfdata = (struct usb_wwan_intf_private *) serial->private; - struct option_port_private *portdata; + struct usb_wwan_port_private *portdata; int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; int val = 0; -- cgit v1.2.3-59-g8ed1b From b9c3aab315b51f81649a0d737c4c73783fbd8de0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 May 2012 18:22:48 +0200 Subject: USB: option: fix memory leak Fix memory leak introduced by commit 383cedc3bb435de7a2 ("USB: serial: full autosuspend support for the option driver") which allocates usb-serial data but never frees it. Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9c2f7b28e254..d12ee2fca76b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -47,6 +47,7 @@ /* Function prototypes */ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id); +static void option_release(struct usb_serial *serial); static int option_send_setup(struct usb_serial_port *port); static void option_instat_callback(struct urb *urb); @@ -1251,7 +1252,7 @@ static struct usb_serial_driver option_1port_device = { .ioctl = usb_wwan_ioctl, .attach = usb_wwan_startup, .disconnect = usb_wwan_disconnect, - .release = usb_wwan_release, + .release = option_release, .read_int_callback = option_instat_callback, #ifdef CONFIG_PM .suspend = usb_wwan_suspend, @@ -1333,6 +1334,15 @@ static int option_probe(struct usb_serial *serial, return 0; } +static void option_release(struct usb_serial *serial) +{ + struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); + + usb_wwan_release(serial); + + kfree(priv); +} + static void option_instat_callback(struct urb *urb) { int err; -- cgit v1.2.3-59-g8ed1b From b9c87663eead64c767e72a373ae6f8a94bead459 Mon Sep 17 00:00:00 2001 From: Tony Zelenoff Date: Tue, 5 Jun 2012 17:58:04 +0400 Subject: USB: mos7840: Fix compilation of usb serial driver The __devinitconst section can't be referenced from usb_serial_device structure. Thus removed it as it done in other mos* device drivers. Error itself: WARNING: drivers/usb/serial/mos7840.o(.data+0x8): Section mismatch in reference from the variable moschip7840_4port_device to the variable .devinit.rodata:id_table The variable moschip7840_4port_device references the variable __devinitconst id_table [v2] no attach now Signed-off-by: Tony Zelenoff Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7840.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 29160f8b5101..57eca2448424 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -190,7 +190,7 @@ static int device_type; -static const struct usb_device_id id_table[] __devinitconst = { +static const struct usb_device_id id_table[] = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)}, -- cgit v1.2.3-59-g8ed1b From 0ef0be15fd2564767f114c249fc4af704d8e16f4 Mon Sep 17 00:00:00 2001 From: 说不得 Date: Mon, 28 May 2012 21:31:29 +0800 Subject: USB: option: add more YUGA device ids Signed-off-by: gavin zhu Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d12ee2fca76b..e668a2460bd4 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -427,7 +427,7 @@ static void option_instat_callback(struct urb *urb); #define SAMSUNG_VENDOR_ID 0x04e8 #define SAMSUNG_PRODUCT_GT_B3730 0x6889 -/* YUGA products www.yuga-info.com*/ +/* YUGA products www.yuga-info.com gavin.kx@qq.com */ #define YUGA_VENDOR_ID 0x257A #define YUGA_PRODUCT_CEM600 0x1601 #define YUGA_PRODUCT_CEM610 0x1602 @@ -444,6 +444,8 @@ static void option_instat_callback(struct urb *urb); #define YUGA_PRODUCT_CEU516 0x160C #define YUGA_PRODUCT_CEU528 0x160D #define YUGA_PRODUCT_CEU526 0x160F +#define YUGA_PRODUCT_CEU881 0x161F +#define YUGA_PRODUCT_CEU882 0x162F #define YUGA_PRODUCT_CWM600 0x2601 #define YUGA_PRODUCT_CWM610 0x2602 @@ -459,23 +461,26 @@ static void option_instat_callback(struct urb *urb); #define YUGA_PRODUCT_CWU518 0x260B #define YUGA_PRODUCT_CWU516 0x260C #define YUGA_PRODUCT_CWU528 0x260D +#define YUGA_PRODUCT_CWU581 0x260E #define YUGA_PRODUCT_CWU526 0x260F - -#define YUGA_PRODUCT_CLM600 0x2601 -#define YUGA_PRODUCT_CLM610 0x2602 -#define YUGA_PRODUCT_CLM500 0x2603 -#define YUGA_PRODUCT_CLM510 0x2604 -#define YUGA_PRODUCT_CLM800 0x2605 -#define YUGA_PRODUCT_CLM900 0x2606 - -#define YUGA_PRODUCT_CLU718 0x2607 -#define YUGA_PRODUCT_CLU716 0x2608 -#define YUGA_PRODUCT_CLU728 0x2609 -#define YUGA_PRODUCT_CLU726 0x260A -#define YUGA_PRODUCT_CLU518 0x260B -#define YUGA_PRODUCT_CLU516 0x260C -#define YUGA_PRODUCT_CLU528 0x260D -#define YUGA_PRODUCT_CLU526 0x260F +#define YUGA_PRODUCT_CWU582 0x261F +#define YUGA_PRODUCT_CWU583 0x262F + +#define YUGA_PRODUCT_CLM600 0x3601 +#define YUGA_PRODUCT_CLM610 0x3602 +#define YUGA_PRODUCT_CLM500 0x3603 +#define YUGA_PRODUCT_CLM510 0x3604 +#define YUGA_PRODUCT_CLM800 0x3605 +#define YUGA_PRODUCT_CLM900 0x3606 + +#define YUGA_PRODUCT_CLU718 0x3607 +#define YUGA_PRODUCT_CLU716 0x3608 +#define YUGA_PRODUCT_CLU728 0x3609 +#define YUGA_PRODUCT_CLU726 0x360A +#define YUGA_PRODUCT_CLU518 0x360B +#define YUGA_PRODUCT_CLU516 0x360C +#define YUGA_PRODUCT_CLU528 0x360D +#define YUGA_PRODUCT_CLU526 0x360F /* Viettel products */ #define VIETTEL_VENDOR_ID 0x2262 @@ -1216,6 +1221,11 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU881) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU882) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU581) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU582) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU583) }, { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) }, { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */ -- cgit v1.2.3-59-g8ed1b From c2fb8a3fa25513de8fedb38509b1f15a5bbee47b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 13 Jun 2012 11:20:19 -0400 Subject: USB: add NO_D3_DURING_SLEEP flag and revert 151b61284776be2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch (as1558) fixes a problem affecting several ASUS computers: The machine crashes or corrupts memory when going into suspend if the ehci-hcd driver is bound to any controllers. Users have been forced to unbind or unload ehci-hcd before putting their systems to sleep. After extensive testing, it was determined that the machines don't like going into suspend when any EHCI controllers are in the PCI D3 power state. Presumably this is a firmware bug, but there's nothing we can do about it except to avoid putting the controllers in D3 during system sleep. The patch adds a new flag to indicate whether the problem is present, and avoids changing the controller's power state if the flag is set. Runtime suspend is unaffected; this matters only for system suspend. However as a side effect, the controller will not respond to remote wakeup requests while the system is asleep. Hence USB wakeup is not functional -- but of course, this is already true in the current state of affairs. A similar patch has already been applied as commit 151b61284776be2d6f02d48c23c3625678960b97 (USB: EHCI: fix crash during suspend on ASUS computers). The patch supersedes that one and reverts it. There are two differences: The old patch added the flag at the USB level; this patch adds it at the PCI level. The old patch applied to all chipsets with the same vendor, subsystem vendor, and product IDs; this patch makes an exception for a known-good system (based on DMI information). Signed-off-by: Alan Stern Tested-by: Dâniel Fraga Tested-by: Andrey Rahmatullin Tested-by: Steven Rostedt Cc: stable Reviewed-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 5 +++++ drivers/pci/quirks.c | 26 ++++++++++++++++++++++++++ drivers/usb/core/hcd-pci.c | 9 --------- drivers/usb/host/ehci-pci.c | 8 -------- include/linux/pci.h | 2 ++ include/linux/usb/hcd.h | 2 -- 6 files changed, 33 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..77cb54a65cde 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1744,6 +1744,11 @@ int pci_prepare_to_sleep(struct pci_dev *dev) if (target_state == PCI_POWER_ERROR) return -EIO; + /* Some devices mustn't be in D3 during system sleep */ + if (target_state == PCI_D3hot && + (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP)) + return 0; + pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); error = pci_set_power_state(dev, target_state); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2a7521677541..194b243a2817 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2929,6 +2929,32 @@ static void __devinit disable_igfx_irq(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); +/* + * The Intel 6 Series/C200 Series chipset's EHCI controllers on many + * ASUS motherboards will cause memory corruption or a system crash + * if they are in D3 while the system is put into S3 sleep. + */ +static void __devinit asus_ehci_no_d3(struct pci_dev *dev) +{ + const char *sys_info; + static const char good_Asus_board[] = "P8Z68-V"; + + if (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP) + return; + if (dev->subsystem_vendor != PCI_VENDOR_ID_ASUSTEK) + return; + sys_info = dmi_get_system_info(DMI_BOARD_NAME); + if (sys_info && memcmp(sys_info, good_Asus_board, + sizeof(good_Asus_board) - 1) == 0) + return; + + dev_info(&dev->dev, "broken D3 during system sleep on ASUS\n"); + dev->dev_flags |= PCI_DEV_FLAGS_NO_D3_DURING_SLEEP; + device_set_wakeup_capable(&dev->dev, false); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c26, asus_ehci_no_d3); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c2d, asus_ehci_no_d3); + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 57ed9e400c06..622b4a48e732 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -493,15 +493,6 @@ static int hcd_pci_suspend_noirq(struct device *dev) pci_save_state(pci_dev); - /* - * Some systems crash if an EHCI controller is in D3 during - * a sleep transition. We have to leave such controllers in D0. - */ - if (hcd->broken_pci_sleep) { - dev_dbg(dev, "Staying in PCI D0\n"); - return retval; - } - /* If the root hub is dead rather than suspended, disallow remote * wakeup. usb_hc_died() should ensure that both hosts are marked as * dying, so we only need to check the primary roothub. diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index bc94d7bf072d..123481793a47 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -144,14 +144,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) hcd->has_tt = 1; tdi_reset(ehci); } - if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) { - /* EHCI #1 or #2 on 6 Series/C200 Series chipset */ - if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) { - ehci_info(ehci, "broken D3 during system sleep on ASUS\n"); - hcd->broken_pci_sleep = 1; - device_set_wakeup_capable(&pdev->dev, false); - } - } break; case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { diff --git a/include/linux/pci.h b/include/linux/pci.h index d8c379dba6ad..fefb4e19bf6a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -176,6 +176,8 @@ enum pci_dev_flags { PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2, /* Provide indication device is assigned by a Virtual Machine Manager */ PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4, + /* Device causes system crash if in D3 during S3 sleep */ + PCI_DEV_FLAGS_NO_D3_DURING_SLEEP = (__force pci_dev_flags_t) 8, }; enum pci_irq_reroute_variant { diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7f855d50cdf5..49b3ac29726a 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -126,8 +126,6 @@ struct usb_hcd { unsigned wireless:1; /* Wireless USB HCD */ unsigned authorized_default:1; unsigned has_tt:1; /* Integrated TT in root hub */ - unsigned broken_pci_sleep:1; /* Don't put the - controller in PCI-D3 for system sleep */ unsigned int irq; /* irq allocated */ void __iomem *regs; /* device memory/io */ -- cgit v1.2.3-59-g8ed1b From 954c3f8a5f1b7716be9eee978b3bc85bae92d7c8 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 30 May 2012 10:00:14 +0200 Subject: USB: serial: Enforce USB driver and USB serial driver match MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to make sure that the USB serial driver we find matches the USB driver whose probe we are currently executing. Otherwise we will end up with USB serial devices bound to the correct serial driver but wrong USB driver. An example of such cross-probing, where the usbserial_generic USB driver has found the sierra serial driver: May 29 18:26:15 nemi kernel: [ 4442.559246] usbserial_generic 4-4:1.0: Sierra USB modem converter detected May 29 18:26:20 nemi kernel: [ 4447.556747] usbserial_generic 4-4:1.2: Sierra USB modem converter detected May 29 18:26:25 nemi kernel: [ 4452.557288] usbserial_generic 4-4:1.3: Sierra USB modem converter detected sysfs view of the same problem: bjorn@nemi:~$ ls -l /sys/bus/usb/drivers/sierra/ total 0 --w------- 1 root root 4096 May 29 18:23 bind lrwxrwxrwx 1 root root 0 May 29 18:23 module -> ../../../../module/usbserial --w------- 1 root root 4096 May 29 18:23 uevent --w------- 1 root root 4096 May 29 18:23 unbind bjorn@nemi:~$ ls -l /sys/bus/usb-serial/drivers/sierra/ total 0 --w------- 1 root root 4096 May 29 18:23 bind lrwxrwxrwx 1 root root 0 May 29 18:23 module -> ../../../../module/sierra -rw-r--r-- 1 root root 4096 May 29 18:23 new_id lrwxrwxrwx 1 root root 0 May 29 18:32 ttyUSB0 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.0/ttyUSB0 lrwxrwxrwx 1 root root 0 May 29 18:32 ttyUSB1 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.2/ttyUSB1 lrwxrwxrwx 1 root root 0 May 29 18:32 ttyUSB2 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.3/ttyUSB2 --w------- 1 root root 4096 May 29 18:23 uevent --w------- 1 root root 4096 May 29 18:23 unbind bjorn@nemi:~$ ls -l /sys/bus/usb/drivers/usbserial_generic/ total 0 lrwxrwxrwx 1 root root 0 May 29 18:33 4-4:1.0 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.0 lrwxrwxrwx 1 root root 0 May 29 18:33 4-4:1.2 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.2 lrwxrwxrwx 1 root root 0 May 29 18:33 4-4:1.3 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.3 --w------- 1 root root 4096 May 29 18:33 bind lrwxrwxrwx 1 root root 0 May 29 18:33 module -> ../../../../module/usbserial --w------- 1 root root 4096 May 29 18:22 uevent --w------- 1 root root 4096 May 29 18:33 unbind bjorn@nemi:~$ ls -l /sys/bus/usb-serial/drivers/generic/ total 0 --w------- 1 root root 4096 May 29 18:33 bind lrwxrwxrwx 1 root root 0 May 29 18:33 module -> ../../../../module/usbserial -rw-r--r-- 1 root root 4096 May 29 18:33 new_id --w------- 1 root root 4096 May 29 18:22 uevent --w------- 1 root root 4096 May 29 18:33 unbind So we end up with a mismatch between the USB driver and the USB serial driver. The reason for the above is simple: The USB driver probe will succeed if *any* registered serial driver matches, and will use that serial driver for all serial driver functions. This makes ref counting go wrong. We count the USB driver as used, but not the USB serial driver. This may result in Oops'es as demonstrated by Johan Hovold : [11811.646396] drivers/usb/serial/usb-serial.c: get_free_serial 1 [11811.646443] drivers/usb/serial/usb-serial.c: get_free_serial - minor base = 0 [11811.646460] drivers/usb/serial/usb-serial.c: usb_serial_probe - registering ttyUSB0 [11811.646766] usb 6-1: pl2303 converter now attached to ttyUSB0 [11812.264197] USB Serial deregistering driver FTDI USB Serial Device [11812.264865] usbcore: deregistering interface driver ftdi_sio [11812.282180] USB Serial deregistering driver pl2303 [11812.283141] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0 [11812.283272] usbcore: deregistering interface driver pl2303 [11812.301056] USB Serial deregistering driver generic [11812.301186] usbcore: deregistering interface driver usbserial_generic [11812.301259] drivers/usb/serial/usb-serial.c: usb_serial_disconnect [11812.301823] BUG: unable to handle kernel paging request at f8e7438c [11812.301845] IP: [] usb_serial_disconnect+0xb5/0x100 [usbserial] [11812.301871] *pde = 357ef067 *pte = 00000000 [11812.301957] Oops: 0000 [#1] PREEMPT SMP [11812.301983] Modules linked in: usbserial(-) [last unloaded: pl2303] [11812.302008] [11812.302019] Pid: 1323, comm: modprobe Tainted: G W 3.4.0-rc7+ #101 Dell Inc. Vostro 1520/0T816J [11812.302115] EIP: 0060:[] EFLAGS: 00010246 CPU: 1 [11812.302130] EIP is at usb_serial_disconnect+0xb5/0x100 [usbserial] [11812.302141] EAX: f508a180 EBX: f508a180 ECX: 00000000 EDX: f8e74300 [11812.302151] ESI: f5050800 EDI: 00000001 EBP: f5141e78 ESP: f5141e58 [11812.302160] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [11812.302170] CR0: 8005003b CR2: f8e7438c CR3: 34848000 CR4: 000007d0 [11812.302180] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 [11812.302189] DR6: ffff0ff0 DR7: 00000400 [11812.302199] Process modprobe (pid: 1323, ti=f5140000 task=f61e2bc0 task.ti=f5140000) [11812.302209] Stack: [11812.302216] f8e3be0f f8e3b29c f8e3ae00 00000000 f513641c f5136400 f513641c f507a540 [11812.302325] f5141e98 c133d2c1 00000000 00000000 f509c400 f513641c f507a590 f5136450 [11812.302372] f5141ea8 c12f0344 f513641c f507a590 f5141ebc c12f0c67 00000000 f507a590 [11812.302419] Call Trace: [11812.302439] [] usb_unbind_interface+0x51/0x190 [11812.302456] [] __device_release_driver+0x64/0xb0 [11812.302469] [] driver_detach+0x97/0xa0 [11812.302483] [] bus_remove_driver+0x6c/0xe0 [11812.302500] [] ? __mutex_unlock_slowpath+0xcd/0x140 [11812.302514] [] driver_unregister+0x49/0x80 [11812.302528] [] ? printk+0x1d/0x1f [11812.302540] [] usb_deregister+0x5d/0xb0 [11812.302557] [] ? usb_serial_deregister+0x45/0x50 [usbserial] [11812.302575] [] usb_serial_deregister_drivers+0x2d/0x40 [usbserial] [11812.302593] [] usb_serial_generic_deregister+0x12/0x20 [usbserial] [11812.302611] [] usb_serial_exit+0x8/0x32 [usbserial] [11812.302716] [] sys_delete_module+0x158/0x260 [11812.302730] [] ? mntput+0x1e/0x30 [11812.302746] [] ? sysenter_exit+0xf/0x18 [11812.302746] [] ? trace_hardirqs_on_caller+0xec/0x170 [11812.302746] [] sysenter_do_call+0x12/0x36 [11812.302746] Code: 24 02 00 00 e8 dd f3 20 c8 f6 86 74 02 00 00 02 74 b4 8d 86 4c 02 00 00 47 e8 78 55 4b c8 0f b6 43 0e 39 f8 7f a9 8b 53 04 89 d8 92 8c 00 00 00 89 d8 e8 0e ff ff ff 8b 45 f0 c7 44 24 04 2f [11812.302746] EIP: [] usb_serial_disconnect+0xb5/0x100 [usbserial] SS:ESP 0068:f5141e58 [11812.302746] CR2: 00000000f8e7438c Fix by only evaluating serial drivers pointing back to the USB driver we are currently probing. This still allows two or more drivers to match the same device, running their serial driver probes to sort out which one to use. Cc: stable@vger.kernel.org # 3.0, 3.2, 3.3, 3.4 Signed-off-by: Bjørn Mork Reviewed-by: Felipe Balbi Tested-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 6a1b609a0d94..6e8c527e07c9 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -659,12 +659,14 @@ exit: static struct usb_serial_driver *search_serial_device( struct usb_interface *iface) { - const struct usb_device_id *id; + const struct usb_device_id *id = NULL; struct usb_serial_driver *drv; + struct usb_driver *driver = to_usb_driver(iface->dev.driver); /* Check if the usb id matches a known device */ list_for_each_entry(drv, &usb_serial_driver_list, driver_list) { - id = get_iface_id(drv, iface); + if (drv->usb_driver == driver) + id = get_iface_id(drv, iface); if (id) return drv; } -- cgit v1.2.3-59-g8ed1b From 0b84704a2d6fdf55a3dcdd2a1f2ac8b48913c84b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 31 May 2012 17:03:52 -0400 Subject: USB: serial-generic: use a single set of device IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The usb-serial-generic driver uses different device IDs for its USB matching and its serial matching. This can lead to problems: The driver can end up getting bound to a USB interface without being allowed to bind to the corresponding serial port. This patch (as1557) fixes the problem by using the same device ID table (the one that can be altered by the "vendor=" and "product=" module parameters) for both purposes. The unused table is removed. Now the driver will bind only to the intended devices. Signed-off-by: Alan Stern CC: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 105a6d898ca4..9b026bf7afef 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -39,13 +39,6 @@ MODULE_PARM_DESC(product, "User specified USB idProduct"); static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ -/* we want to look at all devices, as the vendor/product id can change - * depending on the command line argument */ -static const struct usb_device_id generic_serial_ids[] = { - {.driver_info = 42}, - {} -}; - /* All of the device info needed for the Generic Serial Converter */ struct usb_serial_driver usb_serial_generic_device = { .driver = { @@ -79,7 +72,8 @@ int usb_serial_generic_register(int _debug) USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; /* register our generic driver with ourselves */ - retval = usb_serial_register_drivers(serial_drivers, "usbserial_generic", generic_serial_ids); + retval = usb_serial_register_drivers(serial_drivers, + "usbserial_generic", generic_device_ids); #endif return retval; } -- cgit v1.2.3-59-g8ed1b From afff07e61a5243e14ee3f0a272a0380cd744a8a3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 13 Jun 2012 11:44:58 +0200 Subject: usb-storage: Add 090c:1000 to unusal-devs This device gives a bogus answer to get_capacity(16): [ 8628.278614] scsi 8:0:0:0: Direct-Access USB 2.0 USB Flash Drive 1100 PQ: 0 ANSI: 4 [ 8628.279452] sd 8:0:0:0: Attached scsi generic sg4 type 0 [ 8628.280338] sd 8:0:0:0: [sdd] 35747322042253313 512-byte logical blocks: (18.3 EB/15.8 EiB) So set the quirk flag to avoid using get_capacity(16) with it: [11731.386014] usb-storage 2-1.6:1.0: Quirks match for vid 090c pid 1000: 80000 [11731.386075] scsi9 : usb-storage 2-1.6:1.0 [11731.386172] usbcore: registered new interface driver usb-storage [11731.386175] USB Mass Storage support registered. [11732.387394] scsi 9:0:0:0: Direct-Access USB 2.0 USB Flash Drive 1100 PQ: 0 ANSI: 4 [11732.388462] sd 9:0:0:0: Attached scsi generic sg3 type 0 [11732.389432] sd 9:0:0:0: [sdc] 7975296 512-byte logical blocks: (4.08 GB/3.80 GiB) Which makes the capacity look a lot more sane :) Signed-off-by: Hans de Goede Tested-by: Simon Raffeiner Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 1719886bb9be..caf22bf5f822 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1107,6 +1107,13 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, USB_SC_RBC, USB_PR_BULK, NULL, 0 ), +/* Feiya QDI U2 DISK, reported by Hans de Goede */ +UNUSUAL_DEV( 0x090c, 0x1000, 0x0000, 0xffff, + "Feiya", + "QDI U2 DISK", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_READ_CAPACITY_16 ), + /* aeb */ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, "Feiya", -- cgit v1.2.3-59-g8ed1b From 55558c33d6d46cb6f426b729f4119e3b2f12f02b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 22 May 2012 20:54:34 +0300 Subject: USB: Checking the wrong variable in usb_disable_lpm() We check "u1_params" instead of checking "u2_params". Signed-off-by: Dan Carpenter Signed-off-by: Sarah Sharp --- drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 04fb834c3fa1..25a7422ee657 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3379,7 +3379,7 @@ int usb_disable_lpm(struct usb_device *udev) return 0; udev->lpm_disable_count++; - if ((udev->u1_params.timeout == 0 && udev->u1_params.timeout == 0)) + if ((udev->u1_params.timeout == 0 && udev->u2_params.timeout == 0)) return 0; /* If LPM is enabled, attempt to disable it. */ -- cgit v1.2.3-59-g8ed1b From e25e62aecac42379e113c63a674a86ae3ebbec8d Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 7 Jun 2012 11:10:32 -0700 Subject: xhci: Fix error path return value. This patch fixes an issue discovered by Dan Carpenter: The patch 3b3db026414b: "xhci: Add infrastructure for host-specific LPM policies." from May 9, 2012, leads to the following warning: drivers/usb/host/xhci.c:3909 xhci_get_timeout_no_hub_lpm() warn: signedness bug returning '-22' 3906 default: 3907 dev_warn(&udev->dev, "%s: Can't get timeout for non-U1 or U2 state.\n", 3908 __func__); 3909 return -EINVAL; ^^^^^^^^^^^^^^ This should be a u16 like USB3_LPM_DISABLED or something. 3910 } 3911 3912 if (sel <= max_sel_pel && pel <= max_sel_pel) 3913 return USB3_LPM_DEVICE_INITIATED; Signed-off-by: Sarah Sharp Reported-by: Dan Carpenter --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index afdc73ee84a6..1d4958f7f007 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3906,7 +3906,7 @@ static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, default: dev_warn(&udev->dev, "%s: Can't get timeout for non-U1 or U2 state.\n", __func__); - return -EINVAL; + return USB3_LPM_DISABLED; } if (sel <= max_sel_pel && pel <= max_sel_pel) -- cgit v1.2.3-59-g8ed1b From 46ed8f00d8982e49f8fe2c1a9cea192f640cb3ba Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 1 Jun 2012 10:06:23 +0200 Subject: xhci: Fix invalid loop check in xhci_free_tt_info() xhci_free_tt_info() may access the invalid memory when it removes the last entry but the list is not empty. Then tt_next reaches to the list head but it still tries to check the tt_info of that entry. This patch fixes the bug and cleans up the messy code by rewriting with a simple list_for_each_entry_safe(). This patch should be backported to kernels as old as 3.2, that contain the commit 839c817ce67178ca3c7c7ad534c571bba1e69ebe "xhci: Store information about roothubs and TTs." Signed-off-by: Takashi Iwai Signed-off-by: Sarah Sharp Reviewed-by: Oliver Neukum Cc: --- drivers/usb/host/xhci-mem.c | 39 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index ec4338eec826..898dfc8bc520 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -793,10 +793,9 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, int slot_id) { - struct list_head *tt; struct list_head *tt_list_head; - struct list_head *tt_next; - struct xhci_tt_bw_info *tt_info; + struct xhci_tt_bw_info *tt_info, *next; + bool slot_found = false; /* If the device never made it past the Set Address stage, * it may not have the real_port set correctly. @@ -808,34 +807,16 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci, } tt_list_head = &(xhci->rh_bw[virt_dev->real_port - 1].tts); - if (list_empty(tt_list_head)) - return; - - list_for_each(tt, tt_list_head) { - tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list); - if (tt_info->slot_id == slot_id) + list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) { + /* Multi-TT hubs will have more than one entry */ + if (tt_info->slot_id == slot_id) { + slot_found = true; + list_del(&tt_info->tt_list); + kfree(tt_info); + } else if (slot_found) { break; + } } - /* Cautionary measure in case the hub was disconnected before we - * stored the TT information. - */ - if (tt_info->slot_id != slot_id) - return; - - tt_next = tt->next; - tt_info = list_entry(tt, struct xhci_tt_bw_info, - tt_list); - /* Multi-TT hubs will have more than one entry */ - do { - list_del(tt); - kfree(tt_info); - tt = tt_next; - if (list_empty(tt_list_head)) - break; - tt_next = tt->next; - tt_info = list_entry(tt, struct xhci_tt_bw_info, - tt_list); - } while (tt_info->slot_id == slot_id); } int xhci_alloc_tt_info(struct xhci_hcd *xhci, -- cgit v1.2.3-59-g8ed1b From 32f1d2c536d0c26c5814cb0e6a0606c42d02fac1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 1 Jun 2012 10:06:24 +0200 Subject: xhci: Don't free endpoints in xhci_mem_cleanup() This patch fixes a few issues introduced in the recent fix [f8a9e72d: USB: fix resource leak in xhci power loss path] - The endpoints listed in bw table are just links and each entry is an array member of dev->eps[]. But the commit above adds a kfree() call to these instances, and thus it results in memory corruption. - It clears only the first entry of rh_bw[], but there can be multiple ports. - It'd be safer to clear the list_head of ep as well, not only removing from the list, as it's checked in xhci_discover_or_reset_device(). This patch should be backported to kernels as old as 3.2, that contain the commit 839c817ce67178ca3c7c7ad534c571bba1e69ebe "xhci: Store information about roothubs and TTs." Signed-off-by: Takashi Iwai Signed-off-by: Sarah Sharp Reviewed-by: Oliver Neukum Cc: --- drivers/usb/host/xhci-mem.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 898dfc8bc520..77689bd64cac 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1772,17 +1772,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) { struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); struct dev_info *dev_info, *next; - struct list_head *tt_list_head; - struct list_head *tt; - struct list_head *endpoints; - struct list_head *ep, *q; - struct xhci_tt_bw_info *tt_info; - struct xhci_interval_bw_table *bwt; - struct xhci_virt_ep *virt_ep; - unsigned long flags; int size; - int i; + int i, j, num_ports; /* Free the Event Ring Segment Table and the actual Event Ring */ size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); @@ -1841,21 +1833,22 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) } spin_unlock_irqrestore(&xhci->lock, flags); - bwt = &xhci->rh_bw->bw_table; - for (i = 0; i < XHCI_MAX_INTERVAL; i++) { - endpoints = &bwt->interval_bw[i].endpoints; - list_for_each_safe(ep, q, endpoints) { - virt_ep = list_entry(ep, struct xhci_virt_ep, bw_endpoint_list); - list_del(&virt_ep->bw_endpoint_list); - kfree(virt_ep); + num_ports = HCS_MAX_PORTS(xhci->hcs_params1); + for (i = 0; i < num_ports; i++) { + struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; + for (j = 0; j < XHCI_MAX_INTERVAL; j++) { + struct list_head *ep = &bwt->interval_bw[j].endpoints; + while (!list_empty(ep)) + list_del_init(ep->next); } } - tt_list_head = &xhci->rh_bw->tts; - list_for_each_safe(tt, q, tt_list_head) { - tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list); - list_del(tt); - kfree(tt_info); + for (i = 0; i < num_ports; i++) { + struct xhci_tt_bw_info *tt, *n; + list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) { + list_del(&tt->tt_list); + kfree(tt); + } } xhci->num_usb2_ports = 0; -- cgit v1.2.3-59-g8ed1b From 622eb783fe6ff4c1baa47db16c3a5db97f9e6e50 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Wed, 13 Jun 2012 10:51:57 +0800 Subject: xHCI: Increase the timeout for controller save/restore state operation When system software decides to power down the xHC with the intent of resuming operation at a later time, it will ask xHC to save the internal state and restore it when resume to correctly recover from a power event. Two bits are used to enable this operation: Save State and Restore State. xHCI spec 4.23.2 says software should "Set the Controller Save/Restore State flag in the USBCMD register and wait for the Save/Restore State Status flag in the USBSTS register to transition to '0'". However, it does not define how long software should wait for the SSS/RSS bit to transition to 0. Currently the timeout is set to 1ms. There is bug report (https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1002697) indicates that the timeout is too short for ASMedia ASM1042 host controller to save/restore the state successfully. Increase the timeout to 10ms helps to resolve the issue. This patch should be backported to stable kernels as old as 2.6.37, that contain the commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: PCI power management implementation" Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp Cc: Ming Lei Cc: stable@vger.kernel.org --- drivers/usb/host/xhci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1d4958f7f007..a979cd0dbe0f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -795,8 +795,8 @@ int xhci_suspend(struct xhci_hcd *xhci) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_CSS; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10*100)) { - xhci_warn(xhci, "WARN: xHC CMD_CSS timeout\n"); + if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) { + xhci_warn(xhci, "WARN: xHC save state timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } @@ -848,8 +848,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command |= CMD_CRS; xhci_writel(xhci, command, &xhci->op_regs->command); if (handshake(xhci, &xhci->op_regs->status, - STS_RESTORE, 0, 10*100)) { - xhci_dbg(xhci, "WARN: xHC CMD_CSS timeout\n"); + STS_RESTORE, 0, 10 * 1000)) { + xhci_warn(xhci, "WARN: xHC restore state timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } -- cgit v1.2.3-59-g8ed1b From 4f7a67e2dd49fbfba002c453bc24bf00e701cc71 Mon Sep 17 00:00:00 2001 From: Ricardo Martins Date: Tue, 22 May 2012 18:02:03 +0100 Subject: USB: fix PS3 EHCI systems After commit aaa0ef289afe9186f81e2340114ea413eef0492a "PS3 EHCI QH read work-around", Terratec Grabby (em28xx) stopped working with AMD Geode LX 800 (USB controller AMD CS5536). Since this is a PS3 only fix, the following patch adds a conditional block around it. Signed-off-by: Ricardo Martins Acked-by: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b100f5f9f4b6..800be38c78b4 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -671,7 +671,9 @@ static int ehci_init(struct usb_hcd *hcd) hw = ehci->async->hw; hw->hw_next = QH_NEXT(ehci, ehci->async->qh_dma); hw->hw_info1 = cpu_to_hc32(ehci, QH_HEAD); +#if defined(CONFIG_PPC_PS3) hw->hw_info1 |= cpu_to_hc32(ehci, (1 << 7)); /* I = 1 */ +#endif hw->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT); hw->hw_qtd_next = EHCI_LIST_END(ehci); ehci->async->qh_state = QH_STATE_LINKED; -- cgit v1.2.3-59-g8ed1b From 07828b10985393cd875eac1545fba47107e97bf9 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Tue, 22 May 2012 13:47:25 -0300 Subject: USB: EHCI: Fix build warning in xilinx ehci driver This fixes the following warning: In file included from drivers/usb/host/ehci-hcd.c:1246:0: drivers/usb/host/ehci-xilinx-of.c:293:2: warning: initialization from incompatible pointer type [enabled by default] drivers/usb/host/ehci-xilinx-of.c:293:2: warning: (near initialization for 'ehci_hcd_xilinx_of_driver.shutdown') [enabled by default] Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-xilinx-of.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index 9c2cc4633894..e9713d589e30 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -270,14 +270,12 @@ static int ehci_hcd_xilinx_of_remove(struct platform_device *op) * * Properly shutdown the hcd, call driver's shutdown routine. */ -static int ehci_hcd_xilinx_of_shutdown(struct platform_device *op) +static void ehci_hcd_xilinx_of_shutdown(struct platform_device *op) { struct usb_hcd *hcd = dev_get_drvdata(&op->dev); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); - - return 0; } -- cgit v1.2.3-59-g8ed1b From 0658a3366db7e27fa32c12e886230bb58c414c92 Mon Sep 17 00:00:00 2001 From: Jan Safrata Date: Tue, 22 May 2012 14:04:50 +0200 Subject: usb: use usb_serial_put in usb_serial_probe errors The use of kfree(serial) in error cases of usb_serial_probe was invalid - usb_serial structure allocated in create_serial() gets reference of usb_device that needs to be put, so we need to use usb_serial_put() instead of simple kfree(). Signed-off-by: Jan Safrata Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 6e8c527e07c9..27483f91a4a3 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -757,7 +757,7 @@ static int usb_serial_probe(struct usb_interface *interface, if (retval) { dbg("sub driver rejected device"); - kfree(serial); + usb_serial_put(serial); module_put(type->driver.owner); return retval; } @@ -829,7 +829,7 @@ static int usb_serial_probe(struct usb_interface *interface, */ if (num_bulk_in == 0 || num_bulk_out == 0) { dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); - kfree(serial); + usb_serial_put(serial); module_put(type->driver.owner); return -ENODEV; } @@ -843,7 +843,7 @@ static int usb_serial_probe(struct usb_interface *interface, if (num_ports == 0) { dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); - kfree(serial); + usb_serial_put(serial); module_put(type->driver.owner); return -EIO; } -- cgit v1.2.3-59-g8ed1b From c4828d96900453f1ad506b1488928307711a8b28 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Mon, 11 Jun 2012 21:38:29 +0200 Subject: USB: ohci-hub: Mark ohci_finish_controller_resume() as __maybe_unused ohci_finish_controller_resume() is intended to be used in platform specific drivers ohci-*.c, included from ohci-hcd.c. Some of them don't actually use ohci_finish_controller_resume(), so mark it as __maybe_unused. Signed-off-by: Roland Stigge Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 836772dfabd3..2f3619eefefa 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -317,7 +317,7 @@ static int ohci_bus_resume (struct usb_hcd *hcd) } /* Carry out the final steps of resuming the controller device */ -static void ohci_finish_controller_resume(struct usb_hcd *hcd) +static void __maybe_unused ohci_finish_controller_resume(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int port; -- cgit v1.2.3-59-g8ed1b From 354ab8567ae3107a8cbe7228c3181990ba598aac Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Tue, 5 Jun 2012 15:34:27 +0300 Subject: Fix OMAP EHCI suspend/resume failure (i693) Its observed with some PHY, the 60Mhz clock gets cut too soon for OMAP EHCI, leaving OMAP-EHCI in a bad state. So on starting port suspend, make sure the 60Mhz clock to EHCI is kept alive using an internal clock, so that EHCi can cleanly transition its hw state machine on a port suspend. Its not proven if this is the issue hit on USB3333, but the symptoms look very similar. Signed-off-by: Anand Gadiyar Signed-off-by: Vikram Pandita Signed-off-by: Volodymyr Mieshkov Acked-by: Alan Stern Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 168 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index a44294d13494..17cfb8a1131c 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -43,6 +43,7 @@ #include #include #include +#include /* EHCI Register Set */ #define EHCI_INSNREG04 (0xA0) @@ -55,6 +56,15 @@ #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 +/* Errata i693 */ +static struct clk *utmi_p1_fck; +static struct clk *utmi_p2_fck; +static struct clk *xclk60mhsp1_ck; +static struct clk *xclk60mhsp2_ck; +static struct clk *usbhost_p1_fck; +static struct clk *usbhost_p2_fck; +static struct clk *init_60m_fclk; + /*-------------------------------------------------------------------------*/ static const struct hc_driver ehci_omap_hc_driver; @@ -70,6 +80,41 @@ static inline u32 ehci_read(void __iomem *base, u32 reg) return __raw_readl(base + reg); } +/* Erratum i693 workaround sequence */ +static void omap_ehci_erratum_i693(struct ehci_hcd *ehci) +{ + int ret = 0; + + /* Switch to the internal 60 MHz clock */ + ret = clk_set_parent(utmi_p1_fck, init_60m_fclk); + if (ret != 0) + ehci_err(ehci, "init_60m_fclk set parent" + "failed error:%d\n", ret); + + ret = clk_set_parent(utmi_p2_fck, init_60m_fclk); + if (ret != 0) + ehci_err(ehci, "init_60m_fclk set parent" + "failed error:%d\n", ret); + + clk_enable(usbhost_p1_fck); + clk_enable(usbhost_p2_fck); + + /* Wait 1ms and switch back to the external clock */ + mdelay(1); + ret = clk_set_parent(utmi_p1_fck, xclk60mhsp1_ck); + if (ret != 0) + ehci_err(ehci, "xclk60mhsp1_ck set parent" + "failed error:%d\n", ret); + + ret = clk_set_parent(utmi_p2_fck, xclk60mhsp2_ck); + if (ret != 0) + ehci_err(ehci, "xclk60mhsp2_ck set parent" + "failed error:%d\n", ret); + + clk_disable(usbhost_p1_fck); + clk_disable(usbhost_p2_fck); +} + static void omap_ehci_soft_phy_reset(struct platform_device *pdev, u8 port) { struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev); @@ -100,6 +145,50 @@ static void omap_ehci_soft_phy_reset(struct platform_device *pdev, u8 port) } } +static int omap_ehci_hub_control( + struct usb_hcd *hcd, + u16 typeReq, + u16 wValue, + u16 wIndex, + char *buf, + u16 wLength +) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + u32 __iomem *status_reg = &ehci->regs->port_status[ + (wIndex & 0xff) - 1]; + u32 temp; + unsigned long flags; + int retval = 0; + + spin_lock_irqsave(&ehci->lock, flags); + + if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { + temp = ehci_readl(ehci, status_reg); + if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { + retval = -EPIPE; + goto done; + } + + temp &= ~PORT_WKCONN_E; + temp |= PORT_WKDISC_E | PORT_WKOC_E; + ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); + + omap_ehci_erratum_i693(ehci); + + set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); + goto done; + } + + spin_unlock_irqrestore(&ehci->lock, flags); + + /* Handle the hub control events here */ + return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); +done: + spin_unlock_irqrestore(&ehci->lock, flags); + return retval; +} + static void disable_put_regulator( struct ehci_hcd_omap_platform_data *pdata) { @@ -264,8 +353,76 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) /* root ports should always stay powered */ ehci_port_power(omap_ehci, 1); + /* get clocks */ + utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); + if (IS_ERR(utmi_p1_fck)) { + ret = PTR_ERR(utmi_p1_fck); + dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); + goto err_add_hcd; + } + + xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); + if (IS_ERR(xclk60mhsp1_ck)) { + ret = PTR_ERR(xclk60mhsp1_ck); + dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); + goto err_utmi_p1_fck; + } + + utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); + if (IS_ERR(utmi_p2_fck)) { + ret = PTR_ERR(utmi_p2_fck); + dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); + goto err_xclk60mhsp1_ck; + } + + xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); + if (IS_ERR(xclk60mhsp2_ck)) { + ret = PTR_ERR(xclk60mhsp2_ck); + dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); + goto err_utmi_p2_fck; + } + + usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); + if (IS_ERR(usbhost_p1_fck)) { + ret = PTR_ERR(usbhost_p1_fck); + dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); + goto err_xclk60mhsp2_ck; + } + + usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); + if (IS_ERR(usbhost_p2_fck)) { + ret = PTR_ERR(usbhost_p2_fck); + dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); + goto err_usbhost_p1_fck; + } + + init_60m_fclk = clk_get(dev, "init_60m_fclk"); + if (IS_ERR(init_60m_fclk)) { + ret = PTR_ERR(init_60m_fclk); + dev_err(dev, "init_60m_fclk failed error:%d\n", ret); + goto err_usbhost_p2_fck; + } + return 0; +err_usbhost_p2_fck: + clk_put(usbhost_p2_fck); + +err_usbhost_p1_fck: + clk_put(usbhost_p1_fck); + +err_xclk60mhsp2_ck: + clk_put(xclk60mhsp2_ck); + +err_utmi_p2_fck: + clk_put(utmi_p2_fck); + +err_xclk60mhsp1_ck: + clk_put(xclk60mhsp1_ck); + +err_utmi_p1_fck: + clk_put(utmi_p1_fck); + err_add_hcd: disable_put_regulator(pdata); pm_runtime_put_sync(dev); @@ -294,6 +451,15 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) disable_put_regulator(dev->platform_data); iounmap(hcd->regs); usb_put_hcd(hcd); + + clk_put(utmi_p1_fck); + clk_put(utmi_p2_fck); + clk_put(xclk60mhsp1_ck); + clk_put(xclk60mhsp2_ck); + clk_put(usbhost_p1_fck); + clk_put(usbhost_p2_fck); + clk_put(init_60m_fclk); + pm_runtime_put_sync(dev); pm_runtime_disable(dev); @@ -364,7 +530,7 @@ static const struct hc_driver ehci_omap_hc_driver = { * root hub support */ .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, + .hub_control = omap_ehci_hub_control, .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, -- cgit v1.2.3-59-g8ed1b From 6c4707f3f8c44ec18282e1c014c80e1c257042f9 Mon Sep 17 00:00:00 2001 From: Otto Meta Date: Wed, 6 Jun 2012 18:46:21 +0200 Subject: usb: cdc-acm: fix devices not unthrottled on open Currently CDC-ACM devices stay throttled when their TTY is closed while throttled, stalling further communication attempts after the next open. Unthrottling during open/activate got lost starting with kernel 3.0.0 and this patch reintroduces it. Signed-off-by: Otto Meta Cc: stable Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index f2a120eea9d4..36a2a0b7b82c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -567,6 +567,14 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) usb_autopm_put_interface(acm->control); + /* + * Unthrottle device in case the TTY was closed while throttled. + */ + spin_lock_irq(&acm->read_lock); + acm->throttled = 0; + acm->throttle_req = 0; + spin_unlock_irq(&acm->read_lock); + if (acm_submit_read_urbs(acm, GFP_KERNEL)) goto error_submit_read_urbs; -- cgit v1.2.3-59-g8ed1b From 5897b038296ea84e501ba5f957e11939f8cf9be0 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Tue, 12 Jun 2012 09:34:33 +0900 Subject: usb: ehci-sh: fix illegal phy_init() running when platform_data is NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the platform_data is not set, pdata will be uninitialized value. Since the driver has the following code, if the condition is true when the pdata is uninitialized value, the driver may jump to the illegal phy_init(). if (pdata && pdata->phy_init) pdata->phy_init(); This patch also fixes the following warning: CC drivers/usb/host/ehci-hcd.o drivers/usb/host/ehci-sh.c: In function ‘ehci_hcd_sh_probe’: drivers/usb/host/ehci-sh.c:104: warning: ‘pdata’ may be used uninitialized in this function Signed-off-by: Yoshihiro Shimoda Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sh.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index ca819cdd0c5e..e7cb3925abf8 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -126,8 +126,7 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) goto fail_create_hcd; } - if (pdev->dev.platform_data != NULL) - pdata = pdev->dev.platform_data; + pdata = pdev->dev.platform_data; /* initialize hcd */ hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev, -- cgit v1.2.3-59-g8ed1b From b3a3dd074f7053ef824ad077e5331b52220ceba1 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 12 Jun 2012 20:23:52 +0200 Subject: USB: fix gathering of interface associations TEAC's UD-H01 (and probably other devices) have a gap in the interface number allocation of their descriptors: Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 220 bNumInterfaces 3 [...] Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 [...] Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 2 bInterfaceCount 2 bFunctionClass 1 Audio bFunctionSubClass 0 bFunctionProtocol 32 iFunction 4 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 [...] Once a configuration is selected, usb_set_configuration() walks the known interfaces of a given configuration and calls find_iad() on each of them to set the interface association pointer the interface is included in. The problem here is that the loop variable is taken for the interface number in the comparison logic that gathers the association. Which is fine as long as the descriptors are sane. In the case above, however, the logic gets out of sync and the interface association fields of all interfaces beyond the interface number gap are wrong. Fix this by passing the interface's bInterfaceNumber to find_iad() instead. Signed-off-by: Daniel Mack Reported-by: bEN Reported-by: Ivan Perrone Tested-by: ivan perrone Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b548cf1dbc62..bdd1c6749d88 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1838,7 +1838,6 @@ free_interfaces: intfc = cp->intf_cache[i]; intf->altsetting = intfc->altsetting; intf->num_altsetting = intfc->num_altsetting; - intf->intf_assoc = find_iad(dev, cp, i); kref_get(&intfc->ref); alt = usb_altnum_to_altsetting(intf, 0); @@ -1851,6 +1850,8 @@ free_interfaces: if (!alt) alt = &intf->altsetting[0]; + intf->intf_assoc = + find_iad(dev, cp, alt->desc.bInterfaceNumber); intf->cur_altsetting = alt; usb_enable_interface(dev, intf, true); intf->dev.parent = &dev->dev; -- cgit v1.2.3-59-g8ed1b