1 From aea06453b07c09f77ac6b1efc5644ca74aa982d9 Mon Sep 17 00:00:00 2001
2 From: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
3 Date: Thu, 1 Jun 2006 11:42:38 -0300
4 Subject: [PATCH 11/11] usbserial: pl2303: Ports urb callback functions.
6 Most of the changes are just error/debug messages improvements and the
7 addition of uart_port statatistics.
9 Additionally, pl2303_update_line_status() was completely ported and
10 pl2303_read_bulk_callback() modified to to handle -ECONNRESET and -ENOENT.
12 Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
14 drivers/usb/serial/pl2303.c | 119 +++++++++++++++++++++++++++----------------
15 1 files changed, 74 insertions(+), 45 deletions(-)
17 diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
18 index f93da0b..6d24733 100644
19 --- a/drivers/usb/serial/pl2303.c
20 +++ b/drivers/usb/serial/pl2303.c
21 @@ -883,6 +883,7 @@ static void pl2303_update_line_status(st
24 struct pl2303_private *priv = usb_get_serial_port_data(port);
27 u8 status_idx = UART_STATE;
28 u8 length = UART_STATE + 1;
29 @@ -896,16 +897,29 @@ static void pl2303_update_line_status(st
32 if (actual_length < length)
36 /* Save off the uart status for others to look at */
37 spin_lock_irqsave(&priv->lock, flags);
38 + delta_status = data[status_idx] ^ priv->line_status;
39 priv->line_status = data[status_idx];
40 - spin_unlock_irqrestore(&priv->lock, flags);
41 - wake_up_interruptible (&priv->delta_msr_wait);
46 + if (delta_status & UART_RING)
47 + port->uart_port.icount.rng++;
48 + if (delta_status & UART_DSR)
49 + port->uart_port.icount.dsr++;
50 + if (delta_status & UART_DCD)
51 + uart_handle_dcd_change(&port->uart_port,
52 + delta_status & UART_DCD);
53 + if (delta_status & UART_CTS)
54 + uart_handle_cts_change(&port->uart_port,
55 + delta_status & UART_CTS);
57 + wake_up_interruptible(&port->uart_port.info->delta_msr_wait);
60 + spin_unlock_irqrestore(&priv->lock, flags);
63 static void pl2303_read_int_callback (struct urb *urb, struct pt_regs *regs)
64 @@ -915,11 +929,13 @@ static void pl2303_read_int_callback (st
65 unsigned int actual_length = urb->actual_length;
68 - dbg("(%d)", port->number);
69 + dbg("port %d", port->uart_port.line);
71 switch (urb->status) {
74 + port->uart_port.icount.rx += actual_length;
75 + dbg("URB transfered with success");
79 @@ -928,7 +944,8 @@ static void pl2303_read_int_callback (st
80 dbg("urb shutting down with status: %d", urb->status);
83 - dbg("nonzero urb status received: %d", urb->status);
84 + dev_err(&urb->dev->dev, "nonzero urb status received: %d",
89 @@ -942,7 +959,6 @@ exit:
90 __FUNCTION__, status);
94 static void pl2303_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
96 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
97 @@ -955,25 +971,33 @@ static void pl2303_read_bulk_callback (s
101 - dbg("port %d", port->number);
102 + dbg("port %d", port->uart_port.line);
103 + dbg("urb->status = %d", urb->status);
106 - dbg("urb->status = %d", urb->status);
107 - if (!port->open_count) {
108 - dbg("port is closed, exiting.");
111 - if (urb->status == -EPROTO) {
112 - /* PL2303 mysteriously fails with -EPROTO reschedule the read */
113 - dbg("caught -EPROTO, resubmitting the urb");
115 - urb->dev = port->serial->dev;
116 - result = usb_submit_urb(urb, GFP_ATOMIC);
118 - dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
120 + switch (urb->status) {
125 + /* PL2303 mysteriously fails with -EPROTO reschedule the read */
126 + dbg("caught -EPROTO, resubmitting the urb");
128 + urb->dev = port->serial->dev;
129 + result = usb_submit_urb(urb, GFP_ATOMIC);
131 + dev_err(&urb->dev->dev,
132 + "%s - failed resubmitting read urb, error %d\n",
133 + __FUNCTION__, result);
135 - dbg("unable to handle the error, exiting.");
139 + /* this urb is terminated, clean up */
140 + dbg("urb shutting down with status: %d", urb->status);
143 + dev_err(&urb->dev->dev, "%s - unable to handle the error, exiting.",
148 @@ -986,53 +1010,59 @@ static void pl2303_read_bulk_callback (s
149 status = priv->line_status;
150 priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
151 spin_unlock_irqrestore(&priv->lock, flags);
152 - wake_up_interruptible (&priv->delta_msr_wait);
153 + wake_up_interruptible(&port->uart_port.info->delta_msr_wait);
155 /* break takes precedence over parity, */
156 /* which takes precedence over framing errors */
157 - if (status & UART_BREAK_ERROR )
158 + if (status & UART_BREAK_ERROR ) {
159 tty_flag = TTY_BREAK;
160 - else if (status & UART_PARITY_ERROR)
161 + port->uart_port.icount.brk++;
162 + } else if (status & UART_PARITY_ERROR) {
163 tty_flag = TTY_PARITY;
164 - else if (status & UART_FRAME_ERROR)
165 + port->uart_port.icount.parity++;
166 + } else if (status & UART_FRAME_ERROR) {
167 tty_flag = TTY_FRAME;
168 + port->uart_port.icount.frame++;
170 dbg("tty_flag = %d", tty_flag);
173 + tty = port->uart_port.info->tty;
174 if (tty && urb->actual_length) {
175 tty_buffer_request_room(tty, urb->actual_length + 1);
176 /* overrun is special, not associated with a char */
177 - if (status & UART_OVERRUN_ERROR)
178 + if (status & UART_OVERRUN_ERROR) {
179 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
180 + port->uart_port.icount.overrun++;
182 for (i = 0; i < urb->actual_length; ++i)
183 tty_insert_flip_char (tty, data[i], tty_flag);
184 tty_flip_buffer_push (tty);
185 + port->uart_port.icount.rx += urb->actual_length;
186 + dbg("pushed %d bytes to flip buffer", urb->actual_length);
189 - /* Schedule the next read _if_ we are still open */
190 - if (port->open_count) {
191 - urb->dev = port->serial->dev;
192 - result = usb_submit_urb(urb, GFP_ATOMIC);
194 - dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
195 + urb->dev = port->serial->dev;
196 + result = usb_submit_urb(urb, GFP_ATOMIC);
198 + dev_err(&urb->dev->dev,
199 + "%s - failed resubmitting read urb, error %d\n",
200 + __FUNCTION__, result);
208 static void pl2303_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
210 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
211 struct pl2303_private *priv = usb_get_serial_port_data(port);
214 - dbg("port %d", port->number);
215 + dbg("port %d", port->uart_port.line);
217 switch (urb->status) {
220 + port->uart_port.icount.tx += urb->actual_length;
221 + dbg("URB transfered with success");
225 @@ -1043,8 +1073,8 @@ static void pl2303_write_bulk_callback (
228 /* error in the urb, so we have to resubmit it */
229 - dbg("Overflow in write");
230 - dbg("nonzero write bulk status received: %d", urb->status);
231 + dev_err(&urb->dev->dev, "Overflow in write");
232 + dev_err(&urb->dev->dev, "nonzero write bulk status received: %d", urb->status);
233 port->write_urb->transfer_buffer_length = 1;
234 port->write_urb->dev = port->serial->dev;
235 result = usb_submit_urb (port->write_urb, GFP_ATOMIC);
236 @@ -1060,7 +1090,6 @@ static void pl2303_write_bulk_callback (