Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a28d9e4e authored by Joe Carnuccio's avatar Joe Carnuccio Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Add support for multiple fwdump templates/segments



This patch adds multipe firmware dump template and segments support for
ISP27XX/28XX.

Signed-off-by: default avatarJoe Carnuccio <joe.carnuccio@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f8f97b0c
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -84,8 +84,7 @@ qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
		return 0;
	}

	if (bcode[0] != 'H' || bcode[1] != 'Q' || bcode[2] != 'O' ||
			bcode[3] != 'S') {
	if (memcmp(bcode, "HQOS", 4)) {
		/* Invalid FCP priority data header*/
		ql_dbg(ql_dbg_user, vha, 0x7052,
		    "Invalid FCP Priority data header. bcode=0x%x.\n",
+5 −4
Original line number Diff line number Diff line
@@ -4030,9 +4030,11 @@ struct qla_hw_data {
	uint8_t		pep_version[3];

	/* Firmware dump template */
	void		*fw_dump_template;
	uint32_t	fw_dump_template_len;
	/* Firmware dump information. */
	struct fwdt {
		void *template;
		ulong length;
		ulong dump_size;
	} fwdt[2];
	struct qla2xxx_fw_dump *fw_dump;
	uint32_t	fw_dump_len;
	bool		fw_dumped;
@@ -4075,7 +4077,6 @@ struct qla_hw_data {
	uint16_t	product_id[4];

	uint8_t		model_number[16+1];
#define BINZERO		"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
	char		model_desc[80];
	uint8_t		adapter_id[16+1];

+1 −1
Original line number Diff line number Diff line
@@ -611,7 +611,7 @@ extern void qla82xx_fw_dump(scsi_qla_host_t *, int);
extern void qla8044_fw_dump(scsi_qla_host_t *, int);

extern void qla27xx_fwdump(scsi_qla_host_t *, int);
extern ulong qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *);
extern ulong qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *, void *);
extern int qla27xx_fwdt_template_valid(void *);
extern ulong qla27xx_fwdt_template_size(void *);

+235 −173
Original line number Diff line number Diff line
@@ -3089,12 +3089,15 @@ qla2x00_alloc_offload_mem(scsi_qla_host_t *vha)
void
qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
{
	int rval;
	uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size,
	    eft_size, fce_size, mq_size;
	struct qla_hw_data *ha = vha->hw;
	struct req_que *req = ha->req_q_map[0];
	struct rsp_que *rsp = ha->rsp_q_map[0];
	struct qla2xxx_fw_dump *fw_dump;
	dma_addr_t tc_dma;
	void *tc;

	dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0;
	req_q_size = rsp_q_size = 0;
@@ -3139,20 +3142,51 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)

		fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
try_eft:
		if (ha->eft)
			dma_free_coherent(&ha->pdev->dev,
			    EFT_SIZE, ha->eft, ha->eft_dma);

		/* Allocate memory for Extended Trace Buffer. */
		tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
					 GFP_KERNEL);
		if (!tc) {
			ql_log(ql_log_warn, vha, 0x00c1,
			    "Unable to allocate (%d KB) for EFT.\n",
			    EFT_SIZE / 1024);
			goto allocate;
		}

		rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
		if (rval) {
			ql_log(ql_log_warn, vha, 0x00c2,
			    "Unable to initialize EFT (%d).\n", rval);
			dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc,
			    tc_dma);
		}
		ql_dbg(ql_dbg_init, vha, 0x00c3,
		    "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
		eft_size = EFT_SIZE;
	}

	if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
		if (!ha->fw_dump_template) {
		struct fwdt *fwdt = ha->fwdt;
		uint j;

		for (j = 0; j < 2; j++, fwdt++) {
			if (!fwdt->template) {
				ql_log(ql_log_warn, vha, 0x00ba,
			    "Failed missing fwdump template\n");
			return;
				    "-> fwdt%u no template\n", j);
				continue;
			}
		dump_size = qla27xx_fwdt_calculate_dump_size(vha);
			ql_dbg(ql_dbg_init, vha, 0x00fa,
		    "-> allocating fwdump (%x bytes)...\n", dump_size);
			    "-> fwdt%u calculating fwdump size...\n", j);
			fwdt->dump_size = qla27xx_fwdt_calculate_dump_size(
			    vha, fwdt->template);
			ql_dbg(ql_dbg_init, vha, 0x00fa,
			    "-> fwdt%u calculated fwdump size = %#lx bytes\n",
			    j, fwdt->dump_size);
			dump_size += fwdt->dump_size;
		}
		goto allocate;
	}

@@ -4270,11 +4304,14 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
{
	char *st, *en;
	uint16_t index;
	uint64_t zero[2] = { 0 };
	struct qla_hw_data *ha = vha->hw;
	int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
	    !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha);

	if (memcmp(model, BINZERO, len) != 0) {
	if (len > sizeof(zero))
		len = sizeof(zero);
	if (memcmp(model, &zero, len) != 0) {
		strncpy(ha->model_number, model, len);
		st = en = ha->model_number;
		en += len - 1;
@@ -4378,8 +4415,8 @@ qla2x00_nvram_config(scsi_qla_host_t *vha)
	    nv, ha->nvram_size);

	/* Bad NVRAM data, set defaults parameters. */
	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
	    nv->id[2] != 'P' || nv->id[3] != ' ' || nv->nvram_version < 1) {
	if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
	    nv->nvram_version < 1) {
		/* Reset NVRAM data. */
		ql_log(ql_log_warn, vha, 0x0064,
		    "Inconsistent NVRAM "
@@ -6986,9 +7023,8 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
	    nv, ha->nvram_size);

	/* Bad NVRAM data, set defaults parameters. */
	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P'
	    || nv->id[3] != ' ' ||
	    nv->nvram_version < cpu_to_le16(ICB_VERSION)) {
	if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
	    le16_to_cpu(nv->nvram_version) < ICB_VERSION) {
		/* Reset NVRAM data. */
		ql_log(ql_log_warn, vha, 0x006b,
		    "Inconsistent NVRAM detected: checksum=0x%x id=%c "
@@ -7304,14 +7340,16 @@ static int
qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
    uint32_t faddr)
{
	int	rval = QLA_SUCCESS;
	int	segments, fragment;
	uint32_t *dcode, dlen;
	uint32_t risc_addr;
	uint32_t risc_size;
	uint32_t i;
	int rval;
	uint templates, segments, fragment;
	ulong i;
	uint j;
	ulong dlen;
	uint32_t *dcode;
	uint32_t risc_addr, risc_size, risc_attr = 0;
	struct qla_hw_data *ha = vha->hw;
	struct req_que *req = ha->req_q_map[0];
	struct fwdt *fwdt = ha->fwdt;

	ql_dbg(ql_dbg_init, vha, 0x008b,
	    "FW: Loading firmware from flash (%x).\n", faddr);
@@ -7329,34 +7367,36 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
		return QLA_FUNCTION_FAILED;
	}

	while (segments && rval == QLA_SUCCESS) {
		/* Read segment's load information. */
		qla24xx_read_flash_data(vha, dcode, faddr, 4);

	dcode = (void *)req->ring;
	*srisc_addr = 0;
	segments = FA_RISC_CODE_SEGMENTS;
	for (j = 0; j < segments; j++) {
		ql_dbg(ql_dbg_init, vha, 0x008d,
		    "-> Loading segment %u...\n", j);
		qla24xx_read_flash_data(vha, dcode, faddr, 10);
		risc_addr = be32_to_cpu(dcode[2]);
		*srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr;
		risc_size = be32_to_cpu(dcode[3]);
		if (!*srisc_addr) {
			*srisc_addr = risc_addr;
			risc_attr = be32_to_cpu(dcode[9]);
		}

		fragment = 0;
		while (risc_size > 0 && rval == QLA_SUCCESS) {
			dlen = (uint32_t)(ha->fw_transfer_size >> 2);
		dlen = ha->fw_transfer_size >> 2;
		for (fragment = 0; risc_size; fragment++) {
			if (dlen > risc_size)
				dlen = risc_size;

			ql_dbg(ql_dbg_init, vha, 0x008e,
			    "Loading risc segment@ risc addr %x "
			    "number of dwords 0x%x offset 0x%x.\n",
			    risc_addr, dlen, faddr);

			    "-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n",
			    fragment, risc_addr, faddr, dlen);
			qla24xx_read_flash_data(vha, dcode, faddr, dlen);
			for (i = 0; i < dlen; i++)
				dcode[i] = swab32(dcode[i]);

			rval = qla2x00_load_ram(vha, req->dma, risc_addr,
			    dlen);
			rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen);
			if (rval) {
				ql_log(ql_log_fatal, vha, 0x008f,
				    "Failed to load segment %d of firmware.\n",
				    "-> Failed load firmware fragment %u.\n",
				    fragment);
				return QLA_FUNCTION_FAILED;
			}
@@ -7364,72 +7404,83 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
			faddr += dlen;
			risc_addr += dlen;
			risc_size -= dlen;
			fragment++;
		}

		/* Next segment. */
		segments--;
	}

	if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
		return rval;
		return QLA_SUCCESS;

	if (ha->fw_dump_template)
		vfree(ha->fw_dump_template);
	ha->fw_dump_template = NULL;
	ha->fw_dump_template_len = 0;
	templates = (risc_attr & BIT_9) ? 2 : 1;
	ql_dbg(ql_dbg_init, vha, 0x0160, "-> templates = %u\n", templates);
	for (j = 0; j < templates; j++, fwdt++) {
		if (fwdt->template)
			vfree(fwdt->template);
		fwdt->template = NULL;
		fwdt->length = 0;

	ql_dbg(ql_dbg_init, vha, 0x0161,
	    "Loading fwdump template from %x\n", faddr);
		qla24xx_read_flash_data(vha, dcode, faddr, 7);
		risc_size = be32_to_cpu(dcode[2]);
		ql_dbg(ql_dbg_init, vha, 0x0161,
		    "-> fwdt%u template array at %#x (%#x dwords)\n",
		    j, faddr, risc_size);
		if (!risc_size || !~risc_size) {
			ql_dbg(ql_dbg_init, vha, 0x0162,
	    "-> array size %x dwords\n", risc_size);
	if (risc_size == 0 || risc_size == ~0)
			    "-> fwdt%u failed to read array\n", j);
			goto failed;
		}

		/* skip header and ignore checksum */
		faddr += 7;
		risc_size -= 8;

	dlen = (risc_size - 8) * sizeof(*dcode);
		ql_dbg(ql_dbg_init, vha, 0x0163,
	    "-> template allocating %x bytes...\n", dlen);
	ha->fw_dump_template = vmalloc(dlen);
	if (!ha->fw_dump_template) {
		    "-> fwdt%u template allocate template %#x words...\n",
		    j, risc_size);
		fwdt->template = vmalloc(risc_size * sizeof(*dcode));
		if (!fwdt->template) {
			ql_log(ql_log_warn, vha, 0x0164,
		    "Failed fwdump template allocate %x bytes.\n", risc_size);
			    "-> fwdt%u failed allocate template.\n", j);
			goto failed;
		}

	faddr += 7;
	risc_size -= 8;
	dcode = ha->fw_dump_template;
		dcode = fwdt->template;
		qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
		for (i = 0; i < risc_size; i++)
			dcode[i] = le32_to_cpu(dcode[i]);

		if (!qla27xx_fwdt_template_valid(dcode)) {
			ql_log(ql_log_warn, vha, 0x0165,
		    "Failed fwdump template validate\n");
			    "-> fwdt%u failed template validate\n", j);
			goto failed;
		}

		dlen = qla27xx_fwdt_template_size(dcode);
		ql_dbg(ql_dbg_init, vha, 0x0166,
	    "-> template size %x bytes\n", dlen);
		    "-> fwdt%u template size %#lx bytes (%#lx words)\n",
		    j, dlen, dlen / sizeof(*dcode));
		if (dlen > risc_size * sizeof(*dcode)) {
			ql_log(ql_log_warn, vha, 0x0167,
		    "Failed fwdump template exceeds array by %zx bytes\n",
		    (size_t)(dlen - risc_size * sizeof(*dcode)));
			    "-> fwdt%u template exceeds array (%-lu bytes)\n",
			    j, dlen - risc_size * sizeof(*dcode));
			goto failed;
		}
	ha->fw_dump_template_len = dlen;
	return rval;

		fwdt->length = dlen;
		ql_dbg(ql_dbg_init, vha, 0x0168,
		    "-> fwdt%u loaded template ok\n", j);

		faddr += risc_size + 1;
	}

	return QLA_SUCCESS;

failed:
	ql_log(ql_log_warn, vha, 0x016d, "Failed fwdump template\n");
	if (ha->fw_dump_template)
		vfree(ha->fw_dump_template);
	ha->fw_dump_template = NULL;
	ha->fw_dump_template_len = 0;
	return rval;
	if (fwdt->template)
		vfree(fwdt->template);
	fwdt->template = NULL;
	fwdt->length = 0;

	return QLA_SUCCESS;
}

#define QLA_FW_URL "http://ldriver.qlogic.com/firmware/"
@@ -7537,31 +7588,31 @@ static int
qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
{
	int	rval;
	int	segments, fragment;
	uint32_t *dcode, dlen;
	uint32_t risc_addr;
	uint32_t risc_size;
	uint32_t i;
	uint templates, segments, fragment;
	uint32_t *dcode;
	ulong dlen;
	uint32_t risc_addr, risc_size, risc_attr = 0;
	ulong i;
	uint j;
	struct fw_blob *blob;
	uint32_t *fwcode;
	uint32_t fwclen;
	struct qla_hw_data *ha = vha->hw;
	struct req_que *req = ha->req_q_map[0];
	struct fwdt *fwdt = ha->fwdt;

	ql_dbg(ql_dbg_init, vha, 0x0090,
	    "-> FW: Loading via request-firmware.\n");

	/* Load firmware blob. */
	blob = qla2x00_request_firmware(vha);
	if (!blob) {
		ql_log(ql_log_warn, vha, 0x0090,
		    "Firmware image unavailable.\n");
		ql_log(ql_log_warn, vha, 0x0091,
		    "Firmware images can be retrieved from: "
		    QLA_FW_URL ".\n");
		ql_log(ql_log_warn, vha, 0x0092,
		    "-> Firmware file not found.\n");

		return QLA_FUNCTION_FAILED;
	}

	fwcode = (void *)blob->fw->data;
	dcode = fwcode;
	dcode = fwcode + 4;
	if (qla24xx_risc_firmware_invalid(dcode)) {
		ql_log(ql_log_fatal, vha, 0x0093,
		    "Unable to verify integrity of firmware image (%zd).\n",
@@ -7583,38 +7634,39 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
		return QLA_FUNCTION_FAILED;
	}

	while (segments && rval == QLA_SUCCESS) {
	dcode = (void *)req->ring;
	*srisc_addr = 0;
	segments = FA_RISC_CODE_SEGMENTS;
	for (j = 0; j < segments; j++) {
		ql_dbg(ql_dbg_init, vha, 0x0096,
		    "-> Loading segment %u...\n", j);
		risc_addr = be32_to_cpu(fwcode[2]);
		*srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr;
		risc_size = be32_to_cpu(fwcode[3]);

		/* Validate firmware image size. */
		fwclen += risc_size * sizeof(uint32_t);
		if (blob->fw->size < fwclen) {
			ql_log(ql_log_fatal, vha, 0x0096,
			    "Unable to verify integrity of firmware image "
			    "(%zd).\n", blob->fw->size);
			return QLA_FUNCTION_FAILED;
		if (!*srisc_addr) {
			*srisc_addr = risc_addr;
			risc_attr = be32_to_cpu(fwcode[9]);
		}

		fragment = 0;
		while (risc_size > 0 && rval == QLA_SUCCESS) {
		dlen = ha->fw_transfer_size >> 2;
		for (fragment = 0; risc_size; fragment++) {
			dlen = (uint32_t)(ha->fw_transfer_size >> 2);
			if (dlen > risc_size)
				dlen = risc_size;

			ql_dbg(ql_dbg_init, vha, 0x0097,
			    "Loading risc segment@ risc addr %x "
			    "number of dwords 0x%x.\n", risc_addr, dlen);
			    "-> Loading fragment %u: %#x <- %#x (%#lx words)...\n",
			    fragment, risc_addr,
			    (uint32_t)(fwcode - (typeof(fwcode))blob->fw->data),
			    dlen);

			for (i = 0; i < dlen; i++)
				dcode[i] = swab32(fwcode[i]);

			rval = qla2x00_load_ram(vha, req->dma, risc_addr,
			    dlen);
			rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen);
			if (rval) {
				ql_log(ql_log_fatal, vha, 0x0098,
				    "Failed to load segment %d of firmware.\n",
				    "-> Failed load firmware fragment %u.\n",
				    fragment);
				return QLA_FUNCTION_FAILED;
			}
@@ -7622,71 +7674,82 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
			fwcode += dlen;
			risc_addr += dlen;
			risc_size -= dlen;
			fragment++;
		}

		/* Next segment. */
		segments--;
	}

	if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
		return rval;
		return QLA_SUCCESS;

	if (ha->fw_dump_template)
		vfree(ha->fw_dump_template);
	ha->fw_dump_template = NULL;
	ha->fw_dump_template_len = 0;
	templates = (risc_attr & BIT_9) ? 2 : 1;
	ql_dbg(ql_dbg_init, vha, 0x0170, "-> templates = %u\n", templates);
	for (j = 0; j < templates; j++, fwdt++) {
		if (fwdt->template)
			vfree(fwdt->template);
		fwdt->template = NULL;
		fwdt->length = 0;

	ql_dbg(ql_dbg_init, vha, 0x171,
	    "Loading fwdump template from %x\n",
	    (uint32_t)((void *)fwcode - (void *)blob->fw->data));
		risc_size = be32_to_cpu(fwcode[2]);
	ql_dbg(ql_dbg_init, vha, 0x172,
	    "-> array size %x dwords\n", risc_size);
	if (risc_size == 0 || risc_size == ~0)
		ql_dbg(ql_dbg_init, vha, 0x0171,
		    "-> fwdt%u template array at %#x (%#x dwords)\n",
		    j, (uint32_t)((void *)fwcode - (void *)blob->fw->data),
		    risc_size);
		if (!risc_size || !~risc_size) {
			ql_dbg(ql_dbg_init, vha, 0x0172,
			    "-> fwdt%u failed to read array\n", j);
			goto failed;
		}

		/* skip header and ignore checksum */
		fwcode += 7;
		risc_size -= 8;

	dlen = (risc_size - 8) * sizeof(*fwcode);
		ql_dbg(ql_dbg_init, vha, 0x0173,
	    "-> template allocating %x bytes...\n", dlen);
	ha->fw_dump_template = vmalloc(dlen);
	if (!ha->fw_dump_template) {
		    "-> fwdt%u template allocate template %#x words...\n",
		    j, risc_size);
		fwdt->template = vmalloc(risc_size * sizeof(*dcode));
		if (!fwdt->template) {
			ql_log(ql_log_warn, vha, 0x0174,
		    "Failed fwdump template allocate %x bytes.\n", risc_size);
			    "-> fwdt%u failed allocate template.\n", j);
			goto failed;
		}

	fwcode += 7;
	risc_size -= 8;
	dcode = ha->fw_dump_template;
		dcode = fwdt->template;
		for (i = 0; i < risc_size; i++)
			dcode[i] = le32_to_cpu(fwcode[i]);

		if (!qla27xx_fwdt_template_valid(dcode)) {
			ql_log(ql_log_warn, vha, 0x0175,
		    "Failed fwdump template validate\n");
			    "-> fwdt%u failed template validate\n", j);
			goto failed;
		}

		dlen = qla27xx_fwdt_template_size(dcode);
		ql_dbg(ql_dbg_init, vha, 0x0176,
	    "-> template size %x bytes\n", dlen);
	if (dlen > risc_size * sizeof(*fwcode)) {
		    "-> fwdt%u template size %#lx bytes (%#lx words)\n",
		    j, dlen, dlen / sizeof(*dcode));
		if (dlen > risc_size * sizeof(*dcode)) {
			ql_log(ql_log_warn, vha, 0x0177,
		    "Failed fwdump template exceeds array by %zx bytes\n",
		    (size_t)(dlen - risc_size * sizeof(*fwcode)));
			    "-> fwdt%u template exceeds array (%-lu bytes)\n",
			    j, dlen - risc_size * sizeof(*dcode));
			goto failed;
		}
	ha->fw_dump_template_len = dlen;
	return rval;

		fwdt->length = dlen;
		ql_dbg(ql_dbg_init, vha, 0x0178,
		    "-> fwdt%u loaded template ok\n", j);

		fwcode += risc_size + 1;
	}

	return QLA_SUCCESS;

failed:
	ql_log(ql_log_warn, vha, 0x017d, "Failed fwdump template\n");
	if (ha->fw_dump_template)
		vfree(ha->fw_dump_template);
	ha->fw_dump_template = NULL;
	ha->fw_dump_template_len = 0;
	return rval;
	if (fwdt->template)
		vfree(fwdt->template);
	fwdt->template = NULL;
	fwdt->length = 0;

	return QLA_SUCCESS;
}

int
@@ -7953,9 +8016,8 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
	    nv, ha->nvram_size);

	/* Bad NVRAM data, set defaults parameters. */
	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P'
	    || nv->id[3] != ' ' ||
	    nv->nvram_version < cpu_to_le16(ICB_VERSION)) {
	if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
	    le16_to_cpu(nv->nvram_version) < ICB_VERSION) {
		/* Reset NVRAM data. */
		ql_log(ql_log_info, vha, 0x0073,
		    "Inconsistent NVRAM detected: checksum=0x%x id=%c "
+10 −4
Original line number Diff line number Diff line
@@ -4647,6 +4647,9 @@ qla2x00_free_exchoffld_buffer(struct qla_hw_data *ha)
static void
qla2x00_free_fw_dump(struct qla_hw_data *ha)
{
	struct fwdt *fwdt = ha->fwdt;
	uint j;

	if (ha->fce)
		dma_free_coherent(&ha->pdev->dev,
		    FCE_SIZE, ha->fce, ha->fce_dma);
@@ -4657,8 +4660,6 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha)

	if (ha->fw_dump)
		vfree(ha->fw_dump);
	if (ha->fw_dump_template)
		vfree(ha->fw_dump_template);

	ha->fce = NULL;
	ha->fce_dma = 0;
@@ -4669,8 +4670,13 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha)
	ha->fw_dump_reading = 0;
	ha->fw_dump = NULL;
	ha->fw_dump_len = 0;
	ha->fw_dump_template = NULL;
	ha->fw_dump_template_len = 0;

	for (j = 0; j < 2; j++, fwdt++) {
		if (fwdt->template)
			vfree(fwdt->template);
		fwdt->template = NULL;
		fwdt->length = 0;
	}
}

/*
Loading