Commit c5fd2c5b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-5.5-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB driver fixes from Greg KH:
 "Here are some small USB driver and core fixes for 5.5-rc7

  There's one fix for hub wakeup issues and a number of small usb-serial
  driver fixes and device id updates.

  The hub fix has been in linux-next for a while with no reported
  issues, and the usb-serial ones have all passed 0-day with no
  problems"

* tag 'usb-5.5-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: serial: quatech2: handle unbound ports
  USB: serial: keyspan: handle unbound ports
  USB: serial: io_edgeport: add missing active-port sanity check
  USB: serial: io_edgeport: handle unbound ports on URB completion
  USB: serial: ch341: handle unbound port at reset_resume
  USB: serial: suppress driver bind attributes
  USB: serial: option: add support for Quectel RM500Q in QDL mode
  usb: core: hub: Improved device recognition on remote wakeup
  USB: serial: opticon: fix control-message timeouts
  USB: serial: option: Add support for Quectel RM500Q
  USB: serial: simple: Add Motorola Solutions TETRA MTP3xxx and MTP85xx
parents 25e73aad 453495d4
...@@ -1192,6 +1192,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) ...@@ -1192,6 +1192,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
* PORT_OVER_CURRENT is not. So check for any of them. * PORT_OVER_CURRENT is not. So check for any of them.
*/ */
if (udev || (portstatus & USB_PORT_STAT_CONNECTION) || if (udev || (portstatus & USB_PORT_STAT_CONNECTION) ||
(portchange & USB_PORT_STAT_C_CONNECTION) ||
(portstatus & USB_PORT_STAT_OVERCURRENT) || (portstatus & USB_PORT_STAT_OVERCURRENT) ||
(portchange & USB_PORT_STAT_C_OVERCURRENT)) (portchange & USB_PORT_STAT_C_OVERCURRENT))
set_bit(port1, hub->change_bits); set_bit(port1, hub->change_bits);
......
...@@ -642,9 +642,13 @@ static int ch341_tiocmget(struct tty_struct *tty) ...@@ -642,9 +642,13 @@ static int ch341_tiocmget(struct tty_struct *tty)
static int ch341_reset_resume(struct usb_serial *serial) static int ch341_reset_resume(struct usb_serial *serial)
{ {
struct usb_serial_port *port = serial->port[0]; struct usb_serial_port *port = serial->port[0];
struct ch341_private *priv = usb_get_serial_port_data(port); struct ch341_private *priv;
int ret; int ret;
priv = usb_get_serial_port_data(port);
if (!priv)
return 0;
/* reconfigure ch341 serial port after bus-reset */ /* reconfigure ch341 serial port after bus-reset */
ch341_configure(serial->dev, priv); ch341_configure(serial->dev, priv);
......
...@@ -716,7 +716,7 @@ static void edge_interrupt_callback(struct urb *urb) ...@@ -716,7 +716,7 @@ static void edge_interrupt_callback(struct urb *urb)
if (txCredits) { if (txCredits) {
port = edge_serial->serial->port[portNumber]; port = edge_serial->serial->port[portNumber];
edge_port = usb_get_serial_port_data(port); edge_port = usb_get_serial_port_data(port);
if (edge_port->open) { if (edge_port && edge_port->open) {
spin_lock_irqsave(&edge_port->ep_lock, spin_lock_irqsave(&edge_port->ep_lock,
flags); flags);
edge_port->txCredits += txCredits; edge_port->txCredits += txCredits;
...@@ -1725,7 +1725,8 @@ static void edge_break(struct tty_struct *tty, int break_state) ...@@ -1725,7 +1725,8 @@ static void edge_break(struct tty_struct *tty, int break_state)
static void process_rcvd_data(struct edgeport_serial *edge_serial, static void process_rcvd_data(struct edgeport_serial *edge_serial,
unsigned char *buffer, __u16 bufferLength) unsigned char *buffer, __u16 bufferLength)
{ {
struct device *dev = &edge_serial->serial->dev->dev; struct usb_serial *serial = edge_serial->serial;
struct device *dev = &serial->dev->dev;
struct usb_serial_port *port; struct usb_serial_port *port;
struct edgeport_port *edge_port; struct edgeport_port *edge_port;
__u16 lastBufferLength; __u16 lastBufferLength;
...@@ -1821,11 +1822,10 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, ...@@ -1821,11 +1822,10 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
/* spit this data back into the tty driver if this /* spit this data back into the tty driver if this
port is open */ port is open */
if (rxLen) { if (rxLen && edge_serial->rxPort < serial->num_ports) {
port = edge_serial->serial->port[ port = serial->port[edge_serial->rxPort];
edge_serial->rxPort];
edge_port = usb_get_serial_port_data(port); edge_port = usb_get_serial_port_data(port);
if (edge_port->open) { if (edge_port && edge_port->open) {
dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n", dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n",
__func__, rxLen, __func__, rxLen,
edge_serial->rxPort); edge_serial->rxPort);
...@@ -1833,8 +1833,8 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, ...@@ -1833,8 +1833,8 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
rxLen); rxLen);
edge_port->port->icount.rx += rxLen; edge_port->port->icount.rx += rxLen;
} }
buffer += rxLen;
} }
buffer += rxLen;
break; break;
case EXPECT_HDR3: /* Expect 3rd byte of status header */ case EXPECT_HDR3: /* Expect 3rd byte of status header */
...@@ -1869,6 +1869,8 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, ...@@ -1869,6 +1869,8 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
__u8 code = edge_serial->rxStatusCode; __u8 code = edge_serial->rxStatusCode;
/* switch the port pointer to the one being currently talked about */ /* switch the port pointer to the one being currently talked about */
if (edge_serial->rxPort >= edge_serial->serial->num_ports)
return;
port = edge_serial->serial->port[edge_serial->rxPort]; port = edge_serial->serial->port[edge_serial->rxPort];
edge_port = usb_get_serial_port_data(port); edge_port = usb_get_serial_port_data(port);
if (edge_port == NULL) { if (edge_port == NULL) {
......
...@@ -1058,6 +1058,8 @@ static void usa49_glocont_callback(struct urb *urb) ...@@ -1058,6 +1058,8 @@ static void usa49_glocont_callback(struct urb *urb)
for (i = 0; i < serial->num_ports; ++i) { for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i]; port = serial->port[i];
p_priv = usb_get_serial_port_data(port); p_priv = usb_get_serial_port_data(port);
if (!p_priv)
continue;
if (p_priv->resend_cont) { if (p_priv->resend_cont) {
dev_dbg(&port->dev, "%s - sending setup\n", __func__); dev_dbg(&port->dev, "%s - sending setup\n", __func__);
...@@ -1459,6 +1461,8 @@ static void usa67_glocont_callback(struct urb *urb) ...@@ -1459,6 +1461,8 @@ static void usa67_glocont_callback(struct urb *urb)
for (i = 0; i < serial->num_ports; ++i) { for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i]; port = serial->port[i];
p_priv = usb_get_serial_port_data(port); p_priv = usb_get_serial_port_data(port);
if (!p_priv)
continue;
if (p_priv->resend_cont) { if (p_priv->resend_cont) {
dev_dbg(&port->dev, "%s - sending setup\n", __func__); dev_dbg(&port->dev, "%s - sending setup\n", __func__);
......
...@@ -113,7 +113,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, ...@@ -113,7 +113,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype,
retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
requesttype, requesttype,
USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
0, 0, buffer, 1, 0); 0, 0, buffer, 1, USB_CTRL_SET_TIMEOUT);
kfree(buffer); kfree(buffer);
if (retval < 0) if (retval < 0)
......
...@@ -248,6 +248,7 @@ static void option_instat_callback(struct urb *urb); ...@@ -248,6 +248,7 @@ static void option_instat_callback(struct urb *urb);
#define QUECTEL_PRODUCT_BG96 0x0296 #define QUECTEL_PRODUCT_BG96 0x0296
#define QUECTEL_PRODUCT_EP06 0x0306 #define QUECTEL_PRODUCT_EP06 0x0306
#define QUECTEL_PRODUCT_EM12 0x0512 #define QUECTEL_PRODUCT_EM12 0x0512
#define QUECTEL_PRODUCT_RM500Q 0x0800
#define CMOTECH_VENDOR_ID 0x16d8 #define CMOTECH_VENDOR_ID 0x16d8
#define CMOTECH_PRODUCT_6001 0x6001 #define CMOTECH_PRODUCT_6001 0x6001
...@@ -1104,6 +1105,11 @@ static const struct usb_device_id option_ids[] = { ...@@ -1104,6 +1105,11 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
.driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
.driver_info = ZLP },
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
......
...@@ -841,7 +841,10 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch) ...@@ -841,7 +841,10 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch)
u8 newMSR = (u8) *ch; u8 newMSR = (u8) *ch;
unsigned long flags; unsigned long flags;
/* May be called from qt2_process_read_urb() for an unbound port. */
port_priv = usb_get_serial_port_data(port); port_priv = usb_get_serial_port_data(port);
if (!port_priv)
return;
spin_lock_irqsave(&port_priv->lock, flags); spin_lock_irqsave(&port_priv->lock, flags);
port_priv->shadowMSR = newMSR; port_priv->shadowMSR = newMSR;
...@@ -869,7 +872,10 @@ static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch) ...@@ -869,7 +872,10 @@ static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch)
unsigned long flags; unsigned long flags;
u8 newLSR = (u8) *ch; u8 newLSR = (u8) *ch;
/* May be called from qt2_process_read_urb() for an unbound port. */
port_priv = usb_get_serial_port_data(port); port_priv = usb_get_serial_port_data(port);
if (!port_priv)
return;
if (newLSR & UART_LSR_BI) if (newLSR & UART_LSR_BI)
newLSR &= (u8) (UART_LSR_OE | UART_LSR_BI); newLSR &= (u8) (UART_LSR_OE | UART_LSR_BI);
......
...@@ -86,6 +86,8 @@ DEVICE(moto_modem, MOTO_IDS); ...@@ -86,6 +86,8 @@ DEVICE(moto_modem, MOTO_IDS);
#define MOTOROLA_TETRA_IDS() \ #define MOTOROLA_TETRA_IDS() \
{ USB_DEVICE(0x0cad, 0x9011) }, /* Motorola Solutions TETRA PEI */ \ { USB_DEVICE(0x0cad, 0x9011) }, /* Motorola Solutions TETRA PEI */ \
{ USB_DEVICE(0x0cad, 0x9012) }, /* MTP6550 */ \ { USB_DEVICE(0x0cad, 0x9012) }, /* MTP6550 */ \
{ USB_DEVICE(0x0cad, 0x9013) }, /* MTP3xxx */ \
{ USB_DEVICE(0x0cad, 0x9015) }, /* MTP85xx */ \
{ USB_DEVICE(0x0cad, 0x9016) } /* TPG2200 */ { USB_DEVICE(0x0cad, 0x9016) } /* TPG2200 */
DEVICE(motorola_tetra, MOTOROLA_TETRA_IDS); DEVICE(motorola_tetra, MOTOROLA_TETRA_IDS);
......
...@@ -1317,6 +1317,9 @@ static int usb_serial_register(struct usb_serial_driver *driver) ...@@ -1317,6 +1317,9 @@ static int usb_serial_register(struct usb_serial_driver *driver)
return -EINVAL; return -EINVAL;
} }
/* Prevent individual ports from being unbound. */
driver->driver.suppress_bind_attrs = true;
usb_serial_operations_init(driver); usb_serial_operations_init(driver);
/* Add this device to our list of devices */ /* Add this device to our list of devices */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment