Commit 9c5c07fb authored by Ganesh Varadarajan's avatar Ganesh Varadarajan Committed by Greg Kroah-Hartman

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.
parent e4bd5f50
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (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 * (8/3/2002) ganesh
* The ipaq sometimes emits a '\0' before the CLIENT string. At this * 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 * point of time, the ppp ldisc is not yet attached to the tty, so
...@@ -65,7 +69,7 @@ static int ipaq_write(struct usb_serial_port *port, int from_user, const unsigne ...@@ -65,7 +69,7 @@ static int ipaq_write(struct usb_serial_port *port, int from_user, const unsigne
int count); int count);
static int ipaq_write_bulk(struct usb_serial_port *port, int from_user, const unsigned char *buf, static int ipaq_write_bulk(struct usb_serial_port *port, int from_user, const unsigned char *buf,
int count); 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_read_bulk_callback (struct urb *urb);
static void ipaq_write_bulk_callback(struct urb *urb); static void ipaq_write_bulk_callback(struct urb *urb);
static int ipaq_write_room(struct usb_serial_port *port); static int ipaq_write_room(struct usb_serial_port *port);
...@@ -367,17 +371,23 @@ static int ipaq_write_bulk(struct usb_serial_port *port, int from_user, const un ...@@ -367,17 +371,23 @@ static int ipaq_write_bulk(struct usb_serial_port *port, int from_user, const un
priv->queue_len += count; priv->queue_len += count;
if (priv->active == 0) { if (priv->active == 0) {
priv->active = 1; 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; 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 ipaq_private *priv = (struct ipaq_private *)port->private;
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
int count, room, result; int count, room;
struct ipaq_packet *pkt; struct ipaq_packet *pkt;
struct urb *urb = port->write_urb; struct urb *urb = port->write_urb;
struct list_head *tmp; struct list_head *tmp;
...@@ -385,7 +395,7 @@ static int ipaq_write_flush(struct usb_serial_port *port) ...@@ -385,7 +395,7 @@ static int ipaq_write_flush(struct usb_serial_port *port)
if (urb->status == -EINPROGRESS) { if (urb->status == -EINPROGRESS) {
/* Should never happen */ /* Should never happen */
err(__FUNCTION__ " - flushing while urb is active !"); err(__FUNCTION__ " - flushing while urb is active !");
return -EAGAIN; return;
} }
room = URBDATA_SIZE; room = URBDATA_SIZE;
for (tmp = priv->queue.next; tmp != &priv->queue;) { for (tmp = priv->queue.next; tmp != &priv->queue;) {
...@@ -412,11 +422,7 @@ static int ipaq_write_flush(struct usb_serial_port *port) ...@@ -412,11 +422,7 @@ static int ipaq_write_flush(struct usb_serial_port *port)
usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback, port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback,
port); port);
result = usb_submit_urb(urb, GFP_ATOMIC); return;
if (result) {
err(__FUNCTION__ " - failed submitting write urb, error %d", result);
}
return result;
} }
static void ipaq_write_bulk_callback(struct urb *urb) static void ipaq_write_bulk_callback(struct urb *urb)
...@@ -424,6 +430,7 @@ static void ipaq_write_bulk_callback(struct urb *urb) ...@@ -424,6 +430,7 @@ static void ipaq_write_bulk_callback(struct urb *urb)
struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct ipaq_private *priv = (struct ipaq_private *)port->private; struct ipaq_private *priv = (struct ipaq_private *)port->private;
unsigned long flags; unsigned long flags;
int result;
if (port_paranoia_check (port, __FUNCTION__)) { if (port_paranoia_check (port, __FUNCTION__)) {
return; return;
...@@ -437,11 +444,16 @@ static void ipaq_write_bulk_callback(struct urb *urb) ...@@ -437,11 +444,16 @@ static void ipaq_write_bulk_callback(struct urb *urb)
spin_lock_irqsave(&write_list_lock, flags); spin_lock_irqsave(&write_list_lock, flags);
if (!list_empty(&priv->queue)) { 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 { } else {
priv->active = 0; priv->active = 0;
spin_unlock_irqrestore(&write_list_lock, flags);
} }
spin_unlock_irqrestore(&write_list_lock, flags);
queue_task(&port->tqueue, &tq_immediate); queue_task(&port->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH); mark_bh(IMMEDIATE_BH);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment