diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2009-10-27 10:54:41 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-10-27 10:54:41 -0700 |
| commit | 607008879414ffa8d5f424a3646cca2644119c3b (patch) | |
| tree | 32c49c67c62c88b9559f644f418b1c585122f2d7 /tty | |
| parent | d93ada0e086cc8b5de957b5dfaeb1247489f1717 (diff) | |
| download | patches-607008879414ffa8d5f424a3646cca2644119c3b.tar.gz | |
more patches
Diffstat (limited to 'tty')
| -rw-r--r-- | tty/opticon-fix-resume-logic.patch | 32 | ||||
| -rw-r--r-- | tty/serial-8250-calculate-irqflags-bitmask-before-loop.patch | 72 | ||||
| -rw-r--r-- | tty/serial-cascade-needless-conditionals.patch | 55 | ||||
| -rw-r--r-- | tty/serial-fix-null-pointer-dereference.patch | 71 | ||||
| -rw-r--r-- | tty/tty_port-add-tty_port_open-helper.patch | 174 | ||||
| -rw-r--r-- | tty/tty_port-coding-style-cleaning-pass.patch | 98 | ||||
| -rw-r--r-- | tty/usb_serial-kill-port-mutex.patch | 68 | ||||
| -rw-r--r-- | tty/usb_serial-use-the-shutdown-operation.patch | 124 |
8 files changed, 694 insertions, 0 deletions
diff --git a/tty/opticon-fix-resume-logic.patch b/tty/opticon-fix-resume-logic.patch new file mode 100644 index 00000000000000..3335b23dd16710 --- /dev/null +++ b/tty/opticon-fix-resume-logic.patch @@ -0,0 +1,32 @@ +From alan@linux.intel.com Tue Oct 27 10:08:01 2009 +From: Alan Cox <alan@linux.intel.com> +Date: Tue, 06 Oct 2009 16:06:57 +0100 +Subject: [PATCH 5/5] opticon: Fix resume logic +To: greg@kroah.com, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org +Message-ID: <20091006150651.9431.16939.stgit@localhost.localdomain> + + +Opticon now takes the right mutex to check the port status but the status +check is done wrongly for the modern serial code, so fix it. + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Cc: Alan Stern <stern@rowland.harvard.edu> +Cc: Oliver Neukum <oliver@neukum.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/opticon.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/opticon.c ++++ b/drivers/usb/serial/opticon.c +@@ -502,7 +502,8 @@ static int opticon_resume(struct usb_int + int result; + + mutex_lock(&port->port.mutex); +- if (port->port.count) ++ /* This is protected by the port mutex against close/open */ ++ if (test_bit(ASYNCB_INITIALIZED, &port->port.flags)) + result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO); + else + result = 0; diff --git a/tty/serial-8250-calculate-irqflags-bitmask-before-loop.patch b/tty/serial-8250-calculate-irqflags-bitmask-before-loop.patch new file mode 100644 index 00000000000000..e67d804738ce1d --- /dev/null +++ b/tty/serial-8250-calculate-irqflags-bitmask-before-loop.patch @@ -0,0 +1,72 @@ +From andre.goddard@gmail.com Tue Oct 27 10:44:02 2009 +From: Andr� Goddard Rosa <andre.goddard@gmail.com> +Date: Sun, 25 Oct 2009 12:01:34 -0200 +Subject: serial, 8250: calculate irqflags bitmask before loop +To: alan@linux.intel.com, Andrew Morton <akpm@linux-foundation.org>, ddaney@caviumnetworks.com, tpaoletti@caviumnetworks.com, gregkh@suse.de +Cc: me <andre.goddard@gmail.com> +Message-ID: <b8bf37780910250701r58d25082y12ea482f6c1b2ea4@mail.gmail.com> + + +Signed-off-by: Andr� Goddard Rosa <andre.goddard@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/serial/8250.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/drivers/serial/8250.c ++++ b/drivers/serial/8250.c +@@ -2646,7 +2646,7 @@ static void __init serial8250_isa_init_p + { + struct uart_8250_port *up; + static int first = 1; +- int i; ++ int i, irqflag = 0; + + if (!first) + return; +@@ -2670,6 +2670,9 @@ static void __init serial8250_isa_init_p + up->port.ops = &serial8250_pops; + } + ++ if (share_irqs) ++ irqflag = IRQF_SHARED; ++ + for (i = 0, up = serial8250_ports; + i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; + i++, up++) { +@@ -2683,8 +2686,7 @@ static void __init serial8250_isa_init_p + up->port.iotype = old_serial_port[i].io_type; + up->port.regshift = old_serial_port[i].iomem_reg_shift; + set_io_from_upio(&up->port); +- if (share_irqs) +- up->port.irqflags |= IRQF_SHARED; ++ up->port.irqflags |= irqflag; + } + } + +@@ -2940,10 +2942,13 @@ static int __devinit serial8250_probe(st + { + struct plat_serial8250_port *p = dev->dev.platform_data; + struct uart_port port; +- int ret, i; ++ int ret, i, irqflag = 0; + + memset(&port, 0, sizeof(struct uart_port)); + ++ if (share_irqs) ++ irqflag = IRQF_SHARED; ++ + for (i = 0; p && p->flags != 0; p++, i++) { + port.iobase = p->iobase; + port.membase = p->membase; +@@ -2960,8 +2965,7 @@ static int __devinit serial8250_probe(st + port.serial_in = p->serial_in; + port.serial_out = p->serial_out; + port.dev = &dev->dev; +- if (share_irqs) +- port.irqflags |= IRQF_SHARED; ++ port.irqflags |= irqflag; + ret = serial8250_register_port(&port); + if (ret < 0) { + dev_err(&dev->dev, "unable to register port at index %d " diff --git a/tty/serial-cascade-needless-conditionals.patch b/tty/serial-cascade-needless-conditionals.patch new file mode 100644 index 00000000000000..a3ac4ac1c8db32 --- /dev/null +++ b/tty/serial-cascade-needless-conditionals.patch @@ -0,0 +1,55 @@ +From andre.goddard@gmail.com Tue Oct 27 10:42:56 2009 +From: Andr� Goddard Rosa <andre.goddard@gmail.com> +Date: Sun, 25 Oct 2009 11:18:26 -0200 +Subject: serial: cascade needless conditionals +To: gregkh@suse.de, alan@linux.intel.com, Andrew Morton <akpm@linux-foundation.org>, adobriyan@gmail.com +Cc: me <andre.goddard@gmail.com> +Message-ID: <b8bf37780910250618h3edce547y41a8dd03e4fb4e71@mail.gmail.com> + + +Signed-off-by: Andr� Goddard Rosa <andre.goddard@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/serial/serial_core.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/drivers/serial/serial_core.c ++++ b/drivers/serial/serial_core.c +@@ -342,11 +342,11 @@ uart_get_baud_rate(struct uart_port *por + + if (flags == UPF_SPD_HI) + altbaud = 57600; +- if (flags == UPF_SPD_VHI) ++ else if (flags == UPF_SPD_VHI) + altbaud = 115200; +- if (flags == UPF_SPD_SHI) ++ else if (flags == UPF_SPD_SHI) + altbaud = 230400; +- if (flags == UPF_SPD_WARP) ++ else if (flags == UPF_SPD_WARP) + altbaud = 460800; + + for (try = 0; try < 2; try++) { +@@ -1217,9 +1217,8 @@ static void uart_set_termios(struct tty_ + /* Handle transition to B0 status */ + if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) + uart_clear_mctrl(state->uart_port, TIOCM_RTS | TIOCM_DTR); +- + /* Handle transition away from B0 status */ +- if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { ++ else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { + unsigned int mask = TIOCM_DTR; + if (!(cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) +@@ -1234,9 +1233,8 @@ static void uart_set_termios(struct tty_ + __uart_start(tty); + spin_unlock_irqrestore(&state->uart_port->lock, flags); + } +- + /* Handle turning on CRTSCTS */ +- if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { ++ else if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { + spin_lock_irqsave(&state->uart_port->lock, flags); + if (!(state->uart_port->ops->get_mctrl(state->uart_port) & TIOCM_CTS)) { + tty->hw_stopped = 1; diff --git a/tty/serial-fix-null-pointer-dereference.patch b/tty/serial-fix-null-pointer-dereference.patch new file mode 100644 index 00000000000000..772ff351c318bc --- /dev/null +++ b/tty/serial-fix-null-pointer-dereference.patch @@ -0,0 +1,71 @@ +From andre.goddard@gmail.com Tue Oct 27 10:42:06 2009 +From: Andr� Goddard Rosa <andre.goddard@gmail.com> +Date: Sun, 25 Oct 2009 11:16:32 -0200 +Subject: serial: fix NULL pointer dereference +To: gregkh@suse.de, alan@linux.intel.com, Andrew Morton <akpm@linux-foundation.org>, adobriyan@gmail.com +Cc: me <andre.goddard@gmail.com> +Message-ID: <b8bf37780910250616g8f204d2h471bd4d511a4816@mail.gmail.com> + +From: Andr� Goddard Rosa <andre.goddard@gmail.com> + +If kzalloc() or alloc_tty_driver() fails, we call: + put_tty_driver(normal = NULL). + +Then: + put_tty_driver -> tty_driver_kref_put -> kref_put(&NULL->kref, ...) + +Signed-off-by: Andr� Goddard Rosa <andre.goddard@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/serial/serial_core.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +--- a/drivers/serial/serial_core.c ++++ b/drivers/serial/serial_core.c +@@ -2344,7 +2344,7 @@ static const struct tty_operations uart_ + */ + int uart_register_driver(struct uart_driver *drv) + { +- struct tty_driver *normal = NULL; ++ struct tty_driver *normal; + int i, retval; + + BUG_ON(drv->state); +@@ -2354,13 +2354,12 @@ int uart_register_driver(struct uart_dri + * we have a large number of ports to handle. + */ + drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); +- retval = -ENOMEM; + if (!drv->state) + goto out; + +- normal = alloc_tty_driver(drv->nr); ++ normal = alloc_tty_driver(drv->nr); + if (!normal) +- goto out; ++ goto out_kfree; + + drv->tty_driver = normal; + +@@ -2393,12 +2392,14 @@ int uart_register_driver(struct uart_dri + } + + retval = tty_register_driver(normal); +- out: +- if (retval < 0) { +- put_tty_driver(normal); +- kfree(drv->state); +- } +- return retval; ++ if (retval >= 0) ++ return retval; ++ ++ put_tty_driver(normal); ++out_kfree: ++ kfree(drv->state); ++out: ++ return -ENOMEM; + } + + /** diff --git a/tty/tty_port-add-tty_port_open-helper.patch b/tty/tty_port-add-tty_port_open-helper.patch new file mode 100644 index 00000000000000..968fa62f0458f4 --- /dev/null +++ b/tty/tty_port-add-tty_port_open-helper.patch @@ -0,0 +1,174 @@ +From alan@linux.intel.com Tue Oct 27 10:03:02 2009 +From: Alan Cox <alan@linux.intel.com> +Date: Tue, 06 Oct 2009 16:06:11 +0100 +Subject: tty_port: add "tty_port_open" helper +To: greg@kroah.com, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org +Message-ID: <20091006150555.9431.34664.stgit@localhost.localdomain> + + +For the moment this just moves the USB logic over and fixes the 'what if +we open and hangup at the same time' race noticed by Oliver Neukum. + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Cc: Alan Stern <stern@rowland.harvard.edu> +Cc: Oliver Neukum <oliver@neukum.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/char/tty_port.c | 36 ++++++++++++++++++++++++++++- + drivers/usb/serial/usb-serial.c | 49 ++++++++++++++++------------------------ + include/linux/tty.h | 10 +++++++- + 3 files changed, 64 insertions(+), 31 deletions(-) + +--- a/drivers/char/tty_port.c ++++ b/drivers/char/tty_port.c +@@ -99,10 +99,11 @@ EXPORT_SYMBOL(tty_port_tty_set); + + static void tty_port_shutdown(struct tty_port *port) + { ++ mutex_lock(&port->mutex); + if (port->ops->shutdown && + test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) + port->ops->shutdown(port); +- ++ mutex_unlock(&port->mutex); + } + + /** +@@ -375,3 +376,36 @@ void tty_port_close(struct tty_port *por + tty_port_tty_set(port, NULL); + } + EXPORT_SYMBOL(tty_port_close); ++ ++int tty_port_open(struct tty_port *port, struct tty_struct *tty, ++ struct file *filp) ++{ ++ spin_lock_irq(&port->lock); ++ if (!tty_hung_up_p(filp)) ++ ++port->count; ++ spin_unlock_irq(&port->lock); ++ tty_port_tty_set(port, tty); ++ ++ /* ++ * Do the device-specific open only if the hardware isn't ++ * already initialized. Serialize open and shutdown using the ++ * port mutex. ++ */ ++ ++ mutex_lock(&port->mutex); ++ ++ if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) { ++ if (port->ops->activate) { ++ int retval = port->ops->activate(port, tty); ++ if (retval) { ++ mutex_unlock(&port->mutex); ++ return retval; ++ } ++ } ++ set_bit(ASYNCB_INITIALIZED, &port->flags); ++ } ++ mutex_unlock(&port->mutex); ++ return tty_port_block_til_ready(port, tty, filp); ++} ++ ++EXPORT_SYMBOL(tty_port_open); +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -247,41 +247,31 @@ static int serial_install(struct tty_dri + return retval; + } + +-static int serial_open(struct tty_struct *tty, struct file *filp) ++static int serial_activate(struct tty_port *tport, struct tty_struct *tty) + { +- struct usb_serial_port *port = tty->driver_data; ++ struct usb_serial_port *port = ++ container_of(tport, struct usb_serial_port, port); + struct usb_serial *serial = port->serial; + int retval; + +- dbg("%s - port %d", __func__, port->number); +- +- spin_lock_irq(&port->port.lock); +- if (!tty_hung_up_p(filp)) +- ++port->port.count; +- spin_unlock_irq(&port->port.lock); +- tty_port_tty_set(&port->port, tty); ++ if (mutex_lock_interruptible(&port->mutex)) ++ return -ERESTARTSYS; ++ mutex_lock(&serial->disc_mutex); ++ if (serial->disconnected) ++ retval = -ENODEV; ++ else ++ retval = port->serial->type->open(tty, port); ++ mutex_unlock(&serial->disc_mutex); ++ mutex_unlock(&port->mutex); ++ return retval; ++} + +- /* Do the device-specific open only if the hardware isn't +- * already initialized. +- */ +- if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) { +- if (mutex_lock_interruptible(&port->mutex)) +- return -ERESTARTSYS; +- mutex_lock(&serial->disc_mutex); +- if (serial->disconnected) +- retval = -ENODEV; +- else +- retval = port->serial->type->open(tty, port); +- mutex_unlock(&serial->disc_mutex); +- mutex_unlock(&port->mutex); +- if (retval) +- return retval; +- set_bit(ASYNCB_INITIALIZED, &port->port.flags); +- } ++static int serial_open(struct tty_struct *tty, struct file *filp) ++{ ++ struct usb_serial_port *port = tty->driver_data; + +- /* Now do the correct tty layer semantics */ +- retval = tty_port_block_til_ready(&port->port, tty, filp); +- return retval; ++ dbg("%s - port %d", __func__, port->number); ++ return tty_port_open(&port->port, tty, filp); + } + + /** +@@ -725,6 +715,7 @@ static void serial_dtr_rts(struct tty_po + static const struct tty_port_operations serial_port_ops = { + .carrier_raised = serial_carrier_raised, + .dtr_rts = serial_dtr_rts, ++ .activate = serial_activate, + }; + + int usb_serial_probe(struct usb_interface *interface, +--- a/include/linux/tty.h ++++ b/include/linux/tty.h +@@ -190,9 +190,15 @@ struct tty_port_operations { + /* Control the DTR line */ + void (*dtr_rts)(struct tty_port *port, int raise); + /* Called when the last close completes or a hangup finishes +- IFF the port was initialized. Do not use to free resources */ ++ IFF the port was initialized. Do not use to free resources. Called ++ under the port mutex to serialize against activate/shutdowns */ + void (*shutdown)(struct tty_port *port); + void (*drop)(struct tty_port *port); ++ /* Called under the port mutex from tty_port_open, serialized using ++ the port mutex */ ++ /* FIXME: long term getting the tty argument *out* of this would be ++ good for consoles */ ++ int (*activate)(struct tty_port *port, struct tty_struct *tty); + }; + + struct tty_port { +@@ -467,6 +473,8 @@ extern int tty_port_close_start(struct t + extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty); + extern void tty_port_close(struct tty_port *port, + struct tty_struct *tty, struct file *filp); ++extern int tty_port_open(struct tty_port *port, ++ struct tty_struct *tty, struct file *filp); + extern inline int tty_port_users(struct tty_port *port) + { + return port->count + port->blocked_open; diff --git a/tty/tty_port-coding-style-cleaning-pass.patch b/tty/tty_port-coding-style-cleaning-pass.patch new file mode 100644 index 00000000000000..8c322f6308d063 --- /dev/null +++ b/tty/tty_port-coding-style-cleaning-pass.patch @@ -0,0 +1,98 @@ +From alan@linux.intel.com Tue Oct 27 10:03:21 2009 +From: Alan Cox <alan@linux.intel.com> +Date: Tue, 06 Oct 2009 16:06:21 +0100 +Subject: tty_port: coding style cleaning pass +To: greg@kroah.com, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org +Message-ID: <20091006150616.9431.29417.stgit@localhost.localdomain> + + +Mind the hoover wire... + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Cc: Alan Stern <stern@rowland.harvard.edu> +Cc: Oliver Neukum <oliver@neukum.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/char/tty_port.c | 25 +++++++++++++------------ + 1 file changed, 13 insertions(+), 12 deletions(-) + +--- a/drivers/char/tty_port.c ++++ b/drivers/char/tty_port.c +@@ -199,7 +199,7 @@ EXPORT_SYMBOL(tty_port_lower_dtr_rts); + * management of these lines. Note that the dtr/rts raise is done each + * iteration as a hangup may have previously dropped them while we wait. + */ +- ++ + int tty_port_block_til_ready(struct tty_port *port, + struct tty_struct *tty, struct file *filp) + { +@@ -248,7 +248,8 @@ int tty_port_block_til_ready(struct tty_ + tty_port_raise_dtr_rts(port); + + prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); +- /* Check for a hangup or uninitialised port. Return accordingly */ ++ /* Check for a hangup or uninitialised port. ++ Return accordingly */ + if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { + if (port->flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; +@@ -280,11 +281,11 @@ int tty_port_block_til_ready(struct tty_ + port->flags |= ASYNC_NORMAL_ACTIVE; + spin_unlock_irqrestore(&port->lock, flags); + return retval; +- + } + EXPORT_SYMBOL(tty_port_block_til_ready); + +-int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp) ++int tty_port_close_start(struct tty_port *port, ++ struct tty_struct *tty, struct file *filp) + { + unsigned long flags; + +@@ -294,7 +295,7 @@ int tty_port_close_start(struct tty_port + return 0; + } + +- if( tty->count == 1 && port->count != 1) { ++ if (tty->count == 1 && port->count != 1) { + printk(KERN_WARNING + "tty_port_close_start: tty->count = 1 port count = %d.\n", + port->count); +@@ -326,8 +327,8 @@ int tty_port_close_start(struct tty_port + long timeout; + + if (bps > 1200) +- timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps, +- HZ / 10); ++ timeout = max_t(long, ++ (HZ * 10 * port->drain_delay) / bps, HZ / 10); + else + timeout = 2 * HZ; + schedule_timeout_interruptible(timeout); +@@ -378,7 +379,7 @@ void tty_port_close(struct tty_port *por + EXPORT_SYMBOL(tty_port_close); + + int tty_port_open(struct tty_port *port, struct tty_struct *tty, +- struct file *filp) ++ struct file *filp) + { + spin_lock_irq(&port->lock); + if (!tty_hung_up_p(filp)) +@@ -398,10 +399,10 @@ int tty_port_open(struct tty_port *port, + if (port->ops->activate) { + int retval = port->ops->activate(port, tty); + if (retval) { +- mutex_unlock(&port->mutex); +- return retval; +- } +- } ++ mutex_unlock(&port->mutex); ++ return retval; ++ } ++ } + set_bit(ASYNCB_INITIALIZED, &port->flags); + } + mutex_unlock(&port->mutex); diff --git a/tty/usb_serial-kill-port-mutex.patch b/tty/usb_serial-kill-port-mutex.patch new file mode 100644 index 00000000000000..32b861dffc5506 --- /dev/null +++ b/tty/usb_serial-kill-port-mutex.patch @@ -0,0 +1,68 @@ +From alan@linux.intel.com Tue Oct 27 10:07:10 2009 +From: Alan Cox <alan@linux.intel.com> +Date: Tue, 06 Oct 2009 16:06:46 +0100 +Subject: usb_serial: Kill port mutex +To: greg@kroah.com, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org +Message-ID: <20091006150641.9431.67880.stgit@localhost.localdomain> + + +The tty port has a port mutex used for all the port related locking so we +don't need the one in the USB serial layer any more. + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Cc: Alan Stern <stern@rowland.harvard.edu> +Cc: Oliver Neukum <oliver@neukum.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/opticon.c | 4 ++-- + drivers/usb/serial/usb-serial.c | 1 - + include/linux/usb/serial.h | 3 --- + 3 files changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/opticon.c ++++ b/drivers/usb/serial/opticon.c +@@ -501,12 +501,12 @@ static int opticon_resume(struct usb_int + struct usb_serial_port *port = serial->port[0]; + int result; + +- mutex_lock(&port->mutex); ++ mutex_lock(&port->port.mutex); + if (port->port.count) + result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO); + else + result = 0; +- mutex_unlock(&port->mutex); ++ mutex_unlock(&port->port.mutex); + return result; + } + +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -897,7 +897,6 @@ int usb_serial_probe(struct usb_interfac + spin_lock_init(&port->lock); + /* Keep this for private driver use for the moment but + should probably go away */ +- mutex_init(&port->mutex); + INIT_WORK(&port->work, usb_serial_port_work); + serial->port[i] = port; + port->dev.parent = &interface->dev; +--- a/include/linux/usb/serial.h ++++ b/include/linux/usb/serial.h +@@ -39,8 +39,6 @@ enum port_dev_state { + * @serial: pointer back to the struct usb_serial owner of this port. + * @port: pointer to the corresponding tty_port for this port. + * @lock: spinlock to grab when updating portions of this structure. +- * @mutex: mutex used to synchronize serial_open() and serial_close() +- * access for this port. + * @number: the number of the port (the minor number). + * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. + * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. +@@ -77,7 +75,6 @@ struct usb_serial_port { + struct usb_serial *serial; + struct tty_port port; + spinlock_t lock; +- struct mutex mutex; + unsigned char number; + + unsigned char *interrupt_in_buffer; diff --git a/tty/usb_serial-use-the-shutdown-operation.patch b/tty/usb_serial-use-the-shutdown-operation.patch new file mode 100644 index 00000000000000..0def7d620d5395 --- /dev/null +++ b/tty/usb_serial-use-the-shutdown-operation.patch @@ -0,0 +1,124 @@ +From alan@linux.intel.com Tue Oct 27 10:05:50 2009 +From: Alan Cox <alan@linux.intel.com> +Date: Tue, 06 Oct 2009 16:06:36 +0100 +Subject: [PATCH 3/5] usb_serial: Use the shutdown() operation +To: greg@kroah.com, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org +Message-ID: <20091006150626.9431.34542.stgit@localhost.localdomain> + + +As Alan Stern pointed out - now we have tty_port_open the shutdown method +and locking allow us to whack the other bits into the full helper methods +and provide a shutdown op which the tty port code will synchronize with +setup for us. + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Cc: Alan Stern <stern@rowland.harvard.edu> +Cc: Oliver Neukum <oliver@neukum.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/usb/serial/usb-serial.c | 39 +++++++++++---------------------------- + 1 file changed, 11 insertions(+), 28 deletions(-) + +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -254,15 +254,12 @@ static int serial_activate(struct tty_po + struct usb_serial *serial = port->serial; + int retval; + +- if (mutex_lock_interruptible(&port->mutex)) +- return -ERESTARTSYS; + mutex_lock(&serial->disc_mutex); + if (serial->disconnected) + retval = -ENODEV; + else + retval = port->serial->type->open(tty, port); + mutex_unlock(&serial->disc_mutex); +- mutex_unlock(&port->mutex); + return retval; + } + +@@ -276,57 +273,40 @@ static int serial_open(struct tty_struct + + /** + * serial_down - shut down hardware +- * @port: port to shut down ++ * @tport: tty port to shut down + * + * Shut down a USB serial port unless it is the console. We never +- * shut down the console hardware as it will always be in use. ++ * shut down the console hardware as it will always be in use. Serialized ++ * against activate by the tport mutex and kept to matching open/close pairs ++ * of calls by the ASYNCB_INITIALIZED flag. + */ +-static void serial_down(struct usb_serial_port *port) ++static void serial_down(struct tty_port *tport) + { ++ struct usb_serial_port *port = ++ container_of(tport, struct usb_serial_port, port); + struct usb_serial_driver *drv = port->serial->type; +- + /* + * The console is magical. Do not hang up the console hardware + * or there will be tears. + */ + if (port->console) + return; +- +- /* Don't call the close method if the hardware hasn't been +- * initialized. +- */ +- if (!test_and_clear_bit(ASYNCB_INITIALIZED, &port->port.flags)) +- return; +- +- mutex_lock(&port->mutex); + if (drv->close) + drv->close(port); +- mutex_unlock(&port->mutex); + } + + static void serial_hangup(struct tty_struct *tty) + { + struct usb_serial_port *port = tty->driver_data; +- + dbg("%s - port %d", __func__, port->number); +- +- serial_down(port); + tty_port_hangup(&port->port); + } + + static void serial_close(struct tty_struct *tty, struct file *filp) + { + struct usb_serial_port *port = tty->driver_data; +- + dbg("%s - port %d", __func__, port->number); +- +- if (tty_hung_up_p(filp)) +- return; +- if (tty_port_close_start(&port->port, tty, filp) == 0) +- return; +- serial_down(port); +- tty_port_close_end(&port->port, tty); +- tty_port_tty_set(&port->port, NULL); ++ tty_port_close(&port->port, tty, filp); + } + + /** +@@ -716,6 +696,7 @@ static const struct tty_port_operations + .carrier_raised = serial_carrier_raised, + .dtr_rts = serial_dtr_rts, + .activate = serial_activate, ++ .shutdown = serial_down, + }; + + int usb_serial_probe(struct usb_interface *interface, +@@ -914,6 +895,8 @@ int usb_serial_probe(struct usb_interfac + port->port.ops = &serial_port_ops; + port->serial = serial; + spin_lock_init(&port->lock); ++ /* Keep this for private driver use for the moment but ++ should probably go away */ + mutex_init(&port->mutex); + INIT_WORK(&port->work, usb_serial_port_work); + serial->port[i] = port; |
