diff options
author | Seokmann Ju <seokmann.ju@qlogic.com> | 2007-07-26 16:43:34 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-07-27 09:14:22 -0400 |
commit | 281afe1947d855661754850de29d7530b2ff18dc (patch) | |
tree | 25b085c0c759211b2c416c36b4603d131626b797 | |
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>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 39 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 19 |
3 files changed, 38 insertions, 24 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 | ||
108 | static ssize_t | 110 | static 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 | ||
315 | static ssize_t | 321 | static 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; |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 0c9f36c8a248..27ae3a532a55 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2340,10 +2340,14 @@ typedef struct scsi_qla_host { | |||
2340 | uint8_t serial2; | 2340 | uint8_t serial2; |
2341 | 2341 | ||
2342 | /* NVRAM configuration data */ | 2342 | /* NVRAM configuration data */ |
2343 | #define MAX_NVRAM_SIZE 4096 | ||
2344 | #define VPD_OFFSET MAX_NVRAM_SIZE / 2 | ||
2343 | uint16_t nvram_size; | 2345 | uint16_t nvram_size; |
2344 | uint16_t nvram_base; | 2346 | uint16_t nvram_base; |
2347 | void *nvram; | ||
2345 | uint16_t vpd_size; | 2348 | uint16_t vpd_size; |
2346 | uint16_t vpd_base; | 2349 | uint16_t vpd_base; |
2350 | void *vpd; | ||
2347 | 2351 | ||
2348 | uint16_t loop_reset_delay; | 2352 | uint16_t loop_reset_delay; |
2349 | uint8_t retry_count; | 2353 | uint8_t retry_count; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 5ec798c2bf13..374abe19b547 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1461,8 +1461,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1461 | uint16_t cnt; | 1461 | uint16_t cnt; |
1462 | uint8_t *dptr1, *dptr2; | 1462 | uint8_t *dptr1, *dptr2; |
1463 | init_cb_t *icb = ha->init_cb; | 1463 | init_cb_t *icb = ha->init_cb; |
1464 | nvram_t *nv = (nvram_t *)ha->request_ring; | 1464 | nvram_t *nv = ha->nvram; |
1465 | uint8_t *ptr = (uint8_t *)ha->request_ring; | 1465 | uint8_t *ptr = ha->nvram; |
1466 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 1466 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
1467 | 1467 | ||
1468 | rval = QLA_SUCCESS; | 1468 | rval = QLA_SUCCESS; |
@@ -1480,8 +1480,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1480 | chksum += *ptr++; | 1480 | chksum += *ptr++; |
1481 | 1481 | ||
1482 | DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no)); | 1482 | DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no)); |
1483 | DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring, | 1483 | DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size)); |
1484 | ha->nvram_size)); | ||
1485 | 1484 | ||
1486 | /* Bad NVRAM data, set defaults parameters. */ | 1485 | /* Bad NVRAM data, set defaults parameters. */ |
1487 | if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || | 1486 | if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || |
@@ -3500,7 +3499,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3500 | 3499 | ||
3501 | rval = QLA_SUCCESS; | 3500 | rval = QLA_SUCCESS; |
3502 | icb = (struct init_cb_24xx *)ha->init_cb; | 3501 | icb = (struct init_cb_24xx *)ha->init_cb; |
3503 | nv = (struct nvram_24xx *)ha->request_ring; | 3502 | nv = ha->nvram; |
3504 | 3503 | ||
3505 | /* Determine NVRAM starting address. */ | 3504 | /* Determine NVRAM starting address. */ |
3506 | ha->nvram_size = sizeof(struct nvram_24xx); | 3505 | ha->nvram_size = sizeof(struct nvram_24xx); |
@@ -3512,7 +3511,12 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3512 | ha->vpd_base = FA_NVRAM_VPD1_ADDR; | 3511 | ha->vpd_base = FA_NVRAM_VPD1_ADDR; |
3513 | } | 3512 | } |
3514 | 3513 | ||
3515 | /* Get NVRAM data and calculate checksum. */ | 3514 | /* Get VPD data into cache */ |
3515 | ha->vpd = ha->nvram + VPD_OFFSET; | ||
3516 | ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, | ||
3517 | ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4); | ||
3518 | |||
3519 | /* Get NVRAM data into cache and calculate checksum. */ | ||
3516 | dptr = (uint32_t *)nv; | 3520 | dptr = (uint32_t *)nv; |
3517 | ha->isp_ops->read_nvram(ha, (uint8_t *)dptr, ha->nvram_base, | 3521 | ha->isp_ops->read_nvram(ha, (uint8_t *)dptr, ha->nvram_base, |
3518 | ha->nvram_size); | 3522 | ha->nvram_size); |
@@ -3520,8 +3524,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3520 | chksum += le32_to_cpu(*dptr++); | 3524 | chksum += le32_to_cpu(*dptr++); |
3521 | 3525 | ||
3522 | DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no)); | 3526 | DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no)); |
3523 | DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring, | 3527 | DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size)); |
3524 | ha->nvram_size)); | ||
3525 | 3528 | ||
3526 | /* Bad NVRAM data, set defaults parameters. */ | 3529 | /* Bad NVRAM data, set defaults parameters. */ |
3527 | if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P' | 3530 | if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P' |