Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=281afe1947d855661754850de29d7530b2ff18dc
Commit:     281afe1947d855661754850de29d7530b2ff18dc
Parent:     c835e3727b87115f98c612a5ecb8882826d2537e
Author:     Seokmann Ju <[EMAIL PROTECTED]>
AuthorDate: Thu Jul 26 13:43:34 2007 -0700
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Fri Jul 27 09:14:22 2007 -0400

    [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 <[EMAIL PROTECTED]>.  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 <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/qla2xxx/qla_attr.c |   39 +++++++++++++++++++++++----------------
 drivers/scsi/qla2xxx/qla_def.h  |    4 ++++
 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 1612f92..0f2a9f5 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;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 0c9f36c..27ae3a5 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2340,10 +2340,14 @@ typedef struct scsi_qla_host {
        uint8_t         serial2;
 
        /* NVRAM configuration data */
+#define MAX_NVRAM_SIZE 4096
+#define VPD_OFFSET     MAX_NVRAM_SIZE / 2
        uint16_t        nvram_size;
        uint16_t        nvram_base;
+       void            *nvram;
        uint16_t        vpd_size;
        uint16_t        vpd_base;
+       void            *vpd;
 
        uint16_t        loop_reset_delay;
        uint8_t         retry_count;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 5ec798c..374abe1 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)
        uint16_t        cnt;
        uint8_t         *dptr1, *dptr2;
        init_cb_t       *icb = ha->init_cb;
-       nvram_t         *nv = (nvram_t *)ha->request_ring;
-       uint8_t         *ptr = (uint8_t *)ha->request_ring;
+       nvram_t         *nv = ha->nvram;
+       uint8_t         *ptr = ha->nvram;
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
        rval = QLA_SUCCESS;
@@ -1480,8 +1480,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
                chksum += *ptr++;
 
        DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
-       DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring,
-           ha->nvram_size));
+       DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size));
 
        /* Bad NVRAM data, set defaults parameters. */
        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;
        icb = (struct init_cb_24xx *)ha->init_cb;
-       nv = (struct nvram_24xx *)ha->request_ring;
+       nv = ha->nvram;
 
        /* Determine NVRAM starting address. */
        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;
        }
 
-       /* 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;
        ha->isp_ops->read_nvram(ha, (uint8_t *)dptr, ha->nvram_base,
            ha->nvram_size);
@@ -3520,8 +3524,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
                chksum += le32_to_cpu(*dptr++);
 
        DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
-       DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring,
-           ha->nvram_size));
+       DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size));
 
        /* Bad NVRAM data, set defaults parameters. */
        if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P'
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to