diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-05 12:13:10 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-05 12:13:10 -0700 | 
| commit | ecfd7940b8641da6e41ca94eba36876dc2ba827b (patch) | |
| tree | b25d042366a3b6f165abb4c9fba9b9faf1ba33f6 /drivers/usb/serial/ftdi_sio.c | |
| parent | dd27111e32572fdd3aaae98ba2817df6d202357a (diff) | |
| parent | e3ee0e740c3887d2293e8d54a8707218d70d86ca (diff) | |
Merge tag 'usb-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/Thunderbolt updates from Greg KH:
 "Here is the large set of USB and Thunderbolt patches for 5.9-rc1.
  Nothing really magic/major in here, just lots of little changes and
  updates:
   - clean up language usages in USB core and some drivers
   - Thunderbolt driver updates and additions
   - USB Gadget driver updates
   - dwc3 driver updates (like always...)
   - build with "W=1" warning fixups
   - mtu3 driver updates
   - usb-serial driver updates and device ids
   - typec additions and updates for new hardware
   - xhci debug code updates for future platforms
   - cdns3 driver updates
   - lots of other minor driver updates and fixes and cleanups
  All of these have been in linux-next for a while with no reported
  issues"
* tag 'usb-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (330 commits)
  usb: common: usb-conn-gpio: Register charger
  usb: mtu3: simplify mtu3_req_complete()
  usb: mtu3: clear dual mode of u3port when disable device
  usb: mtu3: use MTU3_EP_WEDGE flag
  usb: mtu3: remove useless member @busy in mtu3_ep struct
  usb: mtu3: remove repeated error log
  usb: mtu3: add ->udc_set_speed()
  usb: mtu3: introduce a funtion to check maximum speed
  usb: mtu3: clear interrupts status when disable interrupts
  usb: mtu3: reinitialize CSR registers
  usb: mtu3: fix macro for maximum number of packets
  usb: mtu3: remove unnecessary pointer checks
  usb: xhci: Fix ASMedia ASM1142 DMA addressing
  usb: xhci: define IDs for various ASMedia host controllers
  usb: musb: convert to devm_platform_ioremap_resource_byname
  usb: gadget: tegra-xudc: convert to devm_platform_ioremap_resource_byname
  usb: gadget: r8a66597: convert to devm_platform_ioremap_resource_byname
  usb: dwc3: convert to devm_platform_ioremap_resource_byname
  usb: cdns3: convert to devm_platform_ioremap_resource_byname
  usb: phy: am335x: convert to devm_platform_ioremap_resource_byname
  ...
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
| -rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 59 | 
1 files changed, 34 insertions, 25 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 9ad44a96dfe3..871cdccf3a5f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -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;  | 
