This still affects 5.15.0-3-amd64:

[624300.704569] usb 5-1: new full-speed USB device number 2 using ohci-pci
[624300.901723] usb 5-1: New USB device found, idVendor=06cd, idProduct=011a, 
bcdDevice=80.01
[624300.901746] usb 5-1: New USB device strings: Mfr=0, Product=0, 
SerialNumber=0
[624300.903869] keyspan 5-1:1.0: Keyspan - (without firmware) converter detected
[624300.904014] usb 5-1: firmware: direct-loading firmware keyspan/usa49wlc.fw
[624304.121517] usb 5-1: ezusb_ihex_firmware_download - ezusb_writememory 
failed writing internal memory (-110 7F92 00000000b8cbdc0a 1)
[624304.121545] usb 5-1: failed to load firmware "keyspan/usa49wlc.fw"
[624304.121559] keyspan: probe of 5-1:1.0 failed with error -2

The patch applies with some fuzz but still solves the issue.
Refreshed patch is attached.

Has anyone already contacted upstream about this? I couldn't find
anything related on the linux-usb ML.

Cheers,
sur5r

-- 
ceterum censeo microsoftem esse delendam.
--- keyspan.c.orig	2022-02-01 15:27:35.472432892 +0100
+++ keyspan.c	2022-02-03 16:03:27.166653874 +0100
@@ -33,6 +33,8 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/firmware.h>
+#include <linux/ihex.h>
 #include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
@@ -599,6 +601,19 @@
 #include "keyspan_usa67msg.h"
 
 
+static int ezusb_writememory(struct usb_device *dev, int address,
+                                unsigned char *data, int length, __u8 request)
+{
+        if (!dev)
+                return -ENODEV;
+
+        return usb_control_msg_send(dev, 0, request,
+                                 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                                 address, 0, data, length, 3000, GFP_KERNEL);
+}
+
+
+
 static void keyspan_break_ctl(struct tty_struct *tty, int break_state)
 {
 	struct usb_serial_port *port = tty->driver_data;
@@ -1599,7 +1614,10 @@
 /* download the firmware to a pre-renumeration device */
 static int keyspan_fake_startup(struct usb_serial *serial)
 {
-	char	*fw_name;
+	int 				response;
+	const struct ihex_binrec 	*record;
+	char				*fw_name;
+	const struct firmware		*fw;
 
 	dev_dbg(&serial->dev->dev, "Keyspan startup version %04x product %04x\n",
 		le16_to_cpu(serial->dev->descriptor.bcdDevice),
@@ -1667,16 +1685,34 @@
 		return 1;
 	}
 
+	if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) {
+		dev_err(&serial->dev->dev, "Required keyspan firmware image (%s) unavailable.\n", fw_name);
+		return 1;
+	}
+
 	dev_dbg(&serial->dev->dev, "Uploading Keyspan %s firmware.\n", fw_name);
 
-	if (ezusb_fx1_ihex_firmware_download(serial->dev, fw_name) < 0) {
-		dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n",
-			fw_name);
-		return -ENOENT;
-	}
+		/* download the firmware image */
+	response = ezusb_fx1_set_reset(serial->dev, 1);
+
+	record = (const struct ihex_binrec *)fw->data;
 
-	/* after downloading firmware Renumeration will occur in a
-	  moment and the new device will bind to the real driver */
+	while (record) {
+		response = ezusb_writememory(serial->dev, be32_to_cpu(record->addr),
+					     (unsigned char *)record->data,
+					     be16_to_cpu(record->len), 0xa0);
+		if (response < 0) {
+			dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan firmware (%d %04X %p %d)\n",
+				response, be32_to_cpu(record->addr),
+				record->data, be16_to_cpu(record->len));
+			break;
+		}
+		record = ihex_next_binrec(record);
+	}
+	release_firmware(fw);
+		/* bring device out of reset. Renumeration will occur in a
+		   moment and the new device will bind to the real driver */
+	response = ezusb_fx1_set_reset(serial->dev, 0);
 
 	/* we don't want this device to have a driver assigned to it. */
 	return 1;

Attachment: pgpMeVe1Xgrz4.pgp
Description: OpenPGP digital signature

Reply via email to