aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/keyspan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/keyspan.c')
-rw-r--r--drivers/usb/serial/keyspan.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 3df8a66c5c3c..11e439b90eac 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -105,6 +105,8 @@
105#include <linux/tty_flip.h> 105#include <linux/tty_flip.h>
106#include <linux/module.h> 106#include <linux/module.h>
107#include <linux/spinlock.h> 107#include <linux/spinlock.h>
108#include <linux/firmware.h>
109#include <linux/ihex.h>
108#include <asm/uaccess.h> 110#include <asm/uaccess.h>
109#include <linux/usb.h> 111#include <linux/usb.h>
110#include <linux/usb/serial.h> 112#include <linux/usb/serial.h>
@@ -1339,13 +1341,13 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
1339 port->tty = NULL; 1341 port->tty = NULL;
1340} 1342}
1341 1343
1342
1343 /* download the firmware to a pre-renumeration device */ 1344 /* download the firmware to a pre-renumeration device */
1344static int keyspan_fake_startup (struct usb_serial *serial) 1345static int keyspan_fake_startup (struct usb_serial *serial)
1345{ 1346{
1346 int response; 1347 int response;
1347 const struct ezusb_hex_record *record; 1348 const struct ihex_binrec *record;
1348 char *fw_name; 1349 char *fw_name;
1350 const struct firmware *fw;
1349 1351
1350 dbg("Keyspan startup version %04x product %04x", 1352 dbg("Keyspan startup version %04x product %04x",
1351 le16_to_cpu(serial->dev->descriptor.bcdDevice), 1353 le16_to_cpu(serial->dev->descriptor.bcdDevice),
@@ -1359,72 +1361,60 @@ static int keyspan_fake_startup (struct usb_serial *serial)
1359 /* Select firmware image on the basis of idProduct */ 1361 /* Select firmware image on the basis of idProduct */
1360 switch (le16_to_cpu(serial->dev->descriptor.idProduct)) { 1362 switch (le16_to_cpu(serial->dev->descriptor.idProduct)) {
1361 case keyspan_usa28_pre_product_id: 1363 case keyspan_usa28_pre_product_id:
1362 record = &keyspan_usa28_firmware[0]; 1364 fw_name = "keyspan/usa28.fw";
1363 fw_name = "USA28";
1364 break; 1365 break;
1365 1366
1366 case keyspan_usa28x_pre_product_id: 1367 case keyspan_usa28x_pre_product_id:
1367 record = &keyspan_usa28x_firmware[0]; 1368 fw_name = "keyspan/usa28x.fw";
1368 fw_name = "USA28X";
1369 break; 1369 break;
1370 1370
1371 case keyspan_usa28xa_pre_product_id: 1371 case keyspan_usa28xa_pre_product_id:
1372 record = &keyspan_usa28xa_firmware[0]; 1372 fw_name = "keyspan/usa28xa.fw";
1373 fw_name = "USA28XA";
1374 break; 1373 break;
1375 1374
1376 case keyspan_usa28xb_pre_product_id: 1375 case keyspan_usa28xb_pre_product_id:
1377 record = &keyspan_usa28xb_firmware[0]; 1376 fw_name = "keyspan/usa28xb.fw";
1378 fw_name = "USA28XB";
1379 break; 1377 break;
1380 1378
1381 case keyspan_usa19_pre_product_id: 1379 case keyspan_usa19_pre_product_id:
1382 record = &keyspan_usa19_firmware[0]; 1380 fw_name = "keyspan/usa19.fw";
1383 fw_name = "USA19";
1384 break; 1381 break;
1385 1382
1386 case keyspan_usa19qi_pre_product_id: 1383 case keyspan_usa19qi_pre_product_id:
1387 record = &keyspan_usa19qi_firmware[0]; 1384 fw_name = "keyspan/usa19qi.fw";
1388 fw_name = "USA19QI";
1389 break; 1385 break;
1390 1386
1391 case keyspan_mpr_pre_product_id: 1387 case keyspan_mpr_pre_product_id:
1392 record = &keyspan_mpr_firmware[0]; 1388 fw_name = "keyspan/mpr.fw";
1393 fw_name = "MPR";
1394 break; 1389 break;
1395 1390
1396 case keyspan_usa19qw_pre_product_id: 1391 case keyspan_usa19qw_pre_product_id:
1397 record = &keyspan_usa19qw_firmware[0]; 1392 fw_name = "keyspan/usa19qw.fw";
1398 fw_name = "USA19QI";
1399 break; 1393 break;
1400 1394
1401 case keyspan_usa18x_pre_product_id: 1395 case keyspan_usa18x_pre_product_id:
1402 record = &keyspan_usa18x_firmware[0]; 1396 fw_name = "keyspan/usa18x.fw";
1403 fw_name = "USA18X";
1404 break; 1397 break;
1405 1398
1406 case keyspan_usa19w_pre_product_id: 1399 case keyspan_usa19w_pre_product_id:
1407 record = &keyspan_usa19w_firmware[0]; 1400 fw_name = "keyspan/usa19w.fw";
1408 fw_name = "USA19W";
1409 break; 1401 break;
1410 1402
1411 case keyspan_usa49w_pre_product_id: 1403 case keyspan_usa49w_pre_product_id:
1412 record = &keyspan_usa49w_firmware[0]; 1404 fw_name = "keyspan/usa49w.fw";
1413 fw_name = "USA49W";
1414 break; 1405 break;
1415 1406
1416 case keyspan_usa49wlc_pre_product_id: 1407 case keyspan_usa49wlc_pre_product_id:
1417 record = &keyspan_usa49wlc_firmware[0]; 1408 fw_name = "keyspan/usa49wlc.fw";
1418 fw_name = "USA49WLC";
1419 break; 1409 break;
1420 1410
1421 default: 1411 default:
1422 record = NULL; 1412 dev_err(&serial->dev->dev, "Unknown product ID (%04x)\n",
1423 fw_name = "Unknown"; 1413 le16_to_cpu(serial->dev->descriptor.idProduct));
1424 break; 1414 return 1;
1425 } 1415 }
1426 1416
1427 if (record == NULL) { 1417 if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) {
1428 dev_err(&serial->dev->dev, "Required keyspan firmware image (%s) unavailable.\n", fw_name); 1418 dev_err(&serial->dev->dev, "Required keyspan firmware image (%s) unavailable.\n", fw_name);
1429 return(1); 1419 return(1);
1430 } 1420 }
@@ -1434,19 +1424,22 @@ static int keyspan_fake_startup (struct usb_serial *serial)
1434 /* download the firmware image */ 1424 /* download the firmware image */
1435 response = ezusb_set_reset(serial, 1); 1425 response = ezusb_set_reset(serial, 1);
1436 1426
1437 while(record->address != 0xffff) { 1427 record = (const struct ihex_binrec *)fw->data;
1438 response = ezusb_writememory(serial, record->address, 1428
1429 while (record) {
1430 response = ezusb_writememory(serial, be32_to_cpu(record->addr),
1439 (unsigned char *)record->data, 1431 (unsigned char *)record->data,
1440 record->data_size, 0xa0); 1432 be16_to_cpu(record->len), 0xa0);
1441 if (response < 0) { 1433 if (response < 0) {
1442 dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan" 1434 dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan"
1443 "firmware (%d %04X %p %d)\n", 1435 "firmware (%d %04X %p %d)\n",
1444 response, 1436 response, be32_to_cpu(record->addr),
1445 record->address, record->data, record->data_size); 1437 record->data, be16_to_cpu(record->len));
1446 break; 1438 break;
1447 } 1439 }
1448 record++; 1440 record = ihex_next_binrec(record);
1449 } 1441 }
1442 release_firmware(fw);
1450 /* bring device out of reset. Renumeration will occur in a 1443 /* bring device out of reset. Renumeration will occur in a
1451 moment and the new device will bind to the real driver */ 1444 moment and the new device will bind to the real driver */
1452 response = ezusb_set_reset(serial, 0); 1445 response = ezusb_set_reset(serial, 0);
@@ -2756,6 +2749,19 @@ MODULE_AUTHOR( DRIVER_AUTHOR );
2756MODULE_DESCRIPTION( DRIVER_DESC ); 2749MODULE_DESCRIPTION( DRIVER_DESC );
2757MODULE_LICENSE("GPL"); 2750MODULE_LICENSE("GPL");
2758 2751
2752MODULE_FIRMWARE("keyspan/usa28.fw");
2753MODULE_FIRMWARE("keyspan/usa28x.fw");
2754MODULE_FIRMWARE("keyspan/usa28xa.fw");
2755MODULE_FIRMWARE("keyspan/usa28xb.fw");
2756MODULE_FIRMWARE("keyspan/usa19.fw");
2757MODULE_FIRMWARE("keyspan/usa19qi.fw");
2758MODULE_FIRMWARE("keyspan/mpr.fw");
2759MODULE_FIRMWARE("keyspan/usa19qw.fw");
2760MODULE_FIRMWARE("keyspan/usa18x.fw");
2761MODULE_FIRMWARE("keyspan/usa19w.fw");
2762MODULE_FIRMWARE("keyspan/usa49w.fw");
2763MODULE_FIRMWARE("keyspan/usa49wlc.fw");
2764
2759module_param(debug, bool, S_IRUGO | S_IWUSR); 2765module_param(debug, bool, S_IRUGO | S_IWUSR);
2760MODULE_PARM_DESC(debug, "Debug enabled or not"); 2766MODULE_PARM_DESC(debug, "Debug enabled or not");
2761 2767