Commit 54a21903 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'usb-serial-4.11-rc1' of...

Merge tag 'usb-serial-4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-next

Johan writes:

USB-serial updates for v4.11-rc1

These updates include

 - a new driver for Renesas uPD78F0730-based devices

 - several fixes of failures to check for short transfers, some of which could
   lead to minor information leaks, and in one case a loop-condition underflow

 - a fix of a long-standing regression in the ftdi_sio driver which resulted
   in excessive bulk-in interrupts

 - a fix for ftdi_sio line-status over-reporting which could lead to an
   endless stream of NULL-characters being forwarded to user space

 - a fix for a regression in the console driver

 - a fix for another mos7840 NULL-pointer dereference due to a missing endpoint
   sanity check

Included are also some clean ups and fixes for various minor issues, as well as
a couple of new device IDs that came in late.

All but the final patch have been in linux-next with no reported issues.
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parents 25534828 5182c2cf
...@@ -713,6 +713,15 @@ config USB_SERIAL_QT2 ...@@ -713,6 +713,15 @@ config USB_SERIAL_QT2
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called quatech-serial. module will be called quatech-serial.
config USB_SERIAL_UPD78F0730
tristate "USB Renesas uPD78F0730 Single Port Serial Driver"
help
Say Y here if you want to use the Renesas uPD78F0730
serial driver.
To compile this driver as a module, choose M here: the
module will be called upd78f0730.
config USB_SERIAL_DEBUG config USB_SERIAL_DEBUG
tristate "USB Debugging Device" tristate "USB Debugging Device"
help help
......
...@@ -56,6 +56,7 @@ obj-$(CONFIG_USB_SERIAL_SSU100) += ssu100.o ...@@ -56,6 +56,7 @@ obj-$(CONFIG_USB_SERIAL_SSU100) += ssu100.o
obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o
obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o
obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
obj-$(CONFIG_USB_SERIAL_UPD78F0730) += upd78f0730.o
obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o
obj-$(CONFIG_USB_SERIAL_WISHBONE) += wishbone-serial.o obj-$(CONFIG_USB_SERIAL_WISHBONE) += wishbone-serial.o
obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o
......
...@@ -99,9 +99,16 @@ static int ark3116_read_reg(struct usb_serial *serial, ...@@ -99,9 +99,16 @@ static int ark3116_read_reg(struct usb_serial *serial,
usb_rcvctrlpipe(serial->dev, 0), usb_rcvctrlpipe(serial->dev, 0),
0xfe, 0xc0, 0, reg, 0xfe, 0xc0, 0, reg,
buf, 1, ARK_TIMEOUT); buf, 1, ARK_TIMEOUT);
if (result < 0) if (result < 1) {
dev_err(&serial->interface->dev,
"failed to read register %u: %d\n",
reg, result);
if (result >= 0)
result = -EIO;
return result; return result;
else }
return buf[0]; return buf[0];
} }
...@@ -118,17 +125,11 @@ static inline int calc_divisor(int bps) ...@@ -118,17 +125,11 @@ static inline int calc_divisor(int bps)
static int ark3116_attach(struct usb_serial *serial) static int ark3116_attach(struct usb_serial *serial)
{ {
/* make sure we have our end-points */ /* make sure we have our end-points */
if ((serial->num_bulk_in == 0) || if (serial->num_bulk_in == 0 ||
(serial->num_bulk_out == 0) || serial->num_bulk_out == 0 ||
(serial->num_interrupt_in == 0)) { serial->num_interrupt_in == 0) {
dev_err(&serial->dev->dev, dev_err(&serial->interface->dev, "missing endpoint\n");
"%s - missing endpoint - " return -ENODEV;
"bulk in: %d, bulk out: %d, int in %d\n",
KBUILD_MODNAME,
serial->num_bulk_in,
serial->num_bulk_out,
serial->num_interrupt_in);
return -EINVAL;
} }
return 0; return 0;
...@@ -186,10 +187,8 @@ static int ark3116_port_probe(struct usb_serial_port *port) ...@@ -186,10 +187,8 @@ static int ark3116_port_probe(struct usb_serial_port *port)
if (priv->irda) if (priv->irda)
ark3116_write_reg(serial, 0x9, 0); ark3116_write_reg(serial, 0x9, 0);
dev_info(&serial->dev->dev, dev_info(&port->dev, "using %s mode\n", priv->irda ? "IrDA" : "RS232");
"%s using %s mode\n",
KBUILD_MODNAME,
priv->irda ? "IrDA" : "RS232");
return 0; return 0;
} }
...@@ -325,9 +324,8 @@ static void ark3116_set_termios(struct tty_struct *tty, ...@@ -325,9 +324,8 @@ static void ark3116_set_termios(struct tty_struct *tty,
/* check for software flow control */ /* check for software flow control */
if (I_IXOFF(tty) || I_IXON(tty)) { if (I_IXOFF(tty) || I_IXON(tty)) {
dev_warn(&serial->dev->dev, dev_warn(&port->dev,
"%s: don't know how to do software flow control\n", "software flow control not implemented\n");
KBUILD_MODNAME);
} }
/* Don't rewrite B0 */ /* Don't rewrite B0 */
...@@ -346,7 +344,7 @@ static void ark3116_close(struct usb_serial_port *port) ...@@ -346,7 +344,7 @@ static void ark3116_close(struct usb_serial_port *port)
ark3116_write_reg(serial, UART_IER, 0); ark3116_write_reg(serial, UART_IER, 0);
usb_serial_generic_close(port); usb_serial_generic_close(port);
if (serial->num_interrupt_in)
usb_kill_urb(port->interrupt_in_urb); usb_kill_urb(port->interrupt_in_urb);
} }
...@@ -366,23 +364,29 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -366,23 +364,29 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
dev_dbg(&port->dev, dev_dbg(&port->dev,
"%s - usb_serial_generic_open failed: %d\n", "%s - usb_serial_generic_open failed: %d\n",
__func__, result); __func__, result);
goto err_out; goto err_free;
} }
/* remove any data still left: also clears error state */ /* remove any data still left: also clears error state */
ark3116_read_reg(serial, UART_RX, buf); ark3116_read_reg(serial, UART_RX, buf);
/* read modem status */ /* read modem status */
priv->msr = ark3116_read_reg(serial, UART_MSR, buf); result = ark3116_read_reg(serial, UART_MSR, buf);
if (result < 0)
goto err_close;
priv->msr = *buf;
/* read line status */ /* read line status */
priv->lsr = ark3116_read_reg(serial, UART_LSR, buf); result = ark3116_read_reg(serial, UART_LSR, buf);
if (result < 0)
goto err_close;
priv->lsr = *buf;
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result) { if (result) {
dev_err(&port->dev, "submit irq_in urb failed %d\n", dev_err(&port->dev, "submit irq_in urb failed %d\n",
result); result);
ark3116_close(port); goto err_close;
goto err_out;
} }
/* activate interrupts */ /* activate interrupts */
...@@ -395,8 +399,15 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -395,8 +399,15 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
if (tty) if (tty)
ark3116_set_termios(tty, port, NULL); ark3116_set_termios(tty, port, NULL);
err_out:
kfree(buf); kfree(buf);
return 0;
err_close:
usb_serial_generic_close(port);
err_free:
kfree(buf);
return result; return result;
} }
...@@ -602,9 +613,8 @@ static void ark3116_read_int_callback(struct urb *urb) ...@@ -602,9 +613,8 @@ static void ark3116_read_int_callback(struct urb *urb)
result = usb_submit_urb(urb, GFP_ATOMIC); result = usb_submit_urb(urb, GFP_ATOMIC);
if (result) if (result)
dev_err(&urb->dev->dev, dev_err(&port->dev, "failed to resubmit interrupt urb: %d\n",
"%s - Error %d submitting interrupt urb\n", result);
__func__, result);
} }
......
...@@ -93,8 +93,8 @@ MODULE_DEVICE_TABLE(usb, id_table); ...@@ -93,8 +93,8 @@ MODULE_DEVICE_TABLE(usb, id_table);
struct ch341_private { struct ch341_private {
spinlock_t lock; /* access lock */ spinlock_t lock; /* access lock */
unsigned baud_rate; /* set baud rate */ unsigned baud_rate; /* set baud rate */
u8 line_control; /* set line control value RTS/DTR */ u8 mcr;
u8 line_status; /* active status of modem control inputs */ u8 msr;
u8 lcr; u8 lcr;
}; };
...@@ -107,8 +107,8 @@ static int ch341_control_out(struct usb_device *dev, u8 request, ...@@ -107,8 +107,8 @@ static int ch341_control_out(struct usb_device *dev, u8 request,
{ {
int r; int r;
dev_dbg(&dev->dev, "ch341_control_out(%02x,%02x,%04x,%04x)\n", dev_dbg(&dev->dev, "%s - (%02x,%04x,%04x)\n", __func__,
USB_DIR_OUT|0x40, (int)request, (int)value, (int)index); request, value, index);
r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
...@@ -125,9 +125,8 @@ static int ch341_control_in(struct usb_device *dev, ...@@ -125,9 +125,8 @@ static int ch341_control_in(struct usb_device *dev,
{ {
int r; int r;
dev_dbg(&dev->dev, "ch341_control_in(%02x,%02x,%04x,%04x,%p,%u)\n", dev_dbg(&dev->dev, "%s - (%02x,%04x,%04x,%u)\n", __func__,
USB_DIR_IN|0x40, (int)request, (int)value, (int)index, buf, request, value, index, bufsize);
(int)bufsize);
r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
...@@ -210,7 +209,7 @@ static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv) ...@@ -210,7 +209,7 @@ static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
goto out; goto out;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT; priv->msr = (~(*buffer)) & CH341_BITS_MODEM_STAT;
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
out: kfree(buffer); out: kfree(buffer);
...@@ -239,30 +238,11 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) ...@@ -239,30 +238,11 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
if (r < 0) if (r < 0)
goto out; goto out;
/* expect two bytes 0x56 0x00 */
r = ch341_control_in(dev, CH341_REQ_READ_REG, 0x2518, 0, buffer, size);
if (r < 0)
goto out;
r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, 0x0050);
if (r < 0)
goto out;
/* expect 0xff 0xee */
r = ch341_get_status(dev, priv);
if (r < 0)
goto out;
r = ch341_set_baudrate_lcr(dev, priv, priv->lcr); r = ch341_set_baudrate_lcr(dev, priv, priv->lcr);
if (r < 0) if (r < 0)
goto out; goto out;
r = ch341_set_handshake(dev, priv->line_control); r = ch341_set_handshake(dev, priv->mcr);
if (r < 0)
goto out;
/* expect 0x9f 0xee */
r = ch341_get_status(dev, priv);
out: kfree(buffer); out: kfree(buffer);
return r; return r;
...@@ -279,6 +259,11 @@ static int ch341_port_probe(struct usb_serial_port *port) ...@@ -279,6 +259,11 @@ static int ch341_port_probe(struct usb_serial_port *port)
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
priv->baud_rate = DEFAULT_BAUD_RATE; priv->baud_rate = DEFAULT_BAUD_RATE;
/*
* Some CH340 devices appear unable to change the initial LCR
* settings, so set a sane 8N1 default.
*/
priv->lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8;
r = ch341_configure(port->serial->dev, priv); r = ch341_configure(port->serial->dev, priv);
if (r < 0) if (r < 0)
...@@ -304,7 +289,7 @@ static int ch341_port_remove(struct usb_serial_port *port) ...@@ -304,7 +289,7 @@ static int ch341_port_remove(struct usb_serial_port *port)
static int ch341_carrier_raised(struct usb_serial_port *port) static int ch341_carrier_raised(struct usb_serial_port *port)
{ {
struct ch341_private *priv = usb_get_serial_port_data(port); struct ch341_private *priv = usb_get_serial_port_data(port);
if (priv->line_status & CH341_BIT_DCD) if (priv->msr & CH341_BIT_DCD)
return 1; return 1;
return 0; return 0;
} }
...@@ -317,11 +302,11 @@ static void ch341_dtr_rts(struct usb_serial_port *port, int on) ...@@ -317,11 +302,11 @@ static void ch341_dtr_rts(struct usb_serial_port *port, int on)
/* drop DTR and RTS */ /* drop DTR and RTS */
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
if (on) if (on)
priv->line_control |= CH341_BIT_RTS | CH341_BIT_DTR; priv->mcr |= CH341_BIT_RTS | CH341_BIT_DTR;
else else
priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR); priv->mcr &= ~(CH341_BIT_RTS | CH341_BIT_DTR);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
ch341_set_handshake(port->serial->dev, priv->line_control); ch341_set_handshake(port->serial->dev, priv->mcr);
} }
static void ch341_close(struct usb_serial_port *port) static void ch341_close(struct usb_serial_port *port)
...@@ -334,14 +319,9 @@ static void ch341_close(struct usb_serial_port *port) ...@@ -334,14 +319,9 @@ static void ch341_close(struct usb_serial_port *port)
/* open this device, set default parameters */ /* open this device, set default parameters */
static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
{ {
struct usb_serial *serial = port->serial;
struct ch341_private *priv = usb_get_serial_port_data(port); struct ch341_private *priv = usb_get_serial_port_data(port);
int r; int r;
r = ch341_configure(serial->dev, priv);
if (r)
return r;
if (tty) if (tty)
ch341_set_termios(tty, port, NULL); ch341_set_termios(tty, port, NULL);
...@@ -353,6 +333,12 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -353,6 +333,12 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
return r; return r;
} }
r = ch341_get_status(port->serial->dev, priv);
if (r < 0) {
dev_err(&port->dev, "failed to read modem status: %d\n", r);
goto err_kill_interrupt_urb;
}
r = usb_serial_generic_open(tty, port); r = usb_serial_generic_open(tty, port);
if (r) if (r)
goto err_kill_interrupt_urb; goto err_kill_interrupt_urb;
...@@ -374,7 +360,7 @@ static void ch341_set_termios(struct tty_struct *tty, ...@@ -374,7 +360,7 @@ static void ch341_set_termios(struct tty_struct *tty,
struct ch341_private *priv = usb_get_serial_port_data(port); struct ch341_private *priv = usb_get_serial_port_data(port);
unsigned baud_rate; unsigned baud_rate;
unsigned long flags; unsigned long flags;
unsigned char ctrl; u8 lcr;
int r; int r;
/* redundant changes may cause the chip to lose bytes */ /* redundant changes may cause the chip to lose bytes */
...@@ -383,54 +369,54 @@ static void ch341_set_termios(struct tty_struct *tty, ...@@ -383,54 +369,54 @@ static void ch341_set_termios(struct tty_struct *tty,
baud_rate = tty_get_baud_rate(tty); baud_rate = tty_get_baud_rate(tty);
ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX; lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX;
switch (C_CSIZE(tty)) { switch (C_CSIZE(tty)) {
case CS5: case CS5:
ctrl |= CH341_LCR_CS5; lcr |= CH341_LCR_CS5;
break; break;
case CS6: case CS6:
ctrl |= CH341_LCR_CS6; lcr |= CH341_LCR_CS6;
break; break;
case CS7: case CS7:
ctrl |= CH341_LCR_CS7; lcr |= CH341_LCR_CS7;
break; break;
case CS8: case CS8:
ctrl |= CH341_LCR_CS8; lcr |= CH341_LCR_CS8;
break; break;
} }
if (C_PARENB(tty)) { if (C_PARENB(tty)) {
ctrl |= CH341_LCR_ENABLE_PAR; lcr |= CH341_LCR_ENABLE_PAR;
if (C_PARODD(tty) == 0) if (C_PARODD(tty) == 0)
ctrl |= CH341_LCR_PAR_EVEN; lcr |= CH341_LCR_PAR_EVEN;
if (C_CMSPAR(tty)) if (C_CMSPAR(tty))
ctrl |= CH341_LCR_MARK_SPACE; lcr |= CH341_LCR_MARK_SPACE;
} }
if (C_CSTOPB(tty)) if (C_CSTOPB(tty))
ctrl |= CH341_LCR_STOP_BITS_2; lcr |= CH341_LCR_STOP_BITS_2;
if (baud_rate) { if (baud_rate) {
priv->baud_rate = baud_rate; priv->baud_rate = baud_rate;
r = ch341_set_baudrate_lcr(port->serial->dev, priv, ctrl); r = ch341_set_baudrate_lcr(port->serial->dev, priv, lcr);
if (r < 0 && old_termios) { if (r < 0 && old_termios) {
priv->baud_rate = tty_termios_baud_rate(old_termios); priv->baud_rate = tty_termios_baud_rate(old_termios);
tty_termios_copy_hw(&tty->termios, old_termios); tty_termios_copy_hw(&tty->termios, old_termios);
} else if (r == 0) { } else if (r == 0) {
priv->lcr = ctrl; priv->lcr = lcr;
} }
} }
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
if (C_BAUD(tty) == B0) if (C_BAUD(tty) == B0)
priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS); priv->mcr &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS); priv->mcr |= (CH341_BIT_DTR | CH341_BIT_RTS);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
ch341_set_handshake(port->serial->dev, priv->line_control); ch341_set_handshake(port->serial->dev, priv->mcr);
} }
static void ch341_break_ctl(struct tty_struct *tty, int break_state) static void ch341_break_ctl(struct tty_struct *tty, int break_state)
...@@ -486,20 +472,20 @@ static int ch341_tiocmset(struct tty_struct *tty, ...@@ -486,20 +472,20 @@ static int ch341_tiocmset(struct tty_struct *tty,
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
if (set & TIOCM_RTS) if (set & TIOCM_RTS)
priv->line_control |= CH341_BIT_RTS; priv->mcr |= CH341_BIT_RTS;
if (set & TIOCM_DTR) if (set & TIOCM_DTR)
priv->line_control |= CH341_BIT_DTR; priv->mcr |= CH341_BIT_DTR;
if (clear & TIOCM_RTS) if (clear & TIOCM_RTS)
priv->line_control &= ~CH341_BIT_RTS; priv->mcr &= ~CH341_BIT_RTS;
if (clear & TIOCM_DTR) if (clear & TIOCM_DTR)
priv->line_control &= ~CH341_BIT_DTR; priv->mcr &= ~CH341_BIT_DTR;
control = priv->line_control; control = priv->mcr;
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
return ch341_set_handshake(port->serial->dev, control); return ch341_set_handshake(port->serial->dev, control);
} }
static void ch341_update_line_status(struct usb_serial_port *port, static void ch341_update_status(struct usb_serial_port *port,
unsigned char *data, size_t len) unsigned char *data, size_t len)
{ {
struct ch341_private *priv = usb_get_serial_port_data(port); struct ch341_private *priv = usb_get_serial_port_data(port);
...@@ -514,8 +500,8 @@ static void ch341_update_line_status(struct usb_serial_port *port, ...@@ -514,8 +500,8 @@ static void ch341_update_line_status(struct usb_serial_port *port,
status = ~data[2] & CH341_BITS_MODEM_STAT; status = ~data[2] & CH341_BITS_MODEM_STAT;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
delta = status ^ priv->line_status; delta = status ^ priv->msr;
priv->line_status = status; priv->msr = status;
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
if (data[1] & CH341_MULT_STAT) if (data[1] & CH341_MULT_STAT)
...@@ -568,7 +554,7 @@ static void ch341_read_int_callback(struct urb *urb) ...@@ -568,7 +554,7 @@ static void ch341_read_int_callback(struct urb *urb)
} }
usb_serial_debug_data(&port->dev, __func__, len, data); usb_serial_debug_data(&port->dev, __func__, len, data);
ch341_update_line_status(port, data, len); ch341_update_status(port, data, len);
exit: exit:
status = usb_submit_urb(urb, GFP_ATOMIC); status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) { if (status) {
...@@ -587,8 +573,8 @@ static int ch341_tiocmget(struct tty_struct *tty) ...@@ -587,8 +573,8 @@ static int ch341_tiocmget(struct tty_struct *tty)
unsigned int result; unsigned int result;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
mcr = priv->line_control; mcr = priv->mcr;
status = priv->line_status; status = priv->msr;
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
result = ((mcr & CH341_BIT_DTR) ? TIOCM_DTR : 0) result = ((mcr & CH341_BIT_DTR) ? TIOCM_DTR : 0)
...@@ -619,6 +605,12 @@ static int ch341_reset_resume(struct usb_serial *serial) ...@@ -619,6 +605,12 @@ static int ch341_reset_resume(struct usb_serial *serial)
ret); ret);
return ret; return ret;
} }
ret = ch341_get_status(port->serial->dev, priv);
if (ret < 0) {
dev_err(&port->dev, "failed to read modem status: %d\n",
ret);
}
} }
return usb_serial_generic_resume(serial); return usb_serial_generic_resume(serial);
......
...@@ -143,6 +143,7 @@ static int usb_console_setup(struct console *co, char *options) ...@@ -143,6 +143,7 @@ static int usb_console_setup(struct console *co, char *options)
tty->driver = usb_serial_tty_driver; tty->driver = usb_serial_tty_driver;
tty->index = co->index; tty->index = co->index;
init_ldsem(&tty->ldisc_sem); init_ldsem(&tty->ldisc_sem);
spin_lock_init(&tty->files_lock);
INIT_LIST_HEAD(&tty->tty_files); INIT_LIST_HEAD(&tty->tty_files);
kref_get(&tty->driver->kref); kref_get(&tty->driver->kref);
__module_get(tty->driver->owner); __module_get(tty->driver->owner);
...@@ -264,8 +265,7 @@ static struct console usbcons = { ...@@ -264,8 +265,7 @@ static struct console usbcons = {
void usb_serial_console_disconnect(struct usb_serial *serial) void usb_serial_console_disconnect(struct usb_serial *serial)
{ {
if (serial && serial->port && serial->port[0] if (serial->port[0] == usbcons_info.port) {
&& serial->port[0] == usbcons_info.port) {
usb_serial_console_exit(); usb_serial_console_exit();
usb_serial_put(serial); usb_serial_put(serial);
} }
......
...@@ -178,6 +178,8 @@ static const struct usb_device_id id_table[] = { ...@@ -178,6 +178,8 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
{ USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
{ USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */
{ USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
......
...@@ -1069,7 +1069,6 @@ static void cypress_read_int_callback(struct urb *urb) ...@@ -1069,7 +1069,6 @@ static void cypress_read_int_callback(struct urb *urb)
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
unsigned long flags; unsigned long flags;
char tty_flag = TTY_NORMAL; char tty_flag = TTY_NORMAL;
int havedata = 0;
int bytes = 0; int bytes = 0;
int result; int result;
int i = 0; int i = 0;
...@@ -1118,16 +1117,12 @@ static void cypress_read_int_callback(struct urb *urb) ...@@ -1118,16 +1117,12 @@ static void cypress_read_int_callback(struct urb *urb)
priv->current_status = data[0] & 0xF8; priv->current_status = data[0] & 0xF8;
bytes = data[1] + 2; bytes = data[1] + 2;
i = 2; i = 2;
if (bytes > 2)
havedata = 1;
break; break;
case packet_format_2: case packet_format_2:
/* This is for the CY7C63743... */ /* This is for the CY7C63743... */
priv->current_status = data[0] & 0xF8; priv->current_status = data[0] & 0xF8;
bytes = (data[0] & 0x07) + 1; bytes = (data[0] & 0x07) + 1;
i = 1; i = 1;
if (bytes > 1)
havedata = 1;
break; break;
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
......
...@@ -1398,25 +1398,30 @@ static int digi_read_inb_callback(struct urb *urb) ...@@ -1398,25 +1398,30 @@ static int digi_read_inb_callback(struct urb *urb)
{ {
struct usb_serial_port *port = urb->context; struct usb_serial_port *port = urb->context;
struct digi_port *priv = usb_get_serial_port_data(port); struct digi_port *priv = usb_get_serial_port_data(port);
int opcode = ((unsigned char *)urb->transfer_buffer)[0]; unsigned char *buf = urb->transfer_buffer;
int len = ((unsigned char *)urb->transfer_buffer)[1]; int opcode;
int port_status = ((unsigned char *)urb->transfer_buffer)[2]; int len;
unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3; int port_status;
unsigned char *data;
int flag, throttled; int flag, throttled;
int status = urb->status;
/* do not process callbacks on closed ports */
/* but do continue the read chain */
if (urb->status == -ENOENT)
return 0;
/* short/multiple packet check */ /* short/multiple packet check */
if (urb->actual_length < 2) {
dev_warn(&port->dev, "short packet received\n");
return -1;
}
opcode = buf[0];
len = buf[1];
if (urb->actual_length != len + 2) { if (urb->actual_length != len + 2) {
dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, " dev_err(&port->dev, "malformed packet received: port=%d, opcode=%d, len=%d, actual_length=%u\n",
"status=%d, port=%d, opcode=%d, len=%d, " priv->dp_port_num, opcode, len, urb->actual_length);
"actual_length=%d, status=%d\n", __func__, status, return -1;
priv->dp_port_num, opcode, len, urb->actual_length, }
port_status);
if (opcode == DIGI_CMD_RECEIVE_DATA && len < 1) {
dev_err(&port->dev, "malformed data packet received\n");
return -1; return -1;
} }
...@@ -1430,6 +1435,9 @@ static int digi_read_inb_callback(struct urb *urb) ...@@ -1430,6 +1435,9 @@ static int digi_read_inb_callback(struct urb *urb)
/* receive data */ /* receive data */
if (opcode == DIGI_CMD_RECEIVE_DATA) { if (opcode == DIGI_CMD_RECEIVE_DATA) {
port_status = buf[2];
data = &buf[3];
/* get flag from port_status */ /* get flag from port_status */
flag = 0; flag = 0;
...@@ -1482,16 +1490,20 @@ static int digi_read_oob_callback(struct urb *urb) ...@@ -1482,16 +1490,20 @@ static int digi_read_oob_callback(struct urb *urb)
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
struct tty_struct *tty; struct tty_struct *tty;
struct digi_port *priv = usb_get_serial_port_data(port); struct digi_port *priv = usb_get_serial_port_data(port);
unsigned char *buf = urb->transfer_buffer;
int opcode, line, status, val; int opcode, line, status, val;
int i; int i;
unsigned int rts; unsigned int rts;
if (urb->actual_length < 4)
return -1;
/* handle each oob command */ /* handle each oob command */
for (i = 0; i < urb->actual_length - 3;) { for (i = 0; i < urb->actual_length - 4; i += 4) {
opcode = ((unsigned char *)urb->transfer_buffer)[i++]; opcode = buf[i];
line = ((unsigned char *)urb->transfer_buffer)[i++]; line = buf[i + 1];
status = ((unsigned char *)urb->transfer_buffer)[i++]; status = buf[i + 2];
val = ((unsigned char *)urb->transfer_buffer)[i++]; val = buf[i + 3];
dev_dbg(&port->dev, "digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d\n", dev_dbg(&port->dev, "digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d\n",
opcode, line, status, val); opcode, line, status, val);
......
...@@ -1439,10 +1439,13 @@ static int read_latency_timer(struct usb_serial_port *port) ...@@ -1439,10 +1439,13 @@ static int read_latency_timer(struct usb_serial_port *port)
FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
0, priv->interface, 0, priv->interface,
buf, 1, WDR_TIMEOUT); buf, 1, WDR_TIMEOUT);
if (rv < 0) if (rv < 1) {
dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); dev_err(&port->dev, "Unable to read latency timer: %i\n", rv);
else if (rv >= 0)
rv = -EIO;
} else {
priv->latency = buf[0]; priv->latency = buf[0];
}
kfree(buf); kfree(buf);
...@@ -1531,7 +1534,7 @@ static int set_serial_info(struct tty_struct *tty, ...@@ -1531,7 +1534,7 @@ static int set_serial_info(struct tty_struct *tty,
} }
static int get_lsr_info(struct usb_serial_port *port, static int get_lsr_info(struct usb_serial_port *port,
struct serial_struct __user *retinfo) unsigned int __user *retinfo)
{ {
struct ftdi_private *priv = usb_get_serial_port_data(port); struct ftdi_private *priv = usb_get_serial_port_data(port);
unsigned int result = 0; unsigned int result = 0;
...@@ -1802,8 +1805,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) ...@@ -1802,8 +1805,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
mutex_init(&priv->cfg_lock); mutex_init(&priv->cfg_lock);
priv->flags = ASYNC_LOW_LATENCY;
if (quirk && quirk->port_probe) if (quirk && quirk->port_probe)
quirk->port_probe(priv); quirk->port_probe(priv);
...@@ -2067,6 +2068,20 @@ static int ftdi_process_packet(struct usb_serial_port *port, ...@@ -2067,6 +2068,20 @@ static int ftdi_process_packet(struct usb_serial_port *port,
priv->prev_status = status; priv->prev_status = status;
} }
/* save if the transmitter is empty or not */
if (packet[1] & FTDI_RS_TEMT)
priv->transmit_empty = 1;
else
priv->transmit_empty = 0;
len -= 2;
if (!len)
return 0; /* status only */
/*
* Break and error status must only be processed for packets with
* data payload to avoid over-reporting.
*/
flag = TTY_NORMAL; flag = TTY_NORMAL;
if (packet[1] & FTDI_RS_ERR_MASK) { if (packet[1] & FTDI_RS_ERR_MASK) {
/* Break takes precedence over parity, which takes precedence /* Break takes precedence over parity, which takes precedence
...@@ -2089,15 +2104,6 @@ static int ftdi_process_packet(struct usb_serial_port *port, ...@@ -2089,15 +2104,6 @@ static int ftdi_process_packet(struct usb_serial_port *port,
} }
} }
/* save if the transmitter is empty or not */
if (packet[1] & FTDI_RS_TEMT)
priv->transmit_empty = 1;
else
priv->transmit_empty = 0;
len -= 2;
if (!len)
return 0; /* status only */
port->icount.rx += len; port->icount.rx += len;
ch = packet + 2; ch = packet + 2;
...@@ -2428,8 +2434,12 @@ static int ftdi_get_modem_status(struct usb_serial_port *port, ...@@ -2428,8 +2434,12 @@ static int ftdi_get_modem_status(struct usb_serial_port *port,
FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
0, priv->interface, 0, priv->interface,
buf, len, WDR_TIMEOUT); buf, len, WDR_TIMEOUT);
if (ret < 0) {
/* NOTE: We allow short responses and handle that below. */
if (ret < 1) {
dev_err(&port->dev, "failed to get modem status: %d\n", ret); dev_err(&port->dev, "failed to get modem status: %d\n", ret);
if (ret >= 0)
ret = -EIO;
ret = usb_translate_errors(ret); ret = usb_translate_errors(ret);
goto out; goto out;
} }
...@@ -2480,20 +2490,15 @@ static int ftdi_ioctl(struct tty_struct *tty, ...@@ -2480,20 +2490,15 @@ static int ftdi_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
struct usb_serial_port *port = tty->driver_data; struct usb_serial_port *port = tty->driver_data;
void __user *argp = (void __user *)arg;
/* Based on code from acm.c and others */
switch (cmd) { switch (cmd) {
case TIOCGSERIAL:
case TIOCGSERIAL: /* gets serial port data */ return get_serial_info(port, argp);
return get_serial_info(port, case TIOCSSERIAL:
(struct serial_struct __user *) arg); return set_serial_info(tty, port, argp);
case TIOCSSERIAL: /* sets serial port data */
return set_serial_info(tty, port,
(struct serial_struct __user *) arg);
case TIOCSERGETLSR: case TIOCSERGETLSR:
return get_lsr_info(port, (struct serial_struct __user *)arg); return get_lsr_info(port, argp);
break;
default: default:
break; break;
} }
......
...@@ -492,20 +492,24 @@ static int get_epic_descriptor(struct edgeport_serial *ep) ...@@ -492,20 +492,24 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
int result; int result;
struct usb_serial *serial = ep->serial; struct usb_serial *serial = ep->serial;
struct edgeport_product_info *product_info = &ep->product_info; struct edgeport_product_info *product_info = &ep->product_info;
struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; struct edge_compatibility_descriptor *epic;
struct edge_compatibility_bits *bits; struct edge_compatibility_bits *bits;
struct device *dev = &serial->dev->dev; struct device *dev = &serial->dev->dev;
ep->is_epic = 0; ep->is_epic = 0;
epic = kmalloc(sizeof(*epic), GFP_KERNEL);
if (!epic)
return -ENOMEM;
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
USB_REQUEST_ION_GET_EPIC_DESC, USB_REQUEST_ION_GET_EPIC_DESC,
0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00,
&ep->epic_descriptor, epic, sizeof(*epic),
sizeof(struct edge_compatibility_descriptor),
300); 300);
if (result == sizeof(*epic)) {
if (result > 0) {
ep->is_epic = 1; ep->is_epic = 1;
memcpy(&ep->epic_descriptor, epic, sizeof(*epic));
memset(product_info, 0, sizeof(struct edgeport_product_info)); memset(product_info, 0, sizeof(struct edgeport_product_info));
product_info->NumPorts = epic->NumPorts; product_info->NumPorts = epic->NumPorts;
...@@ -534,8 +538,16 @@ static int get_epic_descriptor(struct edgeport_serial *ep) ...@@ -534,8 +538,16 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
dev_dbg(dev, " IOSPWriteLCR : %s\n", bits->IOSPWriteLCR ? "TRUE": "FALSE"); dev_dbg(dev, " IOSPWriteLCR : %s\n", bits->IOSPWriteLCR ? "TRUE": "FALSE");
dev_dbg(dev, " IOSPSetBaudRate : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE"); dev_dbg(dev, " IOSPSetBaudRate : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE");
dev_dbg(dev, " TrueEdgeport : %s\n", bits->TrueEdgeport ? "TRUE": "FALSE"); dev_dbg(dev, " TrueEdgeport : %s\n", bits->TrueEdgeport ? "TRUE": "FALSE");
result = 0;
} else if (result >= 0) {
dev_warn(&serial->interface->dev, "short epic descriptor received: %d\n",
result);
result = -EIO;
} }
kfree(epic);
return result; return result;
} }
...@@ -1560,7 +1572,6 @@ static int get_serial_info(struct edgeport_port *edge_port, ...@@ -1560,7 +1572,6 @@ static int get_serial_info(struct edgeport_port *edge_port,
tmp.line = edge_port->port->minor; tmp.line = edge_port->port->minor;
tmp.port = edge_port->port->port_number; tmp.port = edge_port->port->port_number;
tmp.irq = 0; tmp.irq = 0;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
tmp.xmit_fifo_size = edge_port->maxTxCredits; tmp.xmit_fifo_size = edge_port->maxTxCredits;
tmp.baud_base = 9600; tmp.baud_base = 9600;
tmp.close_delay = 5*HZ; tmp.close_delay = 5*HZ;
...@@ -2090,8 +2101,7 @@ static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, ...@@ -2090,8 +2101,7 @@ static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
* rom_read * rom_read
* reads a number of bytes from the Edgeport device starting at the given * reads a number of bytes from the Edgeport device starting at the given
* address. * address.
* If successful returns the number of bytes read, otherwise it returns * Returns zero on success or a negative error number.
* a negative error number of the problem.
****************************************************************************/ ****************************************************************************/
static int rom_read(struct usb_serial *serial, __u16 extAddr, static int rom_read(struct usb_serial *serial, __u16 extAddr,
__u16 addr, __u16 length, __u8 *data) __u16 addr, __u16 length, __u8 *data)
...@@ -2116,12 +2126,17 @@ static int rom_read(struct usb_serial *serial, __u16 extAddr, ...@@ -2116,12 +2126,17 @@ static int rom_read(struct usb_serial *serial, __u16 extAddr,
USB_REQUEST_ION_READ_ROM, USB_REQUEST_ION_READ_ROM,
0xC0, addr, extAddr, transfer_buffer, 0xC0, addr, extAddr, transfer_buffer,
current_length, 300); current_length, 300);
if (result < 0) if (result < current_length) {
if (result >= 0)
result = -EIO;
break; break;
}
memcpy(data, transfer_buffer, current_length); memcpy(data, transfer_buffer, current_length);
length -= current_length; length -= current_length;
addr += current_length; addr += current_length;
data += current_length; data += current_length;
result = 0;
} }
kfree(transfer_buffer); kfree(transfer_buffer);
...@@ -2575,9 +2590,10 @@ static void get_manufacturing_desc(struct edgeport_serial *edge_serial) ...@@ -2575,9 +2590,10 @@ static void get_manufacturing_desc(struct edgeport_serial *edge_serial)
EDGE_MANUF_DESC_LEN, EDGE_MANUF_DESC_LEN,
(__u8 *)(&edge_serial->manuf_descriptor)); (__u8 *)(&edge_serial->manuf_descriptor));
if (response < 1) if (response < 0) {
dev_err(dev, "error in getting manufacturer descriptor\n"); dev_err(dev, "error in getting manufacturer descriptor: %d\n",
else { response);
} else {
char string[30]; char string[30];
dev_dbg(dev, "**Manufacturer Descriptor\n"); dev_dbg(dev, "**Manufacturer Descriptor\n");
dev_dbg(dev, " RomSize: %dK\n", dev_dbg(dev, " RomSize: %dK\n",
...@@ -2634,9 +2650,10 @@ static void get_boot_desc(struct edgeport_serial *edge_serial) ...@@ -2634,9 +2650,10 @@ static void get_boot_desc(struct edgeport_serial *edge_serial)
EDGE_BOOT_DESC_LEN, EDGE_BOOT_DESC_LEN,
(__u8 *)(&edge_serial->boot_descriptor)); (__u8 *)(&edge_serial->boot_descriptor));
if (response < 1) if (response < 0) {
dev_err(dev, "error in getting boot descriptor\n"); dev_err(dev, "error in getting boot descriptor: %d\n",
else { response);
} else {
dev_dbg(dev, "**Boot Descriptor:\n"); dev_dbg(dev, "**Boot Descriptor:\n");
dev_dbg(dev, " BootCodeLength: %d\n", dev_dbg(dev, " BootCodeLength: %d\n",
le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength)); le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength));
...@@ -2779,7 +2796,7 @@ static int edge_startup(struct usb_serial *serial) ...@@ -2779,7 +2796,7 @@ static int edge_startup(struct usb_serial *serial)
dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name);
/* Read the epic descriptor */ /* Read the epic descriptor */
if (get_epic_descriptor(edge_serial) <= 0) { if (get_epic_descriptor(edge_serial) < 0) {
/* memcpy descriptor to Supports structures */ /* memcpy descriptor to Supports structures */
memcpy(&edge_serial->epic_descriptor.Supports, descriptor, memcpy(&edge_serial->epic_descriptor.Supports, descriptor,
sizeof(struct edge_compatibility_bits)); sizeof(struct edge_compatibility_bits));
......
...@@ -2468,7 +2468,6 @@ static int get_serial_info(struct edgeport_port *edge_port, ...@@ -2468,7 +2468,6 @@ static int get_serial_info(struct edgeport_port *edge_port,
tmp.line = edge_port->port->minor; tmp.line = edge_port->port->minor;
tmp.port = edge_port->port->port_number; tmp.port = edge_port->port->port_number;
tmp.irq = 0; tmp.irq = 0;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
tmp.xmit_fifo_size = edge_port->port->bulk_out_size; tmp.xmit_fifo_size = edge_port->port->bulk_out_size;
tmp.baud_base = 9600; tmp.baud_base = 9600;
tmp.close_delay = 5*HZ; tmp.close_delay = 5*HZ;
......
...@@ -976,7 +976,6 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -976,7 +976,6 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
{ {
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
struct device *dev = &port->dev; struct device *dev = &port->dev;
u8 *buf;
int result; int result;
int baud; int baud;
u32 actual; u32 actual;
...@@ -991,20 +990,8 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -991,20 +990,8 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
usb_clear_halt(serial->dev, port->write_urb->pipe); usb_clear_halt(serial->dev, port->write_urb->pipe);
usb_clear_halt(serial->dev, port->read_urb->pipe); usb_clear_halt(serial->dev, port->read_urb->pipe);
buf = kmalloc(10, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
priv->poll = 0; priv->poll = 0;
/* initialize writebuf */
#define FISH(a, b, c, d) do { \
result = usb_control_msg(port->serial->dev, \
usb_rcvctrlpipe(port->serial->dev, 0), \
b, a, c, d, buf, 1, 1000); \
dev_dbg(dev, "0x%x:0x%x:0x%x:0x%x %d - %x\n", a, b, c, d, result, \
buf[0]); } while (0);
#define SOUP(a, b, c, d) do { \ #define SOUP(a, b, c, d) do { \
result = usb_control_msg(port->serial->dev, \ result = usb_control_msg(port->serial->dev, \
usb_sndctrlpipe(port->serial->dev, 0), \ usb_sndctrlpipe(port->serial->dev, 0), \
...@@ -1017,7 +1004,7 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -1017,7 +1004,7 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
/* sprintf(buf ,"%c%c%c%c",0x03,0x02,0x02,0x0); */ /* sprintf(buf ,"%c%c%c%c",0x03,0x02,0x02,0x0); */
SOUP(0x03, 0x02, 0x02, 0x0); SOUP(0x03, 0x02, 0x02, 0x0);
kfree(buf);
iuu_led(port, 0xF000, 0xF000, 0, 0xFF); iuu_led(port, 0xF000, 0xF000, 0, 0xFF);
iuu_uart_on(port); iuu_uart_on(port);
if (boost < 100) if (boost < 100)
......
...@@ -139,6 +139,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) ...@@ -139,6 +139,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
{ {
struct usb_serial_port *port = urb->context; struct usb_serial_port *port = urb->context;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
unsigned int len = urb->actual_length;
int retval; int retval;
int status = urb->status; int status = urb->status;
struct keyspan_pda_private *priv; struct keyspan_pda_private *priv;
...@@ -159,18 +160,26 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) ...@@ -159,18 +160,26 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
goto exit; goto exit;
} }
if (len < 1) {
dev_warn(&port->dev, "short message received\n");
goto exit;
}
/* see if the message is data or a status interrupt */ /* see if the message is data or a status interrupt */
switch (data[0]) { switch (data[0]) {
case 0: case 0:
/* rest of message is rx data */ /* rest of message is rx data */
if (urb->actual_length) { if (len < 2)
tty_insert_flip_string(&port->port, data + 1, break;
urb->actual_length - 1); tty_insert_flip_string(&port->port, data + 1, len - 1);
tty_flip_buffer_push(&port->port); tty_flip_buffer_push(&port->port);
}
break; break;
case 1: case 1:
/* status interrupt */ /* status interrupt */
if (len < 3) {
dev_warn(&port->dev, "short interrupt message received\n");
break;
}
dev_dbg(&port->dev, "rx int, d1=%d, d2=%d\n", data[1], data[2]); dev_dbg(&port->dev, "rx int, d1=%d, d2=%d\n", data[1], data[2]);
switch (data[1]) { switch (data[1]) {
case 1: /* modemline change */ case 1: /* modemline change */
......
...@@ -89,7 +89,6 @@ static struct usb_serial_driver kl5kusb105d_device = { ...@@ -89,7 +89,6 @@ static struct usb_serial_driver kl5kusb105d_device = {
.open = klsi_105_open, .open = klsi_105_open,
.close = klsi_105_close, .close = klsi_105_close,
.set_termios = klsi_105_set_termios, .set_termios = klsi_105_set_termios,
/*.break_ctl = klsi_105_break_ctl,*/
.tiocmget = klsi_105_tiocmget, .tiocmget = klsi_105_tiocmget,
.port_probe = klsi_105_port_probe, .port_probe = klsi_105_port_probe,
.port_remove = klsi_105_port_remove, .port_remove = klsi_105_port_remove,
...@@ -104,16 +103,15 @@ static struct usb_serial_driver * const serial_drivers[] = { ...@@ -104,16 +103,15 @@ static struct usb_serial_driver * const serial_drivers[] = {
}; };
struct klsi_105_port_settings { struct klsi_105_port_settings {
__u8 pktlen; /* always 5, it seems */ u8 pktlen; /* always 5, it seems */
__u8 baudrate; u8 baudrate;
__u8 databits; u8 databits;
__u8 unknown1; u8 unknown1;
__u8 unknown2; u8 unknown2;
} __attribute__ ((packed)); };
struct klsi_105_private { struct klsi_105_private {
struct klsi_105_port_settings cfg; struct klsi_105_port_settings cfg;
struct ktermios termios;
unsigned long line_state; /* modem line settings */ unsigned long line_state; /* modem line settings */
spinlock_t lock; spinlock_t lock;
}; };
...@@ -143,10 +141,12 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port, ...@@ -143,10 +141,12 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port,
if (rc < 0) if (rc < 0)
dev_err(&port->dev, dev_err(&port->dev,
"Change port settings failed (error = %d)\n", rc); "Change port settings failed (error = %d)\n", rc);
dev_info(&port->serial->dev->dev,
"%d byte block, baudrate %x, databits %d, u1 %d, u2 %d\n", dev_dbg(&port->dev,
"pktlen %u, baudrate 0x%02x, databits %u, u1 %u, u2 %u\n",
settings->pktlen, settings->baudrate, settings->databits, settings->pktlen, settings->baudrate, settings->databits,
settings->unknown1, settings->unknown2); settings->unknown1, settings->unknown2);
return rc; return rc;
} }
...@@ -175,8 +175,6 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, ...@@ -175,8 +175,6 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
u8 *status_buf; u8 *status_buf;
__u16 status; __u16 status;
dev_info(&port->serial->dev->dev, "sending SIO Poll request\n");
status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL); status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL);
if (!status_buf) if (!status_buf)
return -ENOMEM; return -ENOMEM;
...@@ -199,7 +197,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, ...@@ -199,7 +197,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
} else { } else {
status = get_unaligned_le16(status_buf); status = get_unaligned_le16(status_buf);
dev_info(&port->serial->dev->dev, "read status %x %x\n", dev_dbg(&port->dev, "read status %02x %02x\n",
status_buf[0], status_buf[1]); status_buf[0], status_buf[1]);
*line_state_p = klsi_105_status2linestate(status); *line_state_p = klsi_105_status2linestate(status);
...@@ -233,8 +231,6 @@ static int klsi_105_port_probe(struct usb_serial_port *port) ...@@ -233,8 +231,6 @@ static int klsi_105_port_probe(struct usb_serial_port *port)
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
/* priv->termios is left uninitialized until port opening */
usb_set_serial_port_data(port, priv); usb_set_serial_port_data(port, priv);
return 0; return 0;
...@@ -255,7 +251,6 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -255,7 +251,6 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
struct klsi_105_private *priv = usb_get_serial_port_data(port); struct klsi_105_private *priv = usb_get_serial_port_data(port);
int retval = 0; int retval = 0;
int rc; int rc;
int i;
unsigned long line_state; unsigned long line_state;
struct klsi_105_port_settings *cfg; struct klsi_105_port_settings *cfg;
unsigned long flags; unsigned long flags;
...@@ -278,14 +273,7 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -278,14 +273,7 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
cfg->unknown2 = 1; cfg->unknown2 = 1;
klsi_105_chg_port_settings(port, cfg); klsi_105_chg_port_settings(port, cfg);
/* set up termios structure */
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
priv->termios.c_iflag = tty->termios.c_iflag;
priv->termios.c_oflag = tty->termios.c_oflag;
priv->termios.c_cflag = tty->termios.c_cflag;
priv->termios.c_lflag = tty->termios.c_lflag;
for (i = 0; i < NCCS; i++)
priv->termios.c_cc[i] = tty->termios.c_cc[i];
priv->cfg.pktlen = cfg->pktlen; priv->cfg.pktlen = cfg->pktlen;
priv->cfg.baudrate = cfg->baudrate; priv->cfg.baudrate = cfg->baudrate;
priv->cfg.databits = cfg->databits; priv->cfg.databits = cfg->databits;
...@@ -438,19 +426,6 @@ static void klsi_105_set_termios(struct tty_struct *tty, ...@@ -438,19 +426,6 @@ static void klsi_105_set_termios(struct tty_struct *tty,
*/ */
baud = tty_get_baud_rate(tty); baud = tty_get_baud_rate(tty);
if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
/* reassert DTR and (maybe) RTS on transition from B0 */
if ((old_cflag & CBAUD) == B0) {
dev_dbg(dev, "%s: baud was B0\n", __func__);
#if 0
priv->control_state |= TIOCM_DTR;
/* don't set RTS if using hardware flow control */
if (!(old_cflag & CRTSCTS))
priv->control_state |= TIOCM_RTS;
mct_u232_set_modem_ctrl(serial, priv->control_state);
#endif
}
}
switch (baud) { switch (baud) {
case 0: /* handled below */ case 0: /* handled below */
break; break;
...@@ -484,17 +459,14 @@ static void klsi_105_set_termios(struct tty_struct *tty, ...@@ -484,17 +459,14 @@ static void klsi_105_set_termios(struct tty_struct *tty,
baud = 9600; baud = 9600;
break; break;
} }
if ((cflag & CBAUD) == B0) {
dev_dbg(dev, "%s: baud is B0\n", __func__); /*
/* Drop RTS and DTR */ * FIXME: implement B0 handling
/* maybe this should be simulated by sending read *
* disable and read enable messages? * Maybe this should be simulated by sending read disable and read
* enable messages?
*/ */
#if 0
priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
mct_u232_set_modem_ctrl(serial, priv->control_state);
#endif
}
tty_encode_baud_rate(tty, baud, baud); tty_encode_baud_rate(tty, baud, baud);
if ((cflag & CSIZE) != (old_cflag & CSIZE)) { if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
...@@ -528,22 +500,6 @@ static void klsi_105_set_termios(struct tty_struct *tty, ...@@ -528,22 +500,6 @@ static void klsi_105_set_termios(struct tty_struct *tty,
|| (cflag & CSTOPB) != (old_cflag & CSTOPB)) { || (cflag & CSTOPB) != (old_cflag & CSTOPB)) {
/* Not currently supported */ /* Not currently supported */
tty->termios.c_cflag &= ~(PARENB|PARODD|CSTOPB); tty->termios.c_cflag &= ~(PARENB|PARODD|CSTOPB);
#if 0
priv->last_lcr = 0;
/* set the parity */
if (cflag & PARENB)
priv->last_lcr |= (cflag & PARODD) ?
MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
else
priv->last_lcr |= MCT_U232_PARITY_NONE;
/* set the number of stop bits */
priv->last_lcr |= (cflag & CSTOPB) ?
MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
mct_u232_set_line_ctrl(serial, priv->last_lcr);
#endif
} }
/* /*
* Set flow control: well, I do not really now how to handle DTR/RTS. * Set flow control: well, I do not really now how to handle DTR/RTS.
...@@ -554,14 +510,6 @@ static void klsi_105_set_termios(struct tty_struct *tty, ...@@ -554,14 +510,6 @@ static void klsi_105_set_termios(struct tty_struct *tty,
|| (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
/* Not currently supported */ /* Not currently supported */
tty->termios.c_cflag &= ~CRTSCTS; tty->termios.c_cflag &= ~CRTSCTS;
/* Drop DTR/RTS if no flow control otherwise assert */
#if 0
if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
priv->control_state |= TIOCM_DTR | TIOCM_RTS;
else
priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
mct_u232_set_modem_ctrl(serial, priv->control_state);
#endif
} }
memcpy(cfg, &priv->cfg, sizeof(*cfg)); memcpy(cfg, &priv->cfg, sizeof(*cfg));
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
...@@ -572,25 +520,6 @@ static void klsi_105_set_termios(struct tty_struct *tty, ...@@ -572,25 +520,6 @@ static void klsi_105_set_termios(struct tty_struct *tty,
kfree(cfg); kfree(cfg);
} }
#if 0
static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
struct mct_u232_private *priv =
(struct mct_u232_private *)port->private;
unsigned char lcr = priv->last_lcr;
dev_dbg(&port->dev, "%s - state=%d\n", __func__, break_state);
/* LOCKING */
if (break_state)
lcr |= MCT_U232_SET_BREAK;
mct_u232_set_line_ctrl(serial, lcr);
}
#endif
static int klsi_105_tiocmget(struct tty_struct *tty) static int klsi_105_tiocmget(struct tty_struct *tty)
{ {
struct usb_serial_port *port = tty->driver_data; struct usb_serial_port *port = tty->driver_data;
......
...@@ -322,8 +322,12 @@ static int mct_u232_get_modem_stat(struct usb_serial_port *port, ...@@ -322,8 +322,12 @@ static int mct_u232_get_modem_stat(struct usb_serial_port *port,
MCT_U232_GET_REQUEST_TYPE, MCT_U232_GET_REQUEST_TYPE,
0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE, 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
WDR_TIMEOUT); WDR_TIMEOUT);
if (rc < 0) { if (rc < MCT_U232_GET_MODEM_STAT_SIZE) {
dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc); dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
if (rc >= 0)
rc = -EIO;
*msr = 0; *msr = 0;
} else { } else {
*msr = buf[0]; *msr = buf[0];
......
...@@ -135,23 +135,8 @@ static void metrousb_read_int_callback(struct urb *urb) ...@@ -135,23 +135,8 @@ static void metrousb_read_int_callback(struct urb *urb)
throttled = metro_priv->throttled; throttled = metro_priv->throttled;
spin_unlock_irqrestore(&metro_priv->lock, flags); spin_unlock_irqrestore(&metro_priv->lock, flags);
/* Continue trying to read if set. */ if (throttled)
if (!throttled) {
usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
usb_rcvintpipe(port->serial->dev, port->interrupt_in_endpointAddress),
port->interrupt_in_urb->transfer_buffer,
port->interrupt_in_urb->transfer_buffer_length,
metrousb_read_int_callback, port, 1);
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
dev_err(&port->dev,
"%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result);
}
return; return;
exit: exit:
/* Try to resubmit the urb. */ /* Try to resubmit the urb. */
result = usb_submit_urb(urb, GFP_ATOMIC); result = usb_submit_urb(urb, GFP_ATOMIC);
...@@ -161,19 +146,8 @@ static void metrousb_read_int_callback(struct urb *urb) ...@@ -161,19 +146,8 @@ static void metrousb_read_int_callback(struct urb *urb)
__func__, result); __func__, result);
} }
static void metrousb_write_int_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
dev_warn(&port->dev, "%s not implemented yet.\n",
__func__);
}
static void metrousb_cleanup(struct usb_serial_port *port) static void metrousb_cleanup(struct usb_serial_port *port)
{ {
dev_dbg(&port->dev, "%s\n", __func__);
usb_unlink_urb(port->interrupt_in_urb);
usb_kill_urb(port->interrupt_in_urb); usb_kill_urb(port->interrupt_in_urb);
metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port);
...@@ -186,8 +160,6 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -186,8 +160,6 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
unsigned long flags = 0; unsigned long flags = 0;
int result = 0; int result = 0;
dev_dbg(&port->dev, "%s\n", __func__);
/* Make sure the urb is initialized. */ /* Make sure the urb is initialized. */
if (!port->interrupt_in_urb) { if (!port->interrupt_in_urb) {
dev_err(&port->dev, "%s - interrupt urb not initialized\n", dev_err(&port->dev, "%s - interrupt urb not initialized\n",
...@@ -227,8 +199,6 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -227,8 +199,6 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
__func__, result); __func__, result);
goto exit; goto exit;
} }
dev_dbg(&port->dev, "%s - port open\n", __func__);
exit: exit:
return result; return result;
} }
...@@ -290,8 +260,6 @@ static void metrousb_throttle(struct tty_struct *tty) ...@@ -290,8 +260,6 @@ static void metrousb_throttle(struct tty_struct *tty)
struct metrousb_private *metro_priv = usb_get_serial_port_data(port); struct metrousb_private *metro_priv = usb_get_serial_port_data(port);
unsigned long flags = 0; unsigned long flags = 0;
dev_dbg(tty->dev, "%s\n", __func__);
/* Set the private information for the port to stop reading data. */ /* Set the private information for the port to stop reading data. */
spin_lock_irqsave(&metro_priv->lock, flags); spin_lock_irqsave(&metro_priv->lock, flags);
metro_priv->throttled = 1; metro_priv->throttled = 1;
...@@ -305,8 +273,6 @@ static int metrousb_tiocmget(struct tty_struct *tty) ...@@ -305,8 +273,6 @@ static int metrousb_tiocmget(struct tty_struct *tty)
struct metrousb_private *metro_priv = usb_get_serial_port_data(port); struct metrousb_private *metro_priv = usb_get_serial_port_data(port);
unsigned long flags = 0; unsigned long flags = 0;
dev_dbg(tty->dev, "%s\n", __func__);
spin_lock_irqsave(&metro_priv->lock, flags); spin_lock_irqsave(&metro_priv->lock, flags);
control_state = metro_priv->control_state; control_state = metro_priv->control_state;
spin_unlock_irqrestore(&metro_priv->lock, flags); spin_unlock_irqrestore(&metro_priv->lock, flags);
...@@ -350,15 +316,12 @@ static void metrousb_unthrottle(struct tty_struct *tty) ...@@ -350,15 +316,12 @@ static void metrousb_unthrottle(struct tty_struct *tty)
unsigned long flags = 0; unsigned long flags = 0;
int result = 0; int result = 0;
dev_dbg(tty->dev, "%s\n", __func__);
/* Set the private information for the port to resume reading data. */ /* Set the private information for the port to resume reading data. */
spin_lock_irqsave(&metro_priv->lock, flags); spin_lock_irqsave(&metro_priv->lock, flags);
metro_priv->throttled = 0; metro_priv->throttled = 0;
spin_unlock_irqrestore(&metro_priv->lock, flags); spin_unlock_irqrestore(&metro_priv->lock, flags);
/* Submit the urb to read from the port. */ /* Submit the urb to read from the port. */
port->interrupt_in_urb->dev = port->serial->dev;
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result) if (result)
dev_err(tty->dev, dev_err(tty->dev,
...@@ -377,7 +340,6 @@ static struct usb_serial_driver metrousb_device = { ...@@ -377,7 +340,6 @@ static struct usb_serial_driver metrousb_device = {
.open = metrousb_open, .open = metrousb_open,
.close = metrousb_cleanup, .close = metrousb_cleanup,
.read_int_callback = metrousb_read_int_callback, .read_int_callback = metrousb_read_int_callback,
.write_int_callback = metrousb_write_int_callback,
.port_probe = metrousb_port_probe, .port_probe = metrousb_port_probe,
.port_remove = metrousb_port_remove, .port_remove = metrousb_port_remove,
.throttle = metrousb_throttle, .throttle = metrousb_throttle,
......
...@@ -234,11 +234,16 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, ...@@ -234,11 +234,16 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum,
status = usb_control_msg(usbdev, pipe, request, requesttype, value, status = usb_control_msg(usbdev, pipe, request, requesttype, value,
index, buf, 1, MOS_WDR_TIMEOUT); index, buf, 1, MOS_WDR_TIMEOUT);
if (status == 1) if (status == 1) {
*data = *buf; *data = *buf;
else if (status < 0) } else {
dev_err(&usbdev->dev, dev_err(&usbdev->dev,
"mos7720: usb_control_msg() failed: %d\n", status); "mos7720: usb_control_msg() failed: %d\n", status);
if (status >= 0)
status = -EIO;
*data = 0;
}
kfree(buf); kfree(buf);
return status; return status;
...@@ -1846,7 +1851,6 @@ static int get_serial_info(struct moschip_port *mos7720_port, ...@@ -1846,7 +1851,6 @@ static int get_serial_info(struct moschip_port *mos7720_port,
tmp.line = mos7720_port->port->minor; tmp.line = mos7720_port->port->minor;
tmp.port = mos7720_port->port->port_number; tmp.port = mos7720_port->port->port_number;
tmp.irq = 0; tmp.irq = 0;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
tmp.baud_base = 9600; tmp.baud_base = 9600;
tmp.close_delay = 5*HZ; tmp.close_delay = 5*HZ;
......
...@@ -284,9 +284,15 @@ static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg, ...@@ -284,9 +284,15 @@ static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg,
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH, MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH,
MOS_WDR_TIMEOUT); MOS_WDR_TIMEOUT);
if (ret < VENDOR_READ_LENGTH) {
if (ret >= 0)
ret = -EIO;
goto out;
}
*val = buf[0]; *val = buf[0];
dev_dbg(&port->dev, "%s offset is %x, return val %x\n", __func__, reg, *val); dev_dbg(&port->dev, "%s offset is %x, return val %x\n", __func__, reg, *val);
out:
kfree(buf); kfree(buf);
return ret; return ret;
} }
...@@ -352,8 +358,13 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, ...@@ -352,8 +358,13 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg,
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH, MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH,
MOS_WDR_TIMEOUT); MOS_WDR_TIMEOUT);
if (ret < VENDOR_READ_LENGTH) {
if (ret >= 0)
ret = -EIO;
goto out;
}
*val = buf[0]; *val = buf[0];
out:
kfree(buf); kfree(buf);
return ret; return ret;
} }
...@@ -1023,6 +1034,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -1023,6 +1034,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
* (can't set it up in mos7840_startup as the structures * * (can't set it up in mos7840_startup as the structures *
* were not set up at that time.) */ * were not set up at that time.) */
if (port0->open_ports == 1) { if (port0->open_ports == 1) {
/* FIXME: Buffer never NULL, so URB is not submitted. */
if (serial->port[0]->interrupt_in_buffer == NULL) { if (serial->port[0]->interrupt_in_buffer == NULL) {
/* set up interrupt urb */ /* set up interrupt urb */
usb_fill_int_urb(serial->port[0]->interrupt_in_urb, usb_fill_int_urb(serial->port[0]->interrupt_in_urb,
...@@ -1479,10 +1491,10 @@ static int mos7840_tiocmget(struct tty_struct *tty) ...@@ -1479,10 +1491,10 @@ static int mos7840_tiocmget(struct tty_struct *tty)
return -ENODEV; return -ENODEV;
status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr); status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
if (status != 1) if (status < 0)
return -EIO; return -EIO;
status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr); status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
if (status != 1) if (status < 0)
return -EIO; return -EIO;
result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
| ((mcr & MCR_RTS) ? TIOCM_RTS : 0) | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
...@@ -1952,7 +1964,6 @@ static int mos7840_get_serial_info(struct moschip_port *mos7840_port, ...@@ -1952,7 +1964,6 @@ static int mos7840_get_serial_info(struct moschip_port *mos7840_port,
tmp.line = mos7840_port->port->minor; tmp.line = mos7840_port->port->minor;
tmp.port = mos7840_port->port->port_number; tmp.port = mos7840_port->port->port_number;
tmp.irq = 0; tmp.irq = 0;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
tmp.baud_base = 9600; tmp.baud_base = 9600;
tmp.close_delay = 5 * HZ; tmp.close_delay = 5 * HZ;
...@@ -2106,7 +2117,8 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) ...@@ -2106,7 +2117,8 @@ static int mos7840_calc_num_ports(struct usb_serial *serial)
static int mos7840_attach(struct usb_serial *serial) static int mos7840_attach(struct usb_serial *serial)
{ {
if (serial->num_bulk_in < serial->num_ports || if (serial->num_bulk_in < serial->num_ports ||
serial->num_bulk_out < serial->num_ports) { serial->num_bulk_out < serial->num_ports ||
serial->num_interrupt_in < 1) {
dev_err(&serial->interface->dev, "missing endpoints\n"); dev_err(&serial->interface->dev, "missing endpoints\n");
return -ENODEV; return -ENODEV;
} }
......
...@@ -142,7 +142,7 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -142,7 +142,7 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
usb_clear_halt(port->serial->dev, port->read_urb->pipe); usb_clear_halt(port->serial->dev, port->read_urb->pipe);
res = usb_serial_generic_open(tty, port); res = usb_serial_generic_open(tty, port);
if (!res) if (res)
return res; return res;
/* Request CTS line state, sometimes during opening the current /* Request CTS line state, sometimes during opening the current
...@@ -343,7 +343,6 @@ static int get_serial_info(struct usb_serial_port *port, ...@@ -343,7 +343,6 @@ static int get_serial_info(struct usb_serial_port *port,
tmp.line = port->minor; tmp.line = port->minor;
tmp.port = 0; tmp.port = 0;
tmp.irq = 0; tmp.irq = 0;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
tmp.xmit_fifo_size = 1024; tmp.xmit_fifo_size = 1024;
tmp.baud_base = 9600; tmp.baud_base = 9600;
tmp.close_delay = 5*HZ; tmp.close_delay = 5*HZ;
......
...@@ -450,7 +450,7 @@ static int pl2303_get_line_request(struct usb_serial_port *port, ...@@ -450,7 +450,7 @@ static int pl2303_get_line_request(struct usb_serial_port *port,
if (ret != 7) { if (ret != 7) {
dev_err(&port->dev, "%s - failed: %d\n", __func__, ret); dev_err(&port->dev, "%s - failed: %d\n", __func__, ret);
if (ret > 0) if (ret >= 0)
ret = -EIO; ret = -EIO;
return ret; return ret;
...@@ -470,12 +470,8 @@ static int pl2303_set_line_request(struct usb_serial_port *port, ...@@ -470,12 +470,8 @@ static int pl2303_set_line_request(struct usb_serial_port *port,
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE, SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE,
0, 0, buf, 7, 100); 0, 0, buf, 7, 100);
if (ret != 7) { if (ret < 0) {
dev_err(&port->dev, "%s - failed: %d\n", __func__, ret); dev_err(&port->dev, "%s - failed: %d\n", __func__, ret);
if (ret > 0)
ret = -EIO;
return ret; return ret;
} }
......
...@@ -188,22 +188,22 @@ static inline int qt2_setdevice(struct usb_device *dev, u8 *data) ...@@ -188,22 +188,22 @@ static inline int qt2_setdevice(struct usb_device *dev, u8 *data)
} }
static inline int qt2_getdevice(struct usb_device *dev, u8 *data)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_DEVICE, 0xc0, 0, 0,
data, 3, QT2_USB_TIMEOUT);
}
static inline int qt2_getregister(struct usb_device *dev, static inline int qt2_getregister(struct usb_device *dev,
u8 uart, u8 uart,
u8 reg, u8 reg,
u8 *data) u8 *data)
{ {
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), int ret;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0xc0, reg, QT_SET_GET_REGISTER, 0xc0, reg,
uart, data, sizeof(*data), QT2_USB_TIMEOUT); uart, data, sizeof(*data), QT2_USB_TIMEOUT);
if (ret < sizeof(*data)) {
if (ret >= 0)
ret = -EIO;
}
return ret;
} }
static inline int qt2_setregister(struct usb_device *dev, static inline int qt2_setregister(struct usb_device *dev,
...@@ -372,9 +372,11 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -372,9 +372,11 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
0xc0, 0, 0xc0, 0,
device_port, data, 2, QT2_USB_TIMEOUT); device_port, data, 2, QT2_USB_TIMEOUT);
if (status < 0) { if (status < 2) {
dev_err(&port->dev, "%s - open port failed %i\n", __func__, dev_err(&port->dev, "%s - open port failed %i\n", __func__,
status); status);
if (status >= 0)
status = -EIO;
kfree(data); kfree(data);
return status; return status;
} }
...@@ -463,7 +465,6 @@ static int get_serial_info(struct usb_serial_port *port, ...@@ -463,7 +465,6 @@ static int get_serial_info(struct usb_serial_port *port,
tmp.line = port->minor; tmp.line = port->minor;
tmp.port = 0; tmp.port = 0;
tmp.irq = 0; tmp.irq = 0;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
tmp.xmit_fifo_size = port->bulk_out_size; tmp.xmit_fifo_size = port->bulk_out_size;
tmp.baud_base = 9600; tmp.baud_base = 9600;
tmp.close_delay = 5*HZ; tmp.close_delay = 5*HZ;
......
...@@ -137,24 +137,9 @@ static int is_himemory(const u8 ifnum, ...@@ -137,24 +137,9 @@ static int is_himemory(const u8 ifnum,
return 0; return 0;
} }
static int sierra_calc_interface(struct usb_serial *serial) static u8 sierra_interface_num(struct usb_serial *serial)
{ {
int interface; return serial->interface->cur_altsetting->desc.bInterfaceNumber;
struct usb_interface *p_interface;
struct usb_host_interface *p_host_interface;
/* Get the interface structure pointer from the serial struct */
p_interface = serial->interface;
/* Get a pointer to the host interface structure */
p_host_interface = p_interface->cur_altsetting;
/* read the interface descriptor for this active altsetting
* to find out the interface number we are on
*/
interface = p_host_interface->desc.bInterfaceNumber;
return interface;
} }
static int sierra_probe(struct usb_serial *serial, static int sierra_probe(struct usb_serial *serial,
...@@ -165,7 +150,7 @@ static int sierra_probe(struct usb_serial *serial, ...@@ -165,7 +150,7 @@ static int sierra_probe(struct usb_serial *serial,
u8 ifnum; u8 ifnum;
udev = serial->dev; udev = serial->dev;
ifnum = sierra_calc_interface(serial); ifnum = sierra_interface_num(serial);
/* /*
* If this interface supports more than 1 alternate * If this interface supports more than 1 alternate
...@@ -178,9 +163,6 @@ static int sierra_probe(struct usb_serial *serial, ...@@ -178,9 +163,6 @@ static int sierra_probe(struct usb_serial *serial,
usb_set_interface(udev, ifnum, 1); usb_set_interface(udev, ifnum, 1);
} }
/* ifnum could have changed - by calling usb_set_interface */
ifnum = sierra_calc_interface(serial);
if (is_blacklisted(ifnum, if (is_blacklisted(ifnum,
(struct sierra_iface_info *)id->driver_info)) { (struct sierra_iface_info *)id->driver_info)) {
dev_dbg(&serial->dev->dev, dev_dbg(&serial->dev->dev,
...@@ -342,7 +324,7 @@ static int sierra_send_setup(struct usb_serial_port *port) ...@@ -342,7 +324,7 @@ static int sierra_send_setup(struct usb_serial_port *port)
/* If composite device then properly report interface */ /* If composite device then properly report interface */
if (serial->num_ports == 1) { if (serial->num_ports == 1) {
interface = sierra_calc_interface(serial); interface = sierra_interface_num(serial);
/* Control message is sent only to interfaces with /* Control message is sent only to interfaces with
* interrupt_in endpoints * interrupt_in endpoints
*/ */
...@@ -916,7 +898,7 @@ static int sierra_port_probe(struct usb_serial_port *port) ...@@ -916,7 +898,7 @@ static int sierra_port_probe(struct usb_serial_port *port)
/* Determine actual memory requirements */ /* Determine actual memory requirements */
if (serial->num_ports == 1) { if (serial->num_ports == 1) {
/* Get interface number for composite device */ /* Get interface number for composite device */
ifnum = sierra_calc_interface(serial); ifnum = sierra_interface_num(serial);
himemoryp = &typeB_interface_list; himemoryp = &typeB_interface_list;
} else { } else {
/* This is really the usb-serial port number of the interface /* This is really the usb-serial port number of the interface
......
...@@ -232,11 +232,17 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status) ...@@ -232,11 +232,17 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status)
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
GET_UART_STATUS, GET_UART_STATUS_TYPE, GET_UART_STATUS, GET_UART_STATUS_TYPE,
0, GET_UART_STATUS_MSR, buf, 1, 100); 0, GET_UART_STATUS_MSR, buf, 1, 100);
if (ret < 0) if (ret < 1) {
dev_err(&port->dev, "failed to get modem status: %d\n", ret); dev_err(&port->dev, "failed to get modem status: %d\n", ret);
if (ret >= 0)
ret = -EIO;
goto out;
}
dev_dbg(&port->dev, "0xc0:0x22:0:6 %d - 0x02%x\n", ret, *buf); dev_dbg(&port->dev, "0xc0:0x22:0:6 %d - 0x02%x\n", ret, *buf);
*status = *buf; *status = *buf;
ret = 0;
out:
kfree(buf); kfree(buf);
return ret; return ret;
......
...@@ -80,9 +80,17 @@ static inline int ssu100_setdevice(struct usb_device *dev, u8 *data) ...@@ -80,9 +80,17 @@ static inline int ssu100_setdevice(struct usb_device *dev, u8 *data)
static inline int ssu100_getdevice(struct usb_device *dev, u8 *data) static inline int ssu100_getdevice(struct usb_device *dev, u8 *data)
{ {
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), int ret;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_DEVICE, 0xc0, 0, 0, QT_SET_GET_DEVICE, 0xc0, 0, 0,
data, 3, 300); data, 3, 300);
if (ret < 3) {
if (ret >= 0)
ret = -EIO;
}
return ret;
} }
static inline int ssu100_getregister(struct usb_device *dev, static inline int ssu100_getregister(struct usb_device *dev,
...@@ -90,10 +98,17 @@ static inline int ssu100_getregister(struct usb_device *dev, ...@@ -90,10 +98,17 @@ static inline int ssu100_getregister(struct usb_device *dev,
unsigned short reg, unsigned short reg,
u8 *data) u8 *data)
{ {
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), int ret;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0xc0, reg, QT_SET_GET_REGISTER, 0xc0, reg,
uart, data, sizeof(*data), 300); uart, data, sizeof(*data), 300);
if (ret < sizeof(*data)) {
if (ret >= 0)
ret = -EIO;
}
return ret;
} }
...@@ -289,8 +304,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -289,8 +304,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
QT_OPEN_CLOSE_CHANNEL, QT_OPEN_CLOSE_CHANNEL,
QT_TRANSFER_IN, 0x01, QT_TRANSFER_IN, 0x01,
0, data, 2, 300); 0, data, 2, 300);
if (result < 0) { if (result < 2) {
dev_dbg(&port->dev, "%s - open failed %i\n", __func__, result); dev_dbg(&port->dev, "%s - open failed %i\n", __func__, result);
if (result >= 0)
result = -EIO;
kfree(data); kfree(data);
return result; return result;
} }
...@@ -322,7 +339,6 @@ static int get_serial_info(struct usb_serial_port *port, ...@@ -322,7 +339,6 @@ static int get_serial_info(struct usb_serial_port *port,
tmp.line = port->minor; tmp.line = port->minor;
tmp.port = 0; tmp.port = 0;
tmp.irq = 0; tmp.irq = 0;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
tmp.xmit_fifo_size = port->bulk_out_size; tmp.xmit_fifo_size = port->bulk_out_size;
tmp.baud_base = 9600; tmp.baud_base = 9600;
tmp.close_delay = 5*HZ; tmp.close_delay = 5*HZ;
......
...@@ -1553,13 +1553,10 @@ static int ti_command_out_sync(struct ti_device *tdev, __u8 command, ...@@ -1553,13 +1553,10 @@ static int ti_command_out_sync(struct ti_device *tdev, __u8 command,
(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT), (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT),
value, moduleid, data, size, 1000); value, moduleid, data, size, 1000);
if (status == size) if (status < 0)
status = 0;
if (status > 0)
status = -ECOMM;
return status; return status;
return 0;
} }
...@@ -1575,8 +1572,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command, ...@@ -1575,8 +1572,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
if (status == size) if (status == size)
status = 0; status = 0;
else if (status >= 0)
if (status > 0)
status = -ECOMM; status = -ECOMM;
return status; return status;
......
This diff is collapsed.
...@@ -487,7 +487,6 @@ static int whiteheat_ioctl(struct tty_struct *tty, ...@@ -487,7 +487,6 @@ static int whiteheat_ioctl(struct tty_struct *tty,
serstruct.type = PORT_16654; serstruct.type = PORT_16654;
serstruct.line = port->minor; serstruct.line = port->minor;
serstruct.port = port->port_number; serstruct.port = port->port_number;
serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
serstruct.xmit_fifo_size = kfifo_size(&port->write_fifo); serstruct.xmit_fifo_size = kfifo_size(&port->write_fifo);
serstruct.custom_divisor = 0; serstruct.custom_divisor = 0;
serstruct.baud_base = 460800; serstruct.baud_base = 460800;
......
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