I have run into a problem accessing 32MB of memory on a PCI card. WD_CardRegister() fails to map the memory.
The problem does not occur if I try to access 16MB of memory on my card.
WD_CardRegister() attempts to map physical memory address ranges to both virtual user-mode and kernel-mode address space, by calling the relevant OS functions. If either of these mappings fail, e.g., because there is not enough user/kernel virtual memory to enable the mapping of the entire memory range, WD_CardRegister() will fail and a relevant error message will be printed to the Debug Monitor log, indicating which OS-mapping function failed (see example in Technical Document #73). You may also encounter the same problem when using the WDC_PciDeviceOpen()/WDC_PcmciaDeviceOpen()/WDC_IsaDeviceOpen() convenience wrappers (v7.0.0+), which call WD_CardRegister(). Solutions: To resolve this problem, you have the following options:
Code Examples: The following code examples demonstrate how to set the WD_ITEM_DO_NOT_MAP_KERNEL flag, or lock less memory, using the different WinDriver APIs. NOTE: For the purpose of this example we assume that the information for the relevant memory item is stored in the second item of the card's items array (i.e., index 1). However, this will not necessarily be the case. For PCI/PCMCIA you should write your code to iterate through the items array, returned by WDC_xxxGetDeviceInfo()/ WD_xxxGetCardInfo(), in order to find the index of the memory item that you wish to modify (card.Item[i].item should be of type ITEM_MEMORY and cardItem.Item[i].dwPhysicalAddr should match the physical address of your target memory range). =========================================================== Example 1: WDC PCI/PCMCIA API NOTE: For PCMCIA, just replace any 'PCI'/'Pci' references below with 'PCMCIA'/'Pcmcia'. WD_PCI_CARD_INFO cardInfo; ... WDC_PciGetDeviceInfo(&cardInfo); cardInfo.Card.Item[1].dwOptions |= WD_ITEM_DO_NOT_MAP_KERNEL; /* Alternatively, modify cardInfo.Item[1].I.Mem.dwBytes, and perhaps also cardInfo.Item[1].I.Mem.dwPhysicalAddr, in order to map only a selected portion of the memory. For example, to lock 1,000 bytes, beginning with offset 0x10 of the address space, set: cardInfo.Item[1].I.Mem.dwBytes = 1000; cardInfo.Item[1].I.Mem.dwPhysicalAddr += 0x10; */ ... WDC_PciDeviceOpen(&hDev, &cardInfo, ...); =========================================================== Example 2: WDC ISA API WD_CARD card; ... card.Item[1].dwOptions |= WD_ITEM_DO_NOT_MAP_KERNEL; /* Alternatively, modify card.Item[1].I.Mem.dwBytes, and perhaps also card.Item[1].I.Mem.dwPhysicalAddr, in order to map only a selected portion of the memory. For example, to lock 1,000 bytes, beginning with offset 0x10 of the address space, set: card.Item[1].I.Mem.dwBytes = 1000; card.Item[1].I.Mem.dwPhysicalAddr += 0x10; */ ... WDC_IsaDeviceOpen(&hDev, &card, ...); =========================================================== Example 3: WD_xxx PCI/PCMCIA API NOTE: For PCMCIA, just replace any 'PCI'/'Pci' references below with 'PCMCIA'/'Pcmcia'. WD_PCI_CARD_INFO cardInfo; WD_CARD_REGISTER cardReg; ... WD_PciGetCardInfo(hWD, &cardInfo); cardInfo.Card.Item[1].dwOptions |= WD_ITEM_DO_NOT_MAP_KERNEL; /* Alternatively, modify cardInfo.Item[1].I.Mem.dwBytes, and perhaps also cardInfo.Item[1].I.Mem.dwPhysicalAddr, in order to map only a selected portion of the memory. For example, to lock 1,000 bytes, beginning with offset 0x10 of the address space, set: cardInfo.Item[1].I.Mem.dwBytes = 1000; cardInfo.Item[1].I.Mem.dwPhysicalAddr += 0x10; */ cardReg.Card = cardInfo.Card; ... WD_CardRegister(hWD, &cardReg); =========================================================== Example 4: WD_xxx ISA API WD_CARD_REGISTER cardReg; ... cardReg.Card.Item[1].dwOptions |= WD_ITEM_DO_NOT_MAP_KERNEL; /* Alternatively, modify cardReg.Item[1].I.Mem.dwBytes, and perhaps also cardReg.Item[1].I.Mem.dwPhysicalAddr, in order to map only a selected portion of the memory. For example, to lock 1,000 bytes, beginning with offset 0x10 of the address space, set: cardReg.Item[1].I.Mem.dwBytes = 1000; cardReg.Item[1].I.Mem.dwPhysicalAddr += 0x10; */ ... WD_CardRegister(hWD, &cardReg); Back to WD_ITEM_DO_NOT_MAP_KERENL explanation ; Back to map less memory explanation |
Technical Documents
(WinDriver related)
WinDriver: Support Center
WinDriver: Product Page
Can't find what you need?
(WinDriver related)
Documents Navigator:
WinDriver: Support Center
WinDriver: Product Page
Can't find what you need?