aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-06-02 11:53:55 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:47 -0400
commitf9c99bb8b3a1ec81af68d484a551307326c2e933 (patch)
tree9031ebe390ecd558d54ad484dde5ba66dcf823b7
parentc706ebdfc8955b850e477255a8c0f93f9f14712d (diff)
USB: usb-serial: replace shutdown with disconnect, release
This patch (as1254) splits up the shutdown method of usb_serial_driver into a disconnect and a release method. The problem is that the usb-serial core was calling shutdown during disconnect handling, but drivers didn't expect it to be called until after all the open file references had been closed. The result was an oops when the close method tried to use memory that had been deallocated by shutdown. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/uc2322/aten2011.c4
-rw-r--r--drivers/usb/serial/aircable.c5
-rw-r--r--drivers/usb/serial/belkin_sa.c7
-rw-r--r--drivers/usb/serial/cp210x.c6
-rw-r--r--drivers/usb/serial/cyberjack.c20
-rw-r--r--drivers/usb/serial/cypress_m8.c11
-rw-r--r--drivers/usb/serial/digi_acceleport.c20
-rw-r--r--drivers/usb/serial/empeg.c8
-rw-r--r--drivers/usb/serial/ftdi_sio.c14
-rw-r--r--drivers/usb/serial/garmin_gps.c16
-rw-r--r--drivers/usb/serial/generic.c9
-rw-r--r--drivers/usb/serial/io_edgeport.c29
-rw-r--r--drivers/usb/serial/io_tables.h12
-rw-r--r--drivers/usb/serial/io_ti.c22
-rw-r--r--drivers/usb/serial/ipaq.c7
-rw-r--r--drivers/usb/serial/iuu_phoenix.c6
-rw-r--r--drivers/usb/serial/keyspan.c13
-rw-r--r--drivers/usb/serial/keyspan.h12
-rw-r--r--drivers/usb/serial/keyspan_pda.c4
-rw-r--r--drivers/usb/serial/kl5kusb105.c39
-rw-r--r--drivers/usb/serial/kobil_sct.c12
-rw-r--r--drivers/usb/serial/mct_u232.c13
-rw-r--r--drivers/usb/serial/mos7720.c9
-rw-r--r--drivers/usb/serial/mos7840.c42
-rw-r--r--drivers/usb/serial/omninet.c19
-rw-r--r--drivers/usb/serial/opticon.c14
-rw-r--r--drivers/usb/serial/option.c17
-rw-r--r--drivers/usb/serial/oti6858.c7
-rw-r--r--drivers/usb/serial/pl2303.c5
-rw-r--r--drivers/usb/serial/sierra.c4
-rw-r--r--drivers/usb/serial/spcp8x5.c5
-rw-r--r--drivers/usb/serial/symbolserial.c14
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c10
-rw-r--r--drivers/usb/serial/usb-serial.c29
-rw-r--r--drivers/usb/serial/visor.c13
-rw-r--r--drivers/usb/serial/whiteheat.c6
-rw-r--r--include/linux/usb/serial.h12
37 files changed, 297 insertions, 198 deletions
diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c
index 9c62f787cc9c..39d0926d1a90 100644
--- a/drivers/staging/uc2322/aten2011.c
+++ b/drivers/staging/uc2322/aten2011.c
@@ -2336,7 +2336,7 @@ static int ATEN2011_startup(struct usb_serial *serial)
2336 return 0; 2336 return 0;
2337} 2337}
2338 2338
2339static void ATEN2011_shutdown(struct usb_serial *serial) 2339static void ATEN2011_release(struct usb_serial *serial)
2340{ 2340{
2341 int i; 2341 int i;
2342 struct ATENINTL_port *ATEN2011_port; 2342 struct ATENINTL_port *ATEN2011_port;
@@ -2382,7 +2382,7 @@ static struct usb_serial_driver aten_serial_driver = {
2382 .tiocmget = ATEN2011_tiocmget, 2382 .tiocmget = ATEN2011_tiocmget,
2383 .tiocmset = ATEN2011_tiocmset, 2383 .tiocmset = ATEN2011_tiocmset,
2384 .attach = ATEN2011_startup, 2384 .attach = ATEN2011_startup,
2385 .shutdown = ATEN2011_shutdown, 2385 .release = ATEN2011_release,
2386 .read_bulk_callback = ATEN2011_bulk_in_callback, 2386 .read_bulk_callback = ATEN2011_bulk_in_callback,
2387 .read_int_callback = ATEN2011_interrupt_callback, 2387 .read_int_callback = ATEN2011_interrupt_callback,
2388}; 2388};
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 6d106e74265e..2cbfab3716e5 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -364,7 +364,7 @@ static int aircable_attach(struct usb_serial *serial)
364 return 0; 364 return 0;
365} 365}
366 366
367static void aircable_shutdown(struct usb_serial *serial) 367static void aircable_release(struct usb_serial *serial)
368{ 368{
369 369
370 struct usb_serial_port *port = serial->port[0]; 370 struct usb_serial_port *port = serial->port[0];
@@ -375,7 +375,6 @@ static void aircable_shutdown(struct usb_serial *serial)
375 if (priv) { 375 if (priv) {
376 serial_buf_free(priv->tx_buf); 376 serial_buf_free(priv->tx_buf);
377 serial_buf_free(priv->rx_buf); 377 serial_buf_free(priv->rx_buf);
378 usb_set_serial_port_data(port, NULL);
379 kfree(priv); 378 kfree(priv);
380 } 379 }
381} 380}
@@ -601,7 +600,7 @@ static struct usb_serial_driver aircable_device = {
601 .num_ports = 1, 600 .num_ports = 1,
602 .attach = aircable_attach, 601 .attach = aircable_attach,
603 .probe = aircable_probe, 602 .probe = aircable_probe,
604 .shutdown = aircable_shutdown, 603 .release = aircable_release,
605 .write = aircable_write, 604 .write = aircable_write,
606 .write_room = aircable_write_room, 605 .write_room = aircable_write_room,
607 .write_bulk_callback = aircable_write_bulk_callback, 606 .write_bulk_callback = aircable_write_bulk_callback,
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 2bfd6dd85b5a..7033b031b443 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -90,7 +90,7 @@ static int debug;
90 90
91/* function prototypes for a Belkin USB Serial Adapter F5U103 */ 91/* function prototypes for a Belkin USB Serial Adapter F5U103 */
92static int belkin_sa_startup(struct usb_serial *serial); 92static int belkin_sa_startup(struct usb_serial *serial);
93static void belkin_sa_shutdown(struct usb_serial *serial); 93static void belkin_sa_release(struct usb_serial *serial);
94static int belkin_sa_open(struct tty_struct *tty, 94static int belkin_sa_open(struct tty_struct *tty,
95 struct usb_serial_port *port, struct file *filp); 95 struct usb_serial_port *port, struct file *filp);
96static void belkin_sa_close(struct usb_serial_port *port); 96static void belkin_sa_close(struct usb_serial_port *port);
@@ -142,7 +142,7 @@ static struct usb_serial_driver belkin_device = {
142 .tiocmget = belkin_sa_tiocmget, 142 .tiocmget = belkin_sa_tiocmget,
143 .tiocmset = belkin_sa_tiocmset, 143 .tiocmset = belkin_sa_tiocmset,
144 .attach = belkin_sa_startup, 144 .attach = belkin_sa_startup,
145 .shutdown = belkin_sa_shutdown, 145 .release = belkin_sa_release,
146}; 146};
147 147
148 148
@@ -197,14 +197,13 @@ static int belkin_sa_startup(struct usb_serial *serial)
197} 197}
198 198
199 199
200static void belkin_sa_shutdown(struct usb_serial *serial) 200static void belkin_sa_release(struct usb_serial *serial)
201{ 201{
202 struct belkin_sa_private *priv; 202 struct belkin_sa_private *priv;
203 int i; 203 int i;
204 204
205 dbg("%s", __func__); 205 dbg("%s", __func__);
206 206
207 /* stop reads and writes on all ports */
208 for (i = 0; i < serial->num_ports; ++i) { 207 for (i = 0; i < serial->num_ports; ++i) {
209 /* My special items, the standard routines free my urbs */ 208 /* My special items, the standard routines free my urbs */
210 priv = usb_get_serial_port_data(serial->port[i]); 209 priv = usb_get_serial_port_data(serial->port[i]);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 16a154d3b2fe..2b9eeda62bfe 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -50,7 +50,7 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *,
50 unsigned int, unsigned int); 50 unsigned int, unsigned int);
51static void cp210x_break_ctl(struct tty_struct *, int); 51static void cp210x_break_ctl(struct tty_struct *, int);
52static int cp210x_startup(struct usb_serial *); 52static int cp210x_startup(struct usb_serial *);
53static void cp210x_shutdown(struct usb_serial *); 53static void cp210x_disconnect(struct usb_serial *);
54 54
55static int debug; 55static int debug;
56 56
@@ -137,7 +137,7 @@ static struct usb_serial_driver cp210x_device = {
137 .tiocmget = cp210x_tiocmget, 137 .tiocmget = cp210x_tiocmget,
138 .tiocmset = cp210x_tiocmset, 138 .tiocmset = cp210x_tiocmset,
139 .attach = cp210x_startup, 139 .attach = cp210x_startup,
140 .shutdown = cp210x_shutdown, 140 .disconnect = cp210x_disconnect,
141}; 141};
142 142
143/* Config request types */ 143/* Config request types */
@@ -792,7 +792,7 @@ static int cp210x_startup(struct usb_serial *serial)
792 return 0; 792 return 0;
793} 793}
794 794
795static void cp210x_shutdown(struct usb_serial *serial) 795static void cp210x_disconnect(struct usb_serial *serial)
796{ 796{
797 int i; 797 int i;
798 798
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 933ba913e66c..336523fd7366 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -58,7 +58,8 @@ static int debug;
58 58
59/* Function prototypes */ 59/* Function prototypes */
60static int cyberjack_startup(struct usb_serial *serial); 60static int cyberjack_startup(struct usb_serial *serial);
61static void cyberjack_shutdown(struct usb_serial *serial); 61static void cyberjack_disconnect(struct usb_serial *serial);
62static void cyberjack_release(struct usb_serial *serial);
62static int cyberjack_open(struct tty_struct *tty, 63static int cyberjack_open(struct tty_struct *tty,
63 struct usb_serial_port *port, struct file *filp); 64 struct usb_serial_port *port, struct file *filp);
64static void cyberjack_close(struct usb_serial_port *port); 65static void cyberjack_close(struct usb_serial_port *port);
@@ -94,7 +95,8 @@ static struct usb_serial_driver cyberjack_device = {
94 .id_table = id_table, 95 .id_table = id_table,
95 .num_ports = 1, 96 .num_ports = 1,
96 .attach = cyberjack_startup, 97 .attach = cyberjack_startup,
97 .shutdown = cyberjack_shutdown, 98 .disconnect = cyberjack_disconnect,
99 .release = cyberjack_release,
98 .open = cyberjack_open, 100 .open = cyberjack_open,
99 .close = cyberjack_close, 101 .close = cyberjack_close,
100 .write = cyberjack_write, 102 .write = cyberjack_write,
@@ -148,17 +150,25 @@ static int cyberjack_startup(struct usb_serial *serial)
148 return 0; 150 return 0;
149} 151}
150 152
151static void cyberjack_shutdown(struct usb_serial *serial) 153static void cyberjack_disconnect(struct usb_serial *serial)
152{ 154{
153 int i; 155 int i;
154 156
155 dbg("%s", __func__); 157 dbg("%s", __func__);
156 158
157 for (i = 0; i < serial->num_ports; ++i) { 159 for (i = 0; i < serial->num_ports; ++i)
158 usb_kill_urb(serial->port[i]->interrupt_in_urb); 160 usb_kill_urb(serial->port[i]->interrupt_in_urb);
161}
162
163static void cyberjack_release(struct usb_serial *serial)
164{
165 int i;
166
167 dbg("%s", __func__);
168
169 for (i = 0; i < serial->num_ports; ++i) {
159 /* My special items, the standard routines free my urbs */ 170 /* My special items, the standard routines free my urbs */
160 kfree(usb_get_serial_port_data(serial->port[i])); 171 kfree(usb_get_serial_port_data(serial->port[i]));
161 usb_set_serial_port_data(serial->port[i], NULL);
162 } 172 }
163} 173}
164 174
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 669f93848539..9734085fd2fe 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -171,7 +171,7 @@ struct cypress_buf {
171static int cypress_earthmate_startup(struct usb_serial *serial); 171static int cypress_earthmate_startup(struct usb_serial *serial);
172static int cypress_hidcom_startup(struct usb_serial *serial); 172static int cypress_hidcom_startup(struct usb_serial *serial);
173static int cypress_ca42v2_startup(struct usb_serial *serial); 173static int cypress_ca42v2_startup(struct usb_serial *serial);
174static void cypress_shutdown(struct usb_serial *serial); 174static void cypress_release(struct usb_serial *serial);
175static int cypress_open(struct tty_struct *tty, 175static int cypress_open(struct tty_struct *tty,
176 struct usb_serial_port *port, struct file *filp); 176 struct usb_serial_port *port, struct file *filp);
177static void cypress_close(struct usb_serial_port *port); 177static void cypress_close(struct usb_serial_port *port);
@@ -215,7 +215,7 @@ static struct usb_serial_driver cypress_earthmate_device = {
215 .id_table = id_table_earthmate, 215 .id_table = id_table_earthmate,
216 .num_ports = 1, 216 .num_ports = 1,
217 .attach = cypress_earthmate_startup, 217 .attach = cypress_earthmate_startup,
218 .shutdown = cypress_shutdown, 218 .release = cypress_release,
219 .open = cypress_open, 219 .open = cypress_open,
220 .close = cypress_close, 220 .close = cypress_close,
221 .dtr_rts = cypress_dtr_rts, 221 .dtr_rts = cypress_dtr_rts,
@@ -242,7 +242,7 @@ static struct usb_serial_driver cypress_hidcom_device = {
242 .id_table = id_table_cyphidcomrs232, 242 .id_table = id_table_cyphidcomrs232,
243 .num_ports = 1, 243 .num_ports = 1,
244 .attach = cypress_hidcom_startup, 244 .attach = cypress_hidcom_startup,
245 .shutdown = cypress_shutdown, 245 .release = cypress_release,
246 .open = cypress_open, 246 .open = cypress_open,
247 .close = cypress_close, 247 .close = cypress_close,
248 .dtr_rts = cypress_dtr_rts, 248 .dtr_rts = cypress_dtr_rts,
@@ -269,7 +269,7 @@ static struct usb_serial_driver cypress_ca42v2_device = {
269 .id_table = id_table_nokiaca42v2, 269 .id_table = id_table_nokiaca42v2,
270 .num_ports = 1, 270 .num_ports = 1,
271 .attach = cypress_ca42v2_startup, 271 .attach = cypress_ca42v2_startup,
272 .shutdown = cypress_shutdown, 272 .release = cypress_release,
273 .open = cypress_open, 273 .open = cypress_open,
274 .close = cypress_close, 274 .close = cypress_close,
275 .dtr_rts = cypress_dtr_rts, 275 .dtr_rts = cypress_dtr_rts,
@@ -616,7 +616,7 @@ static int cypress_ca42v2_startup(struct usb_serial *serial)
616} /* cypress_ca42v2_startup */ 616} /* cypress_ca42v2_startup */
617 617
618 618
619static void cypress_shutdown(struct usb_serial *serial) 619static void cypress_release(struct usb_serial *serial)
620{ 620{
621 struct cypress_private *priv; 621 struct cypress_private *priv;
622 622
@@ -629,7 +629,6 @@ static void cypress_shutdown(struct usb_serial *serial)
629 if (priv) { 629 if (priv) {
630 cypress_buf_free(priv->buf); 630 cypress_buf_free(priv->buf);
631 kfree(priv); 631 kfree(priv);
632 usb_set_serial_port_data(serial->port[0], NULL);
633 } 632 }
634} 633}
635 634
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 30f5140eff03..f4808091c47c 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -460,7 +460,8 @@ static int digi_carrier_raised(struct usb_serial_port *port);
460static void digi_dtr_rts(struct usb_serial_port *port, int on); 460static void digi_dtr_rts(struct usb_serial_port *port, int on);
461static int digi_startup_device(struct usb_serial *serial); 461static int digi_startup_device(struct usb_serial *serial);
462static int digi_startup(struct usb_serial *serial); 462static int digi_startup(struct usb_serial *serial);
463static void digi_shutdown(struct usb_serial *serial); 463static void digi_disconnect(struct usb_serial *serial);
464static void digi_release(struct usb_serial *serial);
464static void digi_read_bulk_callback(struct urb *urb); 465static void digi_read_bulk_callback(struct urb *urb);
465static int digi_read_inb_callback(struct urb *urb); 466static int digi_read_inb_callback(struct urb *urb);
466static int digi_read_oob_callback(struct urb *urb); 467static int digi_read_oob_callback(struct urb *urb);
@@ -524,7 +525,8 @@ static struct usb_serial_driver digi_acceleport_2_device = {
524 .tiocmget = digi_tiocmget, 525 .tiocmget = digi_tiocmget,
525 .tiocmset = digi_tiocmset, 526 .tiocmset = digi_tiocmset,
526 .attach = digi_startup, 527 .attach = digi_startup,
527 .shutdown = digi_shutdown, 528 .disconnect = digi_disconnect,
529 .release = digi_release,
528}; 530};
529 531
530static struct usb_serial_driver digi_acceleport_4_device = { 532static struct usb_serial_driver digi_acceleport_4_device = {
@@ -550,7 +552,8 @@ static struct usb_serial_driver digi_acceleport_4_device = {
550 .tiocmget = digi_tiocmget, 552 .tiocmget = digi_tiocmget,
551 .tiocmset = digi_tiocmset, 553 .tiocmset = digi_tiocmset,
552 .attach = digi_startup, 554 .attach = digi_startup,
553 .shutdown = digi_shutdown, 555 .disconnect = digi_disconnect,
556 .release = digi_release,
554}; 557};
555 558
556 559
@@ -1556,16 +1559,23 @@ static int digi_startup(struct usb_serial *serial)
1556} 1559}
1557 1560
1558 1561
1559static void digi_shutdown(struct usb_serial *serial) 1562static void digi_disconnect(struct usb_serial *serial)
1560{ 1563{
1561 int i; 1564 int i;
1562 dbg("digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt()); 1565 dbg("digi_disconnect: TOP, in_interrupt()=%ld", in_interrupt());
1563 1566
1564 /* stop reads and writes on all ports */ 1567 /* stop reads and writes on all ports */
1565 for (i = 0; i < serial->type->num_ports + 1; i++) { 1568 for (i = 0; i < serial->type->num_ports + 1; i++) {
1566 usb_kill_urb(serial->port[i]->read_urb); 1569 usb_kill_urb(serial->port[i]->read_urb);
1567 usb_kill_urb(serial->port[i]->write_urb); 1570 usb_kill_urb(serial->port[i]->write_urb);
1568 } 1571 }
1572}
1573
1574
1575static void digi_release(struct usb_serial *serial)
1576{
1577 int i;
1578 dbg("digi_release: TOP, in_interrupt()=%ld", in_interrupt());
1569 1579
1570 /* free the private data structures for all ports */ 1580 /* free the private data structures for all ports */
1571 /* number of regular ports + 1 for the out-of-band port */ 1581 /* number of regular ports + 1 for the out-of-band port */
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 2b141ccb0cd9..80cb3471adbe 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -90,7 +90,6 @@ static int empeg_chars_in_buffer(struct tty_struct *tty);
90static void empeg_throttle(struct tty_struct *tty); 90static void empeg_throttle(struct tty_struct *tty);
91static void empeg_unthrottle(struct tty_struct *tty); 91static void empeg_unthrottle(struct tty_struct *tty);
92static int empeg_startup(struct usb_serial *serial); 92static int empeg_startup(struct usb_serial *serial);
93static void empeg_shutdown(struct usb_serial *serial);
94static void empeg_set_termios(struct tty_struct *tty, 93static void empeg_set_termios(struct tty_struct *tty,
95 struct usb_serial_port *port, struct ktermios *old_termios); 94 struct usb_serial_port *port, struct ktermios *old_termios);
96static void empeg_write_bulk_callback(struct urb *urb); 95static void empeg_write_bulk_callback(struct urb *urb);
@@ -124,7 +123,6 @@ static struct usb_serial_driver empeg_device = {
124 .throttle = empeg_throttle, 123 .throttle = empeg_throttle,
125 .unthrottle = empeg_unthrottle, 124 .unthrottle = empeg_unthrottle,
126 .attach = empeg_startup, 125 .attach = empeg_startup,
127 .shutdown = empeg_shutdown,
128 .set_termios = empeg_set_termios, 126 .set_termios = empeg_set_termios,
129 .write = empeg_write, 127 .write = empeg_write,
130 .write_room = empeg_write_room, 128 .write_room = empeg_write_room,
@@ -427,12 +425,6 @@ static int empeg_startup(struct usb_serial *serial)
427} 425}
428 426
429 427
430static void empeg_shutdown(struct usb_serial *serial)
431{
432 dbg("%s", __func__);
433}
434
435
436static void empeg_set_termios(struct tty_struct *tty, 428static void empeg_set_termios(struct tty_struct *tty,
437 struct usb_serial_port *port, struct ktermios *old_termios) 429 struct usb_serial_port *port, struct ktermios *old_termios)
438{ 430{
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index fc423583eede..3dc3768ca71c 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -720,7 +720,6 @@ static const char *ftdi_chip_name[] = {
720/* function prototypes for a FTDI serial converter */ 720/* function prototypes for a FTDI serial converter */
721static int ftdi_sio_probe(struct usb_serial *serial, 721static int ftdi_sio_probe(struct usb_serial *serial,
722 const struct usb_device_id *id); 722 const struct usb_device_id *id);
723static void ftdi_shutdown(struct usb_serial *serial);
724static int ftdi_sio_port_probe(struct usb_serial_port *port); 723static int ftdi_sio_port_probe(struct usb_serial_port *port);
725static int ftdi_sio_port_remove(struct usb_serial_port *port); 724static int ftdi_sio_port_remove(struct usb_serial_port *port);
726static int ftdi_open(struct tty_struct *tty, 725static int ftdi_open(struct tty_struct *tty,
@@ -779,7 +778,6 @@ static struct usb_serial_driver ftdi_sio_device = {
779 .ioctl = ftdi_ioctl, 778 .ioctl = ftdi_ioctl,
780 .set_termios = ftdi_set_termios, 779 .set_termios = ftdi_set_termios,
781 .break_ctl = ftdi_break_ctl, 780 .break_ctl = ftdi_break_ctl,
782 .shutdown = ftdi_shutdown,
783}; 781};
784 782
785 783
@@ -1594,18 +1592,6 @@ static int ftdi_mtxorb_hack_setup(struct usb_serial *serial)
1594 return 0; 1592 return 0;
1595} 1593}
1596 1594
1597/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
1598 * it is called when the usb device is disconnected
1599 *
1600 * usbserial:usb_serial_disconnect
1601 * calls __serial_close for each open of the port
1602 * shutdown is called then (ie ftdi_shutdown)
1603 */
1604static void ftdi_shutdown(struct usb_serial *serial)
1605{
1606 dbg("%s", __func__);
1607}
1608
1609static void ftdi_sio_priv_release(struct kref *k) 1595static void ftdi_sio_priv_release(struct kref *k)
1610{ 1596{
1611 struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); 1597 struct ftdi_private *priv = container_of(k, struct ftdi_private, kref);
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 5092d6aba659..8839f1c70b7f 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1475,7 +1475,7 @@ static int garmin_attach(struct usb_serial *serial)
1475} 1475}
1476 1476
1477 1477
1478static void garmin_shutdown(struct usb_serial *serial) 1478static void garmin_disconnect(struct usb_serial *serial)
1479{ 1479{
1480 struct usb_serial_port *port = serial->port[0]; 1480 struct usb_serial_port *port = serial->port[0];
1481 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); 1481 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
@@ -1484,8 +1484,17 @@ static void garmin_shutdown(struct usb_serial *serial)
1484 1484
1485 usb_kill_urb(port->interrupt_in_urb); 1485 usb_kill_urb(port->interrupt_in_urb);
1486 del_timer_sync(&garmin_data_p->timer); 1486 del_timer_sync(&garmin_data_p->timer);
1487}
1488
1489
1490static void garmin_release(struct usb_serial *serial)
1491{
1492 struct usb_serial_port *port = serial->port[0];
1493 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
1494
1495 dbg("%s", __func__);
1496
1487 kfree(garmin_data_p); 1497 kfree(garmin_data_p);
1488 usb_set_serial_port_data(port, NULL);
1489} 1498}
1490 1499
1491 1500
@@ -1504,7 +1513,8 @@ static struct usb_serial_driver garmin_device = {
1504 .throttle = garmin_throttle, 1513 .throttle = garmin_throttle,
1505 .unthrottle = garmin_unthrottle, 1514 .unthrottle = garmin_unthrottle,
1506 .attach = garmin_attach, 1515 .attach = garmin_attach,
1507 .shutdown = garmin_shutdown, 1516 .disconnect = garmin_disconnect,
1517 .release = garmin_release,
1508 .write = garmin_write, 1518 .write = garmin_write,
1509 .write_room = garmin_write_room, 1519 .write_room = garmin_write_room,
1510 .write_bulk_callback = garmin_write_bulk_callback, 1520 .write_bulk_callback = garmin_write_bulk_callback,
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 8dabac1929b0..932d6241b787 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -63,7 +63,8 @@ struct usb_serial_driver usb_serial_generic_device = {
63 .id_table = generic_device_ids, 63 .id_table = generic_device_ids,
64 .usb_driver = &generic_driver, 64 .usb_driver = &generic_driver,
65 .num_ports = 1, 65 .num_ports = 1,
66 .shutdown = usb_serial_generic_shutdown, 66 .disconnect = usb_serial_generic_disconnect,
67 .release = usb_serial_generic_release,
67 .throttle = usb_serial_generic_throttle, 68 .throttle = usb_serial_generic_throttle,
68 .unthrottle = usb_serial_generic_unthrottle, 69 .unthrottle = usb_serial_generic_unthrottle,
69 .resume = usb_serial_generic_resume, 70 .resume = usb_serial_generic_resume,
@@ -551,7 +552,7 @@ int usb_serial_handle_break(struct usb_serial_port *port)
551} 552}
552EXPORT_SYMBOL_GPL(usb_serial_handle_break); 553EXPORT_SYMBOL_GPL(usb_serial_handle_break);
553 554
554void usb_serial_generic_shutdown(struct usb_serial *serial) 555void usb_serial_generic_disconnect(struct usb_serial *serial)
555{ 556{
556 int i; 557 int i;
557 558
@@ -562,3 +563,7 @@ void usb_serial_generic_shutdown(struct usb_serial *serial)
562 generic_cleanup(serial->port[i]); 563 generic_cleanup(serial->port[i]);
563} 564}
564 565
566void usb_serial_generic_release(struct usb_serial *serial)
567{
568 dbg("%s", __func__);
569}
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 53ef5996e33d..0191693625d6 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -224,7 +224,8 @@ static int edge_tiocmget(struct tty_struct *tty, struct file *file);
224static int edge_tiocmset(struct tty_struct *tty, struct file *file, 224static int edge_tiocmset(struct tty_struct *tty, struct file *file,
225 unsigned int set, unsigned int clear); 225 unsigned int set, unsigned int clear);
226static int edge_startup(struct usb_serial *serial); 226static int edge_startup(struct usb_serial *serial);
227static void edge_shutdown(struct usb_serial *serial); 227static void edge_disconnect(struct usb_serial *serial);
228static void edge_release(struct usb_serial *serial);
228 229
229#include "io_tables.h" /* all of the devices that this driver supports */ 230#include "io_tables.h" /* all of the devices that this driver supports */
230 231
@@ -3193,21 +3194,16 @@ static int edge_startup(struct usb_serial *serial)
3193 3194
3194 3195
3195/**************************************************************************** 3196/****************************************************************************
3196 * edge_shutdown 3197 * edge_disconnect
3197 * This function is called whenever the device is removed from the usb bus. 3198 * This function is called whenever the device is removed from the usb bus.
3198 ****************************************************************************/ 3199 ****************************************************************************/
3199static void edge_shutdown(struct usb_serial *serial) 3200static void edge_disconnect(struct usb_serial *serial)
3200{ 3201{
3201 struct edgeport_serial *edge_serial = usb_get_serial_data(serial); 3202 struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
3202 int i;
3203 3203
3204 dbg("%s", __func__); 3204 dbg("%s", __func__);
3205 3205
3206 /* stop reads and writes on all ports */ 3206 /* stop reads and writes on all ports */
3207 for (i = 0; i < serial->num_ports; ++i) {
3208 kfree(usb_get_serial_port_data(serial->port[i]));
3209 usb_set_serial_port_data(serial->port[i], NULL);
3210 }
3211 /* free up our endpoint stuff */ 3207 /* free up our endpoint stuff */
3212 if (edge_serial->is_epic) { 3208 if (edge_serial->is_epic) {
3213 usb_kill_urb(edge_serial->interrupt_read_urb); 3209 usb_kill_urb(edge_serial->interrupt_read_urb);
@@ -3218,9 +3214,24 @@ static void edge_shutdown(struct usb_serial *serial)
3218 usb_free_urb(edge_serial->read_urb); 3214 usb_free_urb(edge_serial->read_urb);
3219 kfree(edge_serial->bulk_in_buffer); 3215 kfree(edge_serial->bulk_in_buffer);
3220 } 3216 }
3217}
3218
3219
3220/****************************************************************************
3221 * edge_release
3222 * This function is called when the device structure is deallocated.
3223 ****************************************************************************/
3224static void edge_release(struct usb_serial *serial)
3225{
3226 struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
3227 int i;
3228
3229 dbg("%s", __func__);
3230
3231 for (i = 0; i < serial->num_ports; ++i)
3232 kfree(usb_get_serial_port_data(serial->port[i]));
3221 3233
3222 kfree(edge_serial); 3234 kfree(edge_serial);
3223 usb_set_serial_data(serial, NULL);
3224} 3235}
3225 3236
3226 3237
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h
index 7eb9d67b81b6..9241d3147513 100644
--- a/drivers/usb/serial/io_tables.h
+++ b/drivers/usb/serial/io_tables.h
@@ -117,7 +117,8 @@ static struct usb_serial_driver edgeport_2port_device = {
117 .throttle = edge_throttle, 117 .throttle = edge_throttle,
118 .unthrottle = edge_unthrottle, 118 .unthrottle = edge_unthrottle,
119 .attach = edge_startup, 119 .attach = edge_startup,
120 .shutdown = edge_shutdown, 120 .disconnect = edge_disconnect,
121 .release = edge_release,
121 .ioctl = edge_ioctl, 122 .ioctl = edge_ioctl,
122 .set_termios = edge_set_termios, 123 .set_termios = edge_set_termios,
123 .tiocmget = edge_tiocmget, 124 .tiocmget = edge_tiocmget,
@@ -145,7 +146,8 @@ static struct usb_serial_driver edgeport_4port_device = {
145 .throttle = edge_throttle, 146 .throttle = edge_throttle,
146 .unthrottle = edge_unthrottle, 147 .unthrottle = edge_unthrottle,
147 .attach = edge_startup, 148 .attach = edge_startup,
148 .shutdown = edge_shutdown, 149 .disconnect = edge_disconnect,
150 .release = edge_release,
149 .ioctl = edge_ioctl, 151 .ioctl = edge_ioctl,
150 .set_termios = edge_set_termios, 152 .set_termios = edge_set_termios,
151 .tiocmget = edge_tiocmget, 153 .tiocmget = edge_tiocmget,
@@ -173,7 +175,8 @@ static struct usb_serial_driver edgeport_8port_device = {
173 .throttle = edge_throttle, 175 .throttle = edge_throttle,
174 .unthrottle = edge_unthrottle, 176 .unthrottle = edge_unthrottle,
175 .attach = edge_startup, 177 .attach = edge_startup,
176 .shutdown = edge_shutdown, 178 .disconnect = edge_disconnect,
179 .release = edge_release,
177 .ioctl = edge_ioctl, 180 .ioctl = edge_ioctl,
178 .set_termios = edge_set_termios, 181 .set_termios = edge_set_termios,
179 .tiocmget = edge_tiocmget, 182 .tiocmget = edge_tiocmget,
@@ -200,7 +203,8 @@ static struct usb_serial_driver epic_device = {
200 .throttle = edge_throttle, 203 .throttle = edge_throttle,
201 .unthrottle = edge_unthrottle, 204 .unthrottle = edge_unthrottle,
202 .attach = edge_startup, 205 .attach = edge_startup,
203 .shutdown = edge_shutdown, 206 .disconnect = edge_disconnect,
207 .release = edge_release,
204 .ioctl = edge_ioctl, 208 .ioctl = edge_ioctl,
205 .set_termios = edge_set_termios, 209 .set_termios = edge_set_termios,
206 .tiocmget = edge_tiocmget, 210 .tiocmget = edge_tiocmget,
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index db964db42d3c..e8bc42f92e79 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -2663,7 +2663,7 @@ cleanup:
2663 return -ENOMEM; 2663 return -ENOMEM;
2664} 2664}
2665 2665
2666static void edge_shutdown(struct usb_serial *serial) 2666static void edge_disconnect(struct usb_serial *serial)
2667{ 2667{
2668 int i; 2668 int i;
2669 struct edgeport_port *edge_port; 2669 struct edgeport_port *edge_port;
@@ -2673,12 +2673,22 @@ static void edge_shutdown(struct usb_serial *serial)
2673 for (i = 0; i < serial->num_ports; ++i) { 2673 for (i = 0; i < serial->num_ports; ++i) {
2674 edge_port = usb_get_serial_port_data(serial->port[i]); 2674 edge_port = usb_get_serial_port_data(serial->port[i]);
2675 edge_remove_sysfs_attrs(edge_port->port); 2675 edge_remove_sysfs_attrs(edge_port->port);
2676 }
2677}
2678
2679static void edge_release(struct usb_serial *serial)
2680{
2681 int i;
2682 struct edgeport_port *edge_port;
2683
2684 dbg("%s", __func__);
2685
2686 for (i = 0; i < serial->num_ports; ++i) {
2687 edge_port = usb_get_serial_port_data(serial->port[i]);
2676 edge_buf_free(edge_port->ep_out_buf); 2688 edge_buf_free(edge_port->ep_out_buf);
2677 kfree(edge_port); 2689 kfree(edge_port);
2678 usb_set_serial_port_data(serial->port[i], NULL);
2679 } 2690 }
2680 kfree(usb_get_serial_data(serial)); 2691 kfree(usb_get_serial_data(serial));
2681 usb_set_serial_data(serial, NULL);
2682} 2692}
2683 2693
2684 2694
@@ -2915,7 +2925,8 @@ static struct usb_serial_driver edgeport_1port_device = {
2915 .throttle = edge_throttle, 2925 .throttle = edge_throttle,
2916 .unthrottle = edge_unthrottle, 2926 .unthrottle = edge_unthrottle,
2917 .attach = edge_startup, 2927 .attach = edge_startup,
2918 .shutdown = edge_shutdown, 2928 .disconnect = edge_disconnect,
2929 .release = edge_release,
2919 .port_probe = edge_create_sysfs_attrs, 2930 .port_probe = edge_create_sysfs_attrs,
2920 .ioctl = edge_ioctl, 2931 .ioctl = edge_ioctl,
2921 .set_termios = edge_set_termios, 2932 .set_termios = edge_set_termios,
@@ -2944,7 +2955,8 @@ static struct usb_serial_driver edgeport_2port_device = {
2944 .throttle = edge_throttle, 2955 .throttle = edge_throttle,
2945 .unthrottle = edge_unthrottle, 2956 .unthrottle = edge_unthrottle,
2946 .attach = edge_startup, 2957 .attach = edge_startup,
2947 .shutdown = edge_shutdown, 2958 .disconnect = edge_disconnect,
2959 .release = edge_release,
2948 .port_probe = edge_create_sysfs_attrs, 2960 .port_probe = edge_create_sysfs_attrs,
2949 .ioctl = edge_ioctl, 2961 .ioctl = edge_ioctl,
2950 .set_termios = edge_set_termios, 2962 .set_termios = edge_set_termios,
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index c610a99fa477..2545d45ce16f 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -79,7 +79,6 @@ static int ipaq_open(struct tty_struct *tty,
79static void ipaq_close(struct usb_serial_port *port); 79static void ipaq_close(struct usb_serial_port *port);
80static int ipaq_calc_num_ports(struct usb_serial *serial); 80static int ipaq_calc_num_ports(struct usb_serial *serial);
81static int ipaq_startup(struct usb_serial *serial); 81static int ipaq_startup(struct usb_serial *serial);
82static void ipaq_shutdown(struct usb_serial *serial);
83static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, 82static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
84 const unsigned char *buf, int count); 83 const unsigned char *buf, int count);
85static int ipaq_write_bulk(struct usb_serial_port *port, 84static int ipaq_write_bulk(struct usb_serial_port *port,
@@ -576,7 +575,6 @@ static struct usb_serial_driver ipaq_device = {
576 .close = ipaq_close, 575 .close = ipaq_close,
577 .attach = ipaq_startup, 576 .attach = ipaq_startup,
578 .calc_num_ports = ipaq_calc_num_ports, 577 .calc_num_ports = ipaq_calc_num_ports,
579 .shutdown = ipaq_shutdown,
580 .write = ipaq_write, 578 .write = ipaq_write,
581 .write_room = ipaq_write_room, 579 .write_room = ipaq_write_room,
582 .chars_in_buffer = ipaq_chars_in_buffer, 580 .chars_in_buffer = ipaq_chars_in_buffer,
@@ -990,11 +988,6 @@ static int ipaq_startup(struct usb_serial *serial)
990 return usb_reset_configuration(serial->dev); 988 return usb_reset_configuration(serial->dev);
991} 989}
992 990
993static void ipaq_shutdown(struct usb_serial *serial)
994{
995 dbg("%s", __func__);
996}
997
998static int __init ipaq_init(void) 991static int __init ipaq_init(void)
999{ 992{
1000 int retval; 993 int retval;
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 76a3cc327bb9..96873a7a32b0 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -121,8 +121,8 @@ static int iuu_startup(struct usb_serial *serial)
121 return 0; 121 return 0;
122} 122}
123 123
124/* Shutdown function */ 124/* Release function */
125static void iuu_shutdown(struct usb_serial *serial) 125static void iuu_release(struct usb_serial *serial)
126{ 126{
127 struct usb_serial_port *port = serial->port[0]; 127 struct usb_serial_port *port = serial->port[0];
128 struct iuu_private *priv = usb_get_serial_port_data(port); 128 struct iuu_private *priv = usb_get_serial_port_data(port);
@@ -1202,7 +1202,7 @@ static struct usb_serial_driver iuu_device = {
1202 .tiocmset = iuu_tiocmset, 1202 .tiocmset = iuu_tiocmset,
1203 .set_termios = iuu_set_termios, 1203 .set_termios = iuu_set_termios,
1204 .attach = iuu_startup, 1204 .attach = iuu_startup,
1205 .shutdown = iuu_shutdown, 1205 .release = iuu_release,
1206}; 1206};
1207 1207
1208static int __init iuu_init(void) 1208static int __init iuu_init(void)
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index f1195a98f316..2594b8743d3f 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -2689,7 +2689,7 @@ static int keyspan_startup(struct usb_serial *serial)
2689 return 0; 2689 return 0;
2690} 2690}
2691 2691
2692static void keyspan_shutdown(struct usb_serial *serial) 2692static void keyspan_disconnect(struct usb_serial *serial)
2693{ 2693{
2694 int i, j; 2694 int i, j;
2695 struct usb_serial_port *port; 2695 struct usb_serial_port *port;
@@ -2729,6 +2729,17 @@ static void keyspan_shutdown(struct usb_serial *serial)
2729 usb_free_urb(p_priv->out_urbs[j]); 2729 usb_free_urb(p_priv->out_urbs[j]);
2730 } 2730 }
2731 } 2731 }
2732}
2733
2734static void keyspan_release(struct usb_serial *serial)
2735{
2736 int i;
2737 struct usb_serial_port *port;
2738 struct keyspan_serial_private *s_priv;
2739
2740 dbg("%s", __func__);
2741
2742 s_priv = usb_get_serial_data(serial);
2732 2743
2733 /* dbg("Freeing serial->private."); */ 2744 /* dbg("Freeing serial->private."); */
2734 kfree(s_priv); 2745 kfree(s_priv);
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 0d4569b60768..3107ed15af64 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -41,7 +41,8 @@ static int keyspan_open (struct tty_struct *tty,
41static void keyspan_close (struct usb_serial_port *port); 41static void keyspan_close (struct usb_serial_port *port);
42static void keyspan_dtr_rts (struct usb_serial_port *port, int on); 42static void keyspan_dtr_rts (struct usb_serial_port *port, int on);
43static int keyspan_startup (struct usb_serial *serial); 43static int keyspan_startup (struct usb_serial *serial);
44static void keyspan_shutdown (struct usb_serial *serial); 44static void keyspan_disconnect (struct usb_serial *serial);
45static void keyspan_release (struct usb_serial *serial);
45static int keyspan_write_room (struct tty_struct *tty); 46static int keyspan_write_room (struct tty_struct *tty);
46 47
47static int keyspan_write (struct tty_struct *tty, 48static int keyspan_write (struct tty_struct *tty,
@@ -569,7 +570,8 @@ static struct usb_serial_driver keyspan_1port_device = {
569 .tiocmget = keyspan_tiocmget, 570 .tiocmget = keyspan_tiocmget,
570 .tiocmset = keyspan_tiocmset, 571 .tiocmset = keyspan_tiocmset,
571 .attach = keyspan_startup, 572 .attach = keyspan_startup,
572 .shutdown = keyspan_shutdown, 573 .disconnect = keyspan_disconnect,
574 .release = keyspan_release,
573}; 575};
574 576
575static struct usb_serial_driver keyspan_2port_device = { 577static struct usb_serial_driver keyspan_2port_device = {
@@ -590,7 +592,8 @@ static struct usb_serial_driver keyspan_2port_device = {
590 .tiocmget = keyspan_tiocmget, 592 .tiocmget = keyspan_tiocmget,
591 .tiocmset = keyspan_tiocmset, 593 .tiocmset = keyspan_tiocmset,
592 .attach = keyspan_startup, 594 .attach = keyspan_startup,
593 .shutdown = keyspan_shutdown, 595 .disconnect = keyspan_disconnect,
596 .release = keyspan_release,
594}; 597};
595 598
596static struct usb_serial_driver keyspan_4port_device = { 599static struct usb_serial_driver keyspan_4port_device = {
@@ -611,7 +614,8 @@ static struct usb_serial_driver keyspan_4port_device = {
611 .tiocmget = keyspan_tiocmget, 614 .tiocmget = keyspan_tiocmget,
612 .tiocmset = keyspan_tiocmset, 615 .tiocmset = keyspan_tiocmset,
613 .attach = keyspan_startup, 616 .attach = keyspan_startup,
614 .shutdown = keyspan_shutdown, 617 .disconnect = keyspan_disconnect,
618 .release = keyspan_release,
615}; 619};
616 620
617#endif 621#endif
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index ab769dbea1b3..d0b12e40c2b1 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -809,7 +809,7 @@ static int keyspan_pda_startup(struct usb_serial *serial)
809 return 0; 809 return 0;
810} 810}
811 811
812static void keyspan_pda_shutdown(struct usb_serial *serial) 812static void keyspan_pda_release(struct usb_serial *serial)
813{ 813{
814 dbg("%s", __func__); 814 dbg("%s", __func__);
815 815
@@ -869,7 +869,7 @@ static struct usb_serial_driver keyspan_pda_device = {
869 .tiocmget = keyspan_pda_tiocmget, 869 .tiocmget = keyspan_pda_tiocmget,
870 .tiocmset = keyspan_pda_tiocmset, 870 .tiocmset = keyspan_pda_tiocmset,
871 .attach = keyspan_pda_startup, 871 .attach = keyspan_pda_startup,
872 .shutdown = keyspan_pda_shutdown, 872 .release = keyspan_pda_release,
873}; 873};
874 874
875 875
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index fa817c66b3e8..0f44bb8e8d4f 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -73,7 +73,8 @@ static int debug;
73 * Function prototypes 73 * Function prototypes
74 */ 74 */
75static int klsi_105_startup(struct usb_serial *serial); 75static int klsi_105_startup(struct usb_serial *serial);
76static void klsi_105_shutdown(struct usb_serial *serial); 76static void klsi_105_disconnect(struct usb_serial *serial);
77static void klsi_105_release(struct usb_serial *serial);
77static int klsi_105_open(struct tty_struct *tty, 78static int klsi_105_open(struct tty_struct *tty,
78 struct usb_serial_port *port, struct file *filp); 79 struct usb_serial_port *port, struct file *filp);
79static void klsi_105_close(struct usb_serial_port *port); 80static void klsi_105_close(struct usb_serial_port *port);
@@ -131,7 +132,8 @@ static struct usb_serial_driver kl5kusb105d_device = {
131 .tiocmget = klsi_105_tiocmget, 132 .tiocmget = klsi_105_tiocmget,
132 .tiocmset = klsi_105_tiocmset, 133 .tiocmset = klsi_105_tiocmset,
133 .attach = klsi_105_startup, 134 .attach = klsi_105_startup,
134 .shutdown = klsi_105_shutdown, 135 .disconnect = klsi_105_disconnect,
136 .release = klsi_105_release,
135 .throttle = klsi_105_throttle, 137 .throttle = klsi_105_throttle,
136 .unthrottle = klsi_105_unthrottle, 138 .unthrottle = klsi_105_unthrottle,
137}; 139};
@@ -315,7 +317,7 @@ err_cleanup:
315} /* klsi_105_startup */ 317} /* klsi_105_startup */
316 318
317 319
318static void klsi_105_shutdown(struct usb_serial *serial) 320static void klsi_105_disconnect(struct usb_serial *serial)
319{ 321{
320 int i; 322 int i;
321 323
@@ -325,33 +327,36 @@ static void klsi_105_shutdown(struct usb_serial *serial)
325 for (i = 0; i < serial->num_ports; ++i) { 327 for (i = 0; i < serial->num_ports; ++i) {
326 struct klsi_105_private *priv = 328 struct klsi_105_private *priv =
327 usb_get_serial_port_data(serial->port[i]); 329 usb_get_serial_port_data(serial->port[i]);
328 unsigned long flags;
329 330
330 if (priv) { 331 if (priv) {
331 /* kill our write urb pool */ 332 /* kill our write urb pool */
332 int j; 333 int j;
333 struct urb **write_urbs = priv->write_urb_pool; 334 struct urb **write_urbs = priv->write_urb_pool;
334 spin_lock_irqsave(&priv->lock, flags);
335 335
336 for (j = 0; j < NUM_URBS; j++) { 336 for (j = 0; j < NUM_URBS; j++) {
337 if (write_urbs[j]) { 337 if (write_urbs[j]) {
338 /* FIXME - uncomment the following 338 usb_kill_urb(write_urbs[j]);
339 * usb_kill_urb call when the host
340 * controllers get fixed to set
341 * urb->dev = NULL after the urb is
342 * finished. Otherwise this call
343 * oopses. */
344 /* usb_kill_urb(write_urbs[j]); */
345 kfree(write_urbs[j]->transfer_buffer);
346 usb_free_urb(write_urbs[j]); 339 usb_free_urb(write_urbs[j]);
347 } 340 }
348 } 341 }
349 spin_unlock_irqrestore(&priv->lock, flags);
350 kfree(priv);
351 usb_set_serial_port_data(serial->port[i], NULL);
352 } 342 }
353 } 343 }
354} /* klsi_105_shutdown */ 344} /* klsi_105_disconnect */
345
346
347static void klsi_105_release(struct usb_serial *serial)
348{
349 int i;
350
351 dbg("%s", __func__);
352
353 for (i = 0; i < serial->num_ports; ++i) {
354 struct klsi_105_private *priv =
355 usb_get_serial_port_data(serial->port[i]);
356
357 kfree(priv);
358 }
359} /* klsi_105_release */
355 360
356static int klsi_105_open(struct tty_struct *tty, 361static int klsi_105_open(struct tty_struct *tty,
357 struct usb_serial_port *port, struct file *filp) 362 struct usb_serial_port *port, struct file *filp)
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 6b570498287f..6db0e561f680 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -69,7 +69,7 @@ static int debug;
69 69
70/* Function prototypes */ 70/* Function prototypes */
71static int kobil_startup(struct usb_serial *serial); 71static int kobil_startup(struct usb_serial *serial);
72static void kobil_shutdown(struct usb_serial *serial); 72static void kobil_release(struct usb_serial *serial);
73static int kobil_open(struct tty_struct *tty, 73static int kobil_open(struct tty_struct *tty,
74 struct usb_serial_port *port, struct file *filp); 74 struct usb_serial_port *port, struct file *filp);
75static void kobil_close(struct usb_serial_port *port); 75static void kobil_close(struct usb_serial_port *port);
@@ -117,7 +117,7 @@ static struct usb_serial_driver kobil_device = {
117 .id_table = id_table, 117 .id_table = id_table,
118 .num_ports = 1, 118 .num_ports = 1,
119 .attach = kobil_startup, 119 .attach = kobil_startup,
120 .shutdown = kobil_shutdown, 120 .release = kobil_release,
121 .ioctl = kobil_ioctl, 121 .ioctl = kobil_ioctl,
122 .set_termios = kobil_set_termios, 122 .set_termios = kobil_set_termios,
123 .tiocmget = kobil_tiocmget, 123 .tiocmget = kobil_tiocmget,
@@ -201,17 +201,13 @@ static int kobil_startup(struct usb_serial *serial)
201} 201}
202 202
203 203
204static void kobil_shutdown(struct usb_serial *serial) 204static void kobil_release(struct usb_serial *serial)
205{ 205{
206 int i; 206 int i;
207 dbg("%s - port %d", __func__, serial->port[0]->number); 207 dbg("%s - port %d", __func__, serial->port[0]->number);
208 208
209 for (i = 0; i < serial->num_ports; ++i) { 209 for (i = 0; i < serial->num_ports; ++i)
210 while (serial->port[i]->port.count > 0)
211 kobil_close(serial->port[i]);
212 kfree(usb_get_serial_port_data(serial->port[i])); 210 kfree(usb_get_serial_port_data(serial->port[i]));
213 usb_set_serial_port_data(serial->port[i], NULL);
214 }
215} 211}
216 212
217 213
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 873795548fc0..d8825e159aa5 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -92,7 +92,7 @@ static int debug;
92 * Function prototypes 92 * Function prototypes
93 */ 93 */
94static int mct_u232_startup(struct usb_serial *serial); 94static int mct_u232_startup(struct usb_serial *serial);
95static void mct_u232_shutdown(struct usb_serial *serial); 95static void mct_u232_release(struct usb_serial *serial);
96static int mct_u232_open(struct tty_struct *tty, 96static int mct_u232_open(struct tty_struct *tty,
97 struct usb_serial_port *port, struct file *filp); 97 struct usb_serial_port *port, struct file *filp);
98static void mct_u232_close(struct usb_serial_port *port); 98static void mct_u232_close(struct usb_serial_port *port);
@@ -149,7 +149,7 @@ static struct usb_serial_driver mct_u232_device = {
149 .tiocmget = mct_u232_tiocmget, 149 .tiocmget = mct_u232_tiocmget,
150 .tiocmset = mct_u232_tiocmset, 150 .tiocmset = mct_u232_tiocmset,
151 .attach = mct_u232_startup, 151 .attach = mct_u232_startup,
152 .shutdown = mct_u232_shutdown, 152 .release = mct_u232_release,
153}; 153};
154 154
155 155
@@ -407,7 +407,7 @@ static int mct_u232_startup(struct usb_serial *serial)
407} /* mct_u232_startup */ 407} /* mct_u232_startup */
408 408
409 409
410static void mct_u232_shutdown(struct usb_serial *serial) 410static void mct_u232_release(struct usb_serial *serial)
411{ 411{
412 struct mct_u232_private *priv; 412 struct mct_u232_private *priv;
413 int i; 413 int i;
@@ -417,12 +417,9 @@ static void mct_u232_shutdown(struct usb_serial *serial)
417 for (i = 0; i < serial->num_ports; ++i) { 417 for (i = 0; i < serial->num_ports; ++i) {
418 /* My special items, the standard routines free my urbs */ 418 /* My special items, the standard routines free my urbs */
419 priv = usb_get_serial_port_data(serial->port[i]); 419 priv = usb_get_serial_port_data(serial->port[i]);
420 if (priv) { 420 kfree(priv);
421 usb_set_serial_port_data(serial->port[i], NULL);
422 kfree(priv);
423 }
424 } 421 }
425} /* mct_u232_shutdown */ 422} /* mct_u232_release */
426 423
427static int mct_u232_open(struct tty_struct *tty, 424static int mct_u232_open(struct tty_struct *tty,
428 struct usb_serial_port *port, struct file *filp) 425 struct usb_serial_port *port, struct file *filp)
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 9e1a013ee7f6..bfc5ce000ef9 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -1521,19 +1521,16 @@ static int mos7720_startup(struct usb_serial *serial)
1521 return 0; 1521 return 0;
1522} 1522}
1523 1523
1524static void mos7720_shutdown(struct usb_serial *serial) 1524static void mos7720_release(struct usb_serial *serial)
1525{ 1525{
1526 int i; 1526 int i;
1527 1527
1528 /* free private structure allocated for serial port */ 1528 /* free private structure allocated for serial port */
1529 for (i = 0; i < serial->num_ports; ++i) { 1529 for (i = 0; i < serial->num_ports; ++i)
1530 kfree(usb_get_serial_port_data(serial->port[i])); 1530 kfree(usb_get_serial_port_data(serial->port[i]));
1531 usb_set_serial_port_data(serial->port[i], NULL);
1532 }
1533 1531
1534 /* free private structure allocated for serial device */ 1532 /* free private structure allocated for serial device */
1535 kfree(usb_get_serial_data(serial)); 1533 kfree(usb_get_serial_data(serial));
1536 usb_set_serial_data(serial, NULL);
1537} 1534}
1538 1535
1539static struct usb_driver usb_driver = { 1536static struct usb_driver usb_driver = {
@@ -1558,7 +1555,7 @@ static struct usb_serial_driver moschip7720_2port_driver = {
1558 .throttle = mos7720_throttle, 1555 .throttle = mos7720_throttle,
1559 .unthrottle = mos7720_unthrottle, 1556 .unthrottle = mos7720_unthrottle,
1560 .attach = mos7720_startup, 1557 .attach = mos7720_startup,
1561 .shutdown = mos7720_shutdown, 1558 .release = mos7720_release,
1562 .ioctl = mos7720_ioctl, 1559 .ioctl = mos7720_ioctl,
1563 .set_termios = mos7720_set_termios, 1560 .set_termios = mos7720_set_termios,
1564 .write = mos7720_write, 1561 .write = mos7720_write,
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 5fe9fe3df772..c40f95c1951c 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -2633,16 +2633,16 @@ error:
2633} 2633}
2634 2634
2635/**************************************************************************** 2635/****************************************************************************
2636 * mos7840_shutdown 2636 * mos7840_disconnect
2637 * This function is called whenever the device is removed from the usb bus. 2637 * This function is called whenever the device is removed from the usb bus.
2638 ****************************************************************************/ 2638 ****************************************************************************/
2639 2639
2640static void mos7840_shutdown(struct usb_serial *serial) 2640static void mos7840_disconnect(struct usb_serial *serial)
2641{ 2641{
2642 int i; 2642 int i;
2643 unsigned long flags; 2643 unsigned long flags;
2644 struct moschip_port *mos7840_port; 2644 struct moschip_port *mos7840_port;
2645 dbg("%s", " shutdown :entering.........."); 2645 dbg("%s", " disconnect :entering..........");
2646 2646
2647 if (!serial) { 2647 if (!serial) {
2648 dbg("%s", "Invalid Handler"); 2648 dbg("%s", "Invalid Handler");
@@ -2662,11 +2662,42 @@ static void mos7840_shutdown(struct usb_serial *serial)
2662 mos7840_port->zombie = 1; 2662 mos7840_port->zombie = 1;
2663 spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); 2663 spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
2664 usb_kill_urb(mos7840_port->control_urb); 2664 usb_kill_urb(mos7840_port->control_urb);
2665 }
2666 }
2667
2668 dbg("%s", "Thank u :: ");
2669
2670}
2671
2672/****************************************************************************
2673 * mos7840_release
2674 * This function is called when the usb_serial structure is freed.
2675 ****************************************************************************/
2676
2677static void mos7840_release(struct usb_serial *serial)
2678{
2679 int i;
2680 struct moschip_port *mos7840_port;
2681 dbg("%s", " release :entering..........");
2682
2683 if (!serial) {
2684 dbg("%s", "Invalid Handler");
2685 return;
2686 }
2687
2688 /* check for the ports to be closed,close the ports and disconnect */
2689
2690 /* free private structure allocated for serial port *
2691 * stop reads and writes on all ports */
2692
2693 for (i = 0; i < serial->num_ports; ++i) {
2694 mos7840_port = mos7840_get_port_private(serial->port[i]);
2695 dbg("mos7840_port %d = %p", i, mos7840_port);
2696 if (mos7840_port) {
2665 kfree(mos7840_port->ctrl_buf); 2697 kfree(mos7840_port->ctrl_buf);
2666 kfree(mos7840_port->dr); 2698 kfree(mos7840_port->dr);
2667 kfree(mos7840_port); 2699 kfree(mos7840_port);
2668 } 2700 }
2669 mos7840_set_port_private(serial->port[i], NULL);
2670 } 2701 }
2671 2702
2672 dbg("%s", "Thank u :: "); 2703 dbg("%s", "Thank u :: ");
@@ -2707,7 +2738,8 @@ static struct usb_serial_driver moschip7840_4port_device = {
2707 .tiocmget = mos7840_tiocmget, 2738 .tiocmget = mos7840_tiocmget,
2708 .tiocmset = mos7840_tiocmset, 2739 .tiocmset = mos7840_tiocmset,
2709 .attach = mos7840_startup, 2740 .attach = mos7840_startup,
2710 .shutdown = mos7840_shutdown, 2741 .disconnect = mos7840_disconnect,
2742 .release = mos7840_release,
2711 .read_bulk_callback = mos7840_bulk_in_callback, 2743 .read_bulk_callback = mos7840_bulk_in_callback,
2712 .read_int_callback = mos7840_interrupt_callback, 2744 .read_int_callback = mos7840_interrupt_callback,
2713}; 2745};
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 1104617334f5..56857ddbd70b 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -72,7 +72,8 @@ static void omninet_write_bulk_callback(struct urb *urb);
72static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, 72static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
73 const unsigned char *buf, int count); 73 const unsigned char *buf, int count);
74static int omninet_write_room(struct tty_struct *tty); 74static int omninet_write_room(struct tty_struct *tty);
75static void omninet_shutdown(struct usb_serial *serial); 75static void omninet_disconnect(struct usb_serial *serial);
76static void omninet_release(struct usb_serial *serial);
76static int omninet_attach(struct usb_serial *serial); 77static int omninet_attach(struct usb_serial *serial);
77 78
78static struct usb_device_id id_table[] = { 79static struct usb_device_id id_table[] = {
@@ -108,7 +109,8 @@ static struct usb_serial_driver zyxel_omninet_device = {
108 .write_room = omninet_write_room, 109 .write_room = omninet_write_room,
109 .read_bulk_callback = omninet_read_bulk_callback, 110 .read_bulk_callback = omninet_read_bulk_callback,
110 .write_bulk_callback = omninet_write_bulk_callback, 111 .write_bulk_callback = omninet_write_bulk_callback,
111 .shutdown = omninet_shutdown, 112 .disconnect = omninet_disconnect,
113 .release = omninet_release,
112}; 114};
113 115
114 116
@@ -345,13 +347,22 @@ static void omninet_write_bulk_callback(struct urb *urb)
345} 347}
346 348
347 349
348static void omninet_shutdown(struct usb_serial *serial) 350static void omninet_disconnect(struct usb_serial *serial)
349{ 351{
350 struct usb_serial_port *wport = serial->port[1]; 352 struct usb_serial_port *wport = serial->port[1];
351 struct usb_serial_port *port = serial->port[0]; 353
352 dbg("%s", __func__); 354 dbg("%s", __func__);
353 355
354 usb_kill_urb(wport->write_urb); 356 usb_kill_urb(wport->write_urb);
357}
358
359
360static void omninet_release(struct usb_serial *serial)
361{
362 struct usb_serial_port *port = serial->port[0];
363
364 dbg("%s", __func__);
365
355 kfree(usb_get_serial_port_data(port)); 366 kfree(usb_get_serial_port_data(port));
356} 367}
357 368
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index c20480aa9755..336bba79ad32 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -463,7 +463,7 @@ error:
463 return retval; 463 return retval;
464} 464}
465 465
466static void opticon_shutdown(struct usb_serial *serial) 466static void opticon_disconnect(struct usb_serial *serial)
467{ 467{
468 struct opticon_private *priv = usb_get_serial_data(serial); 468 struct opticon_private *priv = usb_get_serial_data(serial);
469 469
@@ -471,9 +471,16 @@ static void opticon_shutdown(struct usb_serial *serial)
471 471
472 usb_kill_urb(priv->bulk_read_urb); 472 usb_kill_urb(priv->bulk_read_urb);
473 usb_free_urb(priv->bulk_read_urb); 473 usb_free_urb(priv->bulk_read_urb);
474}
475
476static void opticon_release(struct usb_serial *serial)
477{
478 struct opticon_private *priv = usb_get_serial_data(serial);
479
480 dbg("%s", __func__);
481
474 kfree(priv->bulk_in_buffer); 482 kfree(priv->bulk_in_buffer);
475 kfree(priv); 483 kfree(priv);
476 usb_set_serial_data(serial, NULL);
477} 484}
478 485
479static int opticon_suspend(struct usb_interface *intf, pm_message_t message) 486static int opticon_suspend(struct usb_interface *intf, pm_message_t message)
@@ -524,7 +531,8 @@ static struct usb_serial_driver opticon_device = {
524 .close = opticon_close, 531 .close = opticon_close,
525 .write = opticon_write, 532 .write = opticon_write,
526 .write_room = opticon_write_room, 533 .write_room = opticon_write_room,
527 .shutdown = opticon_shutdown, 534 .disconnect = opticon_disconnect,
535 .release = opticon_release,
528 .throttle = opticon_throttle, 536 .throttle = opticon_throttle,
529 .unthrottle = opticon_unthrottle, 537 .unthrottle = opticon_unthrottle,
530 .ioctl = opticon_ioctl, 538 .ioctl = opticon_ioctl,
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index a38971cc3731..575816e6ba37 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -51,7 +51,8 @@ static void option_close(struct usb_serial_port *port);
51static void option_dtr_rts(struct usb_serial_port *port, int on); 51static void option_dtr_rts(struct usb_serial_port *port, int on);
52 52
53static int option_startup(struct usb_serial *serial); 53static int option_startup(struct usb_serial *serial);
54static void option_shutdown(struct usb_serial *serial); 54static void option_disconnect(struct usb_serial *serial);
55static void option_release(struct usb_serial *serial);
55static int option_write_room(struct tty_struct *tty); 56static int option_write_room(struct tty_struct *tty);
56 57
57static void option_instat_callback(struct urb *urb); 58static void option_instat_callback(struct urb *urb);
@@ -568,7 +569,8 @@ static struct usb_serial_driver option_1port_device = {
568 .tiocmget = option_tiocmget, 569 .tiocmget = option_tiocmget,
569 .tiocmset = option_tiocmset, 570 .tiocmset = option_tiocmset,
570 .attach = option_startup, 571 .attach = option_startup,
571 .shutdown = option_shutdown, 572 .disconnect = option_disconnect,
573 .release = option_release,
572 .read_int_callback = option_instat_callback, 574 .read_int_callback = option_instat_callback,
573 .suspend = option_suspend, 575 .suspend = option_suspend,
574 .resume = option_resume, 576 .resume = option_resume,
@@ -1149,7 +1151,14 @@ static void stop_read_write_urbs(struct usb_serial *serial)
1149 } 1151 }
1150} 1152}
1151 1153
1152static void option_shutdown(struct usb_serial *serial) 1154static void option_disconnect(struct usb_serial *serial)
1155{
1156 dbg("%s", __func__);
1157
1158 stop_read_write_urbs(serial);
1159}
1160
1161static void option_release(struct usb_serial *serial)
1153{ 1162{
1154 int i, j; 1163 int i, j;
1155 struct usb_serial_port *port; 1164 struct usb_serial_port *port;
@@ -1157,8 +1166,6 @@ static void option_shutdown(struct usb_serial *serial)
1157 1166
1158 dbg("%s", __func__); 1167 dbg("%s", __func__);
1159 1168
1160 stop_read_write_urbs(serial);
1161
1162 /* Now free them */ 1169 /* Now free them */
1163 for (i = 0; i < serial->num_ports; ++i) { 1170 for (i = 0; i < serial->num_ports; ++i) {
1164 port = serial->port[i]; 1171 port = serial->port[i];
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index 7de54781fe61..3cece27325e7 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -159,7 +159,7 @@ static int oti6858_tiocmget(struct tty_struct *tty, struct file *file);
159static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, 159static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
160 unsigned int set, unsigned int clear); 160 unsigned int set, unsigned int clear);
161static int oti6858_startup(struct usb_serial *serial); 161static int oti6858_startup(struct usb_serial *serial);
162static void oti6858_shutdown(struct usb_serial *serial); 162static void oti6858_release(struct usb_serial *serial);
163 163
164/* functions operating on buffers */ 164/* functions operating on buffers */
165static struct oti6858_buf *oti6858_buf_alloc(unsigned int size); 165static struct oti6858_buf *oti6858_buf_alloc(unsigned int size);
@@ -194,7 +194,7 @@ static struct usb_serial_driver oti6858_device = {
194 .write_room = oti6858_write_room, 194 .write_room = oti6858_write_room,
195 .chars_in_buffer = oti6858_chars_in_buffer, 195 .chars_in_buffer = oti6858_chars_in_buffer,
196 .attach = oti6858_startup, 196 .attach = oti6858_startup,
197 .shutdown = oti6858_shutdown, 197 .release = oti6858_release,
198}; 198};
199 199
200struct oti6858_private { 200struct oti6858_private {
@@ -782,7 +782,7 @@ static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
782} 782}
783 783
784 784
785static void oti6858_shutdown(struct usb_serial *serial) 785static void oti6858_release(struct usb_serial *serial)
786{ 786{
787 struct oti6858_private *priv; 787 struct oti6858_private *priv;
788 int i; 788 int i;
@@ -794,7 +794,6 @@ static void oti6858_shutdown(struct usb_serial *serial)
794 if (priv) { 794 if (priv) {
795 oti6858_buf_free(priv->buf); 795 oti6858_buf_free(priv->buf);
796 kfree(priv); 796 kfree(priv);
797 usb_set_serial_port_data(serial->port[i], NULL);
798 } 797 }
799 } 798 }
800} 799}
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 6357b57f628c..ec6c132a25b5 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -878,7 +878,7 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
878 dbg("%s - error sending break = %d", __func__, result); 878 dbg("%s - error sending break = %d", __func__, result);
879} 879}
880 880
881static void pl2303_shutdown(struct usb_serial *serial) 881static void pl2303_release(struct usb_serial *serial)
882{ 882{
883 int i; 883 int i;
884 struct pl2303_private *priv; 884 struct pl2303_private *priv;
@@ -890,7 +890,6 @@ static void pl2303_shutdown(struct usb_serial *serial)
890 if (priv) { 890 if (priv) {
891 pl2303_buf_free(priv->buf); 891 pl2303_buf_free(priv->buf);
892 kfree(priv); 892 kfree(priv);
893 usb_set_serial_port_data(serial->port[i], NULL);
894 } 893 }
895 } 894 }
896} 895}
@@ -1123,7 +1122,7 @@ static struct usb_serial_driver pl2303_device = {
1123 .write_room = pl2303_write_room, 1122 .write_room = pl2303_write_room,
1124 .chars_in_buffer = pl2303_chars_in_buffer, 1123 .chars_in_buffer = pl2303_chars_in_buffer,
1125 .attach = pl2303_startup, 1124 .attach = pl2303_startup,
1126 .shutdown = pl2303_shutdown, 1125 .release = pl2303_release,
1127}; 1126};
1128 1127
1129static int __init pl2303_init(void) 1128static int __init pl2303_init(void)
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index a88cde950161..032f7aeb40a4 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -814,7 +814,7 @@ static int sierra_startup(struct usb_serial *serial)
814 return 0; 814 return 0;
815} 815}
816 816
817static void sierra_shutdown(struct usb_serial *serial) 817static void sierra_disconnect(struct usb_serial *serial)
818{ 818{
819 int i; 819 int i;
820 struct usb_serial_port *port; 820 struct usb_serial_port *port;
@@ -853,7 +853,7 @@ static struct usb_serial_driver sierra_device = {
853 .tiocmget = sierra_tiocmget, 853 .tiocmget = sierra_tiocmget,
854 .tiocmset = sierra_tiocmset, 854 .tiocmset = sierra_tiocmset,
855 .attach = sierra_startup, 855 .attach = sierra_startup,
856 .shutdown = sierra_shutdown, 856 .disconnect = sierra_disconnect,
857 .read_int_callback = sierra_instat_callback, 857 .read_int_callback = sierra_instat_callback,
858}; 858};
859 859
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 8f7ed8f13996..3c249d8e8b8e 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -356,7 +356,7 @@ cleanup:
356} 356}
357 357
358/* call when the device plug out. free all the memory alloced by probe */ 358/* call when the device plug out. free all the memory alloced by probe */
359static void spcp8x5_shutdown(struct usb_serial *serial) 359static void spcp8x5_release(struct usb_serial *serial)
360{ 360{
361 int i; 361 int i;
362 struct spcp8x5_private *priv; 362 struct spcp8x5_private *priv;
@@ -366,7 +366,6 @@ static void spcp8x5_shutdown(struct usb_serial *serial)
366 if (priv) { 366 if (priv) {
367 free_ringbuf(priv->buf); 367 free_ringbuf(priv->buf);
368 kfree(priv); 368 kfree(priv);
369 usb_set_serial_port_data(serial->port[i] , NULL);
370 } 369 }
371 } 370 }
372} 371}
@@ -1020,7 +1019,7 @@ static struct usb_serial_driver spcp8x5_device = {
1020 .write_bulk_callback = spcp8x5_write_bulk_callback, 1019 .write_bulk_callback = spcp8x5_write_bulk_callback,
1021 .chars_in_buffer = spcp8x5_chars_in_buffer, 1020 .chars_in_buffer = spcp8x5_chars_in_buffer,
1022 .attach = spcp8x5_startup, 1021 .attach = spcp8x5_startup,
1023 .shutdown = spcp8x5_shutdown, 1022 .release = spcp8x5_release,
1024}; 1023};
1025 1024
1026static int __init spcp8x5_init(void) 1025static int __init spcp8x5_init(void)
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index 8b07ebc6baeb..6157fac9366b 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -267,7 +267,7 @@ error:
267 return retval; 267 return retval;
268} 268}
269 269
270static void symbol_shutdown(struct usb_serial *serial) 270static void symbol_disconnect(struct usb_serial *serial)
271{ 271{
272 struct symbol_private *priv = usb_get_serial_data(serial); 272 struct symbol_private *priv = usb_get_serial_data(serial);
273 273
@@ -275,9 +275,16 @@ static void symbol_shutdown(struct usb_serial *serial)
275 275
276 usb_kill_urb(priv->int_urb); 276 usb_kill_urb(priv->int_urb);
277 usb_free_urb(priv->int_urb); 277 usb_free_urb(priv->int_urb);
278}
279
280static void symbol_release(struct usb_serial *serial)
281{
282 struct symbol_private *priv = usb_get_serial_data(serial);
283
284 dbg("%s", __func__);
285
278 kfree(priv->int_buffer); 286 kfree(priv->int_buffer);
279 kfree(priv); 287 kfree(priv);
280 usb_set_serial_data(serial, NULL);
281} 288}
282 289
283static struct usb_driver symbol_driver = { 290static struct usb_driver symbol_driver = {
@@ -299,7 +306,8 @@ static struct usb_serial_driver symbol_device = {
299 .attach = symbol_startup, 306 .attach = symbol_startup,
300 .open = symbol_open, 307 .open = symbol_open,
301 .close = symbol_close, 308 .close = symbol_close,
302 .shutdown = symbol_shutdown, 309 .disconnect = symbol_disconnect,
310 .release = symbol_release,
303 .throttle = symbol_throttle, 311 .throttle = symbol_throttle,
304 .unthrottle = symbol_unthrottle, 312 .unthrottle = symbol_unthrottle,
305}; 313};
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 42cb04c403be..991d8232e376 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -97,7 +97,7 @@ struct ti_device {
97/* Function Declarations */ 97/* Function Declarations */
98 98
99static int ti_startup(struct usb_serial *serial); 99static int ti_startup(struct usb_serial *serial);
100static void ti_shutdown(struct usb_serial *serial); 100static void ti_release(struct usb_serial *serial);
101static int ti_open(struct tty_struct *tty, struct usb_serial_port *port, 101static int ti_open(struct tty_struct *tty, struct usb_serial_port *port,
102 struct file *file); 102 struct file *file);
103static void ti_close(struct usb_serial_port *port); 103static void ti_close(struct usb_serial_port *port);
@@ -230,7 +230,7 @@ static struct usb_serial_driver ti_1port_device = {
230 .id_table = ti_id_table_3410, 230 .id_table = ti_id_table_3410,
231 .num_ports = 1, 231 .num_ports = 1,
232 .attach = ti_startup, 232 .attach = ti_startup,
233 .shutdown = ti_shutdown, 233 .release = ti_release,
234 .open = ti_open, 234 .open = ti_open,
235 .close = ti_close, 235 .close = ti_close,
236 .write = ti_write, 236 .write = ti_write,
@@ -258,7 +258,7 @@ static struct usb_serial_driver ti_2port_device = {
258 .id_table = ti_id_table_5052, 258 .id_table = ti_id_table_5052,
259 .num_ports = 2, 259 .num_ports = 2,
260 .attach = ti_startup, 260 .attach = ti_startup,
261 .shutdown = ti_shutdown, 261 .release = ti_release,
262 .open = ti_open, 262 .open = ti_open,
263 .close = ti_close, 263 .close = ti_close,
264 .write = ti_write, 264 .write = ti_write,
@@ -473,7 +473,7 @@ free_tdev:
473} 473}
474 474
475 475
476static void ti_shutdown(struct usb_serial *serial) 476static void ti_release(struct usb_serial *serial)
477{ 477{
478 int i; 478 int i;
479 struct ti_device *tdev = usb_get_serial_data(serial); 479 struct ti_device *tdev = usb_get_serial_data(serial);
@@ -486,12 +486,10 @@ static void ti_shutdown(struct usb_serial *serial)
486 if (tport) { 486 if (tport) {
487 ti_buf_free(tport->tp_write_buf); 487 ti_buf_free(tport->tp_write_buf);
488 kfree(tport); 488 kfree(tport);
489 usb_set_serial_port_data(serial->port[i], NULL);
490 } 489 }
491 } 490 }
492 491
493 kfree(tdev); 492 kfree(tdev);
494 usb_set_serial_data(serial, NULL);
495} 493}
496 494
497 495
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index da890f030fac..d595aa5586a7 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -141,6 +141,14 @@ static void destroy_serial(struct kref *kref)
141 if (serial->minor != SERIAL_TTY_NO_MINOR) 141 if (serial->minor != SERIAL_TTY_NO_MINOR)
142 return_serial(serial); 142 return_serial(serial);
143 143
144 serial->type->release(serial);
145
146 for (i = 0; i < serial->num_ports; ++i) {
147 port = serial->port[i];
148 if (port)
149 put_device(&port->dev);
150 }
151
144 /* If this is a "fake" port, we have to clean it up here, as it will 152 /* If this is a "fake" port, we have to clean it up here, as it will
145 * not get cleaned up in port_release() as it was never registered with 153 * not get cleaned up in port_release() as it was never registered with
146 * the driver core */ 154 * the driver core */
@@ -148,9 +156,8 @@ static void destroy_serial(struct kref *kref)
148 for (i = serial->num_ports; 156 for (i = serial->num_ports;
149 i < serial->num_port_pointers; ++i) { 157 i < serial->num_port_pointers; ++i) {
150 port = serial->port[i]; 158 port = serial->port[i];
151 if (!port) 159 if (port)
152 continue; 160 port_free(port);
153 port_free(port);
154 } 161 }
155 } 162 }
156 163
@@ -1118,10 +1125,6 @@ void usb_serial_disconnect(struct usb_interface *interface)
1118 serial->disconnected = 1; 1125 serial->disconnected = 1;
1119 mutex_unlock(&serial->disc_mutex); 1126 mutex_unlock(&serial->disc_mutex);
1120 1127
1121 /* Unfortunately, many of the sub-drivers expect the port structures
1122 * to exist when their shutdown method is called, so we have to go
1123 * through this awkward two-step unregistration procedure.
1124 */
1125 for (i = 0; i < serial->num_ports; ++i) { 1128 for (i = 0; i < serial->num_ports; ++i) {
1126 port = serial->port[i]; 1129 port = serial->port[i];
1127 if (port) { 1130 if (port) {
@@ -1153,14 +1156,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
1153 } 1156 }
1154 } 1157 }
1155 } 1158 }
1156 serial->type->shutdown(serial); 1159 serial->type->disconnect(serial);
1157 for (i = 0; i < serial->num_ports; ++i) {
1158 port = serial->port[i];
1159 if (port) {
1160 put_device(&port->dev);
1161 serial->port[i] = NULL;
1162 }
1163 }
1164 1160
1165 /* let the last holder of this object 1161 /* let the last holder of this object
1166 * cause it to be cleaned up */ 1162 * cause it to be cleaned up */
@@ -1338,7 +1334,8 @@ static void fixup_generic(struct usb_serial_driver *device)
1338 set_to_generic_if_null(device, chars_in_buffer); 1334 set_to_generic_if_null(device, chars_in_buffer);
1339 set_to_generic_if_null(device, read_bulk_callback); 1335 set_to_generic_if_null(device, read_bulk_callback);
1340 set_to_generic_if_null(device, write_bulk_callback); 1336 set_to_generic_if_null(device, write_bulk_callback);
1341 set_to_generic_if_null(device, shutdown); 1337 set_to_generic_if_null(device, disconnect);
1338 set_to_generic_if_null(device, release);
1342} 1339}
1343 1340
1344int usb_serial_register(struct usb_serial_driver *driver) 1341int usb_serial_register(struct usb_serial_driver *driver)
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index b15f1c0e1d4a..f5d0f64dcc52 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -47,7 +47,7 @@ static void visor_unthrottle(struct tty_struct *tty);
47static int visor_probe(struct usb_serial *serial, 47static int visor_probe(struct usb_serial *serial,
48 const struct usb_device_id *id); 48 const struct usb_device_id *id);
49static int visor_calc_num_ports(struct usb_serial *serial); 49static int visor_calc_num_ports(struct usb_serial *serial);
50static void visor_shutdown(struct usb_serial *serial); 50static void visor_release(struct usb_serial *serial);
51static void visor_write_bulk_callback(struct urb *urb); 51static void visor_write_bulk_callback(struct urb *urb);
52static void visor_read_bulk_callback(struct urb *urb); 52static void visor_read_bulk_callback(struct urb *urb);
53static void visor_read_int_callback(struct urb *urb); 53static void visor_read_int_callback(struct urb *urb);
@@ -202,7 +202,7 @@ static struct usb_serial_driver handspring_device = {
202 .attach = treo_attach, 202 .attach = treo_attach,
203 .probe = visor_probe, 203 .probe = visor_probe,
204 .calc_num_ports = visor_calc_num_ports, 204 .calc_num_ports = visor_calc_num_ports,
205 .shutdown = visor_shutdown, 205 .release = visor_release,
206 .write = visor_write, 206 .write = visor_write,
207 .write_room = visor_write_room, 207 .write_room = visor_write_room,
208 .write_bulk_callback = visor_write_bulk_callback, 208 .write_bulk_callback = visor_write_bulk_callback,
@@ -227,7 +227,7 @@ static struct usb_serial_driver clie_5_device = {
227 .attach = clie_5_attach, 227 .attach = clie_5_attach,
228 .probe = visor_probe, 228 .probe = visor_probe,
229 .calc_num_ports = visor_calc_num_ports, 229 .calc_num_ports = visor_calc_num_ports,
230 .shutdown = visor_shutdown, 230 .release = visor_release,
231 .write = visor_write, 231 .write = visor_write,
232 .write_room = visor_write_room, 232 .write_room = visor_write_room,
233 .write_bulk_callback = visor_write_bulk_callback, 233 .write_bulk_callback = visor_write_bulk_callback,
@@ -918,7 +918,7 @@ static int clie_5_attach(struct usb_serial *serial)
918 return generic_startup(serial); 918 return generic_startup(serial);
919} 919}
920 920
921static void visor_shutdown(struct usb_serial *serial) 921static void visor_release(struct usb_serial *serial)
922{ 922{
923 struct visor_private *priv; 923 struct visor_private *priv;
924 int i; 924 int i;
@@ -927,10 +927,7 @@ static void visor_shutdown(struct usb_serial *serial)
927 927
928 for (i = 0; i < serial->num_ports; i++) { 928 for (i = 0; i < serial->num_ports; i++) {
929 priv = usb_get_serial_port_data(serial->port[i]); 929 priv = usb_get_serial_port_data(serial->port[i]);
930 if (priv) { 930 kfree(priv);
931 usb_set_serial_port_data(serial->port[i], NULL);
932 kfree(priv);
933 }
934 } 931 }
935} 932}
936 933
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 7c7295d09f34..8d126dd7a02e 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -144,7 +144,7 @@ static int whiteheat_firmware_attach(struct usb_serial *serial);
144 144
145/* function prototypes for the Connect Tech WhiteHEAT serial converter */ 145/* function prototypes for the Connect Tech WhiteHEAT serial converter */
146static int whiteheat_attach(struct usb_serial *serial); 146static int whiteheat_attach(struct usb_serial *serial);
147static void whiteheat_shutdown(struct usb_serial *serial); 147static void whiteheat_release(struct usb_serial *serial);
148static int whiteheat_open(struct tty_struct *tty, 148static int whiteheat_open(struct tty_struct *tty,
149 struct usb_serial_port *port, struct file *filp); 149 struct usb_serial_port *port, struct file *filp);
150static void whiteheat_close(struct usb_serial_port *port); 150static void whiteheat_close(struct usb_serial_port *port);
@@ -189,7 +189,7 @@ static struct usb_serial_driver whiteheat_device = {
189 .id_table = id_table_std, 189 .id_table = id_table_std,
190 .num_ports = 4, 190 .num_ports = 4,
191 .attach = whiteheat_attach, 191 .attach = whiteheat_attach,
192 .shutdown = whiteheat_shutdown, 192 .release = whiteheat_release,
193 .open = whiteheat_open, 193 .open = whiteheat_open,
194 .close = whiteheat_close, 194 .close = whiteheat_close,
195 .write = whiteheat_write, 195 .write = whiteheat_write,
@@ -617,7 +617,7 @@ no_command_buffer:
617} 617}
618 618
619 619
620static void whiteheat_shutdown(struct usb_serial *serial) 620static void whiteheat_release(struct usb_serial *serial)
621{ 621{
622 struct usb_serial_port *command_port; 622 struct usb_serial_port *command_port;
623 struct usb_serial_port *port; 623 struct usb_serial_port *port;
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index ed4aa0fa7ed8..44801d26a37a 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -194,8 +194,10 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data)
194 * This will be called when the struct usb_serial structure is fully set 194 * This will be called when the struct usb_serial structure is fully set
195 * set up. Do any local initialization of the device, or any private 195 * set up. Do any local initialization of the device, or any private
196 * memory structure allocation at this point in time. 196 * memory structure allocation at this point in time.
197 * @shutdown: pointer to the driver's shutdown function. This will be 197 * @disconnect: pointer to the driver's disconnect function. This will be
198 * called when the device is removed from the system. 198 * called when the device is unplugged or unbound from the driver.
199 * @release: pointer to the driver's release function. This will be called
200 * when the usb_serial data structure is about to be destroyed.
199 * @usb_driver: pointer to the struct usb_driver that controls this 201 * @usb_driver: pointer to the struct usb_driver that controls this
200 * device. This is necessary to allow dynamic ids to be added to 202 * device. This is necessary to allow dynamic ids to be added to
201 * the driver from sysfs. 203 * the driver from sysfs.
@@ -226,7 +228,8 @@ struct usb_serial_driver {
226 int (*attach)(struct usb_serial *serial); 228 int (*attach)(struct usb_serial *serial);
227 int (*calc_num_ports) (struct usb_serial *serial); 229 int (*calc_num_ports) (struct usb_serial *serial);
228 230
229 void (*shutdown)(struct usb_serial *serial); 231 void (*disconnect)(struct usb_serial *serial);
232 void (*release)(struct usb_serial *serial);
230 233
231 int (*port_probe)(struct usb_serial_port *port); 234 int (*port_probe)(struct usb_serial_port *port);
232 int (*port_remove)(struct usb_serial_port *port); 235 int (*port_remove)(struct usb_serial_port *port);
@@ -308,7 +311,8 @@ extern void usb_serial_generic_read_bulk_callback(struct urb *urb);
308extern void usb_serial_generic_write_bulk_callback(struct urb *urb); 311extern void usb_serial_generic_write_bulk_callback(struct urb *urb);
309extern void usb_serial_generic_throttle(struct tty_struct *tty); 312extern void usb_serial_generic_throttle(struct tty_struct *tty);
310extern void usb_serial_generic_unthrottle(struct tty_struct *tty); 313extern void usb_serial_generic_unthrottle(struct tty_struct *tty);
311extern void usb_serial_generic_shutdown(struct usb_serial *serial); 314extern void usb_serial_generic_disconnect(struct usb_serial *serial);
315extern void usb_serial_generic_release(struct usb_serial *serial);
312extern int usb_serial_generic_register(int debug); 316extern int usb_serial_generic_register(int debug);
313extern void usb_serial_generic_deregister(void); 317extern void usb_serial_generic_deregister(void);
314extern void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, 318extern void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port,