diff options
author | Johan Hovold <jhovold@gmail.com> | 2010-05-15 11:53:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:48 -0400 |
commit | 2afd8287c6e2ac6c1affb46d009cfd866dffed77 (patch) | |
tree | 0222e5ebe9c2a7b1ec415de20cec222700f0d646 /drivers | |
parent | f2f8b7fe5a7542df8e3c906fcc9897b596bbf1fc (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.c | 77 |
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); |
96 | static void belkin_sa_close(struct usb_serial_port *port); | 97 | static void belkin_sa_close(struct usb_serial_port *port); |
97 | static void belkin_sa_read_int_callback(struct urb *urb); | 98 | static void belkin_sa_read_int_callback(struct urb *urb); |
99 | static void belkin_sa_process_read_urb(struct urb *urb); | ||
98 | static void belkin_sa_set_termios(struct tty_struct *tty, | 100 | static 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); |
100 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); | 102 | static 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); |
318 | exit: | 296 | exit: |
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 | ||
303 | static 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 | |||
325 | static void belkin_sa_set_termios(struct tty_struct *tty, | 350 | static 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 | { |