diff options
Diffstat (limited to 'drivers/usb/serial/whiteheat.c')
-rw-r--r-- | drivers/usb/serial/whiteheat.c | 77 |
1 files changed, 50 insertions, 27 deletions
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index f07e8a4c1f3d..665aa77a917b 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -81,7 +81,8 @@ | |||
81 | #include <linux/serial_reg.h> | 81 | #include <linux/serial_reg.h> |
82 | #include <linux/serial.h> | 82 | #include <linux/serial.h> |
83 | #include <linux/usb/serial.h> | 83 | #include <linux/usb/serial.h> |
84 | #include "whiteheat_fw.h" /* firmware for the ConnectTech WhiteHEAT device */ | 84 | #include <linux/firmware.h> |
85 | #include <linux/ihex.h> | ||
85 | #include "whiteheat.h" /* WhiteHEAT specific commands */ | 86 | #include "whiteheat.h" /* WhiteHEAT specific commands */ |
86 | 87 | ||
87 | static int debug; | 88 | static int debug; |
@@ -279,37 +280,52 @@ static int firm_report_tx_done(struct usb_serial_port *port); | |||
279 | */ | 280 | */ |
280 | static int whiteheat_firmware_download (struct usb_serial *serial, const struct usb_device_id *id) | 281 | static int whiteheat_firmware_download (struct usb_serial *serial, const struct usb_device_id *id) |
281 | { | 282 | { |
282 | int response; | 283 | int response, ret = -ENOENT; |
283 | const struct whiteheat_hex_record *record; | 284 | const struct firmware *loader_fw = NULL, *firmware_fw = NULL; |
284 | 285 | const struct ihex_binrec *record; | |
286 | |||
285 | dbg("%s", __func__); | 287 | dbg("%s", __func__); |
286 | 288 | ||
289 | if (request_ihex_firmware(&firmware_fw, "whiteheat.fw", | ||
290 | &serial->dev->dev)) { | ||
291 | err("%s - request \"whiteheat.fw\" failed", __func__); | ||
292 | goto out; | ||
293 | } | ||
294 | if (request_ihex_firmware(&loader_fw, "whiteheat_loader.fw", | ||
295 | &serial->dev->dev)) { | ||
296 | err("%s - request \"whiteheat_loader.fw\" failed", __func__); | ||
297 | goto out; | ||
298 | } | ||
299 | ret = 0; | ||
287 | response = ezusb_set_reset (serial, 1); | 300 | response = ezusb_set_reset (serial, 1); |
288 | 301 | ||
289 | record = &whiteheat_loader[0]; | 302 | record = (const struct ihex_binrec *)loader_fw->data; |
290 | while (record->address != 0xffff) { | 303 | while (record) { |
291 | response = ezusb_writememory (serial, record->address, | 304 | response = ezusb_writememory (serial, be32_to_cpu(record->addr), |
292 | (unsigned char *)record->data, record->data_size, 0xa0); | 305 | (unsigned char *)record->data, |
306 | be16_to_cpu(record->len), 0xa0); | ||
293 | if (response < 0) { | 307 | if (response < 0) { |
294 | err("%s - ezusb_writememory failed for loader (%d %04X %p %d)", | 308 | err("%s - ezusb_writememory failed for loader (%d %04X %p %d)", |
295 | __func__, response, record->address, record->data, record->data_size); | 309 | __func__, response, be32_to_cpu(record->addr), |
310 | record->data, be16_to_cpu(record->len)); | ||
296 | break; | 311 | break; |
297 | } | 312 | } |
298 | ++record; | 313 | record = ihex_next_binrec(record); |
299 | } | 314 | } |
300 | 315 | ||
301 | response = ezusb_set_reset (serial, 0); | 316 | response = ezusb_set_reset (serial, 0); |
302 | 317 | ||
303 | record = &whiteheat_firmware[0]; | 318 | record = (const struct ihex_binrec *)firmware_fw->data; |
304 | while (record->address < 0x1b40) { | 319 | while (record && be32_to_cpu(record->addr) < 0x1b40) |
305 | ++record; | 320 | record = ihex_next_binrec(record); |
306 | } | 321 | while (record) { |
307 | while (record->address != 0xffff) { | 322 | response = ezusb_writememory (serial, be32_to_cpu(record->addr), |
308 | response = ezusb_writememory (serial, record->address, | 323 | (unsigned char *)record->data, |
309 | (unsigned char *)record->data, record->data_size, 0xa3); | 324 | be16_to_cpu(record->len), 0xa3); |
310 | if (response < 0) { | 325 | if (response < 0) { |
311 | err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", | 326 | err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", |
312 | __func__, response, record->address, record->data, record->data_size); | 327 | __func__, response, be32_to_cpu(record->addr), |
328 | record->data, be16_to_cpu(record->len)); | ||
313 | break; | 329 | break; |
314 | } | 330 | } |
315 | ++record; | 331 | ++record; |
@@ -317,21 +333,25 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct | |||
317 | 333 | ||
318 | response = ezusb_set_reset (serial, 1); | 334 | response = ezusb_set_reset (serial, 1); |
319 | 335 | ||
320 | record = &whiteheat_firmware[0]; | 336 | record = (const struct ihex_binrec *)firmware_fw->data; |
321 | while (record->address < 0x1b40) { | 337 | while (record && be32_to_cpu(record->addr) < 0x1b40) { |
322 | response = ezusb_writememory (serial, record->address, | 338 | response = ezusb_writememory (serial, be32_to_cpu(record->addr), |
323 | (unsigned char *)record->data, record->data_size, 0xa0); | 339 | (unsigned char *)record->data, |
340 | be16_to_cpu(record->len), 0xa0); | ||
324 | if (response < 0) { | 341 | if (response < 0) { |
325 | err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", | 342 | err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", |
326 | __func__, response, record->address, record->data, record->data_size); | 343 | __func__, response, be32_to_cpu(record->addr), |
344 | record->data, be16_to_cpu(record->len)); | ||
327 | break; | 345 | break; |
328 | } | 346 | } |
329 | ++record; | 347 | ++record; |
330 | } | 348 | } |
331 | 349 | ret = 0; | |
332 | response = ezusb_set_reset (serial, 0); | 350 | response = ezusb_set_reset (serial, 0); |
333 | 351 | out: | |
334 | return 0; | 352 | release_firmware(loader_fw); |
353 | release_firmware(firmware_fw); | ||
354 | return ret; | ||
335 | } | 355 | } |
336 | 356 | ||
337 | 357 | ||
@@ -1503,6 +1523,9 @@ MODULE_AUTHOR( DRIVER_AUTHOR ); | |||
1503 | MODULE_DESCRIPTION( DRIVER_DESC ); | 1523 | MODULE_DESCRIPTION( DRIVER_DESC ); |
1504 | MODULE_LICENSE("GPL"); | 1524 | MODULE_LICENSE("GPL"); |
1505 | 1525 | ||
1526 | MODULE_FIRMWARE("whiteheat.fw"); | ||
1527 | MODULE_FIRMWARE("whiteheat_loader.fw"); | ||
1528 | |||
1506 | module_param(urb_pool_size, int, 0); | 1529 | module_param(urb_pool_size, int, 0); |
1507 | MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering"); | 1530 | MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering"); |
1508 | 1531 | ||