diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_sup.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 6670ad585f28..c24f3d9dea76 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/vmalloc.h> | ||
10 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
11 | 12 | ||
12 | static uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t); | 13 | 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, | |||
745 | int ret, stat; | 746 | int ret, stat; |
746 | uint32_t i; | 747 | uint32_t i; |
747 | uint16_t *wptr; | 748 | uint16_t *wptr; |
749 | unsigned long flags; | ||
748 | 750 | ||
749 | ret = QLA_SUCCESS; | 751 | ret = QLA_SUCCESS; |
750 | 752 | ||
753 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
751 | qla2x00_lock_nvram_access(ha); | 754 | qla2x00_lock_nvram_access(ha); |
752 | 755 | ||
753 | /* Disable NVRAM write-protection. */ | 756 | /* Disable NVRAM write-protection. */ |
@@ -764,6 +767,7 @@ qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
764 | qla2x00_set_nvram_protection(ha, stat); | 767 | qla2x00_set_nvram_protection(ha, stat); |
765 | 768 | ||
766 | qla2x00_unlock_nvram_access(ha); | 769 | qla2x00_unlock_nvram_access(ha); |
770 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
767 | 771 | ||
768 | return ret; | 772 | return ret; |
769 | } | 773 | } |
@@ -776,9 +780,11 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
776 | uint32_t i; | 780 | uint32_t i; |
777 | uint32_t *dwptr; | 781 | uint32_t *dwptr; |
778 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 782 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
783 | unsigned long flags; | ||
779 | 784 | ||
780 | ret = QLA_SUCCESS; | 785 | ret = QLA_SUCCESS; |
781 | 786 | ||
787 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
782 | /* Enable flash write. */ | 788 | /* Enable flash write. */ |
783 | WRT_REG_DWORD(®->ctrl_status, | 789 | WRT_REG_DWORD(®->ctrl_status, |
784 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); | 790 | 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, | |||
812 | WRT_REG_DWORD(®->ctrl_status, | 818 | WRT_REG_DWORD(®->ctrl_status, |
813 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | 819 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); |
814 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 820 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
821 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
815 | 822 | ||
816 | return ret; | 823 | return ret; |
817 | } | 824 | } |
@@ -836,8 +843,20 @@ int | |||
836 | qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | 843 | qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, |
837 | uint32_t bytes) | 844 | uint32_t bytes) |
838 | { | 845 | { |
839 | return qla24xx_write_flash_data(ha, (uint32_t *)buf, | 846 | #define RMW_BUFFER_SIZE (64 * 1024) |
840 | FA_VPD_NVRAM_ADDR | naddr, bytes >> 2); | 847 | uint8_t *dbuf; |
848 | |||
849 | dbuf = vmalloc(RMW_BUFFER_SIZE); | ||
850 | if (!dbuf) | ||
851 | return QLA_MEMORY_ALLOC_FAILED; | ||
852 | ha->isp_ops->read_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2, | ||
853 | RMW_BUFFER_SIZE); | ||
854 | memcpy(dbuf + (naddr << 2), buf, bytes); | ||
855 | ha->isp_ops->write_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2, | ||
856 | RMW_BUFFER_SIZE); | ||
857 | vfree(dbuf); | ||
858 | |||
859 | return QLA_SUCCESS; | ||
841 | } | 860 | } |
842 | 861 | ||
843 | static inline void | 862 | static inline void |