aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2010-05-15 11:53:53 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:48 -0400
commit2afd8287c6e2ac6c1affb46d009cfd866dffed77 (patch)
tree0222e5ebe9c2a7b1ec415de20cec222700f0d646 /drivers
parentf2f8b7fe5a7542df8e3c906fcc9897b596bbf1fc (diff)
USB: belkin_sa: implement line status handling
Use process_read_urb to implement line status handling. Compile-only tested. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/serial/belkin_sa.c77
1 files changed, 51 insertions, 26 deletions
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index c39673608c35..36df35295db2 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com) 4 * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com)
5 * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com) 5 * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com)
6 * 7 *
7 * This program is largely derived from work by the linux-usb group 8 * This program is largely derived from work by the linux-usb group
8 * and associated source files. Please see the usb/serial files for 9 * and associated source files. Please see the usb/serial files for
@@ -84,7 +85,7 @@ static int debug;
84/* 85/*
85 * Version Information 86 * Version Information
86 */ 87 */
87#define DRIVER_VERSION "v1.2" 88#define DRIVER_VERSION "v1.3"
88#define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>" 89#define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>"
89#define DRIVER_DESC "USB Belkin Serial converter driver" 90#define DRIVER_DESC "USB Belkin Serial converter driver"
90 91
@@ -95,6 +96,7 @@ static int belkin_sa_open(struct tty_struct *tty,
95 struct usb_serial_port *port); 96 struct usb_serial_port *port);
96static void belkin_sa_close(struct usb_serial_port *port); 97static void belkin_sa_close(struct usb_serial_port *port);
97static void belkin_sa_read_int_callback(struct urb *urb); 98static void belkin_sa_read_int_callback(struct urb *urb);
99static void belkin_sa_process_read_urb(struct urb *urb);
98static void belkin_sa_set_termios(struct tty_struct *tty, 100static void belkin_sa_set_termios(struct tty_struct *tty,
99 struct usb_serial_port *port, struct ktermios * old); 101 struct usb_serial_port *port, struct ktermios * old);
100static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); 102static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state);
@@ -135,7 +137,7 @@ static struct usb_serial_driver belkin_device = {
135 .open = belkin_sa_open, 137 .open = belkin_sa_open,
136 .close = belkin_sa_close, 138 .close = belkin_sa_close,
137 .read_int_callback = belkin_sa_read_int_callback, 139 .read_int_callback = belkin_sa_read_int_callback,
138 /* How we get the status info */ 140 .process_read_urb = belkin_sa_process_read_urb,
139 .set_termios = belkin_sa_set_termios, 141 .set_termios = belkin_sa_set_termios,
140 .break_ctl = belkin_sa_break_ctl, 142 .break_ctl = belkin_sa_break_ctl,
141 .tiocmget = belkin_sa_tiocmget, 143 .tiocmget = belkin_sa_tiocmget,
@@ -289,31 +291,7 @@ static void belkin_sa_read_int_callback(struct urb *urb)
289 else 291 else
290 priv->control_state &= ~TIOCM_CD; 292 priv->control_state &= ~TIOCM_CD;
291 293
292 /* Now to report any errors */
293 priv->last_lsr = data[BELKIN_SA_LSR_INDEX]; 294 priv->last_lsr = data[BELKIN_SA_LSR_INDEX];
294#if 0
295 /*
296 * fill in the flip buffer here, but I do not know the relation
297 * to the current/next receive buffer or characters. I need
298 * to look in to this before committing any code.
299 */
300 if (priv->last_lsr & BELKIN_SA_LSR_ERR) {
301 tty = tty_port_tty_get(&port->port);
302 /* Overrun Error */
303 if (priv->last_lsr & BELKIN_SA_LSR_OE) {
304 }
305 /* Parity Error */
306 if (priv->last_lsr & BELKIN_SA_LSR_PE) {
307 }
308 /* Framing Error */
309 if (priv->last_lsr & BELKIN_SA_LSR_FE) {
310 }
311 /* Break Indicator */
312 if (priv->last_lsr & BELKIN_SA_LSR_BI) {
313 }
314 tty_kref_put(tty);
315 }
316#endif
317 spin_unlock_irqrestore(&priv->lock, flags); 295 spin_unlock_irqrestore(&priv->lock, flags);
318exit: 296exit:
319 retval = usb_submit_urb(urb, GFP_ATOMIC); 297 retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -322,6 +300,53 @@ exit:
322 "result %d\n", __func__, retval); 300 "result %d\n", __func__, retval);
323} 301}
324 302
303static void belkin_sa_process_read_urb(struct urb *urb)
304{
305 struct usb_serial_port *port = urb->context;
306 struct belkin_sa_private *priv = usb_get_serial_port_data(port);
307 struct tty_struct *tty;
308 unsigned char *data = urb->transfer_buffer;
309 unsigned long flags;
310 unsigned char status;
311 char tty_flag;
312
313 /* Update line status */
314 tty_flag = TTY_NORMAL;
315
316 spin_lock_irqsave(&priv->lock, flags);
317 status = priv->last_lsr;
318 priv->last_lsr &= ~BELKIN_SA_LSR_ERR;
319 spin_unlock_irqrestore(&priv->lock, flags);
320
321 if (!urb->actual_length)
322 return;
323
324 tty = tty_port_tty_get(&port->port);
325 if (!tty)
326 return;
327
328 if (status & BELKIN_SA_LSR_ERR) {
329 /* Break takes precedence over parity, which takes precedence
330 * over framing errors. */
331 if (status & BELKIN_SA_LSR_BI)
332 tty_flag = TTY_BREAK;
333 else if (status & BELKIN_SA_LSR_PE)
334 tty_flag = TTY_PARITY;
335 else if (status & BELKIN_SA_LSR_FE)
336 tty_flag = TTY_FRAME;
337 dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag);
338
339 /* Overrun is special, not associated with a char. */
340 if (status & BELKIN_SA_LSR_OE)
341 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
342 }
343
344 tty_insert_flip_string_fixed_flag(tty, data, tty_flag,
345 urb->actual_length);
346 tty_flip_buffer_push(tty);
347 tty_kref_put(tty);
348}
349
325static void belkin_sa_set_termios(struct tty_struct *tty, 350static void belkin_sa_set_termios(struct tty_struct *tty,
326 struct usb_serial_port *port, struct ktermios *old_termios) 351 struct usb_serial_port *port, struct ktermios *old_termios)
327{ 352{