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>
This commit is contained in:
Greg Kroah-Hartman
2017-11-02 17:42:47 +01:00
6 changed files with 148 additions and 76 deletions

View File

@@ -54,21 +54,33 @@ MODULE_DEVICE_TABLE(usb, id_table);
#define UNI_CMD_OPEN 0x80
#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;
}
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)
{
int ret;
int actual_len;
u8 *buffer_cmd = NULL;
if (!metrousb_is_unidirectional_mode(port))
if (!metrousb_is_unidirectional_mode(port->serial))
return 0;
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;
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. */
spin_lock_irqsave(&metro_priv->lock, flags);
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,
"%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result);
goto exit;
return result;
}
/* 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,
"%s - failed to configure device, error code=%d\n",
__func__, result);
goto exit;
goto err_kill_urb;
}
exit:
return 0;
err_kill_urb:
usb_kill_urb(port->interrupt_in_urb);
return result;
}
@@ -337,7 +347,8 @@ static struct usb_serial_driver metrousb_device = {
},
.description = "Metrologic USB to Serial",
.id_table = id_table,
.num_ports = 1,
.num_interrupt_in = 1,
.calc_num_ports = metrousb_calc_num_ports,
.open = metrousb_open,
.close = metrousb_cleanup,
.read_int_callback = metrousb_read_int_callback,