summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2005-11-10 02:49:19 +0300
committerJames Bottomley <jejb@mulgrave.(none)>2005-12-14 04:11:19 +0300
commit331e34768657ead5a5b169337351e045305cafcb (patch)
tree952cb2dc4cb8ba3966d2de18e9830f3ca99f1464 /drivers/scsi
parent5433383ef33ed40c9c8a86a4355da344234af2a5 (diff)
downloadlinux-331e34768657ead5a5b169337351e045305cafcb.tar.xz
[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/Makefile3
-rw-r--r--drivers/scsi/qla2xxx/ql2400.c111
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c61
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c82
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
qla2300-y := ql2300.o ql2300_fw.o
qla2322-y := ql2322.o ql2322_fw.o
qla6312-y := ql6312.o ql6312_fw.o
+qla2400-y := ql2400.o ql2400_fw.o
obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o
obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o
obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o
obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o
obj-$(CONFIG_SCSI_QLA6312) += qla2xxx.o qla6312.o
-obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o
+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 @@
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "qla_def.h"
+
+static char qla_driver_name[] = "qla2400";
+
+extern uint32_t fw2400_version_str[];
+extern uint32_t fw2400_addr01;
+extern uint32_t fw2400_code01[];
+extern uint32_t fw2400_length01;
+extern uint32_t fw2400_addr02;
+extern uint32_t fw2400_code02[];
+extern uint32_t fw2400_length02;
+
+static struct qla_fw_info qla_fw_tbl[] = {
+ {
+ .addressing = FW_INFO_ADDR_EXTENDED,
+ .fwcode = (unsigned short *)&fw2400_code01[0],
+ .fwlen = (unsigned short *)&fw2400_length01,
+ .lfwstart = (unsigned long *)&fw2400_addr01,
+ },
+ {
+ .addressing = FW_INFO_ADDR_EXTENDED,
+ .fwcode = (unsigned short *)&fw2400_code02[0],
+ .fwlen = (unsigned short *)&fw2400_length02,
+ .lfwstart = (unsigned long *)&fw2400_addr02,
+ },
+ { FW_INFO_ADDR_NOMORE, },
+};
+
+static struct qla_board_info qla_board_tbl[] = {
+ {
+ .drv_name = qla_driver_name,
+ .isp_name = "ISP2422",
+ .fw_info = qla_fw_tbl,
+ .fw_fname = "ql2400_fw.bin",
+ },
+ {
+ .drv_name = qla_driver_name,
+ .isp_name = "ISP2432",
+ .fw_info = qla_fw_tbl,
+ .fw_fname = "ql2400_fw.bin",
+ },
+};
+
+static struct pci_device_id qla24xx_pci_tbl[] = {
+ {
+ .vendor = PCI_VENDOR_ID_QLOGIC,
+ .device = PCI_DEVICE_ID_QLOGIC_ISP2422,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long)&qla_board_tbl[0],
+ },
+ {
+ .vendor = PCI_VENDOR_ID_QLOGIC,
+ .device = PCI_DEVICE_ID_QLOGIC_ISP2432,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long)&qla_board_tbl[1],
+ },
+ {0, 0},
+};
+MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl);
+
+static int __devinit
+qla24xx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ return qla2x00_probe_one(pdev,
+ (struct qla_board_info *)id->driver_data);
+}
+
+static void __devexit
+qla24xx_remove_one(struct pci_dev *pdev)
+{
+ qla2x00_remove_one(pdev);
+}
+
+static struct pci_driver qla24xx_pci_driver = {
+ .name = "qla2400",
+ .id_table = qla24xx_pci_tbl,
+ .probe = qla24xx_probe_one,
+ .remove = __devexit_p(qla24xx_remove_one),
+};
+
+static int __init
+qla24xx_init(void)
+{
+ return pci_module_init(&qla24xx_pci_driver);
+}
+
+static void __exit
+qla24xx_exit(void)
+{
+ pci_unregister_driver(&qla24xx_pci_driver);
+}
+
+module_init(qla24xx_init);
+module_exit(qla24xx_exit);
+
+MODULE_AUTHOR("QLogic Corporation");
+MODULE_DESCRIPTION("QLogic ISP24xx FC-SCSI Host Bus Adapter driver");
+MODULE_LICENSE("GPL");
+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)
}
int
+qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+ int rval, num, i;
+ uint32_t cnt;
+ uint32_t *risc_code;
+ uint32_t risc_addr, risc_size;
+ uint32_t *req_ring;
+ struct qla_fw_info *fw_iter;
+
+ rval = QLA_SUCCESS;
+
+ /* Load firmware sequences */
+ fw_iter = ha->brd_info->fw_info;
+ *srisc_addr = *((uint32_t *)fw_iter->lfwstart);
+ while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) {
+ risc_code = (uint32_t *)fw_iter->fwcode;
+ risc_size = *((uint32_t *)fw_iter->fwlen);
+ risc_addr = *((uint32_t *)fw_iter->lfwstart);
+
+ num = 0;
+ rval = 0;
+ while (risc_size > 0 && !rval) {
+ cnt = (uint32_t)(ha->fw_transfer_size >> 2);
+ if (cnt > risc_size)
+ cnt = risc_size;
+
+ DEBUG7(printk("scsi(%ld): Loading risc segment@ "
+ "addr %p, number of bytes 0x%x, offset 0x%lx.\n",
+ ha->host_no, risc_code, cnt, risc_addr));
+
+ req_ring = (uint32_t *)ha->request_ring;
+ for (i = 0; i < cnt; i++)
+ req_ring[i] = cpu_to_le32(risc_code[i]);
+
+ rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+ cnt);
+ if (rval) {
+ DEBUG(printk("scsi(%ld): [ERROR] Failed to "
+ "load segment %d of firmware\n",
+ ha->host_no, num));
+ qla_printk(KERN_WARNING, ha,
+ "[ERROR] Failed to load segment %d of "
+ "firmware\n", num);
+
+ qla2x00_dump_regs(ha);
+ break;
+ }
+
+ risc_code += cnt;
+ risc_addr += cnt;
+ risc_size -= cnt;
+ num++;
+ }
+
+ /* Next firmware sequence */
+ fw_iter++;
+ }
+ return rval;
+}
+
+int
qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
{
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);
MODULE_PARM_DESC(ql2xloginretrycount,
"Specify an alternate value for the NVRAM login retry count.");
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+int ql2xfwloadflash;
+module_param(ql2xfwloadflash, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xfwloadflash,
+ "Load ISP24xx firmware image from FLASH (onboard memory).");
+#endif
+
static void qla2x00_free_device(scsi_qla_host_t *);
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)
ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
ha->isp_ops.nvram_config = qla24xx_nvram_config;
ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
-#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
- ha->isp_ops.load_risc = qla24xx_load_risc_flash;
-#else
ha->isp_ops.load_risc = qla24xx_load_risc;
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+ if (ql2xfwloadflash)
+ ha->isp_ops.load_risc = qla24xx_load_risc_flash;
#endif
ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
@@ -2488,53 +2495,8 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
#define qla2x00_release_firmware() do { } while (0)
-
-static struct qla_board_info qla_board_tbl[] = {
- {
- .drv_name = "qla2400",
- .isp_name = "ISP2422",
- .fw_fname = "ql2400_fw.bin",
- .sht = &qla24xx_driver_template,
- },
- {
- .drv_name = "qla2400",
- .isp_name = "ISP2432",
- .fw_fname = "ql2400_fw.bin",
- .sht = &qla24xx_driver_template,
- },
-};
-
-static struct pci_device_id qla2xxx_pci_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_QLOGIC,
- .device = PCI_DEVICE_ID_QLOGIC_ISP2422,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = (unsigned long)&qla_board_tbl[0],
- },
- {
- .vendor = PCI_VENDOR_ID_QLOGIC,
- .device = PCI_DEVICE_ID_QLOGIC_ISP2432,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = (unsigned long)&qla_board_tbl[1],
- },
- {0, 0},
-};
-MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
-
-static int __devinit
-qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- return qla2x00_probe_one(pdev,
- (struct qla_board_info *)id->driver_data);
-}
-
-static void __devexit
-qla2xxx_remove_one(struct pci_dev *pdev)
-{
- qla2x00_remove_one(pdev);
-}
+#define qla2x00_pci_module_init() (0)
+#define qla2x00_pci_module_exit() do { } while (0)
#else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
@@ -2647,8 +2609,6 @@ qla2xxx_remove_one(struct pci_dev *pdev)
qla2x00_remove_one(pdev);
}
-#endif
-
static struct pci_driver qla2xxx_pci_driver = {
.name = "qla2xxx",
.owner = THIS_MODULE,
@@ -2657,6 +2617,20 @@ static struct pci_driver qla2xxx_pci_driver = {
.remove = __devexit_p(qla2xxx_remove_one),
};
+static inline int
+qla2x00_pci_module_init(void)
+{
+ return pci_module_init(&qla2xxx_pci_driver);
+}
+
+static inline void
+qla2x00_pci_module_exit(void)
+{
+ pci_unregister_driver(&qla2xxx_pci_driver);
+}
+
+#endif
+
/**
* qla2x00_module_init - Module initialization.
**/
@@ -2688,7 +2662,7 @@ qla2x00_module_init(void)
return -ENODEV;
printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
- ret = pci_module_init(&qla2xxx_pci_driver);
+ ret = qla2x00_pci_module_init();
if (ret) {
kmem_cache_destroy(srb_cachep);
fc_release_transport(qla2xxx_transport_template);
@@ -2702,7 +2676,7 @@ qla2x00_module_init(void)
static void __exit
qla2x00_module_exit(void)
{
- pci_unregister_driver(&qla2xxx_pci_driver);
+ qla2x00_pci_module_exit();
qla2x00_release_firmware();
kmem_cache_destroy(srb_cachep);
fc_release_transport(qla2xxx_transport_template);