⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 example_lib.c

📁 关于WinDriver的自动生成的PCI驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    pAddrDesc = &pDev->pAddrDesc[AD_PCI_BAR2];
    pTrans[0].dwPort = pAddrDesc->kptAddr + 0x19;
    pTrans[0].cmdTrans = WDC_ADDR_IS_MEM(pAddrDesc) ? RM_BYTE : RP_BYTE;

    /* #2: Write to the IORegister2 register */
    pAddrDesc = &pDev->pAddrDesc[AD_PCI_BAR2];
    pTrans[1].dwPort = pAddrDesc->kptAddr + 0x19;
    pTrans[1].cmdTrans = WDC_ADDR_IS_MEM(pAddrDesc) ? WM_BYTE : WP_BYTE;
    pTrans[1].Data.Byte = 0x0;

    /* Store the diag interrupt handler routine, which will be executed by
       EXAMPLE_IntHandler() when an interrupt is received */
    pDevCtx->funcDiagIntHandler = funcIntHandler;
    
    /* Enable the interrupts */
    dwStatus = WDC_IntEnable(hDev, pTrans, NUM_TRANS_CMDS, INTERRUPT_CMD_COPY,
        EXAMPLE_IntHandler, (PVOID)pDev, WDC_IS_KP(hDev));
        
    if (WD_STATUS_SUCCESS != dwStatus)
    {
        ErrLog("Failed enabling interrupts. Error 0x%lx - %s\n",
            dwStatus, Stat2Str(dwStatus));
        
        free(pTrans);
        
        return dwStatus;
    }

    /* Store the interrupt transfer commands in the device context */
    pDevCtx->pIntTransCmds = pTrans;

    /* TODO: You can add code here to write to the device in order
             to physically enable the hardware interrupts */

    TraceLog("EXAMPLE_IntEnable: Interrupts enabled\n");

    return WD_STATUS_SUCCESS;
}

DWORD EXAMPLE_IntDisable(WDC_DEVICE_HANDLE hDev)
{
    DWORD dwStatus;
    PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
    PEXAMPLE_DEV_CTX pDevCtx;

    TraceLog("EXAMPLE_IntDisable entered. Device handle: 0x%p\n", hDev);

    if (!IsValidDevice(pDev, "EXAMPLE_IntDisable"))
        return WD_INVALID_PARAMETER;

    pDevCtx = (PEXAMPLE_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));
    }

    /* Free the memory allocated for the interrupt transfer commands */
    if (pDevCtx->pIntTransCmds)
    {
        free(pDevCtx->pIntTransCmds);
        pDevCtx->pIntTransCmds = NULL;
    }

    return dwStatus;
}

BOOL EXAMPLE_IntIsEnabled(WDC_DEVICE_HANDLE hDev)
{
    if (!IsValidDevice((PWDC_DEVICE)hDev, "EXAMPLE_IntIsEnabled"))
        return FALSE;

    return WDC_IntIsEnabled(hDev);
}

/* -----------------------------------------------
    Plug-and-play and power management events
   ----------------------------------------------- */
static void EXAMPLE_EventHandler(WD_EVENT *pEvent, PVOID pData)
{
    PWDC_DEVICE pDev = (PWDC_DEVICE)pData;
    PEXAMPLE_DEV_CTX pDevCtx = (PEXAMPLE_DEV_CTX)WDC_GetDevContext(pDev);

    TraceLog("EXAMPLE_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);
}

DWORD EXAMPLE_EventRegister(WDC_DEVICE_HANDLE hDev, EXAMPLE_EVENT_HANDLER funcEventHandler)
{
    DWORD dwStatus;
    PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
    PEXAMPLE_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("EXAMPLE_EventRegister entered. Device handle: 0x%p\n", hDev);
    
    if (!IsValidDevice(pDev, "EXAMPLE_EventRegister"))
        return WD_INVALID_PARAMETER;

    pDevCtx = (PEXAMPLE_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 EXAMPLE_EventHandler() upon an event */
    pDevCtx->funcDiagEventHandler = funcEventHandler;

    /* Register event */
    dwStatus = WDC_EventRegister(hDev, dwActions, EXAMPLE_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;
}

DWORD EXAMPLE_EventUnregister(WDC_DEVICE_HANDLE hDev)
{
    DWORD dwStatus;
    
    TraceLog("EXAMPLE_EventUnregister entered. Device handle: 0x%p\n", hDev);
    
    if (!IsValidDevice((PWDC_DEVICE)hDev, "EXAMPLE_EventUnregister"))
        return WD_INVALID_PARAMETER;

    if (!WDC_EventIsRegistered(hDev))
    {
        ErrLog("Cannot unregister events - no events currently registered ...\n");
        return WD_OPERATION_ALREADY_DONE;
    }

    dwStatus = WDC_EventUnregister(hDev);
    
    if (WD_STATUS_SUCCESS != dwStatus)
    {
        ErrLog("Failed to unregister events. Error 0x%lx - %s\n",
            dwStatus, Stat2Str(dwStatus));
    }

    return dwStatus;
}

BOOL EXAMPLE_EventIsRegistered(WDC_DEVICE_HANDLE hDev)
{
    if (!IsValidDevice((PWDC_DEVICE)hDev, "EXAMPLE_EventIsRegistered"))
        return FALSE;

    return WDC_EventIsRegistered(hDev);
}

/* -----------------------------------------------
    Address spaces information
   ----------------------------------------------- */
DWORD EXAMPLE_GetNumAddrSpaces(WDC_DEVICE_HANDLE hDev)
{
    PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
    
    if (!IsValidDevice(pDev, "EXAMPLE_GetNumAddrSpaces"))
        return 0;

    return pDev->dwNumAddrSpaces;
}

BOOL EXAMPLE_GetAddrSpaceInfo(WDC_DEVICE_HANDLE hDev, EXAMPLE_ADDR_SPACE_INFO *pAddrSpaceInfo)
{
    PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
    WDC_ADDR_DESC *pAddrDesc;
    DWORD dwAddrSpace, dwMaxAddrSpace;
    BOOL fIsMemory;
    
    if (!IsValidDevice(pDev, "EXAMPLE_GetAddrSpaceInfo"))
        return FALSE;

#if defined(DEBUG)
    if (!pAddrSpaceInfo)
    {
        ErrLog("EXAMPLE_GetAddrSpaceInfo: Error - NULL address space information pointer\n");
        return FALSE;
    }
#endif

    dwAddrSpace = pAddrSpaceInfo->dwAddrSpace;
    dwMaxAddrSpace = pDev->dwNumAddrSpaces - 1;

    if (dwAddrSpace > dwMaxAddrSpace)
    {
        ErrLog("EXAMPLE_GetAddrSpaceInfo: Error - Address space %ld is out of range (0 - %ld)\n",
            dwAddrSpace, dwMaxAddrSpace);
        return FALSE;
    }

    pAddrDesc = &pDev->pAddrDesc[dwAddrSpace];

    fIsMemory = WDC_ADDR_IS_MEM(pAddrDesc);
    
    snprintf(pAddrSpaceInfo->sName, MAX_NAME - 1, "BAR %ld", dwAddrSpace);
    snprintf(pAddrSpaceInfo->sType, MAX_TYPE - 1, fIsMemory ? "Memory" : "I/O");
        
    if (WDC_AddrSpaceIsActive(pDev, dwAddrSpace))
    {
        WD_ITEMS *pItem = &pDev->cardReg.Card.Item[pAddrDesc->dwItemIndex];
        DWORD dwAddr = fIsMemory ? pItem->I.Mem.dwPhysicalAddr : (DWORD)pItem->I.IO.dwAddr;
        
        snprintf(pAddrSpaceInfo->sDesc, MAX_DESC - 1, "0x%0*lX - 0x%0*lX (0x%lx bytes)",
            (int)WDC_SIZE_32 * 2, dwAddr,
            (int)WDC_SIZE_32 * 2, dwAddr + pAddrDesc->dwBytes - 1,
            pAddrDesc->dwBytes);
    }
    else
        snprintf(pAddrSpaceInfo->sDesc, MAX_DESC - 1, "Inactive address space");

    /* TODO: You can modify the code above to set a different address space name/description */

    return TRUE;
}

// Function: EXAMPLE_ReadIORegister2()
//   Read from IORegister2 register.
// Parameters:
//   hDev [in] handle to the card as received from EXAMPLE_DeviceOpen().
// Return Value:
//   The value read from the register.
BYTE EXAMPLE_ReadIORegister2 (WDC_DEVICE_HANDLE hDev)
{
    BYTE data;

    WDC_ReadAddr8(hDev, EXAMPLE_IORegister2_SPACE, EXAMPLE_IORegister2_OFFSET, &data);
    return data;
}

// Function: EXAMPLE_WriteIORegister2()
//   Write to IORegister2 register.
// Parameters:
//   hDev [in] handle to the card as received from EXAMPLE_DeviceOpen().
//   data [in] the data to write to the register.
// Return Value:
//   None.
void EXAMPLE_WriteIORegister2 (WDC_DEVICE_HANDLE hDev, BYTE data)
{
    WDC_WriteAddr8(hDev, EXAMPLE_IORegister2_SPACE, EXAMPLE_IORegister2_OFFSET, data);
}

/* -----------------------------------------------
    Debugging and error handling
   ----------------------------------------------- */
static void ErrLog(const CHAR *sFormat, ...)
{
    va_list argp;
    va_start(argp, sFormat);
    vsnprintf(gsEXAMPLE_LastErr, sizeof(gsEXAMPLE_LastErr) - 1, sFormat, argp);
#if defined(DEBUG)
    WDC_Err("EXAMPLE lib: %s", EXAMPLE_GetLastErr());
#endif
    va_end(argp);
}

static void TraceLog(const CHAR *sFormat, ...)
{
#if defined(DEBUG)
    CHAR sMsg[256];
    va_list argp;
    va_start(argp, sFormat);
    vsnprintf(sMsg, sizeof(sMsg) - 1, sFormat, argp);
    WDC_Trace("EXAMPLE lib: %s", sMsg);
    va_end(argp);
#endif
}

const char *EXAMPLE_GetLastErr(void)
{
    return gsEXAMPLE_LastErr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -