diff options
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b59a0536ea5..e06a41bd0f3 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
34 | #include "usb-serial.h" | 34 | #include <linux/usb/serial.h> |
35 | #include "pl2303.h" | 35 | #include "pl2303.h" |
36 | 36 | ||
37 | /* | 37 | /* |
@@ -40,6 +40,8 @@ | |||
40 | #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" | 40 | #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" |
41 | #define DRIVER_DESC "USB Serial Driver core" | 41 | #define DRIVER_DESC "USB Serial Driver core" |
42 | 42 | ||
43 | static void port_free(struct usb_serial_port *port); | ||
44 | |||
43 | /* Driver structure we register with the USB core */ | 45 | /* Driver structure we register with the USB core */ |
44 | static struct usb_driver usb_serial_driver = { | 46 | static struct usb_driver usb_serial_driver = { |
45 | .name = "usbserial", | 47 | .name = "usbserial", |
@@ -146,23 +148,10 @@ static void destroy_serial(struct kref *kref) | |||
146 | port = serial->port[i]; | 148 | port = serial->port[i]; |
147 | if (!port) | 149 | if (!port) |
148 | continue; | 150 | continue; |
149 | usb_kill_urb(port->read_urb); | 151 | port_free(port); |
150 | usb_free_urb(port->read_urb); | ||
151 | usb_kill_urb(port->write_urb); | ||
152 | usb_free_urb(port->write_urb); | ||
153 | usb_kill_urb(port->interrupt_in_urb); | ||
154 | usb_free_urb(port->interrupt_in_urb); | ||
155 | usb_kill_urb(port->interrupt_out_urb); | ||
156 | usb_free_urb(port->interrupt_out_urb); | ||
157 | kfree(port->bulk_in_buffer); | ||
158 | kfree(port->bulk_out_buffer); | ||
159 | kfree(port->interrupt_in_buffer); | ||
160 | kfree(port->interrupt_out_buffer); | ||
161 | } | 152 | } |
162 | } | 153 | } |
163 | 154 | ||
164 | flush_scheduled_work(); /* port->work */ | ||
165 | |||
166 | usb_put_dev(serial->dev); | 155 | usb_put_dev(serial->dev); |
167 | 156 | ||
168 | /* free up any memory that we allocated */ | 157 | /* free up any memory that we allocated */ |
@@ -475,8 +464,10 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int | |||
475 | length += sprintf (page+length, " path:%s", tmp); | 464 | length += sprintf (page+length, " path:%s", tmp); |
476 | 465 | ||
477 | length += sprintf (page+length, "\n"); | 466 | length += sprintf (page+length, "\n"); |
478 | if ((length + begin) > (off + count)) | 467 | if ((length + begin) > (off + count)) { |
468 | usb_serial_put(serial); | ||
479 | goto done; | 469 | goto done; |
470 | } | ||
480 | if ((length + begin) < off) { | 471 | if ((length + begin) < off) { |
481 | begin += length; | 472 | begin += length; |
482 | length = 0; | 473 | length = 0; |
@@ -564,6 +555,11 @@ static void port_release(struct device *dev) | |||
564 | struct usb_serial_port *port = to_usb_serial_port(dev); | 555 | struct usb_serial_port *port = to_usb_serial_port(dev); |
565 | 556 | ||
566 | dbg ("%s - %s", __FUNCTION__, dev->bus_id); | 557 | dbg ("%s - %s", __FUNCTION__, dev->bus_id); |
558 | port_free(port); | ||
559 | } | ||
560 | |||
561 | static void port_free(struct usb_serial_port *port) | ||
562 | { | ||
567 | usb_kill_urb(port->read_urb); | 563 | usb_kill_urb(port->read_urb); |
568 | usb_free_urb(port->read_urb); | 564 | usb_free_urb(port->read_urb); |
569 | usb_kill_urb(port->write_urb); | 565 | usb_kill_urb(port->write_urb); |
@@ -576,6 +572,7 @@ static void port_release(struct device *dev) | |||
576 | kfree(port->bulk_out_buffer); | 572 | kfree(port->bulk_out_buffer); |
577 | kfree(port->interrupt_in_buffer); | 573 | kfree(port->interrupt_in_buffer); |
578 | kfree(port->interrupt_out_buffer); | 574 | kfree(port->interrupt_out_buffer); |
575 | flush_scheduled_work(); /* port->work */ | ||
579 | kfree(port); | 576 | kfree(port); |
580 | } | 577 | } |
581 | 578 | ||