Commit 2afd8287 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

USB: belkin_sa: implement line status handling

Use process_read_urb to implement line status handling.

Compile-only tested.
Signed-off-by: default avatarJohan Hovold <jhovold@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent f2f8b7fe
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* *
* Copyright (C) 2000 William Greathouse (wgreathouse@smva.com) * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com)
* Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2010 Johan Hovold (jhovold@gmail.com)
* *
* This program is largely derived from work by the linux-usb group * This program is largely derived from work by the linux-usb group
* and associated source files. Please see the usb/serial files for * and associated source files. Please see the usb/serial files for
...@@ -84,7 +85,7 @@ static int debug; ...@@ -84,7 +85,7 @@ static int debug;
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "v1.2" #define DRIVER_VERSION "v1.3"
#define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>" #define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>"
#define DRIVER_DESC "USB Belkin Serial converter driver" #define DRIVER_DESC "USB Belkin Serial converter driver"
...@@ -95,6 +96,7 @@ static int belkin_sa_open(struct tty_struct *tty, ...@@ -95,6 +96,7 @@ static int belkin_sa_open(struct tty_struct *tty,
struct usb_serial_port *port); struct usb_serial_port *port);
static void belkin_sa_close(struct usb_serial_port *port); static void belkin_sa_close(struct usb_serial_port *port);
static void belkin_sa_read_int_callback(struct urb *urb); static void belkin_sa_read_int_callback(struct urb *urb);
static void belkin_sa_process_read_urb(struct urb *urb);
static void belkin_sa_set_termios(struct tty_struct *tty, static void belkin_sa_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios * old); struct usb_serial_port *port, struct ktermios * old);
static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); 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,7 +137,7 @@ static struct usb_serial_driver belkin_device = {
.open = belkin_sa_open, .open = belkin_sa_open,
.close = belkin_sa_close, .close = belkin_sa_close,
.read_int_callback = belkin_sa_read_int_callback, .read_int_callback = belkin_sa_read_int_callback,
/* How we get the status info */ .process_read_urb = belkin_sa_process_read_urb,
.set_termios = belkin_sa_set_termios, .set_termios = belkin_sa_set_termios,
.break_ctl = belkin_sa_break_ctl, .break_ctl = belkin_sa_break_ctl,
.tiocmget = belkin_sa_tiocmget, .tiocmget = belkin_sa_tiocmget,
...@@ -289,31 +291,7 @@ static void belkin_sa_read_int_callback(struct urb *urb) ...@@ -289,31 +291,7 @@ static void belkin_sa_read_int_callback(struct urb *urb)
else else
priv->control_state &= ~TIOCM_CD; priv->control_state &= ~TIOCM_CD;
/* Now to report any errors */
priv->last_lsr = data[BELKIN_SA_LSR_INDEX]; priv->last_lsr = data[BELKIN_SA_LSR_INDEX];
#if 0
/*
* fill in the flip buffer here, but I do not know the relation
* to the current/next receive buffer or characters. I need
* to look in to this before committing any code.
*/
if (priv->last_lsr & BELKIN_SA_LSR_ERR) {
tty = tty_port_tty_get(&port->port);
/* Overrun Error */
if (priv->last_lsr & BELKIN_SA_LSR_OE) {
}
/* Parity Error */
if (priv->last_lsr & BELKIN_SA_LSR_PE) {
}
/* Framing Error */
if (priv->last_lsr & BELKIN_SA_LSR_FE) {
}
/* Break Indicator */
if (priv->last_lsr & BELKIN_SA_LSR_BI) {
}
tty_kref_put(tty);
}
#endif
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
exit: exit:
retval = usb_submit_urb(urb, GFP_ATOMIC); retval = usb_submit_urb(urb, GFP_ATOMIC);
...@@ -322,6 +300,53 @@ static void belkin_sa_read_int_callback(struct urb *urb) ...@@ -322,6 +300,53 @@ static void belkin_sa_read_int_callback(struct urb *urb)
"result %d\n", __func__, retval); "result %d\n", __func__, retval);
} }
static void belkin_sa_process_read_urb(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct belkin_sa_private *priv = usb_get_serial_port_data(port);
struct tty_struct *tty;
unsigned char *data = urb->transfer_buffer;
unsigned long flags;
unsigned char status;
char tty_flag;
/* Update line status */
tty_flag = TTY_NORMAL;
spin_lock_irqsave(&priv->lock, flags);
status = priv->last_lsr;
priv->last_lsr &= ~BELKIN_SA_LSR_ERR;
spin_unlock_irqrestore(&priv->lock, flags);
if (!urb->actual_length)
return;
tty = tty_port_tty_get(&port->port);
if (!tty)
return;
if (status & BELKIN_SA_LSR_ERR) {
/* Break takes precedence over parity, which takes precedence
* over framing errors. */
if (status & BELKIN_SA_LSR_BI)
tty_flag = TTY_BREAK;
else if (status & BELKIN_SA_LSR_PE)
tty_flag = TTY_PARITY;
else if (status & BELKIN_SA_LSR_FE)
tty_flag = TTY_FRAME;
dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag);
/* Overrun is special, not associated with a char. */
if (status & BELKIN_SA_LSR_OE)
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
}
tty_insert_flip_string_fixed_flag(tty, data, tty_flag,
urb->actual_length);
tty_flip_buffer_push(tty);
tty_kref_put(tty);
}
static void belkin_sa_set_termios(struct tty_struct *tty, static void belkin_sa_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios) struct usb_serial_port *port, struct ktermios *old_termios)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment