aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/io_ti.c
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 /drivers/usb/serial/io_ti.c
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>
Diffstat (limited to 'drivers/usb/serial/io_ti.c')
-rw-r--r--drivers/usb/serial/io_ti.c22
1 files changed, 17 insertions, 5 deletions
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,