diff options
author | Seokmann Ju <seokmann.ju@qlogic.com> | 2007-07-26 13:43:34 -0700 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-07-27 09:14:22 -0400 |
commit | 281afe1947d855661754850de29d7530b2ff18dc (patch) | |
tree | 25b085c0c759211b2c416c36b4603d131626b797 /drivers/scsi/qla2xxx/qla_attr.c | |
parent | c835e3727b87115f98c612a5ecb8882826d2537e (diff) |
[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>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 1612f9200a52..0f2a9f5d801c 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -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; |