Browse Source

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

Johan writes:

USB-serial updates for v4.15-rc1

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

 - three fixes for longstanding issues in garmin_gps and metro-usb which
   could lead to NULL-pointer dereferences and memory leaks

 - a workaround for broken f81534 firmware-handling of overruns

 - f81534 break support, and

 - conversion to timer_setup()

Included are also various clean ups and a new qcserial device id.

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

Signed-off-by: Johan Hovold <johan@kernel.org>
Greg Kroah-Hartman 7 years ago
parent
commit
29ce32ecca

+ 84 - 6
drivers/usb/serial/f81534.c

@@ -39,9 +39,11 @@
 #define F81534_UART_OFFSET		0x10
 #define F81534_UART_OFFSET		0x10
 #define F81534_DIVISOR_LSB_REG		(0x00 + F81534_UART_BASE_ADDRESS)
 #define F81534_DIVISOR_LSB_REG		(0x00 + F81534_UART_BASE_ADDRESS)
 #define F81534_DIVISOR_MSB_REG		(0x01 + F81534_UART_BASE_ADDRESS)
 #define F81534_DIVISOR_MSB_REG		(0x01 + F81534_UART_BASE_ADDRESS)
+#define F81534_INTERRUPT_ENABLE_REG	(0x01 + F81534_UART_BASE_ADDRESS)
 #define F81534_FIFO_CONTROL_REG		(0x02 + F81534_UART_BASE_ADDRESS)
 #define F81534_FIFO_CONTROL_REG		(0x02 + F81534_UART_BASE_ADDRESS)
 #define F81534_LINE_CONTROL_REG		(0x03 + F81534_UART_BASE_ADDRESS)
 #define F81534_LINE_CONTROL_REG		(0x03 + F81534_UART_BASE_ADDRESS)
 #define F81534_MODEM_CONTROL_REG	(0x04 + F81534_UART_BASE_ADDRESS)
 #define F81534_MODEM_CONTROL_REG	(0x04 + F81534_UART_BASE_ADDRESS)
+#define F81534_LINE_STATUS_REG		(0x05 + F81534_UART_BASE_ADDRESS)
 #define F81534_MODEM_STATUS_REG		(0x06 + F81534_UART_BASE_ADDRESS)
 #define F81534_MODEM_STATUS_REG		(0x06 + F81534_UART_BASE_ADDRESS)
 #define F81534_CONFIG1_REG		(0x09 + F81534_UART_BASE_ADDRESS)
 #define F81534_CONFIG1_REG		(0x09 + F81534_UART_BASE_ADDRESS)
 
 
@@ -126,9 +128,13 @@ struct f81534_serial_private {
 
 
 struct f81534_port_private {
 struct f81534_port_private {
 	struct mutex mcr_mutex;
 	struct mutex mcr_mutex;
+	struct mutex lcr_mutex;
+	struct work_struct lsr_work;
+	struct usb_serial_port *port;
 	unsigned long tx_empty;
 	unsigned long tx_empty;
 	spinlock_t msr_lock;
 	spinlock_t msr_lock;
 	u8 shadow_mcr;
 	u8 shadow_mcr;
+	u8 shadow_lcr;
 	u8 shadow_msr;
 	u8 shadow_msr;
 	u8 phy_num;
 	u8 phy_num;
 };
 };
@@ -461,6 +467,7 @@ static u32 f81534_calc_baud_divisor(u32 baudrate, u32 clockrate)
 static int f81534_set_port_config(struct usb_serial_port *port, u32 baudrate,
 static int f81534_set_port_config(struct usb_serial_port *port, u32 baudrate,
 					u8 lcr)
 					u8 lcr)
 {
 {
+	struct f81534_port_private *port_priv = usb_get_serial_port_data(port);
 	u32 divisor;
 	u32 divisor;
 	int status;
 	int status;
 	u8 value;
 	u8 value;
@@ -489,35 +496,65 @@ static int f81534_set_port_config(struct usb_serial_port *port, u32 baudrate,
 	}
 	}
 
 
 	divisor = f81534_calc_baud_divisor(baudrate, F81534_MAX_BAUDRATE);
 	divisor = f81534_calc_baud_divisor(baudrate, F81534_MAX_BAUDRATE);
+
+	mutex_lock(&port_priv->lcr_mutex);
+
 	value = UART_LCR_DLAB;
 	value = UART_LCR_DLAB;
 	status = f81534_set_port_register(port, F81534_LINE_CONTROL_REG,
 	status = f81534_set_port_register(port, F81534_LINE_CONTROL_REG,
 						value);
 						value);
 	if (status) {
 	if (status) {
 		dev_err(&port->dev, "%s: set LCR failed\n", __func__);
 		dev_err(&port->dev, "%s: set LCR failed\n", __func__);
-		return status;
+		goto out_unlock;
 	}
 	}
 
 
 	value = divisor & 0xff;
 	value = divisor & 0xff;
 	status = f81534_set_port_register(port, F81534_DIVISOR_LSB_REG, value);
 	status = f81534_set_port_register(port, F81534_DIVISOR_LSB_REG, value);
 	if (status) {
 	if (status) {
 		dev_err(&port->dev, "%s: set DLAB LSB failed\n", __func__);
 		dev_err(&port->dev, "%s: set DLAB LSB failed\n", __func__);
-		return status;
+		goto out_unlock;
 	}
 	}
 
 
 	value = (divisor >> 8) & 0xff;
 	value = (divisor >> 8) & 0xff;
 	status = f81534_set_port_register(port, F81534_DIVISOR_MSB_REG, value);
 	status = f81534_set_port_register(port, F81534_DIVISOR_MSB_REG, value);
 	if (status) {
 	if (status) {
 		dev_err(&port->dev, "%s: set DLAB MSB failed\n", __func__);
 		dev_err(&port->dev, "%s: set DLAB MSB failed\n", __func__);
-		return status;
+		goto out_unlock;
 	}
 	}
 
 
-	status = f81534_set_port_register(port, F81534_LINE_CONTROL_REG, lcr);
+	value = lcr | (port_priv->shadow_lcr & UART_LCR_SBC);
+	status = f81534_set_port_register(port, F81534_LINE_CONTROL_REG,
+						value);
 	if (status) {
 	if (status) {
 		dev_err(&port->dev, "%s: set LCR failed\n", __func__);
 		dev_err(&port->dev, "%s: set LCR failed\n", __func__);
-		return status;
+		goto out_unlock;
 	}
 	}
 
 
-	return 0;
+	port_priv->shadow_lcr = value;
+out_unlock:
+	mutex_unlock(&port_priv->lcr_mutex);
+
+	return status;
+}
+
+static void f81534_break_ctl(struct tty_struct *tty, int break_state)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct f81534_port_private *port_priv = usb_get_serial_port_data(port);
+	int status;
+
+	mutex_lock(&port_priv->lcr_mutex);
+
+	if (break_state)
+		port_priv->shadow_lcr |= UART_LCR_SBC;
+	else
+		port_priv->shadow_lcr &= ~UART_LCR_SBC;
+
+	status = f81534_set_port_register(port, F81534_LINE_CONTROL_REG,
+					port_priv->shadow_lcr);
+	if (status)
+		dev_err(&port->dev, "set break failed: %d\n", status);
+
+	mutex_unlock(&port_priv->lcr_mutex);
 }
 }
 
 
 static int f81534_update_mctrl(struct usb_serial_port *port, unsigned int set,
 static int f81534_update_mctrl(struct usb_serial_port *port, unsigned int set,
@@ -1015,6 +1052,8 @@ static void f81534_process_per_serial_block(struct usb_serial_port *port,
 				tty_insert_flip_char(&port->port, 0,
 				tty_insert_flip_char(&port->port, 0,
 						TTY_OVERRUN);
 						TTY_OVERRUN);
 			}
 			}
+
+			schedule_work(&port_priv->lsr_work);
 		}
 		}
 
 
 		if (port->port.console && port->sysrq) {
 		if (port->port.console && port->sysrq) {
@@ -1162,6 +1201,21 @@ static int f81534_attach(struct usb_serial *serial)
 	return 0;
 	return 0;
 }
 }
 
 
+static void f81534_lsr_worker(struct work_struct *work)
+{
+	struct f81534_port_private *port_priv;
+	struct usb_serial_port *port;
+	int status;
+	u8 tmp;
+
+	port_priv = container_of(work, struct f81534_port_private, lsr_work);
+	port = port_priv->port;
+
+	status = f81534_get_port_register(port, F81534_LINE_STATUS_REG, &tmp);
+	if (status)
+		dev_warn(&port->dev, "read LSR failed: %d\n", status);
+}
+
 static int f81534_port_probe(struct usb_serial_port *port)
 static int f81534_port_probe(struct usb_serial_port *port)
 {
 {
 	struct f81534_port_private *port_priv;
 	struct f81534_port_private *port_priv;
@@ -1173,6 +1227,8 @@ static int f81534_port_probe(struct usb_serial_port *port)
 
 
 	spin_lock_init(&port_priv->msr_lock);
 	spin_lock_init(&port_priv->msr_lock);
 	mutex_init(&port_priv->mcr_mutex);
 	mutex_init(&port_priv->mcr_mutex);
+	mutex_init(&port_priv->lcr_mutex);
+	INIT_WORK(&port_priv->lsr_work, f81534_lsr_worker);
 
 
 	/* Assign logic-to-phy mapping */
 	/* Assign logic-to-phy mapping */
 	ret = f81534_logic_to_phy_port(port->serial, port);
 	ret = f81534_logic_to_phy_port(port->serial, port);
@@ -1180,10 +1236,30 @@ static int f81534_port_probe(struct usb_serial_port *port)
 		return ret;
 		return ret;
 
 
 	port_priv->phy_num = ret;
 	port_priv->phy_num = ret;
+	port_priv->port = port;
 	usb_set_serial_port_data(port, port_priv);
 	usb_set_serial_port_data(port, port_priv);
 	dev_dbg(&port->dev, "%s: port_number: %d, phy_num: %d\n", __func__,
 	dev_dbg(&port->dev, "%s: port_number: %d, phy_num: %d\n", __func__,
 			port->port_number, port_priv->phy_num);
 			port->port_number, port_priv->phy_num);
 
 
+	/*
+	 * The F81532/534 will hang-up when enable LSR interrupt in IER and
+	 * occur data overrun. So we'll disable the LSR interrupt in probe()
+	 * and submit the LSR worker to clear LSR state when reported LSR error
+	 * bit with bulk-in data in f81534_process_per_serial_block().
+	 */
+	ret = f81534_set_port_register(port, F81534_INTERRUPT_ENABLE_REG,
+			UART_IER_RDI | UART_IER_THRI | UART_IER_MSI);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int f81534_port_remove(struct usb_serial_port *port)
+{
+	struct f81534_port_private *port_priv = usb_get_serial_port_data(port);
+
+	flush_work(&port_priv->lsr_work);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1317,6 +1393,8 @@ static struct usb_serial_driver f81534_device = {
 	.calc_num_ports =	f81534_calc_num_ports,
 	.calc_num_ports =	f81534_calc_num_ports,
 	.attach =		f81534_attach,
 	.attach =		f81534_attach,
 	.port_probe =		f81534_port_probe,
 	.port_probe =		f81534_port_probe,
+	.port_remove =		f81534_port_remove,
+	.break_ctl =		f81534_break_ctl,
 	.dtr_rts =		f81534_dtr_rts,
 	.dtr_rts =		f81534_dtr_rts,
 	.process_read_urb =	f81534_process_read_urb,
 	.process_read_urb =	f81534_process_read_urb,
 	.ioctl =		f81534_ioctl,
 	.ioctl =		f81534_ioctl,

+ 35 - 32
drivers/usb/serial/garmin_gps.c

@@ -138,6 +138,7 @@ struct garmin_data {
 	__u8   privpkt[4*6];
 	__u8   privpkt[4*6];
 	spinlock_t lock;
 	spinlock_t lock;
 	struct list_head pktlist;
 	struct list_head pktlist;
+	struct usb_anchor write_urbs;
 };
 };
 
 
 
 
@@ -875,42 +876,38 @@ static int garmin_clear(struct garmin_data *garmin_data_p)
 
 
 static int garmin_init_session(struct usb_serial_port *port)
 static int garmin_init_session(struct usb_serial_port *port)
 {
 {
-	struct usb_serial *serial = port->serial;
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
-	int status = 0;
-	int i = 0;
+	int status;
+	int i;
 
 
-	if (status == 0) {
-		usb_kill_urb(port->interrupt_in_urb);
+	usb_kill_urb(port->interrupt_in_urb);
 
 
-		dev_dbg(&serial->dev->dev, "%s - adding interrupt input\n", __func__);
-		status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
-		if (status)
-			dev_err(&serial->dev->dev,
-			  "%s - failed submitting interrupt urb, error %d\n",
-							__func__, status);
+	status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+	if (status) {
+		dev_err(&port->dev, "failed to submit interrupt urb: %d\n",
+				status);
+		return status;
 	}
 	}
 
 
 	/*
 	/*
 	 * using the initialization method from gpsbabel. See comments in
 	 * using the initialization method from gpsbabel. See comments in
 	 * gpsbabel/jeeps/gpslibusb.c gusb_reset_toggles()
 	 * gpsbabel/jeeps/gpslibusb.c gusb_reset_toggles()
 	 */
 	 */
-	if (status == 0) {
-		dev_dbg(&serial->dev->dev, "%s - starting session ...\n", __func__);
-		garmin_data_p->state = STATE_ACTIVE;
+	dev_dbg(&port->dev, "%s - starting session ...\n", __func__);
+	garmin_data_p->state = STATE_ACTIVE;
 
 
-		for (i = 0; i < 3; i++) {
-			status = garmin_write_bulk(port,
-					GARMIN_START_SESSION_REQ,
-					sizeof(GARMIN_START_SESSION_REQ), 0);
+	for (i = 0; i < 3; i++) {
+		status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
+				sizeof(GARMIN_START_SESSION_REQ), 0);
+		if (status < 0)
+			goto err_kill_urbs;
+	}
 
 
-			if (status < 0)
-				break;
-		}
+	return 0;
 
 
-		if (status > 0)
-			status = 0;
-	}
+err_kill_urbs:
+	usb_kill_anchored_urbs(&garmin_data_p->write_urbs);
+	usb_kill_urb(port->interrupt_in_urb);
 
 
 	return status;
 	return status;
 }
 }
@@ -930,7 +927,6 @@ static int garmin_open(struct tty_struct *tty, struct usb_serial_port *port)
 	spin_unlock_irqrestore(&garmin_data_p->lock, flags);
 	spin_unlock_irqrestore(&garmin_data_p->lock, flags);
 
 
 	/* shutdown any bulk reads that might be going on */
 	/* shutdown any bulk reads that might be going on */
-	usb_kill_urb(port->write_urb);
 	usb_kill_urb(port->read_urb);
 	usb_kill_urb(port->read_urb);
 
 
 	if (garmin_data_p->state == STATE_RESET)
 	if (garmin_data_p->state == STATE_RESET)
@@ -953,7 +949,7 @@ static void garmin_close(struct usb_serial_port *port)
 
 
 	/* shutdown our urbs */
 	/* shutdown our urbs */
 	usb_kill_urb(port->read_urb);
 	usb_kill_urb(port->read_urb);
-	usb_kill_urb(port->write_urb);
+	usb_kill_anchored_urbs(&garmin_data_p->write_urbs);
 
 
 	/* keep reset state so we know that we must start a new session */
 	/* keep reset state so we know that we must start a new session */
 	if (garmin_data_p->state != STATE_RESET)
 	if (garmin_data_p->state != STATE_RESET)
@@ -1037,12 +1033,14 @@ static int garmin_write_bulk(struct usb_serial_port *port,
 	}
 	}
 
 
 	/* send it down the pipe */
 	/* send it down the pipe */
+	usb_anchor_urb(urb, &garmin_data_p->write_urbs);
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status) {
 	if (status) {
 		dev_err(&port->dev,
 		dev_err(&port->dev,
 		   "%s - usb_submit_urb(write bulk) failed with status = %d\n",
 		   "%s - usb_submit_urb(write bulk) failed with status = %d\n",
 				__func__, status);
 				__func__, status);
 		count = status;
 		count = status;
+		usb_unanchor_urb(urb);
 		kfree(buffer);
 		kfree(buffer);
 	}
 	}
 
 
@@ -1370,9 +1368,9 @@ static void garmin_unthrottle(struct tty_struct *tty)
  * the tty in cases where the protocol provides no own handshaking
  * the tty in cases where the protocol provides no own handshaking
  * to initiate the transfer.
  * to initiate the transfer.
  */
  */
-static void timeout_handler(unsigned long data)
+static void timeout_handler(struct timer_list *t)
 {
 {
-	struct garmin_data *garmin_data_p = (struct garmin_data *) data;
+	struct garmin_data *garmin_data_p = from_timer(garmin_data_p, t, timer);
 
 
 	/* send the next queued packet to the tty port */
 	/* send the next queued packet to the tty port */
 	if (garmin_data_p->mode == MODE_NATIVE)
 	if (garmin_data_p->mode == MODE_NATIVE)
@@ -1391,19 +1389,23 @@ static int garmin_port_probe(struct usb_serial_port *port)
 	if (!garmin_data_p)
 	if (!garmin_data_p)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	init_timer(&garmin_data_p->timer);
+	timer_setup(&garmin_data_p->timer, timeout_handler, 0);
 	spin_lock_init(&garmin_data_p->lock);
 	spin_lock_init(&garmin_data_p->lock);
 	INIT_LIST_HEAD(&garmin_data_p->pktlist);
 	INIT_LIST_HEAD(&garmin_data_p->pktlist);
-	/* garmin_data_p->timer.expires = jiffies + session_timeout; */
-	garmin_data_p->timer.data = (unsigned long)garmin_data_p;
-	garmin_data_p->timer.function = timeout_handler;
 	garmin_data_p->port = port;
 	garmin_data_p->port = port;
 	garmin_data_p->state = 0;
 	garmin_data_p->state = 0;
 	garmin_data_p->flags = 0;
 	garmin_data_p->flags = 0;
 	garmin_data_p->count = 0;
 	garmin_data_p->count = 0;
+	init_usb_anchor(&garmin_data_p->write_urbs);
 	usb_set_serial_port_data(port, garmin_data_p);
 	usb_set_serial_port_data(port, garmin_data_p);
 
 
 	status = garmin_init_session(port);
 	status = garmin_init_session(port);
+	if (status)
+		goto err_free;
+
+	return 0;
+err_free:
+	kfree(garmin_data_p);
 
 
 	return status;
 	return status;
 }
 }
@@ -1413,6 +1415,7 @@ static int garmin_port_remove(struct usb_serial_port *port)
 {
 {
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 
 
+	usb_kill_anchored_urbs(&garmin_data_p->write_urbs);
 	usb_kill_urb(port->interrupt_in_urb);
 	usb_kill_urb(port->interrupt_in_urb);
 	del_timer_sync(&garmin_data_p->timer);
 	del_timer_sync(&garmin_data_p->timer);
 	kfree(garmin_data_p);
 	kfree(garmin_data_p);

+ 1 - 0
drivers/usb/serial/kobil_sct.c

@@ -491,6 +491,7 @@ static void kobil_set_termios(struct tty_struct *tty,
 		break;
 		break;
 	default:
 	default:
 		speed = 9600;
 		speed = 9600;
+		/* fall through */
 	case 9600:
 	case 9600:
 		urb_val = SUSBCR_SBR_9600;
 		urb_val = SUSBCR_SBR_9600;
 		break;
 		break;

+ 26 - 15
drivers/usb/serial/metro-usb.c

@@ -54,21 +54,33 @@ MODULE_DEVICE_TABLE(usb, id_table);
 #define UNI_CMD_OPEN	0x80
 #define UNI_CMD_OPEN	0x80
 #define UNI_CMD_CLOSE	0xFF
 #define UNI_CMD_CLOSE	0xFF
 
 
-static inline int metrousb_is_unidirectional_mode(struct usb_serial_port *port)
+static int metrousb_is_unidirectional_mode(struct usb_serial *serial)
 {
 {
-	__u16 product_id = le16_to_cpu(
-		port->serial->dev->descriptor.idProduct);
+	u16 product_id = le16_to_cpu(serial->dev->descriptor.idProduct);
 
 
 	return product_id == FOCUS_PRODUCT_ID_UNI;
 	return product_id == FOCUS_PRODUCT_ID_UNI;
 }
 }
 
 
+static int metrousb_calc_num_ports(struct usb_serial *serial,
+				   struct usb_serial_endpoints *epds)
+{
+	if (metrousb_is_unidirectional_mode(serial)) {
+		if (epds->num_interrupt_out == 0) {
+			dev_err(&serial->interface->dev, "interrupt-out endpoint missing\n");
+			return -ENODEV;
+		}
+	}
+
+	return 1;
+}
+
 static int metrousb_send_unidirectional_cmd(u8 cmd, struct usb_serial_port *port)
 static int metrousb_send_unidirectional_cmd(u8 cmd, struct usb_serial_port *port)
 {
 {
 	int ret;
 	int ret;
 	int actual_len;
 	int actual_len;
 	u8 *buffer_cmd = NULL;
 	u8 *buffer_cmd = NULL;
 
 
-	if (!metrousb_is_unidirectional_mode(port))
+	if (!metrousb_is_unidirectional_mode(port->serial))
 		return 0;
 		return 0;
 
 
 	buffer_cmd = kzalloc(sizeof(cmd), GFP_KERNEL);
 	buffer_cmd = kzalloc(sizeof(cmd), GFP_KERNEL);
@@ -161,13 +173,6 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
 	unsigned long flags = 0;
 	unsigned long flags = 0;
 	int result = 0;
 	int result = 0;
 
 
-	/* Make sure the urb is initialized. */
-	if (!port->interrupt_in_urb) {
-		dev_err(&port->dev, "%s - interrupt urb not initialized\n",
-			__func__);
-		return -ENODEV;
-	}
-
 	/* Set the private data information for the port. */
 	/* Set the private data information for the port. */
 	spin_lock_irqsave(&metro_priv->lock, flags);
 	spin_lock_irqsave(&metro_priv->lock, flags);
 	metro_priv->control_state = 0;
 	metro_priv->control_state = 0;
@@ -189,7 +194,7 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
 		dev_err(&port->dev,
 		dev_err(&port->dev,
 			"%s - failed submitting interrupt in urb, error code=%d\n",
 			"%s - failed submitting interrupt in urb, error code=%d\n",
 			__func__, result);
 			__func__, result);
-		goto exit;
+		return result;
 	}
 	}
 
 
 	/* Send activate cmd to device */
 	/* Send activate cmd to device */
@@ -198,9 +203,14 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
 		dev_err(&port->dev,
 		dev_err(&port->dev,
 			"%s - failed to configure device, error code=%d\n",
 			"%s - failed to configure device, error code=%d\n",
 			__func__, result);
 			__func__, result);
-		goto exit;
+		goto err_kill_urb;
 	}
 	}
-exit:
+
+	return 0;
+
+err_kill_urb:
+	usb_kill_urb(port->interrupt_in_urb);
+
 	return result;
 	return result;
 }
 }
 
 
@@ -337,7 +347,8 @@ static struct usb_serial_driver metrousb_device = {
 	},
 	},
 	.description		= "Metrologic USB to Serial",
 	.description		= "Metrologic USB to Serial",
 	.id_table		= id_table,
 	.id_table		= id_table,
-	.num_ports		= 1,
+	.num_interrupt_in	= 1,
+	.calc_num_ports		= metrousb_calc_num_ports,
 	.open			= metrousb_open,
 	.open			= metrousb_open,
 	.close			= metrousb_cleanup,
 	.close			= metrousb_cleanup,
 	.read_int_callback	= metrousb_read_int_callback,
 	.read_int_callback	= metrousb_read_int_callback,

+ 1 - 0
drivers/usb/serial/qcserial.c

@@ -148,6 +148,7 @@ static const struct usb_device_id id_table[] = {
 	{DEVICE_SWI(0x1199, 0x68a2)},	/* Sierra Wireless MC7710 */
 	{DEVICE_SWI(0x1199, 0x68a2)},	/* Sierra Wireless MC7710 */
 	{DEVICE_SWI(0x1199, 0x68c0)},	/* Sierra Wireless MC7304/MC7354 */
 	{DEVICE_SWI(0x1199, 0x68c0)},	/* Sierra Wireless MC7304/MC7354 */
 	{DEVICE_SWI(0x1199, 0x901c)},	/* Sierra Wireless EM7700 */
 	{DEVICE_SWI(0x1199, 0x901c)},	/* Sierra Wireless EM7700 */
+	{DEVICE_SWI(0x1199, 0x901e)},	/* Sierra Wireless EM7355 QDL */
 	{DEVICE_SWI(0x1199, 0x901f)},	/* Sierra Wireless EM7355 */
 	{DEVICE_SWI(0x1199, 0x901f)},	/* Sierra Wireless EM7355 */
 	{DEVICE_SWI(0x1199, 0x9040)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9040)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9041)},	/* Sierra Wireless MC7305/MC7355 */
 	{DEVICE_SWI(0x1199, 0x9041)},	/* Sierra Wireless MC7305/MC7355 */

+ 0 - 22
drivers/usb/serial/usb-serial.c

@@ -1201,17 +1201,6 @@ static const struct tty_operations serial_ops = {
 
 
 struct tty_driver *usb_serial_tty_driver;
 struct tty_driver *usb_serial_tty_driver;
 
 
-/* Driver structure we register with the USB core */
-static struct usb_driver usb_serial_driver = {
-	.name =		"usbserial",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.suspend =	usb_serial_suspend,
-	.resume =	usb_serial_resume,
-	.no_dynamic_id =	1,
-	.supports_autosuspend =	1,
-};
-
 static int __init usb_serial_init(void)
 static int __init usb_serial_init(void)
 {
 {
 	int result;
 	int result;
@@ -1247,13 +1236,6 @@ static int __init usb_serial_init(void)
 		goto exit_reg_driver;
 		goto exit_reg_driver;
 	}
 	}
 
 
-	/* register the USB driver */
-	result = usb_register(&usb_serial_driver);
-	if (result < 0) {
-		pr_err("%s - usb_register failed\n", __func__);
-		goto exit_tty;
-	}
-
 	/* register the generic driver, if we should */
 	/* register the generic driver, if we should */
 	result = usb_serial_generic_register();
 	result = usb_serial_generic_register();
 	if (result < 0) {
 	if (result < 0) {
@@ -1264,9 +1246,6 @@ static int __init usb_serial_init(void)
 	return result;
 	return result;
 
 
 exit_generic:
 exit_generic:
-	usb_deregister(&usb_serial_driver);
-
-exit_tty:
 	tty_unregister_driver(usb_serial_tty_driver);
 	tty_unregister_driver(usb_serial_tty_driver);
 
 
 exit_reg_driver:
 exit_reg_driver:
@@ -1285,7 +1264,6 @@ static void __exit usb_serial_exit(void)
 
 
 	usb_serial_generic_deregister();
 	usb_serial_generic_deregister();
 
 
-	usb_deregister(&usb_serial_driver);
 	tty_unregister_driver(usb_serial_tty_driver);
 	tty_unregister_driver(usb_serial_tty_driver);
 	put_tty_driver(usb_serial_tty_driver);
 	put_tty_driver(usb_serial_tty_driver);
 	bus_unregister(&usb_serial_bus_type);
 	bus_unregister(&usb_serial_bus_type);