aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2013-10-09 11:01:11 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-11 20:00:26 -0400
commit818f60365a29ab1266d92c6a91094fbf93465ff8 (patch)
treeab684c393c0c268fd556179d405de1cc982093fa /drivers/usb/serial
parent92ad247995c587e07cb67dcc8aafac4db636e394 (diff)
USB: serial: add memory flags to usb_serial_generic_write_start
Add memory-flags parameter to usb_serial_generic_write_start which is called from write, resume and completion handler, all with different allocation requirements. Note that by using the memory flag to determine when called from the completion handler, everything will work as before even if the completion handler is run with interrupts enabled (as suggested). Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/generic.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index fce374657ea2..31f78290c0e4 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -123,12 +123,14 @@ int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port,
123/** 123/**
124 * usb_serial_generic_write_start - start writing buffered data 124 * usb_serial_generic_write_start - start writing buffered data
125 * @port: usb-serial port 125 * @port: usb-serial port
126 * @mem_flags: flags to use for memory allocations
126 * 127 *
127 * Serialised using USB_SERIAL_WRITE_BUSY flag. 128 * Serialised using USB_SERIAL_WRITE_BUSY flag.
128 * 129 *
129 * Return: Zero on success or if busy, otherwise a negative errno value. 130 * Return: Zero on success or if busy, otherwise a negative errno value.
130 */ 131 */
131static int usb_serial_generic_write_start(struct usb_serial_port *port) 132static int usb_serial_generic_write_start(struct usb_serial_port *port,
133 gfp_t mem_flags)
132{ 134{
133 struct urb *urb; 135 struct urb *urb;
134 int count, result; 136 int count, result;
@@ -159,7 +161,7 @@ retry:
159 spin_unlock_irqrestore(&port->lock, flags); 161 spin_unlock_irqrestore(&port->lock, flags);
160 162
161 clear_bit(i, &port->write_urbs_free); 163 clear_bit(i, &port->write_urbs_free);
162 result = usb_submit_urb(urb, GFP_ATOMIC); 164 result = usb_submit_urb(urb, mem_flags);
163 if (result) { 165 if (result) {
164 dev_err_console(port, "%s - error submitting urb: %d\n", 166 dev_err_console(port, "%s - error submitting urb: %d\n",
165 __func__, result); 167 __func__, result);
@@ -172,10 +174,10 @@ retry:
172 return result; 174 return result;
173 } 175 }
174 /* 176 /*
175 * Try sending off another urb, unless in irq context (in which case 177 * Try sending off another urb, unless called from completion handler
176 * there will be no free urb). 178 * (in which case there will be no free urb or no data).
177 */ 179 */
178 if (!in_irq()) 180 if (mem_flags != GFP_ATOMIC)
179 goto retry; 181 goto retry;
180 182
181 clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); 183 clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags);
@@ -205,7 +207,7 @@ int usb_serial_generic_write(struct tty_struct *tty,
205 return 0; 207 return 0;
206 208
207 count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); 209 count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock);
208 result = usb_serial_generic_write_start(port); 210 result = usb_serial_generic_write_start(port, GFP_KERNEL);
209 if (result) 211 if (result)
210 return result; 212 return result;
211 213
@@ -409,7 +411,7 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
409 kfifo_reset_out(&port->write_fifo); 411 kfifo_reset_out(&port->write_fifo);
410 spin_unlock_irqrestore(&port->lock, flags); 412 spin_unlock_irqrestore(&port->lock, flags);
411 } else { 413 } else {
412 usb_serial_generic_write_start(port); 414 usb_serial_generic_write_start(port, GFP_ATOMIC);
413 } 415 }
414 416
415 usb_serial_port_softint(port); 417 usb_serial_port_softint(port);
@@ -598,7 +600,7 @@ int usb_serial_generic_resume(struct usb_serial *serial)
598 } 600 }
599 601
600 if (port->bulk_out_size) { 602 if (port->bulk_out_size) {
601 r = usb_serial_generic_write_start(port); 603 r = usb_serial_generic_write_start(port, GFP_NOIO);
602 if (r < 0) 604 if (r < 0)
603 c++; 605 c++;
604 } 606 }