DWORD PCIE_SW_IntDisable(WDC_DEVICE_HANDLE hDev) { DWORD dwStatus; PWDC_DEVICE pDev = (PWDC_DEVICE)hDev; PPCIE_SW_DEV_CTX pDevCtx; TraceLog("PCIE_SW_IntDisable entered. Device handle: 0x%p\n", hDev); if (!IsValidDevice(pDev, "PCIE_SW_IntDisable")) return WD_INVALID_PARAMETER; pDevCtx = (PPCIE_SW_DEV_CTX)WDC_GetDevContext(pDev); if (!WDC_IntIsEnabled(hDev)) { ErrLog("Interrupts are already disabled ...\n"); return WD_OPERATION_ALREADY_DONE; } /* TODO: You can add code here to write to the device in order to physically disable the hardware interrupts */ /* Disable the interrupts */ dwStatus = WDC_IntDisable(hDev); if (WD_STATUS_SUCCESS != dwStatus) { ErrLog("Failed disabling interrupts. Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus)); } return dwStatus; }
DWORD PCIE_SW_IntEnable(WDC_DEVICE_HANDLE hDev, PCIE_SW_INT_HANDLER funcIntHandler) { DWORD dwStatus; PWDC_DEVICE pDev = (PWDC_DEVICE)hDev; PPCIE_SW_DEV_CTX pDevCtx; TraceLog("PCIE_SW_IntEnable entered. Device handle: 0x%p\n", hDev); if (!IsValidDevice(pDev, "PCIE_SW_IntEnable")) return WD_INVALID_PARAMETER; if (!IsItemExists(pDev, ITEM_INTERRUPT)) return WD_OPERATION_FAILED; pDevCtx = (PPCIE_SW_DEV_CTX)WDC_GetDevContext(pDev); /* Check if interrupts are already enabled */ if (WDC_IntIsEnabled(hDev)) { ErrLog("Interrupts are already enabled ...\n"); return WD_OPERATION_ALREADY_DONE; } /* Define the number of interrupt transfer commands to use */ #define NUM_TRANS_CMDS 0 /* NOTE: In order to correctly handle PCI interrupts, you need to ADD CODE HERE to set up transfer commands to read/write the relevant register(s) in order to correctly acknowledge the interrupts, as dictated by your hardware's specifications. When adding transfer commands, be sure to also modify the definition of NUM_TRANS_CMDS (above) accordingly. */ /* Store the diag interrupt handler routine, which will be executed by PCIE_SW_IntHandler() when an interrupt is received */ pDevCtx->funcDiagIntHandler = funcIntHandler; /* Enable the interrupts */ /* NOTE: When adding read transfer commands, set the INTERRUPT_CMD_COPY flag in the 4th argument (dwOptions) passed to WDC_IntEnable() */ dwStatus = WDC_IntEnable(hDev, NULL, 0, 0, PCIE_SW_IntHandler, (PVOID)pDev, WDC_IS_KP(hDev)); if (WD_STATUS_SUCCESS != dwStatus) { ErrLog("Failed enabling interrupts. Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus)); return dwStatus; } /* TODO: You can add code here to write to the device in order to physically enable the hardware interrupts */ TraceLog("PCIE_SW_IntEnable: Interrupts enabled\n"); return WD_STATUS_SUCCESS; }
/* ----------------------------------------------- Plug-and-play and power management events ----------------------------------------------- */ static void PCIE_SW_EventHandler(WD_EVENT *pEvent, PVOID pData) { PWDC_DEVICE pDev = (PWDC_DEVICE)pData; PPCIE_SW_DEV_CTX pDevCtx = (PPCIE_SW_DEV_CTX)WDC_GetDevContext(pDev); TraceLog("PCIE_SW_EventHandler entered, pData: 0x%p, dwAction 0x%lx\n", pData, pEvent->dwAction); /* Execute the diagnostics application's event handler function */ pDevCtx->funcDiagEventHandler((WDC_DEVICE_HANDLE)pDev, pEvent->dwAction); }
static inline BOOL IsValidDevice(PWDC_DEVICE pDev, const CHAR *sFunc) { if (!pDev || !WDC_GetDevContext(pDev)) { snprintf(gsPCIE_SW_LastErr, sizeof(gsPCIE_SW_LastErr) - 1, "%s: NULL device %s\n", sFunc, !pDev ? "handle" : "context"); ErrLog(gsPCIE_SW_LastErr); return FALSE; } return TRUE; }
DWORD EDEN_IntEnable(WDC_DEVICE_HANDLE hDev, EDEN_INT_HANDLER funcIntHandler) { DWORD dwStatus; PWDC_DEVICE pDev = (PWDC_DEVICE)hDev; PEDEN_DEV_CTX pDevCtx; TraceLog("EDEN_IntEnable entered. Device handle: 0x%p\n", hDev); if (!IsValidDevice(pDev, "EDEN_IntEnable")) return WD_INVALID_PARAMETER; if (!IsItemExists(pDev, ITEM_INTERRUPT)) return WD_OPERATION_FAILED; pDevCtx = (PEDEN_DEV_CTX)WDC_GetDevContext(pDev); /* Check if interrupts are already enabled */ if (WDC_IntIsEnabled(hDev)) { ErrLog("Interrupts are already enabled ...\n"); return WD_OPERATION_ALREADY_DONE; } /* Store the diag interrupt handler routine, which will be executed by EDEN_IntHandler() when an interrupt is received */ pDevCtx->funcDiagIntHandler = funcIntHandler; /* Enable the interrupts */ /* NOTE: When adding read transfer commands, set the INTERRUPT_CMD_COPY flag in the 4th argument (dwOptions) passed to WDC_IntEnable() */ dwStatus = WDC_IntEnable(hDev, NULL, 0, 0, EDEN_IntHandler, (PVOID)pDev, WDC_IS_KP(hDev)); if (WD_STATUS_SUCCESS != dwStatus) { ErrLog("Failed enabling interrupts. Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus)); return dwStatus; } /* TODO: You can add code here to write to the device in order to physically enable the hardware interrupts */ TraceLog("EDEN_IntEnable: Interrupts enabled\n"); return WD_STATUS_SUCCESS; }
/* ----------------------------------------------- Interrupts ----------------------------------------------- */ static void DLLCALLCONV PCIE_SW_IntHandler(PVOID pData) { PWDC_DEVICE pDev = (PWDC_DEVICE)pData; PPCIE_SW_DEV_CTX pDevCtx = (PPCIE_SW_DEV_CTX)WDC_GetDevContext(pDev); PCIE_SW_INT_RESULT intResult; BZERO(intResult); intResult.dwCounter = pDev->Int.dwCounter; intResult.dwLost = pDev->Int.dwLost; intResult.waitResult = (WD_INTERRUPT_WAIT_RESULT)pDev->Int.fStopped; intResult.dwEnabledIntType = WDC_GET_ENABLED_INT_TYPE(pDev); intResult.dwLastMessage = WDC_GET_ENABLED_INT_LAST_MSG(pDev); /* Execute the diagnostics application's interrupt handler routine */ pDevCtx->funcDiagIntHandler((WDC_DEVICE_HANDLE)pDev, &intResult); }
DWORD PCIE_SW_EventRegister(WDC_DEVICE_HANDLE hDev, PCIE_SW_EVENT_HANDLER funcEventHandler) { DWORD dwStatus; PWDC_DEVICE pDev = (PWDC_DEVICE)hDev; PPCIE_SW_DEV_CTX pDevCtx; DWORD dwActions = WD_ACTIONS_ALL; /* TODO: Modify the above to set up the plug-and-play/power management events for which you wish to receive notifications. dwActions can be set to any combination of the WD_EVENT_ACTION flags defined in windrvr.h */ TraceLog("PCIE_SW_EventRegister entered. Device handle: 0x%p\n", hDev); if (!IsValidDevice(pDev, "PCIE_SW_EventRegister")) return WD_INVALID_PARAMETER; pDevCtx = (PPCIE_SW_DEV_CTX)WDC_GetDevContext(pDev); /* Check if event is already registered */ if (WDC_EventIsRegistered(hDev)) { ErrLog("Events are already registered ...\n"); return WD_OPERATION_ALREADY_DONE; } /* Store the diag event handler routine to be executed from PCIE_SW_EventHandler() upon an event */ pDevCtx->funcDiagEventHandler = funcEventHandler; /* Register event */ dwStatus = WDC_EventRegister(hDev, dwActions, PCIE_SW_EventHandler, hDev, FALSE); if (WD_STATUS_SUCCESS != dwStatus) { ErrLog("Failed to register events. Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus)); return dwStatus; } TraceLog("Events registered\n"); return WD_STATUS_SUCCESS; }
BOOL PCIE_SW_DeviceClose(WDC_DEVICE_HANDLE hDev) { DWORD dwStatus; PWDC_DEVICE pDev = (PWDC_DEVICE)hDev; PPCIE_SW_DEV_CTX pDevCtx; TraceLog("PCIE_SW_DeviceClose entered. Device handle: 0x%p\n", hDev); if (!hDev) { ErrLog("PCIE_SW_DeviceClose: Error - NULL device handle\n"); return FALSE; } pDevCtx = (PPCIE_SW_DEV_CTX)WDC_GetDevContext(pDev); /* Disable interrupts */ if (WDC_IntIsEnabled(hDev)) { dwStatus = PCIE_SW_IntDisable(hDev); if (WD_STATUS_SUCCESS != dwStatus) { ErrLog("Failed disabling interrupts. Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus)); } } /* Close the device */ dwStatus = WDC_PciDeviceClose(hDev); if (WD_STATUS_SUCCESS != dwStatus) { ErrLog("Failed closing a WDC device handle (0x%p). Error 0x%lx - %s\n", hDev, dwStatus, Stat2Str(dwStatus)); } /* Free PCIE_SW device context memory */ if (pDevCtx) free (pDevCtx); return (WD_STATUS_SUCCESS == dwStatus); }