aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-acm.c
diff options
context:
space:
mode:
authorJohan Hovold <[email protected]>2013-03-19 08:21:06 +0000
committerGreg Kroah-Hartman <[email protected]>2013-03-21 22:59:01 +0000
commitcb25505fc604292c70fc02143fc102f54c8595f0 (patch)
treebc648be558cdcae4376ab51ca038653ad506b3c9 /drivers/usb/class/cdc-acm.c
parentusb: cdc-acm: fix error handling in acm_probe() (diff)
downloadkernel-cb25505fc604292c70fc02143fc102f54c8595f0.tar.gz
kernel-cb25505fc604292c70fc02143fc102f54c8595f0.zip
USB: cdc-acm: fix device unregistration
Unregister tty device in disconnect as is required by the USB stack. By deferring unregistration to when the last tty reference is dropped, the parent interface device can get unregistered before the child resulting in broken hotplug events being generated when the tty is finally closed: KERNEL[2290.798128] remove /devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:3.1 (usb) KERNEL[2290.804589] remove /devices/pci0000:00/0000:00:1d.7/usb2/2-1 (usb) KERNEL[2294.554799] remove /2-1:3.1/tty/ttyACM0 (tty) The driver must deal with tty callbacks after disconnect by checking the disconnected flag. Specifically, further opens must be prevented and this is already implemented. Cc: stable <[email protected]> Cc: Oliver Neukum <[email protected]> Acked-by: Oliver Neukum <[email protected]> Signed-off-by: Johan Hovold <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r--drivers/usb/class/cdc-acm.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index c125b61c2499..387dc6c8ad25 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -593,7 +593,6 @@ static void acm_port_destruct(struct tty_port *port)
dev_dbg(&acm->control->dev, "%s\n", __func__);
- tty_unregister_device(acm_tty_driver, acm->minor);
acm_release_minor(acm);
usb_put_intf(acm->control);
kfree(acm->country_codes);
@@ -1426,6 +1425,8 @@ static void acm_disconnect(struct usb_interface *intf)
stop_data_traffic(acm);
+ tty_unregister_device(acm_tty_driver, acm->minor);
+
usb_free_urb(acm->ctrlurb);
for (i = 0; i < ACM_NW; i++)
usb_free_urb(acm->wb[i].urb);