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 ...
Unified · Split
| @@ -117,7 +117,7 @@ static int aircable_process_packet(struct usb_serial_port *port, · 116 unmodified lines | |||
| 117 | static void aircable_process_read_urb(struct urb *urb) | 117 | static void aircable_process_read_urb(struct urb *urb) |
| 118 | { | 118 | { |
| 119 | struct usb_serial_port *port = urb->context; | 119 | struct usb_serial_port *port = urb->context; |
| 120 | char *data = (char *)urb->transfer_buffer; | 120 | char *data = urb->transfer_buffer; |
| 121 | int has_headers; | 121 | int has_headers; |
| 122 | int count; | 122 | int count; |
| 123 | int len; | 123 | int len; |
| @@ -59,7 +59,11 @@ · 58 unmodified lines | |||
| 59 | #define CH341_REQ_MODEM_CTRL 0xA4 | 59 | #define CH341_REQ_MODEM_CTRL 0xA4 |
| 60 | 60 | ||
| 61 | #define CH341_REG_BREAK 0x05 | 61 | #define CH341_REG_BREAK 0x05 |
| 62 | #define CH341_REG_PRESCALER 0x12 | ||
| 63 | #define CH341_REG_DIVISOR 0x13 | ||
| 62 | #define CH341_REG_LCR 0x18 | 64 | #define CH341_REG_LCR 0x18 |
| 65 | #define CH341_REG_LCR2 0x25 | ||
| 66 | |||
| 63 | #define CH341_NBREAK_BITS 0x01 | 67 | #define CH341_NBREAK_BITS 0x01 |
| 64 | 68 | ||
| 65 | #define CH341_LCR_ENABLE_RX 0x80 | 69 | #define CH341_LCR_ENABLE_RX 0x80 |
| @@ -74,6 +78,7 @@ · 8 unmodified lines | |||
| 74 | #define CH341_LCR_CS5 0x00 | 78 | #define CH341_LCR_CS5 0x00 |
| 75 | 79 | ||
| 76 | #define CH341_QUIRK_LIMITED_PRESCALER BIT(0) | 80 | #define CH341_QUIRK_LIMITED_PRESCALER BIT(0) |
| 81 | #define CH341_QUIRK_SIMULATE_BREAK BIT(1) | ||
| 77 | 82 | ||
| 78 | static const struct usb_device_id id_table[] = { | 83 | static const struct usb_device_id id_table[] = { |
| 79 | { USB_DEVICE(0x4348, 0x5523) }, | 84 | { USB_DEVICE(0x4348, 0x5523) }, |
| @@ -91,6 +96,7 @@ struct ch341_private { · 11 unmodified lines | |||
| 91 | u8 msr; | 96 | u8 msr; |
| 92 | u8 lcr; | 97 | u8 lcr; |
| 93 | unsigned long quirks; | 98 | unsigned long quirks; |
| 99 | unsigned long break_end; | ||
| 94 | }; | 100 | }; |
| 95 | 101 | ||
| 96 | static void ch341_set_termios(struct tty_struct *tty, | 102 | static void ch341_set_termios(struct tty_struct *tty, |
| @@ -153,6 +159,10 @@ static const speed_t ch341_min_rates[] = { · 56 unmodified lines | |||
| 153 | CH341_MIN_RATE(3), | 159 | CH341_MIN_RATE(3), |
| 154 | }; | 160 | }; |
| 155 | 161 | ||
| 162 | /* Supported range is 46 to 3000000 bps. */ | ||
| 163 | #define CH341_MIN_BPS DIV_ROUND_UP(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256) | ||
| 164 | #define CH341_MAX_BPS (CH341_CLKRATE / (CH341_CLK_DIV(3, 0) * 2)) | ||
| 165 | |||
| 156 | /* | 166 | /* |
| 157 | * The device line speed is given by the following equation: | 167 | * The device line speed is given by the following equation: |
| 158 | * | 168 | * |
| @@ -163,10 +173,9 @@ static const speed_t ch341_min_rates[] = { · 4 unmodified lines | |||
| 163 | * 2 <= div <= 256 if fact = 0, or | 173 | * 2 <= div <= 256 if fact = 0, or |
| 164 | * 9 <= div <= 256 if fact = 1 | 174 | * 9 <= div <= 256 if fact = 1 |
| 165 | */ | 175 | */ |
| 166 | static int ch341_get_divisor(struct ch341_private *priv) | 176 | static int ch341_get_divisor(struct ch341_private *priv, speed_t speed) |
| 167 | { | 177 | { |
| 168 | unsigned int fact, div, clk_div; | 178 | unsigned int fact, div, clk_div; |
| 169 | speed_t speed = priv->baud_rate; | ||
| 170 | bool force_fact0 = false; | 179 | bool force_fact0 = false; |
| 171 | int ps; | 180 | int ps; |
| 172 | 181 | ||
| @@ -174,7 +183,7 @@ static int ch341_get_divisor(struct ch341_private *priv) · 1 unmodified line | |||
| 174 | * Clamp to supported range, this makes the (ps < 0) and (div < 2) | 183 | * Clamp to supported range, this makes the (ps < 0) and (div < 2) |
| 175 | * sanity checks below redundant. | 184 | * sanity checks below redundant. |
| 176 | */ | 185 | */ |
| 177 | speed = clamp(speed, 46U, 3000000U); | 186 | speed = clamp_val(speed, CH341_MIN_BPS, CH341_MAX_BPS); |
| 178 | 187 | ||
| 179 | /* | 188 | /* |
| 180 | * Start with highest possible base clock (fact = 1) that will give a | 189 | * 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) · 48 unmodified lines | |||
| 229 | } | 238 | } |
| 230 | 239 | ||
| 231 | static int ch341_set_baudrate_lcr(struct usb_device *dev, | 240 | static int ch341_set_baudrate_lcr(struct usb_device *dev, |
| 232 | struct ch341_private *priv, u8 lcr) | 241 | struct ch341_private *priv, |
| 242 | speed_t baud_rate, u8 lcr) | ||
| 233 | { | 243 | { |
| 234 | int val; | 244 | int val; |
| 235 | int r; | 245 | int r; |
| 236 | 246 | ||
| 237 | if (!priv->baud_rate) | 247 | if (!baud_rate) |
| 238 | return -EINVAL; | 248 | return -EINVAL; |
| 239 | 249 | ||
| 240 | val = ch341_get_divisor(priv); | 250 | val = ch341_get_divisor(priv, baud_rate); |
| 241 | if (val < 0) | 251 | if (val < 0) |
| 242 | return -EINVAL; | 252 | return -EINVAL; |
| 243 | 253 | ||
| @@ -247,11 +257,20 @@ static int ch341_set_baudrate_lcr(struct usb_device *dev, · 3 unmodified lines | |||
| 247 | */ | 257 | */ |
| 248 | val |= BIT(7); | 258 | val |= BIT(7); |
| 249 | 259 | ||
| 250 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, val); | 260 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, |
| 261 | CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, | ||
| 262 | val); | ||
| 251 | if (r) | 263 | if (r) |
| 252 | return r; | 264 | return r; |
| 253 | 265 | ||
| 254 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, lcr); | 266 | /* |
| 267 | * Chip versions before version 0x30 as read using | ||
| 268 | * CH341_REQ_READ_VERSION used separate registers for line control | ||
| 269 | * (stop bits, parity and word length). Version 0x30 and above use | ||
| 270 | * CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero. | ||
| 271 | */ | ||
| 272 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, | ||
| 273 | CH341_REG_LCR2 << 8 | CH341_REG_LCR, lcr); | ||
| 255 | if (r) | 274 | if (r) |
| 256 | return r; | 275 | return r; |
| 257 | 276 | ||
| @@ -308,7 +327,7 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) · 50 unmodified lines | |||
| 308 | if (r < 0) | 327 | if (r < 0) |
| 309 | goto out; | 328 | goto out; |
| 310 | 329 | ||
| 311 | r = ch341_set_baudrate_lcr(dev, priv, priv->lcr); | 330 | r = ch341_set_baudrate_lcr(dev, priv, priv->baud_rate, priv->lcr); |
| 312 | if (r < 0) | 331 | if (r < 0) |
| 313 | goto out; | 332 | goto out; |
| 314 | 333 | ||
| @@ -341,8 +360,8 @@ static int ch341_detect_quirks(struct usb_serial_port *port) · 26 unmodified lines | |||
| 341 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | 360 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
| 342 | CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT); | 361 | CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT); |
| 343 | if (r == -EPIPE) { | 362 | if (r == -EPIPE) { |
| 344 | dev_dbg(&port->dev, "break control not supported\n"); | 363 | dev_info(&port->dev, "break control not supported, using simulated break\n"); |
| 345 | quirks = CH341_QUIRK_LIMITED_PRESCALER; | 364 | quirks = CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK; |
| 346 | r = 0; | 365 | r = 0; |
| 347 | goto out; | 366 | goto out; |
| 348 | } | 367 | } |
| @@ -523,7 +542,8 @@ static void ch341_set_termios(struct tty_struct *tty, · 174 unmodified lines | |||
| 523 | if (baud_rate) { | 542 | if (baud_rate) { |
| 524 | priv->baud_rate = baud_rate; | 543 | priv->baud_rate = baud_rate; |
| 525 | 544 | ||
| 526 | r = ch341_set_baudrate_lcr(port->serial->dev, priv, lcr); | 545 | r = ch341_set_baudrate_lcr(port->serial->dev, priv, |
| 546 | priv->baud_rate, lcr); | ||
| 527 | if (r < 0 && old_termios) { | 547 | if (r < 0 && old_termios) { |
| 528 | priv->baud_rate = tty_termios_baud_rate(old_termios); | 548 | priv->baud_rate = tty_termios_baud_rate(old_termios); |
| 529 | tty_termios_copy_hw(&tty->termios, old_termios); | 549 | tty_termios_copy_hw(&tty->termios, old_termios); |
| @@ -542,15 +562,98 @@ static void ch341_set_termios(struct tty_struct *tty, · 12 unmodified lines | |||
| 542 | ch341_set_handshake(port->serial->dev, priv->mcr); | 562 | ch341_set_handshake(port->serial->dev, priv->mcr); |
| 543 | } | 563 | } |
| 544 | 564 | ||
| 565 | /* | ||
| 566 | * A subset of all CH34x devices don't support a real break condition and | ||
| 567 | * reading CH341_REG_BREAK fails (see also ch341_detect_quirks). This function | ||
| 568 | * simulates a break condition by lowering the baud rate to the minimum | ||
| 569 | * supported by the hardware upon enabling the break condition and sending | ||
| 570 | * a NUL byte. | ||
| 571 | * | ||
| 572 | * Incoming data is corrupted while the break condition is being simulated. | ||
| 573 | * | ||
| 574 | * Normally the duration of the break condition can be controlled individually | ||
| 575 | * by userspace using TIOCSBRK and TIOCCBRK or by passing an argument to | ||
| 576 | * TCSBRKP. Due to how the simulation is implemented the duration can't be | ||
| 577 | * controlled. The duration is always about (1s / 46bd * 9bit) = 196ms. | ||
| 578 | */ | ||
| 579 | static void ch341_simulate_break(struct tty_struct *tty, int break_state) | ||
| 580 | { | ||
| 581 | struct usb_serial_port *port = tty->driver_data; | ||
| 582 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
| 583 | unsigned long now, delay; | ||
| 584 | int r; | ||
| 585 | |||
| 586 | if (break_state != 0) { | ||
| 587 | dev_dbg(&port->dev, "enter break state requested\n"); | ||
| 588 | |||
| 589 | r = ch341_set_baudrate_lcr(port->serial->dev, priv, | ||
| 590 | CH341_MIN_BPS, | ||
| 591 | CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8); | ||
| 592 | if (r < 0) { | ||
| 593 | dev_err(&port->dev, | ||
| 594 | "failed to change baud rate to %u: %d\n", | ||
| 595 | CH341_MIN_BPS, r); | ||
| 596 | goto restore; | ||
| 597 | } | ||
| 598 | |||
| 599 | r = tty_put_char(tty, '\0'); | ||
| 600 | if (r < 0) { | ||
| 601 | dev_err(&port->dev, | ||
| 602 | "failed to write NUL byte for simulated break condition: %d\n", | ||
| 603 | r); | ||
| 604 | goto restore; | ||
| 605 | } | ||
| 606 | |||
| 607 | /* | ||
| 608 | * Compute expected transmission duration including safety | ||
| 609 | * margin. The original baud rate is only restored after the | ||
| 610 | * computed point in time. | ||
| 611 | * | ||
| 612 | * 11 bits = 1 start, 8 data, 1 stop, 1 margin | ||
| 613 | */ | ||
| 614 | priv->break_end = jiffies + (11 * HZ / CH341_MIN_BPS); | ||
| 615 | |||
| 616 | return; | ||
| 617 | } | ||
| 618 | |||
| 619 | dev_dbg(&port->dev, "leave break state requested\n"); | ||
| 620 | |||
| 621 | now = jiffies; | ||
| 622 | |||
| 623 | if (time_before(now, priv->break_end)) { | ||
| 624 | /* Wait until NUL byte is written */ | ||
| 625 | delay = priv->break_end - now; | ||
| 626 | dev_dbg(&port->dev, | ||
| 627 | "wait %d ms while transmitting NUL byte at %u baud\n", | ||
| 628 | jiffies_to_msecs(delay), CH341_MIN_BPS); | ||
| 629 | schedule_timeout_interruptible(delay); | ||
| 630 | } | ||
| 631 | |||
| 632 | restore: | ||
| 633 | /* Restore original baud rate */ | ||
| 634 | r = ch341_set_baudrate_lcr(port->serial->dev, priv, priv->baud_rate, | ||
| 635 | priv->lcr); | ||
| 636 | if (r < 0) | ||
| 637 | dev_err(&port->dev, | ||
| 638 | "restoring original baud rate of %u failed: %d\n", | ||
| 639 | priv->baud_rate, r); | ||
| 640 | } | ||
| 641 | |||
| 545 | static void ch341_break_ctl(struct tty_struct *tty, int break_state) | 642 | static void ch341_break_ctl(struct tty_struct *tty, int break_state) |
| 546 | { | 643 | { |
| 547 | const uint16_t ch341_break_reg = | 644 | const uint16_t ch341_break_reg = |
| 548 | ((uint16_t) CH341_REG_LCR << 8) | CH341_REG_BREAK; | 645 | ((uint16_t) CH341_REG_LCR << 8) | CH341_REG_BREAK; |
| 549 | struct usb_serial_port *port = tty->driver_data; | 646 | struct usb_serial_port *port = tty->driver_data; |
| 647 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
| 550 | int r; | 648 | int r; |
| 551 | uint16_t reg_contents; | 649 | uint16_t reg_contents; |
| 552 | uint8_t *break_reg; | 650 | uint8_t *break_reg; |
| 553 | 651 | ||
| 652 | if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK) { | ||
| 653 | ch341_simulate_break(tty, break_state); | ||
| 654 | return; | ||
| 655 | } | ||
| 656 | |||
| 554 | break_reg = kmalloc(2, GFP_KERNEL); | 657 | break_reg = kmalloc(2, GFP_KERNEL); |
| 555 | if (!break_reg) | 658 | if (!break_reg) |
| 556 | return; | 659 | return; |
| @@ -79,7 +79,7 @@ static int usb_console_setup(struct console *co, char *options) · 78 unmodified lines | |||
| 79 | if (*s) | 79 | if (*s) |
| 80 | doflow = (*s++ == 'r'); | 80 | doflow = (*s++ == 'r'); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | /* Sane default */ | 83 | /* Sane default */ |
| 84 | if (baud == 0) | 84 | if (baud == 0) |
| 85 | baud = 9600; | 85 | baud = 9600; |
| @@ -102,6 +102,9 @@ static int usb_console_setup(struct console *co, char *options) · 16 unmodified lines | |||
| 102 | break; | 102 | break; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | if (doflow) | ||
| 106 | cflag |= CRTSCTS; | ||
| 107 | |||
| 105 | /* | 108 | /* |
| 106 | * no need to check the index here: if the index is wrong, console | 109 | * no need to check the index here: if the index is wrong, console |
| 107 | * code won't call us | 110 | * code won't call us |
| @@ -50,6 +50,9 @@ static void cp210x_release(struct usb_serial *); · 49 unmodified lines | |||
| 50 | static int cp210x_port_probe(struct usb_serial_port *); | 50 | static int cp210x_port_probe(struct usb_serial_port *); |
| 51 | static int cp210x_port_remove(struct usb_serial_port *); | 51 | static int cp210x_port_remove(struct usb_serial_port *); |
| 52 | static void cp210x_dtr_rts(struct usb_serial_port *p, int on); | 52 | static void cp210x_dtr_rts(struct usb_serial_port *p, int on); |
| 53 | static void cp210x_process_read_urb(struct urb *urb); | ||
| 54 | static void cp210x_enable_event_mode(struct usb_serial_port *port); | ||
| 55 | static void cp210x_disable_event_mode(struct usb_serial_port *port); | ||
| 53 | 56 | ||
| 54 | static const struct usb_device_id id_table[] = { | 57 | static const struct usb_device_id id_table[] = { |
| 55 | { USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */ | 58 | { USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */ |
| @@ -253,9 +256,21 @@ struct cp210x_serial_private { · 197 unmodified lines | |||
| 253 | bool use_actual_rate; | 256 | bool use_actual_rate; |
| 254 | }; | 257 | }; |
| 255 | 258 | ||
| 259 | enum cp210x_event_state { | ||
| 260 | ES_DATA, | ||
| 261 | ES_ESCAPE, | ||
| 262 | ES_LSR, | ||
| 263 | ES_LSR_DATA_0, | ||
| 264 | ES_LSR_DATA_1, | ||
| 265 | ES_MSR | ||
| 266 | }; | ||
| 267 | |||
| 256 | struct cp210x_port_private { | 268 | struct cp210x_port_private { |
| 257 | __u8 bInterfaceNumber; | 269 | u8 bInterfaceNumber; |
| 258 | bool has_swapped_line_ctl; | 270 | bool has_swapped_line_ctl; |
| 271 | bool event_mode; | ||
| 272 | enum cp210x_event_state event_state; | ||
| 273 | u8 lsr; | ||
| 259 | }; | 274 | }; |
| 260 | 275 | ||
| 261 | static struct usb_serial_driver cp210x_device = { | 276 | static struct usb_serial_driver cp210x_device = { |
| @@ -272,14 +287,18 @@ static struct usb_serial_driver cp210x_device = { · 10 unmodified lines | |||
| 272 | .break_ctl = cp210x_break_ctl, | 287 | .break_ctl = cp210x_break_ctl, |
| 273 | .set_termios = cp210x_set_termios, | 288 | .set_termios = cp210x_set_termios, |
| 274 | .tx_empty = cp210x_tx_empty, | 289 | .tx_empty = cp210x_tx_empty, |
| 290 | .throttle = usb_serial_generic_throttle, | ||
| 291 | .unthrottle = usb_serial_generic_unthrottle, | ||
| 275 | .tiocmget = cp210x_tiocmget, | 292 | .tiocmget = cp210x_tiocmget, |
| 276 | .tiocmset = cp210x_tiocmset, | 293 | .tiocmset = cp210x_tiocmset, |
| 294 | .get_icount = usb_serial_generic_get_icount, | ||
| 277 | .attach = cp210x_attach, | 295 | .attach = cp210x_attach, |
| 278 | .disconnect = cp210x_disconnect, | 296 | .disconnect = cp210x_disconnect, |
| 279 | .release = cp210x_release, | 297 | .release = cp210x_release, |
| 280 | .port_probe = cp210x_port_probe, | 298 | .port_probe = cp210x_port_probe, |
| 281 | .port_remove = cp210x_port_remove, | 299 | .port_remove = cp210x_port_remove, |
| 282 | .dtr_rts = cp210x_dtr_rts | 300 | .dtr_rts = cp210x_dtr_rts, |
| 301 | .process_read_urb = cp210x_process_read_urb, | ||
| 283 | }; | 302 | }; |
| 284 | 303 | ||
| 285 | static struct usb_serial_driver * const serial_drivers[] = { | 304 | static struct usb_serial_driver * const serial_drivers[] = { |
| @@ -401,13 +420,22 @@ struct cp210x_comm_status { · 115 unmodified lines | |||
| 401 | */ | 420 | */ |
| 402 | #define PURGE_ALL 0x000f | 421 | #define PURGE_ALL 0x000f |
| 403 | 422 | ||
| 423 | /* CP210X_EMBED_EVENTS */ | ||
| 424 | #define CP210X_ESCCHAR 0xec | ||
| 425 | |||
| 426 | #define CP210X_LSR_OVERRUN BIT(1) | ||
| 427 | #define CP210X_LSR_PARITY BIT(2) | ||
| 428 | #define CP210X_LSR_FRAME BIT(3) | ||
| 429 | #define CP210X_LSR_BREAK BIT(4) | ||
| 430 | |||
| 431 | |||
| 404 | /* CP210X_GET_FLOW/CP210X_SET_FLOW read/write these 0x10 bytes */ | 432 | /* CP210X_GET_FLOW/CP210X_SET_FLOW read/write these 0x10 bytes */ |
| 405 | struct cp210x_flow_ctl { | 433 | struct cp210x_flow_ctl { |
| 406 | __le32 ulControlHandshake; | 434 | __le32 ulControlHandshake; |
| 407 | __le32 ulFlowReplace; | 435 | __le32 ulFlowReplace; |
| 408 | __le32 ulXonLimit; | 436 | __le32 ulXonLimit; |
| 409 | __le32 ulXoffLimit; | 437 | __le32 ulXoffLimit; |
| 410 | } __packed; | 438 | }; |
| 411 | 439 | ||
| 412 | /* cp210x_flow_ctl::ulControlHandshake */ | 440 | /* cp210x_flow_ctl::ulControlHandshake */ |
| 413 | #define CP210X_SERIAL_DTR_MASK GENMASK(1, 0) | 441 | #define CP210X_SERIAL_DTR_MASK GENMASK(1, 0) |
| @@ -441,7 +469,7 @@ struct cp210x_flow_ctl { · 27 unmodified lines | |||
| 441 | struct cp210x_pin_mode { | 469 | struct cp210x_pin_mode { |
| 442 | u8 eci; | 470 | u8 eci; |
| 443 | u8 sci; | 471 | u8 sci; |
| 444 | } __packed; | 472 | }; |
| 445 | 473 | ||
| 446 | #define CP210X_PIN_MODE_MODEM 0 | 474 | #define CP210X_PIN_MODE_MODEM 0 |
| 447 | #define CP210X_PIN_MODE_GPIO BIT(0) | 475 | #define CP210X_PIN_MODE_GPIO BIT(0) |
| @@ -504,7 +532,7 @@ struct cp210x_single_port_config { · 56 unmodified lines | |||
| 504 | struct cp210x_gpio_write { | 532 | struct cp210x_gpio_write { |
| 505 | u8 mask; | 533 | u8 mask; |
| 506 | u8 state; | 534 | u8 state; |
| 507 | } __packed; | 535 | }; |
| 508 | 536 | ||
| 509 | /* | 537 | /* |
| 510 | * Helper to get interface number when we only have struct usb_serial. | 538 | * 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) · 296 unmodified lines | |||
| 807 | 835 | ||
| 808 | static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) | 836 | static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) |
| 809 | { | 837 | { |
| 838 | struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); | ||
| 810 | int result; | 839 | int result; |
| 811 | 840 | ||
| 812 | result = cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_ENABLE); | 841 | 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) · 5 unmodified lines | |||
| 818 | /* Configure the termios structure */ | 847 | /* Configure the termios structure */ |
| 819 | cp210x_get_termios(tty, port); | 848 | cp210x_get_termios(tty, port); |
| 820 | 849 | ||
| 821 | /* The baud rate must be initialised on cp2104 */ | 850 | if (tty) { |
| 822 | if (tty) | 851 | /* The baud rate must be initialised on cp2104 */ |
| 823 | cp210x_change_speed(tty, port, NULL); | 852 | cp210x_change_speed(tty, port, NULL); |
| 824 | 853 | ||
| 825 | return usb_serial_generic_open(tty, port); | 854 | if (I_INPCK(tty)) |
| 855 | cp210x_enable_event_mode(port); | ||
| 856 | } | ||
| 857 | |||
| 858 | result = usb_serial_generic_open(tty, port); | ||
| 859 | if (result) | ||
| 860 | goto err_disable; | ||
| 861 | |||
| 862 | return 0; | ||
| 863 | |||
| 864 | err_disable: | ||
| 865 | cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_DISABLE); | ||
| 866 | port_priv->event_mode = false; | ||
| 867 | |||
| 868 | return result; | ||
| 826 | } | 869 | } |
| 827 | 870 | ||
| 828 | static void cp210x_close(struct usb_serial_port *port) | 871 | static void cp210x_close(struct usb_serial_port *port) |
| 829 | { | 872 | { |
| 873 | struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); | ||
| 874 | |||
| 830 | usb_serial_generic_close(port); | 875 | usb_serial_generic_close(port); |
| 831 | 876 | ||
| 832 | /* Clear both queues; cp2108 needs this to avoid an occasional hang */ | 877 | /* Clear both queues; cp2108 needs this to avoid an occasional hang */ |
| 833 | cp210x_write_u16_reg(port, CP210X_PURGE, PURGE_ALL); | 878 | cp210x_write_u16_reg(port, CP210X_PURGE, PURGE_ALL); |
| 834 | 879 | ||
| 835 | cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_DISABLE); | 880 | cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_DISABLE); |
| 881 | |||
| 882 | /* Disabling the interface disables event-insertion mode. */ | ||
| 883 | port_priv->event_mode = false; | ||
| 884 | } | ||
| 885 | |||
| 886 | static void cp210x_process_lsr(struct usb_serial_port *port, unsigned char lsr, char *flag) | ||
| 887 | { | ||
| 888 | if (lsr & CP210X_LSR_BREAK) { | ||
| 889 | port->icount.brk++; | ||
| 890 | *flag = TTY_BREAK; | ||
| 891 | } else if (lsr & CP210X_LSR_PARITY) { | ||
| 892 | port->icount.parity++; | ||
| 893 | *flag = TTY_PARITY; | ||
| 894 | } else if (lsr & CP210X_LSR_FRAME) { | ||
| 895 | port->icount.frame++; | ||
| 896 | *flag = TTY_FRAME; | ||
| 897 | } | ||
| 898 | |||
| 899 | if (lsr & CP210X_LSR_OVERRUN) { | ||
| 900 | port->icount.overrun++; | ||
| 901 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); | ||
| 902 | } | ||
| 903 | } | ||
| 904 | |||
| 905 | static bool cp210x_process_char(struct usb_serial_port *port, unsigned char *ch, char *flag) | ||
| 906 | { | ||
| 907 | struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); | ||
| 908 | |||
| 909 | switch (port_priv->event_state) { | ||
| 910 | case ES_DATA: | ||
| 911 | if (*ch == CP210X_ESCCHAR) { | ||
| 912 | port_priv->event_state = ES_ESCAPE; | ||
| 913 | break; | ||
| 914 | } | ||
| 915 | return false; | ||
| 916 | case ES_ESCAPE: | ||
| 917 | switch (*ch) { | ||
| 918 | case 0: | ||
| 919 | dev_dbg(&port->dev, "%s - escape char\n", __func__); | ||
| 920 | *ch = CP210X_ESCCHAR; | ||
| 921 | port_priv->event_state = ES_DATA; | ||
| 922 | return false; | ||
| 923 | case 1: | ||
| 924 | port_priv->event_state = ES_LSR_DATA_0; | ||
| 925 | break; | ||
| 926 | case 2: | ||
| 927 | port_priv->event_state = ES_LSR; | ||
| 928 | break; | ||
| 929 | case 3: | ||
| 930 | port_priv->event_state = ES_MSR; | ||
| 931 | break; | ||
| 932 | default: | ||
| 933 | dev_err(&port->dev, "malformed event 0x%02x\n", *ch); | ||
| 934 | port_priv->event_state = ES_DATA; | ||
| 935 | break; | ||
| 936 | } | ||
| 937 | break; | ||
| 938 | case ES_LSR_DATA_0: | ||
| 939 | port_priv->lsr = *ch; | ||
| 940 | port_priv->event_state = ES_LSR_DATA_1; | ||
| 941 | break; | ||
| 942 | case ES_LSR_DATA_1: | ||
| 943 | dev_dbg(&port->dev, "%s - lsr = 0x%02x, data = 0x%02x\n", | ||
| 944 | __func__, port_priv->lsr, *ch); | ||
| 945 | cp210x_process_lsr(port, port_priv->lsr, flag); | ||
| 946 | port_priv->event_state = ES_DATA; | ||
| 947 | return false; | ||
| 948 | case ES_LSR: | ||
| 949 | dev_dbg(&port->dev, "%s - lsr = 0x%02x\n", __func__, *ch); | ||
| 950 | port_priv->lsr = *ch; | ||
| 951 | cp210x_process_lsr(port, port_priv->lsr, flag); | ||
| 952 | port_priv->event_state = ES_DATA; | ||
| 953 | break; | ||
| 954 | case ES_MSR: | ||
| 955 | dev_dbg(&port->dev, "%s - msr = 0x%02x\n", __func__, *ch); | ||
| 956 | /* unimplemented */ | ||
| 957 | port_priv->event_state = ES_DATA; | ||
| 958 | break; | ||
| 959 | } | ||
| 960 | |||
| 961 | return true; | ||
| 962 | } | ||
| 963 | |||
| 964 | static void cp210x_process_read_urb(struct urb *urb) | ||
| 965 | { | ||
| 966 | struct usb_serial_port *port = urb->context; | ||
| 967 | struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); | ||
| 968 | unsigned char *ch = urb->transfer_buffer; | ||
| 969 | char flag; | ||
| 970 | int i; | ||
| 971 | |||
| 972 | if (!urb->actual_length) | ||
| 973 | return; | ||
| 974 | |||
| 975 | if (port_priv->event_mode) { | ||
| 976 | for (i = 0; i < urb->actual_length; i++, ch++) { | ||
| 977 | flag = TTY_NORMAL; | ||
| 978 | |||
| 979 | if (cp210x_process_char(port, ch, &flag)) | ||
| 980 | continue; | ||
| 981 | |||
| 982 | tty_insert_flip_char(&port->port, *ch, flag); | ||
| 983 | } | ||
| 984 | } else { | ||
| 985 | tty_insert_flip_string(&port->port, ch, urb->actual_length); | ||
| 986 | } | ||
| 987 | tty_flip_buffer_push(&port->port); | ||
| 836 | } | 988 | } |
| 837 | 989 | ||
| 838 | /* | 990 | /* |
| @@ -915,6 +1067,7 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, · 76 unmodified lines | |||
| 915 | u32 baud; | 1067 | u32 baud; |
| 916 | u16 bits; | 1068 | u16 bits; |
| 917 | u32 ctl_hs; | 1069 | u32 ctl_hs; |
| 1070 | u32 flow_repl; | ||
| 918 | 1071 | ||
| 919 | cp210x_read_u32_reg(port, CP210X_GET_BAUDRATE, &baud); | 1072 | cp210x_read_u32_reg(port, CP210X_GET_BAUDRATE, &baud); |
| 920 | 1073 | ||
| @@ -1015,6 +1168,22 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, · 94 unmodified lines | |||
| 1015 | ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake); | 1168 | ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake); |
| 1016 | if (ctl_hs & CP210X_SERIAL_CTS_HANDSHAKE) { | 1169 | if (ctl_hs & CP210X_SERIAL_CTS_HANDSHAKE) { |
| 1017 | dev_dbg(dev, "%s - flow control = CRTSCTS\n", __func__); | 1170 | dev_dbg(dev, "%s - flow control = CRTSCTS\n", __func__); |
| 1171 | /* | ||
| 1172 | * When the port is closed, the CP210x hardware disables | ||
| 1173 | * auto-RTS and RTS is deasserted but it leaves auto-CTS when | ||
| 1174 | * in hardware flow control mode. When re-opening the port, if | ||
| 1175 | * auto-CTS is enabled on the cp210x, then auto-RTS must be | ||
| 1176 | * re-enabled in the driver. | ||
| 1177 | */ | ||
| 1178 | flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace); | ||
| 1179 | flow_repl &= ~CP210X_SERIAL_RTS_MASK; | ||
| 1180 | flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_FLOW_CTL); | ||
| 1181 | flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl); | ||
| 1182 | cp210x_write_reg_block(port, | ||
| 1183 | CP210X_SET_FLOW, | ||
| 1184 | &flow_ctl, | ||
| 1185 | sizeof(flow_ctl)); | ||
| 1186 | |||
| 1018 | cflag |= CRTSCTS; | 1187 | cflag |= CRTSCTS; |
| 1019 | } else { | 1188 | } else { |
| 1020 | dev_dbg(dev, "%s - flow control = NONE\n", __func__); | 1189 | dev_dbg(dev, "%s - flow control = NONE\n", __func__); |
| @@ -1148,6 +1317,41 @@ static void cp210x_change_speed(struct tty_struct *tty, · 127 unmodified lines | |||
| 1148 | tty_encode_baud_rate(tty, baud, baud); | 1317 | tty_encode_baud_rate(tty, baud, baud); |
| 1149 | } | 1318 | } |
| 1150 | 1319 | ||
| 1320 | static void cp210x_enable_event_mode(struct usb_serial_port *port) | ||
| 1321 | { | ||
| 1322 | struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); | ||
| 1323 | int ret; | ||
| 1324 | |||
| 1325 | if (port_priv->event_mode) | ||
| 1326 | return; | ||
| 1327 | |||
| 1328 | port_priv->event_state = ES_DATA; | ||
| 1329 | port_priv->event_mode = true; | ||
| 1330 | |||
| 1331 | ret = cp210x_write_u16_reg(port, CP210X_EMBED_EVENTS, CP210X_ESCCHAR); | ||
| 1332 | if (ret) { | ||
| 1333 | dev_err(&port->dev, "failed to enable events: %d\n", ret); | ||
| 1334 | port_priv->event_mode = false; | ||
| 1335 | } | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | static void cp210x_disable_event_mode(struct usb_serial_port *port) | ||
| 1339 | { | ||
| 1340 | struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); | ||
| 1341 | int ret; | ||
| 1342 | |||
| 1343 | if (!port_priv->event_mode) | ||
| 1344 | return; | ||
| 1345 | |||
| 1346 | ret = cp210x_write_u16_reg(port, CP210X_EMBED_EVENTS, 0); | ||
| 1347 | if (ret) { | ||
| 1348 | dev_err(&port->dev, "failed to disable events: %d\n", ret); | ||
| 1349 | return; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | port_priv->event_mode = false; | ||
| 1353 | } | ||
| 1354 | |||
| 1151 | static void cp210x_set_termios(struct tty_struct *tty, | 1355 | static void cp210x_set_termios(struct tty_struct *tty, |
| 1152 | struct usb_serial_port *port, struct ktermios *old_termios) | 1356 | struct usb_serial_port *port, struct ktermios *old_termios) |
| 1153 | { | 1357 | { |
| @@ -1270,6 +1474,14 @@ static void cp210x_set_termios(struct tty_struct *tty, · 116 unmodified lines | |||
| 1270 | sizeof(flow_ctl)); | 1474 | sizeof(flow_ctl)); |
| 1271 | } | 1475 | } |
| 1272 | 1476 | ||
| 1477 | /* | ||
| 1478 | * Enable event-insertion mode only if input parity checking is | ||
| 1479 | * enabled for now. | ||
| 1480 | */ | ||
| 1481 | if (I_INPCK(tty)) | ||
| 1482 | cp210x_enable_event_mode(port); | ||
| 1483 | else | ||
| 1484 | cp210x_disable_event_mode(port); | ||
| 1273 | } | 1485 | } |
| 1274 | 1486 | ||
| 1275 | static int cp210x_tiocmset(struct tty_struct *tty, | 1487 | static int cp210x_tiocmset(struct tty_struct *tty, |
| @@ -1048,7 +1048,7 @@ static void cypress_read_int_callback(struct urb *urb) · 1047 unmodified lines | |||
| 1048 | return; | 1048 | return; |
| 1049 | case -EPIPE: | 1049 | case -EPIPE: |
| 1050 | /* Can't call usb_clear_halt while in_interrupt */ | 1050 | /* Can't call usb_clear_halt while in_interrupt */ |
| 1051 | /* FALLS THROUGH */ | 1051 | fallthrough; |
| 1052 | default: | 1052 | default: |
| 1053 | /* something ugly is going on... */ | 1053 | /* something ugly is going on... */ |
| 1054 | dev_err(dev, "%s - unexpected nonzero read status received: %d\n", | 1054 | dev_err(dev, "%s - unexpected nonzero read status received: %d\n", |
| @@ -1197,7 +1197,7 @@ static void cypress_write_int_callback(struct urb *urb) · 142 unmodified lines | |||
| 1197 | return; | 1197 | return; |
| 1198 | case -EPIPE: | 1198 | case -EPIPE: |
| 1199 | /* Cannot call usb_clear_halt while in_interrupt */ | 1199 | /* Cannot call usb_clear_halt while in_interrupt */ |
| 1200 | /* FALLTHROUGH */ | 1200 | fallthrough; |
| 1201 | default: | 1201 | default: |
| 1202 | dev_err(dev, "%s - unexpected nonzero write status received: %d\n", | 1202 | dev_err(dev, "%s - unexpected nonzero write status received: %d\n", |
| 1203 | __func__, status); | 1203 | __func__, status); |
| @@ -424,7 +424,7 @@ static void f81232_process_read_urb(struct urb *urb) · 423 unmodified lines | |||
| 424 | lsr = data[i]; | 424 | lsr = data[i]; |
| 425 | tty_flag = f81232_handle_lsr(port, lsr); | 425 | tty_flag = f81232_handle_lsr(port, lsr); |
| 426 | 426 | ||
| 427 | if (port->port.console && port->sysrq) { | 427 | if (port->sysrq) { |
| 428 | if (usb_serial_handle_sysrq_char(port, data[i + 1])) | 428 | if (usb_serial_handle_sysrq_char(port, data[i + 1])) |
| 429 | continue; | 429 | continue; |
| 430 | } | 430 | } |
| @@ -461,7 +461,7 @@ static void f81534a_process_read_urb(struct urb *urb) · 30 unmodified lines | |||
| 461 | lsr = data[len - 1]; | 461 | lsr = data[len - 1]; |
| 462 | tty_flag = f81232_handle_lsr(port, lsr); | 462 | tty_flag = f81232_handle_lsr(port, lsr); |
| 463 | 463 | ||
| 464 | if (port->port.console && port->sysrq) { | 464 | if (port->sysrq) { |
| 465 | for (i = 1; i < len - 1; ++i) { | 465 | for (i = 1; i < len - 1; ++i) { |
| 466 | if (!usb_serial_handle_sysrq_char(port, data[i])) { | 466 | if (!usb_serial_handle_sysrq_char(port, data[i])) { |
| 467 | tty_insert_flip_char(&port->port, data[i], | 467 | tty_insert_flip_char(&port->port, data[i], |
| @@ -1238,7 +1238,7 @@ static void f81534_process_per_serial_block(struct usb_serial_port *port, · 1237 unmodified lines | |||
| 1238 | schedule_work(&port_priv->lsr_work); | 1238 | schedule_work(&port_priv->lsr_work); |
| 1239 | } | 1239 | } |
| 1240 | 1240 | ||
| 1241 | if (port->port.console && port->sysrq) { | 1241 | if (port->sysrq) { |
| 1242 | if (usb_serial_handle_sysrq_char(port, data[i])) | 1242 | if (usb_serial_handle_sysrq_char(port, data[i])) |
| 1243 | continue; | 1243 | continue; |
| 1244 | } | 1244 | } |
| @@ -2480,12 +2480,12 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port, · 2479 unmodified lines | |||
| 2480 | #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) | 2480 | #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) |
| 2481 | 2481 | ||
| 2482 | static int ftdi_process_packet(struct usb_serial_port *port, | 2482 | static int ftdi_process_packet(struct usb_serial_port *port, |
| 2483 | struct ftdi_private *priv, char *packet, int len) | 2483 | struct ftdi_private *priv, unsigned char *buf, int len) |
| 2484 | { | 2484 | { |
| 2485 | unsigned char status; | ||
| 2486 | bool brkint = false; | ||
| 2485 | int i; | 2487 | int i; |
| 2486 | char status; | ||
| 2487 | char flag; | 2488 | char flag; |
| 2488 | char *ch; | ||
| 2489 | 2489 | ||
| 2490 | if (len < 2) { | 2490 | if (len < 2) { |
| 2491 | dev_dbg(&port->dev, "malformed packet\n"); | 2491 | dev_dbg(&port->dev, "malformed packet\n"); |
| @@ -2495,7 +2495,7 @@ static int ftdi_process_packet(struct usb_serial_port *port, · 3 unmodified lines | |||
| 2495 | /* Compare new line status to the old one, signal if different/ | 2495 | /* Compare new line status to the old one, signal if different/ |
| 2496 | N.B. packet may be processed more than once, but differences | 2496 | N.B. packet may be processed more than once, but differences |
| 2497 | are only processed once. */ | 2497 | are only processed once. */ |
| 2498 | status = packet[0] & FTDI_STATUS_B0_MASK; | 2498 | status = buf[0] & FTDI_STATUS_B0_MASK; |
| 2499 | if (status != priv->prev_status) { | 2499 | if (status != priv->prev_status) { |
| 2500 | char diff_status = status ^ priv->prev_status; | 2500 | char diff_status = status ^ priv->prev_status; |
| 2501 | 2501 | ||
| @@ -2521,13 +2521,12 @@ static int ftdi_process_packet(struct usb_serial_port *port, · 19 unmodified lines | |||
| 2521 | } | 2521 | } |
| 2522 | 2522 | ||
| 2523 | /* save if the transmitter is empty or not */ | 2523 | /* save if the transmitter is empty or not */ |
| 2524 | if (packet[1] & FTDI_RS_TEMT) | 2524 | if (buf[1] & FTDI_RS_TEMT) |
| 2525 | priv->transmit_empty = 1; | 2525 | priv->transmit_empty = 1; |
| 2526 | else | 2526 | else |
| 2527 | priv->transmit_empty = 0; | 2527 | priv->transmit_empty = 0; |
| 2528 | 2528 | ||
| 2529 | len -= 2; | 2529 | if (len == 2) |
| 2530 | if (!len) | ||
| 2531 | return 0; /* status only */ | 2530 | return 0; /* status only */ |
| 2532 | 2531 | ||
| 2533 | /* | 2532 | /* |
| @@ -2535,47 +2534,57 @@ static int ftdi_process_packet(struct usb_serial_port *port, · 1 unmodified line | |||
| 2535 | * data payload to avoid over-reporting. | 2534 | * data payload to avoid over-reporting. |
| 2536 | */ | 2535 | */ |
| 2537 | flag = TTY_NORMAL; | 2536 | flag = TTY_NORMAL; |
| 2538 | if (packet[1] & FTDI_RS_ERR_MASK) { | 2537 | if (buf[1] & FTDI_RS_ERR_MASK) { |
| 2539 | /* Break takes precedence over parity, which takes precedence | 2538 | /* |
| 2540 | * over framing errors */ | 2539 | * Break takes precedence over parity, which takes precedence |
| 2541 | if (packet[1] & FTDI_RS_BI) { | 2540 | * over framing errors. Note that break is only associated |
| 2542 | flag = TTY_BREAK; | 2541 | * with the last character in the buffer and only when it's a |
| 2542 | * NUL. | ||
| 2543 | */ | ||
| 2544 | if (buf[1] & FTDI_RS_BI && buf[len - 1] == '\0') { | ||
| 2543 | port->icount.brk++; | 2545 | port->icount.brk++; |
| 2544 | usb_serial_handle_break(port); | 2546 | brkint = true; |
| 2545 | } else if (packet[1] & FTDI_RS_PE) { | 2547 | } |
| 2548 | if (buf[1] & FTDI_RS_PE) { | ||
| 2546 | flag = TTY_PARITY; | 2549 | flag = TTY_PARITY; |
| 2547 | port->icount.parity++; | 2550 | port->icount.parity++; |
| 2548 | } else if (packet[1] & FTDI_RS_FE) { | 2551 | } else if (buf[1] & FTDI_RS_FE) { |
| 2549 | flag = TTY_FRAME; | 2552 | flag = TTY_FRAME; |
| 2550 | port->icount.frame++; | 2553 | port->icount.frame++; |
| 2551 | } | 2554 | } |
| 2552 | /* Overrun is special, not associated with a char */ | 2555 | /* Overrun is special, not associated with a char */ |
| 2553 | if (packet[1] & FTDI_RS_OE) { | 2556 | if (buf[1] & FTDI_RS_OE) { |
| 2554 | port->icount.overrun++; | 2557 | port->icount.overrun++; |
| 2555 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); | 2558 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
| 2556 | } | 2559 | } |
| 2557 | } | 2560 | } |
| 2558 | 2561 | ||
| 2559 | port->icount.rx += len; | 2562 | port->icount.rx += len - 2; |
| 2560 | ch = packet + 2; | ||
| 2561 | 2563 | ||
| 2562 | if (port->port.console && port->sysrq) { | 2564 | if (brkint || port->sysrq) { |
| 2563 | for (i = 0; i < len; i++, ch++) { | 2565 | for (i = 2; i < len; i++) { |
| 2564 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 2566 | if (brkint && i == len - 1) { |
| 2565 | tty_insert_flip_char(&port->port, *ch, flag); | 2567 | if (usb_serial_handle_break(port)) |
| 2568 | return len - 3; | ||
| 2569 | flag = TTY_BREAK; | ||
| 2570 | } | ||
| 2571 | if (usb_serial_handle_sysrq_char(port, buf[i])) | ||
| 2572 | continue; | ||
| 2573 | tty_insert_flip_char(&port->port, buf[i], flag); | ||
| 2566 | } | 2574 | } |
| 2567 | } else { | 2575 | } else { |
| 2568 | tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len); | 2576 | tty_insert_flip_string_fixed_flag(&port->port, buf + 2, flag, |
| 2577 | len - 2); | ||
| 2569 | } | 2578 | } |
| 2570 | 2579 | ||
| 2571 | return len; | 2580 | return len - 2; |
| 2572 | } | 2581 | } |
| 2573 | 2582 | ||
| 2574 | static void ftdi_process_read_urb(struct urb *urb) | 2583 | static void ftdi_process_read_urb(struct urb *urb) |
| 2575 | { | 2584 | { |
| 2576 | struct usb_serial_port *port = urb->context; | 2585 | struct usb_serial_port *port = urb->context; |
| 2577 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2586 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
| 2578 | char *data = (char *)urb->transfer_buffer; | 2587 | char *data = urb->transfer_buffer; |
| 2579 | int i; | 2588 | int i; |
| 2580 | int len; | 2589 | int len; |
| 2581 | int count = 0; | 2590 | int count = 0; |
| @@ -179,19 +179,22 @@ static unsigned char const GARMIN_START_SESSION_REPLY[] · 178 unmodified lines | |||
| 179 | = { 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0 }; | 179 | = { 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0 }; |
| 180 | static unsigned char const GARMIN_BULK_IN_AVAIL_REPLY[] | 180 | static unsigned char const GARMIN_BULK_IN_AVAIL_REPLY[] |
| 181 | = { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 }; | 181 | = { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 }; |
| 182 | static unsigned char const GARMIN_STOP_TRANSFER_REQ[] | ||
| 183 | = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0 }; | ||
| 184 | static unsigned char const GARMIN_STOP_TRANSFER_REQ_V2[] | ||
| 185 | = { 20, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0 }; | ||
| 186 | |||
| 187 | /* packets currently unused, left as documentation */ | ||
| 188 | #if 0 | ||
| 182 | static unsigned char const GARMIN_APP_LAYER_REPLY[] | 189 | static unsigned char const GARMIN_APP_LAYER_REPLY[] |
| 183 | = { 0x14, 0, 0, 0 }; | 190 | = { 0x14, 0, 0, 0 }; |
| 184 | static unsigned char const GARMIN_START_PVT_REQ[] | 191 | static unsigned char const GARMIN_START_PVT_REQ[] |
| 185 | = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0 }; | 192 | = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0 }; |
| 186 | static unsigned char const GARMIN_STOP_PVT_REQ[] | 193 | static unsigned char const GARMIN_STOP_PVT_REQ[] |
| 187 | = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 50, 0 }; | 194 | = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 50, 0 }; |
| 188 | static unsigned char const GARMIN_STOP_TRANSFER_REQ[] | ||
| 189 | = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0 }; | ||
| 190 | static unsigned char const GARMIN_STOP_TRANSFER_REQ_V2[] | ||
| 191 | = { 20, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0 }; | ||
| 192 | static unsigned char const PRIVATE_REQ[] | 195 | static unsigned char const PRIVATE_REQ[] |
| 193 | = { 0x4B, 0x6E, 0x10, 0x01, 0xFF, 0, 0, 0, 0xFF, 0, 0, 0 }; | 196 | = { 0x4B, 0x6E, 0x10, 0x01, 0xFF, 0, 0, 0, 0xFF, 0, 0, 0 }; |
| 194 | 197 | #endif | |
| 195 | 198 | ||
| 196 | 199 | ||
| 197 | static const struct usb_device_id id_table[] = { | 200 | static const struct usb_device_id id_table[] = { |
| @@ -345,7 +345,7 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs); · 344 unmodified lines | |||
| 345 | void usb_serial_generic_process_read_urb(struct urb *urb) | 345 | void usb_serial_generic_process_read_urb(struct urb *urb) |
| 346 | { | 346 | { |
| 347 | struct usb_serial_port *port = urb->context; | 347 | struct usb_serial_port *port = urb->context; |
| 348 | char *ch = (char *)urb->transfer_buffer; | 348 | char *ch = urb->transfer_buffer; |
| 349 | int i; | 349 | int i; |
| 350 | 350 | ||
| 351 | if (!urb->actual_length) | 351 | if (!urb->actual_length) |
| @@ -355,13 +355,13 @@ void usb_serial_generic_process_read_urb(struct urb *urb) · 3 unmodified lines | |||
| 355 | * stuff like 3G modems, so shortcircuit it in the 99.9999999% of | 355 | * stuff like 3G modems, so shortcircuit it in the 99.9999999% of |
| 356 | * cases where the USB serial is not a console anyway. | 356 | * cases where the USB serial is not a console anyway. |
| 357 | */ | 357 | */ |
| 358 | if (!port->port.console || !port->sysrq) { | 358 | if (port->sysrq) { |
| 359 | tty_insert_flip_string(&port->port, ch, urb->actual_length); | ||
| 360 | } else { | ||
| 361 | for (i = 0; i < urb->actual_length; i++, ch++) { | 359 | for (i = 0; i < urb->actual_length; i++, ch++) { |
| 362 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 360 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
| 363 | tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); | 361 | tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); |
| 364 | } | 362 | } |
| 363 | } else { | ||
| 364 | tty_insert_flip_string(&port->port, ch, urb->actual_length); | ||
| 365 | } | 365 | } |
| 366 | tty_flip_buffer_push(&port->port); | 366 | tty_flip_buffer_push(&port->port); |
| 367 | } | 367 | } |
| @@ -571,10 +571,10 @@ int usb_serial_generic_get_icount(struct tty_struct *tty, · 203 unmodified lines | |||
| 571 | } | 571 | } |
| 572 | EXPORT_SYMBOL_GPL(usb_serial_generic_get_icount); | 572 | EXPORT_SYMBOL_GPL(usb_serial_generic_get_icount); |
| 573 | 573 | ||
| 574 | #ifdef CONFIG_MAGIC_SYSRQ | 574 | #if defined(CONFIG_USB_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
| 575 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) | 575 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
| 576 | { | 576 | { |
| 577 | if (port->sysrq && port->port.console) { | 577 | if (port->sysrq) { |
| 578 | if (ch && time_before(jiffies, port->sysrq)) { | 578 | if (ch && time_before(jiffies, port->sysrq)) { |
| 579 | handle_sysrq(ch); | 579 | handle_sysrq(ch); |
| 580 | port->sysrq = 0; | 580 | port->sysrq = 0; |
| @@ -584,16 +584,13 @@ int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) · 3 unmodified lines | |||
| 584 | } | 584 | } |
| 585 | return 0; | 585 | return 0; |
| 586 | } | 586 | } |
| 587 | #else | ||
| 588 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) | ||
| 589 | { | ||
| 590 | return 0; | ||
| 591 | } | ||
| 592 | #endif | ||
| 593 | EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char); | 587 | EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char); |
| 594 | 588 | ||
| 595 | int usb_serial_handle_break(struct usb_serial_port *port) | 589 | int usb_serial_handle_break(struct usb_serial_port *port) |
| 596 | { | 590 | { |
| 591 | if (!port->port.console) | ||
| 592 | return 0; | ||
| 593 | |||
| 597 | if (!port->sysrq) { | 594 | if (!port->sysrq) { |
| 598 | port->sysrq = jiffies + HZ*5; | 595 | port->sysrq = jiffies + HZ*5; |
| 599 | return 1; | 596 | return 1; |
| @@ -602,6 +599,7 @@ int usb_serial_handle_break(struct usb_serial_port *port) · 2 unmodified lines | |||
| 602 | return 0; | 599 | return 0; |
| 603 | } | 600 | } |
| 604 | EXPORT_SYMBOL_GPL(usb_serial_handle_break); | 601 | EXPORT_SYMBOL_GPL(usb_serial_handle_break); |
| 602 | #endif | ||
| 605 | 603 | ||
| 606 | /** | 604 | /** |
| 607 | * usb_serial_handle_dcd_change - handle a change of carrier detect state | 605 | * usb_serial_handle_dcd_change - handle a change of carrier detect state |
| @@ -1752,7 +1752,7 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, · 1751 unmodified lines | |||
| 1752 | edge_serial->rxState = EXPECT_HDR2; | 1752 | edge_serial->rxState = EXPECT_HDR2; |
| 1753 | break; | 1753 | break; |
| 1754 | } | 1754 | } |
| 1755 | /* Fall through */ | 1755 | fallthrough; |
| 1756 | case EXPECT_HDR2: | 1756 | case EXPECT_HDR2: |
| 1757 | edge_serial->rxHeader2 = *buffer; | 1757 | edge_serial->rxHeader2 = *buffer; |
| 1758 | ++buffer; | 1758 | ++buffer; |
| @@ -1804,7 +1804,7 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, · 45 unmodified lines | |||
| 1804 | edge_serial->rxState = EXPECT_DATA; | 1804 | edge_serial->rxState = EXPECT_DATA; |
| 1805 | break; | 1805 | break; |
| 1806 | } | 1806 | } |
| 1807 | /* Fall through */ | 1807 | fallthrough; |
| 1808 | case EXPECT_DATA: /* Expect data */ | 1808 | case EXPECT_DATA: /* Expect data */ |
| 1809 | if (bufferLength < edge_serial->rxBytesRemaining) { | 1809 | if (bufferLength < edge_serial->rxBytesRemaining) { |
| 1810 | rxLen = bufferLength; | 1810 | rxLen = bufferLength; |
| @@ -158,7 +158,6 @@ static int iuu_tiocmget(struct tty_struct *tty) · 157 unmodified lines | |||
| 158 | static void iuu_rxcmd(struct urb *urb) | 158 | static void iuu_rxcmd(struct urb *urb) |
| 159 | { | 159 | { |
| 160 | struct usb_serial_port *port = urb->context; | 160 | struct usb_serial_port *port = urb->context; |
| 161 | int result; | ||
| 162 | int status = urb->status; | 161 | int status = urb->status; |
| 163 | 162 | ||
| 164 | if (status) { | 163 | if (status) { |
| @@ -174,7 +173,7 @@ static void iuu_rxcmd(struct urb *urb) · 9 unmodified lines | |||
| 174 | port->bulk_out_endpointAddress), | 173 | port->bulk_out_endpointAddress), |
| 175 | port->write_urb->transfer_buffer, 1, | 174 | port->write_urb->transfer_buffer, 1, |
| 176 | read_rxcmd_callback, port); | 175 | read_rxcmd_callback, port); |
| 177 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 176 | usb_submit_urb(port->write_urb, GFP_ATOMIC); |
| 178 | } | 177 | } |
| 179 | 178 | ||
| 180 | static int iuu_reset(struct usb_serial_port *port, u8 wt) | 179 | static int iuu_reset(struct usb_serial_port *port, u8 wt) |
| @@ -241,7 +240,6 @@ static void iuu_update_status_callback(struct urb *urb) · 60 unmodified lines | |||
| 241 | static void iuu_status_callback(struct urb *urb) | 240 | static void iuu_status_callback(struct urb *urb) |
| 242 | { | 241 | { |
| 243 | struct usb_serial_port *port = urb->context; | 242 | struct usb_serial_port *port = urb->context; |
| 244 | int result; | ||
| 245 | int status = urb->status; | 243 | int status = urb->status; |
| 246 | 244 | ||
| 247 | dev_dbg(&port->dev, "%s - status = %d\n", __func__, status); | 245 | dev_dbg(&port->dev, "%s - status = %d\n", __func__, status); |
| @@ -250,7 +248,7 @@ static void iuu_status_callback(struct urb *urb) · 2 unmodified lines | |||
| 250 | port->bulk_in_endpointAddress), | 248 | port->bulk_in_endpointAddress), |
| 251 | port->read_urb->transfer_buffer, 256, | 249 | port->read_urb->transfer_buffer, 256, |
| 252 | iuu_update_status_callback, port); | 250 | iuu_update_status_callback, port); |
| 253 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 251 | usb_submit_urb(port->read_urb, GFP_ATOMIC); |
| 254 | } | 252 | } |
| 255 | 253 | ||
| 256 | static int iuu_status(struct usb_serial_port *port) | 254 | 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, · 94 unmodified lines | |||
| 351 | static void iuu_led_activity_on(struct urb *urb) | 349 | static void iuu_led_activity_on(struct urb *urb) |
| 352 | { | 350 | { |
| 353 | struct usb_serial_port *port = urb->context; | 351 | struct usb_serial_port *port = urb->context; |
| 354 | int result; | ||
| 355 | char *buf_ptr = port->write_urb->transfer_buffer; | 352 | char *buf_ptr = port->write_urb->transfer_buffer; |
| 356 | *buf_ptr++ = IUU_SET_LED; | 353 | |
| 357 | if (xmas) { | 354 | if (xmas) { |
| 358 | get_random_bytes(buf_ptr, 6); | 355 | buf_ptr[0] = IUU_SET_LED; |
| 359 | *(buf_ptr+7) = 1; | 356 | get_random_bytes(buf_ptr + 1, 6); |
| 357 | buf_ptr[7] = 1; | ||
| 360 | } else { | 358 | } else { |
| 361 | iuu_rgbf_fill_buffer(buf_ptr, 255, 255, 0, 0, 0, 0, 255); | 359 | iuu_rgbf_fill_buffer(buf_ptr, 255, 255, 0, 0, 0, 0, 255); |
| 362 | } | 360 | } |
| @@ -366,27 +364,27 @@ static void iuu_led_activity_on(struct urb *urb) · 3 unmodified lines | |||
| 366 | port->bulk_out_endpointAddress), | 364 | port->bulk_out_endpointAddress), |
| 367 | port->write_urb->transfer_buffer, 8 , | 365 | port->write_urb->transfer_buffer, 8 , |
| 368 | iuu_rxcmd, port); | 366 | iuu_rxcmd, port); |
| 369 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 367 | usb_submit_urb(port->write_urb, GFP_ATOMIC); |
| 370 | } | 368 | } |
| 371 | 369 | ||
| 372 | static void iuu_led_activity_off(struct urb *urb) | 370 | static void iuu_led_activity_off(struct urb *urb) |
| 373 | { | 371 | { |
| 374 | struct usb_serial_port *port = urb->context; | 372 | struct usb_serial_port *port = urb->context; |
| 375 | int result; | ||
| 376 | char *buf_ptr = port->write_urb->transfer_buffer; | 373 | char *buf_ptr = port->write_urb->transfer_buffer; |
| 374 | |||
| 377 | if (xmas) { | 375 | if (xmas) { |
| 378 | iuu_rxcmd(urb); | 376 | iuu_rxcmd(urb); |
| 379 | return; | 377 | return; |
| 380 | } else { | ||
| 381 | *buf_ptr++ = IUU_SET_LED; | ||
| 382 | iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255); | ||
| 383 | } | 378 | } |
| 379 | |||
| 380 | iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255); | ||
| 381 | |||
| 384 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | 382 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, |
| 385 | usb_sndbulkpipe(port->serial->dev, | 383 | usb_sndbulkpipe(port->serial->dev, |
| 386 | port->bulk_out_endpointAddress), | 384 | port->bulk_out_endpointAddress), |
| 387 | port->write_urb->transfer_buffer, 8 , | 385 | port->write_urb->transfer_buffer, 8 , |
| 388 | iuu_rxcmd, port); | 386 | iuu_rxcmd, port); |
| 389 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 387 | usb_submit_urb(port->write_urb, GFP_ATOMIC); |
| 390 | } | 388 | } |
| 391 | 389 | ||
| 392 | 390 | ||
| @@ -664,11 +664,10 @@ static void keyspan_pda_close(struct usb_serial_port *port) · 663 unmodified lines | |||
| 664 | /* download the firmware to a "fake" device (pre-renumeration) */ | 664 | /* download the firmware to a "fake" device (pre-renumeration) */ |
| 665 | static int keyspan_pda_fake_startup(struct usb_serial *serial) | 665 | static int keyspan_pda_fake_startup(struct usb_serial *serial) |
| 666 | { | 666 | { |
| 667 | int response; | ||
| 668 | const char *fw_name; | 667 | const char *fw_name; |
| 669 | 668 | ||
| 670 | /* download the firmware here ... */ | 669 | /* download the firmware here ... */ |
| 671 | response = ezusb_fx1_set_reset(serial->dev, 1); | 670 | ezusb_fx1_set_reset(serial->dev, 1); |
| 672 | 671 | ||
| 673 | if (0) { ; } | 672 | if (0) { ; } |
| 674 | #ifdef KEYSPAN | 673 | #ifdef KEYSPAN |
| @@ -499,7 +499,7 @@ static void kobil_set_termios(struct tty_struct *tty, · 498 unmodified lines | |||
| 499 | break; | 499 | break; |
| 500 | default: | 500 | default: |
| 501 | speed = 9600; | 501 | speed = 9600; |
| 502 | /* fall through */ | 502 | fallthrough; |
| 503 | case 9600: | 503 | case 9600: |
| 504 | urb_val = SUSBCR_SBR_9600; | 504 | urb_val = SUSBCR_SBR_9600; |
| 505 | break; | 505 | break; |
| @@ -526,6 +526,10 @@ static void kobil_set_termios(struct tty_struct *tty, · 20 unmodified lines | |||
| 526 | 0, | 526 | 0, |
| 527 | KOBIL_TIMEOUT | 527 | KOBIL_TIMEOUT |
| 528 | ); | 528 | ); |
| 529 | if (result) { | ||
| 530 | dev_err(&port->dev, "failed to update line settings: %d\n", | ||
| 531 | result); | ||
| 532 | } | ||
| 529 | } | 533 | } |
| 530 | 534 | ||
| 531 | static int kobil_ioctl(struct tty_struct *tty, | 535 | static int kobil_ioctl(struct tty_struct *tty, |
| @@ -327,14 +327,14 @@ static void mxuport_process_read_urb_data(struct usb_serial_port *port, · 326 unmodified lines | |||
| 327 | { | 327 | { |
| 328 | int i; | 328 | int i; |
| 329 | 329 | ||
| 330 | if (!port->port.console || !port->sysrq) { | 330 | if (port->sysrq) { |
| 331 | tty_insert_flip_string(&port->port, data, size); | ||
| 332 | } else { | ||
| 333 | for (i = 0; i < size; i++, data++) { | 331 | for (i = 0; i < size; i++, data++) { |
| 334 | if (!usb_serial_handle_sysrq_char(port, *data)) | 332 | if (!usb_serial_handle_sysrq_char(port, *data)) |
| 335 | tty_insert_flip_char(&port->port, *data, | 333 | tty_insert_flip_char(&port->port, *data, |
| 336 | TTY_NORMAL); | 334 | TTY_NORMAL); |
| 337 | } | 335 | } |
| 336 | } else { | ||
| 337 | tty_insert_flip_string(&port->port, data, size); | ||
| 338 | } | 338 | } |
| 339 | tty_flip_buffer_push(&port->port); | 339 | tty_flip_buffer_push(&port->port); |
| 340 | } | 340 | } |
| @@ -2157,8 +2157,7 @@ static void option_instat_callback(struct urb *urb) · 2156 unmodified lines | |||
| 2157 | dev_dbg(dev, "%s: urb %p port %p has data %p\n", __func__, urb, port, portdata); | 2157 | dev_dbg(dev, "%s: urb %p port %p has data %p\n", __func__, urb, port, portdata); |
| 2158 | 2158 | ||
| 2159 | if (status == 0) { | 2159 | if (status == 0) { |
| 2160 | struct usb_ctrlrequest *req_pkt = | 2160 | struct usb_ctrlrequest *req_pkt = urb->transfer_buffer; |
| 2161 | (struct usb_ctrlrequest *)urb->transfer_buffer; | ||
| 2162 | 2161 | ||
| 2163 | if (!req_pkt) { | 2162 | if (!req_pkt) { |
| 2164 | dev_dbg(dev, "%s: NULL req_pkt\n", __func__); | 2163 | dev_dbg(dev, "%s: NULL req_pkt\n", __func__); |
| @@ -1101,7 +1101,7 @@ static void pl2303_process_read_urb(struct urb *urb) · 1100 unmodified lines | |||
| 1101 | if (line_status & UART_OVERRUN_ERROR) | 1101 | if (line_status & UART_OVERRUN_ERROR) |
| 1102 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); | 1102 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
| 1103 | 1103 | ||
| 1104 | if (port->port.console && port->sysrq) { | 1104 | if (port->sysrq) { |
| 1105 | for (i = 0; i < urb->actual_length; ++i) | 1105 | for (i = 0; i < urb->actual_length; ++i) |
| 1106 | if (!usb_serial_handle_sysrq_char(port, data[i])) | 1106 | if (!usb_serial_handle_sysrq_char(port, data[i])) |
| 1107 | tty_insert_flip_char(&port->port, data[i], | 1107 | tty_insert_flip_char(&port->port, data[i], |
| @@ -155,6 +155,7 @@ static const struct usb_device_id id_table[] = { · 154 unmodified lines | |||
| 155 | {DEVICE_SWI(0x1199, 0x9056)}, /* Sierra Wireless Modem */ | 155 | {DEVICE_SWI(0x1199, 0x9056)}, /* Sierra Wireless Modem */ |
| 156 | {DEVICE_SWI(0x1199, 0x9060)}, /* Sierra Wireless Modem */ | 156 | {DEVICE_SWI(0x1199, 0x9060)}, /* Sierra Wireless Modem */ |
| 157 | {DEVICE_SWI(0x1199, 0x9061)}, /* Sierra Wireless Modem */ | 157 | {DEVICE_SWI(0x1199, 0x9061)}, /* Sierra Wireless Modem */ |
| 158 | {DEVICE_SWI(0x1199, 0x9062)}, /* Sierra Wireless EM7305 QDL */ | ||
| 158 | {DEVICE_SWI(0x1199, 0x9063)}, /* Sierra Wireless EM7305 */ | 159 | {DEVICE_SWI(0x1199, 0x9063)}, /* Sierra Wireless EM7305 */ |
| 159 | {DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx */ | 160 | {DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx */ |
| 160 | {DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx */ | 161 | {DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx */ |
| @@ -480,21 +480,6 @@ static void qt2_process_status(struct usb_serial_port *port, unsigned char *ch) · 479 unmodified lines | |||
| 480 | } | 480 | } |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | /* not needed, kept to document functionality */ | ||
| 484 | static void qt2_process_xmit_empty(struct usb_serial_port *port, | ||
| 485 | unsigned char *ch) | ||
| 486 | { | ||
| 487 | int bytes_written; | ||
| 488 | |||
| 489 | bytes_written = (int)(*ch) + (int)(*(ch + 1) << 4); | ||
| 490 | } | ||
| 491 | |||
| 492 | /* not needed, kept to document functionality */ | ||
| 493 | static void qt2_process_flush(struct usb_serial_port *port, unsigned char *ch) | ||
| 494 | { | ||
| 495 | return; | ||
| 496 | } | ||
| 497 | |||
| 498 | static void qt2_process_read_urb(struct urb *urb) | 483 | static void qt2_process_read_urb(struct urb *urb) |
| 499 | { | 484 | { |
| 500 | struct usb_serial *serial; | 485 | struct usb_serial *serial; |
| @@ -540,7 +525,7 @@ static void qt2_process_read_urb(struct urb *urb) · 39 unmodified lines | |||
| 540 | __func__); | 525 | __func__); |
| 541 | break; | 526 | break; |
| 542 | } | 527 | } |
| 543 | qt2_process_xmit_empty(port, ch + 3); | 528 | /* bytes_written = (ch[1] << 4) + ch[0]; */ |
| 544 | i += 4; | 529 | i += 4; |
| 545 | escapeflag = true; | 530 | escapeflag = true; |
| 546 | break; | 531 | break; |
| @@ -569,7 +554,6 @@ static void qt2_process_read_urb(struct urb *urb) · 22 unmodified lines | |||
| 569 | break; | 554 | break; |
| 570 | case QT2_REC_FLUSH: | 555 | case QT2_REC_FLUSH: |
| 571 | case QT2_XMIT_FLUSH: | 556 | case QT2_XMIT_FLUSH: |
| 572 | qt2_process_flush(port, ch + 2); | ||
| 573 | i += 2; | 557 | i += 2; |
| 574 | escapeflag = true; | 558 | escapeflag = true; |
| 575 | break; | 559 | break; |
| @@ -45,10 +45,9 @@ · 44 unmodified lines | |||
| 45 | 45 | ||
| 46 | static bool nmea; | 46 | static bool nmea; |
| 47 | 47 | ||
| 48 | /* Used in interface quirks */ | 48 | struct sierra_iface_list { |
| 49 | struct sierra_iface_quirk { | 49 | const u8 *nums; /* array of interface numbers */ |
| 50 | const u32 infolen; /* number of interface numbers on the list */ | 50 | size_t count; /* number of elements in array */ |
| 51 | const u8 *ifaceinfo; /* pointer to the array holding the numbers */ | ||
| 52 | }; | 51 | }; |
| 53 | 52 | ||
| 54 | struct sierra_intf_private { | 53 | struct sierra_intf_private { |
| @@ -101,20 +100,19 @@ static int sierra_calc_num_ports(struct usb_serial *serial, · 46 unmodified lines | |||
| 101 | return num_ports; | 100 | return num_ports; |
| 102 | } | 101 | } |
| 103 | 102 | ||
| 104 | static int is_quirk(const u8 ifnum, const struct sierra_iface_quirk *quirk) | 103 | static bool is_listed(const u8 ifnum, const struct sierra_iface_list *list) |
| 105 | { | 104 | { |
| 106 | const u8 *info; | ||
| 107 | int i; | 105 | int i; |
| 108 | 106 | ||
| 109 | if (quirk) { | 107 | if (!list) |
| 110 | info = quirk->ifaceinfo; | 108 | return false; |
| 111 | 109 | ||
| 112 | for (i = 0; i < quirk->infolen; i++) { | 110 | for (i = 0; i < list->count; i++) { |
| 113 | if (info[i] == ifnum) | 111 | if (list->nums[i] == ifnum) |
| 114 | return 1; | 112 | return true; |
| 115 | } | ||
| 116 | } | 113 | } |
| 117 | return 0; | 114 | |
| 115 | return false; | ||
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | static u8 sierra_interface_num(struct usb_serial *serial) | 118 | static u8 sierra_interface_num(struct usb_serial *serial) |
| @@ -125,6 +123,7 @@ static u8 sierra_interface_num(struct usb_serial *serial) · 4 unmodified lines | |||
| 125 | static int sierra_probe(struct usb_serial *serial, | 123 | static int sierra_probe(struct usb_serial *serial, |
| 126 | const struct usb_device_id *id) | 124 | const struct usb_device_id *id) |
| 127 | { | 125 | { |
| 126 | const struct sierra_iface_list *ignore_list; | ||
| 128 | int result = 0; | 127 | int result = 0; |
| 129 | struct usb_device *udev; | 128 | struct usb_device *udev; |
| 130 | u8 ifnum; | 129 | u8 ifnum; |
| @@ -143,9 +142,10 @@ static int sierra_probe(struct usb_serial *serial, · 12 unmodified lines | |||
| 143 | usb_set_interface(udev, ifnum, 1); | 142 | usb_set_interface(udev, ifnum, 1); |
| 144 | } | 143 | } |
| 145 | 144 | ||
| 146 | if (is_quirk(ifnum, (struct sierra_iface_quirk *)id->driver_info)) { | 145 | ignore_list = (const struct sierra_iface_list *)id->driver_info; |
| 147 | dev_dbg(&serial->dev->dev, | 146 | |
| 148 | "Ignoring interface #%d\n", ifnum); | 147 | if (is_listed(ifnum, ignore_list)) { |
| 148 | dev_dbg(&serial->dev->dev, "Ignoring interface #%d\n", ifnum); | ||
| 149 | return -ENODEV; | 149 | return -ENODEV; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| @@ -154,22 +154,22 @@ static int sierra_probe(struct usb_serial *serial, · 2 unmodified lines | |||
| 154 | 154 | ||
| 155 | /* interfaces with higher memory requirements */ | 155 | /* interfaces with higher memory requirements */ |
| 156 | static const u8 hi_memory_typeA_ifaces[] = { 0, 2 }; | 156 | static const u8 hi_memory_typeA_ifaces[] = { 0, 2 }; |
| 157 | static const struct sierra_iface_quirk typeA_interface_list = { | 157 | static const struct sierra_iface_list typeA_interface_list = { |
| 158 | .infolen = ARRAY_SIZE(hi_memory_typeA_ifaces), | 158 | .nums = hi_memory_typeA_ifaces, |
| 159 | .ifaceinfo = hi_memory_typeA_ifaces, | 159 | .count = ARRAY_SIZE(hi_memory_typeA_ifaces), |
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | static const u8 hi_memory_typeB_ifaces[] = { 3, 4, 5, 6 }; | 162 | static const u8 hi_memory_typeB_ifaces[] = { 3, 4, 5, 6 }; |
| 163 | static const struct sierra_iface_quirk typeB_interface_list = { | 163 | static const struct sierra_iface_list typeB_interface_list = { |
| 164 | .infolen = ARRAY_SIZE(hi_memory_typeB_ifaces), | 164 | .nums = hi_memory_typeB_ifaces, |
| 165 | .ifaceinfo = hi_memory_typeB_ifaces, | 165 | .count = ARRAY_SIZE(hi_memory_typeB_ifaces), |
| 166 | }; | 166 | }; |
| 167 | 167 | ||
| 168 | /* 'ignorelist' of interfaces not served by this driver */ | 168 | /* 'ignorelist' of interfaces not served by this driver */ |
| 169 | static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 }; | 169 | static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 }; |
| 170 | static const struct sierra_iface_quirk direct_ip_interface_ignore = { | 170 | static const struct sierra_iface_list direct_ip_interface_ignore = { |
| 171 | .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), | 171 | .nums = direct_ip_non_serial_ifaces, |
| 172 | .ifaceinfo = direct_ip_non_serial_ifaces, | 172 | .count = ARRAY_SIZE(direct_ip_non_serial_ifaces), |
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | static const struct usb_device_id id_table[] = { | 175 | static const struct usb_device_id id_table[] = { |
| @@ -570,8 +570,7 @@ static void sierra_instat_callback(struct urb *urb) · 394 unmodified lines | |||
| 570 | urb, port, portdata); | 570 | urb, port, portdata); |
| 571 | 571 | ||
| 572 | if (status == 0) { | 572 | if (status == 0) { |
| 573 | struct usb_ctrlrequest *req_pkt = | 573 | struct usb_ctrlrequest *req_pkt = urb->transfer_buffer; |
| 574 | (struct usb_ctrlrequest *)urb->transfer_buffer; | ||
| 575 | 574 | ||
| 576 | if (!req_pkt) { | 575 | if (!req_pkt) { |
| 577 | dev_dbg(&port->dev, "%s: NULL req_pkt\n", | 576 | dev_dbg(&port->dev, "%s: NULL req_pkt\n", |
| @@ -860,7 +859,7 @@ static int sierra_port_probe(struct usb_serial_port *port) · 282 unmodified lines | |||
| 860 | { | 859 | { |
| 861 | struct usb_serial *serial = port->serial; | 860 | struct usb_serial *serial = port->serial; |
| 862 | struct sierra_port_private *portdata; | 861 | struct sierra_port_private *portdata; |
| 863 | const struct sierra_iface_quirk *himemoryp; | 862 | const struct sierra_iface_list *himemory_list; |
| 864 | u8 ifnum; | 863 | u8 ifnum; |
| 865 | 864 | ||
| 866 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | 865 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); |
| @@ -879,16 +878,16 @@ static int sierra_port_probe(struct usb_serial_port *port) · 12 unmodified lines | |||
| 879 | if (serial->num_ports == 1) { | 878 | if (serial->num_ports == 1) { |
| 880 | /* Get interface number for composite device */ | 879 | /* Get interface number for composite device */ |
| 881 | ifnum = sierra_interface_num(serial); | 880 | ifnum = sierra_interface_num(serial); |
| 882 | himemoryp = &typeB_interface_list; | 881 | himemory_list = &typeB_interface_list; |
| 883 | } else { | 882 | } else { |
| 884 | /* This is really the usb-serial port number of the interface | 883 | /* This is really the usb-serial port number of the interface |
| 885 | * rather than the interface number. | 884 | * rather than the interface number. |
| 886 | */ | 885 | */ |
| 887 | ifnum = port->port_number; | 886 | ifnum = port->port_number; |
| 888 | himemoryp = &typeA_interface_list; | 887 | himemory_list = &typeA_interface_list; |
| 889 | } | 888 | } |
| 890 | 889 | ||
| 891 | if (is_quirk(ifnum, himemoryp)) { | 890 | if (is_listed(ifnum, himemory_list)) { |
| 892 | portdata->num_out_urbs = N_OUT_URB_HM; | 891 | portdata->num_out_urbs = N_OUT_URB_HM; |
| 893 | portdata->num_in_urbs = N_IN_URB_HM; | 892 | portdata->num_in_urbs = N_IN_URB_HM; |
| 894 | } | 893 | } |
| @@ -495,7 +495,7 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, · 494 unmodified lines | |||
| 495 | static void ssu100_process_read_urb(struct urb *urb) | 495 | static void ssu100_process_read_urb(struct urb *urb) |
| 496 | { | 496 | { |
| 497 | struct usb_serial_port *port = urb->context; | 497 | struct usb_serial_port *port = urb->context; |
| 498 | char *packet = (char *)urb->transfer_buffer; | 498 | char *packet = urb->transfer_buffer; |
| 499 | char flag = TTY_NORMAL; | 499 | char flag = TTY_NORMAL; |
| 500 | u32 len = urb->actual_length; | 500 | u32 len = urb->actual_length; |
| 501 | int i; | 501 | int i; |
| @@ -517,13 +517,14 @@ static void ssu100_process_read_urb(struct urb *urb) · 15 unmodified lines | |||
| 517 | if (!len) | 517 | if (!len) |
| 518 | return; /* status only */ | 518 | return; /* status only */ |
| 519 | 519 | ||
| 520 | if (port->port.console && port->sysrq) { | 520 | if (port->sysrq) { |
| 521 | for (i = 0; i < len; i++, ch++) { | 521 | for (i = 0; i < len; i++, ch++) { |
| 522 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 522 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
| 523 | tty_insert_flip_char(&port->port, *ch, flag); | 523 | tty_insert_flip_char(&port->port, *ch, flag); |
| 524 | } | 524 | } |
| 525 | } else | 525 | } else { |
| 526 | tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len); | 526 | tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len); |
| 527 | } | ||
| 527 | 528 | ||
| 528 | tty_flip_buffer_push(&port->port); | 529 | tty_flip_buffer_push(&port->port); |
| 529 | } | 530 | } |
| @@ -332,7 +332,7 @@ static void upd78f0730_set_termios(struct tty_struct *tty, · 331 unmodified lines | |||
| 332 | tty->termios.c_cflag &= ~CSIZE; | 332 | tty->termios.c_cflag &= ~CSIZE; |
| 333 | tty->termios.c_cflag |= CS8; | 333 | tty->termios.c_cflag |= CS8; |
| 334 | dev_warn(dev, "data size is not supported, using 8 bits\n"); | 334 | dev_warn(dev, "data size is not supported, using 8 bits\n"); |
| 335 | /* fall through */ | 335 | fallthrough; |
| 336 | case CS8: | 336 | case CS8: |
| 337 | request.params |= UPD78F0730_DATA_SIZE_8_BITS; | 337 | request.params |= UPD78F0730_DATA_SIZE_8_BITS; |
| 338 | dev_dbg(dev, "%s - 8 data bits\n", __func__); | 338 | dev_dbg(dev, "%s - 8 data bits\n", __func__); |
| @@ -17,7 +17,6 @@ · 16 unmodified lines | |||
| 17 | #include <linux/kref.h> | 17 | #include <linux/kref.h> |
| 18 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
| 19 | #include <linux/serial.h> | 19 | #include <linux/serial.h> |
| 20 | #include <linux/sysrq.h> | ||
| 21 | #include <linux/kfifo.h> | 20 | #include <linux/kfifo.h> |
| 22 | 21 | ||
| 23 | /* The maximum number of ports one device can grab at once */ | 22 | /* The maximum number of ports one device can grab at once */ |
| @@ -316,19 +315,19 @@ struct usb_serial_driver { · 292 unmodified lines | |||
| 316 | #define to_usb_serial_driver(d) \ | 315 | #define to_usb_serial_driver(d) \ |
| 317 | container_of(d, struct usb_serial_driver, driver) | 316 | container_of(d, struct usb_serial_driver, driver) |
| 318 | 317 | ||
| 319 | extern int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[], | 318 | int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[], |
| 320 | const char *name, const struct usb_device_id *id_table); | 319 | const char *name, const struct usb_device_id *id_table); |
| 321 | extern void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[]); | 320 | void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[]); |
| 322 | extern void usb_serial_port_softint(struct usb_serial_port *port); | 321 | void usb_serial_port_softint(struct usb_serial_port *port); |
| 323 | 322 | ||
| 324 | extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t message); | 323 | int usb_serial_suspend(struct usb_interface *intf, pm_message_t message); |
| 325 | extern int usb_serial_resume(struct usb_interface *intf); | 324 | int usb_serial_resume(struct usb_interface *intf); |
| 326 | 325 | ||
| 327 | /* USB Serial console functions */ | 326 | /* USB Serial console functions */ |
| 328 | #ifdef CONFIG_USB_SERIAL_CONSOLE | 327 | #ifdef CONFIG_USB_SERIAL_CONSOLE |
| 329 | extern void usb_serial_console_init(int minor); | 328 | void usb_serial_console_init(int minor); |
| 330 | extern void usb_serial_console_exit(void); | 329 | void usb_serial_console_exit(void); |
| 331 | extern void usb_serial_console_disconnect(struct usb_serial *serial); | 330 | void usb_serial_console_disconnect(struct usb_serial *serial); |
| 332 | #else | 331 | #else |
| 333 | static inline void usb_serial_console_init(int minor) { } | 332 | static inline void usb_serial_console_init(int minor) { } |
| 334 | static inline void usb_serial_console_exit(void) { } | 333 | static inline void usb_serial_console_exit(void) { } |
| @@ -336,45 +335,49 @@ static inline void usb_serial_console_disconnect(struct usb_serial *serial) {} · 1 unmodified line | |||
| 336 | #endif | 335 | #endif |
| 337 | 336 | ||
| 338 | /* Functions needed by other parts of the usbserial core */ | 337 | /* Functions needed by other parts of the usbserial core */ |
| 339 | extern struct usb_serial_port *usb_serial_port_get_by_minor(unsigned int minor); | 338 | struct usb_serial_port *usb_serial_port_get_by_minor(unsigned int minor); |
| 340 | extern void usb_serial_put(struct usb_serial *serial); | 339 | void usb_serial_put(struct usb_serial *serial); |
| 341 | extern int usb_serial_generic_open(struct tty_struct *tty, | 340 | int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port); |
| 342 | struct usb_serial_port *port); | 341 | int usb_serial_generic_write_start(struct usb_serial_port *port, gfp_t mem_flags); |
| 343 | extern int usb_serial_generic_write_start(struct usb_serial_port *port, | 342 | int usb_serial_generic_write(struct tty_struct *tty, struct usb_serial_port *port, |
| 344 | gfp_t mem_flags); | 343 | const unsigned char *buf, int count); |
| 345 | extern int usb_serial_generic_write(struct tty_struct *tty, | 344 | void usb_serial_generic_close(struct usb_serial_port *port); |
| 346 | struct usb_serial_port *port, const unsigned char *buf, int count); | 345 | int usb_serial_generic_resume(struct usb_serial *serial); |
| 347 | extern void usb_serial_generic_close(struct usb_serial_port *port); | 346 | int usb_serial_generic_write_room(struct tty_struct *tty); |
| 348 | extern int usb_serial_generic_resume(struct usb_serial *serial); | 347 | int usb_serial_generic_chars_in_buffer(struct tty_struct *tty); |
| 349 | extern int usb_serial_generic_write_room(struct tty_struct *tty); | 348 | void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout); |
| 350 | extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty); | 349 | void usb_serial_generic_read_bulk_callback(struct urb *urb); |
| 351 | extern void usb_serial_generic_wait_until_sent(struct tty_struct *tty, | 350 | void usb_serial_generic_write_bulk_callback(struct urb *urb); |
| 352 | long timeout); | 351 | void usb_serial_generic_throttle(struct tty_struct *tty); |
| 353 | extern void usb_serial_generic_read_bulk_callback(struct urb *urb); | 352 | void usb_serial_generic_unthrottle(struct tty_struct *tty); |
| 354 | extern void usb_serial_generic_write_bulk_callback(struct urb *urb); | 353 | int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg); |
| 355 | extern void usb_serial_generic_throttle(struct tty_struct *tty); | 354 | int usb_serial_generic_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount); |
| 356 | extern void usb_serial_generic_unthrottle(struct tty_struct *tty); | 355 | int usb_serial_generic_register(void); |
| 357 | extern int usb_serial_generic_tiocmiwait(struct tty_struct *tty, | 356 | void usb_serial_generic_deregister(void); |
| 358 | unsigned long arg); | 357 | int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, gfp_t mem_flags); |
| 359 | extern int usb_serial_generic_get_icount(struct tty_struct *tty, | 358 | void usb_serial_generic_process_read_urb(struct urb *urb); |
| 360 | struct serial_icounter_struct *icount); | 359 | int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, void *dest, size_t size); |
| 361 | extern int usb_serial_generic_register(void); | 360 | |
| 362 | extern void usb_serial_generic_deregister(void); | 361 | #if defined(CONFIG_USB_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
| 363 | extern int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, | 362 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch); |
| 364 | gfp_t mem_flags); | 363 | int usb_serial_handle_break(struct usb_serial_port *port); |
| 365 | extern void usb_serial_generic_process_read_urb(struct urb *urb); | 364 | #else |
| 366 | extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, | 365 | static inline int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
| 367 | void *dest, size_t size); | 366 | { |
| 368 | extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port, | 367 | return 0; |
| 369 | unsigned int ch); | 368 | } |
| 370 | extern int usb_serial_handle_break(struct usb_serial_port *port); | 369 | static inline int usb_serial_handle_break(struct usb_serial_port *port) |
| 371 | extern void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, | 370 | { |
| 372 | struct tty_struct *tty, | 371 | return 0; |
| 373 | unsigned int status); | 372 | } |
| 373 | #endif | ||
| 374 | |||
| 375 | void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, | ||
| 376 | struct tty_struct *tty, unsigned int status); | ||
| 374 | 377 | ||
| 375 | 378 | ||
| 376 | extern int usb_serial_bus_register(struct usb_serial_driver *device); | 379 | int usb_serial_bus_register(struct usb_serial_driver *device); |
| 377 | extern void usb_serial_bus_deregister(struct usb_serial_driver *device); | 380 | void usb_serial_bus_deregister(struct usb_serial_driver *device); |
| 378 | 381 | ||
| 379 | extern struct bus_type usb_serial_bus_type; | 382 | extern struct bus_type usb_serial_bus_type; |
| 380 | extern struct tty_driver *usb_serial_tty_driver; | 383 | extern struct tty_driver *usb_serial_tty_driver; |