aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/ezusb.c79
-rw-r--r--drivers/usb/serial/keyspan.c39
-rw-r--r--drivers/usb/serial/keyspan_pda.c29
-rw-r--r--drivers/usb/serial/whiteheat.c85
4 files changed, 99 insertions, 133 deletions
diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c
index bc3076f2c066..4223d761223d 100644
--- a/drivers/usb/serial/ezusb.c
+++ b/drivers/usb/serial/ezusb.c
@@ -13,6 +13,8 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/usb.h> 15#include <linux/usb.h>
16#include <linux/firmware.h>
17#include <linux/ihex.h>
16 18
17struct ezusb_fx_type { 19struct ezusb_fx_type {
18 /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ 20 /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
@@ -79,3 +81,80 @@ int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit)
79 return ezusb_set_reset(dev, ezusb_fx2.cpucs_reg, reset_bit); 81 return ezusb_set_reset(dev, ezusb_fx2.cpucs_reg, reset_bit);
80} 82}
81EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset); 83EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset);
84
85static int ezusb_ihex_firmware_download(struct usb_device *dev,
86 struct ezusb_fx_type fx,
87 const char *firmware_path)
88{
89 int ret = -ENOENT;
90 const struct firmware *firmware = NULL;
91 const struct ihex_binrec *record;
92
93 if (request_ihex_firmware(&firmware, firmware_path,
94 &dev->dev)) {
95 dev_err(&dev->dev,
96 "%s - request \"%s\" failed\n",
97 __func__, firmware_path);
98 goto out;
99 }
100
101 ret = ezusb_set_reset(dev, fx.cpucs_reg, 0);
102 if (ret < 0)
103 goto out;
104
105 record = (const struct ihex_binrec *)firmware->data;
106 for (; record; record = ihex_next_binrec(record)) {
107 if (be32_to_cpu(record->addr) > fx.max_internal_adress) {
108 ret = ezusb_writememory(dev, be32_to_cpu(record->addr),
109 (unsigned char *)record->data,
110 be16_to_cpu(record->len), WRITE_EXT_RAM);
111 if (ret < 0) {
112 dev_err(&dev->dev, "%s - ezusb_writememory "
113 "failed writing internal memory "
114 "(%d %04X %p %d)\n", __func__, ret,
115 be32_to_cpu(record->addr), record->data,
116 be16_to_cpu(record->len));
117 goto out;
118 }
119 }
120 }
121
122 ret = ezusb_set_reset(dev, fx.cpucs_reg, 1);
123 if (ret < 0)
124 goto out;
125 record = (const struct ihex_binrec *)firmware->data;
126 for (; record; record = ihex_next_binrec(record)) {
127 if (be32_to_cpu(record->addr) <= fx.max_internal_adress) {
128 ret = ezusb_writememory(dev, be32_to_cpu(record->addr),
129 (unsigned char *)record->data,
130 be16_to_cpu(record->len), WRITE_INT_RAM);
131 if (ret < 0) {
132 dev_err(&dev->dev, "%s - ezusb_writememory "
133 "failed writing external memory "
134 "(%d %04X %p %d)\n", __func__, ret,
135 be32_to_cpu(record->addr), record->data,
136 be16_to_cpu(record->len));
137 goto out;
138 }
139 }
140 }
141 ret = ezusb_set_reset(dev, fx.cpucs_reg, 0);
142out:
143 release_firmware(firmware);
144 return ret;
145}
146
147int ezusb_fx1_ihex_firmware_download(struct usb_device *dev,
148 const char *firmware_path)
149{
150 return ezusb_ihex_firmware_download(dev, ezusb_fx1, firmware_path);
151}
152EXPORT_SYMBOL_GPL(ezusb_fx1_ihex_firmware_download);
153
154int ezusb_fx2_ihex_firmware_download(struct usb_device *dev,
155 const char *firmware_path)
156{
157 return ezusb_ihex_firmware_download(dev, ezusb_fx2, firmware_path);
158}
159EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download);
160
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 4f25849d343e..0acb07131f6e 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -38,8 +38,6 @@
38#include <linux/tty_flip.h> 38#include <linux/tty_flip.h>
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/spinlock.h> 40#include <linux/spinlock.h>
41#include <linux/firmware.h>
42#include <linux/ihex.h>
43#include <linux/uaccess.h> 41#include <linux/uaccess.h>
44#include <linux/usb.h> 42#include <linux/usb.h>
45#include <linux/usb/serial.h> 43#include <linux/usb/serial.h>
@@ -1167,10 +1165,7 @@ static void keyspan_close(struct usb_serial_port *port)
1167/* download the firmware to a pre-renumeration device */ 1165/* download the firmware to a pre-renumeration device */
1168static int keyspan_fake_startup(struct usb_serial *serial) 1166static int keyspan_fake_startup(struct usb_serial *serial)
1169{ 1167{
1170 int response; 1168 char *fw_name;
1171 const struct ihex_binrec *record;
1172 char *fw_name;
1173 const struct firmware *fw;
1174 1169
1175 dev_dbg(&serial->dev->dev, "Keyspan startup version %04x product %04x\n", 1170 dev_dbg(&serial->dev->dev, "Keyspan startup version %04x product %04x\n",
1176 le16_to_cpu(serial->dev->descriptor.bcdDevice), 1171 le16_to_cpu(serial->dev->descriptor.bcdDevice),
@@ -1238,34 +1233,16 @@ static int keyspan_fake_startup(struct usb_serial *serial)
1238 return 1; 1233 return 1;
1239 } 1234 }
1240 1235
1241 if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) {
1242 dev_err(&serial->dev->dev, "Required keyspan firmware image (%s) unavailable.\n", fw_name);
1243 return 1;
1244 }
1245
1246 dev_dbg(&serial->dev->dev, "Uploading Keyspan %s firmware.\n", fw_name); 1236 dev_dbg(&serial->dev->dev, "Uploading Keyspan %s firmware.\n", fw_name);
1247 1237
1248 /* download the firmware image */ 1238 if (ezusb_fx1_ihex_firmware_download(serial->dev, fw_name) < 0) {
1249 response = ezusb_fx1_set_reset(serial->dev, 1); 1239 dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n",
1250 1240 fw_name);
1251 record = (const struct ihex_binrec *)fw->data; 1241 return -ENOENT;
1252
1253 while (record) {
1254 response = ezusb_writememory(serial->dev, be32_to_cpu(record->addr),
1255 (unsigned char *)record->data,
1256 be16_to_cpu(record->len), 0xa0);
1257 if (response < 0) {
1258 dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan firmware (%d %04X %p %d)\n",
1259 response, be32_to_cpu(record->addr),
1260 record->data, be16_to_cpu(record->len));
1261 break;
1262 }
1263 record = ihex_next_binrec(record);
1264 } 1242 }
1265 release_firmware(fw); 1243
1266 /* bring device out of reset. Renumeration will occur in a 1244 /* after downloading firmware Renumeration will occur in a
1267 moment and the new device will bind to the real driver */ 1245 moment and the new device will bind to the real driver */
1268 response = ezusb_fx1_set_reset(serial->dev, 0);
1269 1246
1270 /* we don't want this device to have a driver assigned to it. */ 1247 /* we don't want this device to have a driver assigned to it. */
1271 return 1; 1248 return 1;
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 39ab6687ce23..e1cada31356e 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -25,8 +25,6 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <linux/workqueue.h> 27#include <linux/workqueue.h>
28#include <linux/firmware.h>
29#include <linux/ihex.h>
30#include <linux/uaccess.h> 28#include <linux/uaccess.h>
31#include <linux/usb.h> 29#include <linux/usb.h>
32#include <linux/usb/serial.h> 30#include <linux/usb/serial.h>
@@ -675,8 +673,6 @@ static int keyspan_pda_fake_startup(struct usb_serial *serial)
675{ 673{
676 int response; 674 int response;
677 const char *fw_name; 675 const char *fw_name;
678 const struct ihex_binrec *record;
679 const struct firmware *fw;
680 676
681 /* download the firmware here ... */ 677 /* download the firmware here ... */
682 response = ezusb_fx1_set_reset(serial->dev, 1); 678 response = ezusb_fx1_set_reset(serial->dev, 1);
@@ -696,30 +692,15 @@ static int keyspan_pda_fake_startup(struct usb_serial *serial)
696 __func__); 692 __func__);
697 return -ENODEV; 693 return -ENODEV;
698 } 694 }
699 if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) { 695
696 if (ezusb_fx1_ihex_firmware_download(serial->dev, fw_name) < 0) {
700 dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n", 697 dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n",
701 fw_name); 698 fw_name);
702 return -ENOENT; 699 return -ENOENT;
703 } 700 }
704 record = (const struct ihex_binrec *)fw->data; 701
705 702 /* after downloading firmware Renumeration will occur in a
706 while (record) { 703 moment and the new device will bind to the real driver */
707 response = ezusb_writememory(serial->dev, be32_to_cpu(record->addr),
708 (unsigned char *)record->data,
709 be16_to_cpu(record->len), 0xa0);
710 if (response < 0) {
711 dev_err(&serial->dev->dev, "ezusb_writememory failed "
712 "for Keyspan PDA firmware (%d %04X %p %d)\n",
713 response, be32_to_cpu(record->addr),
714 record->data, be16_to_cpu(record->len));
715 break;
716 }
717 record = ihex_next_binrec(record);
718 }
719 release_firmware(fw);
720 /* bring device out of reset. Renumeration will occur in a moment
721 and the new device will bind to the real driver */
722 response = ezusb_fx1_set_reset(serial->dev, 0);
723 704
724 /* we want this device to fail to have a driver assigned to it. */ 705 /* we want this device to fail to have a driver assigned to it. */
725 return 1; 706 return 1;
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 8172ea3aead0..efa32bf5f758 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -33,8 +33,6 @@
33#include <linux/serial.h> 33#include <linux/serial.h>
34#include <linux/usb/serial.h> 34#include <linux/usb/serial.h>
35#include <linux/usb/ezusb.h> 35#include <linux/usb/ezusb.h>
36#include <linux/firmware.h>
37#include <linux/ihex.h>
38#include "whiteheat.h" /* WhiteHEAT specific commands */ 36#include "whiteheat.h" /* WhiteHEAT specific commands */
39 37
40#ifndef CMSPAR 38#ifndef CMSPAR
@@ -194,84 +192,15 @@ static int firm_report_tx_done(struct usb_serial_port *port);
194static int whiteheat_firmware_download(struct usb_serial *serial, 192static int whiteheat_firmware_download(struct usb_serial *serial,
195 const struct usb_device_id *id) 193 const struct usb_device_id *id)
196{ 194{
197 int response, ret = -ENOENT; 195 int response;
198 const struct firmware *loader_fw = NULL, *firmware_fw = NULL;
199 const struct ihex_binrec *record;
200 196
201 if (request_ihex_firmware(&firmware_fw, "whiteheat.fw", 197 response = ezusb_fx1_ihex_firmware_download(serial->dev, "whiteheat_loader.fw");
202 &serial->dev->dev)) { 198 if (response >= 0) {
203 dev_err(&serial->dev->dev, 199 response = ezusb_fx1_ihex_firmware_download(serial->dev, "whiteheat.fw");
204 "%s - request \"whiteheat.fw\" failed\n", __func__); 200 if (response >= 0)
205 goto out; 201 return 0;
206 }
207 if (request_ihex_firmware(&loader_fw, "whiteheat_loader.fw",
208 &serial->dev->dev)) {
209 dev_err(&serial->dev->dev,
210 "%s - request \"whiteheat_loader.fw\" failed\n",
211 __func__);
212 goto out;
213 }
214 ret = 0;
215 response = ezusb_fx1_set_reset(serial->dev, 1);
216
217 record = (const struct ihex_binrec *)loader_fw->data;
218 while (record) {
219 response = ezusb_writememory(serial->dev, be32_to_cpu(record->addr),
220 (unsigned char *)record->data,
221 be16_to_cpu(record->len), 0xa0);
222 if (response < 0) {
223 dev_err(&serial->dev->dev, "%s - ezusb_writememory "
224 "failed for loader (%d %04X %p %d)\n",
225 __func__, response, be32_to_cpu(record->addr),
226 record->data, be16_to_cpu(record->len));
227 break;
228 }
229 record = ihex_next_binrec(record);
230 }
231
232 response = ezusb_fx1_set_reset(serial->dev, 0);
233
234 record = (const struct ihex_binrec *)firmware_fw->data;
235 while (record && be32_to_cpu(record->addr) < 0x1b40)
236 record = ihex_next_binrec(record);
237 while (record) {
238 response = ezusb_writememory(serial->dev, be32_to_cpu(record->addr),
239 (unsigned char *)record->data,
240 be16_to_cpu(record->len), 0xa3);
241 if (response < 0) {
242 dev_err(&serial->dev->dev, "%s - ezusb_writememory "
243 "failed for first firmware step "
244 "(%d %04X %p %d)\n", __func__, response,
245 be32_to_cpu(record->addr), record->data,
246 be16_to_cpu(record->len));
247 break;
248 }
249 ++record;
250 }
251
252 response = ezusb_fx1_set_reset(serial->dev, 1);
253
254 record = (const struct ihex_binrec *)firmware_fw->data;
255 while (record && be32_to_cpu(record->addr) < 0x1b40) {
256 response = ezusb_writememory(serial->dev, be32_to_cpu(record->addr),
257 (unsigned char *)record->data,
258 be16_to_cpu(record->len), 0xa0);
259 if (response < 0) {
260 dev_err(&serial->dev->dev, "%s - ezusb_writememory "
261 "failed for second firmware step "
262 "(%d %04X %p %d)\n", __func__, response,
263 be32_to_cpu(record->addr), record->data,
264 be16_to_cpu(record->len));
265 break;
266 }
267 ++record;
268 } 202 }
269 ret = 0; 203 return -ENOENT;
270 response = ezusb_fx1_set_reset(serial->dev, 0);
271 out:
272 release_firmware(loader_fw);
273 release_firmware(firmware_fw);
274 return ret;
275} 204}
276 205
277 206