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;
pgpI7o044C24n.pgp
Description: OpenPGP digital signature