[Previous] [Next]
Windows 98 never sends an IRP_MN_SURPRISE_REMOVAL request. Consequently, a WDM driver needs to treat an unexpected IRP_MN_REMOVE_DEVICE as indicating surprise removal. The code samples I showed you in this chapter accomplish that by calling AbortRequests and StopDevice when they get this IRP out of the blue.
Windows 98 fails calls to the IoReportTargetDeviceChange function with STATUS_NOT_IMPLEMENTED. It doesn't export the symbol IoReportTargetDeviceChangeAsynchronous at all; a driver that calls that function will simply fail to load in Windows 98. Refer to Appendix A for information about how you can stub this and other missing support functions so as to be able to ship a single driver binary.
The architecture of Windows 98 doesn't lend itself at all well to blocking in kernel mode while waiting for
[Previous] [Next]
Chapter 7
All the infrastructure I've described so far in this book leads up to this chapter, where I finally cover how to read and write data from a device. I'll discuss the service functions you call to perform these important operations on a device plugged in to one of the traditional buses, such as PCI (Peripheral Component Interconnect). Since many devices use a hardware interrupt to notify system software about I/O completion or exceptional events, I'll also discuss how to handle an interrupt. Interrupt processing normally requires you to schedule a deferred procedure call (DPC), so I'll describe the DPC mechanism, too. Finally, I'll tell you how to arrange direct memory access (DMA) transfers between your device and main memory.
[Previous] [Next]
In the previous chapter, I discussed the various IRP_MJ_PNP
NTSTATUSStartDevice(PDEVICE_OBJECTfdo,
PCM_PARTIAL_RESOURCE_LISTraw,
PCM_PARTIAL_RESOURCE_LISTtranslated)
{
...
}
|
The time has now come to explain what to do with these resource lists. In summary, you'll extract descriptions of your assigned resources from the translated list and use those descriptions to create additional kernel objects that give you access to your hardware.
The CM_PARTIAL_RESOURCE_LIST structures contain a count and an array of CM_PARTIAL_RESOURCE_DESCRIPTOR structures, as
Figure 7-1. Structure of a partial resource list.
In sketch, then, your StartDevice function looks like this:
1 |
NTSTATUSStartDevice(PDEVICE_OBJECTfdo,
PCM_PARTIAL_RESOURCE_LISTraw,
PCM_PARTIAL_RESOURCE_LISTtranslated)
{
PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;
PCM_PARTIAL_RESOURCE_DESCRIPTORresource=
translated->PartialDescriptors;
ULONGnres=translated->Count;
<localvariabledeclarations>
for(ULONGi=0;i<nres;++i,++resource)
{
switch(resource->Type)
{
caseCmResourceTypePort:
<saveportinfoinlocalvariables>
break;
caseCmResourceTypeInterrupt:
<saveinterruptinfoinlocalvariables>
break;
caseCmResourceTypeMemory:
<savememoryinfoinlocalvariables>
break;
caseCmResourceTypeDma:
<saveDMAinfoinlocalvariables>
break;
}
}
<uselocalvariablestoconfiguredriver&hardware>
IoSetDeviceInterfaceState(&pdx->ifname,TRUE);
}
|
If you have more than one resource of a particular type, you need to invent a way to tell the resource descriptors apart. To give a concrete (but entirely fictitious) example, suppose that your device uses one 4-KB range of memory for control purposes and a different 16-KB range of memory as a data capture buffer. You expect to receive two CmResourceTypeMemory resources from the PnP Manager. The control memory is the block that's 4 KB long, whereas the data memory is the block that's 16 KB long. If your device's resources have a distinguishing characteristic such as the
When dealing with multiple resources of the same type, don't assume that the resource descriptors will be in the same order that your configuration space lists them in, and don't assume that the same bus driver will always construct resource descriptors in the same order on every platform or every release of the operating system. The first assumption is tantamount to assuming that the bus driver programmer adopted a particular algorithm, while the second is tantamount to
I'll explain how to deal with each of the four standard I/O resource types at appropriate places in the remainder of this chapter. Table 7-1
Table 7-1. Overview of processing steps for I/O resources.
| Resource Type | Overview |
|---|---|
| Port | Possibly maps port range; saves base port address in device extension |
| Memory | Maps memory range; saves base address in device extension |
| Dma | Calls IoGetDmaAdapter to create an adapter object |
| Interrupt | Calls IoConnectInterrupt to create an interrupt object that points to your interrupt service routine (ISR) |

The Windows 2000 Device Driver Book: A Guide for Programmers (2nd Edition)

Windows System Programming (4th Edition) (Addison-Wesley Microsoft Technology Series)

Developing Drivers with the Windows Driver Foundation (Pro Developer)

Windowsu00ae Internals: Including Windows Server 2008 and Windows Vista, Fifth Edition (Pro Developer)