Jungo WinDriver  
Official Documentation
kp_pci.c
Go to the documentation of this file.
1/* @JUNGO_COPYRIGHT@ */
2
3/************************************************************************
4* File: kp_pci.c
5*
6* Kernel PlugIn driver for accessing PCI devices.
7* The code accesses hardware using WinDriver's WDC library.
8@CODE_GEN@
9*
10* Note: This code sample is provided AS-IS and as a guiding sample only.
11*************************************************************************/
12
13#include "kpstdlib.h"
14#include "wd_kp.h"
15#ifndef ISA
16#include "pci_regs.h"
17#endif /* ifndef ISA */
18#include "../pci_lib.h"
19
20/*************************************************************
21 Functions prototypes
22 *************************************************************/
23BOOL __cdecl KP_PCI_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData,
24 PVOID *ppDrvContext);
25/* @32on64@ */
26BOOL __cdecl KP_PCI_Open_32_64(KP_OPEN_CALL *kpOpenCall, HANDLE hWD,
27 PVOID pOpenData, PVOID *ppDrvContext);
28/* @32on64@ */
29void __cdecl KP_PCI_Close(PVOID pDrvContext);
30void __cdecl KP_PCI_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall);
31BOOL __cdecl KP_PCI_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall,
32 PVOID *ppIntContext);
33void __cdecl KP_PCI_IntDisable(PVOID pIntContext);
34BOOL __cdecl KP_PCI_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt);
35DWORD __cdecl KP_PCI_IntAtDpc(PVOID pIntContext, DWORD dwCount);
36#ifndef PLATFORM_API
37BOOL __cdecl KP_PCI_IntAtIrqlMSI(PVOID pIntContext, ULONG dwLastMessage,
38 DWORD dwVector);
39DWORD __cdecl KP_PCI_IntAtDpcMSI(PVOID pIntContext, DWORD dwCount,
40 ULONG dwLastMessage, DWORD dwReserved);
41#ifndef ISA
42BOOL __cdecl KP_PCI_Event(PVOID pDrvContext, WD_EVENT *wd_event);
43#endif /* ifndef ISA */
44#endif /* ifndef PLATFORM_API */
45static void KP_PCI_Err(const CHAR *sFormat, ...);
46static void KP_PCI_Trace(const CHAR *sFormat, ...);
47/* @32on64@ */
48#define PTR32 UINT32
49
50typedef struct {
51 UINT32 dwNumAddrSpaces; /* Total number of device address spaces */
52 PTR32 pAddrDesc; /* Array of device address spaces information */
53} PCI_DEV_ADDR_DESC_32B;
54/* @32on64@ */
55
56/*************************************************************
57 Functions implementation
58 *************************************************************/
59
67BOOL __cdecl KP_Init(KP_INIT *kpInit)
68{
69 /* Verify that the version of the WinDriver Kernel PlugIn library
70 is identical to that of the windrvr.h and wd_kp.h files */
71 if (WD_VER != kpInit->dwVerWD)
72 {
73 /* Rebuild your Kernel PlugIn driver project with the compatible
74 version of the WinDriver Kernel PlugIn library (kp_nt<version>.lib)
75 and windrvr.h and wd_kp.h files */
76
77 return FALSE;
78 }
79
80 kpInit->funcOpen = KP_PCI_Open;
81/* @32on64@ */
83/* @32on64@ */
84#if defined(WINNT)
85 strcpy(kpInit->cDriverName, KP_PCI_DRIVER_NAME);
86#else
87 strncpy(kpInit->cDriverName, KP_PCI_DRIVER_NAME,
88 sizeof(kpInit->cDriverName));
89#endif
90 kpInit->cDriverName[sizeof(kpInit->cDriverName) - 1] = 0;
91
92 return TRUE;
93}
94
156BOOL __cdecl KP_PCI_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData,
157 PVOID *ppDrvContext)
158{
159 PCI_DEV_ADDR_DESC *pDevAddrDesc;
160 DWORD dwSize;
161 DWORD dwStatus;
162
163 /* Initialize the PCI library */
164 dwStatus = PCI_LibInit();
165 if (WD_STATUS_SUCCESS != dwStatus)
166 {
167 KP_PCI_Err("KP_PCI_Open: Failed to initialize the PCI library. "
168 "Last error [%s]\n", PCI_GetLastErr());
169 return FALSE;
170 }
171
172 KP_PCI_Trace("KP_PCI_Open: Entered. PCI library initialized\n");
173
174 kpOpenCall->funcClose = KP_PCI_Close;
175 kpOpenCall->funcCall = KP_PCI_Call;
176 kpOpenCall->funcIntEnable = KP_PCI_IntEnable;
177 kpOpenCall->funcIntDisable = KP_PCI_IntDisable;
178 kpOpenCall->funcIntAtIrql = KP_PCI_IntAtIrql;
179 kpOpenCall->funcIntAtDpc = KP_PCI_IntAtDpc;
180#ifndef PLATFORM_API
181 kpOpenCall->funcIntAtIrqlMSI = KP_PCI_IntAtIrqlMSI;
182 kpOpenCall->funcIntAtDpcMSI = KP_PCI_IntAtDpcMSI;
183#ifndef ISA
184 kpOpenCall->funcEvent = KP_PCI_Event;
185#endif /* ifndef ISA */
186#endif /* ifndef PLATFORM_API */
187
188 if (ppDrvContext)
189 {
190 if (pOpenData)
191 {
192 WDC_ADDR_DESC *pAddrDesc;
193
194 /* Create a copy of device information in the driver context */
195 dwSize = sizeof(PCI_DEV_ADDR_DESC);
196 pDevAddrDesc = malloc(dwSize);
197 if (!pDevAddrDesc)
198 goto malloc_error;
199
200 COPY_FROM_USER(pDevAddrDesc, pOpenData, dwSize);
201
202 dwSize = sizeof(WDC_ADDR_DESC) * pDevAddrDesc->dwNumAddrSpaces;
203 pAddrDesc = malloc(dwSize);
204 if (!pAddrDesc)
205 goto malloc_error;
206
207 COPY_FROM_USER(pAddrDesc, pDevAddrDesc->pAddrDesc, dwSize);
208 pDevAddrDesc->pAddrDesc = pAddrDesc;
209
210 *ppDrvContext = pDevAddrDesc;
211 }
212 else
213 {
214 *ppDrvContext = NULL;
215 }
216 }
217
218 KP_PCI_Trace("KP_PCI_Open: Kernel PlugIn driver opened successfully\n");
219
220 return TRUE;
221
222malloc_error:
223 KP_PCI_Err("KP_PCI_Open: Failed allocating [%ld] bytes\n", dwSize);
224 if (pDevAddrDesc)
225 free(pDevAddrDesc);
226 PCI_LibUninit();
227 return FALSE;
228}
229
230/* @32on64@ */
231
238BOOL __cdecl KP_PCI_Open_32_64(KP_OPEN_CALL *kpOpenCall, HANDLE hWD,
239 PVOID pOpenData, PVOID *ppDrvContext)
240{
241 PCI_DEV_ADDR_DESC *pDevAddrDesc;
242 DWORD dwSize;
243 DWORD dwStatus;
244
245 /* Initialize the PCI library */
246 dwStatus = PCI_LibInit();
247 if (WD_STATUS_SUCCESS != dwStatus)
248 {
249 KP_PCI_Err("KP_PCI_Open_32_64: Failed to initialize the PCI library. "
250 "Last error [%s]\n", PCI_GetLastErr());
251 return FALSE;
252 }
253
254 KP_PCI_Trace("KP_PCI_Open_32_64: Entered. PCI library initialized\n");
255
256 kpOpenCall->funcClose = KP_PCI_Close;
257 kpOpenCall->funcCall = KP_PCI_Call;
258 kpOpenCall->funcIntEnable = KP_PCI_IntEnable;
259 kpOpenCall->funcIntDisable = KP_PCI_IntDisable;
260 kpOpenCall->funcIntAtIrql = KP_PCI_IntAtIrql;
261 kpOpenCall->funcIntAtDpc = KP_PCI_IntAtDpc;
262#ifndef PLATFORM_API
263 kpOpenCall->funcIntAtIrqlMSI = KP_PCI_IntAtIrqlMSI;
264 kpOpenCall->funcIntAtDpcMSI = KP_PCI_IntAtDpcMSI;
265#ifndef ISA
266 kpOpenCall->funcEvent = KP_PCI_Event;
267#endif /* ifndef ISA */
268#endif /* ifndef PLATFORM_API */
269
270 if (ppDrvContext)
271 {
272 if (pOpenData)
273 {
274 PCI_DEV_ADDR_DESC_32B devAddrDesc_32;
275 WDC_ADDR_DESC *pAddrDesc;
276
277 /* Create a copy of the device information in the driver context */
278 dwSize = sizeof(PCI_DEV_ADDR_DESC);
279 pDevAddrDesc = malloc(dwSize);
280 if (!pDevAddrDesc)
281 goto malloc_error;
282
283 /* Copy device information sent from a 32-bit user application */
284 COPY_FROM_USER(&devAddrDesc_32, pOpenData,
285 sizeof(PCI_DEV_ADDR_DESC_32B));
286
287 /* Copy the 32-bit data to a 64-bit struct */
288 pDevAddrDesc->dwNumAddrSpaces = devAddrDesc_32.dwNumAddrSpaces;
289 dwSize = sizeof(WDC_ADDR_DESC) * pDevAddrDesc->dwNumAddrSpaces;
290 pAddrDesc = malloc(dwSize);
291 if (!pAddrDesc)
292 goto malloc_error;
293
294 COPY_FROM_USER(pAddrDesc, (PVOID)(KPTR)devAddrDesc_32.pAddrDesc,
295 dwSize);
296 pDevAddrDesc->pAddrDesc = pAddrDesc;
297
298 *ppDrvContext = pDevAddrDesc;
299 }
300 else
301 {
302 *ppDrvContext = NULL;
303 }
304 }
305
306 KP_PCI_Trace("KP_PCI_Open_32_64: Kernel PlugIn driver opened "
307 "successfully\n");
308
309 return TRUE;
310
311malloc_error:
312 KP_PCI_Err("KP_PCI_Open_32_64: Failed allocating [%ld] bytes\n", dwSize);
313 if (pDevAddrDesc)
314 free(pDevAddrDesc);
315 PCI_LibUninit();
316 return FALSE;
317}
318/* @32on64@ */
319
332void __cdecl KP_PCI_Close(PVOID pDrvContext)
333{
334 DWORD dwStatus;
335
336 KP_PCI_Trace("KP_PCI_Close: Entered\n");
337
338 /* Uninit the PCI library */
339 dwStatus = PCI_LibUninit();
340 if (WD_STATUS_SUCCESS != dwStatus)
341 {
342 KP_PCI_Err("KP_PCI_Close: Failed to uninit the PCI library. "
343 "Last error [%s]\n", PCI_GetLastErr());
344 }
345
346 /* Free the memory allocated for the driver context */
347 if (pDrvContext)
348 {
349 if (((PCI_DEV_ADDR_DESC *)pDrvContext)->pAddrDesc)
350 free(((PCI_DEV_ADDR_DESC *)pDrvContext)->pAddrDesc);
351 free(pDrvContext);
352 }
353}
354
383void __cdecl KP_PCI_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall)
384{
385 KP_PCI_Trace("KP_PCI_Call: Entered. Message [0x%lx]\n", kpCall->dwMessage);
386
387 kpCall->dwResult = KP_PCI_STATUS_OK;
388
389 switch (kpCall->dwMessage)
390 {
391 case KP_PCI_MSG_VERSION: /* Get the version of the Kernel PlugIn driver */
392 {
393 KP_PCI_VERSION *pUserKPVer = (KP_PCI_VERSION *)(kpCall->pData);
394 KP_PCI_VERSION kernelKPVer;
395
396 BZERO(kernelKPVer);
397 kernelKPVer.dwVer = 100;
398#define DRIVER_VER_STR "My Driver V1.00"
399 memcpy(kernelKPVer.cVer, DRIVER_VER_STR, sizeof(DRIVER_VER_STR));
400 COPY_TO_USER(pUserKPVer, &kernelKPVer, sizeof(KP_PCI_VERSION));
401 kpCall->dwResult = KP_PCI_STATUS_OK;
402 }
403 break;
404
405 default:
406 kpCall->dwResult = KP_PCI_STATUS_MSG_NO_IMPL;
407 }
408
409 /* NOTE: You can modify the messages above and/or add your own
410 Kernel PlugIn messages.
411 When changing/adding messages, be sure to also update the
412 messages definitions in ../pci_lib.h. */
413}
434BOOL __cdecl KP_PCI_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall,
435 PVOID *ppIntContext)
436{
437 KP_PCI_Trace("KP_PCI_IntEnable: Entered\n");
438
439 /* You can allocate specific memory for each interrupt in *ppIntContext */
440
441 /* In this sample we will set the interrupt context to the driver context,
442 which has been set in KP_PCI_Open to hold the device information. */
443 *ppIntContext = pDrvContext;
444
445 /* TODO: You can add code here to write to the device in order
446 to physically enable the hardware interrupts */
447
448 return TRUE;
449}
450
462void __cdecl KP_PCI_IntDisable(PVOID pIntContext)
463{
464 /* Free any memory allocated in KP_PCI_IntEnable() here */
465}
501BOOL __cdecl KP_PCI_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt)
502{
503 static DWORD dwIntCount = 0; /* Interrupts count */
504 PCI_DEV_ADDR_DESC *pDevAddrDesc = (PCI_DEV_ADDR_DESC *)pIntContext;
505/* @kp_IntAtIrql@ */
506/* @sample_only_start@ */
507#ifndef ISA
508 WDC_ADDR_DESC *pAddrDesc = &pDevAddrDesc->pAddrDesc[INTCSR_ADDR_SPACE];
509
510#define USE_MULTI_TRANSFER
511#if defined USE_MULTI_TRANSFER
512 /* Define the number of interrupt transfer commands to use */
513 WD_TRANSFER trans[2];
514
515 /*
516 This sample demonstrates how to set up two transfer commands, one for
517 reading the device's INTCSR register (as defined in gPCI_Regs) and one
518 for writing to it to acknowledge the interrupt.
519
520 TODO: PCI interrupts are level sensitive interrupts and must be
521 acknowledged in the kernel immediately when they are received.
522 Since the information for acknowledging the interrupts is
523 hardware-specific, YOU MUST MODIFY THE CODE below and set up
524 transfer commands in order to correctly acknowledge the interrupts
525 on your device, as dictated by your hardware's specifications.
526
527 *************************************************************************
528 * NOTE: If you attempt to use this code without first modifying it in *
529 * order to correctly acknowledge your device's interrupts, as *
530 * explained above, the OS will HANG when an interrupt occurs! *
531 *************************************************************************
532 */
533
534 BZERO(trans);
535
536 /* Prepare the interrupt transfer commands */
537
538 /* #1: Read status from the INTCSR register */
539 trans[0].pPort = pAddrDesc->pAddr + INTCSR;
540 /* 32bit read: */
541 trans[0].cmdTrans =
542#ifndef PLATFORM_API
543 WDC_ADDR_IS_MEM(pAddrDesc) ? RM_DWORD : RP_DWORD;
544#else /* ifdef PLATFORM_API */
545 RM_DWORD;
546#endif /* ifndef PLATFORM_API */
547
548 /* #2: Write ALL_INT_MASK to the INTCSR register to acknowledge the
549 interrupt */
550 /* In this example both commands access the same address (register): */
551 trans[1].pPort = trans[0].pPort;
552 /* 32bit write: */
553 trans[1].cmdTrans =
554#ifndef PLATFORM_API
555 WDC_ADDR_IS_MEM(pAddrDesc) ? WM_DWORD : WP_DWORD;
556#else /* ifdef PLATFORM_API */
557 WM_DWORD;
558#endif /* ifndef PLATFORM_API */
559 trans[1].Data.Dword = ALL_INT_MASK;
560
561 /* Execute the transfer commands */
562 WDC_MultiTransfer(trans, 2);
563#else
564 /* NOTE: For memory registers you can replace the use of WDC_MultiTransfer()
565 (or any other WD_xxx/WDC_xxx read/write function call) with direct
566 memory access. For example, if INTCSR is a memory register, the code
567 above can be replaced with the following: */
568
569 UINT32 readData;
570 PVOID pData = (DWORD *)(pAddrDesc->pAddr + INTCSR);
571
572 /* Read status from the PCI_INTCSR register */
573 readData = WDC_ReadMem32(pData, 0);
574
575 /* Write to the PCI_INTCSR register to acknowledge the interrupt */
576 WDC_WriteMem32(pData, 0, ALL_INT_MASK);
577#endif
578#undef USE_MULTI_TRANSFER
579
580 /* If the data read from the hardware indicates that the interrupt belongs
581 to you, you must set *pfIsMyInterrupt to TRUE.
582 Otherwise, set it to FALSE (this will let ISR's of other drivers be
583 invoked). */
584 *pfIsMyInterrupt = FALSE;
585#endif /* ifndef ISA */
586/* @sample_only_end@ */
587 /* This sample schedules a DPC once in every 5 interrupts.
588 TODO: You can modify the implementation to schedule the DPC as needed. */
589 dwIntCount++;
590 if (!(dwIntCount % 5))
591 return TRUE;
592
593 return FALSE;
594}
595
618DWORD __cdecl KP_PCI_IntAtDpc(PVOID pIntContext, DWORD dwCount)
619{
620 return dwCount;
621}
622
623#ifndef PLATFORM_API
661BOOL __cdecl KP_PCI_IntAtIrqlMSI(PVOID pIntContext, ULONG dwLastMessage,
662 DWORD dwVector)
663{
664 static DWORD dwIntCount = 0; /* Interrupts count */
665
666 /* There is no need to acknowledge MSI/MSI-X. However, you can implement
667 the same functionality here as done in the KP_PCI_IntAtIrql handler
668 to read/write data from/to registers at HIGH IRQL. */
669
670 /* This sample schedules a DPC once in every 5 interrupts.
671 TODO: You can modify the implementation to schedule the DPC as needed. */
672 dwIntCount++;
673 if (!(dwIntCount % 5))
674 return TRUE;
675
676 return FALSE;
677}
678
706DWORD __cdecl KP_PCI_IntAtDpcMSI(PVOID pIntContext, DWORD dwCount,
707 ULONG dwLastMessage, DWORD dwReserved)
708{
709 return dwCount;
710}
711
712#ifndef ISA
713
730BOOL __cdecl KP_PCI_Event(PVOID pDrvContext, WD_EVENT *wd_event)
731{
732 return TRUE; /* Return TRUE to notify the user mode of the event */
733}
734#endif /* ifndef ISA */
735#endif /* ifndef PLATFORM_API */
736
737/* -----------------------------------------------
738 Debugging and error handling
739 ----------------------------------------------- */
740static void KP_PCI_Err(const CHAR *sFormat, ...)
741{
742#if defined(DEBUG)
743 CHAR sMsg[256];
744 va_list argp;
745
746 va_start(argp, sFormat);
747 vsnprintf(sMsg, sizeof(sMsg) - 1, sFormat, argp);
748 WDC_Err("%s: %s", KP_PCI_DRIVER_NAME, sMsg);
749 va_end(argp);
750#endif
751}
752
753static void KP_PCI_Trace(const CHAR *sFormat, ...)
754{
755#if defined(DEBUG)
756 CHAR sMsg[256];
757 va_list argp;
758
759 va_start(argp, sFormat);
760 vsnprintf(sMsg, sizeof(sMsg) - 1, sFormat, argp);
761 WDC_Trace("%s: %s", KP_PCI_DRIVER_NAME, sMsg);
762 va_end(argp);
763#endif
764}
765
BOOL __cdecl KP_PCI_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData, PVOID *ppDrvContext)
Kernel PlugIn open function.
Definition: kp_pci.c:156
DWORD __cdecl KP_PCI_IntAtDpc(PVOID pIntContext, DWORD dwCount)
Deferred processing legacy interrupt handler routine.
Definition: kp_pci.c:618
BOOL __cdecl KP_PCI_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, PVOID *ppIntContext)
Called when WDC_IntEnable() / WD_IntEnable() is called from the user mode with a Kernel PlugIn handle...
Definition: kp_pci.c:434
BOOL __cdecl KP_PCI_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt)
High-priority legacy interrupt handler routine, which is run at high interrupt request level.
Definition: kp_pci.c:501
#define DRIVER_VER_STR
#define PTR32
Definition: kp_pci.c:48
void __cdecl KP_PCI_Close(PVOID pDrvContext)
Called when WD_KernelPlugInClose() (see the WinDriver PCI Low-Level API Reference) is called from use...
Definition: kp_pci.c:332
void __cdecl KP_PCI_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall)
Called when the user-mode application calls WDC_CallKerPlug() (or the low-level WD_KernelPlugInCall()...
Definition: kp_pci.c:383
void __cdecl KP_PCI_IntDisable(PVOID pIntContext)
Called when WDC_IntDisable() / WD_IntDisable() is called from the user mode for interrupts that were ...
Definition: kp_pci.c:462
BOOL __cdecl KP_Init(KP_INIT *kpInit)
KP_Init is called when the Kernel PlugIn driver is loaded.
Definition: kp_pci.c:67
BOOL __cdecl KP_PCI_Open_32_64(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData, PVOID *ppDrvContext)
KP_PCI_Open_32_64 is called when WD_KernelPlugInOpen() is called from a 32-bit user mode application ...
Definition: kp_pci.c:238
#define NULL
Definition: kpstdlib.h:269
void *__cdecl malloc(size_t size)
#define TRUE
Definition: kpstdlib.h:265
#define FALSE
Definition: kpstdlib.h:261
void __cdecl free(void *buf)
char *__cdecl strcpy(char *s1, const char *s2)
CHAR cDriverName[WD_MAX_KP_NAME_LENGTH]
return the device driver name
Definition: wd_kp.h:69
DWORD dwVerWD
version of the WinDriver Kernel PlugIn library
Definition: wd_kp.h:68
KP_FUNC_OPEN funcOpen
returns the KP_Open function
Definition: wd_kp.h:71
KP_FUNC_OPEN funcOpen_32_64
returns the KP_Open function for 32 bit app with 64 bit KP.
Definition: wd_kp.h:72
Definition: wd_kp.h:67
KP_FUNC_EVENT funcEvent
Definition: wd_kp.h:58
KP_FUNC_CLOSE funcClose
Definition: wd_kp.h:50
KP_FUNC_INT_AT_IRQL funcIntAtIrql
Definition: wd_kp.h:54
KP_FUNC_INT_AT_DPC_MSI funcIntAtDpcMSI
Definition: wd_kp.h:57
KP_FUNC_INT_ENABLE funcIntEnable
Definition: wd_kp.h:52
KP_FUNC_INT_AT_IRQL_MSI funcIntAtIrqlMSI
Definition: wd_kp.h:56
KP_FUNC_INT_AT_DPC funcIntAtDpc
Definition: wd_kp.h:55
KP_FUNC_CALL funcCall
Definition: wd_kp.h:51
KP_FUNC_INT_DISABLE funcIntDisable
Definition: wd_kp.h:53
KPTR pAddr
I/O / Memory kernel mapped address – for WD_Transfer(), WD_MultiTransfer(), or direct kernel access.
Definition: wdc_defs.h:34
Address space information struct.
Definition: wdc_defs.h:27
DWORD cmdTrans
Transfer command WD_TRANSFER_CMD.
Definition: windrvr.h:604
UINT32 Dword
Use for 32 bit transfer.
Definition: windrvr.h:616
KPTR pPort
I/O port for transfer or kernel memory address.
Definition: windrvr.h:603
union WD_TRANSFER::@16 Data
#define vsnprintf
Definition: utils.h:25
#define WD_VER
Definition: wd_ver.h:25
#define WDC_ADDR_IS_MEM(pAddrDesc)
Check if memory or I/O address.
Definition: wdc_defs.h:87
void DLLCALLCONV WDC_Trace(const CHAR *format,...)
Displays debug trace messages according to the WDC debug options.
DWORD DLLCALLCONV WDC_MultiTransfer(_In_ WD_TRANSFER *pTransCmds, _In_ DWORD dwNumTrans)
Performs a group of memory and/or I/O read/write transfers.
void DLLCALLCONV WDC_Err(const CHAR *format,...)
Displays debug error messages according to the WDC debug options.
#define WDC_ReadMem32(addr, off)
reads 4 byte (32 bits) from a specified memory address.
Definition: wdc_lib.h:920
#define WDC_WriteMem32(addr, off, val)
writes 4 byte (32 bits) to a specified memory address.
Definition: wdc_lib.h:945
@ WD_STATUS_SUCCESS
[0] Operation completed successfully
Definition: windrvr.h:1127
@ RM_DWORD
Read memory dword.
Definition: windrvr.h:423
@ WP_DWORD
Write port dword.
Definition: windrvr.h:408
@ WM_DWORD
Write memory dword.
Definition: windrvr.h:426
@ RP_DWORD
Read port dword.
Definition: windrvr.h:405
#define BZERO(buf)
Definition: windrvr.h:1617
unsigned int UINT32
Definition: windrvr.h:341
UINT32 KPTR
Definition: windrvr.h:381