[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#804350: ITP: vizzini -- Kernel driver for Exar XR21V1414 USB UART



Hi Ben,

On Tue, 10 Nov 2015 22:06:20 +0000 Ben Hutchings <ben@decadent.org.uk> wrote:
> However, as this device doesn't really seem to follow the CDC-ACM class
> at all, I suspect that the way to support it upstream is with a custom
> USB serial driver.  I've attached a patch against Linux 4.3 which
> implements that.  This involved a certain amount of guesswork as I have
> no experience with serial drivers, but I think it's worth trying.

Thanks for the patch. Similarly, I don't have experience with serial
drivers. We managed to get it working with some changes to skip over
the interrupt endpoint. While this hack works, we need to work out
what we're missing by ignoring this descriptor.

I have a tree with my patch atop Bens here:

 https://github.com/shenki/linux/tree/vizzini

Cheers,

Joel
From 36b15d5c5a6374acf075f3dbe38ecd67757f8564 Mon Sep 17 00:00:00 2001
From: Joel Stanley <joel@jms.id.au>
Date: Sun, 15 Nov 2015 17:30:19 +1030
Subject: [PATCH] usb-serial/vizzini: Fix probing for 1410 device

This device has the following configuration:

 device
  - interface
    - interrupt endpoint
  - interface
    - in bulk endpoint
    - out bulk endpoint

The first interface should be ignored in order to correctly probe. The
device appears to operate correctly, but this may be a horrible hack.

Signed-off-by: Joel Stanley <joel@jms.id.au>
---
 drivers/usb/serial/vizzini.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/usb/serial/vizzini.c b/drivers/usb/serial/vizzini.c
index b462cb694ed5..ee33366348a7 100644
--- a/drivers/usb/serial/vizzini.c
+++ b/drivers/usb/serial/vizzini.c
@@ -294,6 +294,32 @@ static void vizzini_set_termios(struct tty_struct *tty,
         vizzini_enable(port);
 }
 
+static int vizzini_probe(struct usb_serial *serial,
+			 const struct usb_device_id *id)
+{
+	struct usb_host_interface *iface_desc = serial->interface->
+								cur_altsetting;
+	struct usb_endpoint_descriptor *endpoint;
+	int num_bulk_out = 0;
+	int i;
+
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+		endpoint = &iface_desc->endpoint[i].desc;
+		if (usb_endpoint_is_bulk_out(endpoint)) {
+			dev_dbg(&serial->dev->dev,
+				"found bulk out on endpoint %d\n", i);
+			++num_bulk_out;
+		}
+	}
+
+	if (num_bulk_out == 0) {
+		dev_dbg(&serial->dev->dev, "Invalid interface, discarding\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x04e2, 0x1410), },
 	{ USB_DEVICE(0x04e2, 0x1412), },
@@ -314,6 +340,7 @@ static struct usb_serial_driver vizzini_1410_device = {
 	.id_table =		vizzini_1410_id_table,
 	.num_ports =		1,
 	.set_termios =		vizzini_set_termios,
+	.probe =		vizzini_probe,
 };
 
 static const struct usb_device_id vizzini_1412_id_table[] = {
-- 
2.6.4


Reply to: