Skip to content

Commit

Permalink
[SCSI] qla2xxx: Handle unaligned sector writes during NVRAM/VPD updates.
Browse files Browse the repository at this point in the history
Since both NVRAM and VPD regions of the flash reside on unaligned
sector boundaries, during update, the driver must perform a
read-modify-write operation to the composite NVRAM/VPD region.
This affects ISP25xx type boards only.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
Andrew Vasquez authored and James Bottomley committed Oct 23, 2007
1 parent a3a63d5 commit 2c96d8d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
6 changes: 0 additions & 6 deletions drivers/scsi/qla2xxx/qla_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
{
struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
struct device, kobj)));
unsigned long flags;
uint16_t cnt;

if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
Expand Down Expand Up @@ -144,11 +143,9 @@ 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);

Expand Down Expand Up @@ -397,16 +394,13 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
{
struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
struct device, kobj)));
unsigned long flags;

if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
return 0;

/* 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;
}
Expand Down
23 changes: 21 additions & 2 deletions drivers/scsi/qla2xxx/qla_sup.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "qla_def.h"

#include <linux/delay.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>

static uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t);
Expand Down Expand Up @@ -745,9 +746,11 @@ qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
int ret, stat;
uint32_t i;
uint16_t *wptr;
unsigned long flags;

ret = QLA_SUCCESS;

spin_lock_irqsave(&ha->hardware_lock, flags);
qla2x00_lock_nvram_access(ha);

/* Disable NVRAM write-protection. */
Expand All @@ -764,6 +767,7 @@ qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
qla2x00_set_nvram_protection(ha, stat);

qla2x00_unlock_nvram_access(ha);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

return ret;
}
Expand All @@ -776,9 +780,11 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
uint32_t i;
uint32_t *dwptr;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
unsigned long flags;

ret = QLA_SUCCESS;

spin_lock_irqsave(&ha->hardware_lock, flags);
/* Enable flash write. */
WRT_REG_DWORD(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
Expand Down Expand Up @@ -812,6 +818,7 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
WRT_REG_DWORD(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
spin_unlock_irqrestore(&ha->hardware_lock, flags);

return ret;
}
Expand All @@ -836,8 +843,20 @@ int
qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
uint32_t bytes)
{
return qla24xx_write_flash_data(ha, (uint32_t *)buf,
FA_VPD_NVRAM_ADDR | naddr, bytes >> 2);
#define RMW_BUFFER_SIZE (64 * 1024)
uint8_t *dbuf;

dbuf = vmalloc(RMW_BUFFER_SIZE);
if (!dbuf)
return QLA_MEMORY_ALLOC_FAILED;
ha->isp_ops->read_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2,
RMW_BUFFER_SIZE);
memcpy(dbuf + (naddr << 2), buf, bytes);
ha->isp_ops->write_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2,
RMW_BUFFER_SIZE);
vfree(dbuf);

return QLA_SUCCESS;
}

static inline void
Expand Down

0 comments on commit 2c96d8d

Please sign in to comment.