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  *************************************************************/
23 BOOL __cdecl KP_PCI_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData,
24  PVOID *ppDrvContext);
25 /* @32on64@ */
26 BOOL __cdecl KP_PCI_Open_32_64(KP_OPEN_CALL *kpOpenCall, HANDLE hWD,
27  PVOID pOpenData, PVOID *ppDrvContext);
28 /* @32on64@ */
29 void __cdecl KP_PCI_Close(PVOID pDrvContext);
30 void __cdecl KP_PCI_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall);
31 BOOL __cdecl KP_PCI_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall,
32  PVOID *ppIntContext);
33 void __cdecl KP_PCI_IntDisable(PVOID pIntContext);
34 BOOL __cdecl KP_PCI_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt);
35 DWORD __cdecl KP_PCI_IntAtDpc(PVOID pIntContext, DWORD dwCount);
36 BOOL __cdecl KP_PCI_IntAtIrqlMSI(PVOID pIntContext, ULONG dwLastMessage,
37  DWORD dwReserved);
38 DWORD __cdecl KP_PCI_IntAtDpcMSI(PVOID pIntContext, DWORD dwCount,
39  ULONG dwLastMessage, DWORD dwReserved);
40 #ifndef ISA
41 BOOL __cdecl KP_PCI_Event(PVOID pDrvContext, WD_EVENT *wd_event);
42 #endif /* ifndef ISA */
43 static void KP_PCI_Err(const CHAR *sFormat, ...);
44 static void KP_PCI_Trace(const CHAR *sFormat, ...);
45 /* @32on64@ */
46 #define PTR32 UINT32
47 
48 typedef struct {
49  UINT32 dwNumAddrSpaces; /* Total number of device address spaces */
50  PTR32 pAddrDesc; /* Array of device address spaces information */
51 } PCI_DEV_ADDR_DESC_32B;
52 /* @32on64@ */
53 
54 /*************************************************************
55  Functions implementation
56  *************************************************************/
57 
65 BOOL __cdecl KP_Init(KP_INIT *kpInit)
66 {
67  /* Verify that the version of the WinDriver Kernel PlugIn library
68  is identical to that of the windrvr.h and wd_kp.h files */
69  if (WD_VER != kpInit->dwVerWD)
70  {
71  /* Rebuild your Kernel PlugIn driver project with the compatible
72  version of the WinDriver Kernel PlugIn library (kp_nt<version>.lib)
73  and windrvr.h and wd_kp.h files */
74 
75  return FALSE;
76  }
77 
78  kpInit->funcOpen = KP_PCI_Open;
79 /* @32on64@ */
81 /* @32on64@ */
82 #if defined(WINNT)
83  strcpy(kpInit->cDriverName, KP_PCI_DRIVER_NAME);
84 #else
85  strncpy(kpInit->cDriverName, KP_PCI_DRIVER_NAME,
86  sizeof(kpInit->cDriverName));
87 #endif
88  kpInit->cDriverName[sizeof(kpInit->cDriverName) - 1] = 0;
89 
90  return TRUE;
91 }
92 
154 BOOL __cdecl KP_PCI_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData,
155  PVOID *ppDrvContext)
156 {
157  PCI_DEV_ADDR_DESC *pDevAddrDesc;
158  DWORD dwSize;
159  DWORD dwStatus;
160 
161  /* Initialize the PCI library */
162  dwStatus = PCI_LibInit();
163  if (WD_STATUS_SUCCESS != dwStatus)
164  {
165  KP_PCI_Err("KP_PCI_Open: Failed to initialize the PCI library. "
166  "Last error [%s]\n", PCI_GetLastErr());
167  return FALSE;
168  }
169 
170  KP_PCI_Trace("KP_PCI_Open: Entered. PCI library initialized\n");
171 
172  kpOpenCall->funcClose = KP_PCI_Close;
173  kpOpenCall->funcCall = KP_PCI_Call;
174  kpOpenCall->funcIntEnable = KP_PCI_IntEnable;
175  kpOpenCall->funcIntDisable = KP_PCI_IntDisable;
176  kpOpenCall->funcIntAtIrql = KP_PCI_IntAtIrql;
177  kpOpenCall->funcIntAtDpc = KP_PCI_IntAtDpc;
179  kpOpenCall->funcIntAtDpcMSI = KP_PCI_IntAtDpcMSI;
180 #ifndef ISA
181  kpOpenCall->funcEvent = KP_PCI_Event;
182 #endif /* ifndef ISA */
183 
184  if (ppDrvContext)
185  {
186  if (pOpenData)
187  {
188  WDC_ADDR_DESC *pAddrDesc;
189 
190  /* Create a copy of device information in the driver context */
191  dwSize = sizeof(PCI_DEV_ADDR_DESC);
192  pDevAddrDesc = malloc(dwSize);
193  if (!pDevAddrDesc)
194  goto malloc_error;
195 
196  COPY_FROM_USER(pDevAddrDesc, pOpenData, dwSize);
197 
198  dwSize = sizeof(WDC_ADDR_DESC) * pDevAddrDesc->dwNumAddrSpaces;
199  pAddrDesc = malloc(dwSize);
200  if (!pAddrDesc)
201  goto malloc_error;
202 
203  COPY_FROM_USER(pAddrDesc, pDevAddrDesc->pAddrDesc, dwSize);
204  pDevAddrDesc->pAddrDesc = pAddrDesc;
205 
206  *ppDrvContext = pDevAddrDesc;
207  }
208  else
209  {
210  *ppDrvContext = NULL;
211  }
212  }
213 
214  KP_PCI_Trace("KP_PCI_Open: Kernel PlugIn driver opened successfully\n");
215 
216  return TRUE;
217 
218 malloc_error:
219  KP_PCI_Err("KP_PCI_Open: Failed allocating [%ld] bytes\n", dwSize);
220  if (pDevAddrDesc)
221  free(pDevAddrDesc);
222  PCI_LibUninit();
223  return FALSE;
224 }
225 
226 /* @32on64@ */
227 
234 BOOL __cdecl KP_PCI_Open_32_64(KP_OPEN_CALL *kpOpenCall, HANDLE hWD,
235  PVOID pOpenData, PVOID *ppDrvContext)
236 {
237  PCI_DEV_ADDR_DESC *pDevAddrDesc;
238  DWORD dwSize;
239  DWORD dwStatus;
240 
241  /* Initialize the PCI library */
242  dwStatus = PCI_LibInit();
243  if (WD_STATUS_SUCCESS != dwStatus)
244  {
245  KP_PCI_Err("KP_PCI_Open_32_64: Failed to initialize the PCI library. "
246  "Last error [%s]\n", PCI_GetLastErr());
247  return FALSE;
248  }
249 
250  KP_PCI_Trace("KP_PCI_Open_32_64: Entered. PCI library initialized\n");
251 
252  kpOpenCall->funcClose = KP_PCI_Close;
253  kpOpenCall->funcCall = KP_PCI_Call;
254  kpOpenCall->funcIntEnable = KP_PCI_IntEnable;
255  kpOpenCall->funcIntDisable = KP_PCI_IntDisable;
256  kpOpenCall->funcIntAtIrql = KP_PCI_IntAtIrql;
257  kpOpenCall->funcIntAtDpc = KP_PCI_IntAtDpc;
259  kpOpenCall->funcIntAtDpcMSI = KP_PCI_IntAtDpcMSI;
260 #ifndef ISA
261  kpOpenCall->funcEvent = KP_PCI_Event;
262 #endif /* ifndef ISA */
263 
264  if (ppDrvContext)
265  {
266  if (pOpenData)
267  {
268  PCI_DEV_ADDR_DESC_32B devAddrDesc_32;
269  WDC_ADDR_DESC *pAddrDesc;
270 
271  /* Create a copy of the device information in the driver context */
272  dwSize = sizeof(PCI_DEV_ADDR_DESC);
273  pDevAddrDesc = malloc(dwSize);
274  if (!pDevAddrDesc)
275  goto malloc_error;
276 
277  /* Copy device information sent from a 32-bit user application */
278  COPY_FROM_USER(&devAddrDesc_32, pOpenData,
279  sizeof(PCI_DEV_ADDR_DESC_32B));
280 
281  /* Copy the 32-bit data to a 64-bit struct */
282  pDevAddrDesc->dwNumAddrSpaces = devAddrDesc_32.dwNumAddrSpaces;
283  dwSize = sizeof(WDC_ADDR_DESC) * pDevAddrDesc->dwNumAddrSpaces;
284  pAddrDesc = malloc(dwSize);
285  if (!pAddrDesc)
286  goto malloc_error;
287 
288  COPY_FROM_USER(pAddrDesc, (PVOID)(KPTR)devAddrDesc_32.pAddrDesc,
289  dwSize);
290  pDevAddrDesc->pAddrDesc = pAddrDesc;
291 
292  *ppDrvContext = pDevAddrDesc;
293  }
294  else
295  {
296  *ppDrvContext = NULL;
297  }
298  }
299 
300  KP_PCI_Trace("KP_PCI_Open_32_64: Kernel PlugIn driver opened "
301  "successfully\n");
302 
303  return TRUE;
304 
305 malloc_error:
306  KP_PCI_Err("KP_PCI_Open_32_64: Failed allocating [%ld] bytes\n", dwSize);
307  if (pDevAddrDesc)
308  free(pDevAddrDesc);
309  PCI_LibUninit();
310  return FALSE;
311 }
312 /* @32on64@ */
313 
326 void __cdecl KP_PCI_Close(PVOID pDrvContext)
327 {
328  DWORD dwStatus;
329 
330  KP_PCI_Trace("KP_PCI_Close: Entered\n");
331 
332  /* Uninit the PCI library */
333  dwStatus = PCI_LibUninit();
334  if (WD_STATUS_SUCCESS != dwStatus)
335  {
336  KP_PCI_Err("KP_PCI_Close: Failed to uninit the PCI library. "
337  "Last error [%s]\n", PCI_GetLastErr());
338  }
339 
340  /* Free the memory allocated for the driver context */
341  if (pDrvContext)
342  {
343  if (((PCI_DEV_ADDR_DESC *)pDrvContext)->pAddrDesc)
344  free(((PCI_DEV_ADDR_DESC *)pDrvContext)->pAddrDesc);
345  free(pDrvContext);
346  }
347 }
348 
377 void __cdecl KP_PCI_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall)
378 {
379  KP_PCI_Trace("KP_PCI_Call: Entered. Message [0x%lx]\n", kpCall->dwMessage);
380 
381  kpCall->dwResult = KP_PCI_STATUS_OK;
382 
383  switch (kpCall->dwMessage)
384  {
385  case KP_PCI_MSG_VERSION: /* Get the version of the Kernel PlugIn driver */
386  {
387  KP_PCI_VERSION *pUserKPVer = (KP_PCI_VERSION *)(kpCall->pData);
388  KP_PCI_VERSION kernelKPVer;
389 
390  BZERO(kernelKPVer);
391  kernelKPVer.dwVer = 100;
392 #define DRIVER_VER_STR "My Driver V1.00"
393  memcpy(kernelKPVer.cVer, DRIVER_VER_STR, sizeof(DRIVER_VER_STR));
394  COPY_TO_USER(pUserKPVer, &kernelKPVer, sizeof(KP_PCI_VERSION));
395  kpCall->dwResult = KP_PCI_STATUS_OK;
396  }
397  break;
398 
399  default:
400  kpCall->dwResult = KP_PCI_STATUS_MSG_NO_IMPL;
401  }
402 
403  /* NOTE: You can modify the messages above and/or add your own
404  Kernel PlugIn messages.
405  When changing/adding messages, be sure to also update the
406  messages definitions in ../pci_lib.h. */
407 }
428 BOOL __cdecl KP_PCI_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall,
429  PVOID *ppIntContext)
430 {
431  KP_PCI_Trace("KP_PCI_IntEnable: Entered\n");
432 
433  /* You can allocate specific memory for each interrupt in *ppIntContext */
434 
435  /* In this sample we will set the interrupt context to the driver context,
436  which has been set in KP_PCI_Open to hold the device information. */
437  *ppIntContext = pDrvContext;
438 
439  /* TODO: You can add code here to write to the device in order
440  to physically enable the hardware interrupts */
441 
442  return TRUE;
443 }
444 
456 void __cdecl KP_PCI_IntDisable(PVOID pIntContext)
457 {
458  /* Free any memory allocated in KP_PCI_IntEnable() here */
459 }
495 BOOL __cdecl KP_PCI_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt)
496 {
497  static DWORD dwIntCount = 0; /* Interrupts count */
498  PCI_DEV_ADDR_DESC *pDevAddrDesc = (PCI_DEV_ADDR_DESC *)pIntContext;
499 /* @kp_IntAtIrql@ */
500 /* @sample_only_start@ */
501 #ifndef ISA
502  WDC_ADDR_DESC *pAddrDesc = &pDevAddrDesc->pAddrDesc[INTCSR_ADDR_SPACE];
503 
504 #define USE_MULTI_TRANSFER
505 #if defined USE_MULTI_TRANSFER
506  /* Define the number of interrupt transfer commands to use */
507  WD_TRANSFER trans[2];
508 
509  /*
510  This sample demonstrates how to set up two transfer commands, one for
511  reading the device's INTCSR register (as defined in gPCI_Regs) and one
512  for writing to it to acknowledge the interrupt.
513 
514  TODO: PCI interrupts are level sensitive interrupts and must be
515  acknowledged in the kernel immediately when they are received.
516  Since the information for acknowledging the interrupts is
517  hardware-specific, YOU MUST MODIFY THE CODE below and set up
518  transfer commands in order to correctly acknowledge the interrupts
519  on your device, as dictated by your hardware's specifications.
520 
521  *************************************************************************
522  * NOTE: If you attempt to use this code without first modifying it in *
523  * order to correctly acknowledge your device's interrupts, as *
524  * explained above, the OS will HANG when an interrupt occurs! *
525  *************************************************************************
526  */
527 
528  BZERO(trans);
529 
530  /* Prepare the interrupt transfer commands */
531 
532  /* #1: Read status from the INTCSR register */
533  trans[0].pPort = pAddrDesc->pAddr + INTCSR;
534  /* 32bit read: */
535  trans[0].cmdTrans = WDC_ADDR_IS_MEM(pAddrDesc) ? RM_DWORD : RP_DWORD;
536 
537  /* #2: Write ALL_INT_MASK to the INTCSR register to acknowledge the
538  interrupt */
539  /* In this example both commands access the same address (register): */
540  trans[1].pPort = trans[0].pPort;
541  /* 32bit write: */
542  trans[1].cmdTrans = WDC_ADDR_IS_MEM(pAddrDesc) ? WM_DWORD : WP_DWORD;
543  trans[1].Data.Dword = ALL_INT_MASK;
544 
545  /* Execute the transfer commands */
546  WDC_MultiTransfer(trans, 2);
547 #else
548  /* NOTE: For memory registers you can replace the use of WDC_MultiTransfer()
549  (or any other WD_xxx/WDC_xxx read/write function call) with direct
550  memory access. For example, if INTCSR is a memory register, the code
551  above can be replaced with the following: */
552 
553  UINT32 readData;
554  PVOID pData = (DWORD *)(pAddrDesc->pAddr + INTCSR);
555 
556  /* Read status from the PCI_INTCSR register */
557  readData = WDC_ReadMem32(pData, 0);
558 
559  /* Write to the PCI_INTCSR register to acknowledge the interrupt */
560  WDC_WriteMem32(pData, 0, ALL_INT_MASK);
561 #endif
562 #undef USE_MULTI_TRANSFER
563 
564  /* If the data read from the hardware indicates that the interrupt belongs
565  to you, you must set *pfIsMyInterrupt to TRUE.
566  Otherwise, set it to FALSE (this will let ISR's of other drivers be
567  invoked). */
568  *pfIsMyInterrupt = FALSE;
569 #endif /* ifndef ISA */
570 /* @sample_only_end@ */
571  /* This sample schedules a DPC once in every 5 interrupts.
572  TODO: You can modify the implementation to schedule the DPC as needed. */
573  dwIntCount++;
574  if (!(dwIntCount % 5))
575  return TRUE;
576 
577  return FALSE;
578 }
579 
602 DWORD __cdecl KP_PCI_IntAtDpc(PVOID pIntContext, DWORD dwCount)
603 {
604  return dwCount;
605 }
643 BOOL __cdecl KP_PCI_IntAtIrqlMSI(PVOID pIntContext, ULONG dwLastMessage,
644  DWORD dwReserved)
645 {
646  static DWORD dwIntCount = 0; /* Interrupts count */
647 
648  /* There is no need to acknowledge MSI/MSI-X. However, you can implement
649  the same functionality here as done in the KP_PCI_IntAtIrql handler
650  to read/write data from/to registers at HIGH IRQL. */
651 
652  /* This sample schedules a DPC once in every 5 interrupts.
653  TODO: You can modify the implementation to schedule the DPC as needed. */
654  dwIntCount++;
655  if (!(dwIntCount % 5))
656  return TRUE;
657 
658  return FALSE;
659 }
660 
688 DWORD __cdecl KP_PCI_IntAtDpcMSI(PVOID pIntContext, DWORD dwCount,
689  ULONG dwLastMessage, DWORD dwReserved)
690 {
691  return dwCount;
692 }
693 
694 #ifndef ISA
695 
712 BOOL __cdecl KP_PCI_Event(PVOID pDrvContext, WD_EVENT *wd_event)
713 {
714  return TRUE; /* Return TRUE to notify the user mode of the event */
715 }
716 #endif /* ifndef ISA */
717 
718 /* -----------------------------------------------
719  Debugging and error handling
720  ----------------------------------------------- */
721 static void KP_PCI_Err(const CHAR *sFormat, ...)
722 {
723 #if defined(DEBUG)
724  CHAR sMsg[256];
725  va_list argp;
726 
727  va_start(argp, sFormat);
728  vsnprintf(sMsg, sizeof(sMsg) - 1, sFormat, argp);
729  WDC_Err("%s: %s", KP_PCI_DRIVER_NAME, sMsg);
730  va_end(argp);
731 #endif
732 }
733 
734 static void KP_PCI_Trace(const CHAR *sFormat, ...)
735 {
736 #if defined(DEBUG)
737  CHAR sMsg[256];
738  va_list argp;
739 
740  va_start(argp, sFormat);
741  vsnprintf(sMsg, sizeof(sMsg) - 1, sFormat, argp);
742  WDC_Trace("%s: %s", KP_PCI_DRIVER_NAME, sMsg);
743  va_end(argp);
744 #endif
745 }
746 
BOOL __cdecl KP_PCI_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData, PVOID *ppDrvContext)
Kernel PlugIn open function.
Definition: kp_pci.c:154
BOOL __cdecl KP_PCI_IntAtIrqlMSI(PVOID pIntContext, ULONG dwLastMessage, DWORD dwReserved)
High-priority Message-Signaled Interrupts (MSI) / Extended Message-Signaled Interrupts (MSI-X) handle...
Definition: kp_pci.c:643
DWORD __cdecl KP_PCI_IntAtDpcMSI(PVOID pIntContext, DWORD dwCount, ULONG dwLastMessage, DWORD dwReserved)
Deferred processing Message-Signaled Interrupts (MSI) / Extended Message-Signaled Interrupts (MSI-X) ...
Definition: kp_pci.c:688
DWORD __cdecl KP_PCI_IntAtDpc(PVOID pIntContext, DWORD dwCount)
Deferred processing legacy interrupt handler routine.
Definition: kp_pci.c:602
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:428
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:495
#define DRIVER_VER_STR
#define PTR32
Definition: kp_pci.c:46
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:326
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:377
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:456
BOOL __cdecl KP_Init(KP_INIT *kpInit)
KP_Init is called when the Kernel PlugIn driver is loaded.
Definition: kp_pci.c:65
BOOL __cdecl KP_PCI_Event(PVOID pDrvContext, WD_EVENT *wd_event)
Called when a Plug-and-Play or power management event for the device is received, provided the user-m...
Definition: kp_pci.c:712
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:234
#define NULL
Definition: kpstdlib.h:268
char *__cdecl strcpy(char *s1, const char *s2)
void *__cdecl malloc(unsigned long size)
#define TRUE
Definition: kpstdlib.h:264
#define FALSE
Definition: kpstdlib.h:260
void __cdecl free(void *buf)
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:586
UINT32 Dword
Use for 32 bit transfer.
Definition: windrvr.h:597
union WD_TRANSFER::@14 Data
KPTR pPort
I/O port for transfer or kernel memory address.
Definition: windrvr.h:585
#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:739
#define WDC_WriteMem32(addr, off, val)
writes 4 byte (32 bits) to a specified memory address.
Definition: wdc_lib.h:764
@ WD_STATUS_SUCCESS
[0] Operation completed successfully
Definition: windrvr.h:1061
@ RM_DWORD
Read memory dword.
Definition: windrvr.h:410
@ WP_DWORD
Write port dword.
Definition: windrvr.h:395
@ WM_DWORD
Write memory dword.
Definition: windrvr.h:413
@ RP_DWORD
Read port dword.
Definition: windrvr.h:392
#define BZERO(buf)
Definition: windrvr.h:1548
unsigned int UINT32
Definition: windrvr.h:337
UINT32 KPTR
Definition: windrvr.h:368