[PATCH 5/12] qla2xxx: Add support for embedded ISP24xx firmware.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Andrew Vasquez <andrew.vasquez@xxxxxxxxxx>

---

 drivers/scsi/qla2xxx/Makefile   |    3 +
 drivers/scsi/qla2xxx/ql2400.c   |  113 +++++++++++++++++++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_def.h  |    2 -
 drivers/scsi/qla2xxx/qla_gbl.h  |    1 
 drivers/scsi/qla2xxx/qla_init.c |   63 ++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_os.c   |   85 ++++++-----------------------
 6 files changed, 196 insertions(+), 71 deletions(-)
 create mode 100644 drivers/scsi/qla2xxx/ql2400.c

applies-to: fd35977ee7de3602087def1d4b490e31c9a383d2
84910304aeb3d5db54db9e975309e21791b9baca
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
index b169687..f1c3dfd 100644
--- a/drivers/scsi/qla2xxx/Makefile
+++ b/drivers/scsi/qla2xxx/Makefile
@@ -8,10 +8,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 0000000..76a48ed
--- /dev/null
+++ b/drivers/scsi/qla2xxx/ql2400.c
@@ -0,0 +1,113 @@
+/*
+ * 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",
+		.alternate_sht	= 1,
+	},
+	{
+		.drv_name	= qla_driver_name,
+		.isp_name	= "ISP2432",
+		.fw_info	= qla_fw_tbl,
+		.fw_fname	= "ql2400_fw.bin",
+		.alternate_sht	= 1,
+	},
+};
+
+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_def.h b/drivers/scsi/qla2xxx/qla_def.h
index fc3234c..73a066c 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2118,7 +2118,7 @@ struct qla_board_info {
 	char isp_name[8];
 	struct qla_fw_info *fw_info;
 	char *fw_fname;
-	struct scsi_host_template *sht;
+	int alternate_sht;
 };
 
 /* Return data from MBC_GET_ID_LIST call. */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index ba44636..ec30ac1 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -35,6 +35,7 @@ extern void qla24xx_update_fw_options(sc
 extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
 extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *);
 extern int qla24xx_load_risc_hotplug(scsi_qla_host_t *, uint32_t *);
+extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
 
 extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, int);
 
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 5ab88e7..7407780 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3729,3 +3729,66 @@ fail_fw_integrity:
 	return QLA_FUNCTION_FAILED;
 
 }
+
+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_address;
+	uint32_t risc_code_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_code_size = *((uint32_t *)fw_iter->fwlen);
+		risc_address = *((uint32_t *)fw_iter->lfwstart);
+
+		num = 0;
+		rval = 0;
+		while (risc_code_size > 0 && !rval) {
+			cnt = (uint32_t)(ha->fw_transfer_size >> 2);
+			if (cnt > risc_code_size)
+				cnt = risc_code_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_address));
+
+			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_ext(ha, ha->request_dma,
+			    risc_address, 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_address += cnt;
+			risc_code_size -= cnt;
+			num++;
+		}
+
+		/* Next firmware sequence */
+		fw_iter++;
+	}
+
+	return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 42c53ea..40b124d 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -54,10 +54,15 @@ module_param(ql2xloginretrycount, int, S
 MODULE_PARM_DESC(ql2xloginretrycount,
 		"Specify an alternate value for the NVRAM login retry count.");
 
-int ql2xfwloadbin=1;
+int ql2xfwloadbin;
 module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
 MODULE_PARM_DESC(ql2xfwloadbin,
-		"Load ISP2xxx firmware image via hotplug.");
+		"Option to specify location in which to load ISP24xx firmware: "
+		" 2 -- load firmware via the request_firmware() (hotplug) "
+		"      interface.  A file, ql2400_fw.bin, (containing the "
+		"      firmware image) should be hotplug accessible."
+		" 1 -- load firmware from flash."
+		" 0 -- load firmware embedded with driver (default).");
 
 static void qla2x00_free_device(scsi_qla_host_t *);
 
@@ -1210,8 +1215,9 @@ int qla2x00_probe_one(struct pci_dev *pd
 	if (pci_enable_device(pdev))
 		goto probe_out;
 
-	host = scsi_host_alloc(brd_info->sht ? brd_info->sht:
-	    &qla2x00_driver_template, sizeof(scsi_qla_host_t));
+	host = scsi_host_alloc(brd_info->alternate_sht ?
+	    &qla24xx_driver_template: &qla2x00_driver_template,
+	    sizeof(scsi_qla_host_t));
 	if (host == NULL) {
 		printk(KERN_WARNING
 		    "qla2xxx: Couldn't allocate host from scsi layer!\n");
@@ -1311,9 +1317,12 @@ int qla2x00_probe_one(struct pci_dev *pd
 		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;
-		ha->isp_ops.load_risc = qla24xx_load_risc_flash;
-		if (ql2xfwloadbin)
+		if (ql2xfwloadbin == 2)
 			ha->isp_ops.load_risc = qla24xx_load_risc_hotplug;
+		else if (ql2xfwloadbin == 1)
+			ha->isp_ops.load_risc = qla24xx_load_risc_flash;
+		else
+			ha->isp_ops.load_risc = qla24xx_load_risc;
 		ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
 		ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
 		ha->isp_ops.intr_handler = qla24xx_intr_handler;
@@ -2419,68 +2428,12 @@ qla2x00_down_timeout(struct semaphore *s
 	return -ETIMEDOUT;
 }
 
-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);
-}
-
-static struct pci_driver qla2xxx_pci_driver = {
-	.name		= "qla2xxx",
-	.id_table	= qla2xxx_pci_tbl,
-	.probe		= qla2xxx_probe_one,
-	.remove		= __devexit_p(qla2xxx_remove_one),
-};
-
 /**
  * qla2x00_module_init - Module initialization.
  **/
 static int __init
 qla2x00_module_init(void)
 {
-	int ret = 0;
-
 	/* Allocate cache for SRBs. */
 	srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
 	    SLAB_HWCACHE_ALIGN, NULL, NULL);
@@ -2501,12 +2454,7 @@ qla2x00_module_init(void)
 		return -ENODEV;
 
 	printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
-	ret = pci_module_init(&qla2xxx_pci_driver);
-	if (ret) {
-		kmem_cache_destroy(srb_cachep);
-		fc_release_transport(qla2xxx_transport_template);
-	}
-	return ret;
+	return 0;
 }
 
 /**
@@ -2515,7 +2463,6 @@ qla2x00_module_init(void)
 static void __exit
 qla2x00_module_exit(void)
 {
-	pci_unregister_driver(&qla2xxx_pci_driver);
 	kmem_cache_destroy(srb_cachep);
 	fc_release_transport(qla2xxx_transport_template);
 }
---
0.99.8.GIT

-- 
Andrew Vasquez
-
: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux