aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/keyspan_pda.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/keyspan_pda.c')
-rw-r--r--drivers/usb/serial/keyspan_pda.c51
1 files changed, 24 insertions, 27 deletions
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index ff54203944c..644a1eaaa37 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
83static int debug; 85static int debug;
84 86
85struct 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)
722static int keyspan_pda_fake_startup (struct usb_serial *serial) 710static 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);