# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.548 -> 1.549 # drivers/usb/serial/ipaq.c 1.5 -> 1.6 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/03/19 ganesh@tuxtop.vxindia.veritas.com 1.549 # USB ipaq driver # # Don't submit urbs while holding spinlocks. Not strictly required in # 2.5.x, but it's always better to do less while holding a spinlock. # Also a good idea to keep 2.{4,5}.x drivers in sync. # -------------------------------------------- # diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c Wed Apr 3 16:40:02 2002 +++ b/drivers/usb/serial/ipaq.c Wed Apr 3 16:40:02 2002 @@ -9,6 +9,10 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * + * (19/3/2002) ganesh + * Don't submit urbs while holding spinlocks. Not strictly necessary + * in 2.5.x. + * * (8/3/2002) ganesh * The ipaq sometimes emits a '\0' before the CLIENT string. At this * point of time, the ppp ldisc is not yet attached to the tty, so @@ -65,7 +69,7 @@ int count); static int ipaq_write_bulk(struct usb_serial_port *port, int from_user, const unsigned char *buf, int count); -static int ipaq_write_flush(struct usb_serial_port *port); +static void ipaq_write_gather(struct usb_serial_port *port); static void ipaq_read_bulk_callback (struct urb *urb); static void ipaq_write_bulk_callback(struct urb *urb); static int ipaq_write_room(struct usb_serial_port *port); @@ -367,17 +371,23 @@ priv->queue_len += count; if (priv->active == 0) { priv->active = 1; - result = ipaq_write_flush(port); + ipaq_write_gather(port); + spin_unlock_irqrestore(&write_list_lock, flags); + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + if (result) { + err(__FUNCTION__ " - failed submitting write urb, error %d", result); + } + } else { + spin_unlock_irqrestore(&write_list_lock, flags); } - spin_unlock_irqrestore(&write_list_lock, flags); return result; } -static int ipaq_write_flush(struct usb_serial_port *port) +static void ipaq_write_gather(struct usb_serial_port *port) { struct ipaq_private *priv = (struct ipaq_private *)port->private; struct usb_serial *serial = port->serial; - int count, room, result; + int count, room; struct ipaq_packet *pkt; struct urb *urb = port->write_urb; struct list_head *tmp; @@ -385,7 +395,7 @@ if (urb->status == -EINPROGRESS) { /* Should never happen */ err(__FUNCTION__ " - flushing while urb is active !"); - return -EAGAIN; + return; } room = URBDATA_SIZE; for (tmp = priv->queue.next; tmp != &priv->queue;) { @@ -412,11 +422,7 @@ usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback, port); - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) { - err(__FUNCTION__ " - failed submitting write urb, error %d", result); - } - return result; + return; } static void ipaq_write_bulk_callback(struct urb *urb) @@ -424,6 +430,7 @@ struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct ipaq_private *priv = (struct ipaq_private *)port->private; unsigned long flags; + int result; if (port_paranoia_check (port, __FUNCTION__)) { return; @@ -437,11 +444,16 @@ spin_lock_irqsave(&write_list_lock, flags); if (!list_empty(&priv->queue)) { - ipaq_write_flush(port); + ipaq_write_gather(port); + spin_unlock_irqrestore(&write_list_lock, flags); + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + if (result) { + err(__FUNCTION__ " - failed submitting write urb, error %d", result); + } } else { priv->active = 0; + spin_unlock_irqrestore(&write_list_lock, flags); } - spin_unlock_irqrestore(&write_list_lock, flags); queue_task(&port->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH);