/** * interrupt_wait() will wait on the PCI interrupt line and determine if GPIO * input or DMA requested the interrupt * * @return 1 if success 0 if failure */ int interrupt_wait(U32 * interrupt) { int rc; /*clear and reset interrupt structure*/ memset(&plx_intr, 0, sizeof (PLX_INTERRUPT)); /*set interrupt structure*/ plx_intr.LocalToPci = 1; //set bit 11 // plx_intr.PciMain = 1; // Bit 8 -- should already been on /*enable interrupt on PLX bridge*/ rc = PlxPci_InterruptEnable(&fpga_dev, &plx_intr); // sets PCI9056_INT_CTRL_STAT if (rc != ApiSuccess) PlxSdkErrorDisplay(rc); /*register for interrupt with kernel*/ rc = PlxPci_NotificationRegisterFor(&fpga_dev, &plx_intr, &plx_event); if (rc != ApiSuccess) PlxSdkErrorDisplay(rc); /*wait for interrupt*/ int waitrc = PlxPci_NotificationWait(&fpga_dev, &plx_event, FPGA_TIMEOUT); /*cancel interrupt notification*/ rc = PlxPci_NotificationCancel(&fpga_dev, &plx_event); if (rc != ApiSuccess) PlxSdkErrorDisplay(rc); /*disable interrupt*/ rc = PlxPci_InterruptDisable(&fpga_dev, &plx_intr); // sets PCI9056_INT_CTRL_STAT if (rc != ApiSuccess) PlxSdkErrorDisplay(rc); /*handle return code of wait function*/ if (waitrc == ApiWaitTimeout) { *interrupt = TIMEOUT_INT; return TRUE; } else if (waitrc == ApiSuccess) { *interrupt = INP_INT; return TRUE; } else if (waitrc == ApiWaitCanceled) { record("Wait canceled\n"); return FALSE; } else { record("Wait returned an unknown value\n"); return FALSE; } }
void InterruptTest( PLX_DEVICE_OBJECT *pDevice ) { PLX_STATUS rc; PLX_INTERRUPT PlxInterrupt; PLX_NOTIFY_OBJECT NotifyObject; Cons_printf( "Description:\n" " This sample demonstrates how to use the PLX API for\n" " notification of the generic Local->PCI interrupts (e.g. LINTi#).\n" " The interrupt trigger must be initiated by the\n" " OEM hardware. PLX software is not able to manually\n" " assert the interrupt since its source is OEM-dependent.\n" "\n" " Press any key to start...\n" "\n" ); Cons_getch(); Cons_printf(" Register for notification...... "); // Clear interrupt fields memset(&PlxInterrupt, 0, sizeof(PLX_INTERRUPT)); // Setup to wait for either generic interrupt PlxInterrupt.LocalToPci = (1 << 0) | (1 << 1); rc = PlxPci_NotificationRegisterFor( pDevice, &PlxInterrupt, &NotifyObject ); if (rc != ApiSuccess) { Cons_printf("*ERROR* - API failed\n"); PlxSdkErrorDisplay(rc); } else { Cons_printf("Ok\n"); } /*********************************************************** * This loop will loop only one time. It is provided here to * demonstrate which code should be placed within the loop * if waiting for the interrupt multiple times. * Note that the generic L->P interrupt must constantly be * re-enabled since the PLX driver will mask it. **********************************************************/ do { Cons_printf(" Enable interrupt(s)............ "); rc = PlxPci_InterruptEnable( pDevice, &PlxInterrupt ); if (rc != ApiSuccess) { Cons_printf("*ERROR* - API failed\n"); PlxSdkErrorDisplay(rc); } else { Cons_printf("Ok\n"); } Cons_printf( "\n" " -- You may now trigger the interrupt --\n" "\n" ); Cons_printf(" Wait for interrupt event....... "); rc = PlxPci_NotificationWait( pDevice, &NotifyObject, 120 * 1000 ); switch (rc) { case ApiSuccess: Cons_printf("Ok (Int received)\n"); /************************************************ * * Custom code to clear the OEM source of the * interrupt should be placed here. Another option * is to modify the PLX driver interrupt handler * to perform the souce clear. In that case, it * will not constantly need to be masked/re-enabled. * ***********************************************/ break; case ApiWaitTimeout: Cons_printf("*ERROR* - Timeout waiting for Int Event\n"); break; case ApiWaitCanceled: Cons_printf("*ERROR* - Interrupt event cancelled\n"); break; default: Cons_printf("*ERROR* - API failed\n"); PlxSdkErrorDisplay(rc); break; } Cons_printf(" Check notification status...... "); rc = PlxPci_NotificationStatus( pDevice, &NotifyObject, &PlxInterrupt ); if (rc == ApiSuccess) { Cons_printf("Ok (triggered ints:"); if (PlxInterrupt.LocalToPci & (1 << 0)) Cons_printf(" L->P 1"); if (PlxInterrupt.LocalToPci & (1 << 1)) Cons_printf(" L->P 2"); Cons_printf(")\n"); } else { Cons_printf("*ERROR* - API failed\n"); PlxSdkErrorDisplay(rc); } } while (0); // Release the interrupt wait object Cons_printf(" Cancelling Int Notification.... "); rc = PlxPci_NotificationCancel( pDevice, &NotifyObject ); if (rc != ApiSuccess) { Cons_printf("*ERROR* - API failed\n"); PlxSdkErrorDisplay(rc); } else { Cons_printf("Ok\n"); } }