diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2005-11-09 18:49:19 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-12-13 20:11:19 -0500 |
commit | 331e34768657ead5a5b169337351e045305cafcb (patch) | |
tree | 952cb2dc4cb8ba3966d2de18e9830f3ca99f1464 /drivers/scsi | |
parent | 5433383ef33ed40c9c8a86a4355da344234af2a5 (diff) |
[SCSI] qla2xxx: Add support for embedded ISP24xx firmware.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla2xxx/Makefile | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/ql2400.c | 111 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 61 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 82 |
4 files changed, 202 insertions, 55 deletions
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile index 549dfe410208..40c0de125889 100644 --- a/drivers/scsi/qla2xxx/Makefile +++ b/drivers/scsi/qla2xxx/Makefile | |||
@@ -10,10 +10,11 @@ qla2200-y := ql2200.o ql2200_fw.o | |||
10 | qla2300-y := ql2300.o ql2300_fw.o | 10 | qla2300-y := ql2300.o ql2300_fw.o |
11 | qla2322-y := ql2322.o ql2322_fw.o | 11 | qla2322-y := ql2322.o ql2322_fw.o |
12 | qla6312-y := ql6312.o ql6312_fw.o | 12 | qla6312-y := ql6312.o ql6312_fw.o |
13 | qla2400-y := ql2400.o ql2400_fw.o | ||
13 | 14 | ||
14 | obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o | 15 | obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o |
15 | obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o | 16 | obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o |
16 | obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o | 17 | obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o |
17 | obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o | 18 | obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o |
18 | obj-$(CONFIG_SCSI_QLA6312) += qla2xxx.o qla6312.o | 19 | obj-$(CONFIG_SCSI_QLA6312) += qla2xxx.o qla6312.o |
19 | obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o | 20 | obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o |
diff --git a/drivers/scsi/qla2xxx/ql2400.c b/drivers/scsi/qla2xxx/ql2400.c new file mode 100644 index 000000000000..6c7165f47e29 --- /dev/null +++ b/drivers/scsi/qla2xxx/ql2400.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * QLogic Fibre Channel HBA Driver | ||
3 | * Copyright (c) 2003-2005 QLogic Corporation | ||
4 | * | ||
5 | * See LICENSE.qla2xxx for copyright and licensing details. | ||
6 | */ | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/pci.h> | ||
10 | |||
11 | #include "qla_def.h" | ||
12 | |||
13 | static char qla_driver_name[] = "qla2400"; | ||
14 | |||
15 | extern uint32_t fw2400_version_str[]; | ||
16 | extern uint32_t fw2400_addr01; | ||
17 | extern uint32_t fw2400_code01[]; | ||
18 | extern uint32_t fw2400_length01; | ||
19 | extern uint32_t fw2400_addr02; | ||
20 | extern uint32_t fw2400_code02[]; | ||
21 | extern uint32_t fw2400_length02; | ||
22 | |||
23 | static struct qla_fw_info qla_fw_tbl[] = { | ||
24 | { | ||
25 | .addressing = FW_INFO_ADDR_EXTENDED, | ||
26 | .fwcode = (unsigned short *)&fw2400_code01[0], | ||
27 | .fwlen = (unsigned short *)&fw2400_length01, | ||
28 | .lfwstart = (unsigned long *)&fw2400_addr01, | ||
29 | }, | ||
30 | { | ||
31 | .addressing = FW_INFO_ADDR_EXTENDED, | ||
32 | .fwcode = (unsigned short *)&fw2400_code02[0], | ||
33 | .fwlen = (unsigned short *)&fw2400_length02, | ||
34 | .lfwstart = (unsigned long *)&fw2400_addr02, | ||
35 | }, | ||
36 | { FW_INFO_ADDR_NOMORE, }, | ||
37 | }; | ||
38 | |||
39 | static struct qla_board_info qla_board_tbl[] = { | ||
40 | { | ||
41 | .drv_name = qla_driver_name, | ||
42 | .isp_name = "ISP2422", | ||
43 | .fw_info = qla_fw_tbl, | ||
44 | .fw_fname = "ql2400_fw.bin", | ||
45 | }, | ||
46 | { | ||
47 | .drv_name = qla_driver_name, | ||
48 | .isp_name = "ISP2432", | ||
49 | .fw_info = qla_fw_tbl, | ||
50 | .fw_fname = "ql2400_fw.bin", | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | static struct pci_device_id qla24xx_pci_tbl[] = { | ||
55 | { | ||
56 | .vendor = PCI_VENDOR_ID_QLOGIC, | ||
57 | .device = PCI_DEVICE_ID_QLOGIC_ISP2422, | ||
58 | .subvendor = PCI_ANY_ID, | ||
59 | .subdevice = PCI_ANY_ID, | ||
60 | .driver_data = (unsigned long)&qla_board_tbl[0], | ||
61 | }, | ||
62 | { | ||
63 | .vendor = PCI_VENDOR_ID_QLOGIC, | ||
64 | .device = PCI_DEVICE_ID_QLOGIC_ISP2432, | ||
65 | .subvendor = PCI_ANY_ID, | ||
66 | .subdevice = PCI_ANY_ID, | ||
67 | .driver_data = (unsigned long)&qla_board_tbl[1], | ||
68 | }, | ||
69 | {0, 0}, | ||
70 | }; | ||
71 | MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl); | ||
72 | |||
73 | static int __devinit | ||
74 | qla24xx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
75 | { | ||
76 | return qla2x00_probe_one(pdev, | ||
77 | (struct qla_board_info *)id->driver_data); | ||
78 | } | ||
79 | |||
80 | static void __devexit | ||
81 | qla24xx_remove_one(struct pci_dev *pdev) | ||
82 | { | ||
83 | qla2x00_remove_one(pdev); | ||
84 | } | ||
85 | |||
86 | static struct pci_driver qla24xx_pci_driver = { | ||
87 | .name = "qla2400", | ||
88 | .id_table = qla24xx_pci_tbl, | ||
89 | .probe = qla24xx_probe_one, | ||
90 | .remove = __devexit_p(qla24xx_remove_one), | ||
91 | }; | ||
92 | |||
93 | static int __init | ||
94 | qla24xx_init(void) | ||
95 | { | ||
96 | return pci_module_init(&qla24xx_pci_driver); | ||
97 | } | ||
98 | |||
99 | static void __exit | ||
100 | qla24xx_exit(void) | ||
101 | { | ||
102 | pci_unregister_driver(&qla24xx_pci_driver); | ||
103 | } | ||
104 | |||
105 | module_init(qla24xx_init); | ||
106 | module_exit(qla24xx_exit); | ||
107 | |||
108 | MODULE_AUTHOR("QLogic Corporation"); | ||
109 | MODULE_DESCRIPTION("QLogic ISP24xx FC-SCSI Host Bus Adapter driver"); | ||
110 | MODULE_LICENSE("GPL"); | ||
111 | MODULE_VERSION(QLA2XXX_VERSION); | ||
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 13e2aaf56769..dadc91bd0ea9 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -3550,6 +3550,67 @@ qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3550 | } | 3550 | } |
3551 | 3551 | ||
3552 | int | 3552 | int |
3553 | qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) | ||
3554 | { | ||
3555 | int rval, num, i; | ||
3556 | uint32_t cnt; | ||
3557 | uint32_t *risc_code; | ||
3558 | uint32_t risc_addr, risc_size; | ||
3559 | uint32_t *req_ring; | ||
3560 | struct qla_fw_info *fw_iter; | ||
3561 | |||
3562 | rval = QLA_SUCCESS; | ||
3563 | |||
3564 | /* Load firmware sequences */ | ||
3565 | fw_iter = ha->brd_info->fw_info; | ||
3566 | *srisc_addr = *((uint32_t *)fw_iter->lfwstart); | ||
3567 | while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) { | ||
3568 | risc_code = (uint32_t *)fw_iter->fwcode; | ||
3569 | risc_size = *((uint32_t *)fw_iter->fwlen); | ||
3570 | risc_addr = *((uint32_t *)fw_iter->lfwstart); | ||
3571 | |||
3572 | num = 0; | ||
3573 | rval = 0; | ||
3574 | while (risc_size > 0 && !rval) { | ||
3575 | cnt = (uint32_t)(ha->fw_transfer_size >> 2); | ||
3576 | if (cnt > risc_size) | ||
3577 | cnt = risc_size; | ||
3578 | |||
3579 | DEBUG7(printk("scsi(%ld): Loading risc segment@ " | ||
3580 | "addr %p, number of bytes 0x%x, offset 0x%lx.\n", | ||
3581 | ha->host_no, risc_code, cnt, risc_addr)); | ||
3582 | |||
3583 | req_ring = (uint32_t *)ha->request_ring; | ||
3584 | for (i = 0; i < cnt; i++) | ||
3585 | req_ring[i] = cpu_to_le32(risc_code[i]); | ||
3586 | |||
3587 | rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr, | ||
3588 | cnt); | ||
3589 | if (rval) { | ||
3590 | DEBUG(printk("scsi(%ld): [ERROR] Failed to " | ||
3591 | "load segment %d of firmware\n", | ||
3592 | ha->host_no, num)); | ||
3593 | qla_printk(KERN_WARNING, ha, | ||
3594 | "[ERROR] Failed to load segment %d of " | ||
3595 | "firmware\n", num); | ||
3596 | |||
3597 | qla2x00_dump_regs(ha); | ||
3598 | break; | ||
3599 | } | ||
3600 | |||
3601 | risc_code += cnt; | ||
3602 | risc_addr += cnt; | ||
3603 | risc_size -= cnt; | ||
3604 | num++; | ||
3605 | } | ||
3606 | |||
3607 | /* Next firmware sequence */ | ||
3608 | fw_iter++; | ||
3609 | } | ||
3610 | return rval; | ||
3611 | } | ||
3612 | |||
3613 | int | ||
3553 | qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) | 3614 | qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) |
3554 | { | 3615 | { |
3555 | int rval; | 3616 | int rval; |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 47db029b2fce..41d2aeee0963 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -54,6 +54,13 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR); | |||
54 | MODULE_PARM_DESC(ql2xloginretrycount, | 54 | MODULE_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 | ||
57 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) | ||
58 | int ql2xfwloadflash; | ||
59 | module_param(ql2xfwloadflash, int, S_IRUGO|S_IRUSR); | ||
60 | MODULE_PARM_DESC(ql2xfwloadflash, | ||
61 | "Load ISP24xx firmware image from FLASH (onboard memory)."); | ||
62 | #endif | ||
63 | |||
57 | static void qla2x00_free_device(scsi_qla_host_t *); | 64 | static void qla2x00_free_device(scsi_qla_host_t *); |
58 | 65 | ||
59 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); | 66 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); |
@@ -1367,10 +1374,10 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1367 | ha->isp_ops.reset_adapter = qla24xx_reset_adapter; | 1374 | ha->isp_ops.reset_adapter = qla24xx_reset_adapter; |
1368 | ha->isp_ops.nvram_config = qla24xx_nvram_config; | 1375 | ha->isp_ops.nvram_config = qla24xx_nvram_config; |
1369 | ha->isp_ops.update_fw_options = qla24xx_update_fw_options; | 1376 | 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; | ||
1372 | #else | ||
1373 | ha->isp_ops.load_risc = qla24xx_load_risc; | 1377 | ha->isp_ops.load_risc = qla24xx_load_risc; |
1378 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) | ||
1379 | if (ql2xfwloadflash) | ||
1380 | ha->isp_ops.load_risc = qla24xx_load_risc_flash; | ||
1374 | #endif | 1381 | #endif |
1375 | ha->isp_ops.pci_info_str = qla24xx_pci_info_str; | 1382 | ha->isp_ops.pci_info_str = qla24xx_pci_info_str; |
1376 | ha->isp_ops.fw_version_str = qla24xx_fw_version_str; | 1383 | ha->isp_ops.fw_version_str = qla24xx_fw_version_str; |
@@ -2488,53 +2495,8 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) | |||
2488 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) | 2495 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) |
2489 | 2496 | ||
2490 | #define qla2x00_release_firmware() do { } while (0) | 2497 | #define qla2x00_release_firmware() do { } while (0) |
2491 | 2498 | #define qla2x00_pci_module_init() (0) | |
2492 | static struct qla_board_info qla_board_tbl[] = { | 2499 | #define qla2x00_pci_module_exit() do { } while (0) |
2493 | { | ||
2494 | .drv_name = "qla2400", | ||
2495 | .isp_name = "ISP2422", | ||
2496 | .fw_fname = "ql2400_fw.bin", | ||
2497 | .sht = &qla24xx_driver_template, | ||
2498 | }, | ||
2499 | { | ||
2500 | .drv_name = "qla2400", | ||
2501 | .isp_name = "ISP2432", | ||
2502 | .fw_fname = "ql2400_fw.bin", | ||
2503 | .sht = &qla24xx_driver_template, | ||
2504 | }, | ||
2505 | }; | ||
2506 | |||
2507 | static struct pci_device_id qla2xxx_pci_tbl[] = { | ||
2508 | { | ||
2509 | .vendor = PCI_VENDOR_ID_QLOGIC, | ||
2510 | .device = PCI_DEVICE_ID_QLOGIC_ISP2422, | ||
2511 | .subvendor = PCI_ANY_ID, | ||
2512 | .subdevice = PCI_ANY_ID, | ||
2513 | .driver_data = (unsigned long)&qla_board_tbl[0], | ||
2514 | }, | ||
2515 | { | ||
2516 | .vendor = PCI_VENDOR_ID_QLOGIC, | ||
2517 | .device = PCI_DEVICE_ID_QLOGIC_ISP2432, | ||
2518 | .subvendor = PCI_ANY_ID, | ||
2519 | .subdevice = PCI_ANY_ID, | ||
2520 | .driver_data = (unsigned long)&qla_board_tbl[1], | ||
2521 | }, | ||
2522 | {0, 0}, | ||
2523 | }; | ||
2524 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); | ||
2525 | |||
2526 | static int __devinit | ||
2527 | qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
2528 | { | ||
2529 | return qla2x00_probe_one(pdev, | ||
2530 | (struct qla_board_info *)id->driver_data); | ||
2531 | } | ||
2532 | |||
2533 | static void __devexit | ||
2534 | qla2xxx_remove_one(struct pci_dev *pdev) | ||
2535 | { | ||
2536 | qla2x00_remove_one(pdev); | ||
2537 | } | ||
2538 | 2500 | ||
2539 | #else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */ | 2501 | #else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */ |
2540 | 2502 | ||
@@ -2647,8 +2609,6 @@ qla2xxx_remove_one(struct pci_dev *pdev) | |||
2647 | qla2x00_remove_one(pdev); | 2609 | qla2x00_remove_one(pdev); |
2648 | } | 2610 | } |
2649 | 2611 | ||
2650 | #endif | ||
2651 | |||
2652 | static struct pci_driver qla2xxx_pci_driver = { | 2612 | static struct pci_driver qla2xxx_pci_driver = { |
2653 | .name = "qla2xxx", | 2613 | .name = "qla2xxx", |
2654 | .owner = THIS_MODULE, | 2614 | .owner = THIS_MODULE, |
@@ -2657,6 +2617,20 @@ static struct pci_driver qla2xxx_pci_driver = { | |||
2657 | .remove = __devexit_p(qla2xxx_remove_one), | 2617 | .remove = __devexit_p(qla2xxx_remove_one), |
2658 | }; | 2618 | }; |
2659 | 2619 | ||
2620 | static inline int | ||
2621 | qla2x00_pci_module_init(void) | ||
2622 | { | ||
2623 | return pci_module_init(&qla2xxx_pci_driver); | ||
2624 | } | ||
2625 | |||
2626 | static inline void | ||
2627 | qla2x00_pci_module_exit(void) | ||
2628 | { | ||
2629 | pci_unregister_driver(&qla2xxx_pci_driver); | ||
2630 | } | ||
2631 | |||
2632 | #endif | ||
2633 | |||
2660 | /** | 2634 | /** |
2661 | * qla2x00_module_init - Module initialization. | 2635 | * qla2x00_module_init - Module initialization. |
2662 | **/ | 2636 | **/ |
@@ -2688,7 +2662,7 @@ qla2x00_module_init(void) | |||
2688 | return -ENODEV; | 2662 | return -ENODEV; |
2689 | 2663 | ||
2690 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); | 2664 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); |
2691 | ret = pci_module_init(&qla2xxx_pci_driver); | 2665 | ret = qla2x00_pci_module_init(); |
2692 | if (ret) { | 2666 | if (ret) { |
2693 | kmem_cache_destroy(srb_cachep); | 2667 | kmem_cache_destroy(srb_cachep); |
2694 | fc_release_transport(qla2xxx_transport_template); | 2668 | fc_release_transport(qla2xxx_transport_template); |
@@ -2702,7 +2676,7 @@ qla2x00_module_init(void) | |||
2702 | static void __exit | 2676 | static void __exit |
2703 | qla2x00_module_exit(void) | 2677 | qla2x00_module_exit(void) |
2704 | { | 2678 | { |
2705 | pci_unregister_driver(&qla2xxx_pci_driver); | 2679 | qla2x00_pci_module_exit(); |
2706 | qla2x00_release_firmware(); | 2680 | qla2x00_release_firmware(); |
2707 | kmem_cache_destroy(srb_cachep); | 2681 | kmem_cache_destroy(srb_cachep); |
2708 | fc_release_transport(qla2xxx_transport_template); | 2682 | fc_release_transport(qla2xxx_transport_template); |