Skip to content

Commit

Permalink
tty: USB serial termios bits
Browse files Browse the repository at this point in the history
Various drivers have hacks to mangle termios structures. This stems from
the fact there is no nice setup hook for configuring the termios settings
when the port is created

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Alan Cox authored and Live-CD User committed Sep 19, 2009
1 parent ba15ab0 commit fe1ae7f
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 107 deletions.
1 change: 1 addition & 0 deletions drivers/char/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,7 @@ int tty_init_termios(struct tty_struct *tty)
tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
return 0;
}
EXPORT_SYMBOL_GPL(tty_init_termios);

/**
* tty_driver_install_tty() - install a tty entry in the driver
Expand Down
46 changes: 11 additions & 35 deletions drivers/usb/serial/ark3116.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ static struct usb_device_id id_table [] = {
};
MODULE_DEVICE_TABLE(usb, id_table);

struct ark3116_private {
spinlock_t lock;
u8 termios_initialized;
};

static inline void ARK3116_SND(struct usb_serial *serial, int seq,
__u8 request, __u8 requesttype,
__u16 value, __u16 index)
Expand Down Expand Up @@ -82,22 +77,11 @@ static inline void ARK3116_RCV_QUIET(struct usb_serial *serial,
static int ark3116_attach(struct usb_serial *serial)
{
char *buf;
struct ark3116_private *priv;
int i;

for (i = 0; i < serial->num_ports; ++i) {
priv = kzalloc(sizeof(struct ark3116_private), GFP_KERNEL);
if (!priv)
goto cleanup;
spin_lock_init(&priv->lock);

usb_set_serial_port_data(serial->port[i], priv);
}

buf = kmalloc(1, GFP_KERNEL);
if (!buf) {
dbg("error kmalloc -> out of mem?");
goto cleanup;
return -ENOMEM;
}

/* 3 */
Expand Down Expand Up @@ -149,24 +133,25 @@ static int ark3116_attach(struct usb_serial *serial)

kfree(buf);
return 0;
}

cleanup:
for (--i; i >= 0; --i) {
kfree(usb_get_serial_port_data(serial->port[i]));
usb_set_serial_port_data(serial->port[i], NULL);
}
return -ENOMEM;
static void ark3116_init_termios(struct tty_struct *tty)
{
struct ktermios *termios = tty->termios;
*termios = tty_std_termios;
termios->c_cflag = B9600 | CS8
| CREAD | HUPCL | CLOCAL;
termios->c_ispeed = 9600;
termios->c_ospeed = 9600;
}

static void ark3116_set_termios(struct tty_struct *tty,
struct usb_serial_port *port,
struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
struct ark3116_private *priv = usb_get_serial_port_data(port);
struct ktermios *termios = tty->termios;
unsigned int cflag = termios->c_cflag;
unsigned long flags;
int baud;
int ark3116_baud;
char *buf;
Expand All @@ -176,16 +161,6 @@ static void ark3116_set_termios(struct tty_struct *tty,

dbg("%s - port %d", __func__, port->number);

spin_lock_irqsave(&priv->lock, flags);
if (!priv->termios_initialized) {
*termios = tty_std_termios;
termios->c_cflag = B9600 | CS8
| CREAD | HUPCL | CLOCAL;
termios->c_ispeed = 9600;
termios->c_ospeed = 9600;
priv->termios_initialized = 1;
}
spin_unlock_irqrestore(&priv->lock, flags);

cflag = termios->c_cflag;
termios->c_cflag &= ~(CMSPAR|CRTSCTS);
Expand Down Expand Up @@ -454,6 +429,7 @@ static struct usb_serial_driver ark3116_device = {
.num_ports = 1,
.attach = ark3116_attach,
.set_termios = ark3116_set_termios,
.init_termios = ark3116_init_termios,
.ioctl = ark3116_ioctl,
.tiocmget = ark3116_tiocmget,
.open = ark3116_open,
Expand Down
12 changes: 3 additions & 9 deletions drivers/usb/serial/cypress_m8.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,15 +657,7 @@ static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
spin_unlock_irqrestore(&priv->lock, flags);

/* Set termios */
result = cypress_write(tty, port, NULL, 0);

if (result) {
dev_err(&port->dev,
"%s - failed setting the control lines - error %d\n",
__func__, result);
return result;
} else
dbg("%s - success setting the control lines", __func__);
cypress_send(port);

if (tty)
cypress_set_termios(tty, port, &priv->tmp_termios);
Expand Down Expand Up @@ -1003,6 +995,8 @@ static void cypress_set_termios(struct tty_struct *tty,
dbg("%s - port %d", __func__, port->number);

spin_lock_irqsave(&priv->lock, flags);
/* We can't clean this one up as we don't know the device type
early enough */
if (!priv->termios_initialized) {
if (priv->chiptype == CT_EARTHMATE) {
*(tty->termios) = tty_std_termios;
Expand Down
12 changes: 3 additions & 9 deletions drivers/usb/serial/empeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ static int empeg_chars_in_buffer(struct tty_struct *tty);
static void empeg_throttle(struct tty_struct *tty);
static void empeg_unthrottle(struct tty_struct *tty);
static int empeg_startup(struct usb_serial *serial);
static void empeg_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios);
static void empeg_init_termios(struct tty_struct *tty);
static void empeg_write_bulk_callback(struct urb *urb);
static void empeg_read_bulk_callback(struct urb *urb);

Expand Down Expand Up @@ -122,7 +121,7 @@ static struct usb_serial_driver empeg_device = {
.throttle = empeg_throttle,
.unthrottle = empeg_unthrottle,
.attach = empeg_startup,
.set_termios = empeg_set_termios,
.init_termios = empeg_init_termios,
.write = empeg_write,
.write_room = empeg_write_room,
.chars_in_buffer = empeg_chars_in_buffer,
Expand All @@ -148,9 +147,6 @@ static int empeg_open(struct tty_struct *tty,struct usb_serial_port *port)

dbg("%s - port %d", __func__, port->number);

/* Force default termio settings */
empeg_set_termios(tty, port, NULL);

bytes_in = 0;
bytes_out = 0;

Expand Down Expand Up @@ -423,11 +419,9 @@ static int empeg_startup(struct usb_serial *serial)
}


static void empeg_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios)
static void empeg_init_termios(struct tty_struct *tty)
{
struct ktermios *termios = tty->termios;
dbg("%s - port %d", __func__, port->number);

/*
* The empeg-car player wants these particular tty settings.
Expand Down
31 changes: 14 additions & 17 deletions drivers/usb/serial/iuu_phoenix.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ struct iuu_private {
spinlock_t lock; /* store irq state */
wait_queue_head_t delta_msr_wait;
u8 line_status;
u8 termios_initialized;
int tiostatus; /* store IUART SIGNAL for tiocmget call */
u8 reset; /* if 1 reset is needed */
int poll; /* number of poll */
Expand Down Expand Up @@ -1018,13 +1017,24 @@ static void iuu_close(struct usb_serial_port *port)
}
}

static void iuu_init_termios(struct tty_struct *tty)
{
*(tty->termios) = tty_std_termios;
tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
| TIOCM_CTS | CSTOPB | PARENB;
tty->termios->c_ispeed = 9600;
tty->termios->c_ospeed = 9600;
tty->termios->c_lflag = 0;
tty->termios->c_oflag = 0;
tty->termios->c_iflag = 0;
}

static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
u8 *buf;
int result;
u32 actual;
unsigned long flags;
struct iuu_private *priv = usb_get_serial_port_data(port);

dbg("%s - port %d", __func__, port->number);
Expand Down Expand Up @@ -1063,21 +1073,7 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
port->bulk_in_buffer, 512,
NULL, NULL);

/* set the termios structure */
spin_lock_irqsave(&priv->lock, flags);
if (tty && !priv->termios_initialized) {
*(tty->termios) = tty_std_termios;
tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
| TIOCM_CTS | CSTOPB | PARENB;
tty->termios->c_ispeed = 9600;
tty->termios->c_ospeed = 9600;
tty->termios->c_lflag = 0;
tty->termios->c_oflag = 0;
tty->termios->c_iflag = 0;
priv->termios_initialized = 1;
priv->poll = 0;
}
spin_unlock_irqrestore(&priv->lock, flags);
priv->poll = 0;

/* initialize writebuf */
#define FISH(a, b, c, d) do { \
Expand Down Expand Up @@ -1200,6 +1196,7 @@ static struct usb_serial_driver iuu_device = {
.tiocmget = iuu_tiocmget,
.tiocmset = iuu_tiocmset,
.set_termios = iuu_set_termios,
.init_termios = iuu_init_termios,
.attach = iuu_startup,
.release = iuu_release,
};
Expand Down
22 changes: 11 additions & 11 deletions drivers/usb/serial/kobil_sct.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static void kobil_read_int_callback(struct urb *urb);
static void kobil_write_callback(struct urb *purb);
static void kobil_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old);

static void kobil_init_termios(struct tty_struct *tty);

static struct usb_device_id id_table [] = {
{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) },
Expand Down Expand Up @@ -119,6 +119,7 @@ static struct usb_serial_driver kobil_device = {
.release = kobil_release,
.ioctl = kobil_ioctl,
.set_termios = kobil_set_termios,
.init_termios = kobil_init_termios,
.tiocmget = kobil_tiocmget,
.tiocmset = kobil_tiocmset,
.open = kobil_open,
Expand Down Expand Up @@ -209,6 +210,15 @@ static void kobil_release(struct usb_serial *serial)
kfree(usb_get_serial_port_data(serial->port[i]));
}

static void kobil_init_termios(struct tty_struct *tty)
{
/* Default to echo off and other sane device settings */
tty->termios->c_lflag = 0;
tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
/* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
tty->termios->c_oflag &= ~ONLCR;
}

static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
{
Expand All @@ -224,16 +234,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
/* someone sets the dev to 0 if the close method has been called */
port->interrupt_in_urb->dev = port->serial->dev;

if (tty) {

/* Default to echo off and other sane device settings */
tty->termios->c_lflag = 0;
tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN |
XCASE);
tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
/* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
tty->termios->c_oflag &= ~ONLCR;
}
/* allocate memory for transfer buffer */
transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
if (!transfer_buffer)
Expand Down
21 changes: 10 additions & 11 deletions drivers/usb/serial/oti6858.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port);
static void oti6858_close(struct usb_serial_port *port);
static void oti6858_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old);
static void oti6858_init_termios(struct tty_struct *tty);
static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg);
static void oti6858_read_int_callback(struct urb *urb);
Expand Down Expand Up @@ -185,6 +186,7 @@ static struct usb_serial_driver oti6858_device = {
.write = oti6858_write,
.ioctl = oti6858_ioctl,
.set_termios = oti6858_set_termios,
.init_termios = oti6858_init_termios,
.tiocmget = oti6858_tiocmget,
.tiocmset = oti6858_tiocmset,
.read_bulk_callback = oti6858_read_bulk_callback,
Expand All @@ -205,7 +207,6 @@ struct oti6858_private {
struct {
u8 read_urb_in_use;
u8 write_urb_in_use;
u8 termios_initialized;
} flags;
struct delayed_work delayed_write_work;

Expand Down Expand Up @@ -446,6 +447,14 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty)
return chars;
}

static void oti6858_init_termios(struct tty_struct *tty)
{
*(tty->termios) = tty_std_termios;
tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
tty->termios->c_ispeed = 38400;
tty->termios->c_ospeed = 38400;
}

static void oti6858_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios)
{
Expand All @@ -463,16 +472,6 @@ static void oti6858_set_termios(struct tty_struct *tty,
return;
}

spin_lock_irqsave(&priv->lock, flags);
if (!priv->flags.termios_initialized) {
*(tty->termios) = tty_std_termios;
tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
tty->termios->c_ispeed = 38400;
tty->termios->c_ospeed = 38400;
priv->flags.termios_initialized = 1;
}
spin_unlock_irqrestore(&priv->lock, flags);

cflag = tty->termios->c_cflag;

spin_lock_irqsave(&priv->lock, flags);
Expand Down
21 changes: 10 additions & 11 deletions drivers/usb/serial/spcp8x5.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,6 @@ struct spcp8x5_private {
wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
u8 termios_initialized;
};

/* desc : when device plug in,this function would be called.
Expand Down Expand Up @@ -498,6 +497,15 @@ static void spcp8x5_close(struct usb_serial_port *port)
dev_dbg(&port->dev, "usb_unlink_urb(read_urb) = %d\n", result);
}

static void spcp8x5_init_termios(struct tty_struct *tty)
{
/* for the 1st time call this function */
*(tty->termios) = tty_std_termios;
tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
tty->termios->c_ispeed = 115200;
tty->termios->c_ospeed = 115200;
}

/* set the serial param for transfer. we should check if we really need to
* transfer. if we set flow control we should do this too. */
static void spcp8x5_set_termios(struct tty_struct *tty,
Expand All @@ -514,16 +522,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
int i;
u8 control;

/* for the 1st time call this function */
spin_lock_irqsave(&priv->lock, flags);
if (!priv->termios_initialized) {
*(tty->termios) = tty_std_termios;
tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
tty->termios->c_ispeed = 115200;
tty->termios->c_ospeed = 115200;
priv->termios_initialized = 1;
}
spin_unlock_irqrestore(&priv->lock, flags);

/* check that they really want us to change something */
if (!tty_termios_hw_change(tty->termios, old_termios))
Expand Down Expand Up @@ -1008,6 +1006,7 @@ static struct usb_serial_driver spcp8x5_device = {
.carrier_raised = spcp8x5_carrier_raised,
.write = spcp8x5_write,
.set_termios = spcp8x5_set_termios,
.init_termios = spcp8x5_init_termios,
.ioctl = spcp8x5_ioctl,
.tiocmget = spcp8x5_tiocmget,
.tiocmset = spcp8x5_tiocmset,
Expand Down
Loading

0 comments on commit fe1ae7f

Please sign in to comment.