]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
USB: serial: fix up urb->status usage
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 11 Dec 2008 00:00:30 +0000 (16:00 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 7 Jan 2009 18:00:06 +0000 (10:00 -0800)
Some of the usb-serial drivers are starting to use urb->status in ways
they should not be doing.  This fixes up some of them to prevent that.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/iuu_phoenix.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/spcp8x5.c

index 69f84f0ea6fe71c0e319a5d38d21d6da10ecb171..38ba4ea8b6bfdf1b84b69d9338cd9c3154d60e51 100644 (file)
@@ -635,8 +635,7 @@ static int digi_write_oob_command(struct usb_serial_port *port,
 
        spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
        while (count > 0) {
-               while (oob_port->write_urb->status == -EINPROGRESS
-                       || oob_priv->dp_write_urb_in_use) {
+               while (oob_priv->dp_write_urb_in_use) {
                        cond_wait_interruptible_timeout_irqrestore(
                                &oob_port->write_wait, DIGI_RETRY_TIMEOUT,
                                &oob_priv->dp_port_lock, flags);
@@ -699,9 +698,8 @@ static int digi_write_inb_command(struct usb_serial_port *port,
 
        spin_lock_irqsave(&priv->dp_port_lock, flags);
        while (count > 0 && ret == 0) {
-               while ((port->write_urb->status == -EINPROGRESS
-                               || priv->dp_write_urb_in_use)
-                                       && time_before(jiffies, timeout)) {
+               while (priv->dp_write_urb_in_use &&
+                      time_before(jiffies, timeout)) {
                        cond_wait_interruptible_timeout_irqrestore(
                                &port->write_wait, DIGI_RETRY_TIMEOUT,
                                &priv->dp_port_lock, flags);
@@ -779,8 +777,7 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
        spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
        spin_lock(&port_priv->dp_port_lock);
 
-       while (oob_port->write_urb->status == -EINPROGRESS ||
-                                       oob_priv->dp_write_urb_in_use) {
+       while (oob_priv->dp_write_urb_in_use) {
                spin_unlock(&port_priv->dp_port_lock);
                cond_wait_interruptible_timeout_irqrestore(
                        &oob_port->write_wait, DIGI_RETRY_TIMEOUT,
@@ -1168,12 +1165,10 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
 
        /* be sure only one write proceeds at a time */
        /* there are races on the port private buffer */
-       /* and races to check write_urb->status */
        spin_lock_irqsave(&priv->dp_port_lock, flags);
 
        /* wait for urb status clear to submit another urb */
-       if (port->write_urb->status == -EINPROGRESS ||
-                                       priv->dp_write_urb_in_use) {
+       if (priv->dp_write_urb_in_use) {
                /* buffer data if count is 1 (probably put_char) if possible */
                if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) {
                        priv->dp_out_buf[priv->dp_out_buf_len++] = *buf;
@@ -1236,7 +1231,7 @@ static void digi_write_bulk_callback(struct urb *urb)
        int ret = 0;
        int status = urb->status;
 
-       dbg("digi_write_bulk_callback: TOP, urb->status=%d", status);
+       dbg("digi_write_bulk_callback: TOP, status=%d", status);
 
        /* port and serial sanity check */
        if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
@@ -1266,8 +1261,7 @@ static void digi_write_bulk_callback(struct urb *urb)
        /* try to send any buffered data on this port, if it is open */
        spin_lock(&priv->dp_port_lock);
        priv->dp_write_urb_in_use = 0;
-       if (port->port.count && port->write_urb->status != -EINPROGRESS
-           && priv->dp_out_buf_len > 0) {
+       if (port->port.count && priv->dp_out_buf_len > 0) {
                *((unsigned char *)(port->write_urb->transfer_buffer))
                        = (unsigned char)DIGI_CMD_SEND_DATA;
                *((unsigned char *)(port->write_urb->transfer_buffer) + 1)
@@ -1305,8 +1299,7 @@ static int digi_write_room(struct tty_struct *tty)
 
        spin_lock_irqsave(&priv->dp_port_lock, flags);
 
-       if (port->write_urb->status == -EINPROGRESS ||
-                                       priv->dp_write_urb_in_use)
+       if (priv->dp_write_urb_in_use)
                room = 0;
        else
                room = port->bulk_out_size - 2 - priv->dp_out_buf_len;
@@ -1322,8 +1315,7 @@ static int digi_chars_in_buffer(struct tty_struct *tty)
        struct usb_serial_port *port = tty->driver_data;
        struct digi_port *priv = usb_get_serial_port_data(port);
 
-       if (port->write_urb->status == -EINPROGRESS
-           || priv->dp_write_urb_in_use) {
+       if (priv->dp_write_urb_in_use) {
                dbg("digi_chars_in_buffer: port=%d, chars=%d",
                        priv->dp_port_num, port->bulk_out_size - 2);
                /* return(port->bulk_out_size - 2); */
@@ -1702,7 +1694,7 @@ static int digi_read_inb_callback(struct urb *urb)
        /* short/multiple packet check */
        if (urb->actual_length != len + 2) {
                dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, "
-                       "urb->status=%d, port=%d, opcode=%d, len=%d, "
+                       "status=%d, port=%d, opcode=%d, len=%d, "
                        "actual_length=%d, status=%d\n", __func__, status,
                        priv->dp_port_num, opcode, len, urb->actual_length,
                        port_status);
index 8e6a66e38db27ecd3fd7e97ffdbce4e80e79eff1..a26a0e2cdb4acd8debe7f26506d1e5c542595ddd 100644 (file)
@@ -1056,7 +1056,7 @@ static void garmin_write_bulk_callback(struct urb *urb)
 
                if (status) {
                        dbg("%s - nonzero write bulk status received: %d",
-                           __func__, urb->status);
+                           __func__, status);
                        spin_lock_irqsave(&garmin_data_p->lock, flags);
                        garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
                        spin_unlock_irqrestore(&garmin_data_p->lock, flags);
index e320972cb227deb511359d664d9cb5ebc0218e57..2314c6ae4fc26813dcd0b46aee575eba27e3208d 100644 (file)
@@ -190,10 +190,12 @@ static void iuu_rxcmd(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        int result;
+       int status = urb->status;
+
        dbg("%s - enter", __func__);
 
-       if (urb->status) {
-               dbg("%s - urb->status = %d", __func__, urb->status);
+       if (status) {
+               dbg("%s - status = %d", __func__, status);
                /* error stop all */
                return;
        }
@@ -245,10 +247,12 @@ static void iuu_update_status_callback(struct urb *urb)
        struct usb_serial_port *port = urb->context;
        struct iuu_private *priv = usb_get_serial_port_data(port);
        u8 *st;
+       int status = urb->status;
+
        dbg("%s - enter", __func__);
 
-       if (urb->status) {
-               dbg("%s - urb->status = %d", __func__, urb->status);
+       if (status) {
+               dbg("%s - status = %d", __func__, status);
                /* error stop all */
                return;
        }
@@ -274,9 +278,9 @@ static void iuu_status_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        int result;
-       dbg("%s - enter", __func__);
+       int status = urb->status;
 
-       dbg("%s - urb->status = %d", __func__, urb->status);
+       dbg("%s - status = %d", __func__, status);
        usb_fill_bulk_urb(port->read_urb, port->serial->dev,
                          usb_rcvbulkpipe(port->serial->dev,
                                          port->bulk_in_endpointAddress),
@@ -618,11 +622,12 @@ static void read_buf_callback(struct urb *urb)
        struct usb_serial_port *port = urb->context;
        unsigned char *data = urb->transfer_buffer;
        struct tty_struct *tty;
-       dbg("%s - urb->status = %d", __func__, urb->status);
+       int status = urb->status;
 
-       if (urb->status) {
-               dbg("%s - urb->status = %d", __func__, urb->status);
-               if (urb->status == -EPROTO) {
+       dbg("%s - status = %d", __func__, status);
+
+       if (status) {
+               if (status == -EPROTO) {
                        /* reschedule needed */
                }
                return;
@@ -695,7 +700,7 @@ static void iuu_uart_read_callback(struct urb *urb)
        struct usb_serial_port *port = urb->context;
        struct iuu_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
-       int status;
+       int status = urb->status;
        int error = 0;
        int len = 0;
        unsigned char *data = urb->transfer_buffer;
@@ -703,8 +708,8 @@ static void iuu_uart_read_callback(struct urb *urb)
 
        dbg("%s - enter", __func__);
 
-       if (urb->status) {
-               dbg("%s - urb->status = %d", __func__, urb->status);
+       if (status) {
+               dbg("%s - status = %d", __func__, status);
                /* error stop all */
                return;
        }
@@ -782,12 +787,11 @@ static void read_rxcmd_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        int result;
-       dbg("%s - enter", __func__);
+       int status = urb->status;
 
-       dbg("%s - urb->status = %d", __func__, urb->status);
+       dbg("%s - status = %d", __func__, status);
 
-       if (urb->status) {
-               dbg("%s - urb->status = %d", __func__, urb->status);
+       if (status) {
                /* error stop all */
                return;
        }
index 96a8c7713212871cf98ce1031cdefe8cfdfae430..2c20e88a91b3df84b8a19b7d2e5d46caf2f329f9 100644 (file)
@@ -214,6 +214,7 @@ struct moschip_port {
        spinlock_t pool_lock;
        struct urb *write_urb_pool[NUM_URBS];
        char busy[NUM_URBS];
+       bool read_urb_busy;
 };
 
 
@@ -679,26 +680,30 @@ static void mos7840_bulk_in_callback(struct urb *urb)
        struct tty_struct *tty;
        int status = urb->status;
 
-       if (status) {
-               dbg("nonzero read bulk status received: %d", status);
-               return;
-       }
-
        mos7840_port = urb->context;
        if (!mos7840_port) {
                dbg("%s", "NULL mos7840_port pointer \n");
+               mos7840_port->read_urb_busy = false;
+               return;
+       }
+
+       if (status) {
+               dbg("nonzero read bulk status received: %d", status);
+               mos7840_port->read_urb_busy = false;
                return;
        }
 
        port = (struct usb_serial_port *)mos7840_port->port;
        if (mos7840_port_paranoia_check(port, __func__)) {
                dbg("%s", "Port Paranoia failed \n");
+               mos7840_port->read_urb_busy = false;
                return;
        }
 
        serial = mos7840_get_usb_serial(port, __func__);
        if (!serial) {
                dbg("%s\n", "Bad serial pointer ");
+               mos7840_port->read_urb_busy = false;
                return;
        }
 
@@ -725,17 +730,19 @@ static void mos7840_bulk_in_callback(struct urb *urb)
 
        if (!mos7840_port->read_urb) {
                dbg("%s", "URB KILLED !!!\n");
+               mos7840_port->read_urb_busy = false;
                return;
        }
 
 
        mos7840_port->read_urb->dev = serial->dev;
 
+       mos7840_port->read_urb_busy = true;
        retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
 
        if (retval) {
-               dbg(" usb_submit_urb(read bulk) failed, retval = %d",
-                retval);
+               dbg("usb_submit_urb(read bulk) failed, retval = %d", retval);
+               mos7840_port->read_urb_busy = false;
        }
 }
 
@@ -1055,10 +1062,12 @@ static int mos7840_open(struct tty_struct *tty,
 
        dbg("mos7840_open: bulkin endpoint is %d\n",
            port->bulk_in_endpointAddress);
+       mos7840_port->read_urb_busy = true;
        response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL);
        if (response) {
                dev_err(&port->dev, "%s - Error %d submitting control urb\n",
                        __func__, response);
+               mos7840_port->read_urb_busy = false;
        }
 
        /* initialize our wait queues */
@@ -1227,6 +1236,7 @@ static void mos7840_close(struct tty_struct *tty,
                if (mos7840_port->read_urb) {
                        dbg("%s", "Shutdown bulk read\n");
                        usb_kill_urb(mos7840_port->read_urb);
+                       mos7840_port->read_urb_busy = false;
                }
                if ((&mos7840_port->control_urb)) {
                        dbg("%s", "Shutdown control read\n");
@@ -2043,14 +2053,14 @@ static void mos7840_change_port_settings(struct tty_struct *tty,
        Data = 0x0c;
        mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
 
-       if (mos7840_port->read_urb->status != -EINPROGRESS) {
+       if (mos7840_port->read_urb_busy == false) {
                mos7840_port->read_urb->dev = serial->dev;
-
+               mos7840_port->read_urb_busy = true;
                status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
-
                if (status) {
-                       dbg(" usb_submit_urb(read bulk) failed, status = %d",
+                       dbg("usb_submit_urb(read bulk) failed, status = %d",
                            status);
+                       mos7840_port->read_urb_busy = false;
                }
        }
        wake_up(&mos7840_port->delta_msr_wait);
@@ -2117,12 +2127,14 @@ static void mos7840_set_termios(struct tty_struct *tty,
                return;
        }
 
-       if (mos7840_port->read_urb->status != -EINPROGRESS) {
+       if (mos7840_port->read_urb_busy == false) {
                mos7840_port->read_urb->dev = serial->dev;
+               mos7840_port->read_urb_busy = true;
                status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
                if (status) {
-                       dbg(" usb_submit_urb(read bulk) failed, status = %d",
+                       dbg("usb_submit_urb(read bulk) failed, status = %d",
                            status);
+                       mos7840_port->read_urb_busy = false;
                }
        }
        return;
index 809697b3c7fcbed04a9d3a4e2eeac5d412a92adc..4c9497d05d13909a2dd364206e000f1417502f1c 100644 (file)
@@ -654,10 +654,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
                        usb_unlink_urb(this_urb);
                        continue;
                }
-               if (this_urb->status != 0)
-                       dbg("usb_write %p failed (err=%d)",
-                               this_urb, this_urb->status);
-
                dbg("%s: endpoint %d buf %d", __func__,
                        usb_pipeendpoint(this_urb->pipe), i);
 
@@ -669,8 +665,7 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
                err = usb_submit_urb(this_urb, GFP_ATOMIC);
                if (err) {
                        dbg("usb_submit_urb %p (write bulk) failed "
-                               "(%d, has %d)", this_urb,
-                               err, this_urb->status);
+                               "(%d)", this_urb, err);
                        clear_bit(i, &portdata->out_busy);
                        continue;
                }
index a65bc2bd8e710f0cd32d61777de7c0630be9077a..5e7528cc81a8e624f8ef64a869eca06b18918126 100644 (file)
@@ -709,21 +709,20 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)
        unsigned char *data = urb->transfer_buffer;
        unsigned long flags;
        int i;
-       int result;
-       u8 status = 0;
+       int result = urb->status;
+       u8 status;
        char tty_flag;
 
-       dev_dbg(&port->dev, "start, urb->status = %d, "
-               "urb->actual_length = %d\n,", urb->status, urb->actual_length);
+       dev_dbg(&port->dev, "start, result = %d, urb->actual_length = %d\n,",
+               result, urb->actual_length);
 
        /* check the urb status */
-       if (urb->status) {
+       if (result) {
                if (!port->port.count)
                        return;
-               if (urb->status == -EPROTO) {
+               if (result == -EPROTO) {
                        /* spcp8x5 mysteriously fails with -EPROTO */
                        /* reschedule the read */
-                       urb->status = 0;
                        urb->dev = port->serial->dev;
                        result = usb_submit_urb(urb , GFP_ATOMIC);
                        if (result)
@@ -833,8 +832,9 @@ static void spcp8x5_write_bulk_callback(struct urb *urb)
        struct usb_serial_port *port = urb->context;
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        int result;
+       int status = urb->status;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -843,14 +843,14 @@ static void spcp8x5_write_bulk_callback(struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dev_dbg(&port->dev, "urb shutting down with status: %d\n",
-                       urb->status);
+                       status);
                priv->write_urb_in_use = 0;
                return;
        default:
                /* error in the urb, so we have to resubmit it */
                dbg("%s - Overflow in write", __func__);
                dbg("%s - nonzero write bulk status received: %d",
-                       __func__, urb->status);
+                       __func__, status);
                port->write_urb->transfer_buffer_length = 1;
                port->write_urb->dev = port->serial->dev;
                result = usb_submit_urb(port->write_urb, GFP_ATOMIC);