Most of the changes are just error/debug messages improvements and the
addition of uart_port statatistics.

 Additionally, pl2303_update_line_status() was completely ported and
pl2303_read_bulk_callback() modified to to handle -ECONNRESET and -ENOENT.

Signed-off-by: Luiz Fernando N. Capitulino <[EMAIL PROTECTED]>
---
 drivers/usb/serial/pl2303.c |  119 +++++++++++++++++++++++++++----------------
 1 files changed, 74 insertions(+), 45 deletions(-)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index f93da0b..6d24733 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -883,6 +883,7 @@ static void pl2303_update_line_status(st
 {
 
        struct pl2303_private *priv = usb_get_serial_port_data(port);
+       char delta_status;
        unsigned long flags;
        u8 status_idx = UART_STATE;
        u8 length = UART_STATE + 1;
@@ -896,16 +897,29 @@ static void pl2303_update_line_status(st
        }
 
        if (actual_length < length)
-               goto exit;
+               return;
 
         /* Save off the uart status for others to look at */
        spin_lock_irqsave(&priv->lock, flags);
+       delta_status = data[status_idx] ^ priv->line_status;
        priv->line_status = data[status_idx];
-       spin_unlock_irqrestore(&priv->lock, flags);
-       wake_up_interruptible (&priv->delta_msr_wait);
 
-exit:
-       return;
+       if (delta_status) {
+               if (delta_status & UART_RING)
+                       port->uart_port.icount.rng++;
+               if (delta_status & UART_DSR)
+                       port->uart_port.icount.dsr++;
+               if (delta_status & UART_DCD)
+                       uart_handle_dcd_change(&port->uart_port,
+                                              delta_status & UART_DCD);
+               if (delta_status & UART_CTS)
+                       uart_handle_cts_change(&port->uart_port,
+                                              delta_status & UART_CTS);
+
+               wake_up_interruptible(&port->uart_port.info->delta_msr_wait);
+       }
+
+       spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 static void pl2303_read_int_callback (struct urb *urb, struct pt_regs *regs)
@@ -915,11 +929,13 @@ static void pl2303_read_int_callback (st
        unsigned int actual_length = urb->actual_length;
        int status;
 
-       dbg("(%d)", port->number);
+       dbg("port %d",  port->uart_port.line);
 
        switch (urb->status) {
        case 0:
                /* success */
+               port->uart_port.icount.rx += actual_length;
+               dbg("URB transfered with success");
                break;
        case -ECONNRESET:
        case -ENOENT:
@@ -928,7 +944,8 @@ static void pl2303_read_int_callback (st
                dbg("urb shutting down with status: %d", urb->status);
                return;
        default:
-               dbg("nonzero urb status received: %d", urb->status);
+               dev_err(&urb->dev->dev, "nonzero urb status received: %d",
+                       urb->status);
                goto exit;
        }
 
@@ -942,7 +959,6 @@ exit:
                        __FUNCTION__, status);
 }
 
-
 static void pl2303_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
@@ -955,25 +971,33 @@ static void pl2303_read_bulk_callback (s
        u8 status;
        char tty_flag;
 
-       dbg("port %d", port->number);
+       dbg("port %d",  port->uart_port.line);
+       dbg("urb->status = %d", urb->status);
 
-       if (urb->status) {
-               dbg("urb->status = %d", urb->status);
-               if (!port->open_count) {
-                       dbg("port is closed, exiting.");
-                       return;
-               }
-               if (urb->status == -EPROTO) {
-                       /* PL2303 mysteriously fails with -EPROTO reschedule 
the read */
-                       dbg("caught -EPROTO, resubmitting the urb");
-                       urb->status = 0;
-                       urb->dev = port->serial->dev;
-                       result = usb_submit_urb(urb, GFP_ATOMIC);
-                       if (result)
-                               dev_err(&urb->dev->dev, "%s - failed 
resubmitting read urb, error %d\n", __FUNCTION__, result);
-                       return;
+       switch (urb->status) {
+       case 0:
+               /* success */
+               break;
+       case -EPROTO:
+               /* PL2303 mysteriously fails with -EPROTO reschedule the read */
+               dbg("caught -EPROTO, resubmitting the urb");
+               urb->status = 0;
+               urb->dev = port->serial->dev;
+               result = usb_submit_urb(urb, GFP_ATOMIC);
+               if (result) {
+                       dev_err(&urb->dev->dev,
+                               "%s - failed resubmitting read urb, error %d\n",
+                               __FUNCTION__, result);
                }
-               dbg("unable to handle the error, exiting.");
+               return;
+       case -ECONNRESET:
+       case -ENOENT:
+               /* this urb is terminated, clean up */
+               dbg("urb shutting down with status: %d", urb->status);
+               return;
+       default:
+               dev_err(&urb->dev->dev, "%s - unable to handle the error, 
exiting.",
+                       __FUNCTION__);
                return;
        }
 
@@ -986,53 +1010,59 @@ static void pl2303_read_bulk_callback (s
        status = priv->line_status;
        priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
        spin_unlock_irqrestore(&priv->lock, flags);
-       wake_up_interruptible (&priv->delta_msr_wait);
+       wake_up_interruptible(&port->uart_port.info->delta_msr_wait);
 
        /* break takes precedence over parity, */
        /* which takes precedence over framing errors */
-       if (status & UART_BREAK_ERROR )
+       if (status & UART_BREAK_ERROR ) {
                tty_flag = TTY_BREAK;
-       else if (status & UART_PARITY_ERROR)
+               port->uart_port.icount.brk++;
+       } else if (status & UART_PARITY_ERROR) {
                tty_flag = TTY_PARITY;
-       else if (status & UART_FRAME_ERROR)
+               port->uart_port.icount.parity++;
+       } else if (status & UART_FRAME_ERROR) {
                tty_flag = TTY_FRAME;
+               port->uart_port.icount.frame++;
+       }
        dbg("tty_flag = %d", tty_flag);
 
-       tty = port->tty;
+       tty = port->uart_port.info->tty;
        if (tty && urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length + 1);
                /* overrun is special, not associated with a char */
-               if (status & UART_OVERRUN_ERROR)
+               if (status & UART_OVERRUN_ERROR) {
                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+                       port->uart_port.icount.overrun++;
+               }
                for (i = 0; i < urb->actual_length; ++i)
                        tty_insert_flip_char (tty, data[i], tty_flag);
                tty_flip_buffer_push (tty);
+               port->uart_port.icount.rx += urb->actual_length;
+               dbg("pushed %d bytes to flip buffer", urb->actual_length);
        }
 
-       /* Schedule the next read _if_ we are still open */
-       if (port->open_count) {
-               urb->dev = port->serial->dev;
-               result = usb_submit_urb(urb, GFP_ATOMIC);
-               if (result)
-                       dev_err(&urb->dev->dev, "%s - failed resubmitting read 
urb, error %d\n", __FUNCTION__, result);
+       urb->dev = port->serial->dev;
+       result = usb_submit_urb(urb, GFP_ATOMIC);
+       if (result) {
+               dev_err(&urb->dev->dev,
+                       "%s - failed resubmitting read urb, error %d\n",
+                       __FUNCTION__, result);
        }
-
-       return;
 }
 
-
-
 static void pl2303_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        int result;
 
-       dbg("port %d", port->number);
+       dbg("port %d",  port->uart_port.line);
 
        switch (urb->status) {
        case 0:
                /* success */
+               port->uart_port.icount.tx += urb->actual_length;
+               dbg("URB transfered with success");
                break;
        case -ECONNRESET:
        case -ENOENT:
@@ -1043,8 +1073,8 @@ static void pl2303_write_bulk_callback (
                return;
        default:
                /* error in the urb, so we have to resubmit it */
-               dbg("Overflow in write");
-               dbg("nonzero write bulk status received: %d", urb->status);
+               dev_err(&urb->dev->dev, "Overflow in write");
+               dev_err(&urb->dev->dev, "nonzero write bulk status received: 
%d", urb->status);
                port->write_urb->transfer_buffer_length = 1;
                port->write_urb->dev = port->serial->dev;
                result = usb_submit_urb (port->write_urb, GFP_ATOMIC);
@@ -1060,7 +1090,6 @@ static void pl2303_write_bulk_callback (
        pl2303_send(port);
 }
 
-
 /*
  * pl2303_buf_alloc
  *
-- 
1.3.3.g0825d



_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to