linux/drivers
Bjørn Mork 954c3f8a5f USB: serial: Enforce USB driver and USB serial driver match
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.

Cc: stable@vger.kernel.org # 3.0, 3.2, 3.3, 3.4
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>
2012-06-13 14:01:56 -07:00
..
accessibility
acpi x86, realmode: Unbreak the ia64 build of drivers/acpi/sleep.c 2012-05-30 10:12:48 -07:00
amba arm-soc: driver specific updates 2012-05-26 12:22:27 -07:00
ata arm-soc: clock driver changes 2012-05-26 12:42:29 -07:00
atm solos-pci: Fix DMA support 2012-05-24 16:22:53 -04:00
auxdisplay
base Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-06-01 10:34:35 -07:00
bcma Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-05-24 11:54:29 -07:00
block mtip32xx: Changes to sysfs entries 2012-05-31 08:46:50 +02:00
bluetooth Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-05-24 11:54:29 -07:00
cdrom
char Merge branch 'drm-core-next' of git://people.freedesktop.org/~airlied/linux 2012-05-24 12:42:54 -07:00
clk arm-soc: soc specific changes, part 2 2012-05-26 13:05:55 -07:00
clocksource
connector
cpufreq
cpuidle
crypto arm-soc: clock driver changes 2012-05-26 12:42:29 -07:00
dca
devfreq Power management updates for 3.5 2012-05-23 14:07:06 -07:00
dio
dma arm-soc: device tree conversions, part 2 2012-05-26 12:57:47 -07:00
edac Merge branch 'x86/trampoline' into x86/urgent 2012-05-30 12:11:32 -07:00
eisa
extcon Driver core pull for 3.5-rc1 2012-05-22 16:02:13 -07:00
firewire IEEE 1394 (FireWire) subsystem updates post v3.4: 2012-05-24 12:57:47 -07:00
firmware
gpio Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2012-05-29 18:27:19 -07:00
gpu Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux 2012-06-01 15:40:29 -07:00
hid Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2012-05-22 19:22:50 -07:00
hsi
hv Driver core pull for 3.5-rc1 2012-05-22 16:02:13 -07:00
hwmon hwmon/sch56xx: Depend on watchdog for watchdog core functions 2012-05-30 07:56:20 +02:00
hwspinlock
i2c i2c: Split I2C_M_NOSTART support out of I2C_FUNC_PROTOCOL_MANGLING 2012-05-30 10:55:34 +02:00
ide
idle
ieee802154 drivers/ieee802154: IEEE 802.15.4 loopback driver 2012-05-16 15:17:08 -04:00
iio
infiniband InfiniBand/RDMA changes for the 3.5 merge window: 2012-05-21 17:54:55 -07:00
input i2c: Split I2C_M_NOSTART support out of I2C_FUNC_PROTOCOL_MANGLING 2012-05-30 10:55:34 +02:00
iommu IOMMU Updates for Linux 3.5 2012-05-30 08:49:28 -07:00
isdn Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-05-24 11:54:29 -07:00
leds leds: add LM3533 LED driver 2012-05-29 16:22:32 -07:00
lguest
macintosh
md Improve multipath's retrying mechanism in some defined circumstances 2012-06-02 17:39:40 -07:00
media arm-soc: clock driver changes 2012-05-26 12:42:29 -07:00
memory
memstick
message Merge branch 'akpm' (Andrew's patch-bomb) 2012-05-31 18:10:18 -07:00
mfd ARM: ux500: Provide regulator support for SMSC911x via Device Tree 2012-06-01 02:04:46 +02:00
misc MFD changes for 3.5 2012-05-29 11:53:11 -07:00
mmc arm-soc: device tree conversions, part 2 2012-05-26 12:57:47 -07:00
mtd - More robust parsing especially of xattr data in JFFS2 2012-06-01 16:55:42 -07:00
net fec_mpc52xx: fix timestamp filtering 2012-06-02 17:09:08 -04:00
nfc NFC: potential integer overflow problem in check_crc() 2012-05-25 11:16:16 -04:00
nubus
of Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2012-05-29 18:27:19 -07:00
oprofile
parisc Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2012-05-22 19:22:50 -07:00
parport Driver core pull for 3.5-rc1 2012-05-22 16:02:13 -07:00
pci USB: add NO_D3_DURING_SLEEP flag and revert 151b612847 2012-06-13 13:11:39 -07:00
pcmcia
pinctrl pinctrl-nomadik: Allow Device Tree driver probing 2012-06-01 02:03:25 +02:00
platform apple-gmux: Fix up the suspend/resume patch 2012-06-01 15:18:52 -04:00
pnp
power A bunch of fixes for v3.5, nothing extraordinary. 2012-05-31 12:10:15 -07:00
pps
ps3
ptp Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2012-05-22 19:22:50 -07:00
rapidio rapidio/tsi721: add DMA engine support 2012-05-31 17:49:31 -07:00
regulator MFD changes for 3.5 2012-05-29 11:53:11 -07:00
remoteproc IOMMU Updates for Linux 3.5 2012-05-30 08:49:28 -07:00
rpmsg
rtc drivers/rtc/rtc-s3c.c: fix compiler warning 2012-05-29 16:22:34 -07:00
s390 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux 2012-05-31 10:51:10 -07:00
sbus
scsi SCSI misc on 20120531 2012-05-31 12:02:41 -07:00
sfi
sh sh: intc: Kill off special reservation interface. 2012-05-22 19:07:55 +09:00
sn
spi arm-soc: soc specific changes, part 2 2012-05-26 13:05:55 -07:00
ssb ssb: add PCI IDs 0x4322 and 43222 2012-05-16 12:46:37 -04:00
staging mm/fs: route MADV_REMOVE to FALLOC_FL_PUNCH_HOLE 2012-05-29 16:22:22 -07:00
target Merge branch 'sbp-target-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending 2012-05-23 16:52:27 -07:00
tc
thermal
tty tty: Revert the tty locking series, it needs more work 2012-06-02 15:21:43 -07:00
uio
usb USB: serial: Enforce USB driver and USB serial driver match 2012-06-13 14:01:56 -07:00
uwb
vhost Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-05-16 22:17:37 -04:00
video fbdev updates for 3.5 2012-06-01 16:57:51 -07:00
virt
virtio virtio-mmio: Devices parameter parsing 2012-05-22 12:16:15 +09:30
vlynq
vme
w1 arm-soc: clock driver changes 2012-05-26 12:42:29 -07:00
watchdog watchdog: iTCO_wdt.c: fix printk format warnings 2012-05-30 08:16:48 +02:00
xen Merge branch 'x86-trampoline-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2012-05-29 20:14:53 -07:00
zorro
Kconfig Staging tree pull request for 3.5-rc1 2012-05-22 16:34:21 -07:00
Makefile arm-soc: driver specific updates 2012-05-26 12:22:27 -07:00