From cf1b18030de29e4e5b0a57695ae5db4a89da0ff7 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sun, 24 Jul 2016 13:53:30 +0200 Subject: USB: serial: option: add D-Link DWM-156/A3 The device has four interfaces; the three serial ports ought to be handled by this driver: 00 Diagnostic interface serial port 01 NMEA device serial port 02 Mass storage (sd card) 03 Modem serial port The other product ids listed in the Windows driver are present already. Signed-off-by: Lubomir Rintel Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 8e07536c233a..0338851e31a2 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1966,6 +1966,7 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */ { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */ { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, -- cgit v1.2.3 From 6977495c06f7f47636a076ee5a0ca571279d9697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Deli=C3=ABn?= Date: Thu, 28 Jul 2016 18:52:55 +0000 Subject: USB: serial: ftdi_sio: add PIDs for Ivium Technologies devices Ivium Technologies uses the FTDI VID with custom PIDs for their line of electrochemical interfaces and the PalmSens they developed for PalmSens BV. Signed-off-by: Robert Delien Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 00820809139a..8962cdcfe9ff 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -648,6 +648,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_PALMSENS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IVIUM_XSTAT_PID) }, { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index c5d6c1e73e8e..067e3a6300d1 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -405,6 +405,12 @@ #define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 #define FTDI_4N_GALAXY_DE_3_PID 0xF3C2 +/* + * Ivium Technologies product IDs + */ +#define FTDI_PALMSENS_PID 0xf440 +#define FTDI_IVIUM_XSTAT_PID 0xf441 + /* * Linx Technologies product ids */ -- cgit v1.2.3 From ae34d12cc1e212ffcd92e069030e54dae69c832f Mon Sep 17 00:00:00 2001 From: "Sheng-Hui J. Chu" Date: Thu, 28 Jul 2016 17:01:45 -0400 Subject: USB: serial: ftdi_sio: add device ID for WICED USB UART dev board BCM20706V2_EVAL is a WICED dev board designed with FT2232H USB 2.0 UART/FIFO IC. To support BCM920706V2_EVAL dev board for WICED development on Linux. Add the VID(0a5c) and PID(6422) to ftdi_sio driver to allow loading ftdi_sio for this board. Signed-off-by: Sheng-Hui J. Chu Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8962cdcfe9ff..b2d767e743fc 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1010,6 +1010,7 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) }, { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) }, { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) }, + { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 067e3a6300d1..f87a938cf005 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -678,6 +678,12 @@ #define INTREPID_VALUECAN_PID 0x0601 #define INTREPID_NEOVI_PID 0x0701 +/* + * WICED USB UART + */ +#define WICED_VID 0x0A5C +#define WICED_USB20706V2_PID 0x6422 + /* * Definitions for ID TECH (www.idt-net.com) devices */ -- cgit v1.2.3 From 01d7956b58e644ea0d2e8d9340c5727a8fc39d70 Mon Sep 17 00:00:00 2001 From: Daniele Palmas Date: Tue, 2 Aug 2016 11:29:25 +0200 Subject: USB: serial: option: add support for Telit LE920A4 This patch adds a set of compositions for Telit LE920A4. Compositions in short are: 0x1207: tty + tty 0x1208: tty + adb + tty + tty 0x1211: tty + adb + ecm 0x1212: tty + adb 0x1213: ecm + tty 0x1214: tty + adb + ecm + tty telit_le922_blacklist_usbcfg3 is reused for compositions 0x1211 and 0x1214 due to the same interfaces positions. Signed-off-by: Daniele Palmas Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 0338851e31a2..bc472584a229 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -274,6 +274,12 @@ static void option_instat_callback(struct urb *urb); #define TELIT_PRODUCT_LE920 0x1200 #define TELIT_PRODUCT_LE910 0x1201 #define TELIT_PRODUCT_LE910_USBCFG4 0x1206 +#define TELIT_PRODUCT_LE920A4_1207 0x1207 +#define TELIT_PRODUCT_LE920A4_1208 0x1208 +#define TELIT_PRODUCT_LE920A4_1211 0x1211 +#define TELIT_PRODUCT_LE920A4_1212 0x1212 +#define TELIT_PRODUCT_LE920A4_1213 0x1213 +#define TELIT_PRODUCT_LE920A4_1214 0x1214 /* ZTE PRODUCTS */ #define ZTE_VENDOR_ID 0x19d2 @@ -628,6 +634,11 @@ static const struct option_blacklist_info telit_le920_blacklist = { .reserved = BIT(1) | BIT(5), }; +static const struct option_blacklist_info telit_le920a4_blacklist_1 = { + .sendsetup = BIT(0), + .reserved = BIT(1), +}; + static const struct option_blacklist_info telit_le922_blacklist_usbcfg0 = { .sendsetup = BIT(2), .reserved = BIT(0) | BIT(1) | BIT(3), @@ -1203,6 +1214,16 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1207) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1208), + .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1211), + .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1212), + .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214), + .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, -- cgit v1.2.3 From 647024a7df36014bbc4479d92d88e6b77c0afcf6 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Mon, 8 Aug 2016 02:34:46 +0100 Subject: USB: serial: fix memleak in driver-registration error path udriver struct allocated by kzalloc() will not be freed if usb_register() and next calls fail. This patch fixes this by adding one more step with kfree(udriver) in error path. Signed-off-by: Alexey Klimov Acked-by: Alan Stern Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/usb-serial.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b1b9bac44016..d213cf44a7e4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1433,7 +1433,7 @@ int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[] rc = usb_register(udriver); if (rc) - return rc; + goto failed_usb_register; for (sd = serial_drivers; *sd; ++sd) { (*sd)->usb_driver = udriver; @@ -1451,6 +1451,8 @@ int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[] while (sd-- > serial_drivers) usb_serial_deregister(*sd); usb_deregister(udriver); +failed_usb_register: + kfree(udriver); return rc; } EXPORT_SYMBOL_GPL(usb_serial_register_drivers); -- cgit v1.2.3 From 6bb47e8ab98accb1319bd43c64966340ba3bba9a Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 4 Aug 2016 13:32:22 -0700 Subject: usb: hub: Fix unbalanced reference count/memory leak/deadlocks Memory leak and unbalanced reference count: If the hub gets disconnected while the core is still activating it, this can result in leaking memory of few USB structures. This will happen if we have done a kref_get() from hub_activate() and scheduled a delayed work item for HUB_INIT2/3. Now if hub_disconnect() gets called before the delayed work expires, then we will cancel the work from hub_quiesce(), but wouldn't do a kref_put(). And so the unbalance. kmemleak reports this as (with the commit e50293ef9775 backported to 3.10 kernel with other changes, though the same is true for mainline as well): unreferenced object 0xffffffc08af5b800 (size 1024): comm "khubd", pid 73, jiffies 4295051211 (age 6482.350s) hex dump (first 32 bytes): 30 68 f3 8c c0 ff ff ff 00 a0 b2 2e c0 ff ff ff 0h.............. 01 00 00 00 00 00 00 00 00 94 7d 40 c0 ff ff ff ..........}@.... backtrace: [] create_object+0x148/0x2a0 [] kmemleak_alloc+0x80/0xbc [] kmem_cache_alloc_trace+0x120/0x1ac [] hub_probe+0x120/0xb84 [] usb_probe_interface+0x1ec/0x298 [] driver_probe_device+0x160/0x374 [] __device_attach+0x28/0x4c [] bus_for_each_drv+0x78/0xac [] device_attach+0x6c/0x9c [] bus_probe_device+0x28/0xa0 [] device_add+0x324/0x604 [] usb_set_configuration+0x660/0x6cc [] generic_probe+0x44/0x84 [] usb_probe_device+0x54/0x74 [] driver_probe_device+0x160/0x374 [] __device_attach+0x28/0x4c Deadlocks: If the hub gets disconnected early enough (i.e. before INIT2/INIT3 are finished and the init_work is still queued), the core may call hub_quiesce() after acquiring interface device locks and it will wait for the work to be cancelled synchronously. But if the work handler is already running in parallel, it may try to acquire the same interface device lock and this may result in deadlock. Fix both the issues by removing the call to cancel_delayed_work_sync(). CC: #4.4+ Fixes: e50293ef9775 ("USB: fix invalid memory access in hub_activate()") Reported-by: Manu Gautam Signed-off-by: Viresh Kumar Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index bee13517676f..3ccffac0f647 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1315,8 +1315,6 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) struct usb_device *hdev = hub->hdev; int i; - cancel_delayed_work_sync(&hub->init_work); - /* hub_wq and related activity won't re-trigger */ hub->quiescing = 1; -- cgit v1.2.3 From ca5cbc8b02f9b21cc8cd1ab36668763ec34f9ee8 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 5 Aug 2016 11:49:45 -0400 Subject: USB: hub: fix up early-exit pathway in hub_activate The early-exit pathway in hub_activate, added by commit e50293ef9775 ("USB: fix invalid memory access in hub_activate()") needs improvement. It duplicates code that is already present at the end of the subroutine, and it neglects to undo the effect of a usb_autopm_get_interface_no_resume() call. This patch fixes both problems by making the early-exit pathway jump directly to the end of the subroutine. It simplifies the code at the end by merging two conditionals that actually test the same condition although they appear different: If type < HUB_INIT3 then type must be either HUB_INIT2 or HUB_INIT, and it can't be HUB_INIT because in that case the subroutine would have exited earlier. Signed-off-by: Alan Stern CC: #4.4+ Reviewed-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 3ccffac0f647..bb69d262b6f9 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1055,11 +1055,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) device_lock(hub->intfdev); /* Was the hub disconnected while we were waiting? */ - if (hub->disconnected) { - device_unlock(hub->intfdev); - kref_put(&hub->kref, hub_release); - return; - } + if (hub->disconnected) + goto disconnected; if (type == HUB_INIT2) goto init2; goto init3; @@ -1281,12 +1278,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Scan all ports that need attention */ kick_hub_wq(hub); - /* Allow autosuspend if it was suppressed */ - if (type <= HUB_INIT3) + if (type == HUB_INIT2 || type == HUB_INIT3) { + /* Allow autosuspend if it was suppressed */ + disconnected: usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); - - if (type == HUB_INIT2 || type == HUB_INIT3) device_unlock(hub->intfdev); + } kref_put(&hub->kref, hub_release); } -- cgit v1.2.3 From 07d316a22e119fa301fd7dba7f1e1adfd4f72c05 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 5 Aug 2016 11:51:30 -0400 Subject: USB: hub: change the locking in hub_activate The locking in hub_activate() is not adequate to provide full mutual exclusion with hub_quiesce(). The subroutine locks the hub's usb_interface, but the callers of hub_quiesce() (such as hub_pre_reset() and hub_event()) hold the lock to the hub's usb_device. This patch changes hub_activate() to make it acquire the same lock as those other routines. Signed-off-by: Alan Stern CC: #4.4+ Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index bb69d262b6f9..1d5fc32d06d0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1052,7 +1052,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Continue a partial initialization */ if (type == HUB_INIT2 || type == HUB_INIT3) { - device_lock(hub->intfdev); + device_lock(&hdev->dev); /* Was the hub disconnected while we were waiting? */ if (hub->disconnected) @@ -1259,7 +1259,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) queue_delayed_work(system_power_efficient_wq, &hub->init_work, msecs_to_jiffies(delay)); - device_unlock(hub->intfdev); + device_unlock(&hdev->dev); return; /* Continues at init3: below */ } else { msleep(delay); @@ -1282,7 +1282,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Allow autosuspend if it was suppressed */ disconnected: usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); - device_unlock(hub->intfdev); + device_unlock(&hdev->dev); } kref_put(&hub->kref, hub_release); -- cgit v1.2.3 From 28324936f3d672bbf83472fece8f36a158a52276 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 26 Jul 2016 16:01:30 +0800 Subject: usb: misc: usbtest: usbtest_do_ioctl may return positive integer For case 14 and case 21, their correct return value is the number of bytes transferred, so it is a positive integer. But in usbtest_ioctl, it takes non-zero as false return value for usbtest_do_ioctl, so it will treat the correct test as wrong test, then the time on tests will be the minus value. Signed-off-by: Peter Chen Cc: stable Fixes: 18fc4ebdc705 ("usb: misc: usbtest: Remove timeval usage") 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 6b978f04b8d7..5e3464e8d4e5 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2602,7 +2602,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) ktime_get_ts64(&start); retval = usbtest_do_ioctl(intf, param_32); - if (retval) + if (retval < 0) goto free_mutex; ktime_get_ts64(&end); -- cgit v1.2.3 From 9c6256a5e707a9eb8b91962b550050b13aa75334 Mon Sep 17 00:00:00 2001 From: Xiao Han Date: Tue, 14 Jun 2016 16:22:54 +0200 Subject: usb: misc: ftdi-elan: Fix off-by-one memory corruptions This patch fixes fives off-by-one bugs in the ftdi-elan driver code. The bug can be triggered by plugging a USB adapter for CardBus 3G cards (model U132 manufactured by Elan Digital Systems, Ltd), causing a kernel panic. The fix was tested on Ubuntu 14.04.4 with 4.7.0-rc14.2.0-27-generic+ and 4.4.0-22-generic+ kernel. In the ftdi_elan_synchronize function, an off-by-one memory corruption occurs when packet_bytes is equal or bigger than m. After having read m bytes, that is bytes_read is equal to m, " ..\x00" is still copied to the stack variable causing an out bounds write of 4 bytes, which overwrites the stack canary and results in a kernel panic. This off-by-one requires physical access to the machine. It is not exploitable since we have no control on the overwritten data. Similar off-by-one bugs have been observed in 4 other functions: ftdi_elan_stuck_waiting, ftdi_elan_read, ftdi_elan_edset_output and ftdi_elan_flush_input_fifo. Reported-by: Alex Palesandro Signed-off-by: Xiao Han Tested-by: Paul Chaignon Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ftdi-elan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 52c27cab78c3..9b5b3b2281ca 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -665,7 +665,7 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer, { char data[30 *3 + 4]; char *d = data; - int m = (sizeof(data) - 1) / 3; + int m = (sizeof(data) - 1) / 3 - 1; int bytes_read = 0; int retry_on_empty = 10; int retry_on_timeout = 5; @@ -1684,7 +1684,7 @@ wait:if (ftdi->disconnected > 0) { int i = 0; char data[30 *3 + 4]; char *d = data; - int m = (sizeof(data) - 1) / 3; + int m = (sizeof(data) - 1) / 3 - 1; int l = 0; struct u132_target *target = &ftdi->target[ed]; struct u132_command *command = &ftdi->command[ @@ -1876,7 +1876,7 @@ more:{ if (packet_bytes > 2) { char diag[30 *3 + 4]; char *d = diag; - int m = (sizeof(diag) - 1) / 3; + int m = (sizeof(diag) - 1) / 3 - 1; char *b = ftdi->bulk_in_buffer; int bytes_read = 0; diag[0] = 0; @@ -2053,7 +2053,7 @@ static int ftdi_elan_synchronize(struct usb_ftdi *ftdi) if (packet_bytes > 2) { char diag[30 *3 + 4]; char *d = diag; - int m = (sizeof(diag) - 1) / 3; + int m = (sizeof(diag) - 1) / 3 - 1; char *b = ftdi->bulk_in_buffer; int bytes_read = 0; unsigned char c = 0; @@ -2155,7 +2155,7 @@ more:{ if (packet_bytes > 2) { char diag[30 *3 + 4]; char *d = diag; - int m = (sizeof(diag) - 1) / 3; + int m = (sizeof(diag) - 1) / 3 - 1; char *b = ftdi->bulk_in_buffer; int bytes_read = 0; diag[0] = 0; -- cgit v1.2.3 From aed9d65ac3278d4febd8665bd7db59ef53e825fe Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 1 Aug 2016 15:25:56 -0400 Subject: USB: validate wMaxPacketValue entries in endpoint descriptors Erroneous or malicious endpoint descriptors may have non-zero bits in reserved positions, or out-of-bounds values. This patch helps prevent these from causing problems by bounds-checking the wMaxPacketValue entries in endpoint descriptors and capping the values at the maximum allowed. This issue was first discovered and tests were conducted by Jake Lamberson , an intern working for Rosie Hall. Signed-off-by: Alan Stern Reported-by: roswest Tested-by: roswest CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 66 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 31ccdccd7a04..051163189810 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -171,6 +171,31 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, ep, buffer, size); } +static const unsigned short low_speed_maxpacket_maxes[4] = { + [USB_ENDPOINT_XFER_CONTROL] = 8, + [USB_ENDPOINT_XFER_ISOC] = 0, + [USB_ENDPOINT_XFER_BULK] = 0, + [USB_ENDPOINT_XFER_INT] = 8, +}; +static const unsigned short full_speed_maxpacket_maxes[4] = { + [USB_ENDPOINT_XFER_CONTROL] = 64, + [USB_ENDPOINT_XFER_ISOC] = 1023, + [USB_ENDPOINT_XFER_BULK] = 64, + [USB_ENDPOINT_XFER_INT] = 64, +}; +static const unsigned short high_speed_maxpacket_maxes[4] = { + [USB_ENDPOINT_XFER_CONTROL] = 64, + [USB_ENDPOINT_XFER_ISOC] = 1024, + [USB_ENDPOINT_XFER_BULK] = 512, + [USB_ENDPOINT_XFER_INT] = 1023, +}; +static const unsigned short super_speed_maxpacket_maxes[4] = { + [USB_ENDPOINT_XFER_CONTROL] = 512, + [USB_ENDPOINT_XFER_ISOC] = 1024, + [USB_ENDPOINT_XFER_BULK] = 1024, + [USB_ENDPOINT_XFER_INT] = 1024, +}; + static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, int asnum, struct usb_host_interface *ifp, int num_ep, unsigned char *buffer, int size) @@ -179,6 +204,8 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, struct usb_endpoint_descriptor *d; struct usb_host_endpoint *endpoint; int n, i, j, retval; + unsigned int maxp; + const unsigned short *maxpacket_maxes; d = (struct usb_endpoint_descriptor *) buffer; buffer += d->bLength; @@ -286,6 +313,42 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, endpoint->desc.wMaxPacketSize = cpu_to_le16(8); } + /* Validate the wMaxPacketSize field */ + maxp = usb_endpoint_maxp(&endpoint->desc); + + /* Find the highest legal maxpacket size for this endpoint */ + i = 0; /* additional transactions per microframe */ + switch (to_usb_device(ddev)->speed) { + case USB_SPEED_LOW: + maxpacket_maxes = low_speed_maxpacket_maxes; + break; + case USB_SPEED_FULL: + maxpacket_maxes = full_speed_maxpacket_maxes; + break; + case USB_SPEED_HIGH: + /* Bits 12..11 are allowed only for HS periodic endpoints */ + if (usb_endpoint_xfer_int(d) || usb_endpoint_xfer_isoc(d)) { + i = maxp & (BIT(12) | BIT(11)); + maxp &= ~i; + } + /* fallthrough */ + default: + maxpacket_maxes = high_speed_maxpacket_maxes; + break; + case USB_SPEED_SUPER: + case USB_SPEED_SUPER_PLUS: + maxpacket_maxes = super_speed_maxpacket_maxes; + break; + } + j = maxpacket_maxes[usb_endpoint_type(&endpoint->desc)]; + + if (maxp > j) { + dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n", + cfgno, inum, asnum, d->bEndpointAddress, maxp, j); + maxp = j; + endpoint->desc.wMaxPacketSize = cpu_to_le16(i | maxp); + } + /* * Some buggy high speed devices have bulk endpoints using * maxpacket sizes other than 512. High speed HCDs may not @@ -293,9 +356,6 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, */ if (to_usb_device(ddev)->speed == USB_SPEED_HIGH && usb_endpoint_xfer_bulk(d)) { - unsigned maxp; - - maxp = usb_endpoint_maxp(&endpoint->desc) & 0x07ff; if (maxp != 512) dev_warn(ddev, "config %d interface %d altsetting %d " "bulk endpoint 0x%X has invalid maxpacket %d\n", -- cgit v1.2.3 From bc337b51508beb2d039aff5074a76cfe1c212030 Mon Sep 17 00:00:00 2001 From: Marc Ohlf Date: Wed, 3 Aug 2016 11:51:54 +0200 Subject: usb: ehci: change order of register cleanup during shutdown In ehci_turn_off_all_ports() all EHCI port registers are cleared to zero. On some hardware, this can lead to an system hang, when ehci_port_power() accesses the already cleared registers. This patch changes the order of cleanup. First call ehci_port_power() which respects the current bits in port status registers and afterwards cleanup the hard way by setting everything to zero. Signed-off-by: Marc Ohlf Acked-by: Alan Stern CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index a962b89b65a6..1e5f529d51a2 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -332,11 +332,11 @@ static void ehci_turn_off_all_ports(struct ehci_hcd *ehci) int port = HCS_N_PORTS(ehci->hcs_params); while (port--) { - ehci_writel(ehci, PORT_RWC_BITS, - &ehci->regs->port_status[port]); spin_unlock_irq(&ehci->lock); ehci_port_power(ehci, port, false); spin_lock_irq(&ehci->lock); + ehci_writel(ehci, PORT_RWC_BITS, + &ehci->regs->port_status[port]); } } -- cgit v1.2.3 From 70f7ca9a0262784d0b80727860a63d64ab228e7b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 15 Jun 2016 15:56:11 +0200 Subject: usb: devio, do not warn when allocation fails usbdev_mmap allocates a buffer. The size of the buffer is determined by a user. So with this code (no need to be root): int fd = open("/dev/bus/usb/001/001", O_RDONLY); mmap(NULL, 0x800000, PROT_READ, MAP_SHARED, fd, 0); we can see a warning: WARNING: CPU: 0 PID: 21771 at ../mm/page_alloc.c:3563 __alloc_pages_slowpath+0x1036/0x16e0() ... Call Trace: [] ? warn_slowpath_null+0x2e/0x40 [] ? __alloc_pages_slowpath+0x1036/0x16e0 [] ? warn_alloc_failed+0x250/0x250 [] ? get_page_from_freelist+0x75b/0x28b0 [] ? __alloc_pages_nodemask+0x583/0x6b0 [] ? __alloc_pages_slowpath+0x16e0/0x16e0 [] ? dma_generic_alloc_coherent+0x104/0x220 [] ? hcd_buffer_alloc+0x1d6/0x3e0 [usbcore] [] ? hcd_buffer_destroy+0xa0/0xa0 [usbcore] [] ? usb_alloc_coherent+0x65/0x90 [usbcore] [] ? usbdev_mmap+0x1a5/0x770 [usbcore] ... Allocations like this one should be marked as __GFP_NOWARN. So do so. The size could be also clipped by something like: if (size >= (1 << (MAX_ORDER + PAGE_SHIFT - 1))) return -ENOMEM; But I think the overall limit of 16M (by usbfs_increase_memory_usage) is enough, so that we only silence the warning here. Signed-off-by: Jiri Slaby Cc: Greg Kroah-Hartman Cc: Alan Stern Cc: Steinar H. Gunderson Cc: Markus Rechberger Fixes: f7d34b445a (USB: Add support for usbfs zerocopy.) Cc: 4.6+ Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e9f5043a2167..472cbcdf7456 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -241,7 +241,8 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) goto error_decrease_mem; } - mem = usb_alloc_coherent(ps->dev, size, GFP_USER, &dma_handle); + mem = usb_alloc_coherent(ps->dev, size, GFP_USER | __GFP_NOWARN, + &dma_handle); if (!mem) { ret = -ENOMEM; goto error_free_usbm; -- cgit v1.2.3 From 5cce438298a0d2a7a857a4a3c3e26aeb8f77b941 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 10 Jun 2016 14:42:55 -0400 Subject: USB: remove race condition in usbfs/libusb when using reap-after-disconnect Hans de Goede has reported a difficulty in the Linux port of libusb. When a device is removed, the poll() system call in usbfs starts returning POLLERR as soon as udev->state is set to USB_STATE_NOTATTACHED, but the outstanding URBs are not available for reaping until some time later (after usbdev_remove() has been called). This is awkward for libusb or other usbfs clients, although not an insuperable problem. At any rate, it's easy to change usbfs so that it returns POLLHUP as soon as the state becomes USB_STATE_NOTATTACHED but it doesn't return POLLERR until after the outstanding URBs have completed. That's what this patch does; it uses the fact that ps->list is always on the dev->filelist list until usbdev_remove() takes it off, which happens after all the outstanding URBs have been cancelled. Signed-off-by: Alan Stern Reported-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 472cbcdf7456..e6a6d67c8705 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -2583,7 +2583,9 @@ static unsigned int usbdev_poll(struct file *file, if (file->f_mode & FMODE_WRITE && !list_empty(&ps->async_completed)) mask |= POLLOUT | POLLWRNORM; if (!connected(ps)) - mask |= POLLERR | POLLHUP; + mask |= POLLHUP; + if (list_empty(&ps->list)) + mask |= POLLERR; return mask; } -- cgit v1.2.3 From 59b71f774fc2ec2d985251e72fde0f9f88164547 Mon Sep 17 00:00:00 2001 From: Jaewon Kim Date: Thu, 21 Jul 2016 22:20:53 +0900 Subject: usb: host: max3421-hcd: fix mask of IO control register GPIO control register is divided into IOPINS1 and IOPINS2. And low 4-bit of register is controls output. So, this patch fixes wrong mask of GPIO output. Signed-off-by: Jaewon Kim Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/max3421-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index c369c29e496d..2f7690092a7f 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -1675,7 +1675,7 @@ max3421_gpout_set_value(struct usb_hcd *hcd, u8 pin_number, u8 value) if (pin_number > 7) return; - mask = 1u << pin_number; + mask = 1u << (pin_number % 4); idx = pin_number / 4; if (value) -- cgit v1.2.3 From c7de573471832dff7d31f0c13b0f143d6f017799 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 29 Jul 2016 03:17:58 +0300 Subject: usb: dwc3: gadget: increment request->actual once When using SG lists, we would end up setting request->actual to: num_mapped_sgs * (request->length - count) Let's fix that up by incrementing request->actual only once. Cc: Reported-by: Brian E Rogers Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8f8c2157910e..863c306ebb69 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2013,14 +2013,6 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, s_pkt = 1; } - /* - * We assume here we will always receive the entire data block - * which we should receive. Meaning, if we program RX to - * receive 4K but we receive only 2K, we assume that's all we - * should receive and we simply bounce the request back to the - * gadget driver for further processing. - */ - req->request.actual += req->request.length - count; if (s_pkt) return 1; if ((event->status & DEPEVT_STATUS_LST) && @@ -2040,6 +2032,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, struct dwc3_trb *trb; unsigned int slot; unsigned int i; + int count = 0; int ret; do { @@ -2054,6 +2047,8 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, slot++; slot %= DWC3_TRB_NUM; trb = &dep->trb_pool[slot]; + count += trb->size & DWC3_TRB_SIZE_MASK; + ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, event, status); @@ -2061,6 +2056,14 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, break; } while (++i < req->request.num_mapped_sgs); + /* + * We assume here we will always receive the entire data block + * which we should receive. Meaning, if we program RX to + * receive 4K but we receive only 2K, we assume that's all we + * should receive and we simply bounce the request back to the + * gadget driver for further processing. + */ + req->request.actual += req->request.length - count; dwc3_gadget_giveback(dep, req, status); if (ret) -- cgit v1.2.3 From e5b36ae2f851024d43c76e51f395d32ce8d769ce Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 10 Aug 2016 11:13:26 +0300 Subject: usb: dwc3: gadget: fix for short pkts during chained xfers DWC3 has one interesting peculiarity with chained transfers. If we setup N chained transfers and we get a short packet before processing all N TRBs, DWC3 will (conditionally) issue a XferComplete or XferInProgress event and retire all TRBs from the one which got a short packet to the last without clearing their HWO bits. This means SW must clear HWO bit manually, which this patch is doing. Cc: Cc: Brian E Rogers Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 863c306ebb69..241f5c7b34bf 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1955,7 +1955,8 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, struct dwc3_request *req, struct dwc3_trb *trb, - const struct dwc3_event_depevt *event, int status) + const struct dwc3_event_depevt *event, int status, + int chain) { unsigned int count; unsigned int s_pkt = 0; @@ -1964,6 +1965,19 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, dep->queued_requests--; trace_dwc3_complete_trb(dep, trb); + /* + * If we're in the middle of series of chained TRBs and we + * receive a short transfer along the way, DWC3 will skip + * through all TRBs including the last TRB in the chain (the + * where CHN bit is zero. DWC3 will also avoid clearing HWO + * bit and SW has to do it manually. + * + * We're going to do that here to avoid problems of HW trying + * to use bogus TRBs for transfers. + */ + if (chain && (trb->ctrl & DWC3_TRB_CTRL_HWO)) + trb->ctrl &= ~DWC3_TRB_CTRL_HWO; + if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN) /* * We continue despite the error. There is not much we @@ -1975,6 +1989,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, */ dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", dep->name, trb); + count = trb->size & DWC3_TRB_SIZE_MASK; if (dep->direction) { @@ -2036,10 +2051,13 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, int ret; do { + int chain; + req = next_request(&dep->started_list); if (WARN_ON_ONCE(!req)) return 1; + chain = req->request.num_mapped_sgs > 0; i = 0; do { slot = req->first_trb_index + i; @@ -2049,9 +2067,8 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, trb = &dep->trb_pool[slot]; count += trb->size & DWC3_TRB_SIZE_MASK; - ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, - event, status); + event, status, chain); if (ret) break; } while (++i < req->request.num_mapped_sgs); -- cgit v1.2.3 From 7c705dfe2ebe731c8fd068623b6b4df2d3512c08 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 10 Aug 2016 12:35:30 +0300 Subject: usb: dwc3: gadget: always cleanup all TRBs If we stop earlier due to short packet, we will not be able to giveback all TRBs. Cc: Cc: Brian E Rogers Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 241f5c7b34bf..eb820e4ab49d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2028,7 +2028,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, s_pkt = 1; } - if (s_pkt) + if (s_pkt && !chain) return 1; if ((event->status & DEPEVT_STATUS_LST) && (trb->ctrl & (DWC3_TRB_CTRL_LST | -- cgit v1.2.3 From 4491ed5042f0419b22a4b08331adb54af31e2caa Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 1 Apr 2016 17:13:11 +0300 Subject: usb: dwc3: pci: add Intel Kabylake PCI ID Intel Kabylake PCH has the same DWC3 than Intel Sunrisepoint. Add the new ID to the supported devices. Cc: Signed-off-by: Heikki Krogerus Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 45f5a232d9fb..2eb84d6c24a6 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -37,6 +37,7 @@ #define PCI_DEVICE_ID_INTEL_BXT 0x0aaa #define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa #define PCI_DEVICE_ID_INTEL_APL 0x5aaa +#define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 static const struct acpi_gpio_params reset_gpios = { 0, 0, false }; static const struct acpi_gpio_params cs_gpios = { 1, 0, false }; @@ -227,6 +228,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, { } /* Terminating Entry */ }; -- cgit v1.2.3 From 772ce81264b179c0e61340998e3b29e900b2fa6d Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 8 Aug 2016 21:50:51 +0900 Subject: usb: renesas_usbhs: Fix receiving data corrupt on R-Car Gen3 with dmac Since R-Car Gen3 SoC has the USB-DMAC, this driver should set dparam->has_usb_dmac to 1. Otherwise, behavior of this driver and the usb-dmac driver will be mismatch, then sometimes receiving data will be corrupt. Fixes: de18757e272d ("usb: renesas_usbhs: add R-Car Gen3 power control") Cc: # v4.5+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 8fbbc2d32371..ac67bab9124c 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -514,7 +514,8 @@ static struct renesas_usbhs_platform_info *usbhs_parse_dt(struct device *dev) if (gpio > 0) dparam->enable_gpio = gpio; - if (dparam->type == USBHS_TYPE_RCAR_GEN2) + if (dparam->type == USBHS_TYPE_RCAR_GEN2 || + dparam->type == USBHS_TYPE_RCAR_GEN3) dparam->has_usb_dmac = 1; return info; -- cgit v1.2.3 From 9ab967e6db7412b675ecbff80d5371d53c82cb2e Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 8 Aug 2016 21:50:52 +0900 Subject: usb: renesas_usbhs: clear the BRDYSTS in usbhsg_ep_enable() This patch fixes an issue that unexpected BRDY interruption happens when the usb_ep_{enable,disable}() are called with different direction. In this case, the driver will cause the following message: renesas_usbhs e6590000.usb: irq_ready run_error 1 : -16 This issue causes the followings: 1) A pipe is enabled as transmission 2) The pipe sent a data 3) The pipe is disabled and re-enabled as reception. 4) The pipe got a queue Since the driver doesn't clear the BRDYSTS flags after 2) above, the issue happens. If we add such clearing the flags into the driver, the code will become complicate. So, this patch clears the BRDYSTS flag of reception in usbhsg_ep_enable() to avoid complicate. Cc: # v4.1+ (usbhs_xxxsts_clear() is needed) Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_gadget.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 50f3363cc382..92bc83b92d10 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -617,10 +617,13 @@ static int usbhsg_ep_enable(struct usb_ep *ep, * use dmaengine if possible. * It will use pio handler if impossible. */ - if (usb_endpoint_dir_in(desc)) + if (usb_endpoint_dir_in(desc)) { pipe->handler = &usbhs_fifo_dma_push_handler; - else + } else { pipe->handler = &usbhs_fifo_dma_pop_handler; + usbhs_xxxsts_clear(priv, BRDYSTS, + usbhs_pipe_number(pipe)); + } ret = 0; } -- cgit v1.2.3 From 700aa7ff8d2c2b9cc669c99375e2ccd06d3cd38d Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 8 Aug 2016 21:50:53 +0900 Subject: usb: renesas_usbhs: Use dmac only if the pipe type is bulk This patch fixes an issue that isochronous transfer's data is possible to be lost as a workaround. Since this driver uses a workqueue to start the dmac, the transfer is possible to be delayed when system load is high. Fixes: 6e4b74e4690d ("usb: renesas: fix scheduling in atomic context bug") Cc: # v3.4+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 280ed5ff021b..857e78337324 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -871,7 +871,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) /* use PIO if packet is less than pio_dma_border or pipe is DCP */ if ((len < usbhs_get_dparam(priv, pio_dma_border)) || - usbhs_pipe_is_dcp(pipe)) + usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC)) goto usbhsf_pio_prepare_push; /* check data length if this driver don't use USB-DMAC */ @@ -976,7 +976,7 @@ static int usbhsf_dma_prepare_pop_with_usb_dmac(struct usbhs_pkt *pkt, /* use PIO if packet is less than pio_dma_border or pipe is DCP */ if ((pkt->length < usbhs_get_dparam(priv, pio_dma_border)) || - usbhs_pipe_is_dcp(pipe)) + usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC)) goto usbhsf_pio_prepare_pop; fifo = usbhsf_get_dma_fifo(priv, pkt); -- cgit v1.2.3 From c526c62d565ea5a5bba9433f28756079734f430d Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 1 Jul 2016 15:33:28 +0800 Subject: usb: gadget: composite: fix dereference after null check coverify warning cdev->config is checked for null pointer at above code, so cdev->config might be null, fix it by adding null pointer check. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index eb648485a58c..a8ecc7a612b9 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1913,6 +1913,8 @@ unknown: break; case USB_RECIP_ENDPOINT: + if (!cdev->config) + break; endp = ((w_index & 0x80) >> 3) | (w_index & 0x0f); list_for_each_entry(f, &cdev->config->functions, list) { if (test_bit(endp, f->endpoints)) -- cgit v1.2.3 From 88c09eacf560c3303d0ee8cf91b8b7ff7f000350 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 1 Jul 2016 15:33:29 +0800 Subject: usb: gadget: u_ether: fix dereference after null check coverify warning dev->port_usb is checked for null pointer at above code, so dev->port_usb might be null, fix it by adding null pointer check. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/u_ether.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index a3f7e7c55ebb..5f562c1ec795 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -556,7 +556,8 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, /* Multi frame CDC protocols may store the frame for * later which is not a dropped frame. */ - if (dev->port_usb->supports_multi_frame) + if (dev->port_usb && + dev->port_usb->supports_multi_frame) goto multiframe; goto drop; } -- cgit v1.2.3 From cee51c33f52ebf673a088a428ac0fecc33ab77fa Mon Sep 17 00:00:00 2001 From: Winter Wang Date: Wed, 27 Jul 2016 10:03:19 +0800 Subject: usb: gadget: configfs: add mutex lock before unregister gadget There may be a race condition if f_fs calls unregister_gadget_item in ffs_closed() when unregister_gadget is called by UDC store at the same time. this leads to a kernel NULL pointer dereference: [ 310.644928] Unable to handle kernel NULL pointer dereference at virtual address 00000004 [ 310.645053] init: Service 'adbd' is being killed... [ 310.658938] pgd = c9528000 [ 310.662515] [00000004] *pgd=19451831, *pte=00000000, *ppte=00000000 [ 310.669702] Internal error: Oops: 817 [#1] PREEMPT SMP ARM [ 310.675211] Modules linked in: [ 310.678294] CPU: 0 PID: 1537 Comm: ->transport Not tainted 4.1.15-03725-g793404c #2 [ 310.685958] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) [ 310.692493] task: c8e24200 ti: c945e000 task.ti: c945e000 [ 310.697911] PC is at usb_gadget_unregister_driver+0xb4/0xd0 [ 310.703502] LR is at __mutex_lock_slowpath+0x10c/0x16c [ 310.708648] pc : [] lr : [] psr: 600f0113 [ 311.565585] [] (usb_gadget_unregister_driver) from [] (unregister_gadget_item+0x1c/0x34) [ 311.575426] [] (unregister_gadget_item) from [] (ffs_closed+0x8c/0x9c) [ 311.583702] [] (ffs_closed) from [] (ffs_data_reset+0xc/0xa0) [ 311.591194] [] (ffs_data_reset) from [] (ffs_data_closed+0x90/0xd0) [ 311.599208] [] (ffs_data_closed) from [] (ffs_ep0_release+0xc/0x14) [ 311.607224] [] (ffs_ep0_release) from [] (__fput+0x80/0x1d0) [ 311.614635] [] (__fput) from [] (task_work_run+0xb0/0xe8) [ 311.621788] [] (task_work_run) from [] (do_work_pending+0x7c/0xa4) [ 311.629718] [] (do_work_pending) from [] (work_pending+0xc/0x20) for functions using functionFS, i.e. android adbd will close /dev/usb-ffs/adb/ep0 when usb IO thread fails, but switch adb from on to off also triggers write "none" > UDC. These 2 operations both call unregister_gadget, which will lead to the panic above. add a mutex before calling unregister_gadget for api used in f_fs. Signed-off-by: Winter Wang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 70cf3477f951..f9237fe2be05 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1490,7 +1490,9 @@ void unregister_gadget_item(struct config_item *item) { struct gadget_info *gi = to_gadget_info(item); + mutex_lock(&gi->lock); unregister_gadget(gi); + mutex_unlock(&gi->lock); } EXPORT_SYMBOL_GPL(unregister_gadget_item); -- cgit v1.2.3 From ec57fcd042a9448096705847290d4e4e97fbb7e1 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 26 Jul 2016 14:48:39 +0000 Subject: usb: phy: omap-otg: Fix missing platform_set_drvdata() in omap_otg_probe() Add missing platform_set_drvdata() in omap_otg_probe(), otherwise calling platform_get_drvdata() in remove returns NULL. This is detected by Coccinelle semantic patch. Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-omap-otg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/phy/phy-omap-otg.c b/drivers/usb/phy/phy-omap-otg.c index 6f6d2a7fd5a0..6523af4f8f93 100644 --- a/drivers/usb/phy/phy-omap-otg.c +++ b/drivers/usb/phy/phy-omap-otg.c @@ -140,6 +140,8 @@ static int omap_otg_probe(struct platform_device *pdev) (rev >> 4) & 0xf, rev & 0xf, config->extcon, otg_dev->id, otg_dev->vbus); + platform_set_drvdata(pdev, otg_dev); + return 0; } -- cgit v1.2.3 From 4c4f106c032ff32b89c98a4d819e68e6e643c14e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 26 Jul 2016 14:47:00 +0000 Subject: usb: dwc3: fix missing platform_set_drvdata() in dwc3_of_simple_probe() Add missing platform_set_drvdata() in dwc3_of_simple_probe(), otherwise calling platform_get_drvdata() in remove returns NULL. This is detected by Coccinelle semantic patch. Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-of-simple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index 974335377d9f..e56d59b19a0e 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -61,6 +61,7 @@ static int dwc3_of_simple_probe(struct platform_device *pdev) if (!simple->clks) return -ENOMEM; + platform_set_drvdata(pdev, simple); simple->dev = dev; for (i = 0; i < simple->num_clocks; i++) { -- cgit v1.2.3 From 528d28138f91009f230903bd89ccd44719667831 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 26 Jul 2016 16:01:30 +0800 Subject: usb: misc: usbtest: usbtest_do_ioctl may return positive integer For case 14 and case 21, their correct return value is the number of bytes transferred, so it is a positive integer. But in usbtest_ioctl, it takes non-zero as false return value for usbtest_do_ioctl, so it will treat the correct test as wrong test, then the time on tests will be the minus value. Signed-off-by: Peter Chen Cc: stable Fixes: 18fc4ebdc705 ("usb: misc: usbtest: Remove timeval usage") Signed-off-by: Felipe Balbi --- 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 6b978f04b8d7..5e3464e8d4e5 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2602,7 +2602,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) ktime_get_ts64(&start); retval = usbtest_do_ioctl(intf, param_32); - if (retval) + if (retval < 0) goto free_mutex; ktime_get_ts64(&end); -- cgit v1.2.3 From 63196e989699ddffb4e3d30ca8c3567d408820f4 Mon Sep 17 00:00:00 2001 From: Binyamin Sharet Date: Thu, 7 Jul 2016 22:22:04 +0300 Subject: usb: gadget: fix check in sync read from ep in gadgetfs When reading synchronously from a non-zero endpoint, gadgetfs will return -EFAULT even if the read succeeds, due to a bad check of the copy_to_iter() return value. This fix compares the return value of copy_to_iter to the amount of bytes that was passed, and only fails if they are not the same. Signed-off-by: Binyamin Sharet Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index aa3707bdebb4..8560f2fe3af5 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -606,7 +606,7 @@ ep_read_iter(struct kiocb *iocb, struct iov_iter *to) } if (is_sync_kiocb(iocb)) { value = ep_io(epdata, buf, len); - if (value >= 0 && copy_to_iter(buf, value, to)) + if (value >= 0 && (copy_to_iter(buf, value, to) != value)) value = -EFAULT; } else { struct kiocb_priv *priv = kzalloc(sizeof *priv, GFP_KERNEL); -- cgit v1.2.3 From bd610c5aa9fcc9817d2629274a27aab81aa77cec Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 16 Jul 2016 09:04:40 +0200 Subject: usb: gadget: uvc: Fix return value in case of error If this memory allocation fail, we will return 0, which means success. Return -ENOMEM instead. Reviewed-by: Laurent Pinchart Signed-off-by: Christophe JAILLET Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/uvc_configfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 66753ba7a42e..31125a4a2658 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -2023,7 +2023,7 @@ static int uvcg_streaming_class_allow_link(struct config_item *src, if (!data) { kfree(*class_array); *class_array = NULL; - ret = PTR_ERR(data); + ret = -ENOMEM; goto unlock; } cl_arr = *class_array; -- cgit v1.2.3 From 3887db5c2b6531c59e9649a4293071b575d6eb3b Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 16 Jul 2016 08:34:33 +0200 Subject: usb: gadget: composite: Fix return value in case of error In 'composite_os_desc_req_prepare', if one of the memory allocations fail, 0 will be returned, which means success. We should return -ENOMEM instead. Signed-off-by: Christophe JAILLET Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index a8ecc7a612b9..5ebe6af7976e 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2126,14 +2126,14 @@ int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, cdev->os_desc_req = usb_ep_alloc_request(ep0, GFP_KERNEL); if (!cdev->os_desc_req) { - ret = PTR_ERR(cdev->os_desc_req); + ret = -ENOMEM; goto end; } /* OS feature descriptor length <= 4kB */ cdev->os_desc_req->buf = kmalloc(4096, GFP_KERNEL); if (!cdev->os_desc_req->buf) { - ret = PTR_ERR(cdev->os_desc_req->buf); + ret = -ENOMEM; kfree(cdev->os_desc_req); goto end; } -- cgit v1.2.3 From 327b21da884fe1a29f733e41792ddd53e4a30379 Mon Sep 17 00:00:00 2001 From: Mathieu Laurendeau Date: Fri, 15 Jul 2016 14:58:41 +0200 Subject: usb/gadget: fix gadgetfs aio support. Fix io submissions failing with ENODEV. Signed-off-by: Mathieu Laurendeau Fixes: 7fe3976e0f3a ("gadget: switch ep_io_operations to ->read_iter/->write_iter") Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 8560f2fe3af5..16104b5ebdcb 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -542,7 +542,7 @@ static ssize_t ep_aio(struct kiocb *iocb, */ spin_lock_irq(&epdata->dev->lock); value = -ENODEV; - if (unlikely(epdata->ep)) + if (unlikely(epdata->ep == NULL)) goto fail; req = usb_ep_alloc_request(epdata->ep, GFP_ATOMIC); -- cgit v1.2.3 From 7442e6db5bdd0dce4615205508301f9b22e502d6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Jul 2016 13:14:33 +0300 Subject: usb: gadget: fsl_qe_udc: off by one in setup_received_handle() The udc->eps[] array has USB_MAX_ENDPOINTS elements so > should be >=. Fixes: 3948f0e0c999 ('usb: add Freescale QE/CPM USB peripheral controller driver') Acked-by: Peter Chen Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/fsl_qe_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 93d28cb00b76..cf8819a5c5b2 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -2053,7 +2053,7 @@ static void setup_received_handle(struct qe_udc *udc, struct qe_ep *ep; if (wValue != 0 || wLength != 0 - || pipe > USB_MAX_ENDPOINTS) + || pipe >= USB_MAX_ENDPOINTS) break; ep = &udc->eps[pipe]; -- cgit v1.2.3 From 17a1dc5e22d25ba374d8c8dd8d5bf10bd20d3265 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 11 Jul 2016 09:58:16 +0800 Subject: usb: udc: core: fix error handling The udc device needs to be deleted if error occurs Fixes: 855ed04a3758 ("usb: gadget: udc-core: independent registration of gadgets and gadget drivers") Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index ff8685ea7219..934f83881c30 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1145,7 +1145,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, if (ret != -EPROBE_DEFER) list_del(&driver->pending); if (ret) - goto err4; + goto err5; break; } } @@ -1154,6 +1154,9 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, return 0; +err5: + device_del(&udc->dev); + err4: list_del(&udc->list); mutex_unlock(&udc_lock); -- cgit v1.2.3 From 207707d8fd48ebc977fb2b2794004a020e1ee08e Mon Sep 17 00:00:00 2001 From: Xerox Lin Date: Wed, 29 Jun 2016 14:34:21 +0530 Subject: usb: gadget: rndis: free response queue during REMOTE_NDIS_RESET_MSG When rndis data transfer is in progress, some Windows7 Host PC is not sending the GET_ENCAPSULATED_RESPONSE command for receiving the response for the previous SEND_ENCAPSULATED_COMMAND processed. The rndis function driver appends each response for the SEND_ENCAPSULATED_COMMAND in a queue. As the above process got corrupted, the Host sends a REMOTE_NDIS_RESET_MSG command to do a soft-reset. As the rndis response queue is not freed, the previous response is sent as a part of this REMOTE_NDIS_RESET_MSG's reset response and the Host block any more Rndis transfers. Hence free the rndis response queue as a part of this soft-reset so that the correct response for REMOTE_NDIS_RESET_MSG is sent properly during the response command. Signed-off-by: Rajkumar Raghupathy Signed-off-by: Xerox Lin [AmitP: Cherry-picked this patch and folded other relevant fixes from Android common kernel android-4.4] Signed-off-by: Amit Pundir Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/rndis.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index 943c21aafd3b..ab6ac1b74ac0 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -680,6 +680,12 @@ static int rndis_reset_response(struct rndis_params *params, { rndis_reset_cmplt_type *resp; rndis_resp_t *r; + u8 *xbuf; + u32 length; + + /* drain the response queue */ + while ((xbuf = rndis_get_next_response(params, &length))) + rndis_free_response(params, xbuf); r = rndis_add_response(params, sizeof(rndis_reset_cmplt_type)); if (!r) -- cgit v1.2.3 From 79d17482a4091056e128a5048e253f2ed53440cc Mon Sep 17 00:00:00 2001 From: Janusz Dziedzic Date: Thu, 7 Jul 2016 08:39:09 +0200 Subject: usb: dwc3: don't set last bit for ISOC endpoints According to Synopsys Databook 2.60a, section 8.3.4, it's stated that: The LST bit should be set to 0 (isochronous transfers normally continue until the endpoint is removed entirely, at which time an End Transfer command is used to stop the transfer). This patch makes sure that detail is observed and fixes a regression with Android Audio playback caused by recent changes to DWC3 gadget. Signed-off-by: Janusz Dziedzic Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index eb820e4ab49d..7a4d4d2534d4 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -829,7 +829,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, if (!req->request.no_interrupt && !chain) trb->ctrl |= DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI; - if (last) + if (last && !usb_endpoint_xfer_isoc(dep->endpoint.desc)) trb->ctrl |= DWC3_TRB_CTRL_LST; if (chain) -- cgit v1.2.3 From a0ad85ae866f8a01f29a18ffa1e9b1aa8ca888bd Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 10 Aug 2016 18:07:46 +0300 Subject: usb: dwc3: gadget: stop processing on HWO set stop consuming TRBs when we reach one with HWO bit already set. This will prevent us from prematurely retiring a TRB. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 7a4d4d2534d4..1f5597ef945d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1979,16 +1979,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, trb->ctrl &= ~DWC3_TRB_CTRL_HWO; if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN) - /* - * We continue despite the error. There is not much we - * can do. If we don't clean it up we loop forever. If - * we skip the TRB then it gets overwritten after a - * while since we use them in a ring buffer. A BUG() - * would help. Lets hope that if this occurs, someone - * fixes the root cause instead of looking away :) - */ - dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", - dep->name, trb); + return 1; count = trb->size & DWC3_TRB_SIZE_MASK; -- cgit v1.2.3 From 539587511835ea12d8daa444cbed766cf2bc3612 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Thu, 11 Aug 2016 10:31:14 +0800 Subject: usb: misc: usbtest: add fix for driver hang In sg_timeout(), req->status is set to "-ETIMEDOUT" before calling into usb_sg_cancel(). usb_sg_cancel() will do nothing and return directly if req->status has been set to a non-zero value. This will cause driver hang whenever transfer time out is triggered. This patch fixes this issue. It could be backported to stable kernel with version later than v3.15. Cc: stable@vger.kernel.org # 3.15+ Cc: Alan Stern Signed-off-by: Lu Baolu Suggested-by: Alan Stern Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 5e3464e8d4e5..5c8210dc6fd9 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -585,7 +585,6 @@ static void sg_timeout(unsigned long _req) { struct usb_sg_request *req = (struct usb_sg_request *) _req; - req->status = -ETIMEDOUT; usb_sg_cancel(req); } @@ -616,8 +615,10 @@ static int perform_sglist( mod_timer(&sg_timer, jiffies + msecs_to_jiffies(SIMPLE_IO_TIMEOUT)); usb_sg_wait(req); - del_timer_sync(&sg_timer); - retval = req->status; + if (!del_timer_sync(&sg_timer)) + retval = -ETIMEDOUT; + else + retval = req->status; /* FIXME check resulting data pattern */ -- cgit v1.2.3 From add125054b8727103631dce116361668436ef6a7 Mon Sep 17 00:00:00 2001 From: Gavin Li Date: Fri, 12 Aug 2016 00:52:56 -0700 Subject: cdc-acm: fix wrong pipe type on rx interrupt xfers This fixes the "BOGUS urb xfer" warning logged by usb_submit_urb(). Signed-off-by: Gavin Li Acked-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 5 ++--- drivers/usb/class/cdc-acm.h | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 71912301ef7f..0f3f62e81e5b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1354,7 +1354,6 @@ made_compressed_probe: spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); mutex_init(&acm->mutex); - acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); acm->is_int_ep = usb_endpoint_xfer_int(epread); if (acm->is_int_ep) acm->bInterval = epread->bInterval; @@ -1394,14 +1393,14 @@ made_compressed_probe: urb->transfer_dma = rb->dma; if (acm->is_int_ep) { usb_fill_int_urb(urb, acm->dev, - acm->rx_endpoint, + usb_rcvintpipe(usb_dev, epread->bEndpointAddress), rb->base, acm->readsize, acm_read_bulk_callback, rb, acm->bInterval); } else { usb_fill_bulk_urb(urb, acm->dev, - acm->rx_endpoint, + usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress), rb->base, acm->readsize, acm_read_bulk_callback, rb); diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 05ce308d5d2a..1f1eabfd8462 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -96,7 +96,6 @@ struct acm { struct acm_rb read_buffers[ACM_NR]; struct acm_wb *putbuffer; /* for acm_tty_put_char() */ int rx_buflimit; - int rx_endpoint; spinlock_t read_lock; int write_used; /* number of non-empty write buffers */ int transmitting; -- cgit v1.2.3 From 33be126510974e2eb9679f1ca9bca4f67ee4c4c7 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 16 Aug 2016 10:18:03 +0300 Subject: xhci: always handle "Command Ring Stopped" events Fix "Command completion event does not match command" errors by always handling the command ring stopped events. The command ring stopped event is generated as a result of aborting or stopping the command ring with a register write. It is not caused by a command in the command queue, and thus won't have a matching command in the comman list. Solve it by handling the command ring stopped event before checking for a matching command. In most command time out cases we abort the command ring, and get a command ring stopped event. The events command pointer will point at the current command ring dequeue, which in most cases matches the timed out command in the command list, and no error messages are seen. If we instead get a command aborted event before the command ring stopped event, the abort event will increse the command ring dequeue pointer, and the following command ring stopped events command pointer will point at the next, not yet queued command. This case triggered the error message Signed-off-by: Mathias Nyman CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 918e0c739b79..fe5b70be61ba 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1334,12 +1334,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list); - if (cmd->command_trb != xhci->cmd_ring->dequeue) { - xhci_err(xhci, - "Command completion event does not match command\n"); - return; - } - del_timer(&xhci->cmd_timer); trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event); @@ -1351,6 +1345,13 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, xhci_handle_stopped_cmd_ring(xhci, cmd); return; } + + if (cmd->command_trb != xhci->cmd_ring->dequeue) { + xhci_err(xhci, + "Command completion event does not match command\n"); + return; + } + /* * Host aborted the command ring, check if the current command was * supposed to be aborted, otherwise continue normally. -- cgit v1.2.3 From 0d2daaded82565f807a4435d678343f437b8b848 Mon Sep 17 00:00:00 2001 From: Alban Browaeys Date: Tue, 16 Aug 2016 10:18:04 +0300 Subject: xhci: really enqueue zero length TRBs. Enqueue the first TRB even if full_len is zero. Without this "adb install " freezes the system. Signed-off-by: Alban Browaeys Fixes: 86065c2719a5 ("xhci: don't rely on precalculated value of needed trbs in the enqueue loop") Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index fe5b70be61ba..fd9fd12e4861 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3244,7 +3244,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, send_addr = addr; /* Queue the TRBs, even if they are zero-length */ - for (enqd_len = 0; enqd_len < full_len; enqd_len += trb_buff_len) { + for (enqd_len = 0; first_trb || enqd_len < full_len; + enqd_len += trb_buff_len) { field = TRB_TYPE(TRB_NORMAL); /* TRB buffer should not cross 64KB boundaries */ -- cgit v1.2.3 From 88716a93766b8f095cdef37a8e8f2c93aa233b21 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Tue, 16 Aug 2016 10:18:05 +0300 Subject: usb: xhci: Fix panic if disconnect After a device is disconnected, xhci_stop_device() will be invoked in xhci_bus_suspend(). Also the "disconnect" IRQ will have ISR to invoke xhci_free_virt_device() in this sequence. xhci_irq -> xhci_handle_event -> handle_cmd_completion -> xhci_handle_cmd_disable_slot -> xhci_free_virt_device If xhci->devs[slot_id] has been assigned to NULL in xhci_free_virt_device(), then virt_dev->eps[i].ring in xhci_stop_device() may point to an invlid address to cause kernel panic. virt_dev = xhci->devs[slot_id]; : if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) [] Unable to handle kernel paging request at virtual address 00001a68 [] pgd=ffffffc001430000 [] [00001a68] *pgd=000000013c807003, *pud=000000013c807003, *pmd=000000013c808003, *pte=0000000000000000 [] Internal error: Oops: 96000006 [#1] PREEMPT SMP [] CPU: 0 PID: 39 Comm: kworker/0:1 Tainted: G U [] Workqueue: pm pm_runtime_work [] task: ffffffc0bc0e0bc0 ti: ffffffc0bc0ec000 task.ti: ffffffc0bc0ec000 [] PC is at xhci_stop_device.constprop.11+0xb4/0x1a4 This issue is found when running with realtek ethernet device (0bda:8153). Signed-off-by: Jim Lin Cc: Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index d61fcc48099e..730b9fd26685 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -386,6 +386,9 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) ret = 0; virt_dev = xhci->devs[slot_id]; + if (!virt_dev) + return -ENODEV; + cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); if (!cmd) { xhci_dbg(xhci, "Couldn't allocate command structure.\n"); -- cgit v1.2.3 From f1f6d9a8b540df22b87a5bf6bc104edaade81f47 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 16 Aug 2016 10:18:06 +0300 Subject: xhci: don't dereference a xhci member after removing xhci Remove the hcd after checking for the xhci last quirks, not before. This caused a hang on a Alpine Ridge xhci based maching which remove the whole xhci controller when unplugging the last usb device CC: Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 4fd041bec332..d7b0f97abbad 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -314,11 +314,12 @@ static void xhci_pci_remove(struct pci_dev *dev) usb_remove_hcd(xhci->shared_hcd); usb_put_hcd(xhci->shared_hcd); } - usb_hcd_pci_remove(dev); /* Workaround for spurious wakeups at shutdown with HSW */ if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) pci_set_power_state(dev, PCI_D3hot); + + usb_hcd_pci_remove(dev); } #ifdef CONFIG_PM -- cgit v1.2.3