]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/qla2xxx/qla_sup.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[linux-2.6-omap-h63xx.git] / drivers / scsi / qla2xxx / qla_sup.c
index 40b059fc19813db3c5c3f41bd0b2482d09db4731..b68fb73613ed1a69ba6cb4774e0ea202bc27ab45 100644 (file)
@@ -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);
@@ -21,7 +22,7 @@ static void qla2x00_nv_write(scsi_qla_host_t *, uint16_t);
  * qla2x00_lock_nvram_access() -
  * @ha: HA context
  */
-void
+static void
 qla2x00_lock_nvram_access(scsi_qla_host_t *ha)
 {
        uint16_t data;
@@ -54,7 +55,7 @@ qla2x00_lock_nvram_access(scsi_qla_host_t *ha)
  * qla2x00_unlock_nvram_access() -
  * @ha: HA context
  */
-void
+static void
 qla2x00_unlock_nvram_access(scsi_qla_host_t *ha)
 {
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
@@ -73,7 +74,7 @@ qla2x00_unlock_nvram_access(scsi_qla_host_t *ha)
  *
  * Returns the word read from nvram @addr.
  */
-uint16_t
+static uint16_t
 qla2x00_get_nvram_word(scsi_qla_host_t *ha, uint32_t addr)
 {
        uint16_t        data;
@@ -92,7 +93,7 @@ qla2x00_get_nvram_word(scsi_qla_host_t *ha, uint32_t addr)
  * @addr: Address in NVRAM to write
  * @data: word to program
  */
-void
+static void
 qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
 {
        int count;
@@ -549,7 +550,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
        int ret;
        uint32_t liter, miter;
        uint32_t sec_mask, rest_addr, conf_addr;
-       uint32_t fdata, findex ;
+       uint32_t fdata, findex, cnt;
        uint8_t man_id, flash_id;
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
        dma_addr_t optrom_dma;
@@ -642,7 +643,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
                }
 
                /* Go with burst-write. */
-               if (optrom && (liter + OPTROM_BURST_DWORDS) < dwords) {
+               if (optrom && (liter + OPTROM_BURST_DWORDS) <= dwords) {
                        /* Copy data to DMA'ble buffer. */
                        for (miter = 0, s = optrom, d = dwptr;
                            miter < OPTROM_BURST_DWORDS; miter++, s++, d++)
@@ -656,7 +657,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
                                    "Unable to burst-write optrom segment "
                                    "(%x/%x/%llx).\n", ret,
                                    flash_data_to_access_addr(faddr),
-                                   optrom_dma);
+                                   (unsigned long long)optrom_dma);
                                qla_printk(KERN_WARNING, ha,
                                    "Reverting to slow-write.\n");
 
@@ -689,8 +690,14 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
                            0xff0000) | ((fdata >> 16) & 0xff));
        }
 
-       /* Enable flash write-protection. */
+       /* Enable flash write-protection and wait for completion. */
        qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c);
+       for (cnt = 300; cnt &&
+           qla24xx_read_flash_dword(ha,
+                   flash_conf_to_access_addr(0x005)) & BIT_0;
+           cnt--) {
+               udelay(10);
+       }
 
        /* Disable flash write. */
        WRT_REG_DWORD(&reg->ctrl_status,
@@ -745,9 +752,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 +773,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 +786,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);
@@ -812,6 +824,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;
 }
@@ -836,8 +849,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
@@ -1853,7 +1878,8 @@ qla25xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
                        qla_printk(KERN_WARNING, ha,
                            "Unable to burst-read optrom segment "
                            "(%x/%x/%llx).\n", rval,
-                           flash_data_to_access_addr(faddr), optrom_dma);
+                           flash_data_to_access_addr(faddr),
+                           (unsigned long long)optrom_dma);
                        qla_printk(KERN_WARNING, ha,
                            "Reverting to slow-read.\n");