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

Commit 281afe19 authored by Seokmann Ju's avatar Seokmann Ju Committed by James Bottomley
Browse files

[SCSI] qla2xxx: fix to honor ignored parameters in sysfs attributes



This is a patch to fix 'segmentation fault' issue which was initiated
by Richard Lary <rlary@us.ibm.com>.  Thanks again Richard.

- on following sysfs attritute function, changes have made so that both
  count and offset input parameters are honored by the functions.
    = qla2x00_sysfs_read_nvram()
    = qla2x00_sysfs_read_vpd()
- made changes so that NVRAM data to be cached to minimize H/W accesses
  during agent querying of the driver's.

Signed-off-by: default avatarSeokmann Ju <seokmann.ju@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent c835e372
Loading
Loading
Loading
Loading
+23 −16
Original line number Diff line number Diff line
@@ -91,18 +91,20 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
{
	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	unsigned long	flags;
	int		size = ha->nvram_size;
	char		*nvram_cache = ha->nvram;

	if (!capable(CAP_SYS_ADMIN) || off != 0)
	if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
		return 0;
	if (off + count > size) {
		size -= off;
		count = size;
	}

	/* Read NVRAM. */
	spin_lock_irqsave(&ha->hardware_lock, flags);
	ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->nvram_base,
	    ha->nvram_size);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
	/* Read NVRAM data from cache. */
	memcpy(buf, &nvram_cache[off], count);

	return ha->nvram_size;
	return count;
}

static ssize_t
@@ -144,6 +146,8 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
	/* Write NVRAM. */
	spin_lock_irqsave(&ha->hardware_lock, flags);
	ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count);
	ha->isp_ops->read_nvram(ha, (uint8_t *)&ha->nvram, ha->nvram_base,
	    count);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);

	set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
@@ -298,18 +302,20 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
{
	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	unsigned long flags;
	int           size = ha->vpd_size;
	char          *vpd_cache = ha->vpd;

	if (!capable(CAP_SYS_ADMIN) || off != 0)
	if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
		return 0;
	if (off + count > size) {
		size -= off;
		count = size;
	}

	/* Read NVRAM. */
	spin_lock_irqsave(&ha->hardware_lock, flags);
	ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->vpd_base,
	    ha->vpd_size);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
	/* Read NVRAM data from cache. */
	memcpy(buf, &vpd_cache[off], count);

	return ha->vpd_size;
	return count;
}

static ssize_t
@@ -327,6 +333,7 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
	/* Write NVRAM. */
	spin_lock_irqsave(&ha->hardware_lock, flags);
	ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count);
	ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, ha->vpd_base, count);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);

	return count;
+4 −0
Original line number Diff line number Diff line
@@ -2340,10 +2340,14 @@ typedef struct scsi_qla_host {
	uint8_t		serial2;

	/* NVRAM configuration data */
#define MAX_NVRAM_SIZE	4096
#define VPD_OFFSET	MAX_NVRAM_SIZE / 2
	uint16_t	nvram_size;
	uint16_t	nvram_base;
	void		*nvram;
	uint16_t	vpd_size;
	uint16_t	vpd_base;
	void		*vpd;

	uint16_t	loop_reset_delay;
	uint8_t		retry_count;
+11 −8
Original line number Diff line number Diff line
@@ -1461,8 +1461,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
	uint16_t        cnt;
	uint8_t         *dptr1, *dptr2;
	init_cb_t       *icb = ha->init_cb;
	nvram_t         *nv = (nvram_t *)ha->request_ring;
	uint8_t         *ptr = (uint8_t *)ha->request_ring;
	nvram_t         *nv = ha->nvram;
	uint8_t         *ptr = ha->nvram;
	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;

	rval = QLA_SUCCESS;
@@ -1480,8 +1480,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
		chksum += *ptr++;

	DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
	DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring,
	    ha->nvram_size));
	DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size));

	/* Bad NVRAM data, set defaults parameters. */
	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
@@ -3500,7 +3499,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)

	rval = QLA_SUCCESS;
	icb = (struct init_cb_24xx *)ha->init_cb;
	nv = (struct nvram_24xx *)ha->request_ring;
	nv = ha->nvram;

	/* Determine NVRAM starting address. */
	ha->nvram_size = sizeof(struct nvram_24xx);
@@ -3512,7 +3511,12 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
		ha->vpd_base = FA_NVRAM_VPD1_ADDR;
	}

	/* Get NVRAM data and calculate checksum. */
	/* Get VPD data into cache */
	ha->vpd = ha->nvram + VPD_OFFSET;
	ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd,
	    ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4);

	/* Get NVRAM data into cache and calculate checksum. */
	dptr = (uint32_t *)nv;
	ha->isp_ops->read_nvram(ha, (uint8_t *)dptr, ha->nvram_base,
	    ha->nvram_size);
@@ -3520,8 +3524,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
		chksum += le32_to_cpu(*dptr++);

	DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
	DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring,
	    ha->nvram_size));
	DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size));

	/* Bad NVRAM data, set defaults parameters. */
	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P'