aboutsummaryrefslogtreecommitdiffstats
path: root/usb.current
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2009-04-23 12:58:04 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2009-04-23 12:58:04 -0700
commitf8c15b8f051b95e1ac809f45c4a51cfbbd58ca54 (patch)
tree0219b970cdd0444d74422e2314b1ddadaab4f412 /usb.current
parent7d3a619978ad23b22aa8de6ce99bfd6ada37a5ce (diff)
downloadpatches-f8c15b8f051b95e1ac809f45c4a51cfbbd58ca54.tar.gz
usb serial bugfix
Diffstat (limited to 'usb.current')
-rw-r--r--usb.current/usb-pwc-do-not-pass-stack-allocated-buffers-to-usb-core.patch1
-rw-r--r--usb.current/usb-serial-fix-lifetime-and-locking-problems.patch51
2 files changed, 36 insertions, 16 deletions
diff --git a/usb.current/usb-pwc-do-not-pass-stack-allocated-buffers-to-usb-core.patch b/usb.current/usb-pwc-do-not-pass-stack-allocated-buffers-to-usb-core.patch
index 6364ea196dd9e1..44eb1d3ae92d74 100644
--- a/usb.current/usb-pwc-do-not-pass-stack-allocated-buffers-to-usb-core.patch
+++ b/usb.current/usb-pwc-do-not-pass-stack-allocated-buffers-to-usb-core.patch
@@ -10,6 +10,7 @@ This is causes problems on platforms that have alignment requirements
for DMA transfers.
Signed-off-by: Martin Fuzzey <mfuzzey@gmail.com>
+Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/usb.current/usb-serial-fix-lifetime-and-locking-problems.patch b/usb.current/usb-serial-fix-lifetime-and-locking-problems.patch
index a29dfeac0d82eb..5ebf232c9a5057 100644
--- a/usb.current/usb-serial-fix-lifetime-and-locking-problems.patch
+++ b/usb.current/usb-serial-fix-lifetime-and-locking-problems.patch
@@ -43,18 +43,25 @@ This fixes the bug reported in
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Tested-by: Dan Williams <dcbw@redhat.com>
+Tested-by: Ming Lei <tom.leiming@gmail.com>
Reviewed-by: Oliver Neukum <oliver@neukum.org>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
- drivers/usb/serial/usb-serial.c | 90 ++++++++++++++++++++++++----------------
- 1 file changed, 56 insertions(+), 34 deletions(-)
+ drivers/usb/serial/usb-serial.c | 104 ++++++++++++++++++++++++++--------------
+ 1 file changed, 68 insertions(+), 36 deletions(-)
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
-@@ -143,16 +143,6 @@ static void destroy_serial(struct kref *
+@@ -137,22 +137,10 @@ static void destroy_serial(struct kref *
+
+ dbg("%s - %s", __func__, serial->type->description);
+
+- serial->type->shutdown(serial);
+-
+ /* return the minor range that this device had */
if (serial->minor != SERIAL_TTY_NO_MINOR)
return_serial(serial);
@@ -71,7 +78,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* If this is a "fake" port, we have to clean it up here, as it will
* not get cleaned up in port_release() as it was never registered with
* the driver core */
-@@ -187,7 +177,7 @@ static int serial_open (struct tty_struc
+@@ -187,7 +175,7 @@ static int serial_open (struct tty_struc
struct usb_serial *serial;
struct usb_serial_port *port;
unsigned int portNumber;
@@ -80,7 +87,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
dbg("%s", __func__);
-@@ -198,21 +188,24 @@ static int serial_open (struct tty_struc
+@@ -198,21 +186,24 @@ static int serial_open (struct tty_struc
return -ENODEV;
}
@@ -114,7 +121,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
++port->port.count;
-@@ -232,14 +225,20 @@ static int serial_open (struct tty_struc
+@@ -232,14 +223,20 @@ static int serial_open (struct tty_struc
goto bailout_mutex_unlock;
}
@@ -136,7 +143,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
mutex_unlock(&port->mutex);
-@@ -248,13 +247,16 @@ static int serial_open (struct tty_struc
+@@ -248,13 +245,16 @@ static int serial_open (struct tty_struc
bailout_interface_put:
usb_autopm_put_interface(serial->interface);
bailout_module_put:
@@ -154,7 +161,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
usb_serial_put(serial);
return retval;
}
-@@ -262,6 +264,9 @@ bailout_kref_put:
+@@ -262,6 +262,9 @@ bailout_kref_put:
static void serial_close(struct tty_struct *tty, struct file *filp)
{
struct usb_serial_port *port = tty->driver_data;
@@ -164,7 +171,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
if (!port)
return;
-@@ -269,6 +274,8 @@ static void serial_close(struct tty_stru
+@@ -269,6 +272,8 @@ static void serial_close(struct tty_stru
dbg("%s - port %d", __func__, port->number);
mutex_lock(&port->mutex);
@@ -173,7 +180,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
if (port->port.count == 0) {
mutex_unlock(&port->mutex);
-@@ -281,7 +288,7 @@ static void serial_close(struct tty_stru
+@@ -281,7 +286,7 @@ static void serial_close(struct tty_stru
* this before we drop the port count. The call is protected
* by the port mutex
*/
@@ -182,7 +189,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
if (port->port.count == (port->console ? 2 : 1)) {
struct tty_struct *tty = tty_port_tty_get(&port->port);
-@@ -295,17 +302,23 @@ static void serial_close(struct tty_stru
+@@ -295,17 +300,23 @@ static void serial_close(struct tty_stru
}
}
@@ -215,7 +222,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
static int serial_write(struct tty_struct *tty, const unsigned char *buf,
-@@ -549,7 +562,13 @@ static void kill_traffic(struct usb_seri
+@@ -549,7 +560,13 @@ static void kill_traffic(struct usb_seri
static void port_free(struct usb_serial_port *port)
{
@@ -229,7 +236,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
usb_free_urb(port->read_urb);
usb_free_urb(port->write_urb);
usb_free_urb(port->interrupt_in_urb);
-@@ -558,7 +577,6 @@ static void port_free(struct usb_serial_
+@@ -558,7 +575,6 @@ static void port_free(struct usb_serial_
kfree(port->bulk_out_buffer);
kfree(port->interrupt_in_buffer);
kfree(port->interrupt_out_buffer);
@@ -237,24 +244,36 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
kfree(port);
}
-@@ -1043,6 +1061,8 @@ void usb_serial_disconnect(struct usb_in
+@@ -1043,6 +1059,12 @@ void usb_serial_disconnect(struct usb_in
usb_set_intfdata(interface, NULL);
/* must set a flag, to signal subdrivers */
serial->disconnected = 1;
+ mutex_unlock(&serial->disc_mutex);
+
++ /* Unfortunately, many of the sub-drivers expect the port structures
++ * to exist when their shutdown method is called, so we have to go
++ * through this awkward two-step unregistration procedure.
++ */
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port) {
-@@ -1052,11 +1072,13 @@ void usb_serial_disconnect(struct usb_in
+@@ -1052,11 +1074,21 @@ void usb_serial_disconnect(struct usb_in
tty_kref_put(tty);
}
kill_traffic(port);
+ cancel_work_sync(&port->work);
-+ device_unregister(&port->dev);
++ device_del(&port->dev);
++ }
++ }
++ serial->type->shutdown(serial);
++ for (i = 0; i < serial->num_ports; ++i) {
++ port = serial->port[i];
++ if (port) {
++ put_device(&port->dev);
+ serial->port[i] = NULL;
}
}
++
/* let the last holder of this object
* cause it to be cleaned up */
- mutex_unlock(&serial->disc_mutex);