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/symbolserial.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/symbolserial.c')
-rw-r--r-- | drivers/usb/serial/symbolserial.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index f25e54526843..b282c0f2d8e5 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c | |||
@@ -165,33 +165,31 @@ static void symbol_throttle(struct tty_struct *tty) | |||
165 | { | 165 | { |
166 | struct usb_serial_port *port = tty->driver_data; | 166 | struct usb_serial_port *port = tty->driver_data; |
167 | struct symbol_private *priv = usb_get_serial_data(port->serial); | 167 | struct symbol_private *priv = usb_get_serial_data(port->serial); |
168 | unsigned long flags; | ||
169 | 168 | ||
170 | dbg("%s - port %d", __func__, port->number); | 169 | dbg("%s - port %d", __func__, port->number); |
171 | spin_lock_irqsave(&priv->lock, flags); | 170 | spin_lock_irq(&priv->lock); |
172 | priv->throttled = true; | 171 | priv->throttled = true; |
173 | spin_unlock_irqrestore(&priv->lock, flags); | 172 | spin_unlock_irq(&priv->lock); |
174 | } | 173 | } |
175 | 174 | ||
176 | static void symbol_unthrottle(struct tty_struct *tty) | 175 | static void symbol_unthrottle(struct tty_struct *tty) |
177 | { | 176 | { |
178 | struct usb_serial_port *port = tty->driver_data; | 177 | struct usb_serial_port *port = tty->driver_data; |
179 | struct symbol_private *priv = usb_get_serial_data(port->serial); | 178 | struct symbol_private *priv = usb_get_serial_data(port->serial); |
180 | unsigned long flags; | ||
181 | int result; | 179 | int result; |
182 | bool was_throttled; | 180 | bool was_throttled; |
183 | 181 | ||
184 | dbg("%s - port %d", __func__, port->number); | 182 | dbg("%s - port %d", __func__, port->number); |
185 | 183 | ||
186 | spin_lock_irqsave(&priv->lock, flags); | 184 | spin_lock_irq(&priv->lock); |
187 | priv->throttled = false; | 185 | priv->throttled = false; |
188 | was_throttled = priv->actually_throttled; | 186 | was_throttled = priv->actually_throttled; |
189 | priv->actually_throttled = false; | 187 | priv->actually_throttled = false; |
190 | spin_unlock_irqrestore(&priv->lock, flags); | 188 | spin_unlock_irq(&priv->lock); |
191 | 189 | ||
192 | priv->int_urb->dev = port->serial->dev; | 190 | priv->int_urb->dev = port->serial->dev; |
193 | if (was_throttled) { | 191 | if (was_throttled) { |
194 | result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); | 192 | result = usb_submit_urb(priv->int_urb, GFP_KERNEL); |
195 | if (result) | 193 | if (result) |
196 | dev_err(&port->dev, | 194 | dev_err(&port->dev, |
197 | "%s - failed submitting read urb, error %d\n", | 195 | "%s - failed submitting read urb, error %d\n", |