aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/whiteheat.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/whiteheat.c')
-rw-r--r--drivers/usb/serial/whiteheat.c77
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
87static int debug; 88static int debug;
@@ -279,37 +280,52 @@ static int firm_report_tx_done(struct usb_serial_port *port);
279*/ 280*/
280static int whiteheat_firmware_download (struct usb_serial *serial, const struct usb_device_id *id) 281static 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 );
1503MODULE_DESCRIPTION( DRIVER_DESC ); 1523MODULE_DESCRIPTION( DRIVER_DESC );
1504MODULE_LICENSE("GPL"); 1524MODULE_LICENSE("GPL");
1505 1525
1526MODULE_FIRMWARE("whiteheat.fw");
1527MODULE_FIRMWARE("whiteheat_loader.fw");
1528
1506module_param(urb_pool_size, int, 0); 1529module_param(urb_pool_size, int, 0);
1507MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering"); 1530MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering");
1508 1531