mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-18 23:18:20 +00:00
[SCSI] qla2xxx: Handle unaligned sector writes during NVRAM/VPD updates.
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>
This commit is contained in:
parent
a3a63d55a4
commit
2c96d8d0c1
@ -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)
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
@ -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. */
|
||||
@ -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;
|
||||
}
|
||||
@ -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(®->ctrl_status,
|
||||
RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE);
|
||||
@ -812,6 +818,7 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
|
||||
WRT_REG_DWORD(®->ctrl_status,
|
||||
RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE);
|
||||
RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user