aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2005-11-09 18:49:04 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2005-12-13 20:11:16 -0500
commit5433383ef33ed40c9c8a86a4355da344234af2a5 (patch)
tree8d82c620fe6faadfa805fb465d5beb67946133c7 /drivers/scsi/qla2xxx/qla_os.c
parent26a68019c86e1d1782984a7a5babff762cde1501 (diff)
[SCSI] qla2xxx: Add full firmware(-request) hotplug support for all ISPs.
Transition driver to exclusively use the request_firmware() interfaces to retrieve firmware-blobs from user-space. This will be the default behaviour going forward until the embedded firmware-binary images are removed from the upstream kernel. Upon request, the driver caches the firmware image until the driver is unloaded. NOTE: The option is present to allow the user to continue to use the firmware-loader modules, but, should be considered deprecated. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Rejections fixed up and Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c156
1 files changed, 140 insertions, 16 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index c58c9d97b041..47db029b2fce 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -54,11 +54,6 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
54MODULE_PARM_DESC(ql2xloginretrycount, 54MODULE_PARM_DESC(ql2xloginretrycount,
55 "Specify an alternate value for the NVRAM login retry count."); 55 "Specify an alternate value for the NVRAM login retry count.");
56 56
57int ql2xfwloadbin=1;
58module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
59MODULE_PARM_DESC(ql2xfwloadbin,
60 "Load ISP2xxx firmware image via hotplug.");
61
62static void qla2x00_free_device(scsi_qla_host_t *); 57static void qla2x00_free_device(scsi_qla_host_t *);
63 58
64static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); 59static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha);
@@ -1261,12 +1256,16 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1261 char pci_info[20]; 1256 char pci_info[20];
1262 char fw_str[30]; 1257 char fw_str[30];
1263 fc_port_t *fcport; 1258 fc_port_t *fcport;
1259 struct scsi_host_template *sht;
1264 1260
1265 if (pci_enable_device(pdev)) 1261 if (pci_enable_device(pdev))
1266 goto probe_out; 1262 goto probe_out;
1267 1263
1268 host = scsi_host_alloc(brd_info->sht ? brd_info->sht: 1264 sht = &qla2x00_driver_template;
1269 &qla2x00_driver_template, sizeof(scsi_qla_host_t)); 1265 if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
1266 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
1267 sht = &qla24xx_driver_template;
1268 host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
1270 if (host == NULL) { 1269 if (host == NULL) {
1271 printk(KERN_WARNING 1270 printk(KERN_WARNING
1272 "qla2xxx: Couldn't allocate host from scsi layer!\n"); 1271 "qla2xxx: Couldn't allocate host from scsi layer!\n");
@@ -1291,8 +1290,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1291 goto probe_failed; 1290 goto probe_failed;
1292 1291
1293 qla_printk(KERN_INFO, ha, 1292 qla_printk(KERN_INFO, ha,
1294 "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name, 1293 "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq,
1295 pdev->irq, ha->iobase); 1294 ha->iobase);
1296 1295
1297 spin_lock_init(&ha->hardware_lock); 1296 spin_lock_init(&ha->hardware_lock);
1298 1297
@@ -1368,9 +1367,11 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1368 ha->isp_ops.reset_adapter = qla24xx_reset_adapter; 1367 ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
1369 ha->isp_ops.nvram_config = qla24xx_nvram_config; 1368 ha->isp_ops.nvram_config = qla24xx_nvram_config;
1370 ha->isp_ops.update_fw_options = qla24xx_update_fw_options; 1369 ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
1370#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
1371 ha->isp_ops.load_risc = qla24xx_load_risc_flash; 1371 ha->isp_ops.load_risc = qla24xx_load_risc_flash;
1372 if (ql2xfwloadbin) 1372#else
1373 ha->isp_ops.load_risc = qla24xx_load_risc_hotplug; 1373 ha->isp_ops.load_risc = qla24xx_load_risc;
1374#endif
1374 ha->isp_ops.pci_info_str = qla24xx_pci_info_str; 1375 ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
1375 ha->isp_ops.fw_version_str = qla24xx_fw_version_str; 1376 ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
1376 ha->isp_ops.intr_handler = qla24xx_intr_handler; 1377 ha->isp_ops.intr_handler = qla24xx_intr_handler;
@@ -1531,11 +1532,12 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1531 qla_printk(KERN_INFO, ha, "\n" 1532 qla_printk(KERN_INFO, ha, "\n"
1532 " QLogic Fibre Channel HBA Driver: %s\n" 1533 " QLogic Fibre Channel HBA Driver: %s\n"
1533 " QLogic %s - %s\n" 1534 " QLogic %s - %s\n"
1534 " %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str, 1535 " ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n",
1535 ha->model_number, ha->model_desc ? ha->model_desc: "", 1536 qla2x00_version_str, ha->model_number,
1536 ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info), 1537 ha->model_desc ? ha->model_desc: "", pdev->device,
1537 pci_name(pdev), ha->flags.enable_64bit_addressing ? '+': '-', 1538 ha->isp_ops.pci_info_str(ha, pci_info), pci_name(pdev),
1538 ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str)); 1539 ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
1540 ha->isp_ops.fw_version_str(ha, fw_str));
1539 1541
1540 /* Go with fc_rport registration. */ 1542 /* Go with fc_rport registration. */
1541 list_for_each_entry(fcport, &ha->fcports, list) 1543 list_for_each_entry(fcport, &ha->fcports, list)
@@ -2483,6 +2485,10 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
2483 return -ETIMEDOUT; 2485 return -ETIMEDOUT;
2484} 2486}
2485 2487
2488#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
2489
2490#define qla2x00_release_firmware() do { } while (0)
2491
2486static struct qla_board_info qla_board_tbl[] = { 2492static struct qla_board_info qla_board_tbl[] = {
2487 { 2493 {
2488 .drv_name = "qla2400", 2494 .drv_name = "qla2400",
@@ -2530,8 +2536,122 @@ qla2xxx_remove_one(struct pci_dev *pdev)
2530 qla2x00_remove_one(pdev); 2536 qla2x00_remove_one(pdev);
2531} 2537}
2532 2538
2539#else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
2540
2541/* Firmware interface routines. */
2542
2543#define FW_BLOBS 6
2544#define FW_ISP21XX 0
2545#define FW_ISP22XX 1
2546#define FW_ISP2300 2
2547#define FW_ISP2322 3
2548#define FW_ISP63XX 4
2549#define FW_ISP24XX 5
2550
2551static DECLARE_MUTEX(qla_fw_lock);
2552
2553static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
2554 { .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, },
2555 { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
2556 { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
2557 { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
2558 { .name = "ql6312_fw.bin", .segs = { 0x800, 0 }, },
2559 { .name = "ql2400_fw.bin", },
2560};
2561
2562struct fw_blob *
2563qla2x00_request_firmware(scsi_qla_host_t *ha)
2564{
2565 struct fw_blob *blob;
2566
2567 blob = NULL;
2568 if (IS_QLA2100(ha)) {
2569 blob = &qla_fw_blobs[FW_ISP21XX];
2570 } else if (IS_QLA2200(ha)) {
2571 blob = &qla_fw_blobs[FW_ISP22XX];
2572 } else if (IS_QLA2300(ha) || IS_QLA2312(ha)) {
2573 blob = &qla_fw_blobs[FW_ISP2300];
2574 } else if (IS_QLA2322(ha)) {
2575 blob = &qla_fw_blobs[FW_ISP2322];
2576 } else if (IS_QLA6312(ha) || IS_QLA6322(ha)) {
2577 blob = &qla_fw_blobs[FW_ISP63XX];
2578 } else if (IS_QLA24XX(ha)) {
2579 blob = &qla_fw_blobs[FW_ISP24XX];
2580 }
2581
2582 down(&qla_fw_lock);
2583 if (blob->fw)
2584 goto out;
2585
2586 if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) {
2587 DEBUG2(printk("scsi(%ld): Failed to load firmware image "
2588 "(%s).\n", ha->host_no, blob->name));
2589 blob->fw = NULL;
2590 blob = NULL;
2591 goto out;
2592 }
2593
2594out:
2595 up(&qla_fw_lock);
2596 return blob;
2597}
2598
2599static void
2600qla2x00_release_firmware(void)
2601{
2602 int idx;
2603
2604 down(&qla_fw_lock);
2605 for (idx = 0; idx < FW_BLOBS; idx++)
2606 if (qla_fw_blobs[idx].fw)
2607 release_firmware(qla_fw_blobs[idx].fw);
2608 up(&qla_fw_lock);
2609}
2610
2611static struct qla_board_info qla_board_tbl = {
2612 .drv_name = "qla2xxx",
2613};
2614
2615static struct pci_device_id qla2xxx_pci_tbl[] = {
2616 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100,
2617 PCI_ANY_ID, PCI_ANY_ID, },
2618 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200,
2619 PCI_ANY_ID, PCI_ANY_ID, },
2620 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300,
2621 PCI_ANY_ID, PCI_ANY_ID, },
2622 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312,
2623 PCI_ANY_ID, PCI_ANY_ID, },
2624 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322,
2625 PCI_ANY_ID, PCI_ANY_ID, },
2626 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312,
2627 PCI_ANY_ID, PCI_ANY_ID, },
2628 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322,
2629 PCI_ANY_ID, PCI_ANY_ID, },
2630 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422,
2631 PCI_ANY_ID, PCI_ANY_ID, },
2632 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432,
2633 PCI_ANY_ID, PCI_ANY_ID, },
2634 { 0 },
2635};
2636MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
2637
2638static int __devinit
2639qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2640{
2641 return qla2x00_probe_one(pdev, &qla_board_tbl);
2642}
2643
2644static void __devexit
2645qla2xxx_remove_one(struct pci_dev *pdev)
2646{
2647 qla2x00_remove_one(pdev);
2648}
2649
2650#endif
2651
2533static struct pci_driver qla2xxx_pci_driver = { 2652static struct pci_driver qla2xxx_pci_driver = {
2534 .name = "qla2xxx", 2653 .name = "qla2xxx",
2654 .owner = THIS_MODULE,
2535 .id_table = qla2xxx_pci_tbl, 2655 .id_table = qla2xxx_pci_tbl,
2536 .probe = qla2xxx_probe_one, 2656 .probe = qla2xxx_probe_one,
2537 .remove = __devexit_p(qla2xxx_remove_one), 2657 .remove = __devexit_p(qla2xxx_remove_one),
@@ -2556,6 +2676,9 @@ qla2x00_module_init(void)
2556 2676
2557 /* Derive version string. */ 2677 /* Derive version string. */
2558 strcpy(qla2x00_version_str, QLA2XXX_VERSION); 2678 strcpy(qla2x00_version_str, QLA2XXX_VERSION);
2679#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
2680 strcat(qla2x00_version_str, "-fw");
2681#endif
2559#if DEBUG_QLA2100 2682#if DEBUG_QLA2100
2560 strcat(qla2x00_version_str, "-debug"); 2683 strcat(qla2x00_version_str, "-debug");
2561#endif 2684#endif
@@ -2580,6 +2703,7 @@ static void __exit
2580qla2x00_module_exit(void) 2703qla2x00_module_exit(void)
2581{ 2704{
2582 pci_unregister_driver(&qla2xxx_pci_driver); 2705 pci_unregister_driver(&qla2xxx_pci_driver);
2706 qla2x00_release_firmware();
2583 kmem_cache_destroy(srb_cachep); 2707 kmem_cache_destroy(srb_cachep);
2584 fc_release_transport(qla2xxx_transport_template); 2708 fc_release_transport(qla2xxx_transport_template);
2585} 2709}