PRIVATE IX_STATUS ixTimeSyncAccCodeletDispatcherStart () { /* get dispatcher function pointer, this should be initialized once */ ixQMgrDispatcherLoopGet(&ixTimeSyncAccCodeletDispatcherFunc); if (NULL == ixTimeSyncAccCodeletDispatcherFunc) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletDispatcherStart: failed to get dispatcher function pointer\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } /* Hook the QM QLOW dispatcher to the interrupt controller */ if (IX_SUCCESS != ixOsalIrqBind(IX_OSAL_IXP400_QM1_IRQ_LVL, (IxOsalVoidFnVoidPtr)(ixTimeSyncAccCodeletDispatcherFunc), (void *)IX_QMGR_QUELOW_GROUP)) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletDispatcherStart: failed to hook QM QLOW dispatcher to the interrupt controller\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } return (IX_SUCCESS); } /* end of ixTimeSyncAccCodeletDispatcherStart function */
IX_STATUS ixParityENAccSwcpPEInit (IxParityENAccInternalCallback ixSwcpPECallback) { /* Verify parameters */ if ((IxParityENAccInternalCallback)NULL == ixSwcpPECallback) { return IX_FAIL; } /* end of if */ /* Register main module internal callback routine */ ixParityENAccSwcpPEConfig.swcpPECallback = ixSwcpPECallback; /* Interrupt Service Routine Info */ ixParityENAccSwcpPEConfig.swcpIsrInfo.swcpInterruptId = IRQ_IXP400_INTC_PARITYENACC_SWCP; ixParityENAccSwcpPEConfig.swcpIsrInfo.swcpIsr = ixParityENAccSwcpPEIsr; /* Install SWCP Interrupt Service Routine */ { INT32 lockKey = ixOsalIrqLock(); if ((IX_SUCCESS != ixOsalIrqBind ((UINT32) IRQ_IXP400_INTC_PARITYENACC_SWCP, (IxOsalVoidFnVoidPtr) ixParityENAccSwcpPEIsr, (void *) NULL)) || (IX_SUCCESS != ixParityENAccIcInterruptDisable( IXP400_PARITYENACC_INTC_SWCP_PARITY_INTERRUPT))) { ixOsalIrqUnlock(lockKey); return IX_FAIL; } /* end of if */ ixOsalIrqUnlock(lockKey); } return IX_SUCCESS; } /* end of ixParityENAccSwcpPEInit() function */
IX_STATUS ixParityENAccAqmPEInit (IxParityENAccInternalCallback ixAqmPECallback) { UINT32 aqmVirtualBaseAddr = 0; /* Verify parameters */ if ((IxParityENAccInternalCallback)NULL == ixAqmPECallback) { return IX_FAIL; } /* end of if */ /* Memory mapping of the AQM registers */ aqmVirtualBaseAddr = (UINT32) IX_OSAL_MEM_MAP ( IXP400_PARITYENACC_AQM_BASEADDR, IXP400_PARITYENACC_AQM_MEMMAP_SIZE); if ((UINT32)NULL == aqmVirtualBaseAddr) { return IX_FAIL; } /* end of if */ /* Virtual Addresses assignment for AQM Registers */ ixParityENAccAqmPEConfig.aqmPERegisters.aqmQueAddErr = aqmVirtualBaseAddr + IXP400_PARITYENACC_AQM_QUEADDRERR_OFFSET; ixParityENAccAqmPEConfig.aqmPERegisters.aqmQueDataErr = aqmVirtualBaseAddr + IXP400_PARITYENACC_AQM_QUEDATAERR_OFFSET; /* Register main module internal callback routine for AQM */ ixParityENAccAqmPEConfig.aqmPECallback = ixAqmPECallback; /* Interrupt Service Routine Info for AQM for debug purpose */ ixParityENAccAqmPEConfig.aqmIsrInfo.aqmInterruptId = IRQ_IXP400_INTC_PARITYENACC_AQM; ixParityENAccAqmPEConfig.aqmIsrInfo.aqmIsr = ixParityENAccAqmPEIsr; /* Disable parity error detection */ IXP400_PARITYENACC_REG_BIT_CLEAR( ixParityENAccAqmPEConfig.aqmPERegisters.aqmQueAddErr, IXP400_PARITYENACC_AQM_QUEADDRERR_PERR_ENABLE | IXP400_PARITYENACC_AQM_QUEADDRERR_PERR_FLAG); /* Install AQM Interrupt Service Routine */ { INT32 lockKey = ixOsalIrqLock(); if ((IX_SUCCESS != ixOsalIrqBind ((UINT32) IRQ_IXP400_INTC_PARITYENACC_AQM, (IxOsalVoidFnVoidPtr) ixParityENAccAqmPEIsr, (void *) NULL)) || (IX_SUCCESS != ixParityENAccIcInterruptDisable( IXP400_PARITYENACC_INTC_AQM_PARITY_INTERRUPT))) { ixOsalIrqUnlock(lockKey); IX_OSAL_MEM_UNMAP(aqmVirtualBaseAddr); return IX_FAIL; } /* end of if */ ixOsalIrqUnlock(lockKey); } return IX_SUCCESS; } /* end of ixParityENAccAqmPEInit() function */
/* * Function definition : ixDmaAccCodeletDispatcherStart() * See header file for documentation. */ PRIVATE IX_STATUS ixDmaAccCodeletDispatcherStart(BOOL useInterrupt) { IxOsalThreadAttr threadAttr; char *pThreadName = "Dispatcher"; ixQMgrDispatcherLoopGet(&ixDmaAccCodeletDispatcherFunc); if(useInterrupt) /* Interrupt mode */ { /* * Hook the QM QLOW dispatcher to the interrupt controller. * IX_QMGR_QUELOW_GROUP refers to Queues 0-31 * Dma NPE A: queues 19 & 20; NPE B: 24 & 26; NPE B: 25 & 27 */ if (ixOsalIrqBind(IX_OSAL_IXP400_QM1_IRQ_LVL, (IxOsalVoidFnVoidPtr)ixDmaAccCodeletDispatcherFunc, (void *)IX_QMGR_QUELOW_GROUP) != IX_SUCCESS) { printf("\nFailed to bind to QM1 interrupt"); return (IX_FAIL); } } else /* Polled mode */ { threadAttr.name = pThreadName; threadAttr.stackSize = IX_DMA_CODELET_QMGR_STACK_SIZE; threadAttr.priority = IX_DMA_CODELET_QMR_PRIORITY; if (ixOsalThreadCreate(&ixDmaAccCodeletDispatchId, &threadAttr, (IxOsalVoidFnVoidPtr)ixDmaAccCodeletDispatcherPoll, NULL ) != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "\nError spawning dispatch task", 0,0,0,0,0,0); return (IX_FAIL); } if (ixOsalThreadStart (&ixDmaAccCodeletDispatchId) != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "\nError starting spawing dispatch task", 0,0,0,0,0,0); return (IX_FAIL); } } return (IX_SUCCESS); }
IX_STATUS ixParityENAccEbcPEInit (IxParityENAccInternalCallback ixEbcPECallback) { UINT32 ebcVirtualBaseAddr = 0; IxParityENAccChipSelectId csId = IXP400_PARITYENACC_PE_EBC_CHIPSEL0; register IxParityENAccEbcPERegisters *ebcPERegisters = &ixParityENAccEbcPEConfig.ebcPERegisters; /* Verify parameters */ if ((IxParityENAccInternalCallback)NULL == ixEbcPECallback) { return IX_FAIL; } /* end of if */ /* Memory mapping of the EBC registers */ if ((UINT32)NULL == (ebcVirtualBaseAddr = (UINT32) IX_OSAL_MEM_MAP ( IXP400_PARITYENACC_EBC_BASEADDR, IXP400_PARITYENACC_EBC_MEMMAP_SIZE))) { return IX_FAIL; } /* end of if */ /* Virtual Addresses assignment for EBC Registers */ ebcPERegisters->expTimingCs[IXP400_PARITYENACC_PE_EBC_CHIPSEL0] = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_TIMING_CS0_OFFSET; ebcPERegisters->expTimingCs[IXP400_PARITYENACC_PE_EBC_CHIPSEL1] = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_TIMING_CS1_OFFSET; ebcPERegisters->expTimingCs[IXP400_PARITYENACC_PE_EBC_CHIPSEL2] = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_TIMING_CS2_OFFSET; ebcPERegisters->expTimingCs[IXP400_PARITYENACC_PE_EBC_CHIPSEL3] = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_TIMING_CS3_OFFSET; ebcPERegisters->expTimingCs[IXP400_PARITYENACC_PE_EBC_CHIPSEL4] = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_TIMING_CS4_OFFSET; ebcPERegisters->expTimingCs[IXP400_PARITYENACC_PE_EBC_CHIPSEL5] = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_TIMING_CS5_OFFSET; ebcPERegisters->expTimingCs[IXP400_PARITYENACC_PE_EBC_CHIPSEL6] = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_TIMING_CS6_OFFSET; ebcPERegisters->expTimingCs[IXP400_PARITYENACC_PE_EBC_CHIPSEL7] = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_TIMING_CS7_OFFSET; ebcPERegisters->expMstControl = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_MST_CONTROL_OFFSET; ebcPERegisters->expParityStatus = ebcVirtualBaseAddr + IXP400_PARITYENACC_EBC_PARITY_STATUS_OFFSET; /* Register main module internal callback routine */ ixParityENAccEbcPEConfig.ebcPECallback = ixEbcPECallback; /* Interrupt Service Routine Info for debug purpose */ ixParityENAccEbcPEConfig.ebcIsrInfo.ebcInterruptId = IRQ_IXP400_INTC_PARITYENACC_EBC; ixParityENAccEbcPEConfig.ebcIsrInfo.ebcIsr = ixParityENAccEbcPEIsr; /* Disable parity error detection on both Inbound & Outbound interfaces */ for (; csId < IXP400_PARITYENACC_PE_EBC_CHIPSEL_MAX; csId++) { IXP400_PARITYENACC_REG_BIT_CLEAR(ebcPERegisters->expTimingCs[csId], IXP400_PARITYENACC_EBC_TIMING_CSX_PAR_EN); } /* end of for */ IXP400_PARITYENACC_REG_BIT_CLEAR(ebcPERegisters->expMstControl, IXP400_PARITYENACC_EBC_MST_CONTROL_INPAR_EN); /* Install EBC Interrupt Service Routine */ { INT32 lockKey = ixOsalIrqLock(); if ((IX_SUCCESS != ixOsalIrqBind ((UINT32) IRQ_IXP400_INTC_PARITYENACC_EBC, (IxOsalVoidFnVoidPtr) ixParityENAccEbcPEIsr, (void *) NULL)) || (IX_SUCCESS != ixParityENAccIcInterruptDisable( IXP400_PARITYENACC_INTC_EBC_PARITY_INTERRUPT))) { ixOsalIrqUnlock(lockKey); IX_OSAL_MEM_UNMAP(ebcVirtualBaseAddr); return IX_FAIL; } /* end of if */ ixOsalIrqUnlock(lockKey); } return IX_SUCCESS; } /* end of ixParityENAccEbcPEInit() function */
/* -------------------------------------------------------------- Initialise system components used by the Atm Codelet. -------------------------------------------------------------- */ PUBLIC IX_STATUS ixAtmCodeletSystemInit (UINT32 numPorts, IxAtmCodeletMode mode) { IX_STATUS retval = IX_SUCCESS; #if IX_UTOPIAMODE == 1 IxAtmmPhyMode phyMode = IX_ATMM_SPHY_MODE; #else IxAtmmPhyMode phyMode = IX_ATMM_MPHY_MODE; #endif IxOsalThread dispatchtid; IxOsalThreadAttr threadAttr; char *pThreadName = "QMgr Dispatcher"; #ifdef __vxworks if (endFindByName ("ixe", 0) != NULL) { IX_ATMCODELET_LOG ("FAIL : Driver ixe0 detected\n"); printf("FAIL : Driver ixe0 detected\n"); return IX_FAIL; } if (endFindByName ("ixe", 1) != NULL) { IX_ATMCODELET_LOG ("FAIL : Driver ixe1 detected\\n"); printf("FAIL : Driver ixe1 detected\n"); return IX_FAIL; } #endif /**************** System initialisation ****************/ /* * The IxQMgr component provides interfaces for configuring and accessing the IXP4XX * AQM hardware queues used to facilitate communication of data between the NPEs and * the xscale. IxAtmdAcc configures these queues. The IxQMgr component provides a * dispatcher that will call registered callback functions will specified queue events * occur. */ IX_ATMCODELET_COMP_INIT(ixQMgrInit()); ixQMgrDispatcherLoopGet(&dispatcherFunc); /* This next section sets up how the IxQMgrDispatcher is called. * For the purposes of demonstration under vxWorks the IxQMgrDispatcher * is polled, and under Linux intterrupts are used. * This offers the best performance respectively. */ if (IX_ATMCODELET_USE_QMGR_INT) { /* Running IxQMgrDispatcher from interrupt level */ /* * Bind the IxQMgr dispatcher to interrupt. The IX_QMGR_QUELOW_GROUP group * of queues concern ATM Transmit , Receive, Transmit Done queues */ retval = ixOsalIrqBind(IX_OSAL_IXP400_QM1_IRQ_LVL, (IxOsalVoidFnVoidPtr)(dispatcherFunc), (void *)IX_QMGR_QUELOW_GROUP); if (IX_SUCCESS != retval) { IX_ATMCODELET_LOG ("Failed to bind to QM1 interrupt\n"); return IX_FAIL; } /* * Bind the IxQMgr dispatcher to interrupt. The IX_QMGR_QUELOW_GROUP group * of queues concern ATM Receive Free queues. */ retval = ixOsalIrqBind(IX_OSAL_IXP400_QM2_IRQ_LVL, (IxOsalVoidFnVoidPtr)(dispatcherFunc), (void *)IX_QMGR_QUEUPP_GROUP); if (IX_SUCCESS != retval) { IX_ATMCODELET_LOG ("Failed to bind to QM2 interrupt\n"); return IX_FAIL; } } else /* Running IxQMgrDispatcher from task level */ { threadAttr.name = pThreadName; threadAttr.stackSize = IX_ATMCODELET_QMGR_DISPATCHER_THREAD_STACK_SIZE; threadAttr.priority = IX_ATMCODELET_QMGR_DISPATCHER_PRIORITY; if (ixOsalThreadCreate(&dispatchtid, &threadAttr, (IxOsalVoidFnVoidPtr)ixAtmCodeletDispatchTask, NULL) != IX_SUCCESS) { IX_ATMCODELET_LOG ("Error spawning dispatch task\n"); return IX_FAIL; } if(IX_SUCCESS != ixOsalThreadStart(&dispatchtid)) { IX_ATMCODELET_LOG ("Error starting dispatch task\n"); return IX_FAIL; } } /* Initialise IxNpeMh */ IX_ATMCODELET_COMP_INIT(ixNpeMhInitialize (IX_NPEMH_NPEINTERRUPTS_YES)); /* Download NPE image */ retval = ixAtmUtilsAtmImageDownload (numPorts, &phyMode); if (retval != IX_SUCCESS) { IX_ATMCODELET_LOG ("NPE download failed\n"); return IX_FAIL; } ixAtmCodeletMode = mode; return IX_SUCCESS; }
IX_STATUS ixEthAccCodeletDispatcherStart(BOOL useInterrupt) { IxOsalThread qDispatchThread; IxOsalThreadAttr threadAttr; threadAttr.name = "Codelet Q Dispatcher"; threadAttr.stackSize = 32 * 1024; /* 32kbytes */ threadAttr.priority = IX_ETHACC_CODELET_QMR_PRIORITY; if (!ixEthAccCodeletDispatcherInitialized) { /* this should be initialized once */ ixQMgrDispatcherLoopGet(&ixEthAccCodeletDispatcherFunc); ixOsalMutexInit (&ixEthAccCodeletDispatcherPollRunning); ixEthAccCodeletDispatcherPollStopTrigger = TRUE; ixEthAccCodeletDispatcherInitialized = TRUE; } if(useInterrupt) /* Interrupt mode */ { /* * Hook the QM QLOW dispatcher to the interrupt controller. */ if (ixOsalIrqBind(IX_ETH_CODELET_QMGR_IRQ, (IxOsalVoidFnVoidPtr)(ixEthAccCodeletDispatcherFunc), (void *)IX_QMGR_QUELOW_GROUP) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDispatcherPollRunning); printf("Dispatcher: Failed to bind to QM1 interrupt\n"); return (IX_FAIL); } } else { if (ixEthAccCodeletDispatcherPollStopTrigger) { /* Polled mode based on a task running a loop */ if (ixOsalThreadCreate(&qDispatchThread, &threadAttr, (IxOsalVoidFnVoidPtr) ixEthAccCodeletDispatcherPoll, NULL) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDispatcherPollRunning); printf("Dispatcher: Error spawning Q Dispatcher task\n"); return (IX_FAIL); } /* Start the thread */ if (ixOsalThreadStart(&qDispatchThread) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDispatcherPollRunning); printf("Dispatcher: Error failed to start the Q Dispatcher thread\n"); return IX_FAIL; } } } return (IX_SUCCESS); }
IX_STATUS ixParityENAccMcuPEInit (IxParityENAccInternalCallback ixMcuPECallback) { UINT32 virtualBaseAddr = 0; /* Verify parameters */ if ((IxParityENAccInternalCallback)NULL == ixMcuPECallback) { return IX_FAIL; } /* end of if */ /* Memory mapping of the MCU registers */ if ((UINT32)NULL == (virtualBaseAddr = (UINT32) IX_OSAL_MEM_MAP ( IXP400_PARITYENACC_MCU_BASEADDR, IXP400_PARITYENACC_MCU_MEMMAP_SIZE))) { return IX_FAIL; } /* end of if */ /* Virtual Addresses assignment for MCU Registers */ ixParityENAccMcuPEConfig.mcuPERegisters.mcuEccr = virtualBaseAddr + IXP400_PARITYENACC_MCU_ECCR_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuElog0 = virtualBaseAddr + IXP400_PARITYENACC_MCU_ELOG0_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuElog1 = virtualBaseAddr + IXP400_PARITYENACC_MCU_ELOG1_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuEcar0 = virtualBaseAddr + IXP400_PARITYENACC_MCU_ECAR0_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuEcar1 = virtualBaseAddr + IXP400_PARITYENACC_MCU_ECAR1_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuMcisr = virtualBaseAddr + IXP400_PARITYENACC_MCU_MCISR_OFFSET; /* Register main module internal callback routine */ ixParityENAccMcuPEConfig.mcuPECallback = ixMcuPECallback; /* Interrupt Service Routine Info for debug purpose only */ ixParityENAccMcuPEConfig.mcuIsrInfo.mcuInterruptId = IRQ_IXP400_INTC_PARITYENACC_MCU; ixParityENAccMcuPEConfig.mcuIsrInfo.mcuIsr = ixParityENAccMcuPEIsr; /* * Disable parity error detection for both single and multi-bit ECC * and correction of single bit parity using ECC */ IXP400_PARITYENACC_REG_BIT_CLEAR( ixParityENAccMcuPEConfig.mcuPERegisters.mcuEccr, IXP400_PARITYENACC_MCU_SBIT_CORRECT_MASK | IXP400_PARITYENACC_MCU_MBIT_REPORT_MASK | IXP400_PARITYENACC_MCU_SBIT_REPORT_MASK); /* Clear off the pending interrupts, if any */ IXP400_PARITYENACC_REG_BIT_SET( ixParityENAccMcuPEConfig.mcuPERegisters.mcuMcisr, IXP400_PARITYENACC_MCU_ERROR0_MASK | IXP400_PARITYENACC_MCU_ERROR1_MASK | IXP400_PARITYENACC_MCU_ERRORN_MASK); /* Install MCU Interrupt Service Routine after disabling the interrupt */ { INT32 lockKey = ixOsalIrqLock(); if ((IX_SUCCESS != ixOsalIrqBind ((UINT32) IRQ_IXP400_INTC_PARITYENACC_MCU, (IxOsalVoidFnVoidPtr) ixParityENAccMcuPEIsr, (void *) NULL)) || (IX_SUCCESS != ixParityENAccIcInterruptDisable( IXP400_PARITYENACC_INTC_MCU_PARITY_INTERRUPT))) { ixOsalIrqUnlock(lockKey); IX_OSAL_MEM_UNMAP (virtualBaseAddr); return IX_FAIL; } /* end of if */ ixOsalIrqUnlock(lockKey); } return IX_SUCCESS; } /* end of ixParityENAccMcuPEInit() function */
IX_STATUS ixParityENAccPbcPEInit(IxParityENAccInternalCallback ixPbcPECallback) { UINT32 pbcVirtualBaseAddr = 0; register IxParityENAccPbcPERegisters *pbcPERegisters = &ixParityENAccPbcPEConfig.pbcPERegisters; /* Verify parameters */ if ((IxParityENAccInternalCallback)NULL == ixPbcPECallback) { return IX_FAIL; } /* end of if */ /* Memory mapping of the PBC registers */ if ((UINT32)NULL == (pbcVirtualBaseAddr = (UINT32) IX_OSAL_MEM_MAP ( IXP400_PARITYENACC_PBC_PCICSR_BASEADDR, IXP400_PARITYENACC_PBC_PCICSR_MEMMAP_SIZE))) { return IX_FAIL; } /* end of if */ ixPbcVirtualBaseAddr = pbcVirtualBaseAddr; /* Virtual Addresses assignment for PBC Control and Status Registers */ pbcPERegisters->pciCrpAdCbe = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_CRP_AD_CBE_OFFSET; pbcPERegisters->pciCrpWdata = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_CRP_WDATA_OFFSET; pbcPERegisters->pciCrpRdata = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_CRP_RDATA_OFFSET; pbcPERegisters->pciCsr = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_CSR_OFFSET; pbcPERegisters->pciIsr = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_ISR_OFFSET; pbcPERegisters->pciInten = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_INTEN_OFFSET; /* Register main module internal callback routine */ ixParityENAccPbcPEConfig.pbcPECallback = ixPbcPECallback; /* Interrupt Service Routine Info for debug purpose */ ixParityENAccPbcPEConfig.pbcIsrInfo.pbcInterruptId = IRQ_IXP400_INTC_PARITYENACC_PBC; ixParityENAccPbcPEConfig.pbcIsrInfo.pbcIsr = ixParityENAccPbcPEIsr; /* Disable parity error detection */ /* Write '1' to clear-off the PPE bit */ IXP400_PARITYENACC_REG_BIT_SET( pbcPERegisters->pciIsr, IXP400_PARITYENACC_PBC_ISR_PPE); IXP400_PARITYENACC_REG_BIT_CLEAR( pbcPERegisters->pciInten, IXP400_PARITYENACC_PBC_INTEN_PPE); /* Install PBC Interrupt Service Routine */ { INT32 lockKey = ixOsalIrqLock(); if ((IX_SUCCESS != ixOsalIrqBind ((UINT32) IRQ_IXP400_INTC_PARITYENACC_PBC, (IxOsalVoidFnVoidPtr) ixParityENAccPbcPEIsr, (void *) NULL)) || (IX_FAIL == ixParityENAccIcInterruptDisable( IXP400_PARITYENACC_INTC_PBC_PARITY_INTERRUPT))) { ixOsalIrqUnlock(lockKey); IX_OSAL_MEM_UNMAP(pbcVirtualBaseAddr); return IX_FAIL; } /* end of if */ ixOsalIrqUnlock(lockKey); } return IX_SUCCESS; } /* end of ixParityENAccPbcPEInit() function */