2.11. WD_Transfer()

Purpose

Executes a single read/write instruction to an I/O port or to a memory address.

Prototype
DWORD WD_Transfer(
    HANDLE hWD,
    WD_TRANSFER *pTrans);
Parameters
NameTypeInput/Output
hWDHANDLEInput
pTransWD_TRANSFER* 
• cmdTransDWORDInput
• dwPortKPTRInput
• dwBytesDWORDInput
• fAutoincDWORDInput
• dwOptionsDWORDInput
• Dataunion 
 * ByteBYTEInput/Output
 * WordWORDInput/Output
 * DwordUINT32Input/Output
 * QwordUINT64Input/Output
 * pBufferPVOIDInput/Output
Description
NameDescription
hWDHandle to WinDriver's kernel-mode driver as received from WD_Open() [5.2]
pTransPointer to a transfer information structure:
• cmdTrans

A value indicating the type of transfer to perform — see definition of the WD_TRANSFER_CMD enumeration in windrvr.h.

In calls to WD_Transfer() the transfer command should be a read/write transfer command that conforms to the following format: <dir><p>_[S]<size>
Explanation:
<dir>: R for read, W for write
<p>: P for I/O, M for memory
<S>: signifies a string (block) transfer, as opposed to a single transfer
<size>: BYTE, WORD, DWORD or QWORD .

• dwPort

The memory or I/O address to access.

For a memory transfer, use the kernel-mapping of the base address received from WD_CardRegister() [2.8] in pCardReg->Card.Item[i]I.Mem.dwTransAddr (where 'i' is the index of the relevant memory item) + the desired offset from the beginning of the address range.

For an I/O transfer, use the base address received from WD_CardRegister() [2.8] in pCardReg->Card.Item[i]I.IO.dwAddr (where 'i' is the index of the relevant I/O item) + the desired offset from the beginning of the address range.

• dwBytes Used in string transfers — number of bytes to transfer
• fAutoinc Used for string transfers.
If TRUE, I/O or memory address should be incremented for transfer.
If FALSE, all data is transferred to the same port/address.
• dwOptions Must be set to 0
• Data The transfer data — input for read transfers, output for write transfers:
 * Byte Used for 8-bit transfers
 * WordUsed for 16-bit transfers
 * DwordUsed for 32-bit transfers
 * QwordUsed for 64-bit transfers
 * pBufferUsed for string (block) transfers
Return Value

Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A].

Remarks
  • 64-bit data transfers (QWORD) are available only for memory string transfers.
    Such transfers require 64-bit enabled PCI device, a 64-bit PCI bus, and an x86 CPU running under any of the operating systems supported by WinDriver. (Note: 64-bit data transfers performed with WD_Transfer() do not require 64-bit operating system/CPU).
  • When using WD_Transfer(), it is important to align the base address according to the size of the data type, especially when issuing string transfer commands. Otherwise, the transfers are split into smaller portions. The easiest way to align data is to use basic types when defining a buffer, i.e.:
    BYTE buf[len];    /* For BYTE transfers - not aligned */
    WORD buf[len];    /* For WORD transfers - aligned on 2-byte boundary */
    UINT32 buf[len];  /* For DWORD transfers - aligned on 4-byte boundary */
    UINT64 buf[len];  /* For QWORD transfers - aligned on 8-byte boundary */
    

Example
WD_TRANSFER Trans;
BYTE read_data;

BZERO(Trans);
Trans.cmdTrans = RP_BYTE; /* Read Port BYTE */
Trans.dwPort = 0x210;
WD_Transfer(hWD, &Trans);
read_data = Trans.Data.Byte;