Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee13a25f authored by Johan Hovold's avatar Johan Hovold
Browse files

USB: serial: metro-usb: add missing interrupt-out endpoint check



One class of "unidirectional" devices managed by this driver uses an
interrupt-out endpoint to send control messages at open and close. Due
to a missing endpoint sanity check, this could result in an interrupt
URB being submitted to endpoint 0 instead. This would be caught by
USB core (without a WARN dump), but let's verify that the expected
endpoints are present at probe rather than when a port is later opened.

Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parent 6f792f47
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -53,21 +53,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);
@@ -334,8 +346,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,