📄 example_lib.c
字号:
/************************************************************************
* File: example_lib.c
*
* Library for accessing EXAMPLE devices.
* The code accesses hardware using WinDriver's WDC library.
* Code was generated by DriverWizard v9.21.
*
* Jungo Confidential. Copyright (c) 2009 Jungo Ltd. http://www.jungo.com
*************************************************************************/
#include <stdio.h>
#include <stdarg.h>
#include "wdc_defs.h"
#include "utils.h"
#include "status_strings.h"
#include "example_lib.h"
/*************************************************************
Internal definitions
*************************************************************/
/* WinDriver license registration string */
/* TODO: When using a registered WinDriver version, make sure the license string
below is your specific WinDriver license registration string and set
* the driver name to your driver's name */
#define EXAMPLE_DEFAULT_LICENSE_STRING "6C3CC2CFE89E7AD04238DF2EF24449E848CDA951.3ddown.com"
#define EXAMPLE_DEFAULT_DRIVER_NAME "windrvr6"
/* EXAMPLE device information struct */
typedef struct {
WD_TRANSFER *pIntTransCmds;
EXAMPLE_INT_HANDLER funcDiagIntHandler;
EXAMPLE_EVENT_HANDLER funcDiagEventHandler;
} EXAMPLE_DEV_CTX, *PEXAMPLE_DEV_CTX;
/* TODO: You can add fields to store additional device-specific information */
static CHAR gsEXAMPLE_LastErr[256];
/*************************************************************
Static functions prototypes and inline implementation
*************************************************************/
static BOOL DeviceValidate(const PWDC_DEVICE pDev);
static void DLLCALLCONV EXAMPLE_IntHandler(PVOID pData);
static void EXAMPLE_EventHandler(WD_EVENT *pEvent, PVOID pData);
static void ErrLog(const CHAR *sFormat, ...);
static void TraceLog(const CHAR *sFormat, ...);
static inline BOOL IsValidDevice(PWDC_DEVICE pDev, const CHAR *sFunc)
{
if (!pDev || !WDC_GetDevContext(pDev))
{
snprintf(gsEXAMPLE_LastErr, sizeof(gsEXAMPLE_LastErr) - 1, "%s: NULL device %s\n",
sFunc, !pDev ? "handle" : "context");
ErrLog(gsEXAMPLE_LastErr);
return FALSE;
}
return TRUE;
}
/*************************************************************
Functions implementation
*************************************************************/
/* -----------------------------------------------
EXAMPLE and WDC library initialize/uninit
----------------------------------------------- */
DWORD EXAMPLE_LibInit(void)
{
DWORD dwStatus;
#if defined(WD_DRIVER_NAME_CHANGE)
/* Set the driver name */
if (!WD_DriverName(EXAMPLE_DEFAULT_DRIVER_NAME/*"windrvr6"*/))
{
ErrLog("Failed to set the driver name for WDC library.\n");
return WD_SYSTEM_INTERNAL_ERROR;
}
#endif
/* Set WDC library's debug options (default: level TRACE, output to Debug Monitor) */
dwStatus = WDC_SetDebugOptions(WDC_DBG_DEFAULT/**/, NULL);
if (WD_STATUS_SUCCESS != dwStatus)
{
ErrLog("Failed to initialize debug options for WDC library.\n"
"Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
return dwStatus;
}
/* Open a handle to the driver and initialize the WDC library */
dwStatus = WDC_DriverOpen(WDC_DRV_OPEN_DEFAULT, EXAMPLE_DEFAULT_LICENSE_STRING/*"6C3CC2CFE89E7AD04238DF2EF24449E848CDA951.3ddown.com"*/);
if (WD_STATUS_SUCCESS != dwStatus)
{
ErrLog("Failed to initialize the WDC library. Error 0x%lx - %s\n",
dwStatus, Stat2Str(dwStatus));
return dwStatus;
}
return WD_STATUS_SUCCESS;
}
DWORD EXAMPLE_LibUninit(void)
{
DWORD dwStatus;
/* Uninit the WDC library and close the handle to WinDriver */
dwStatus = WDC_DriverClose();
if (WD_STATUS_SUCCESS != dwStatus)
{
ErrLog("Failed to uninit the WDC library. Error 0x%lx - %s\n",
dwStatus, Stat2Str(dwStatus));
}
return dwStatus;
}
/* -----------------------------------------------
Device open/close
----------------------------------------------- */
WDC_DEVICE_HANDLE EXAMPLE_DeviceOpen(const WD_PCI_CARD_INFO *pDeviceInfo)
{
DWORD dwStatus;
PEXAMPLE_DEV_CTX pDevCtx = NULL;
WDC_DEVICE_HANDLE hDev = NULL;
/* Validate arguments */
if (!pDeviceInfo)
{
ErrLog("EXAMPLE_DeviceOpen: Error - NULL device information struct pointer\n");
return NULL;
}
/* Allocate memory for the EXAMPLE device context */
pDevCtx = (PEXAMPLE_DEV_CTX)malloc(sizeof (EXAMPLE_DEV_CTX));
if (!pDevCtx)
{
ErrLog("Failed allocating memory for EXAMPLE device context\n");
return NULL;
}
BZERO(*pDevCtx);
/* Open a WDC device handle */
dwStatus = WDC_PciDeviceOpen(&hDev, pDeviceInfo, pDevCtx, NULL, NULL, NULL);
if (WD_STATUS_SUCCESS != dwStatus)
{
ErrLog("Failed opening a WDC device handle. Error 0x%lx - %s\n",
dwStatus, Stat2Str(dwStatus));
goto Error;
}
/* Validate device information */
if (!DeviceValidate((PWDC_DEVICE)hDev))
goto Error;
/* Return handle to the new device */
TraceLog("EXAMPLE_DeviceOpen: Opened a EXAMPLE device (handle 0x%p)\n", hDev);
return hDev;
Error:
if (hDev)
EXAMPLE_DeviceClose(hDev);
else
free(pDevCtx);
return NULL;
}
BOOL EXAMPLE_DeviceClose(WDC_DEVICE_HANDLE hDev)
{
DWORD dwStatus;
PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
PEXAMPLE_DEV_CTX pDevCtx;
TraceLog("EXAMPLE_DeviceClose entered. Device handle: 0x%p\n", hDev);
if (!hDev)
{
ErrLog("EXAMPLE_DeviceClose: Error - NULL device handle\n");
return FALSE;
}
pDevCtx = (PEXAMPLE_DEV_CTX)WDC_GetDevContext(pDev);
/* Disable interrupts */
if (WDC_IntIsEnabled(hDev))
{
dwStatus = EXAMPLE_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 EXAMPLE device context memory */
if (pDevCtx)
free (pDevCtx);
return (WD_STATUS_SUCCESS == dwStatus);
}
static BOOL DeviceValidate(const PWDC_DEVICE pDev)
{
DWORD i, dwNumAddrSpaces = pDev->dwNumAddrSpaces;
/* TODO: You can modify the implementation of this function in order to
verify that the device has all expected resources. */
/* Verify that the device has at least one active address space */
for (i = 0; i < dwNumAddrSpaces; i++)
{
if (WDC_AddrSpaceIsActive(pDev, i))
return TRUE;
}
TraceLog("Device does not have any active memory or I/O address spaces\n");
return TRUE;
}
/* -----------------------------------------------
Interrupts
----------------------------------------------- */
static void DLLCALLCONV EXAMPLE_IntHandler(PVOID pData)
{
PWDC_DEVICE pDev = (PWDC_DEVICE)pData;
PEXAMPLE_DEV_CTX pDevCtx = (PEXAMPLE_DEV_CTX)WDC_GetDevContext(pDev);
EXAMPLE_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);
}
static BOOL IsItemExists(PWDC_DEVICE pDev, ITEM_TYPE item)
{
int i;
DWORD dwNumItems = pDev->cardReg.Card.dwItems;
for (i=0; i<dwNumItems; i++)
{
if (pDev->cardReg.Card.Item[i].item == item)
return TRUE;
}
return FALSE;
}
DWORD EXAMPLE_IntEnable(WDC_DEVICE_HANDLE hDev, EXAMPLE_INT_HANDLER funcIntHandler)
{
DWORD dwStatus;
PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
PEXAMPLE_DEV_CTX pDevCtx;
WDC_ADDR_DESC *pAddrDesc;
WD_TRANSFER *pTrans;
TraceLog("EXAMPLE_IntEnable entered. Device handle: 0x%p\n", hDev);
if (!IsValidDevice(pDev, "EXAMPLE_IntEnable"))
return WD_INVALID_PARAMETER;
if (!IsItemExists(pDev, ITEM_INTERRUPT))
return WD_OPERATION_FAILED;
pDevCtx = (PEXAMPLE_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 2
/* Allocate memory for the interrupt transfer commands */
pTrans = (WD_TRANSFER*)calloc(NUM_TRANS_CMDS, sizeof(WD_TRANSFER));
if (!pTrans)
{
ErrLog("Failed allocating memory for interrupt transfer commands\n");
return WD_INSUFFICIENT_RESOURCES;
}
/* Prepare the interrupt transfer commands */
/* The transfer commands will be executed by WinDriver in the kernel
for each interrupt that is received */
/* #1: Read from the IORegister2 register */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -