• Maps the physical memory ranges to be accessed by kernel-mode
processes and user-mode applications.
• Checks whether an I/O or Memory resource was previously
exclusively registered.
• Saves data regarding the interrupt request (IRQ) number and the
interrupt type in internal data structures; this data will later be used by
InterruptEnable() [2.18]
and/or
WD_IntEnable() [3.2].
DWORD WD_CardRegister(
HANDLE hWD,
WD_CARD_REGISTER *pCardReg);
| Name | Type | Input/Output |
|---|---|---|
| hWD | HANDLE | Input |
| pCardReg | WD_CARD_REGISTER* | |
| • Card | WD_CARD | |
| * dwItems | DWORD | Input |
| * Item | WD_ITEMS[WD_CARD_ITEMS] | |
| • item | DWORD | Input |
| • fNotSharable | DWORD | Input |
| • dwReserved | DWORD | N/A |
| • dwOptions | DWORD | Input |
| • I | union | |
| * Mem | struct | |
| • dwPhysicalAddr | DWORD | Input |
| • dwBytes | DWORD | Input |
| • dwTransAddr | DWORD | Output |
| • dwUserDirectAddr | DWORD | Output |
| • dwCpuPhysicalAddr | DWORD | Output |
| • dwBar | DWORD | Input |
| * IO | struct | |
| • dwAddr | KPTR | Input |
| • dwBytes | DWORD | Input |
| • dwBar | DWORD | Input |
| * Int | struct | |
| • dwInterrupt | DWORD | Input |
| • dwOptions | DWORD | Input |
| • hInterrupt | DWORD | Output |
| * Bus | WD_BUS | |
| • dwBusType | WD_BUS_TYPE | Input |
| • dwBusNum | DWORD | Input |
| • dwSlotFunc | DWORD | Input |
| * Val | struct | N/A |
| • fCheckLockOnly | DWORD | Input |
| • hCard | DWORD | Output |
| • dwOptions | DWORD | Input |
| • cName | CHAR[32] | Input |
| • cDescription | CHAR[100] | Input |
| Name | Description |
|---|---|
| hWD | Handle to WinDriver's kernel-mode driver as
received from WD_Open() [5.2] |
| pCardReg | Pointer to a card registration information structure: |
| • Card |
Card information structure. For PCI and PCMCIA devices it is recommended to
pass the card structure received from a previous call to
WD_PciGetCardInfo() [2.3]
/ WD_PcmciaGetCardInfo() [2.6], respectively (refer to the first remark below.
|
| * dwItems | Number of items detected on the card |
| * Item | Card items information structure: |
| • item | Type of item. Can be ITEM_MEMORY, ITEM_IO,
ITEM_INTERRUPT or ITEM_BUS. |
| • fNotSharable | If TRUE, only one application at a time can access
the mapped memory range, or monitor this card's interrupts |
| • dwOptions |
Can be set to a combination of any of the following
WD_ITEM_OPTIONS flags:• WD_ITEM_DO_NOT_MAP_KERNEL: Avoid mapping a
memory address range to the kernel virtual address space and map the
memory only to the user-mode virtual address space For more information,
see the Remarks to this function.NOTE: This flag is applicable only to memory items. • WD_ITEM_ALLOW_CACHE (Windows and Windows CE): Map the
item's physical memory (I.Mem.dwPhysicalAddr) as cached.
NOTE: This flag is applicable only to memory items that pertain to the host's RAM, as opposed to local memory on the card. |
| • I | Specific data according to the item type: |
| * Mem | Describes a memory item (item = ITEM_MEMORY): |
| • dwPhysicalAddr | First address of the physical memory range |
| • dwBytes | Length (in bytes) of the memory range |
| • dwTransAddr |
Kernel-mode mapping of the memory range's physical base address
(dwPhysicalAddr).This address should be used when setting the memory address in calls to WD_Transfer() [2.11] or
WD_MultiTransfer() [2.12]
or when accessing memory directly from a Kernel PlugIn driver.
|
| • dwUserDirectAddr |
User-mode mapping of the memory range's physical base address
(dwPhysicalAddr).This address should be used for accessing a memory address directly from a user-mode process. |
| • dwCpuPhysicalAddr | Translation of the card's physical memory base address
(dwPhysicalAddr) from bus-specific values to CPU values
|
| • dwBar | Base Address Register number of PCI card |
| * IO | Describes an I/O item (item = ITEM_IO): |
| • dwAddr | First address of the I/O range |
| • dwBytes | Length of the I/O range, in bytes |
| • dwBar | Base Address Register (BAR) number for the I/O range |
| * Int |
Describes an interrupt item (item = ITEM_INTERRUPT):
|
| • dwInterrupt | Physical interrupt request (IRQ) number |
| • dwOptions |
Interrupt options bit-mask, which can consist of a combination of any of
the following flags: Interrupt type flags: NOTE: In the call to WD_CardRegister() the interrupt type
flags are appliable only to ISA devices. For Plug-and-Play hardware (PCI/PCMCIA)
the function retrieves the supported interrupt types independently.• INTERRUPT_LEVEL_SENSITIVE – indicates
that the device supports level-sensitive interrupts.• INTERRUPT_LATCHED – indicates that the
device supports legacy edge-triggered interrupts.The value of this flag is zero, therefore it is applicable only when no other interrupt flag is set. Miscellaneous interrupt flags: • INTERRUPT_CE_INT_ID – On Windows CE(unlike other operating systems), there is an abstraction of the physical interrupt number to a logical one. Setting this bit will instruct WinDriver to refer to the dwInterrupt value as a logical interrupt
number and convert it to a physical interrupt number.
|
| • hInterrupt |
An interrupt handle to be used in calls to
InterruptEnable() [2.18] or
WD_IntEnable() [3.2].
|
| * Bus |
Describes a bus item (item = ITEM_BUS):
|
| • dwBusType |
The card's bus type. Can be any of the following WD_BUS_TYPE
enumeration values:• WD_BUS_PCI – PCI bus• WD_BUS_PCMCIA – PCMCIA bus• WD_BUS_ISA – ISA bus • WD_BUS_EISA – EISA bus
|
| • dwBusNum | Bus number |
| • dwSlotFunc | A combination of the card's bus slot/socket and function numbers: the lower three bits represent the function number and the remaining bits represent the slot/socket number. For example: a value of 0x80 (<=> 10000000 binary) corresponds to a function number of 0 (lower 3 bits: 000) and a slot/socket number of 0x10 (remaining bits: 10000). |
| • fCheckLockOnly |
Set to TRUE to check if the defined card resources can be
locked (in which case hCard will be set to 1), or whether
they are already locked for exclusive use. When this flag is set to
TRUE the function doesn't actually locking the specified
resources.
|
| • hCard |
Handle to the card resources defined in the Card field.
This handle should later be passed to
WD_CardUnregister() [2.10]
in order to free the resources. If the
card registration fails, this field is set to 0.When fCheckLockOnly is set to TRUE,
hCard is set to 1 if the card's resources can be be locked
successfully (i.e., the resources aren't currently locked for exclusive
use), or 0 otherwise.
|
| • dwOptions | Should always be set to zero |
| • cName | Card name (optional) |
| • cDescription | Card description (optional) |
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate
error code otherwise [A].
cardReg.Card input resources information
should be retrieved from the Plug-and-Play Manager via
WD_PciGetCardInfo() [2.3]
WD_PcmciaGetCardInfo() [2.6] (respectively).
If your card has a large memory range, which cannot be mapped entirely to
the kernel virtual address space, you can set the
WD_ITEM_DO_NOT_MAP_KERNEL flag for the relevant memory
WD_ITEMS structure
(pCardReg->Card.Item[i].dwOptions) in order to instruct the
function to map this memory range only to the user-mode virtual address
space but not the kernel address space.
(For PCI/PCMCIA devices, you can modify the relevant item in the card
information structure (pCard) that you received from
WD_PciGetCardInfo() [2.3]
WD_PcmciaGetCardInfo() [2.6] before passing this structure to
WD_CardRegister()).
NOTE that if you select to set this flag,
WD_CardRegister() will not update the item's
dwTransAddr field with a kernel-mapping of the memory and you
will therefore not be able to call WD_Transfer() [2.11] or WD_MultiTransfer() [2.12] in order to access the memory from the
kernel, nor will you be able to access the memory directly from a Kernel
PlugIn driver using the memory item's dwTransAddr field.
WD_CardRegister() enables the user to map the card memory
resources into virtual memory and access them as regular pointers. In
Windows CE there is a security mechanism that prevents processes
from accessing each other's memory space, without explicitly requesting it.
This request is made using the SetProcPermissions() function,
which sets the desired permissions for the current thread. Since the card
resources are mapped inside WinDriver and these mappings belong to the Device
Manager process, any other thread should call this function before
accessing these mappings. Every call to WD_Open() calls
SetProcPermissions() (see
windrvr.h), so any thread that accesses
mapped regions and does not call WD_Open(), such as a user
thread, Windows message thread etc, should explicitly call
SetProcPermissions() For more information, please refer to
Microsoft's documentation. WinDriver's ThreadStart() function
performs the required call to SetProcPermissions(), therefore
when using ThreadStart() to create new threads you do not need
to call SetProcPermissions() yourself.
WD_CARD_REGISTER cardReg;
BZERO(cardReg);
cardReg.Card.dwItems = 1;
cardReg.Card.Item[0].item = ITEM_IO;
cardReg.Card.Item[0].fNotSharable = TRUE;
cardReg.Card.Item[0].I.IO.dwAddr = 0x378;
cardReg.Card.Item[0].I.IO.dwBytes = 8;
WD_CardRegister(hWD, &cardReg);
if (cardReg.hCard == 0)
{
printf("Failed locking device\n");
return FALSE;
}