diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2009-04-23 12:58:04 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-04-23 12:58:04 -0700 |
| commit | f8c15b8f051b95e1ac809f45c4a51cfbbd58ca54 (patch) | |
| tree | 0219b970cdd0444d74422e2314b1ddadaab4f412 /usb.current | |
| parent | 7d3a619978ad23b22aa8de6ce99bfd6ada37a5ce (diff) | |
| download | patches-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.patch | 1 | ||||
| -rw-r--r-- | usb.current/usb-serial-fix-lifetime-and-locking-problems.patch | 51 |
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); |
