mirror of
https://git.yoctoproject.org/meta-ti
synced 2026-07-16 22:38:04 +00:00
189ce92b4c
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> Signed-off-by: Denys Dmytriyenko <denys@ti.com>
163 lines
8.2 KiB
Diff
163 lines
8.2 KiB
Diff
From 445ae7e401ef25e383d9784a4602b815b2a580e1 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
|
|
Date: Wed, 30 May 2012 10:00:14 +0200
|
|
Subject: [PATCH 57/67] 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
|
|
|
|
commit 954c3f8a5f1b7716be9eee978b3bc85bae92d7c8 upstream.
|
|
|
|
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 <jhovold@gmail.com>:
|
|
|
|
[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: [<f8e38445>] 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:[<f8e38445>] 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] [<c133d2c1>] usb_unbind_interface+0x51/0x190
|
|
[11812.302456] [<c12f0344>] __device_release_driver+0x64/0xb0
|
|
[11812.302469] [<c12f0c67>] driver_detach+0x97/0xa0
|
|
[11812.302483] [<c12f001c>] bus_remove_driver+0x6c/0xe0
|
|
[11812.302500] [<c145938d>] ? __mutex_unlock_slowpath+0xcd/0x140
|
|
[11812.302514] [<c12f0ff9>] driver_unregister+0x49/0x80
|
|
[11812.302528] [<c1457df6>] ? printk+0x1d/0x1f
|
|
[11812.302540] [<c133c50d>] usb_deregister+0x5d/0xb0
|
|
[11812.302557] [<f8e37c55>] ? usb_serial_deregister+0x45/0x50 [usbserial]
|
|
[11812.302575] [<f8e37c8d>] usb_serial_deregister_drivers+0x2d/0x40 [usbserial]
|
|
[11812.302593] [<f8e3a6e2>] usb_serial_generic_deregister+0x12/0x20 [usbserial]
|
|
[11812.302611] [<f8e3acf0>] usb_serial_exit+0x8/0x32 [usbserial]
|
|
[11812.302716] [<c1080b48>] sys_delete_module+0x158/0x260
|
|
[11812.302730] [<c110594e>] ? mntput+0x1e/0x30
|
|
[11812.302746] [<c145c3c3>] ? sysenter_exit+0xf/0x18
|
|
[11812.302746] [<c107777c>] ? trace_hardirqs_on_caller+0xec/0x170
|
|
[11812.302746] [<c145c390>] 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 <ff> 92 8c 00 00 00 89 d8 e8 0e ff ff ff 8b 45 f0 c7 44 24 04 2f
|
|
[11812.302746] EIP: [<f8e38445>] 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.
|
|
|
|
Signed-off-by: Bjørn Mork <bjorn@mork.no>
|
|
Reviewed-by: Felipe Balbi <balbi@ti.com>
|
|
Tested-by: Johan Hovold <jhovold@gmail.com>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
|
---
|
|
drivers/usb/serial/usb-serial.c | 6 ++++--
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
|
|
index 38d7ebd..8bea45c 100644
|
|
--- a/drivers/usb/serial/usb-serial.c
|
|
+++ b/drivers/usb/serial/usb-serial.c
|
|
@@ -669,12 +669,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;
|
|
}
|
|
--
|
|
1.7.9.5
|
|
|