diff options
Diffstat (limited to 'drivers/usb/serial/keyspan_pda.c')
-rw-r--r-- | drivers/usb/serial/keyspan_pda.c | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index ff54203944ca..644a1eaaa376 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -76,18 +76,14 @@ | |||
76 | #include <linux/module.h> | 76 | #include <linux/module.h> |
77 | #include <linux/spinlock.h> | 77 | #include <linux/spinlock.h> |
78 | #include <linux/workqueue.h> | 78 | #include <linux/workqueue.h> |
79 | #include <linux/firmware.h> | ||
80 | #include <linux/ihex.h> | ||
79 | #include <asm/uaccess.h> | 81 | #include <asm/uaccess.h> |
80 | #include <linux/usb.h> | 82 | #include <linux/usb.h> |
81 | #include <linux/usb/serial.h> | 83 | #include <linux/usb/serial.h> |
82 | 84 | ||
83 | static int debug; | 85 | static int debug; |
84 | 86 | ||
85 | struct ezusb_hex_record { | ||
86 | __u16 address; | ||
87 | __u8 data_size; | ||
88 | __u8 data[16]; | ||
89 | }; | ||
90 | |||
91 | /* make a simple define to handle if we are compiling keyspan_pda or xircom support */ | 87 | /* make a simple define to handle if we are compiling keyspan_pda or xircom support */ |
92 | #if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE) | 88 | #if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE) |
93 | #define KEYSPAN | 89 | #define KEYSPAN |
@@ -100,14 +96,6 @@ struct ezusb_hex_record { | |||
100 | #undef XIRCOM | 96 | #undef XIRCOM |
101 | #endif | 97 | #endif |
102 | 98 | ||
103 | #ifdef KEYSPAN | ||
104 | #include "keyspan_pda_fw.h" | ||
105 | #endif | ||
106 | |||
107 | #ifdef XIRCOM | ||
108 | #include "xircom_pgs_fw.h" | ||
109 | #endif | ||
110 | |||
111 | /* | 99 | /* |
112 | * Version Information | 100 | * Version Information |
113 | */ | 101 | */ |
@@ -722,38 +710,47 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp) | |||
722 | static int keyspan_pda_fake_startup (struct usb_serial *serial) | 710 | static int keyspan_pda_fake_startup (struct usb_serial *serial) |
723 | { | 711 | { |
724 | int response; | 712 | int response; |
725 | const struct ezusb_hex_record *record = NULL; | 713 | const char *fw_name; |
714 | const struct ihex_binrec *record; | ||
715 | const struct firmware *fw; | ||
726 | 716 | ||
727 | /* download the firmware here ... */ | 717 | /* download the firmware here ... */ |
728 | response = ezusb_set_reset(serial, 1); | 718 | response = ezusb_set_reset(serial, 1); |
729 | 719 | ||
720 | if (0) { ; } | ||
730 | #ifdef KEYSPAN | 721 | #ifdef KEYSPAN |
731 | if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID) | 722 | else if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID) |
732 | record = &keyspan_pda_firmware[0]; | 723 | fw_name = "keyspan_pda/keyspan_pda.fw"; |
733 | #endif | 724 | #endif |
734 | #ifdef XIRCOM | 725 | #ifdef XIRCOM |
735 | if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) || | 726 | else if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) || |
736 | (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID)) | 727 | (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID)) |
737 | record = &xircom_pgs_firmware[0]; | 728 | fw_name = "keyspan_pda/xircom_pgs.fw"; |
738 | #endif | 729 | #endif |
739 | if (record == NULL) { | 730 | else { |
740 | err("%s: unknown vendor, aborting.", __func__); | 731 | err("%s: unknown vendor, aborting.", __func__); |
741 | return -ENODEV; | 732 | return -ENODEV; |
742 | } | 733 | } |
734 | if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) { | ||
735 | err("failed to load firmware \"%s\"\n", fw_name); | ||
736 | return -ENOENT; | ||
737 | } | ||
738 | record = (const struct ihex_binrec *)fw->data; | ||
743 | 739 | ||
744 | while(record->address != 0xffff) { | 740 | while (record) { |
745 | response = ezusb_writememory(serial, record->address, | 741 | response = ezusb_writememory(serial, be32_to_cpu(record->addr), |
746 | (unsigned char *)record->data, | 742 | (unsigned char *)record->data, |
747 | record->data_size, 0xa0); | 743 | be16_to_cpu(record->len), 0xa0); |
748 | if (response < 0) { | 744 | if (response < 0) { |
749 | err("ezusb_writememory failed for Keyspan PDA " | 745 | err("ezusb_writememory failed for Keyspan PDA " |
750 | "firmware (%d %04X %p %d)", | 746 | "firmware (%d %04X %p %d)", |
751 | response, | 747 | response, be32_to_cpu(record->addr), |
752 | record->address, record->data, record->data_size); | 748 | record->data, be16_to_cpu(record->len)); |
753 | break; | 749 | break; |
754 | } | 750 | } |
755 | record++; | 751 | record = ihex_next_binrec(record); |
756 | } | 752 | } |
753 | release_firmware(fw); | ||
757 | /* bring device out of reset. Renumeration will occur in a moment | 754 | /* bring device out of reset. Renumeration will occur in a moment |
758 | and the new device will bind to the real driver */ | 755 | and the new device will bind to the real driver */ |
759 | response = ezusb_set_reset(serial, 0); | 756 | response = ezusb_set_reset(serial, 0); |