[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: Seokmann Ju <seokmann.ju@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
committed by
James Bottomley
parent
c835e3727b
commit
281afe1947
@ -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 scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
|
||||||
struct device, 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;
|
return 0;
|
||||||
|
if (off + count > size) {
|
||||||
|
size -= off;
|
||||||
|
count = size;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read NVRAM. */
|
/* Read NVRAM data from cache. */
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
memcpy(buf, &nvram_cache[off], count);
|
||||||
ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->nvram_base,
|
|
||||||
ha->nvram_size);
|
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
||||||
|
|
||||||
return ha->nvram_size;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
@ -144,6 +146,8 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
|
|||||||
/* Write NVRAM. */
|
/* Write NVRAM. */
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count);
|
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);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_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 scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
|
||||||
struct device, 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;
|
return 0;
|
||||||
|
if (off + count > size) {
|
||||||
|
size -= off;
|
||||||
|
count = size;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read NVRAM. */
|
/* Read NVRAM data from cache. */
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
memcpy(buf, &vpd_cache[off], count);
|
||||||
ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->vpd_base,
|
|
||||||
ha->vpd_size);
|
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
||||||
|
|
||||||
return ha->vpd_size;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
@ -327,6 +333,7 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
|
|||||||
/* Write NVRAM. */
|
/* Write NVRAM. */
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count);
|
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);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -2340,10 +2340,14 @@ typedef struct scsi_qla_host {
|
|||||||
uint8_t serial2;
|
uint8_t serial2;
|
||||||
|
|
||||||
/* NVRAM configuration data */
|
/* NVRAM configuration data */
|
||||||
|
#define MAX_NVRAM_SIZE 4096
|
||||||
|
#define VPD_OFFSET MAX_NVRAM_SIZE / 2
|
||||||
uint16_t nvram_size;
|
uint16_t nvram_size;
|
||||||
uint16_t nvram_base;
|
uint16_t nvram_base;
|
||||||
|
void *nvram;
|
||||||
uint16_t vpd_size;
|
uint16_t vpd_size;
|
||||||
uint16_t vpd_base;
|
uint16_t vpd_base;
|
||||||
|
void *vpd;
|
||||||
|
|
||||||
uint16_t loop_reset_delay;
|
uint16_t loop_reset_delay;
|
||||||
uint8_t retry_count;
|
uint8_t retry_count;
|
||||||
|
@ -1461,8 +1461,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
|||||||
uint16_t cnt;
|
uint16_t cnt;
|
||||||
uint8_t *dptr1, *dptr2;
|
uint8_t *dptr1, *dptr2;
|
||||||
init_cb_t *icb = ha->init_cb;
|
init_cb_t *icb = ha->init_cb;
|
||||||
nvram_t *nv = (nvram_t *)ha->request_ring;
|
nvram_t *nv = ha->nvram;
|
||||||
uint8_t *ptr = (uint8_t *)ha->request_ring;
|
uint8_t *ptr = ha->nvram;
|
||||||
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
|
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
|
||||||
|
|
||||||
rval = QLA_SUCCESS;
|
rval = QLA_SUCCESS;
|
||||||
@ -1480,8 +1480,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
|||||||
chksum += *ptr++;
|
chksum += *ptr++;
|
||||||
|
|
||||||
DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
|
DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
|
||||||
DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring,
|
DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size));
|
||||||
ha->nvram_size));
|
|
||||||
|
|
||||||
/* Bad NVRAM data, set defaults parameters. */
|
/* Bad NVRAM data, set defaults parameters. */
|
||||||
if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
|
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;
|
rval = QLA_SUCCESS;
|
||||||
icb = (struct init_cb_24xx *)ha->init_cb;
|
icb = (struct init_cb_24xx *)ha->init_cb;
|
||||||
nv = (struct nvram_24xx *)ha->request_ring;
|
nv = ha->nvram;
|
||||||
|
|
||||||
/* Determine NVRAM starting address. */
|
/* Determine NVRAM starting address. */
|
||||||
ha->nvram_size = sizeof(struct nvram_24xx);
|
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;
|
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;
|
dptr = (uint32_t *)nv;
|
||||||
ha->isp_ops->read_nvram(ha, (uint8_t *)dptr, ha->nvram_base,
|
ha->isp_ops->read_nvram(ha, (uint8_t *)dptr, ha->nvram_base,
|
||||||
ha->nvram_size);
|
ha->nvram_size);
|
||||||
@ -3520,8 +3524,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
|||||||
chksum += le32_to_cpu(*dptr++);
|
chksum += le32_to_cpu(*dptr++);
|
||||||
|
|
||||||
DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
|
DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
|
||||||
DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring,
|
DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size));
|
||||||
ha->nvram_size));
|
|
||||||
|
|
||||||
/* Bad NVRAM data, set defaults parameters. */
|
/* Bad NVRAM data, set defaults parameters. */
|
||||||
if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P'
|
if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P'
|
||||||
|
Reference in New Issue
Block a user