diff options
author | Oliver Neukum <oliver@neukum.org> | 2009-10-07 04:50:23 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-10-09 16:52:09 -0400 |
commit | 638325154572ba2113a18669fe3b299caa2dabd9 (patch) | |
tree | c562a8460be432facbbba11288edaceba5ecbf1c /drivers/usb/serial/whiteheat.c | |
parent | b2a5cf1bdc011f5474c72543f9d8116c0f07f452 (diff) |
USB: serial: fix assumption that throttle/unthrottle cannot sleep
many serial subdrivers are clearly written as if throttle/unthrottle
cannot sleep. This leads to unneeded atomic submissions. This
patch converts affected drivers in a way to makes very clear that
throttle/unthrottle can sleep. Thus future misdesigns can be avoided
and efficiency and reliability improved.
This removes any such assumption using GFP_KERNEL and spin_lock_irq()
Signed-off-by: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/whiteheat.c')
-rw-r--r-- | drivers/usb/serial/whiteheat.c | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 62424eec33ec..1093d2eb046a 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -949,13 +949,12 @@ static void whiteheat_throttle(struct tty_struct *tty) | |||
949 | { | 949 | { |
950 | struct usb_serial_port *port = tty->driver_data; | 950 | struct usb_serial_port *port = tty->driver_data; |
951 | struct whiteheat_private *info = usb_get_serial_port_data(port); | 951 | struct whiteheat_private *info = usb_get_serial_port_data(port); |
952 | unsigned long flags; | ||
953 | 952 | ||
954 | dbg("%s - port %d", __func__, port->number); | 953 | dbg("%s - port %d", __func__, port->number); |
955 | 954 | ||
956 | spin_lock_irqsave(&info->lock, flags); | 955 | spin_lock_irq(&info->lock); |
957 | info->flags |= THROTTLED; | 956 | info->flags |= THROTTLED; |
958 | spin_unlock_irqrestore(&info->lock, flags); | 957 | spin_unlock_irq(&info->lock); |
959 | 958 | ||
960 | return; | 959 | return; |
961 | } | 960 | } |
@@ -966,14 +965,13 @@ static void whiteheat_unthrottle(struct tty_struct *tty) | |||
966 | struct usb_serial_port *port = tty->driver_data; | 965 | struct usb_serial_port *port = tty->driver_data; |
967 | struct whiteheat_private *info = usb_get_serial_port_data(port); | 966 | struct whiteheat_private *info = usb_get_serial_port_data(port); |
968 | int actually_throttled; | 967 | int actually_throttled; |
969 | unsigned long flags; | ||
970 | 968 | ||
971 | dbg("%s - port %d", __func__, port->number); | 969 | dbg("%s - port %d", __func__, port->number); |
972 | 970 | ||
973 | spin_lock_irqsave(&info->lock, flags); | 971 | spin_lock_irq(&info->lock); |
974 | actually_throttled = info->flags & ACTUALLY_THROTTLED; | 972 | actually_throttled = info->flags & ACTUALLY_THROTTLED; |
975 | info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | 973 | info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED); |
976 | spin_unlock_irqrestore(&info->lock, flags); | 974 | spin_unlock_irq(&info->lock); |
977 | 975 | ||
978 | if (actually_throttled) | 976 | if (actually_throttled) |
979 | rx_data_softint(&info->rx_work); | 977 | rx_data_softint(&info->rx_work); |