提交 a5b6f60c 编写于 作者: A Alan Cox 提交者: Greg Kroah-Hartman

usb serial: more fixes and groundwork for tty changes

 - If a termios change fails due to lack of memory we should copy the
   old settings back over as the device has not changed
 - Note various locking problems
 - kl5kusb105 had various remaining tty flag handling problems
 - Make safe_serial use tty_insert_flip_string not open coded loops
 - set termios speed properly in usb_serial
Signed-off-by: NAlan Cox <alan@redhat.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 441b62c1
...@@ -192,6 +192,7 @@ static void ark3116_set_termios(struct usb_serial_port *port, ...@@ -192,6 +192,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
buf = kmalloc(1, GFP_KERNEL); buf = kmalloc(1, GFP_KERNEL);
if (!buf) { if (!buf) {
dbg("error kmalloc"); dbg("error kmalloc");
*port->tty->termios = *old_termios;
return; return;
} }
......
...@@ -151,7 +151,7 @@ static void cyberjack_shutdown (struct usb_serial *serial) ...@@ -151,7 +151,7 @@ static void cyberjack_shutdown (struct usb_serial *serial)
dbg("%s", __func__); dbg("%s", __func__);
for (i=0; i < serial->num_ports; ++i) { for (i = 0; i < serial->num_ports; ++i) {
usb_kill_urb(serial->port[i]->interrupt_in_urb); usb_kill_urb(serial->port[i]->interrupt_in_urb);
/* My special items, the standard routines free my urbs */ /* My special items, the standard routines free my urbs */
kfree(usb_get_serial_port_data(serial->port[i])); kfree(usb_get_serial_port_data(serial->port[i]));
...@@ -209,7 +209,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b ...@@ -209,7 +209,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
if (count == 0) { if (count == 0) {
dbg("%s - write request of 0 bytes", __func__); dbg("%s - write request of 0 bytes", __func__);
return (0); return 0;
} }
spin_lock_bh(&port->lock); spin_lock_bh(&port->lock);
...@@ -223,12 +223,12 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b ...@@ -223,12 +223,12 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) { if( (count+priv->wrfilled) > sizeof(priv->wrbuf) ) {
/* To much data for buffer. Reset buffer. */ /* To much data for buffer. Reset buffer. */
priv->wrfilled=0; priv->wrfilled = 0;
spin_unlock_irqrestore(&priv->lock, flags);
port->write_urb_busy = 0; port->write_urb_busy = 0;
return (0); spin_unlock_irqrestore(&priv->lock, flags);
return 0;
} }
/* Copy data */ /* Copy data */
...@@ -269,8 +269,8 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b ...@@ -269,8 +269,8 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
if (result) { if (result) {
err("%s - failed submitting write urb, error %d", __func__, result); err("%s - failed submitting write urb, error %d", __func__, result);
/* Throw away data. No better idea what to do with it. */ /* Throw away data. No better idea what to do with it. */
priv->wrfilled=0; priv->wrfilled = 0;
priv->wrsent=0; priv->wrsent = 0;
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
port->write_urb_busy = 0; port->write_urb_busy = 0;
return 0; return 0;
...@@ -282,8 +282,8 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b ...@@ -282,8 +282,8 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
if( priv->wrsent>=priv->wrfilled ) { if( priv->wrsent>=priv->wrfilled ) {
dbg("%s - buffer cleaned", __func__); dbg("%s - buffer cleaned", __func__);
memset( priv->wrbuf, 0, sizeof(priv->wrbuf) ); memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
priv->wrfilled=0; priv->wrfilled = 0;
priv->wrsent=0; priv->wrsent = 0;
} }
} }
...@@ -294,6 +294,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b ...@@ -294,6 +294,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
static int cyberjack_write_room( struct usb_serial_port *port ) static int cyberjack_write_room( struct usb_serial_port *port )
{ {
/* FIXME: .... */
return CYBERJACK_LOCAL_BUF_SIZE; return CYBERJACK_LOCAL_BUF_SIZE;
} }
...@@ -314,7 +315,7 @@ static void cyberjack_read_int_callback( struct urb *urb ) ...@@ -314,7 +315,7 @@ static void cyberjack_read_int_callback( struct urb *urb )
usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
/* React only to interrupts signaling a bulk_in transfer */ /* React only to interrupts signaling a bulk_in transfer */
if( (urb->actual_length==4) && (data[0]==0x01) ) { if( (urb->actual_length == 4) && (data[0] == 0x01) ) {
short old_rdtodo; short old_rdtodo;
/* This is a announcement of coming bulk_ins. */ /* This is a announcement of coming bulk_ins. */
...@@ -450,8 +451,8 @@ static void cyberjack_write_bulk_callback (struct urb *urb) ...@@ -450,8 +451,8 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
if (result) { if (result) {
err("%s - failed submitting write urb, error %d", __func__, result); err("%s - failed submitting write urb, error %d", __func__, result);
/* Throw away data. No better idea what to do with it. */ /* Throw away data. No better idea what to do with it. */
priv->wrfilled=0; priv->wrfilled = 0;
priv->wrsent=0; priv->wrsent = 0;
goto exit; goto exit;
} }
...@@ -463,8 +464,8 @@ static void cyberjack_write_bulk_callback (struct urb *urb) ...@@ -463,8 +464,8 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) { if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) {
dbg("%s - buffer cleaned", __func__); dbg("%s - buffer cleaned", __func__);
memset( priv->wrbuf, 0, sizeof(priv->wrbuf) ); memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
priv->wrfilled=0; priv->wrfilled = 0;
priv->wrsent=0; priv->wrsent = 0;
} }
} }
......
...@@ -262,13 +262,14 @@ int usb_serial_generic_write_room (struct usb_serial_port *port) ...@@ -262,13 +262,14 @@ int usb_serial_generic_write_room (struct usb_serial_port *port)
dbg("%s - port %d", __func__, port->number); dbg("%s - port %d", __func__, port->number);
/* FIXME: Locking */
if (serial->num_bulk_out) { if (serial->num_bulk_out) {
if (!(port->write_urb_busy)) if (!(port->write_urb_busy))
room = port->bulk_out_size; room = port->bulk_out_size;
} }
dbg("%s - returns %d", __func__, room); dbg("%s - returns %d", __func__, room);
return (room); return room;
} }
int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
...@@ -278,6 +279,7 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) ...@@ -278,6 +279,7 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
dbg("%s - port %d", __func__, port->number); dbg("%s - port %d", __func__, port->number);
/* FIXME: Locking */
if (serial->num_bulk_out) { if (serial->num_bulk_out) {
if (port->write_urb_busy) if (port->write_urb_busy)
chars = port->write_urb->transfer_buffer_length; chars = port->write_urb->transfer_buffer_length;
...@@ -368,7 +370,6 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb) ...@@ -368,7 +370,6 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb)
__func__, status); __func__, status);
return; return;
} }
usb_serial_port_softint(port); usb_serial_port_softint(port);
} }
EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
......
...@@ -1187,6 +1187,7 @@ static int keyspan_write_room (struct usb_serial_port *port) ...@@ -1187,6 +1187,7 @@ static int keyspan_write_room (struct usb_serial_port *port)
p_priv = usb_get_serial_port_data(port); p_priv = usb_get_serial_port_data(port);
d_details = p_priv->device_details; d_details = p_priv->device_details;
/* FIXME: locking */
if (d_details->msg_format == msg_usa90) if (d_details->msg_format == msg_usa90)
data_len = 64; data_len = 64;
else else
...@@ -1203,13 +1204,13 @@ static int keyspan_write_room (struct usb_serial_port *port) ...@@ -1203,13 +1204,13 @@ static int keyspan_write_room (struct usb_serial_port *port)
if (this_urb->status != -EINPROGRESS) if (this_urb->status != -EINPROGRESS)
return (data_len); return (data_len);
} }
return (0); return 0;
} }
static int keyspan_chars_in_buffer (struct usb_serial_port *port) static int keyspan_chars_in_buffer (struct usb_serial_port *port)
{ {
return (0); return 0;
} }
...@@ -1289,7 +1290,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) ...@@ -1289,7 +1290,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
//mdelay(100); //mdelay(100);
//keyspan_set_termios(port, NULL); //keyspan_set_termios(port, NULL);
return (0); return 0;
} }
static inline void stop_urb(struct urb *urb) static inline void stop_urb(struct urb *urb)
...@@ -2006,7 +2007,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, ...@@ -2006,7 +2007,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
} }
#endif #endif
return (0); return 0;
} }
static int keyspan_usa28_send_setup(struct usb_serial *serial, static int keyspan_usa28_send_setup(struct usb_serial *serial,
...@@ -2131,7 +2132,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial, ...@@ -2131,7 +2132,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
} }
#endif #endif
return (0); return 0;
} }
static int keyspan_usa49_send_setup(struct usb_serial *serial, static int keyspan_usa49_send_setup(struct usb_serial *serial,
...@@ -2317,7 +2318,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, ...@@ -2317,7 +2318,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
} }
#endif #endif
return (0); return 0;
} }
static int keyspan_usa90_send_setup(struct usb_serial *serial, static int keyspan_usa90_send_setup(struct usb_serial *serial,
...@@ -2455,7 +2456,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial, ...@@ -2455,7 +2456,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err);
} }
return (0); return 0;
} }
static int keyspan_usa67_send_setup(struct usb_serial *serial, static int keyspan_usa67_send_setup(struct usb_serial *serial,
...@@ -2603,7 +2604,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial, ...@@ -2603,7 +2604,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial,
if (err != 0) if (err != 0)
dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, dbg("%s - usb_submit_urb(setup) failed (%d)", __func__,
err); err);
return (0); return 0;
} }
static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
...@@ -2696,7 +2697,7 @@ static int keyspan_startup (struct usb_serial *serial) ...@@ -2696,7 +2697,7 @@ static int keyspan_startup (struct usb_serial *serial)
err); err);
} }
return (0); return 0;
} }
static void keyspan_shutdown (struct usb_serial *serial) static void keyspan_shutdown (struct usb_serial *serial)
......
...@@ -636,14 +636,19 @@ static int keyspan_pda_write_room (struct usb_serial_port *port) ...@@ -636,14 +636,19 @@ static int keyspan_pda_write_room (struct usb_serial_port *port)
static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port) static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
{ {
struct keyspan_pda_private *priv; struct keyspan_pda_private *priv;
unsigned long flags;
int ret = 0;
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
/* when throttled, return at least WAKEUP_CHARS to tell select() (via /* when throttled, return at least WAKEUP_CHARS to tell select() (via
n_tty.c:normal_poll() ) that we're not writeable. */ n_tty.c:normal_poll() ) that we're not writeable. */
spin_lock_irqsave(&port->lock, flags);
if (port->write_urb_busy || priv->tx_throttled) if (port->write_urb_busy || priv->tx_throttled)
return 256; ret = 256;
return 0; spin_unlock_irqrestore(&port->lock, flags);
return ret;
} }
......
...@@ -702,12 +702,14 @@ static void klsi_105_set_termios (struct usb_serial_port *port, ...@@ -702,12 +702,14 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
struct ktermios *old_termios) struct ktermios *old_termios)
{ {
struct klsi_105_private *priv = usb_get_serial_port_data(port); struct klsi_105_private *priv = usb_get_serial_port_data(port);
unsigned int iflag = port->tty->termios->c_iflag; struct tty_struct *tty = port->tty;
unsigned int iflag = tty->termios->c_iflag;
unsigned int old_iflag = old_termios->c_iflag; unsigned int old_iflag = old_termios->c_iflag;
unsigned int cflag = port->tty->termios->c_cflag; unsigned int cflag = tty->termios->c_cflag;
unsigned int old_cflag = old_termios->c_cflag; unsigned int old_cflag = old_termios->c_cflag;
struct klsi_105_port_settings cfg; struct klsi_105_port_settings cfg;
unsigned long flags; unsigned long flags;
speed_t baud;
/* lock while we are modifying the settings */ /* lock while we are modifying the settings */
spin_lock_irqsave (&priv->lock, flags); spin_lock_irqsave (&priv->lock, flags);
...@@ -715,6 +717,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port, ...@@ -715,6 +717,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
/* /*
* Update baud rate * Update baud rate
*/ */
baud = tty_get_baud_rate(tty);
if( (cflag & CBAUD) != (old_cflag & CBAUD) ) { if( (cflag & CBAUD) != (old_cflag & CBAUD) ) {
/* reassert DTR and (maybe) RTS on transition from B0 */ /* reassert DTR and (maybe) RTS on transition from B0 */
if( (old_cflag & CBAUD) == B0 ) { if( (old_cflag & CBAUD) == B0 ) {
...@@ -728,8 +732,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port, ...@@ -728,8 +732,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
mct_u232_set_modem_ctrl(serial, priv->control_state); mct_u232_set_modem_ctrl(serial, priv->control_state);
#endif #endif
} }
}
switch(tty_get_baud_rate(port->tty)) { switch(baud) {
case 0: /* handled below */ case 0: /* handled below */
break; break;
case 1200: case 1200:
...@@ -757,25 +761,26 @@ static void klsi_105_set_termios (struct usb_serial_port *port, ...@@ -757,25 +761,26 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
priv->cfg.baudrate = kl5kusb105a_sio_b115200; priv->cfg.baudrate = kl5kusb105a_sio_b115200;
break; break;
default: default:
err("KLSI USB->Serial converter:" dbg("KLSI USB->Serial converter:"
" unsupported baudrate request, using default" " unsupported baudrate request, using default"
" of 9600"); " of 9600");
priv->cfg.baudrate = kl5kusb105a_sio_b9600; priv->cfg.baudrate = kl5kusb105a_sio_b9600;
baud = 9600;
break; break;
} }
if ((cflag & CBAUD) == B0 ) { if ((cflag & CBAUD) == B0 ) {
dbg("%s: baud is B0", __func__); dbg("%s: baud is B0", __func__);
/* Drop RTS and DTR */ /* Drop RTS and DTR */
/* maybe this should be simulated by sending read /* maybe this should be simulated by sending read
* disable and read enable messages? * disable and read enable messages?
*/ */
; ;
#if 0 #if 0
priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
mct_u232_set_modem_ctrl(serial, priv->control_state); mct_u232_set_modem_ctrl(serial, priv->control_state);
#endif #endif
}
} }
tty_encode_baud_rate(tty, baud, baud);
if ((cflag & CSIZE) != (old_cflag & CSIZE)) { if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
/* set the number of data bits */ /* set the number of data bits */
...@@ -807,6 +812,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port, ...@@ -807,6 +812,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD)) if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))
|| (cflag & CSTOPB) != (old_cflag & CSTOPB) ) { || (cflag & CSTOPB) != (old_cflag & CSTOPB) ) {
/* Not currently supported */
tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB);
#if 0 #if 0
priv->last_lcr = 0; priv->last_lcr = 0;
...@@ -834,6 +841,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port, ...@@ -834,6 +841,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
|| (iflag & IXON) != (old_iflag & IXON) || (iflag & IXON) != (old_iflag & IXON)
|| (cflag & CRTSCTS) != (old_cflag & CRTSCTS) ) { || (cflag & CRTSCTS) != (old_cflag & CRTSCTS) ) {
/* Not currently supported */
tty->termios->c_cflag &= ~CRTSCTS;
/* Drop DTR/RTS if no flow control otherwise assert */ /* Drop DTR/RTS if no flow control otherwise assert */
#if 0 #if 0
if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS) ) if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS) )
......
...@@ -635,6 +635,7 @@ static int mos7720_write_room(struct usb_serial_port *port) ...@@ -635,6 +635,7 @@ static int mos7720_write_room(struct usb_serial_port *port)
return -ENODEV; return -ENODEV;
} }
/* FIXME: Locking */
for (i = 0; i < NUM_URBS; ++i) { for (i = 0; i < NUM_URBS; ++i) {
if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS)
room += URB_TRANSFER_BUFFER_SIZE; room += URB_TRANSFER_BUFFER_SIZE;
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation. * version 2 as published by the Free Software Foundation.
*
* TODO:
* Add termios method that uses copy_hw but also kills all echo
* flags as the navman is rx only so cannot echo.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -106,12 +110,8 @@ static int navman_write(struct usb_serial_port *port, ...@@ -106,12 +110,8 @@ static int navman_write(struct usb_serial_port *port,
/* /*
* This device can't write any data, only read from the device * This device can't write any data, only read from the device
* so we just silently eat all data sent to us and say it was
* successfully sent.
* Evil, I know, but do you have a better idea?
*/ */
return -EOPNOTSUPP;
return count;
} }
static struct usb_serial_driver navman_device = { static struct usb_serial_driver navman_device = {
......
...@@ -295,8 +295,9 @@ static int omninet_write_room (struct usb_serial_port *port) ...@@ -295,8 +295,9 @@ static int omninet_write_room (struct usb_serial_port *port)
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
struct usb_serial_port *wport = serial->port[1]; struct usb_serial_port *wport = serial->port[1];
int room = 0; // Default: no room int room = 0; /* Default: no room */
/* FIXME: no consistent locking for write_urb_busy */
if (wport->write_urb_busy) if (wport->write_urb_busy)
room = wport->bulk_out_size - OMNINET_HEADERLEN; room = wport->bulk_out_size - OMNINET_HEADERLEN;
......
...@@ -656,6 +656,7 @@ static int option_write_room(struct usb_serial_port *port) ...@@ -656,6 +656,7 @@ static int option_write_room(struct usb_serial_port *port)
portdata = usb_get_serial_port_data(port); portdata = usb_get_serial_port_data(port);
for (i=0; i < N_OUT_URB; i++) { for (i=0; i < N_OUT_URB; i++) {
this_urb = portdata->out_urbs[i]; this_urb = portdata->out_urbs[i];
if (this_urb && !test_bit(i, &portdata->out_busy)) if (this_urb && !test_bit(i, &portdata->out_busy))
...@@ -677,6 +678,8 @@ static int option_chars_in_buffer(struct usb_serial_port *port) ...@@ -677,6 +678,8 @@ static int option_chars_in_buffer(struct usb_serial_port *port)
for (i=0; i < N_OUT_URB; i++) { for (i=0; i < N_OUT_URB; i++) {
this_urb = portdata->out_urbs[i]; this_urb = portdata->out_urbs[i];
/* FIXME: This locking is insufficient as this_urb may
go unused during the test */
if (this_urb && test_bit(i, &portdata->out_busy)) if (this_urb && test_bit(i, &portdata->out_busy))
data_len += this_urb->transfer_buffer_length; data_len += this_urb->transfer_buffer_length;
} }
......
...@@ -546,6 +546,8 @@ static void pl2303_set_termios(struct usb_serial_port *port, ...@@ -546,6 +546,8 @@ static void pl2303_set_termios(struct usb_serial_port *port,
buf = kzalloc(7, GFP_KERNEL); buf = kzalloc(7, GFP_KERNEL);
if (!buf) { if (!buf) {
dev_err(&port->dev, "%s - out of memory.\n", __func__); dev_err(&port->dev, "%s - out of memory.\n", __func__);
/* Report back no change occurred */
*port->tty->termios = *old_termios;
return; return;
} }
......
...@@ -198,7 +198,6 @@ static void safe_read_bulk_callback (struct urb *urb) ...@@ -198,7 +198,6 @@ static void safe_read_bulk_callback (struct urb *urb)
struct usb_serial_port *port = (struct usb_serial_port *) urb->context; struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
unsigned char length = urb->actual_length; unsigned char length = urb->actual_length;
int i;
int result; int result;
int status = urb->status; int status = urb->status;
...@@ -227,16 +226,10 @@ static void safe_read_bulk_callback (struct urb *urb) ...@@ -227,16 +226,10 @@ static void safe_read_bulk_callback (struct urb *urb)
if (safe) { if (safe) {
__u16 fcs; __u16 fcs;
if (!(fcs = fcs_compute10 (data, length, CRC10_INITFCS))) { if (!(fcs = fcs_compute10 (data, length, CRC10_INITFCS))) {
int actual_length = data[length - 2] >> 2; int actual_length = data[length - 2] >> 2;
if (actual_length <= (length - 2)) { if (actual_length <= (length - 2)) {
info ("%s - actual: %d", __func__, actual_length); info ("%s - actual: %d", __func__, actual_length);
tty_insert_flip_string(port->tty, data, actual_length);
for (i = 0; i < actual_length; i++) {
tty_insert_flip_char (port->tty, data[i], 0);
}
tty_flip_buffer_push (port->tty); tty_flip_buffer_push (port->tty);
} else { } else {
err ("%s - inconsistent lengths %d:%d", __func__, err ("%s - inconsistent lengths %d:%d", __func__,
...@@ -246,9 +239,7 @@ static void safe_read_bulk_callback (struct urb *urb) ...@@ -246,9 +239,7 @@ static void safe_read_bulk_callback (struct urb *urb)
err ("%s - bad CRC %x", __func__, fcs); err ("%s - bad CRC %x", __func__, fcs);
} }
} else { } else {
for (i = 0; i < length; i++) { tty_insert_flip_string(port->tty, data, length);
tty_insert_flip_char (port->tty, data[i], 0);
}
tty_flip_buffer_push (port->tty); tty_flip_buffer_push (port->tty);
} }
...@@ -260,6 +251,7 @@ static void safe_read_bulk_callback (struct urb *urb) ...@@ -260,6 +251,7 @@ static void safe_read_bulk_callback (struct urb *urb)
if ((result = usb_submit_urb (urb, GFP_ATOMIC))) { if ((result = usb_submit_urb (urb, GFP_ATOMIC))) {
err ("%s - failed resubmitting read urb, error %d", __func__, result); err ("%s - failed resubmitting read urb, error %d", __func__, result);
/* FIXME: Need a mechanism to retry later if this happens */
} }
} }
...@@ -275,7 +267,7 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i ...@@ -275,7 +267,7 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i
if (!port->write_urb) { if (!port->write_urb) {
dbg ("%s - write urb NULL", __func__); dbg ("%s - write urb NULL", __func__);
return (0); return 0;
} }
dbg ("safe_write write_urb: %d transfer_buffer_length", dbg ("safe_write write_urb: %d transfer_buffer_length",
...@@ -283,11 +275,11 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i ...@@ -283,11 +275,11 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i
if (!port->write_urb->transfer_buffer_length) { if (!port->write_urb->transfer_buffer_length) {
dbg ("%s - write urb transfer_buffer_length zero", __func__); dbg ("%s - write urb transfer_buffer_length zero", __func__);
return (0); return 0;
} }
if (count == 0) { if (count == 0) {
dbg ("%s - write request of 0 bytes", __func__); dbg ("%s - write request of 0 bytes", __func__);
return (0); return 0;
} }
spin_lock_bh(&port->lock); spin_lock_bh(&port->lock);
if (port->write_urb_busy) { if (port->write_urb_busy) {
...@@ -359,18 +351,21 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i ...@@ -359,18 +351,21 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i
static int safe_write_room (struct usb_serial_port *port) static int safe_write_room (struct usb_serial_port *port)
{ {
int room = 0; // Default: no room int room = 0; /* Default: no room */
unsigned long flags;
dbg ("%s", __func__); dbg ("%s", __func__);
spin_lock_irqsave(&port->lock, flags);
if (port->write_urb_busy) if (port->write_urb_busy)
room = port->bulk_out_size - (safe ? 2 : 0); room = port->bulk_out_size - (safe ? 2 : 0);
spin_unlock_irqrestore(&port->lock, flags);
if (room) { if (room) {
dbg ("safe_write_room returns %d", room); dbg ("safe_write_room returns %d", room);
} }
return (room); return room;
} }
static int safe_startup (struct usb_serial *serial) static int safe_startup (struct usb_serial *serial)
......
...@@ -566,6 +566,8 @@ static int sierra_chars_in_buffer(struct usb_serial_port *port) ...@@ -566,6 +566,8 @@ static int sierra_chars_in_buffer(struct usb_serial_port *port)
* have sent out, but hasn't made it through to the * have sent out, but hasn't made it through to the
* device as we can't see the backend here, so just * device as we can't see the backend here, so just
* tell the tty layer that everything is flushed. * tell the tty layer that everything is flushed.
*
* FIXME: should walk the outstanding urbs info
*/ */
return 0; return 0;
} }
......
...@@ -1179,6 +1179,8 @@ static int __init usb_serial_init(void) ...@@ -1179,6 +1179,8 @@ static int __init usb_serial_init(void)
usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
usb_serial_tty_driver->init_termios = tty_std_termios; usb_serial_tty_driver->init_termios = tty_std_termios;
usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
usb_serial_tty_driver->init_termios.c_ispeed = 9600;
usb_serial_tty_driver->init_termios.c_ospeed = 9600;
tty_set_operations(usb_serial_tty_driver, &serial_ops); tty_set_operations(usb_serial_tty_driver, &serial_ops);
result = tty_register_driver(usb_serial_tty_driver); result = tty_register_driver(usb_serial_tty_driver);
if (result) { if (result) {
......
...@@ -469,6 +469,8 @@ static int visor_chars_in_buffer (struct usb_serial_port *port) ...@@ -469,6 +469,8 @@ static int visor_chars_in_buffer (struct usb_serial_port *port)
* have sent out, but hasn't made it through to the * have sent out, but hasn't made it through to the
* device, so just tell the tty layer that everything * device, so just tell the tty layer that everything
* is flushed. * is flushed.
*
* FIXME: Should walk outstanding_urbs
*/ */
return 0; return 0;
} }
......
...@@ -219,7 +219,7 @@ struct whiteheat_urb_wrap { ...@@ -219,7 +219,7 @@ struct whiteheat_urb_wrap {
struct whiteheat_private { struct whiteheat_private {
spinlock_t lock; spinlock_t lock;
__u8 flags; __u8 flags;
__u8 mcr; __u8 mcr; /* FIXME: no locking on mcr */
struct list_head rx_urbs_free; struct list_head rx_urbs_free;
struct list_head rx_urbs_submitted; struct list_head rx_urbs_submitted;
struct list_head rx_urb_q; struct list_head rx_urb_q;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册