[PATCH 061/123] USB: serial: fix up urb->status usage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxx>
---
 drivers/usb/serial/digi_acceleport.c |   28 +++++++++----------------
 drivers/usb/serial/garmin_gps.c      |    2 +-
 drivers/usb/serial/iuu_phoenix.c     |   38 ++++++++++++++++++---------------
 drivers/usb/serial/mos7840.c         |   38 ++++++++++++++++++++++-----------
 drivers/usb/serial/option.c          |    7 +-----
 drivers/usb/serial/spcp8x5.c         |   20 +++++++++---------
 6 files changed, 68 insertions(+), 65 deletions(-)

diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 69f84f0..38ba4ea 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -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);
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 8e6a66e..a26a0e2 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -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);
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index e320972..2314c6a 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -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;
 	}
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 96a8c77..2c20e88 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -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;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 809697b..4c9497d 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -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;
 		}
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index a65bc2b..5e7528c 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -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);
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux