aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c39
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,
91{ 91{
92 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 92 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
93 struct device, kobj))); 93 struct device, kobj)));
94 unsigned long flags; 94 int size = ha->nvram_size;
95 char *nvram_cache = ha->nvram;
95 96
96 if (!capable(CAP_SYS_ADMIN) || off != 0) 97 if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
97 return 0; 98 return 0;
99 if (off + count > size) {
100 size -= off;
101 count = size;
102 }
98 103
99 /* Read NVRAM. */ 104 /* Read NVRAM data from cache. */
100 spin_lock_irqsave(&ha->hardware_lock, flags); 105 memcpy(buf, &nvram_cache[off], count);
101 ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->nvram_base,
102 ha->nvram_size);
103 spin_unlock_irqrestore(&ha->hardware_lock, flags);
104 106
105 return ha->nvram_size; 107 return count;
106} 108}
107 109
108static ssize_t 110static ssize_t
@@ -144,6 +146,8 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
144 /* Write NVRAM. */ 146 /* Write NVRAM. */
145 spin_lock_irqsave(&ha->hardware_lock, flags); 147 spin_lock_irqsave(&ha->hardware_lock, flags);
146 ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); 148 ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count);
149 ha->isp_ops->read_nvram(ha, (uint8_t *)&ha->nvram, ha->nvram_base,
150 count);
147 spin_unlock_irqrestore(&ha->hardware_lock, flags); 151 spin_unlock_irqrestore(&ha->hardware_lock, flags);
148 152
149 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 153 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
@@ -298,18 +302,20 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
298{ 302{
299 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 303 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
300 struct device, kobj))); 304 struct device, kobj)));
301 unsigned long flags; 305 int size = ha->vpd_size;
306 char *vpd_cache = ha->vpd;
302 307
303 if (!capable(CAP_SYS_ADMIN) || off != 0) 308 if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
304 return 0; 309 return 0;
310 if (off + count > size) {
311 size -= off;
312 count = size;
313 }
305 314
306 /* Read NVRAM. */ 315 /* Read NVRAM data from cache. */
307 spin_lock_irqsave(&ha->hardware_lock, flags); 316 memcpy(buf, &vpd_cache[off], count);
308 ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->vpd_base,
309 ha->vpd_size);
310 spin_unlock_irqrestore(&ha->hardware_lock, flags);
311 317
312 return ha->vpd_size; 318 return count;
313} 319}
314 320
315static ssize_t 321static ssize_t
@@ -327,6 +333,7 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
327 /* Write NVRAM. */ 333 /* Write NVRAM. */
328 spin_lock_irqsave(&ha->hardware_lock, flags); 334 spin_lock_irqsave(&ha->hardware_lock, flags);
329 ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); 335 ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count);
336 ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, ha->vpd_base, count);
330 spin_unlock_irqrestore(&ha->hardware_lock, flags); 337 spin_unlock_irqrestore(&ha->hardware_lock, flags);
331 338
332 return count; 339 return count;