[PATCH 04/15] qla2xxx: Update ISP24xx firwmare loading heuristics.

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

 



If firmware image is unavailable via request_firwmare(), then
attempt to load the image (likely out-of-date) stored in flash
memory.

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

---

2a8aef079b2a41648c80b218a9fa840a3e070429
 drivers/scsi/qla2xxx/qla_init.c |  176 +++++++++++++++++++++------------------
 1 files changed, 93 insertions(+), 83 deletions(-)

2a8aef079b2a41648c80b218a9fa840a3e070429
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 89a3fc0..1cf27fe 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3498,6 +3498,88 @@ qla24xx_nvram_config(scsi_qla_host_t *ha
 	return (rval);
 }
 
+int
+qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+	int	rval;
+	int	segments, fragment;
+	uint32_t faddr;
+	uint32_t *dcode, dlen;
+	uint32_t risc_addr;
+	uint32_t risc_size;
+	uint32_t i;
+
+	rval = QLA_SUCCESS;
+
+	segments = FA_RISC_CODE_SEGMENTS;
+	faddr = FA_RISC_CODE_ADDR;
+	dcode = (uint32_t *)ha->request_ring;
+	*srisc_addr = 0;
+
+	/* Validate firmware image by checking version. */
+	qla24xx_read_flash_data(ha, dcode, faddr + 4, 4);
+	for (i = 0; i < 4; i++)
+		dcode[i] = be32_to_cpu(dcode[i]);
+	if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff &&
+	    dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) ||
+	    (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
+		dcode[3] == 0)) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to verify integrity of flash firmware image!\n");
+		qla_printk(KERN_WARNING, ha,
+		    "Firmware data: %08x %08x %08x %08x!\n", dcode[0],
+		    dcode[1], dcode[2], dcode[3]);
+
+		return QLA_FUNCTION_FAILED;
+	}
+
+	while (segments && rval == QLA_SUCCESS) {
+		/* Read segment's load information. */
+		qla24xx_read_flash_data(ha, dcode, faddr, 4);
+
+		risc_addr = be32_to_cpu(dcode[2]);
+		*srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr;
+		risc_size = be32_to_cpu(dcode[3]);
+
+		fragment = 0;
+		while (risc_size > 0 && rval == QLA_SUCCESS) {
+			dlen = (uint32_t)(ha->fw_transfer_size >> 2);
+			if (dlen > risc_size)
+				dlen = risc_size;
+
+			DEBUG7(printk("scsi(%ld): Loading risc segment@ risc "
+			    "addr %x, number of dwords 0x%x, offset 0x%x.\n",
+			    ha->host_no, risc_addr, dlen, faddr));
+
+			qla24xx_read_flash_data(ha, dcode, faddr, dlen);
+			for (i = 0; i < dlen; i++)
+				dcode[i] = swab32(dcode[i]);
+
+			rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+			    dlen);
+			if (rval) {
+				DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
+				    "segment %d of firmware\n", ha->host_no,
+				    fragment));
+				qla_printk(KERN_WARNING, ha,
+				    "[ERROR] Failed to load segment %d of "
+				    "firmware\n", fragment);
+				break;
+			}
+
+			faddr += dlen;
+			risc_addr += dlen;
+			risc_size -= dlen;
+			fragment++;
+		}
+
+		/* Next segment. */
+		segments--;
+	}
+
+	return rval;
+}
+
 #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
 
 int
@@ -3625,90 +3707,10 @@ qla24xx_load_risc(scsi_qla_host_t *ha, u
 	return rval;
 }
 
-int
-qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
-{
-	int	rval;
-	int	segments, fragment;
-	uint32_t faddr;
-	uint32_t *dcode, dlen;
-	uint32_t risc_addr;
-	uint32_t risc_size;
-	uint32_t i;
-
-	rval = QLA_SUCCESS;
-
-	segments = FA_RISC_CODE_SEGMENTS;
-	faddr = FA_RISC_CODE_ADDR;
-	dcode = (uint32_t *)ha->request_ring;
-	*srisc_addr = 0;
-
-	/* Validate firmware image by checking version. */
-	qla24xx_read_flash_data(ha, dcode, faddr + 4, 4);
-	for (i = 0; i < 4; i++)
-		dcode[i] = be32_to_cpu(dcode[i]);
-	if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff &&
-	    dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) ||
-	    (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
-		dcode[3] == 0)) {
-		qla_printk(KERN_WARNING, ha,
-		    "Unable to verify integrity of flash firmware image!\n");
-		qla_printk(KERN_WARNING, ha,
-		    "Firmware data: %08x %08x %08x %08x!\n", dcode[0],
-		    dcode[1], dcode[2], dcode[3]);
-
-		return QLA_FUNCTION_FAILED;
-	}
-
-	while (segments && rval == QLA_SUCCESS) {
-		/* Read segment's load information. */
-		qla24xx_read_flash_data(ha, dcode, faddr, 4);
-
-		risc_addr = be32_to_cpu(dcode[2]);
-		*srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr;
-		risc_size = be32_to_cpu(dcode[3]);
-
-		fragment = 0;
-		while (risc_size > 0 && rval == QLA_SUCCESS) {
-			dlen = (uint32_t)(ha->fw_transfer_size >> 2);
-			if (dlen > risc_size)
-				dlen = risc_size;
-
-			DEBUG7(printk("scsi(%ld): Loading risc segment@ risc "
-			    "addr %x, number of dwords 0x%x, offset 0x%x.\n",
-			    ha->host_no, risc_addr, dlen, faddr));
-
-			qla24xx_read_flash_data(ha, dcode, faddr, dlen);
-			for (i = 0; i < dlen; i++)
-				dcode[i] = swab32(dcode[i]);
-
-			rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
-			    dlen);
-			if (rval) {
-				DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
-				    "segment %d of firmware\n", ha->host_no,
-				    fragment));
-				qla_printk(KERN_WARNING, ha,
-				    "[ERROR] Failed to load segment %d of "
-				    "firmware\n", fragment);
-				break;
-			}
-
-			faddr += dlen;
-			risc_addr += dlen;
-			risc_size -= dlen;
-			fragment++;
-		}
-
-		/* Next segment. */
-		segments--;
-	}
-
-	return rval;
-}
-
 #else	/* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
 
+#define QLA_FW_URL "ftp://ftp.qlogic.com/outgoing/linux/firmware/";
+
 int
 qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
 {
@@ -3722,6 +3724,8 @@ qla2x00_load_risc(scsi_qla_host_t *ha, u
 	blob = qla2x00_request_firmware(ha);
 	if (!blob) {
 		qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n");
+		qla_printk(KERN_ERR, ha, "Firmware images can be retrieved "
+		    "from: " QLA_FW_URL ".\n");
 		return QLA_FUNCTION_FAILED;
 	}
 
@@ -3823,7 +3827,13 @@ qla24xx_load_risc(scsi_qla_host_t *ha, u
 	blob = qla2x00_request_firmware(ha);
 	if (!blob) {
 		qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n");
-		return QLA_FUNCTION_FAILED;
+		qla_printk(KERN_ERR, ha, "Firmware images can be retrieved "
+		    "from: " QLA_FW_URL ".\n");
+
+		/* Try to load RISC code from flash. */
+		qla_printk(KERN_ERR, ha, "Attempting to load (potentially "
+		    "outdated) firmware from flash.\n");
+		return qla24xx_load_risc_flash(ha, srisc_addr);
 	}
 
 	rval = QLA_SUCCESS;
-- 
1.3.3.g63df


-
: 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