Книга: Writing Windows WDM Device Drivers

Hardware Access

Hardware Access

Before I start in earnest, note that the WdmIo driver is a standard WDM driver in a device stack. It is layered over the Unknown bus driver. It does not use the Unknown driver to access hardware. Instead, it talks to hardware directly.

The StartDevice, RetrieveResources, and StopDevice routines in DeviceIo.cpp have been altered slightly from their originals in Wdm2. They insist that one port or memory resource be allocated. If necessary a memory-mapped set of registers is mapped into memory, and unmapped when the device is stopped. Similarly, if WdmIo has connected to an interrupt, StopDevice disconnects and StartDevice connects again.

The WriteByte and ReadByte routines are shown in Listing 16.1. They both fail silently if the register offset is out of range. The DebugPrint trace calls should not be used in these routines, as they may be called at device IRQL (DIRQL) (i.e., above the maximum IRQL suitable for DebugPrint calls, DISPATCH_LEVEL).

If you need to delay for a short period, use the KeStallExecutionProcessor routine, specifying the stall period in microseconds. The DDK recommends that you keep the delay as short as possible, and definitely no more than 50µs. Longer delays usually mean writing code in a very different way. For example, you could use custom timers, as described in the next chapter. Alternatively, a system thread could use the KeDelayExecutionThread function for longer delays.

Listing 16.1 WriteByte and ReadByte

void WriteByte(IN PWDMIO_DEVICE_EXTENSION dx, IN ULONG offset, IN UCHAR byte) {
 if (offset>=dx->PortLength) return;
 PUCHAR Port = dx->PortBase+offset;
 if (dx->PortInIOSpace) WRITE_PORT_UCHAR(Port, byte);
 else WRITE_REGISTER_UCHAR(Port, byte);
}
UCHAR ReadByte(IN PWDMIO_DEVICE_EXTENSION dx, IN ULONG offset) {
 if (offset>=dx->PortLength) return 0;
 PUCHAR Port = dx->PortBase+offset;
 UCHAR b;
 if (dx->PortInIOSpace) b = READ_PORT_UCHAR(Port);
 else b = READ_REGISTER_UCHAR(Port);
 return b;
}

Finally, note that the WdmIo driver read and write dispatch routines and the IOCTLs all use Buffered I/O.

Оглавление книги


Генерация: 0.593. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз