summaryrefslogtreecommitdiff
path: root/drivers/usb/class/cdc-acm.h
diff options
context:
space:
mode:
authorHavard Skinnemoen <hskinnemoen@google.com>2011-12-01 01:28:14 +0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-12-10 04:18:18 +0400
commit7fb57a019f94ea0c1290c39b8da753be155af41c (patch)
tree58e93fc2b2bd2e6656bbde2cc9e068a1ffe31b10 /drivers/usb/class/cdc-acm.h
parent332ceddb8c4ba2367abcb9a94a69386b2785441b (diff)
downloadlinux-7fb57a019f94ea0c1290c39b8da753be155af41c.tar.xz
USB: cdc-acm: Fix potential deadlock (lockdep warning)
Rework the locking and lifecycle management in the cdc-acm driver. Instead of using a global mutex to prevent the 'acm' object from being freed, use the tty_port kref to keep the device alive when either the USB side or TTY side is still active. This allows us to use the global mutex purely for protecting the acm_table, while use acm->mutex to guard against disconnect during TTY port activation and shutdown. The USB-side kref is taken during port initialization in probe(), and released at the end of disconnect(). The TTY-side kref is taken in install() and released in cleanup(). On disconnect, tty_vhangup() is called instead of tty_hangup() to ensure the TTY hangup processing is completed before the USB device is taken down. The TTY open and close handlers have been gutted and replaced with tty_port_open() and tty_port_close() respectively. The driver-specific code which used to be there was spread across install(), activate() and shutdown(). Reported-by: Dave Jones <davej@redhat.com> Cc: Alan Cox <alan@linux.intel.com> Cc: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/class/cdc-acm.h')
-rw-r--r--drivers/usb/class/cdc-acm.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index ca7937f26e27..35ef887b7417 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -101,6 +101,7 @@ struct acm {
int transmitting;
spinlock_t write_lock;
struct mutex mutex;
+ bool disconnected;
struct usb_cdc_line_coding line; /* bits, stop, parity */
struct work_struct work; /* work queue entry for line discipline waking up */
unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */