USB-serial updates for 5.9-rc1

Here are the USB-serial updates for 5.9-rc1, including:
 
  - console flow-control support
  - simulated line-breaks on some ch341
  - hardware flow-control fixes for cp210x
  - break-detection and sysrq fixes for ftdi_sio
  - sysrq optimisations
  - input parity checking for cp210x
 
 Included are also some new device ids and various clean ups.
 
 All have been in linux-next with no reported issues.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQQHbPq+cpGvN/peuzMLxc3C7H1lCAUCXyAjIwAKCRALxc3C7H1l
 CHruAQDTSejnRcrxMqU6mqL2AuEw+fABGUxjE+ah/HbXMf7CDwD/d0XQFimA8U8J
 ovxTVm35R+vYQ7T7jTNuVxso6nWGxw8=
 =15J7
 -----END PGP SIGNATURE-----

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

Johan writes:

USB-serial updates for 5.9-rc1

Here are the USB-serial updates for 5.9-rc1, including:

 - console flow-control support
 - simulated line-breaks on some ch341
 - hardware flow-control fixes for cp210x
 - break-detection and sysrq fixes for ftdi_sio
 - sysrq optimisations
 - input parity checking for cp210x

Included are also some new device ids and various clean ups.

All have been in linux-next with no reported issues.

* tag 'usb-serial-5.9-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial: (31 commits)
  USB: serial: qcserial: add EM7305 QDL product ID
  USB: serial: iuu_phoenix: fix led-activity helpers
  USB: serial: sierra: clean up special-interface handling
  USB: serial: cp210x: use in-kernel types in port data
  USB: serial: cp210x: drop unnecessary packed attributes
  USB: serial: cp210x: add support for TIOCGICOUNT
  USB: serial: cp210x: add support for line-status events
  USB: serial: cp210x: disable interface on errors in open
  USB: serial: drop redundant transfer-buffer casts
  USB: serial: drop extern keyword from function declarations
  USB: serial: drop unnecessary sysrq include
  USB: serial: add sysrq break-handler dummy
  USB: serial: inline sysrq dummy function
  USB: serial: only process sysrq when enabled
  USB: serial: only set sysrq timestamp for consoles
  USB: serial: ftdi_sio: fix break and sysrq handling
  USB: serial: ftdi_sio: clean up receive processing
  USB: serial: ftdi_sio: make process-packet buffer unsigned
  USB: serial: use fallthrough pseudo-keyword
  USB: serial: ch341: fix missing simulated-break margin
  ...
This commit is contained in:
Greg Kroah-Hartman 2020-07-28 17:33:10 +02:00
commit fa56dd9152
23 changed files with 508 additions and 192 deletions

View File

@ -117,7 +117,7 @@ static int aircable_process_packet(struct usb_serial_port *port,
static void aircable_process_read_urb(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
char *data = (char *)urb->transfer_buffer;
char *data = urb->transfer_buffer;
int has_headers;
int count;
int len;

View File

@ -59,7 +59,11 @@
#define CH341_REQ_MODEM_CTRL 0xA4
#define CH341_REG_BREAK 0x05
#define CH341_REG_PRESCALER 0x12
#define CH341_REG_DIVISOR 0x13
#define CH341_REG_LCR 0x18
#define CH341_REG_LCR2 0x25
#define CH341_NBREAK_BITS 0x01
#define CH341_LCR_ENABLE_RX 0x80
@ -74,6 +78,7 @@
#define CH341_LCR_CS5 0x00
#define CH341_QUIRK_LIMITED_PRESCALER BIT(0)
#define CH341_QUIRK_SIMULATE_BREAK BIT(1)
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x4348, 0x5523) },
@ -91,6 +96,7 @@ struct ch341_private {
u8 msr;
u8 lcr;
unsigned long quirks;
unsigned long break_end;
};
static void ch341_set_termios(struct tty_struct *tty,
@ -153,6 +159,10 @@ static const speed_t ch341_min_rates[] = {
CH341_MIN_RATE(3),
};
/* Supported range is 46 to 3000000 bps. */
#define CH341_MIN_BPS DIV_ROUND_UP(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256)
#define CH341_MAX_BPS (CH341_CLKRATE / (CH341_CLK_DIV(3, 0) * 2))
/*
* The device line speed is given by the following equation:
*
@ -163,10 +173,9 @@ static const speed_t ch341_min_rates[] = {
* 2 <= div <= 256 if fact = 0, or
* 9 <= div <= 256 if fact = 1
*/
static int ch341_get_divisor(struct ch341_private *priv)
static int ch341_get_divisor(struct ch341_private *priv, speed_t speed)
{
unsigned int fact, div, clk_div;
speed_t speed = priv->baud_rate;
bool force_fact0 = false;
int ps;
@ -174,7 +183,7 @@ static int ch341_get_divisor(struct ch341_private *priv)
* Clamp to supported range, this makes the (ps < 0) and (div < 2)
* sanity checks below redundant.
*/
speed = clamp(speed, 46U, 3000000U);
speed = clamp_val(speed, CH341_MIN_BPS, CH341_MAX_BPS);
/*
* Start with highest possible base clock (fact = 1) that will give a
@ -229,15 +238,16 @@ static int ch341_get_divisor(struct ch341_private *priv)
}
static int ch341_set_baudrate_lcr(struct usb_device *dev,
struct ch341_private *priv, u8 lcr)
struct ch341_private *priv,
speed_t baud_rate, u8 lcr)
{
int val;
int r;
if (!priv->baud_rate)
if (!baud_rate)
return -EINVAL;
val = ch341_get_divisor(priv);
val = ch341_get_divisor(priv, baud_rate);
if (val < 0)
return -EINVAL;
@ -247,11 +257,20 @@ static int ch341_set_baudrate_lcr(struct usb_device *dev,
*/
val |= BIT(7);
r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, val);
r = ch341_control_out(dev, CH341_REQ_WRITE_REG,
CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER,
val);
if (r)
return r;
r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, lcr);
/*
* Chip versions before version 0x30 as read using
* CH341_REQ_READ_VERSION used separate registers for line control
* (stop bits, parity and word length). Version 0x30 and above use
* CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero.
*/
r = ch341_control_out(dev, CH341_REQ_WRITE_REG,
CH341_REG_LCR2 << 8 | CH341_REG_LCR, lcr);
if (r)
return r;
@ -308,7 +327,7 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
if (r < 0)
goto out;
r = ch341_set_baudrate_lcr(dev, priv, priv->lcr);
r = ch341_set_baudrate_lcr(dev, priv, priv->baud_rate, priv->lcr);
if (r < 0)
goto out;
@ -341,8 +360,8 @@ static int ch341_detect_quirks(struct usb_serial_port *port)
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT);
if (r == -EPIPE) {
dev_dbg(&port->dev, "break control not supported\n");
quirks = CH341_QUIRK_LIMITED_PRESCALER;
dev_info(&port->dev, "break control not supported, using simulated break\n");
quirks = CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK;
r = 0;
goto out;
}
@ -523,7 +542,8 @@ static void ch341_set_termios(struct tty_struct *tty,
if (baud_rate) {
priv->baud_rate = baud_rate;
r = ch341_set_baudrate_lcr(port->serial->dev, priv, lcr);
r = ch341_set_baudrate_lcr(port->serial->dev, priv,
priv->baud_rate, lcr);
if (r < 0 && old_termios) {
priv->baud_rate = tty_termios_baud_rate(old_termios);
tty_termios_copy_hw(&tty->termios, old_termios);
@ -542,15 +562,98 @@ static void ch341_set_termios(struct tty_struct *tty,
ch341_set_handshake(port->serial->dev, priv->mcr);
}
/*
* A subset of all CH34x devices don't support a real break condition and
* reading CH341_REG_BREAK fails (see also ch341_detect_quirks). This function
* simulates a break condition by lowering the baud rate to the minimum
* supported by the hardware upon enabling the break condition and sending
* a NUL byte.
*
* Incoming data is corrupted while the break condition is being simulated.
*
* Normally the duration of the break condition can be controlled individually
* by userspace using TIOCSBRK and TIOCCBRK or by passing an argument to
* TCSBRKP. Due to how the simulation is implemented the duration can't be
* controlled. The duration is always about (1s / 46bd * 9bit) = 196ms.
*/
static void ch341_simulate_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct ch341_private *priv = usb_get_serial_port_data(port);
unsigned long now, delay;
int r;
if (break_state != 0) {
dev_dbg(&port->dev, "enter break state requested\n");
r = ch341_set_baudrate_lcr(port->serial->dev, priv,
CH341_MIN_BPS,
CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8);
if (r < 0) {
dev_err(&port->dev,
"failed to change baud rate to %u: %d\n",
CH341_MIN_BPS, r);
goto restore;
}
r = tty_put_char(tty, '\0');
if (r < 0) {
dev_err(&port->dev,
"failed to write NUL byte for simulated break condition: %d\n",
r);
goto restore;
}
/*
* Compute expected transmission duration including safety
* margin. The original baud rate is only restored after the
* computed point in time.
*
* 11 bits = 1 start, 8 data, 1 stop, 1 margin
*/
priv->break_end = jiffies + (11 * HZ / CH341_MIN_BPS);
return;
}
dev_dbg(&port->dev, "leave break state requested\n");
now = jiffies;
if (time_before(now, priv->break_end)) {
/* Wait until NUL byte is written */
delay = priv->break_end - now;
dev_dbg(&port->dev,
"wait %d ms while transmitting NUL byte at %u baud\n",
jiffies_to_msecs(delay), CH341_MIN_BPS);
schedule_timeout_interruptible(delay);
}
restore:
/* Restore original baud rate */
r = ch341_set_baudrate_lcr(port->serial->dev, priv, priv->baud_rate,
priv->lcr);
if (r < 0)
dev_err(&port->dev,
"restoring original baud rate of %u failed: %d\n",
priv->baud_rate, r);
}
static void ch341_break_ctl(struct tty_struct *tty, int break_state)
{
const uint16_t ch341_break_reg =
((uint16_t) CH341_REG_LCR << 8) | CH341_REG_BREAK;
struct usb_serial_port *port = tty->driver_data;
struct ch341_private *priv = usb_get_serial_port_data(port);
int r;
uint16_t reg_contents;
uint8_t *break_reg;
if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK) {
ch341_simulate_break(tty, break_state);
return;
}
break_reg = kmalloc(2, GFP_KERNEL);
if (!break_reg)
return;

View File

@ -79,7 +79,7 @@ static int usb_console_setup(struct console *co, char *options)
if (*s)
doflow = (*s++ == 'r');
}
/* Sane default */
if (baud == 0)
baud = 9600;
@ -102,6 +102,9 @@ static int usb_console_setup(struct console *co, char *options)
break;
}
if (doflow)
cflag |= CRTSCTS;
/*
* no need to check the index here: if the index is wrong, console
* code won't call us

View File

@ -50,6 +50,9 @@ static void cp210x_release(struct usb_serial *);
static int cp210x_port_probe(struct usb_serial_port *);
static int cp210x_port_remove(struct usb_serial_port *);
static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
static void cp210x_process_read_urb(struct urb *urb);
static void cp210x_enable_event_mode(struct usb_serial_port *port);
static void cp210x_disable_event_mode(struct usb_serial_port *port);
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */
@ -253,9 +256,21 @@ struct cp210x_serial_private {
bool use_actual_rate;
};
enum cp210x_event_state {
ES_DATA,
ES_ESCAPE,
ES_LSR,
ES_LSR_DATA_0,
ES_LSR_DATA_1,
ES_MSR
};
struct cp210x_port_private {
__u8 bInterfaceNumber;
u8 bInterfaceNumber;
bool has_swapped_line_ctl;
bool event_mode;
enum cp210x_event_state event_state;
u8 lsr;
};
static struct usb_serial_driver cp210x_device = {
@ -272,14 +287,18 @@ static struct usb_serial_driver cp210x_device = {
.break_ctl = cp210x_break_ctl,
.set_termios = cp210x_set_termios,
.tx_empty = cp210x_tx_empty,
.throttle = usb_serial_generic_throttle,
.unthrottle = usb_serial_generic_unthrottle,
.tiocmget = cp210x_tiocmget,
.tiocmset = cp210x_tiocmset,
.get_icount = usb_serial_generic_get_icount,
.attach = cp210x_attach,
.disconnect = cp210x_disconnect,
.release = cp210x_release,
.port_probe = cp210x_port_probe,
.port_remove = cp210x_port_remove,
.dtr_rts = cp210x_dtr_rts
.dtr_rts = cp210x_dtr_rts,
.process_read_urb = cp210x_process_read_urb,
};
static struct usb_serial_driver * const serial_drivers[] = {
@ -401,13 +420,22 @@ struct cp210x_comm_status {
*/
#define PURGE_ALL 0x000f
/* CP210X_EMBED_EVENTS */
#define CP210X_ESCCHAR 0xec
#define CP210X_LSR_OVERRUN BIT(1)
#define CP210X_LSR_PARITY BIT(2)
#define CP210X_LSR_FRAME BIT(3)
#define CP210X_LSR_BREAK BIT(4)
/* CP210X_GET_FLOW/CP210X_SET_FLOW read/write these 0x10 bytes */
struct cp210x_flow_ctl {
__le32 ulControlHandshake;
__le32 ulFlowReplace;
__le32 ulXonLimit;
__le32 ulXoffLimit;
} __packed;
};
/* cp210x_flow_ctl::ulControlHandshake */
#define CP210X_SERIAL_DTR_MASK GENMASK(1, 0)
@ -441,7 +469,7 @@ struct cp210x_flow_ctl {
struct cp210x_pin_mode {
u8 eci;
u8 sci;
} __packed;
};
#define CP210X_PIN_MODE_MODEM 0
#define CP210X_PIN_MODE_GPIO BIT(0)
@ -504,7 +532,7 @@ struct cp210x_single_port_config {
struct cp210x_gpio_write {
u8 mask;
u8 state;
} __packed;
};
/*
* Helper to get interface number when we only have struct usb_serial.
@ -807,6 +835,7 @@ static int cp210x_get_line_ctl(struct usb_serial_port *port, u16 *ctl)
static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
{
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
int result;
result = cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_ENABLE);
@ -818,21 +847,144 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
/* Configure the termios structure */
cp210x_get_termios(tty, port);
/* The baud rate must be initialised on cp2104 */
if (tty)
if (tty) {
/* The baud rate must be initialised on cp2104 */
cp210x_change_speed(tty, port, NULL);
return usb_serial_generic_open(tty, port);
if (I_INPCK(tty))
cp210x_enable_event_mode(port);
}
result = usb_serial_generic_open(tty, port);
if (result)
goto err_disable;
return 0;
err_disable:
cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_DISABLE);
port_priv->event_mode = false;
return result;
}
static void cp210x_close(struct usb_serial_port *port)
{
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
usb_serial_generic_close(port);
/* Clear both queues; cp2108 needs this to avoid an occasional hang */
cp210x_write_u16_reg(port, CP210X_PURGE, PURGE_ALL);
cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_DISABLE);
/* Disabling the interface disables event-insertion mode. */
port_priv->event_mode = false;
}
static void cp210x_process_lsr(struct usb_serial_port *port, unsigned char lsr, char *flag)
{
if (lsr & CP210X_LSR_BREAK) {
port->icount.brk++;
*flag = TTY_BREAK;
} else if (lsr & CP210X_LSR_PARITY) {
port->icount.parity++;
*flag = TTY_PARITY;
} else if (lsr & CP210X_LSR_FRAME) {
port->icount.frame++;
*flag = TTY_FRAME;
}
if (lsr & CP210X_LSR_OVERRUN) {
port->icount.overrun++;
tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
}
}
static bool cp210x_process_char(struct usb_serial_port *port, unsigned char *ch, char *flag)
{
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
switch (port_priv->event_state) {
case ES_DATA:
if (*ch == CP210X_ESCCHAR) {
port_priv->event_state = ES_ESCAPE;
break;
}
return false;
case ES_ESCAPE:
switch (*ch) {
case 0:
dev_dbg(&port->dev, "%s - escape char\n", __func__);
*ch = CP210X_ESCCHAR;
port_priv->event_state = ES_DATA;
return false;
case 1:
port_priv->event_state = ES_LSR_DATA_0;
break;
case 2:
port_priv->event_state = ES_LSR;
break;
case 3:
port_priv->event_state = ES_MSR;
break;
default:
dev_err(&port->dev, "malformed event 0x%02x\n", *ch);
port_priv->event_state = ES_DATA;
break;
}
break;
case ES_LSR_DATA_0:
port_priv->lsr = *ch;
port_priv->event_state = ES_LSR_DATA_1;
break;
case ES_LSR_DATA_1:
dev_dbg(&port->dev, "%s - lsr = 0x%02x, data = 0x%02x\n",
__func__, port_priv->lsr, *ch);
cp210x_process_lsr(port, port_priv->lsr, flag);
port_priv->event_state = ES_DATA;
return false;
case ES_LSR:
dev_dbg(&port->dev, "%s - lsr = 0x%02x\n", __func__, *ch);
port_priv->lsr = *ch;
cp210x_process_lsr(port, port_priv->lsr, flag);
port_priv->event_state = ES_DATA;
break;
case ES_MSR:
dev_dbg(&port->dev, "%s - msr = 0x%02x\n", __func__, *ch);
/* unimplemented */
port_priv->event_state = ES_DATA;
break;
}
return true;
}
static void cp210x_process_read_urb(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
unsigned char *ch = urb->transfer_buffer;
char flag;
int i;
if (!urb->actual_length)
return;
if (port_priv->event_mode) {
for (i = 0; i < urb->actual_length; i++, ch++) {
flag = TTY_NORMAL;
if (cp210x_process_char(port, ch, &flag))
continue;
tty_insert_flip_char(&port->port, *ch, flag);
}
} else {
tty_insert_flip_string(&port->port, ch, urb->actual_length);
}
tty_flip_buffer_push(&port->port);
}
/*
@ -915,6 +1067,7 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
u32 baud;
u16 bits;
u32 ctl_hs;
u32 flow_repl;
cp210x_read_u32_reg(port, CP210X_GET_BAUDRATE, &baud);
@ -1015,6 +1168,22 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake);
if (ctl_hs & CP210X_SERIAL_CTS_HANDSHAKE) {
dev_dbg(dev, "%s - flow control = CRTSCTS\n", __func__);
/*
* When the port is closed, the CP210x hardware disables
* auto-RTS and RTS is deasserted but it leaves auto-CTS when
* in hardware flow control mode. When re-opening the port, if
* auto-CTS is enabled on the cp210x, then auto-RTS must be
* re-enabled in the driver.
*/
flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace);
flow_repl &= ~CP210X_SERIAL_RTS_MASK;
flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_FLOW_CTL);
flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl);
cp210x_write_reg_block(port,
CP210X_SET_FLOW,
&flow_ctl,
sizeof(flow_ctl));
cflag |= CRTSCTS;
} else {
dev_dbg(dev, "%s - flow control = NONE\n", __func__);
@ -1148,6 +1317,41 @@ static void cp210x_change_speed(struct tty_struct *tty,
tty_encode_baud_rate(tty, baud, baud);
}
static void cp210x_enable_event_mode(struct usb_serial_port *port)
{
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
int ret;
if (port_priv->event_mode)
return;
port_priv->event_state = ES_DATA;
port_priv->event_mode = true;
ret = cp210x_write_u16_reg(port, CP210X_EMBED_EVENTS, CP210X_ESCCHAR);
if (ret) {
dev_err(&port->dev, "failed to enable events: %d\n", ret);
port_priv->event_mode = false;
}
}
static void cp210x_disable_event_mode(struct usb_serial_port *port)
{
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
int ret;
if (!port_priv->event_mode)
return;
ret = cp210x_write_u16_reg(port, CP210X_EMBED_EVENTS, 0);
if (ret) {
dev_err(&port->dev, "failed to disable events: %d\n", ret);
return;
}
port_priv->event_mode = false;
}
static void cp210x_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios)
{
@ -1270,6 +1474,14 @@ static void cp210x_set_termios(struct tty_struct *tty,
sizeof(flow_ctl));
}
/*
* Enable event-insertion mode only if input parity checking is
* enabled for now.
*/
if (I_INPCK(tty))
cp210x_enable_event_mode(port);
else
cp210x_disable_event_mode(port);
}
static int cp210x_tiocmset(struct tty_struct *tty,

View File

@ -1048,7 +1048,7 @@ static void cypress_read_int_callback(struct urb *urb)
return;
case -EPIPE:
/* Can't call usb_clear_halt while in_interrupt */
/* FALLS THROUGH */
fallthrough;
default:
/* something ugly is going on... */
dev_err(dev, "%s - unexpected nonzero read status received: %d\n",
@ -1197,7 +1197,7 @@ static void cypress_write_int_callback(struct urb *urb)
return;
case -EPIPE:
/* Cannot call usb_clear_halt while in_interrupt */
/* FALLTHROUGH */
fallthrough;
default:
dev_err(dev, "%s - unexpected nonzero write status received: %d\n",
__func__, status);

View File

@ -424,7 +424,7 @@ static void f81232_process_read_urb(struct urb *urb)
lsr = data[i];
tty_flag = f81232_handle_lsr(port, lsr);
if (port->port.console && port->sysrq) {
if (port->sysrq) {
if (usb_serial_handle_sysrq_char(port, data[i + 1]))
continue;
}
@ -461,7 +461,7 @@ static void f81534a_process_read_urb(struct urb *urb)
lsr = data[len - 1];
tty_flag = f81232_handle_lsr(port, lsr);
if (port->port.console && port->sysrq) {
if (port->sysrq) {
for (i = 1; i < len - 1; ++i) {
if (!usb_serial_handle_sysrq_char(port, data[i])) {
tty_insert_flip_char(&port->port, data[i],

View File

@ -1238,7 +1238,7 @@ static void f81534_process_per_serial_block(struct usb_serial_port *port,
schedule_work(&port_priv->lsr_work);
}
if (port->port.console && port->sysrq) {
if (port->sysrq) {
if (usb_serial_handle_sysrq_char(port, data[i]))
continue;
}

View File

@ -2480,12 +2480,12 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port,
#define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE)
static int ftdi_process_packet(struct usb_serial_port *port,
struct ftdi_private *priv, char *packet, int len)
struct ftdi_private *priv, unsigned char *buf, int len)
{
unsigned char status;
bool brkint = false;
int i;
char status;
char flag;
char *ch;
if (len < 2) {
dev_dbg(&port->dev, "malformed packet\n");
@ -2495,7 +2495,7 @@ static int ftdi_process_packet(struct usb_serial_port *port,
/* Compare new line status to the old one, signal if different/
N.B. packet may be processed more than once, but differences
are only processed once. */
status = packet[0] & FTDI_STATUS_B0_MASK;
status = buf[0] & FTDI_STATUS_B0_MASK;
if (status != priv->prev_status) {
char diff_status = status ^ priv->prev_status;
@ -2521,13 +2521,12 @@ static int ftdi_process_packet(struct usb_serial_port *port,
}
/* save if the transmitter is empty or not */
if (packet[1] & FTDI_RS_TEMT)
if (buf[1] & FTDI_RS_TEMT)
priv->transmit_empty = 1;
else
priv->transmit_empty = 0;
len -= 2;
if (!len)
if (len == 2)
return 0; /* status only */
/*
@ -2535,47 +2534,57 @@ static int ftdi_process_packet(struct usb_serial_port *port,
* data payload to avoid over-reporting.
*/
flag = TTY_NORMAL;
if (packet[1] & FTDI_RS_ERR_MASK) {
/* Break takes precedence over parity, which takes precedence
* over framing errors */
if (packet[1] & FTDI_RS_BI) {
flag = TTY_BREAK;
if (buf[1] & FTDI_RS_ERR_MASK) {
/*
* Break takes precedence over parity, which takes precedence
* over framing errors. Note that break is only associated
* with the last character in the buffer and only when it's a
* NUL.
*/
if (buf[1] & FTDI_RS_BI && buf[len - 1] == '\0') {
port->icount.brk++;
usb_serial_handle_break(port);
} else if (packet[1] & FTDI_RS_PE) {
brkint = true;
}
if (buf[1] & FTDI_RS_PE) {
flag = TTY_PARITY;
port->icount.parity++;
} else if (packet[1] & FTDI_RS_FE) {
} else if (buf[1] & FTDI_RS_FE) {
flag = TTY_FRAME;
port->icount.frame++;
}
/* Overrun is special, not associated with a char */
if (packet[1] & FTDI_RS_OE) {
if (buf[1] & FTDI_RS_OE) {
port->icount.overrun++;
tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
}
}
port->icount.rx += len;
ch = packet + 2;
port->icount.rx += len - 2;
if (port->port.console && port->sysrq) {
for (i = 0; i < len; i++, ch++) {
if (!usb_serial_handle_sysrq_char(port, *ch))
tty_insert_flip_char(&port->port, *ch, flag);
if (brkint || port->sysrq) {
for (i = 2; i < len; i++) {
if (brkint && i == len - 1) {
if (usb_serial_handle_break(port))
return len - 3;
flag = TTY_BREAK;
}
if (usb_serial_handle_sysrq_char(port, buf[i]))
continue;
tty_insert_flip_char(&port->port, buf[i], flag);
}
} else {
tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len);
tty_insert_flip_string_fixed_flag(&port->port, buf + 2, flag,
len - 2);
}
return len;
return len - 2;
}
static void ftdi_process_read_urb(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct ftdi_private *priv = usb_get_serial_port_data(port);
char *data = (char *)urb->transfer_buffer;
char *data = urb->transfer_buffer;
int i;
int len;
int count = 0;

View File

@ -179,19 +179,22 @@ static unsigned char const GARMIN_START_SESSION_REPLY[]
= { 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0 };
static unsigned char const GARMIN_BULK_IN_AVAIL_REPLY[]
= { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 };
static unsigned char const GARMIN_STOP_TRANSFER_REQ[]
= { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0 };
static unsigned char const GARMIN_STOP_TRANSFER_REQ_V2[]
= { 20, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0 };
/* packets currently unused, left as documentation */
#if 0
static unsigned char const GARMIN_APP_LAYER_REPLY[]
= { 0x14, 0, 0, 0 };
static unsigned char const GARMIN_START_PVT_REQ[]
= { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0 };
static unsigned char const GARMIN_STOP_PVT_REQ[]
= { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 50, 0 };
static unsigned char const GARMIN_STOP_TRANSFER_REQ[]
= { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0 };
static unsigned char const GARMIN_STOP_TRANSFER_REQ_V2[]
= { 20, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0 };
static unsigned char const PRIVATE_REQ[]
= { 0x4B, 0x6E, 0x10, 0x01, 0xFF, 0, 0, 0, 0xFF, 0, 0, 0 };
#endif
static const struct usb_device_id id_table[] = {

View File

@ -345,7 +345,7 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs);
void usb_serial_generic_process_read_urb(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
char *ch = (char *)urb->transfer_buffer;
char *ch = urb->transfer_buffer;
int i;
if (!urb->actual_length)
@ -355,13 +355,13 @@ void usb_serial_generic_process_read_urb(struct urb *urb)
* stuff like 3G modems, so shortcircuit it in the 99.9999999% of
* cases where the USB serial is not a console anyway.
*/
if (!port->port.console || !port->sysrq) {
tty_insert_flip_string(&port->port, ch, urb->actual_length);
} else {
if (port->sysrq) {
for (i = 0; i < urb->actual_length; i++, ch++) {
if (!usb_serial_handle_sysrq_char(port, *ch))
tty_insert_flip_char(&port->port, *ch, TTY_NORMAL);
}
} else {
tty_insert_flip_string(&port->port, ch, urb->actual_length);
}
tty_flip_buffer_push(&port->port);
}
@ -571,10 +571,10 @@ int usb_serial_generic_get_icount(struct tty_struct *tty,
}
EXPORT_SYMBOL_GPL(usb_serial_generic_get_icount);
#ifdef CONFIG_MAGIC_SYSRQ
#if defined(CONFIG_USB_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch)
{
if (port->sysrq && port->port.console) {
if (port->sysrq) {
if (ch && time_before(jiffies, port->sysrq)) {
handle_sysrq(ch);
port->sysrq = 0;
@ -584,16 +584,13 @@ int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch)
}
return 0;
}
#else
int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch)
{
return 0;
}
#endif
EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char);
int usb_serial_handle_break(struct usb_serial_port *port)
{
if (!port->port.console)
return 0;
if (!port->sysrq) {
port->sysrq = jiffies + HZ*5;
return 1;
@ -602,6 +599,7 @@ int usb_serial_handle_break(struct usb_serial_port *port)
return 0;
}
EXPORT_SYMBOL_GPL(usb_serial_handle_break);
#endif
/**
* usb_serial_handle_dcd_change - handle a change of carrier detect state

View File

@ -1752,7 +1752,7 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
edge_serial->rxState = EXPECT_HDR2;
break;
}
/* Fall through */
fallthrough;
case EXPECT_HDR2:
edge_serial->rxHeader2 = *buffer;
++buffer;
@ -1804,7 +1804,7 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
edge_serial->rxState = EXPECT_DATA;
break;
}
/* Fall through */
fallthrough;
case EXPECT_DATA: /* Expect data */
if (bufferLength < edge_serial->rxBytesRemaining) {
rxLen = bufferLength;

View File

@ -158,7 +158,6 @@ static int iuu_tiocmget(struct tty_struct *tty)
static void iuu_rxcmd(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
int result;
int status = urb->status;
if (status) {
@ -174,7 +173,7 @@ static void iuu_rxcmd(struct urb *urb)
port->bulk_out_endpointAddress),
port->write_urb->transfer_buffer, 1,
read_rxcmd_callback, port);
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
usb_submit_urb(port->write_urb, GFP_ATOMIC);
}
static int iuu_reset(struct usb_serial_port *port, u8 wt)
@ -241,7 +240,6 @@ static void iuu_update_status_callback(struct urb *urb)
static void iuu_status_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
int result;
int status = urb->status;
dev_dbg(&port->dev, "%s - status = %d\n", __func__, status);
@ -250,7 +248,7 @@ static void iuu_status_callback(struct urb *urb)
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer, 256,
iuu_update_status_callback, port);
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
usb_submit_urb(port->read_urb, GFP_ATOMIC);
}
static int iuu_status(struct usb_serial_port *port)
@ -351,12 +349,12 @@ static void iuu_rgbf_fill_buffer(u8 *buf, u8 r1, u8 r2, u8 g1, u8 g2, u8 b1,
static void iuu_led_activity_on(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
int result;
char *buf_ptr = port->write_urb->transfer_buffer;
*buf_ptr++ = IUU_SET_LED;
if (xmas) {
get_random_bytes(buf_ptr, 6);
*(buf_ptr+7) = 1;
buf_ptr[0] = IUU_SET_LED;
get_random_bytes(buf_ptr + 1, 6);
buf_ptr[7] = 1;
} else {
iuu_rgbf_fill_buffer(buf_ptr, 255, 255, 0, 0, 0, 0, 255);
}
@ -366,27 +364,27 @@ static void iuu_led_activity_on(struct urb *urb)
port->bulk_out_endpointAddress),
port->write_urb->transfer_buffer, 8 ,
iuu_rxcmd, port);
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
usb_submit_urb(port->write_urb, GFP_ATOMIC);
}
static void iuu_led_activity_off(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
int result;
char *buf_ptr = port->write_urb->transfer_buffer;
if (xmas) {
iuu_rxcmd(urb);
return;
} else {
*buf_ptr++ = IUU_SET_LED;
iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255);
}
iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255);
usb_fill_bulk_urb(port->write_urb, port->serial->dev,
usb_sndbulkpipe(port->serial->dev,
port->bulk_out_endpointAddress),
port->write_urb->transfer_buffer, 8 ,
iuu_rxcmd, port);
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
usb_submit_urb(port->write_urb, GFP_ATOMIC);
}

View File

@ -664,11 +664,10 @@ static void keyspan_pda_close(struct usb_serial_port *port)
/* download the firmware to a "fake" device (pre-renumeration) */
static int keyspan_pda_fake_startup(struct usb_serial *serial)
{
int response;
const char *fw_name;
/* download the firmware here ... */
response = ezusb_fx1_set_reset(serial->dev, 1);
ezusb_fx1_set_reset(serial->dev, 1);
if (0) { ; }
#ifdef KEYSPAN

View File

@ -499,7 +499,7 @@ static void kobil_set_termios(struct tty_struct *tty,
break;
default:
speed = 9600;
/* fall through */
fallthrough;
case 9600:
urb_val = SUSBCR_SBR_9600;
break;
@ -526,6 +526,10 @@ static void kobil_set_termios(struct tty_struct *tty,
0,
KOBIL_TIMEOUT
);
if (result) {
dev_err(&port->dev, "failed to update line settings: %d\n",
result);
}
}
static int kobil_ioctl(struct tty_struct *tty,

View File

@ -327,14 +327,14 @@ static void mxuport_process_read_urb_data(struct usb_serial_port *port,
{
int i;
if (!port->port.console || !port->sysrq) {
tty_insert_flip_string(&port->port, data, size);
} else {
if (port->sysrq) {
for (i = 0; i < size; i++, data++) {
if (!usb_serial_handle_sysrq_char(port, *data))
tty_insert_flip_char(&port->port, *data,
TTY_NORMAL);
}
} else {
tty_insert_flip_string(&port->port, data, size);
}
tty_flip_buffer_push(&port->port);
}

View File

@ -2157,8 +2157,7 @@ static void option_instat_callback(struct urb *urb)
dev_dbg(dev, "%s: urb %p port %p has data %p\n", __func__, urb, port, portdata);
if (status == 0) {
struct usb_ctrlrequest *req_pkt =
(struct usb_ctrlrequest *)urb->transfer_buffer;
struct usb_ctrlrequest *req_pkt = urb->transfer_buffer;
if (!req_pkt) {
dev_dbg(dev, "%s: NULL req_pkt\n", __func__);

View File

@ -1101,7 +1101,7 @@ static void pl2303_process_read_urb(struct urb *urb)
if (line_status & UART_OVERRUN_ERROR)
tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
if (port->port.console && port->sysrq) {
if (port->sysrq) {
for (i = 0; i < urb->actual_length; ++i)
if (!usb_serial_handle_sysrq_char(port, data[i]))
tty_insert_flip_char(&port->port, data[i],

View File

@ -155,6 +155,7 @@ static const struct usb_device_id id_table[] = {
{DEVICE_SWI(0x1199, 0x9056)}, /* Sierra Wireless Modem */
{DEVICE_SWI(0x1199, 0x9060)}, /* Sierra Wireless Modem */
{DEVICE_SWI(0x1199, 0x9061)}, /* Sierra Wireless Modem */
{DEVICE_SWI(0x1199, 0x9062)}, /* Sierra Wireless EM7305 QDL */
{DEVICE_SWI(0x1199, 0x9063)}, /* Sierra Wireless EM7305 */
{DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx */
{DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx */

View File

@ -480,21 +480,6 @@ static void qt2_process_status(struct usb_serial_port *port, unsigned char *ch)
}
}
/* not needed, kept to document functionality */
static void qt2_process_xmit_empty(struct usb_serial_port *port,
unsigned char *ch)
{
int bytes_written;
bytes_written = (int)(*ch) + (int)(*(ch + 1) << 4);
}
/* not needed, kept to document functionality */
static void qt2_process_flush(struct usb_serial_port *port, unsigned char *ch)
{
return;
}
static void qt2_process_read_urb(struct urb *urb)
{
struct usb_serial *serial;
@ -540,7 +525,7 @@ static void qt2_process_read_urb(struct urb *urb)
__func__);
break;
}
qt2_process_xmit_empty(port, ch + 3);
/* bytes_written = (ch[1] << 4) + ch[0]; */
i += 4;
escapeflag = true;
break;
@ -569,7 +554,6 @@ static void qt2_process_read_urb(struct urb *urb)
break;
case QT2_REC_FLUSH:
case QT2_XMIT_FLUSH:
qt2_process_flush(port, ch + 2);
i += 2;
escapeflag = true;
break;

View File

@ -45,10 +45,9 @@
static bool nmea;
/* Used in interface quirks */
struct sierra_iface_quirk {
const u32 infolen; /* number of interface numbers on the list */
const u8 *ifaceinfo; /* pointer to the array holding the numbers */
struct sierra_iface_list {
const u8 *nums; /* array of interface numbers */
size_t count; /* number of elements in array */
};
struct sierra_intf_private {
@ -101,20 +100,19 @@ static int sierra_calc_num_ports(struct usb_serial *serial,
return num_ports;
}
static int is_quirk(const u8 ifnum, const struct sierra_iface_quirk *quirk)
static bool is_listed(const u8 ifnum, const struct sierra_iface_list *list)
{
const u8 *info;
int i;
if (quirk) {
info = quirk->ifaceinfo;
if (!list)
return false;
for (i = 0; i < quirk->infolen; i++) {
if (info[i] == ifnum)
return 1;
}
for (i = 0; i < list->count; i++) {
if (list->nums[i] == ifnum)
return true;
}
return 0;
return false;
}
static u8 sierra_interface_num(struct usb_serial *serial)
@ -125,6 +123,7 @@ static u8 sierra_interface_num(struct usb_serial *serial)
static int sierra_probe(struct usb_serial *serial,
const struct usb_device_id *id)
{
const struct sierra_iface_list *ignore_list;
int result = 0;
struct usb_device *udev;
u8 ifnum;
@ -143,9 +142,10 @@ static int sierra_probe(struct usb_serial *serial,
usb_set_interface(udev, ifnum, 1);
}
if (is_quirk(ifnum, (struct sierra_iface_quirk *)id->driver_info)) {
dev_dbg(&serial->dev->dev,
"Ignoring interface #%d\n", ifnum);
ignore_list = (const struct sierra_iface_list *)id->driver_info;
if (is_listed(ifnum, ignore_list)) {
dev_dbg(&serial->dev->dev, "Ignoring interface #%d\n", ifnum);
return -ENODEV;
}
@ -154,22 +154,22 @@ static int sierra_probe(struct usb_serial *serial,
/* interfaces with higher memory requirements */
static const u8 hi_memory_typeA_ifaces[] = { 0, 2 };
static const struct sierra_iface_quirk typeA_interface_list = {
.infolen = ARRAY_SIZE(hi_memory_typeA_ifaces),
.ifaceinfo = hi_memory_typeA_ifaces,
static const struct sierra_iface_list typeA_interface_list = {
.nums = hi_memory_typeA_ifaces,
.count = ARRAY_SIZE(hi_memory_typeA_ifaces),
};
static const u8 hi_memory_typeB_ifaces[] = { 3, 4, 5, 6 };
static const struct sierra_iface_quirk typeB_interface_list = {
.infolen = ARRAY_SIZE(hi_memory_typeB_ifaces),
.ifaceinfo = hi_memory_typeB_ifaces,
static const struct sierra_iface_list typeB_interface_list = {
.nums = hi_memory_typeB_ifaces,
.count = ARRAY_SIZE(hi_memory_typeB_ifaces),
};
/* 'ignorelist' of interfaces not served by this driver */
static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };
static const struct sierra_iface_quirk direct_ip_interface_ignore = {
.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
.ifaceinfo = direct_ip_non_serial_ifaces,
static const struct sierra_iface_list direct_ip_interface_ignore = {
.nums = direct_ip_non_serial_ifaces,
.count = ARRAY_SIZE(direct_ip_non_serial_ifaces),
};
static const struct usb_device_id id_table[] = {
@ -570,8 +570,7 @@ static void sierra_instat_callback(struct urb *urb)
urb, port, portdata);
if (status == 0) {
struct usb_ctrlrequest *req_pkt =
(struct usb_ctrlrequest *)urb->transfer_buffer;
struct usb_ctrlrequest *req_pkt = urb->transfer_buffer;
if (!req_pkt) {
dev_dbg(&port->dev, "%s: NULL req_pkt\n",
@ -860,7 +859,7 @@ static int sierra_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct sierra_port_private *portdata;
const struct sierra_iface_quirk *himemoryp;
const struct sierra_iface_list *himemory_list;
u8 ifnum;
portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
@ -879,16 +878,16 @@ static int sierra_port_probe(struct usb_serial_port *port)
if (serial->num_ports == 1) {
/* Get interface number for composite device */
ifnum = sierra_interface_num(serial);
himemoryp = &typeB_interface_list;
himemory_list = &typeB_interface_list;
} else {
/* This is really the usb-serial port number of the interface
* rather than the interface number.
*/
ifnum = port->port_number;
himemoryp = &typeA_interface_list;
himemory_list = &typeA_interface_list;
}
if (is_quirk(ifnum, himemoryp)) {
if (is_listed(ifnum, himemory_list)) {
portdata->num_out_urbs = N_OUT_URB_HM;
portdata->num_in_urbs = N_IN_URB_HM;
}

View File

@ -495,7 +495,7 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr,
static void ssu100_process_read_urb(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
char *packet = (char *)urb->transfer_buffer;
char *packet = urb->transfer_buffer;
char flag = TTY_NORMAL;
u32 len = urb->actual_length;
int i;
@ -517,13 +517,14 @@ static void ssu100_process_read_urb(struct urb *urb)
if (!len)
return; /* status only */
if (port->port.console && port->sysrq) {
if (port->sysrq) {
for (i = 0; i < len; i++, ch++) {
if (!usb_serial_handle_sysrq_char(port, *ch))
tty_insert_flip_char(&port->port, *ch, flag);
}
} else
} else {
tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len);
}
tty_flip_buffer_push(&port->port);
}

View File

@ -332,7 +332,7 @@ static void upd78f0730_set_termios(struct tty_struct *tty,
tty->termios.c_cflag &= ~CSIZE;
tty->termios.c_cflag |= CS8;
dev_warn(dev, "data size is not supported, using 8 bits\n");
/* fall through */
fallthrough;
case CS8:
request.params |= UPD78F0730_DATA_SIZE_8_BITS;
dev_dbg(dev, "%s - 8 data bits\n", __func__);

View File

@ -17,7 +17,6 @@
#include <linux/kref.h>
#include <linux/mutex.h>
#include <linux/serial.h>
#include <linux/sysrq.h>
#include <linux/kfifo.h>
/* The maximum number of ports one device can grab at once */
@ -316,19 +315,19 @@ struct usb_serial_driver {
#define to_usb_serial_driver(d) \
container_of(d, struct usb_serial_driver, driver)
extern int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
const char *name, const struct usb_device_id *id_table);
extern void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[]);
extern void usb_serial_port_softint(struct usb_serial_port *port);
void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[]);
void usb_serial_port_softint(struct usb_serial_port *port);
extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t message);
extern int usb_serial_resume(struct usb_interface *intf);
int usb_serial_suspend(struct usb_interface *intf, pm_message_t message);
int usb_serial_resume(struct usb_interface *intf);
/* USB Serial console functions */
#ifdef CONFIG_USB_SERIAL_CONSOLE
extern void usb_serial_console_init(int minor);
extern void usb_serial_console_exit(void);
extern void usb_serial_console_disconnect(struct usb_serial *serial);
void usb_serial_console_init(int minor);
void usb_serial_console_exit(void);
void usb_serial_console_disconnect(struct usb_serial *serial);
#else
static inline void usb_serial_console_init(int minor) { }
static inline void usb_serial_console_exit(void) { }
@ -336,45 +335,49 @@ static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}
#endif
/* Functions needed by other parts of the usbserial core */
extern struct usb_serial_port *usb_serial_port_get_by_minor(unsigned int minor);
extern void usb_serial_put(struct usb_serial *serial);
extern int usb_serial_generic_open(struct tty_struct *tty,
struct usb_serial_port *port);
extern int usb_serial_generic_write_start(struct usb_serial_port *port,
gfp_t mem_flags);
extern int usb_serial_generic_write(struct tty_struct *tty,
struct usb_serial_port *port, const unsigned char *buf, int count);
extern void usb_serial_generic_close(struct usb_serial_port *port);
extern int usb_serial_generic_resume(struct usb_serial *serial);
extern int usb_serial_generic_write_room(struct tty_struct *tty);
extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);
extern void usb_serial_generic_wait_until_sent(struct tty_struct *tty,
long timeout);
extern void usb_serial_generic_read_bulk_callback(struct urb *urb);
extern void usb_serial_generic_write_bulk_callback(struct urb *urb);
extern void usb_serial_generic_throttle(struct tty_struct *tty);
extern void usb_serial_generic_unthrottle(struct tty_struct *tty);
extern int usb_serial_generic_tiocmiwait(struct tty_struct *tty,
unsigned long arg);
extern int usb_serial_generic_get_icount(struct tty_struct *tty,
struct serial_icounter_struct *icount);
extern int usb_serial_generic_register(void);
extern void usb_serial_generic_deregister(void);
extern int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port,
gfp_t mem_flags);
extern void usb_serial_generic_process_read_urb(struct urb *urb);
extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port,
void *dest, size_t size);
extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port,
unsigned int ch);
extern int usb_serial_handle_break(struct usb_serial_port *port);
extern void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
struct tty_struct *tty,
unsigned int status);
struct usb_serial_port *usb_serial_port_get_by_minor(unsigned int minor);
void usb_serial_put(struct usb_serial *serial);
int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port);
int usb_serial_generic_write_start(struct usb_serial_port *port, gfp_t mem_flags);
int usb_serial_generic_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
void usb_serial_generic_close(struct usb_serial_port *port);
int usb_serial_generic_resume(struct usb_serial *serial);
int usb_serial_generic_write_room(struct tty_struct *tty);
int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);
void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout);
void usb_serial_generic_read_bulk_callback(struct urb *urb);
void usb_serial_generic_write_bulk_callback(struct urb *urb);
void usb_serial_generic_throttle(struct tty_struct *tty);
void usb_serial_generic_unthrottle(struct tty_struct *tty);
int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg);
int usb_serial_generic_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount);
int usb_serial_generic_register(void);
void usb_serial_generic_deregister(void);
int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, gfp_t mem_flags);
void usb_serial_generic_process_read_urb(struct urb *urb);
int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, void *dest, size_t size);
#if defined(CONFIG_USB_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch);
int usb_serial_handle_break(struct usb_serial_port *port);
#else
static inline int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch)
{
return 0;
}
static inline int usb_serial_handle_break(struct usb_serial_port *port)
{
return 0;
}
#endif
void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
struct tty_struct *tty, unsigned int status);
extern int usb_serial_bus_register(struct usb_serial_driver *device);
extern void usb_serial_bus_deregister(struct usb_serial_driver *device);
int usb_serial_bus_register(struct usb_serial_driver *device);
void usb_serial_bus_deregister(struct usb_serial_driver *device);
extern struct bus_type usb_serial_bus_type;
extern struct tty_driver *usb_serial_tty_driver;