Convert the keyspan USB serial driver to use request_firmware and
firmware_load_ihex.

Signed-off-by: Jan Harkes <[EMAIL PROTECTED]>

Index: linux/drivers/usb/serial/keyspan.c
===================================================================
--- linux.orig/drivers/usb/serial/keyspan.c     2005-03-10 16:01:15.000000000 
-0500
+++ linux/drivers/usb/serial/keyspan.c  2005-03-10 23:07:21.070790916 -0500
@@ -28,6 +28,9 @@
 
   Change History
 
+    2005mar10  Jan Harkes
+      Use generic request_firmware/firmware_load_ihex functions.
+
     2003sep04  LPM (Keyspan) add support for new single port product USA19HS.
                                Improve setup message handling for all devices.
 
@@ -106,6 +109,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/firmware.h>
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 #include "usb-serial.h"
@@ -1165,13 +1169,28 @@
        port->tty = NULL;
 }
 
+static int keyspan_fw_load(struct ihex_record *record, void *arg)
+{
+       struct usb_serial *serial = (struct usb_serial *)arg;
+       int ret;
+
+       ret = ezusb_writememory(serial, record->address, record->data,
+                               record->len, 0xa0);
+       if (ret < 0) {
+               dev_err(&serial->dev->dev,
+                       "ezusb_writememory failed for Keyspan"
+                       "firmware (%d %08X %p %d)\n",
+                       ret, record->address, record->data, record->len);
+       }
+       return ret;
+}
 
        /* download the firmware to a pre-renumeration device */
 static int keyspan_fake_startup (struct usb_serial *serial)
 {
        int                             response;
-       const struct ezusb_hex_record   *record;
-       char                            *fw_name;
+       char                            *model, fw_name[20];
+       const struct firmware           *fw;
 
        dbg("Keyspan startup version %04x product %04x",
            le16_to_cpu(serial->dev->descriptor.bcdDevice),
@@ -1182,97 +1201,43 @@
                return(1);
        }
 
-               /* Select firmware image on the basis of idProduct */
        switch (le16_to_cpu(serial->dev->descriptor.idProduct)) {
-       case keyspan_usa28_pre_product_id:
-               record = &keyspan_usa28_firmware[0];
-               fw_name = "USA28";
-               break;
-
-       case keyspan_usa28x_pre_product_id:
-               record = &keyspan_usa28x_firmware[0];
-               fw_name = "USA28X";
-               break;
-
-       case keyspan_usa28xa_pre_product_id:
-               record = &keyspan_usa28xa_firmware[0];
-               fw_name = "USA28XA";
-               break;
-
-       case keyspan_usa28xb_pre_product_id:
-               record = &keyspan_usa28xb_firmware[0];
-               fw_name = "USA28XB";
-               break;
-
-       case keyspan_usa19_pre_product_id:
-               record = &keyspan_usa19_firmware[0];
-               fw_name = "USA19";
-               break;
-                            
-       case keyspan_usa19qi_pre_product_id:
-               record = &keyspan_usa19qi_firmware[0];
-               fw_name = "USA19QI";
-               break;
-                            
-       case keyspan_mpr_pre_product_id:
-               record = &keyspan_mpr_firmware[0];
-               fw_name = "MPR";
-               break;
-
-       case keyspan_usa19qw_pre_product_id:
-               record = &keyspan_usa19qw_firmware[0];
-               fw_name = "USA19QI";
-               break;
-                            
-       case keyspan_usa18x_pre_product_id:
-               record = &keyspan_usa18x_firmware[0];
-               fw_name = "USA18X";
-               break;
-                            
-       case keyspan_usa19w_pre_product_id:
-               record = &keyspan_usa19w_firmware[0];
-               fw_name = "USA19W";
-               break;
-               
-       case keyspan_usa49w_pre_product_id:
-               record = &keyspan_usa49w_firmware[0];
-               fw_name = "USA49W";
-               break;
-
-       case keyspan_usa49wlc_pre_product_id:
-               record = &keyspan_usa49wlc_firmware[0];
-               fw_name = "USA49WLC";
-               break;
-
+       case keyspan_usa18x_pre_product_id:   model = "usa18x";   break;
+       case keyspan_usa19_pre_product_id:    model = "usa19";    break;
+       case keyspan_usa19qi_pre_product_id:  model = "usa19qi";  break;
+       case keyspan_mpr_pre_product_id:      model = "mpr";      break;
+       case keyspan_usa19qw_pre_product_id:  model = "usa19qw";  break;
+       case keyspan_usa19w_pre_product_id:   model = "usa19w";   break;
+       case keyspan_usa28_pre_product_id:    model = "usa28";    break;
+       case keyspan_usa28x_pre_product_id:   model = "usa28x";   break;
+       case keyspan_usa28xa_pre_product_id:  model = "usa28xa";  break;
+       case keyspan_usa28xb_pre_product_id:  model = "usa28xb";  break;
+       case keyspan_usa49w_pre_product_id:   model = "usa49w";   break;
+       case keyspan_usa49wlc_pre_product_id: model = "usa49wlc"; break;
        default:
-               record = NULL;
-               fw_name = "Unknown";
-               break;
+               dev_err(&serial->dev->dev, "Unknown keyspan device (%04x).\n",
+                       le16_to_cpu(serial->dev->descriptor.idProduct));
+               return(1);
        }
 
-       if (record == NULL) {
-               dev_err(&serial->dev->dev, "Required keyspan firmware image 
(%s) unavailable.\n", fw_name);
+       sprintf(fw_name, "keyspan-%s.fw", model);
+
+       if (request_firmware(&fw, fw_name, &serial->dev->dev) != 0) {
+               dev_err(&serial->dev->dev, "Required firmware image (%s) 
unavailable.\n", fw_name);
                return(1);
        }
 
-       dbg("Uploading Keyspan %s firmware.", fw_name);
+       dbg("Uploading Keyspan %s firmware.", model);
 
                /* download the firmware image */
        response = ezusb_set_reset(serial, 1);
 
-       while(record->address != 0xffff) {
-               response = ezusb_writememory(serial, record->address,
-                                            (unsigned char *)record->data,
-                                            record->data_size, 0xa0);
-               if (response < 0) {
-                       dev_err(&serial->dev->dev, "ezusb_writememory failed 
for Keyspan"
-                               "firmware (%d %04X %p %d)\n",
-                               response, 
-                               record->address, record->data, 
record->data_size);
-                       break;
-               }
-               record++;
-       }
+       if (firmware_load_ihex(fw, serial, keyspan_fw_load))
+               dev_err(&serial->dev->dev, "Firmware %s upload failed\n",
+                       fw_name);
+
+       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_set_reset(serial, 0);
@@ -1418,7 +1383,7 @@
                        (serial, d_details->outcont_endpoints[i], USB_DIR_OUT,
                         port, p_priv->outcont_buffer, 64,
                         cback->outcont_callback);
-       }       
+       }
 
 }
 
Index: linux/drivers/usb/serial/keyspan.h
===================================================================
--- linux.orig/drivers/usb/serial/keyspan.h     2005-03-10 15:59:58.000000000 
-0500
+++ linux/drivers/usb/serial/keyspan.h  2005-03-10 22:56:15.343354346 -0500
@@ -99,90 +99,6 @@
                                         struct usb_serial_port *port,
                                         int reset_port);
 
-/* Struct used for firmware - increased size of data section
-   to allow Keyspan's 'C' firmware struct to be used unmodified */
-struct ezusb_hex_record {
-       __u16 address;
-       __u8 data_size;
-       __u8 data[64];
-};
-
-/* Conditionally include firmware images, if they aren't
-   included create a null pointer instead.  Current 
-   firmware images aren't optimised to remove duplicate
-   addresses in the image itself. */
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28
-       #include "keyspan_usa28_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa28_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28X
-       #include "keyspan_usa28x_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa28x_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28XA
-       #include "keyspan_usa28xa_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa28xa_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28XB
-       #include "keyspan_usa28xb_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa28xb_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19
-       #include "keyspan_usa19_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa19_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19QI
-       #include "keyspan_usa19qi_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa19qi_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_MPR
-        #include "keyspan_mpr_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_mpr_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19QW
-       #include "keyspan_usa19qw_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa19qw_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA18X
-       #include "keyspan_usa18x_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa18x_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19W
-       #include "keyspan_usa19w_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa19w_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA49W
-       #include "keyspan_usa49w_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa49w_firmware = NULL;
-#endif
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA49WLC
-        #include "keyspan_usa49wlc_fw.h"
-#else
-       static const struct ezusb_hex_record *keyspan_usa49wlc_firmware = NULL;
-#endif
-
 /* Values used for baud rate calculation - device specific */
 #define        KEYSPAN_INVALID_BAUD_RATE               (-1)
 #define        KEYSPAN_BAUD_RATE_OK                    (0)
Index: linux/drivers/usb/serial/Kconfig
===================================================================
--- linux.orig/drivers/usb/serial/Kconfig       2005-03-10 16:01:14.000000000 
-0500
+++ linux/drivers/usb/serial/Kconfig    2005-03-10 16:18:19.000000000 -0500
@@ -242,92 +242,21 @@
        ---help---
          Say Y here if you want to use Keyspan USB to serial converter
          devices.  This driver makes use of Keyspan's official firmware
-         and was developed with their support.  You must also include
-         firmware to support your particular device(s).
+         and was developed with their support.  It uses hotplug to load
+         the required firmware from /usr/lib/hotplug/firmware or
+         /lib/firmware.
+         
+         However there really isn't a good way to get this firmware
+         since the license only allows it to be distributed as part of
+         a Linux or other Open Source operating system kernel.  So you
+         will have to copy the firmware files from the kernel source
+         tree (drivers/usb/serial/*.fw) to /lib/firmware yourself.
 
          See <http://misc.nu/hugh/keyspan.html> for more information.
 
          To compile this driver as a module, choose M here: the
          module will be called keyspan.
 
-config USB_SERIAL_KEYSPAN_MPR
-       bool "USB Keyspan MPR Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the Keyspan MPR converter.
-
-config USB_SERIAL_KEYSPAN_USA28
-       bool "USB Keyspan USA-28 Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-28 converter.
-
-config USB_SERIAL_KEYSPAN_USA28X
-       bool "USB Keyspan USA-28X Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-28X converter.
-         Be sure you have a USA-28X, there are also 28XA and 28XB
-         models, the label underneath has the actual part number.
-
-config USB_SERIAL_KEYSPAN_USA28XA
-       bool "USB Keyspan USA-28XA Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-28XA converter.
-         Be sure you have a USA-28XA, there are also 28X and 28XB
-         models, the label underneath has the actual part number.
-
-config USB_SERIAL_KEYSPAN_USA28XB
-       bool "USB Keyspan USA-28XB Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-28XB converter.
-         Be sure you have a USA-28XB, there are also 28X and 28XA
-         models, the label underneath has the actual part number.
-
-config USB_SERIAL_KEYSPAN_USA19
-       bool "USB Keyspan USA-19 Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-19 converter.
-
-config USB_SERIAL_KEYSPAN_USA18X
-       bool "USB Keyspan USA-18X Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-18X converter.
-
-config USB_SERIAL_KEYSPAN_USA19W
-       bool "USB Keyspan USA-19W Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-19W converter.
-
-config USB_SERIAL_KEYSPAN_USA19QW
-       bool "USB Keyspan USA-19QW Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-19QW converter.
-
-config USB_SERIAL_KEYSPAN_USA19QI
-       bool "USB Keyspan USA-19QI Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-19QI converter.
-
-config USB_SERIAL_KEYSPAN_USA49W
-       bool "USB Keyspan USA-49W Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-49W converter.
-
-config USB_SERIAL_KEYSPAN_USA49WLC
-       bool "USB Keyspan USA-49WLC Firmware"
-       depends on USB_SERIAL_KEYSPAN
-       help
-         Say Y here to include firmware for the USA-49WLC converter.
-
 config USB_SERIAL_KLSI
        tristate "USB KL5KUSB105 (Palmconnect) Driver (EXPERIMENTAL)"
        depends on USB_SERIAL && EXPERIMENTAL
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to