[alsa-devel] [PATCH 4/5] asihpi: replace volatile with barriers
Replace volatile with barriers where required. Other minor cleanups.
Signed-off-by: Eliot Blennerhassett <linux@audioscience.com --- diff -r 6def4892d3f5 pci/asihpi/hpi6205.c --- a/pci/asihpi/hpi6205.c Mon Mar 03 11:05:48 2008 +0100 +++ b/pci/asihpi/hpi6205.c Thu Mar 06 12:21:54 2008 +1300 @@ -27,6 +27,7 @@ (C) Copyright AudioScience Inc. 1998-2003
*******************************************************************************/ #define SOURCEFILE_NAME "hpi6205.c" + #include "hpi.h" #include "hpidebug.h" #include "hpi6205.h" @@ -35,42 +36,42 @@
/*****************************************************************************/ /* HPI6205 specific error codes */ -#define HPI6205_ERROR_BASE 1000 -#define HPI6205_ERROR_MEM_ALLOC 1001 -#define HPI6205_ERROR_6205_NO_IRQ 1002 -#define HPI6205_ERROR_6205_INIT_FAILED 1003 +#define HPI6205_ERROR_BASE 1000 +/*#define HPI6205_ERROR_MEM_ALLOC 1001 */ +#define HPI6205_ERROR_6205_NO_IRQ 1002 +#define HPI6205_ERROR_6205_INIT_FAILED 1003 /*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */ -#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005 -#define HPI6205_ERROR_6205_REG 1006 -#define HPI6205_ERROR_6205_DSPPAGE 1007 -#define HPI6205_ERROR_BAD_DSPINDEX 1008 -#define HPI6205_ERROR_C6713_HPIC 1009 -#define HPI6205_ERROR_C6713_HPIA 1010 -#define HPI6205_ERROR_C6713_PLL 1011 -#define HPI6205_ERROR_DSP_INTMEM 1012 -#define HPI6205_ERROR_DSP_EXTMEM 1013 -#define HPI6205_ERROR_DSP_PLD 1014 -#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015 -#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016 -#define HPI6205_ERROR_6205_EEPROM 1017 -#define HPI6205_ERROR_DSP_EMIF 1018 +#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005 +#define HPI6205_ERROR_6205_REG 1006 +#define HPI6205_ERROR_6205_DSPPAGE 1007 +#define HPI6205_ERROR_BAD_DSPINDEX 1008 +#define HPI6205_ERROR_C6713_HPIC 1009 +#define HPI6205_ERROR_C6713_HPIA 1010 +#define HPI6205_ERROR_C6713_PLL 1011 +#define HPI6205_ERROR_DSP_INTMEM 1012 +#define HPI6205_ERROR_DSP_EXTMEM 1013 +#define HPI6205_ERROR_DSP_PLD 1014 +#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015 +#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016 +#define HPI6205_ERROR_6205_EEPROM 1017 +#define HPI6205_ERROR_DSP_EMIF 1018
#define Hpi6205_Error(nDspIndex, err) (err) /*****************************************************************************/ /* for C6205 PCI i/f */ /* Host Status Register (HSR) bitfields */ -#define C6205_HSR_INTSRC 0x01 -#define C6205_HSR_INTAVAL 0x02 -#define C6205_HSR_INTAM 0x04 -#define C6205_HSR_CFGERR 0x08 -#define C6205_HSR_EEREAD 0x10 +#define C6205_HSR_INTSRC 0x01 +#define C6205_HSR_INTAVAL 0x02 +#define C6205_HSR_INTAM 0x04 +#define C6205_HSR_CFGERR 0x08 +#define C6205_HSR_EEREAD 0x10 /* Host-to-DSP Control Register (HDCR) bitfields */ -#define C6205_HDCR_WARMRESET 0x01 -#define C6205_HDCR_DSPINT 0x02 -#define C6205_HDCR_PCIBOOT 0x04 +#define C6205_HDCR_WARMRESET 0x01 +#define C6205_HDCR_DSPINT 0x02 +#define C6205_HDCR_PCIBOOT 0x04 /* DSP Page Register (DSPP) bitfields, */ /* defines 4 Mbyte page that BAR0 points to */ -#define C6205_DSPP_MAP1 0x400 +#define C6205_DSPP_MAP1 0x400
/* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP. * BAR1 maps to non-prefetchable 8 Mbyte memory block @@ -79,7 +80,7 @@ * needs to be added to the BAR1 base address set in the PCI config reg */ #define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L) -#define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET) +#define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET) #define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4) #define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
@@ -87,23 +88,23 @@ #define C6205_BAR0_TIMER1_CTL (0x01980000L)
/* For first 6713 in CE1 space, using DA17,16,2 */ -#define HPICL_ADDR 0x01400000L -#define HPICH_ADDR 0x01400004L -#define HPIAL_ADDR 0x01410000L -#define HPIAH_ADDR 0x01410004L -#define HPIDIL_ADDR 0x01420000L -#define HPIDIH_ADDR 0x01420004L -#define HPIDL_ADDR 0x01430000L -#define HPIDH_ADDR 0x01430004L - -#define C6713_EMIF_GCTL 0x01800000 -#define C6713_EMIF_CE1 0x01800004 -#define C6713_EMIF_CE0 0x01800008 -#define C6713_EMIF_CE2 0x01800010 -#define C6713_EMIF_CE3 0x01800014 -#define C6713_EMIF_SDRAMCTL 0x01800018 -#define C6713_EMIF_SDRAMTIMING 0x0180001C -#define C6713_EMIF_SDRAMEXT 0x01800020 +#define HPICL_ADDR 0x01400000L +#define HPICH_ADDR 0x01400004L +#define HPIAL_ADDR 0x01410000L +#define HPIAH_ADDR 0x01410004L +#define HPIDIL_ADDR 0x01420000L +#define HPIDIH_ADDR 0x01420004L +#define HPIDL_ADDR 0x01430000L +#define HPIDH_ADDR 0x01430004L + +#define C6713_EMIF_GCTL 0x01800000 +#define C6713_EMIF_CE1 0x01800004 +#define C6713_EMIF_CE0 0x01800008 +#define C6713_EMIF_CE2 0x01800010 +#define C6713_EMIF_CE3 0x01800014 +#define C6713_EMIF_SDRAMCTL 0x01800018 +#define C6713_EMIF_SDRAMTIMING 0x0180001C +#define C6713_EMIF_SDRAMEXT 0x01800020
struct hpi_hw_obj { /* PCI registers */ @@ -114,7 +115,7 @@ struct hpi_hw_obj { u32 dwDspPage;
struct consistent_dma_area hLockedMem; - volatile struct bus_master_interface *pInterfaceBuffer; + struct bus_master_interface *pInterfaceBuffer;
u16 flagOStreamJustReset[HPI_MAX_STREAMS]; /* a non-NULL handle means there is an HPI allocated buffer */ @@ -134,6 +135,17 @@ struct hpi_hw_obj { /* local prototypes */
#define CheckBeforeBBMCopy(status, pBBMData, lFirstWrite, lSecondWrite) + +static int WaitDspAck( + struct hpi_hw_obj *pHw6205, + int state, + int timeout_us +); + +static void SendDspCommand( + struct hpi_hw_obj *pHw6205, + int cmd +);
static u16 Hpi6205_AdapterBootLoadDsp( struct hpi_adapter_obj *pao, @@ -312,11 +324,13 @@ static void ControlMessage(
switch (phm->wFunction) { case HPI_CONTROL_GET_STATE: - if (pao->wHasControlCache) + if (pao->wHasControlCache) { + rmb(); /* make sure we see updates DMAed from DSP */ if (HpiCheckControlCache (&pHw6205->pControlCache[phm->u.c. wControlIndex], phm, phr)) break; + } HW_Message(pao, phm, phr); break; case HPI_CONTROL_GET_INFO: @@ -597,7 +611,7 @@ static u16 CreateAdapterObj( ) { struct hpi_hw_obj *pHw6205 = pao->priv; - volatile struct bus_master_interface *interface; + struct bus_master_interface *interface; u32 dwPhysAddr; u32 dwTimeOut = HPI6205_TIMEOUT; u32 dwTemp1; @@ -631,6 +645,7 @@ static u16 CreateAdapterObj(
HPI_DEBUG_LOG(DEBUG, "Interface buffer address %p\n", pHw6205->pInterfaceBuffer); + if (pHw6205->pInterfaceBuffer) { memset((void *)pHw6205->pInterfaceBuffer, 0, sizeof(struct bus_master_interface)); @@ -647,7 +662,7 @@ static u16 CreateAdapterObj(
/* allow boot load even if mem alloc wont work */ if (!pHw6205->pInterfaceBuffer) - return (Hpi6205_Error(0, HPI6205_ERROR_MEM_ALLOC)); + return (Hpi6205_Error(0, HPI_ERROR_MEMORY_ALLOC));
interface = pHw6205->pInterfaceBuffer;
@@ -671,14 +686,8 @@ static u16 CreateAdapterObj( iowrite32(C6205_HSR_INTSRC, pHw6205->prHSR);
/* make sure the DSP has started ok */ - dwTimeOut = 100; - while ((interface->dwDspAck != H620_HIF_RESET) && dwTimeOut) { - dwTimeOut--; - HpiOs_DelayMicroSeconds(10000); - } - - if (dwTimeOut == 0) { - HPI_DEBUG_LOG(ERROR, "Timed out waiting ack \n"); + if (!WaitDspAck(pHw6205, H620_HIF_RESET, HPI6205_TIMEOUT)) { + HPI_DEBUG_LOG(ERROR, "Timed out waiting reset state \n"); return (Hpi6205_Error(0, HPI6205_ERROR_6205_INIT_FAILED)); } /* Note that *pao, *pHw6205 are zeroed after allocation, @@ -746,14 +755,7 @@ static u16 CreateAdapterObj( } } } - /* set interface to idle */ - interface->dwHostCmd = H620_HIF_IDLE; - /* interrupt the DSP again */ - dwTemp1 = ioread32(pHw6205->prHDCR); - dwTemp1 |= (u32)C6205_HDCR_DSPINT; - iowrite32(dwTemp1, pHw6205->prHDCR); - dwTemp1 &= ~(u32)C6205_HDCR_DSPINT; - iowrite32(dwTemp1, pHw6205->prHDCR); + SendDspCommand(pHw6205, H620_HIF_IDLE);
{ struct hpi_message hM; @@ -789,7 +791,7 @@ static u16 CreateAdapterObj( }
HPI_DEBUG_LOG(VERBOSE, "Get adapter info OK\n"); - pao->wOpen = 0; /* upon creation the adapter is closed */ + pao->wOpen = 0; /* upon creation the adapter is closed */
HPI_DEBUG_LOG(INFO, "Bootload DSP OK\n"); return (0); @@ -872,8 +874,7 @@ static void OutStreamHostBufferAllocate( u32 dwCommand = phm->u.d.u.Buffer.dwCommand; /*u16 wStreamIndex = phm->u.d.wStreamIndex; */ struct hpi_hw_obj *pHw6205 = pao->priv; - volatile struct bus_master_interface *interface = - pHw6205->pInterfaceBuffer; + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
HPI_InitResponse(phr, phm->wObject, phm->wFunction, 0);
@@ -941,7 +942,7 @@ static void OutStreamHostBufferAllocate( /* GRANT phase. Set up the BBM status, tell the DSP about the buffer so it can start using BBM. */ - volatile struct hostbuffer_status_6205 *status; + struct hostbuffer_status_6205 *status;
if (phm->u.d.u.Buffer. dwBufferSize & (phm->u.d.u.Buffer.dwBufferSize - 1)) { @@ -1005,7 +1006,7 @@ static void OutStreamHostBufferFree( }
static long OutStreamGetSpaceAvailable( - volatile struct hostbuffer_status_6205 *status + struct hostbuffer_status_6205 *status ) { return status->dwSizeInBytes - ((long)(status->dwHostIndex) - @@ -1019,9 +1020,8 @@ static void OutStreamWrite( ) { struct hpi_hw_obj *pHw6205 = pao->priv; - volatile struct bus_master_interface *interface = - pHw6205->pInterfaceBuffer; - volatile struct hostbuffer_status_6205 *status; + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer; + struct hostbuffer_status_6205 *status; long dwSpaceAvailable; if (!pHw6205->OutStreamHostBufferSize[phm->u.d.wStreamIndex]) { /* there is no BBM buffer */ @@ -1126,9 +1126,8 @@ static void OutStreamGetInfo( ) { struct hpi_hw_obj *pHw6205 = pao->priv; - volatile struct bus_master_interface *interface = - pHw6205->pInterfaceBuffer; - volatile struct hostbuffer_status_6205 *status; + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer; + struct hostbuffer_status_6205 *status;
if (!pHw6205->OutStreamHostBufferSize[phm->u.d.wStreamIndex]) { HW_Message(pao, phm, phr); @@ -1188,13 +1187,13 @@ static void InStreamHostBufferAllocate( u16 err = 0; u32 dwCommand = phm->u.d.u.Buffer.dwCommand; struct hpi_hw_obj *pHw6205 = pao->priv; - volatile struct bus_master_interface *interface = - pHw6205->pInterfaceBuffer; + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
HPI_InitResponse(phr, phm->wObject, phm->wFunction, 0);
if (dwCommand == HPI_BUFFER_CMD_EXTERNAL || dwCommand == HPI_BUFFER_CMD_INTERNAL_ALLOC) { + phm->u.d.u.Buffer.dwBufferSize = roundup_pow_of_two(phm->u.d.u.Buffer.dwBufferSize); phr->u.d.u.stream_info.dwDataAvailable = @@ -1247,7 +1246,7 @@ static void InStreamHostBufferAllocate(
if (dwCommand == HPI_BUFFER_CMD_EXTERNAL || dwCommand == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) { - volatile struct hostbuffer_status_6205 *status; + struct hostbuffer_status_6205 *status;
if (phm->u.d.u.Buffer. dwBufferSize & (phm->u.d.u.Buffer.dwBufferSize - 1)) { @@ -1267,6 +1266,7 @@ static void InStreamHostBufferAllocate( status->dwDSPIndex = 0; status->dwHostIndex = status->dwDSPIndex; status->dwSizeInBytes = phm->u.d.u.Buffer.dwBufferSize; + HW_Message(pao, phm, phr); if (phr->wError && HpiOs_LockedMem_Valid(&pHw6205-> @@ -1297,10 +1297,10 @@ static void InStreamHostBufferFree( }
if (dwCommand == HPI_BUFFER_CMD_EXTERNAL || - dwCommand == HPI_BUFFER_CMD_INTERNAL_FREE) { + dwCommand == HPI_BUFFER_CMD_INTERNAL_FREE) HpiOs_LockedMem_Free(&pHw6205-> InStreamHostBuffers[phm->u.d.wStreamIndex]); - } + } else { /* Should HPI_ERROR_INVALID_OPERATION be returned if no host buffer is allocated? */ @@ -1321,7 +1321,7 @@ static void InStreamStart( }
static long InStreamGetBytesAvailable( - volatile struct hostbuffer_status_6205 *status + struct hostbuffer_status_6205 *status ) { return (long)(status->dwDSPIndex) - (long)(status->dwHostIndex); @@ -1334,9 +1334,8 @@ static void InStreamRead( ) { struct hpi_hw_obj *pHw6205 = pao->priv; - volatile struct bus_master_interface *interface = - pHw6205->pInterfaceBuffer; - volatile struct hostbuffer_status_6205 *status; + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer; + struct hostbuffer_status_6205 *status; long dwDataAvailable; u8 *pBBMData; long lFirstRead; @@ -1387,9 +1386,8 @@ static void InStreamGetInfo( ) { struct hpi_hw_obj *pHw6205 = pao->priv; - volatile struct bus_master_interface *interface = - pHw6205->pInterfaceBuffer; - volatile struct hostbuffer_status_6205 *status; + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer; + struct hostbuffer_status_6205 *status; if (!pHw6205->InStreamHostBufferSize[phm->u.d.wStreamIndex]) { HW_Message(pao, phm, phr); return; @@ -1451,7 +1449,7 @@ static u16 Hpi6205_AdapterBootLoadDsp( dwTemp = C6205_HDCR_WARMRESET; iowrite32(dwTemp, pHw6205->prHDCR); HpiOs_DelayMicroSeconds(1000); -/* for(i=0;i<1000; i++) dwTemp = ioread32(pao,pHw6205->prHDCR); */ +/* for(i=0;i<1000; i++) dwTemp = ioread32(pao,pHw6205->prHDCR); */
/* check that PCI i/f was configured by EEPROM */ dwTemp = ioread32(pHw6205->prHSR); @@ -1620,7 +1618,7 @@ static u16 Hpi6205_AdapterBootLoadDsp( if (pHw6205->pInterfaceBuffer) { /* we need to tell the card the physical PCI address */ u32 dwPhysicalPCIaddress; - volatile struct bus_master_interface *interface = + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer; u32 dwHostMailboxAddressOnDsp; u32 dwPhysicalPCIaddressVerify = 0; @@ -1628,6 +1626,7 @@ static u16 Hpi6205_AdapterBootLoadDsp( /* set ack so we know when DSP is ready to go */ /* (dwDspAck will be changed to HIF_RESET) */ interface->dwDspAck = H620_HIF_UNKNOWN; + wmb(); /* ensure ack is written before dsp writes back */
err = HpiOs_LockedMem_GetPhysAddr(&pHw6205->hLockedMem, &dwPhysicalPCIaddress); @@ -1715,7 +1714,7 @@ static u16 BootLoader_WriteMem32( struct hpi_hw_obj *pHw6205 = pao->priv; u16 err = 0; __iomem u32 *pData; - /* u32 dwVerifyData=0; */ + /* u32 dwVerifyData=0; */
if (nDSPIndex == 0) { /* DSP 0 is always C6205 */ @@ -1771,8 +1770,8 @@ static u16 BootLoader_ConfigEMIF(
/* Set the EMIF */ /* memory map of C6205 */ - /* 00000000-0000FFFF 16Kx32 internal program */ - /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */ + /* 00000000-0000FFFF 16Kx32 internal program */ + /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
/* EMIF config */ /*------------ */ @@ -1899,7 +1898,7 @@ static u16 BootLoader_ConfigEMIF( BootLoader_WriteMem32(pao, nDSPIndex, 0x01B7C120, 0x8002); /* peri = 189/2 */ BootLoader_WriteMem32(pao, nDSPIndex, 0x01B7C11C, 0x8001); - /* cpu = 189/1 */ + /* cpu = 189/1 */ BootLoader_WriteMem32(pao, nDSPIndex, 0x01B7C118, 0x8000); HpiOs_DelayMicroSeconds(1000); /* ** SGT test to take GPO3 high when we start the PLL */ @@ -1980,15 +1979,15 @@ static u16 BootLoader_TestMemory( dwTestAddr); if (dwData != dwTestData) { HPI_DEBUG_LOG(VERBOSE, - "Memtest error details " + "Memtest error details " "%08x %08x %08x %i\n", dwTestAddr, dwTestData, dwData, nDSPIndex); return (1); /* error */ } dwTestData = dwTestData << 1; - } /* for(j) */ - } /* for(i) */ + } /* for(j) */ + } /* for(i) */
/* for the next 100 locations test each location, leaving it as zero */ /* write a zero to the next word in memory before we read */ @@ -2001,7 +2000,7 @@ static u16 BootLoader_TestMemory( dwData = BootLoader_ReadMem32(pao, nDSPIndex, dwTestAddr); if (dwData != dwTestData) { HPI_DEBUG_LOG(VERBOSE, - "Memtest error details " + "Memtest error details " "%08x %08x %08x %i\n", dwTestAddr, dwTestData, dwData, nDSPIndex); return (1); /* error */ @@ -2015,7 +2014,7 @@ static u16 BootLoader_TestMemory( dwTestAddr = dwStartAddress + (u32)i *4; BootLoader_WriteMem32(pao, nDSPIndex, dwTestAddr, 0x0); } - return (0); /*success! */ + return (0); /*success! */ }
static u16 BootLoader_TestInternalMemory( @@ -2134,22 +2133,14 @@ static short Hpi6205_TransferData( /*u8 *pData =(u8 *)phm->u.d.u.Data.dwpbData; */ /*u16 wTimeOut=8; */ u16 err = 0; - u32 dwTimeOut, dwTemp1, dwTemp2; - volatile struct bus_master_interface *interface = - pHw6205->pInterfaceBuffer; + u32 dwTimeOut, dwTemp2; + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
dwDataSize &= ~3L; /* round dwDataSize down to nearest 4 bytes */
/* make sure state is IDLE */ - dwTimeOut = HPI6205_TIMEOUT; - dwTemp2 = 0; - while ((interface->dwDspAck != H620_HIF_IDLE) && dwTimeOut--) - HpiOs_DelayMicroSeconds(1); - - if (interface->dwDspAck != H620_HIF_IDLE) + if (!WaitDspAck(pHw6205, H620_HIF_IDLE, HPI6205_TIMEOUT)) return HPI_ERROR_DSP_HARDWARE; - - interface->dwHostCmd = nOperation;
while (dwDataTransferred < dwDataSize) { u32 nThisCopy = dwDataSize - dwDataTransferred; @@ -2162,13 +2153,7 @@ static short Hpi6205_TransferData( &pData[dwDataTransferred], nThisCopy);
interface->dwTransferSizeInBytes = nThisCopy; - - /* interrupt the DSP */ - dwTemp1 = ioread32(pHw6205->prHDCR); - dwTemp1 |= (u32)C6205_HDCR_DSPINT; - iowrite32(dwTemp1, pHw6205->prHDCR); - dwTemp1 &= ~(u32)C6205_HDCR_DSPINT; - iowrite32(dwTemp1, pHw6205->prHDCR); + SendDspCommand(pHw6205, nOperation);
/* spin waiting on the result */ dwTimeOut = HPI6205_TIMEOUT; @@ -2212,20 +2197,55 @@ static short Hpi6205_TransferData( if (interface->dwDspAck != nOperation) HPI_DEBUG_LOG(DEBUG, "interface->dwDspAck=%d, expected %d\n", interface->dwDspAck, nOperation); - /* err=HPI_ERROR_DSP_HARDWARE; */ - - /* set interface back to idle */ - interface->dwHostCmd = H620_HIF_IDLE; - /* interrupt the DSP again */ - dwTemp1 = ioread32(pHw6205->prHDCR); - dwTemp1 |= (u32)C6205_HDCR_DSPINT; - iowrite32(dwTemp1, pHw6205->prHDCR); - dwTemp1 &= ~(u32)C6205_HDCR_DSPINT; - iowrite32(dwTemp1, pHw6205->prHDCR); + /* err=HPI_ERROR_DSP_HARDWARE; */ + + SendDspCommand(pHw6205, H620_HIF_IDLE);
return err; }
+/* wait for up to timeout_us microseconds for the DSP + to signal state by DMA into dwDspAck +*/ +static int WaitDspAck( + struct hpi_hw_obj *pHw6205, + int state, + int timeout_us +) +{ + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer; + int t = timeout_us / 4; + + rmb(); /* ensure interface->dwDspAck is up to date */ + while ((interface->dwDspAck != state) && t--) { + HpiOs_DelayMicroSeconds(4); + rmb(); /* DSP changes dwDspAck by DMA */ + } + + /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */ + return t; +} + +/* set the busmaster interface to cmd, then interrupt the DSP */ +static void SendDspCommand( + struct hpi_hw_obj *pHw6205, + int cmd +) +{ + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer; + + u32 r; + + interface->dwHostCmd = cmd; + wmb(); /* DSP gets state by DMA, make sure it is written to memory */ + /* before we interrupt the DSP */ + r = ioread32(pHw6205->prHDCR); + r |= (u32)C6205_HDCR_DSPINT; + iowrite32(r, pHw6205->prHDCR); + r &= ~(u32)C6205_HDCR_DSPINT; + iowrite32(r, pHw6205->prHDCR); +} + static unsigned int messageCount;
static u16 Hpi6205_MessageResponseSequence( @@ -2234,46 +2254,26 @@ static u16 Hpi6205_MessageResponseSequen struct hpi_response *phr ) { - u32 dwTemp1, dwTemp2, dwTimeOut, dwTimeOut2; + u32 dwTemp2, dwTimeOut, dwTimeOut2; struct hpi_hw_obj *pHw6205 = pao->priv; - volatile struct bus_master_interface *interface = - pHw6205->pInterfaceBuffer; + struct bus_master_interface *interface = pHw6205->pInterfaceBuffer; u16 err = 0;
messageCount++; /* Assume buffer of type struct bus_master_interface is allocated "noncacheable" */
- /* make sure state is IDLE */ - dwTimeOut = HPI6205_TIMEOUT; - dwTemp2 = 0; - while ((interface->dwDspAck != H620_HIF_IDLE) && --dwTimeOut) - HpiOs_DelayMicroSeconds(1); - - if (dwTimeOut == 0) { + if (!WaitDspAck(pHw6205, H620_HIF_IDLE, HPI6205_TIMEOUT)) { HPI_DEBUG_LOG(DEBUG, "Timeout waiting for idle\n"); return (Hpi6205_Error (0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT)); } interface->u.MessageBuffer = *phm; /* signal we want a response */ - interface->dwHostCmd = H620_HIF_GET_RESP; - - /* interrupt the DSP */ - dwTemp1 = ioread32(pHw6205->prHDCR); - dwTemp1 |= (u32)C6205_HDCR_DSPINT; - HpiOs_DelayMicroSeconds(1); - iowrite32(dwTemp1, pHw6205->prHDCR); - dwTemp1 &= ~(u32)C6205_HDCR_DSPINT; - iowrite32(dwTemp1, pHw6205->prHDCR); - - /* spin waiting on state change (start of msg process) */ - dwTimeOut2 = HPI6205_TIMEOUT; - dwTemp2 = 0; - while ((interface->dwDspAck != H620_HIF_GET_RESP) && --dwTimeOut2) { - dwTemp2 = ioread32(pHw6205->prHSR); - dwTemp2 &= C6205_HSR_INTSRC; - } + SendDspCommand(pHw6205, H620_HIF_GET_RESP); + + dwTimeOut2 = WaitDspAck(pHw6205, H620_HIF_GET_RESP, HPI6205_TIMEOUT); + if (dwTimeOut2 == 0) { HPI_DEBUG_LOG(DEBUG, "(%u)Timed out waiting for " @@ -2284,16 +2284,16 @@ static u16 Hpi6205_MessageResponseSequen "(%u)Transition to GET_RESP after %u\n", messageCount, HPI6205_TIMEOUT - dwTimeOut2); } - /* spin waiting on HIF interrupt flag (end of msg process) */ dwTimeOut = HPI6205_TIMEOUT; dwTemp2 = 0; while ((dwTemp2 == 0) && --dwTimeOut) { dwTemp2 = ioread32(pHw6205->prHSR); dwTemp2 &= C6205_HSR_INTSRC; - /* HpiOs_DelayMicroSeconds(5); */ + HpiOs_DelayMicroSeconds(1); } if (dwTemp2 == C6205_HSR_INTSRC) { + rmb(); /* ensure we see latest value for dwDspAck */ if ((interface->dwDspAck != H620_HIF_GET_RESP)) { HPI_DEBUG_LOG(DEBUG, "(%u)interface->dwDspAck(0x%x) != " @@ -2306,12 +2306,12 @@ static u16 Hpi6205_MessageResponseSequen messageCount, HPI6205_TIMEOUT - dwTimeOut); }
- } -/* need to handle this differently... */ - else + } else { + /* can we do anything else in response to the error ? */ HPI_DEBUG_LOG(ERROR, "Interrupt from HIF module BAD (wFunction %x)\n", phm->wFunction); + }
/* reset the interrupt from the DSP */ iowrite32(C6205_HSR_INTSRC, pHw6205->prHSR); @@ -2321,15 +2321,8 @@ static u16 Hpi6205_MessageResponseSequen *phr = interface->u.ResponseBuffer;
/* set interface back to idle */ - interface->dwHostCmd = H620_HIF_IDLE; - /* interrupt the DSP again */ - dwTemp1 = ioread32(pHw6205->prHDCR); - dwTemp1 |= (u32)C6205_HDCR_DSPINT; - iowrite32(dwTemp1, pHw6205->prHDCR); - dwTemp1 &= ~(u32)C6205_HDCR_DSPINT; - iowrite32(dwTemp1, pHw6205->prHDCR); - -/* EWB move timeoutcheck to after IDLE command, maybe recover? */ + SendDspCommand(pHw6205, H620_HIF_IDLE); + if ((dwTimeOut == 0) || (dwTimeOut2 == 0)) { HPI_DEBUG_LOG(DEBUG, "Something timed out!\n"); return Hpi6205_Error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT); @@ -2337,13 +2330,7 @@ static u16 Hpi6205_MessageResponseSequen /* special case for adapter close - */ /* wait for the DSP to indicate it is idle */ if (phm->wFunction == HPI_ADAPTER_CLOSE) { - /* make sure state is IDLE */ - dwTimeOut = HPI6205_TIMEOUT; - dwTemp2 = 0; - while ((interface->dwDspAck != H620_HIF_IDLE) && --dwTimeOut) - HpiOs_DelayMicroSeconds(1); - - if (dwTimeOut == 0) { + if (!WaitDspAck(pHw6205, H620_HIF_IDLE, HPI6205_TIMEOUT)) { HPI_DEBUG_LOG(DEBUG, "Timeout waiting for idle " "(on AdapterClose)\n"); diff -r 6def4892d3f5 pci/asihpi/hpicmn.c --- a/pci/asihpi/hpicmn.c Mon Mar 03 11:05:48 2008 +0100 +++ b/pci/asihpi/hpicmn.c Thu Mar 06 12:21:31 2008 +1300 @@ -148,7 +148,7 @@ static void SubSysGetAdapters(
/* input: NONE */ /* output: wNumAdapters */ - /* awAdapter[] */ + /* awAdapter[] */ /* */
short i; @@ -178,7 +178,7 @@ static void SubSysGetAdapters( * It returns nonzero if a cache hit occurred, zero otherwise. */ short HpiCheckControlCache( - volatile struct hpi_control_cache_single *pC, + struct hpi_control_cache_single *pC, struct hpi_message *phm, struct hpi_response *phr ) @@ -301,7 +301,7 @@ Multiplexer does so use sent values Multiplexer does so use sent values */ void HpiSyncControlCache( - volatile struct hpi_control_cache_single *pC, + struct hpi_control_cache_single *pC, struct hpi_message *phm, struct hpi_response *phr ) diff -r 6def4892d3f5 pci/asihpi/hpicmn.h --- a/pci/asihpi/hpicmn.h Mon Mar 03 11:05:48 2008 +0100 +++ b/pci/asihpi/hpicmn.h Thu Mar 06 12:21:30 2008 +1300 @@ -44,12 +44,12 @@ void HpiDeleteAdapter( );
short HpiCheckControlCache( - volatile struct hpi_control_cache_single *pC, + struct hpi_control_cache_single *pC, struct hpi_message *phm, struct hpi_response *phr ); void HpiSyncControlCache( - volatile struct hpi_control_cache_single *pC, + struct hpi_control_cache_single *pC, struct hpi_message *phm, struct hpi_response *phr );
participants (1)
-
Eliot Blennerhassett