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/cypress_m8.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/cypress_m8.c')
-rw-r--r-- | drivers/usb/serial/cypress_m8.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index e0a8b715f2f2..a591ebec0f89 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1155,13 +1155,12 @@ static void cypress_throttle(struct tty_struct *tty) | |||
1155 | { | 1155 | { |
1156 | struct usb_serial_port *port = tty->driver_data; | 1156 | struct usb_serial_port *port = tty->driver_data; |
1157 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1157 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1158 | unsigned long flags; | ||
1159 | 1158 | ||
1160 | dbg("%s - port %d", __func__, port->number); | 1159 | dbg("%s - port %d", __func__, port->number); |
1161 | 1160 | ||
1162 | spin_lock_irqsave(&priv->lock, flags); | 1161 | spin_lock_irq(&priv->lock); |
1163 | priv->rx_flags = THROTTLED; | 1162 | priv->rx_flags = THROTTLED; |
1164 | spin_unlock_irqrestore(&priv->lock, flags); | 1163 | spin_unlock_irq(&priv->lock); |
1165 | } | 1164 | } |
1166 | 1165 | ||
1167 | 1166 | ||
@@ -1170,14 +1169,13 @@ static void cypress_unthrottle(struct tty_struct *tty) | |||
1170 | struct usb_serial_port *port = tty->driver_data; | 1169 | struct usb_serial_port *port = tty->driver_data; |
1171 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1170 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1172 | int actually_throttled, result; | 1171 | int actually_throttled, result; |
1173 | unsigned long flags; | ||
1174 | 1172 | ||
1175 | dbg("%s - port %d", __func__, port->number); | 1173 | dbg("%s - port %d", __func__, port->number); |
1176 | 1174 | ||
1177 | spin_lock_irqsave(&priv->lock, flags); | 1175 | spin_lock_irq(&priv->lock); |
1178 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; | 1176 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; |
1179 | priv->rx_flags = 0; | 1177 | priv->rx_flags = 0; |
1180 | spin_unlock_irqrestore(&priv->lock, flags); | 1178 | spin_unlock_irq(&priv->lock); |
1181 | 1179 | ||
1182 | if (!priv->comm_is_ok) | 1180 | if (!priv->comm_is_ok) |
1183 | return; | 1181 | return; |
@@ -1185,7 +1183,7 @@ static void cypress_unthrottle(struct tty_struct *tty) | |||
1185 | if (actually_throttled) { | 1183 | if (actually_throttled) { |
1186 | port->interrupt_in_urb->dev = port->serial->dev; | 1184 | port->interrupt_in_urb->dev = port->serial->dev; |
1187 | 1185 | ||
1188 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 1186 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
1189 | if (result) { | 1187 | if (result) { |
1190 | dev_err(&port->dev, "%s - failed submitting read urb, " | 1188 | dev_err(&port->dev, "%s - failed submitting read urb, " |
1191 | "error %d\n", __func__, result); | 1189 | "error %d\n", __func__, result); |