break;
case CmResourceTypeDma:
case CmResourceTypeDeviceSpecific:
case CmResourceTypeBusNumber:
default:
DebugPrint('RetrieveResources: Unrecognised resource type %d', resource->Type);
GotFrror = true;
break;
}
}
// Check we've got the resources we need
if (GotError /*|| !GotPortOrMemory || !GotInterrupt*/)
return STATUS_DEVICE_CONFIGURATION_ERROR;
return STATUS_SUCCESS;
}
Allocating Resources
The
For memory mapped I/O ports (with the CM_RESOURCE_PORT_MEMORY flag bit set) you must call
dx->PortBase = (PUCHAR)MmMapIoSpace(dx->PortStartAddress, dx->PortLength, MmNonCached);
For ordinary I/O ports and memory, simply use the low 32 bits of the
dx->PortBase = (PUCHAR)dx->PortStartAddress.LowPart;
For interrupts,
Any code that tries to access some real hardware must synchronize its activities with the interrupt handler. It is no good having an interrupt during a complicated device access procedure. Critical section routines solve this problem. You call
Finally,
Port and Memory I/O
There are several standard kernel routines to access I/O ports and memory, as this code snippet shows.
void WriteByte(IN PWDM2_DEVICE_EXTENSION dx, IN ULONG offset, IN UCHAR byte) {
if (dx->PortInIOSpace) WRITE_PORT_UCHAR(dx->PortBase+offset, byte);
else WRITE_REGISTER_UCHAR(dx->PortBase+offset, byte);
}
Read data using the routines with READ in their name and write data with WRITE routines. PORT routines access I/O registers in I/O port space, while REGISTER routines access registers in memory space. Each type has UCHAR, USHORT, and ULONG variants. Finally, BUFFER variants transfer more than one data value. For example, use the following code to read a set of ULONG values from I/O port space into a buffer.
READ_PORT_BUFFER_ULONG( PortBase, Buffer, Count);
As mentioned previously, synchronize all your hardware accesses with any interrupt routines using Critical section routines and
Device Access
Most WDM drivers do not, in fact, need to access I/O ports and memory or handle interrupts. Instead, they access their devices using the facilities provided by class drivers. For example, a USB client driver uses the oft-mentioned USB Request Blocks (URBs) to access its device.
When a USB client driver handles a PnP
For
Testing Wdm2
The
First, install a Wdm2 device using one of the installation INF files in the book software Wdm2sys directory. It does not matter whether you use the free or checked build, although the checked build produces
Check that the Wdm2 driver can be removed or reinstalled when
It is very difficult to test the other new aspects of Plug and Play support in the Wdm2 driver. First,
If the test for open handles is not made, then W2000 in fact will still not allow the device to be removed, as it must contain its own internal reference count for the device. However, W98 would let the device be removed. Any I/O requests on open handles would then simply fail.
The
Adding a Device
The following PnP calls are made when a Wdm2 device is successfully added, or when the driver for a device is reinstalled. Two of the messages are issued only by Windows 2000.
AddDevice
(W2000) IRP_MN_QUERY_LEGACY_BUS_INFORMATION
IRP_MN_FILTER_RESOURCE_REQUIREMENTS
IRP_MN_START_DEVICE
IRP_MN_QUERY_CAPABILITIES
IRP_MN_QUERY_PNP_DEVICE_STATE
IRP_MN_QUERY_DEVICE_RELATIONS BusRelations
IRP_MN_QUERY_DEVICE_RELATIONS BusRelations (W2000)
Removing a Device
The following PnP messages are sent when a Wdm2 device is successfully removed, or when the driver for a device is reinstalled.
IRP_MN_QUERY_DEVICE_RELATIONS RemoveRelations
IRP_MN_QUERY_REMOVE_DEVICE
IRP_MN_REMOVE_DEVICE
Unknown Status Returns
It is interesting to note the IRP status values are returned by the lower Unknown driver when Wdm2 sends IRPs down the stack. Windows is supposed to set the IRP status return value to STATUS_NOT_SUPPORTED before it is issued to the top of the device stack. If Wdm2 sees this value on return from its
For Wdm2, W98 succeeds all the PnP IRPs that it receives.
For Wdm2, W2000 does not process IRP_MN_FILTER_RESOURCE_REQUIREMENTS, IRP_MN_QUERY_PNP_DEVICE_STATE, IRP_MN_QUERY_BUS_INFORMATION, and IRP_MN_QUERY_DEVICE_RELATIONS IRPs.
Other PnP IRPs