diff options
author | Oliver Neukum <oneukum@suse.de> | 2007-03-20 08:41:21 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-04-27 16:28:37 -0400 |
commit | 7d28e74b97c8eb859fd9f5eb018bb1c75627bd55 (patch) | |
tree | 4c574a625a044bf3d6dc1ebd7cbacbb4a1f0732f /drivers/usb | |
parent | 4f93b3e8212df43ff380e118aebb68f6d1e5b060 (diff) |
USB: option close race
the option driver does not directly use usb_kill_urb(). It uses a wrapper.
This wrapper means that callbacks which are running are not killed during
close, resubmitting and illicitly pushing data into the tty layer.
The whole purpose of usb_kill_urb() is subverted. The wrapper must be removed.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Matthias Urlichs <smurf@smurf.noris.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/option.c | 14 |
1 files changed, 4 insertions, 10 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e178e6f40319..2846656d8358 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -591,12 +591,6 @@ static int option_open(struct usb_serial_port *port, struct file *filp) | |||
591 | return (0); | 591 | return (0); |
592 | } | 592 | } |
593 | 593 | ||
594 | static inline void stop_urb(struct urb *urb) | ||
595 | { | ||
596 | if (urb && urb->status == -EINPROGRESS) | ||
597 | usb_kill_urb(urb); | ||
598 | } | ||
599 | |||
600 | static void option_close(struct usb_serial_port *port, struct file *filp) | 594 | static void option_close(struct usb_serial_port *port, struct file *filp) |
601 | { | 595 | { |
602 | int i; | 596 | int i; |
@@ -614,9 +608,9 @@ static void option_close(struct usb_serial_port *port, struct file *filp) | |||
614 | 608 | ||
615 | /* Stop reading/writing urbs */ | 609 | /* Stop reading/writing urbs */ |
616 | for (i = 0; i < N_IN_URB; i++) | 610 | for (i = 0; i < N_IN_URB; i++) |
617 | stop_urb(portdata->in_urbs[i]); | 611 | usb_kill_urb(portdata->in_urbs[i]); |
618 | for (i = 0; i < N_OUT_URB; i++) | 612 | for (i = 0; i < N_OUT_URB; i++) |
619 | stop_urb(portdata->out_urbs[i]); | 613 | usb_kill_urb(portdata->out_urbs[i]); |
620 | } | 614 | } |
621 | port->tty = NULL; | 615 | port->tty = NULL; |
622 | } | 616 | } |
@@ -747,9 +741,9 @@ static void option_shutdown(struct usb_serial *serial) | |||
747 | port = serial->port[i]; | 741 | port = serial->port[i]; |
748 | portdata = usb_get_serial_port_data(port); | 742 | portdata = usb_get_serial_port_data(port); |
749 | for (j = 0; j < N_IN_URB; j++) | 743 | for (j = 0; j < N_IN_URB; j++) |
750 | stop_urb(portdata->in_urbs[j]); | 744 | usb_kill_urb(portdata->in_urbs[j]); |
751 | for (j = 0; j < N_OUT_URB; j++) | 745 | for (j = 0; j < N_OUT_URB; j++) |
752 | stop_urb(portdata->out_urbs[j]); | 746 | usb_kill_urb(portdata->out_urbs[j]); |
753 | } | 747 | } |
754 | 748 | ||
755 | /* Now free them */ | 749 | /* Now free them */ |