aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorSeokmann Ju <seokmann.ju@qlogic.com>2007-07-26 16:43:34 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-07-27 09:14:22 -0400
commit281afe1947d855661754850de29d7530b2ff18dc (patch)
tree25b085c0c759211b2c416c36b4603d131626b797 /drivers/scsi
parentc835e3727b87115f98c612a5ecb8882826d2537e (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')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c39
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c19
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
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;
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'