From: "Erik Habbinga" The mpt_downloadboot function in drivers/message/fusion/mptbase.c doesn't work correctly on big endian systems (powerpc in my case). I've added appropriate le32_to_cpu calls to correctly translate little endian firmware file data into cpu endian format before getting written to little endian PCI registers. This patch has been tested successfully on a powerpc target and an Intel target. Signed-off-by: Erik Habbinga Cc: "Moore, Eric Dean" Signed-off-by: Andrew Morton --- drivers/message/fusion/mptbase.c | 28 ++++++++++++++-------------- 1 files changed, 14 insertions(+), 14 deletions(-) diff -puN drivers/message/fusion/mptbase.c~scsi-improve-endian-handling-in-lsi-fusion-firmware-mpt_downloadboot drivers/message/fusion/mptbase.c --- a/drivers/message/fusion/mptbase.c~scsi-improve-endian-handling-in-lsi-fusion-firmware-mpt_downloadboot +++ a/drivers/message/fusion/mptbase.c @@ -2893,7 +2893,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFw u32 ioc_state=0; ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n", - ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader)); + ioc->name, le32_to_cpu(pFwHeader->ImageSize), le32_to_cpu(pFwHeader->ImageSize), pFwHeader)); CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); @@ -2946,7 +2946,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFw /* Set the DiagRwEn and Disable ARM bits */ CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM)); - fwSize = (pFwHeader->ImageSize + 3)/4; + fwSize = (le32_to_cpu(pFwHeader->ImageSize) + 3)/4; ptrFw = (u32 *) pFwHeader; /* Write the LoadStartAddress to the DiagRw Address Register @@ -2955,23 +2955,23 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFw if (ioc->errata_flag_1064) pci_enable_io_access(ioc->pcidev); - CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress); + CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, le32_to_cpu(pFwHeader->LoadStartAddress)); ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n", - ioc->name, pFwHeader->LoadStartAddress)); + ioc->name, le32_to_cpu(pFwHeader->LoadStartAddress))); ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n", ioc->name, fwSize*4, ptrFw)); while (fwSize--) { - CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++); + CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, le32_to_cpu(*ptrFw++)); } - nextImage = pFwHeader->NextImageHeaderOffset; + nextImage = le32_to_cpu(pFwHeader->NextImageHeaderOffset); while (nextImage) { pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage); - load_addr = pExtImage->LoadStartAddress; + load_addr = le32_to_cpu(pExtImage->LoadStartAddress); - fwSize = (pExtImage->ImageSize + 3) >> 2; + fwSize = (le32_to_cpu(pExtImage->ImageSize) + 3) >> 2; ptrFw = (u32 *)pExtImage; ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n", @@ -2979,18 +2979,18 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFw CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr); while (fwSize--) { - CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++); + CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, le32_to_cpu(*ptrFw++)); } - nextImage = pExtImage->NextImageHeaderOffset; + nextImage = le32_to_cpu(pExtImage->NextImageHeaderOffset); } /* Write the IopResetVectorRegAddr */ - ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr)); - CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr); + ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, le32_to_cpu(pFwHeader->IopResetRegAddr))); + CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, le32_to_cpu(pFwHeader->IopResetRegAddr)); /* Write the IopResetVectorValue */ - ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue)); - CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue); + ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, le32_to_cpu(pFwHeader->IopResetVectorValue))); + CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, le32_to_cpu(pFwHeader->IopResetVectorValue)); /* Clear the internal flash bad bit - autoincrementing register, * so must do two writes. _