All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] USB: serial: pl2303: amend device-type detection
@ 2021-03-11 16:14 Johan Hovold
  2021-03-11 16:14 ` [PATCH 1/5] USB: serial: pl2303: clean up type detection Johan Hovold
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Johan Hovold @ 2021-03-11 16:14 UTC (permalink / raw)
  To: linux-usb
  Cc: Michael G. Katzmann, Charles Yeh,
	Yeh.Charles [葉榮鑫],
	Johan Hovold

This series cleans up, amends and tightens the pl2303 device-type
detection.

There are number of different PL2303 devices out there with various
features and we need to be able to detect more types reliably. 

Specifically this will be used to add support for the alternate divisor
encoding scheme that is used by TA devices.

Johan


Johan Hovold (5):
  USB: serial: pl2303: clean up type detection
  USB: serial: pl2303: amend and tighten type detection
  USB: serial: pl2303: rename legacy PL2303H type
  USB: serial: pl2303: tighten type HXN (G) detection
  USB: serial: pl2303: add device-type names

 drivers/usb/serial/pl2303.c | 131 +++++++++++++++++++++++++++---------
 1 file changed, 98 insertions(+), 33 deletions(-)

-- 
2.26.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] USB: serial: pl2303: clean up type detection
  2021-03-11 16:14 [PATCH 0/5] USB: serial: pl2303: amend device-type detection Johan Hovold
@ 2021-03-11 16:14 ` Johan Hovold
  2021-03-11 16:14 ` [PATCH 2/5] USB: serial: pl2303: amend and tighten " Johan Hovold
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Johan Hovold @ 2021-03-11 16:14 UTC (permalink / raw)
  To: linux-usb
  Cc: Michael G. Katzmann, Charles Yeh,
	Yeh.Charles [葉榮鑫],
	Johan Hovold

Clean up the type detection somewhat in preparation for adding support
for more types.

Note this also fixes the type debug printk for the new HXN type.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/pl2303.c | 68 +++++++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index eed9acd1ae08..db840b471adb 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -362,42 +362,52 @@ static int pl2303_calc_num_ports(struct usb_serial *serial,
 	return 1;
 }
 
+static enum pl2303_type pl2303_detect_type(struct usb_serial *serial)
+{
+	struct usb_device_descriptor *desc = &serial->dev->descriptor;
+	int ret;
+	u8 buf;
+
+	/*
+	 * Legacy types 0 and 1, difference unknown.
+	 */
+	if (desc->bDeviceClass == 0x02)
+		return TYPE_01;		/* type 0 */
+
+	if (desc->bMaxPacketSize0 != 0x40) {
+		if (desc->bDeviceClass == 0x00 || desc->bDeviceClass == 0xff)
+			return TYPE_01;	/* type 1 */
+
+		return TYPE_01;		/* type 0 */
+	}
+
+	/*
+	 * Assume it's an HXN-type if the device doesn't support the old read
+	 * request value.
+	 */
+	ret = usb_control_msg_recv(serial->dev, 0, VENDOR_READ_REQUEST,
+			VENDOR_READ_REQUEST_TYPE, PL2303_READ_TYPE_HX_STATUS,
+			0, &buf, 1, 100, GFP_KERNEL);
+	if (ret)
+		return TYPE_HXN;
+
+	return TYPE_HX;
+}
+
 static int pl2303_startup(struct usb_serial *serial)
 {
 	struct pl2303_serial_private *spriv;
-	enum pl2303_type type = TYPE_01;
+	enum pl2303_type type;
 	unsigned char *buf;
-	int res;
 
 	spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
 	if (!spriv)
 		return -ENOMEM;
 
-	buf = kmalloc(1, GFP_KERNEL);
-	if (!buf) {
-		kfree(spriv);
-		return -ENOMEM;
-	}
+	type = pl2303_detect_type(serial);
 
-	if (serial->dev->descriptor.bDeviceClass == 0x02)
-		type = TYPE_01;		/* type 0 */
-	else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40)
-		type = TYPE_HX;
-	else if (serial->dev->descriptor.bDeviceClass == 0x00)
-		type = TYPE_01;		/* type 1 */
-	else if (serial->dev->descriptor.bDeviceClass == 0xFF)
-		type = TYPE_01;		/* type 1 */
 	dev_dbg(&serial->interface->dev, "device type: %d\n", type);
 
-	if (type == TYPE_HX) {
-		res = usb_control_msg(serial->dev,
-				usb_rcvctrlpipe(serial->dev, 0),
-				VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE,
-				PL2303_READ_TYPE_HX_STATUS, 0, buf, 1, 100);
-		if (res != 1)
-			type = TYPE_HXN;
-	}
-
 	spriv->type = &pl2303_type_data[type];
 	spriv->quirks = (unsigned long)usb_get_serial_data(serial);
 	spriv->quirks |= spriv->type->quirks;
@@ -405,6 +415,12 @@ static int pl2303_startup(struct usb_serial *serial)
 	usb_set_serial_data(serial, spriv);
 
 	if (type != TYPE_HXN) {
+		buf = kmalloc(1, GFP_KERNEL);
+		if (!buf) {
+			kfree(spriv);
+			return -ENOMEM;
+		}
+
 		pl2303_vendor_read(serial, 0x8484, buf);
 		pl2303_vendor_write(serial, 0x0404, 0);
 		pl2303_vendor_read(serial, 0x8484, buf);
@@ -419,9 +435,9 @@ static int pl2303_startup(struct usb_serial *serial)
 			pl2303_vendor_write(serial, 2, 0x24);
 		else
 			pl2303_vendor_write(serial, 2, 0x44);
-	}
 
-	kfree(buf);
+		kfree(buf);
+	}
 
 	return 0;
 }
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] USB: serial: pl2303: amend and tighten type detection
  2021-03-11 16:14 [PATCH 0/5] USB: serial: pl2303: amend device-type detection Johan Hovold
  2021-03-11 16:14 ` [PATCH 1/5] USB: serial: pl2303: clean up type detection Johan Hovold
@ 2021-03-11 16:14 ` Johan Hovold
  2021-03-11 16:14 ` [PATCH 3/5] USB: serial: pl2303: rename legacy PL2303H type Johan Hovold
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Johan Hovold @ 2021-03-11 16:14 UTC (permalink / raw)
  To: linux-usb
  Cc: Michael G. Katzmann, Charles Yeh,
	Yeh.Charles [葉榮鑫],
	Johan Hovold

Add support for detecting the HX, TA, TB and HXD device types and refuse
to bind to any unknown types.

Note that the HX type includes the XA variant, while the HXD type
includes the EA, RA and SA variants.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/pl2303.c | 50 +++++++++++++++++++++++++++++++------
 1 file changed, 42 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index db840b471adb..42dcc3cfb449 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -174,8 +174,11 @@ static void pl2303_set_break(struct usb_serial_port *port, bool enable);
 
 enum pl2303_type {
 	TYPE_01,	/* Type 0 and 1 (difference unknown) */
-	TYPE_HX,	/* HX version of the pl2303 chip */
-	TYPE_HXN,	/* HXN version of the pl2303 chip */
+	TYPE_HX,
+	TYPE_TA,
+	TYPE_TB,
+	TYPE_HXD,
+	TYPE_HXN,
 	TYPE_COUNT
 };
 
@@ -206,6 +209,15 @@ static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
 		.no_autoxonxoff		= true,
 	},
 	[TYPE_HX] = {
+		.max_baud_rate		= 6000000,
+	},
+	[TYPE_TA] = {
+		.max_baud_rate		= 6000000,
+	},
+	[TYPE_TB] = {
+		.max_baud_rate		= 12000000,
+	},
+	[TYPE_HXD] = {
 		.max_baud_rate		= 12000000,
 	},
 	[TYPE_HXN] = {
@@ -362,9 +374,10 @@ static int pl2303_calc_num_ports(struct usb_serial *serial,
 	return 1;
 }
 
-static enum pl2303_type pl2303_detect_type(struct usb_serial *serial)
+static int pl2303_detect_type(struct usb_serial *serial)
 {
 	struct usb_device_descriptor *desc = &serial->dev->descriptor;
+	u16 bcdDevice, bcdUSB;
 	int ret;
 	u8 buf;
 
@@ -391,7 +404,24 @@ static enum pl2303_type pl2303_detect_type(struct usb_serial *serial)
 	if (ret)
 		return TYPE_HXN;
 
-	return TYPE_HX;
+	bcdDevice = le16_to_cpu(desc->bcdDevice);
+	bcdUSB = le16_to_cpu(desc->bcdUSB);
+
+	switch (bcdDevice) {
+	case 0x300:
+		if (bcdUSB == 0x200)
+			return TYPE_TA;
+
+		return TYPE_HX;
+	case 0x400:
+		return TYPE_HXD;
+	case 0x500:
+		return TYPE_TB;
+	}
+
+	dev_err(&serial->interface->dev,
+			"unknown device type, please report to linux-usb@vger.kernel.org\n");
+	return -ENODEV;
 }
 
 static int pl2303_startup(struct usb_serial *serial)
@@ -399,15 +429,19 @@ static int pl2303_startup(struct usb_serial *serial)
 	struct pl2303_serial_private *spriv;
 	enum pl2303_type type;
 	unsigned char *buf;
+	int ret;
+
+	ret = pl2303_detect_type(serial);
+	if (ret < 0)
+		return ret;
+
+	type = ret;
+	dev_dbg(&serial->interface->dev, "device type: %d\n", type);
 
 	spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
 	if (!spriv)
 		return -ENOMEM;
 
-	type = pl2303_detect_type(serial);
-
-	dev_dbg(&serial->interface->dev, "device type: %d\n", type);
-
 	spriv->type = &pl2303_type_data[type];
 	spriv->quirks = (unsigned long)usb_get_serial_data(serial);
 	spriv->quirks |= spriv->type->quirks;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] USB: serial: pl2303: rename legacy PL2303H type
  2021-03-11 16:14 [PATCH 0/5] USB: serial: pl2303: amend device-type detection Johan Hovold
  2021-03-11 16:14 ` [PATCH 1/5] USB: serial: pl2303: clean up type detection Johan Hovold
  2021-03-11 16:14 ` [PATCH 2/5] USB: serial: pl2303: amend and tighten " Johan Hovold
@ 2021-03-11 16:14 ` Johan Hovold
  2021-03-11 16:14 ` [PATCH 4/5] USB: serial: pl2303: tighten type HXN (G) detection Johan Hovold
  2021-03-11 16:14 ` [PATCH 5/5] USB: serial: pl2303: add device-type names Johan Hovold
  4 siblings, 0 replies; 6+ messages in thread
From: Johan Hovold @ 2021-03-11 16:14 UTC (permalink / raw)
  To: linux-usb
  Cc: Michael G. Katzmann, Charles Yeh,
	Yeh.Charles [葉榮鑫],
	Johan Hovold

Rename the legacy type which is supposedly a PL2303H which came in two
variants (and which we handle the same way).

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/pl2303.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 42dcc3cfb449..cd2acd8c5246 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -173,7 +173,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
 static void pl2303_set_break(struct usb_serial_port *port, bool enable);
 
 enum pl2303_type {
-	TYPE_01,	/* Type 0 and 1 (difference unknown) */
+	TYPE_H,
 	TYPE_HX,
 	TYPE_TA,
 	TYPE_TB,
@@ -203,7 +203,7 @@ struct pl2303_private {
 };
 
 static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
-	[TYPE_01] = {
+	[TYPE_H] = {
 		.max_baud_rate		= 1228800,
 		.quirks			= PL2303_QUIRK_LEGACY,
 		.no_autoxonxoff		= true,
@@ -382,16 +382,16 @@ static int pl2303_detect_type(struct usb_serial *serial)
 	u8 buf;
 
 	/*
-	 * Legacy types 0 and 1, difference unknown.
+	 * Legacy PL2303H, variants 0 and 1 (difference unknown).
 	 */
 	if (desc->bDeviceClass == 0x02)
-		return TYPE_01;		/* type 0 */
+		return TYPE_H;		/* variant 0 */
 
 	if (desc->bMaxPacketSize0 != 0x40) {
 		if (desc->bDeviceClass == 0x00 || desc->bDeviceClass == 0xff)
-			return TYPE_01;	/* type 1 */
+			return TYPE_H;	/* variant 1 */
 
-		return TYPE_01;		/* type 0 */
+		return TYPE_H;		/* variant 0 */
 	}
 
 	/*
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] USB: serial: pl2303: tighten type HXN (G) detection
  2021-03-11 16:14 [PATCH 0/5] USB: serial: pl2303: amend device-type detection Johan Hovold
                   ` (2 preceding siblings ...)
  2021-03-11 16:14 ` [PATCH 3/5] USB: serial: pl2303: rename legacy PL2303H type Johan Hovold
@ 2021-03-11 16:14 ` Johan Hovold
  2021-03-11 16:14 ` [PATCH 5/5] USB: serial: pl2303: add device-type names Johan Hovold
  4 siblings, 0 replies; 6+ messages in thread
From: Johan Hovold @ 2021-03-11 16:14 UTC (permalink / raw)
  To: linux-usb
  Cc: Michael G. Katzmann, Charles Yeh,
	Yeh.Charles [葉榮鑫],
	Johan Hovold

Tighten the detection of the new HXN (G) type instead of assuming that
every device which doesn't support the old read request is an HXN.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/pl2303.c | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index cd2acd8c5246..e742187c8a7f 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -374,12 +374,22 @@ static int pl2303_calc_num_ports(struct usb_serial *serial,
 	return 1;
 }
 
+static bool pl2303_supports_hx_status(struct usb_serial *serial)
+{
+	int ret;
+	u8 buf;
+
+	ret = usb_control_msg_recv(serial->dev, 0, VENDOR_READ_REQUEST,
+			VENDOR_READ_REQUEST_TYPE, PL2303_READ_TYPE_HX_STATUS,
+			0, &buf, 1, 100, GFP_KERNEL);
+
+	return ret == 0;
+}
+
 static int pl2303_detect_type(struct usb_serial *serial)
 {
 	struct usb_device_descriptor *desc = &serial->dev->descriptor;
 	u16 bcdDevice, bcdUSB;
-	int ret;
-	u8 buf;
 
 	/*
 	 * Legacy PL2303H, variants 0 and 1 (difference unknown).
@@ -394,20 +404,18 @@ static int pl2303_detect_type(struct usb_serial *serial)
 		return TYPE_H;		/* variant 0 */
 	}
 
-	/*
-	 * Assume it's an HXN-type if the device doesn't support the old read
-	 * request value.
-	 */
-	ret = usb_control_msg_recv(serial->dev, 0, VENDOR_READ_REQUEST,
-			VENDOR_READ_REQUEST_TYPE, PL2303_READ_TYPE_HX_STATUS,
-			0, &buf, 1, 100, GFP_KERNEL);
-	if (ret)
-		return TYPE_HXN;
-
 	bcdDevice = le16_to_cpu(desc->bcdDevice);
 	bcdUSB = le16_to_cpu(desc->bcdUSB);
 
 	switch (bcdDevice) {
+	case 0x100:
+		/*
+		 * Assume it's an HXN-type if the device doesn't support the old read
+		 * request value.
+		 */
+		if (bcdUSB == 0x200 && !pl2303_supports_hx_status(serial))
+			return TYPE_HXN;
+		break;
 	case 0x300:
 		if (bcdUSB == 0x200)
 			return TYPE_TA;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] USB: serial: pl2303: add device-type names
  2021-03-11 16:14 [PATCH 0/5] USB: serial: pl2303: amend device-type detection Johan Hovold
                   ` (3 preceding siblings ...)
  2021-03-11 16:14 ` [PATCH 4/5] USB: serial: pl2303: tighten type HXN (G) detection Johan Hovold
@ 2021-03-11 16:14 ` Johan Hovold
  4 siblings, 0 replies; 6+ messages in thread
From: Johan Hovold @ 2021-03-11 16:14 UTC (permalink / raw)
  To: linux-usb
  Cc: Michael G. Katzmann, Charles Yeh,
	Yeh.Charles [葉榮鑫],
	Johan Hovold

Add names for the device types to be printed at probe when debugging is
enabled.

Note that the HXN type is referred to as G for now as that is the name
the vendor uses.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/pl2303.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index e742187c8a7f..7208966891d0 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -183,6 +183,7 @@ enum pl2303_type {
 };
 
 struct pl2303_type_data {
+	const char *name;
 	speed_t max_baud_rate;
 	unsigned long quirks;
 	unsigned int no_autoxonxoff:1;
@@ -204,23 +205,29 @@ struct pl2303_private {
 
 static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
 	[TYPE_H] = {
+		.name			= "H",
 		.max_baud_rate		= 1228800,
 		.quirks			= PL2303_QUIRK_LEGACY,
 		.no_autoxonxoff		= true,
 	},
 	[TYPE_HX] = {
+		.name			= "HX",
 		.max_baud_rate		= 6000000,
 	},
 	[TYPE_TA] = {
+		.name			= "TA",
 		.max_baud_rate		= 6000000,
 	},
 	[TYPE_TB] = {
+		.name			= "TB",
 		.max_baud_rate		= 12000000,
 	},
 	[TYPE_HXD] = {
+		.name			= "HXD",
 		.max_baud_rate		= 12000000,
 	},
 	[TYPE_HXN] = {
+		.name			= "G",
 		.max_baud_rate		= 12000000,
 		.no_divisors		= true,
 	},
@@ -444,7 +451,7 @@ static int pl2303_startup(struct usb_serial *serial)
 		return ret;
 
 	type = ret;
-	dev_dbg(&serial->interface->dev, "device type: %d\n", type);
+	dev_dbg(&serial->interface->dev, "device type: %s\n", pl2303_type_data[type].name);
 
 	spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
 	if (!spriv)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-03-11 16:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-11 16:14 [PATCH 0/5] USB: serial: pl2303: amend device-type detection Johan Hovold
2021-03-11 16:14 ` [PATCH 1/5] USB: serial: pl2303: clean up type detection Johan Hovold
2021-03-11 16:14 ` [PATCH 2/5] USB: serial: pl2303: amend and tighten " Johan Hovold
2021-03-11 16:14 ` [PATCH 3/5] USB: serial: pl2303: rename legacy PL2303H type Johan Hovold
2021-03-11 16:14 ` [PATCH 4/5] USB: serial: pl2303: tighten type HXN (G) detection Johan Hovold
2021-03-11 16:14 ` [PATCH 5/5] USB: serial: pl2303: add device-type names Johan Hovold

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.