diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/ezusb.c | 79 | ||||
-rw-r--r-- | drivers/usb/serial/keyspan.c | 39 | ||||
-rw-r--r-- | drivers/usb/serial/keyspan_pda.c | 29 | ||||
-rw-r--r-- | drivers/usb/serial/whiteheat.c | 85 |
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 | ||
17 | struct ezusb_fx_type { | 19 | struct 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 | } |
81 | EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset); | 83 | EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset); |
84 | |||
85 | static 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); | ||
142 | out: | ||
143 | release_firmware(firmware); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | int 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 | } | ||
152 | EXPORT_SYMBOL_GPL(ezusb_fx1_ihex_firmware_download); | ||
153 | |||
154 | int 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 | } | ||
159 | EXPORT_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 */ |
1168 | static int keyspan_fake_startup(struct usb_serial *serial) | 1166 | static 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); | |||
194 | static int whiteheat_firmware_download(struct usb_serial *serial, | 192 | static 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 | ||