Chris Cant - Writing Windows WDM Device Drivers

Здесь есть возможность читать онлайн «Chris Cant - Writing Windows WDM Device Drivers» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Lawrence, Kansas 66046, ISBN: , Издательство: R & D Books, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Writing Windows WDM Device Drivers: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Writing Windows WDM Device Drivers»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Writing Windows WDM Device Drivers — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Writing Windows WDM Device Drivers», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

If the transfer is now complete, this is remembered by setting Timeout to –1. Interrupt routines run at Device IRQL and so cannot complete IRPs. Completing an IRP also takes some time, so this job ought not to be done in the interrupt handler, anyway. The driver model uses Deferred Procedure Calls (DPCs) to solve these problems, as described in the next section. InterruptHandler calls IoRequestDpc to request that the WdmIo DPC be run.

Listing 17.3 WdmIo Interrupt Handler

BOOLEAN InterruptHandler(IN PKINTERRUPT Interrupt, IN PWDMIO_DEVICE_EXTENSION dx) {

// See if interrupt is ours

dx->TxLastIntReg = ReadByte(dx, dx->InterruptReg);

if ((dx->TxLastIntReg&dx->InterruptRegMask) != dx->InterruptRegValue) return FALSE;

// If no transfer in progress then no further processing required

if (dx->Timeout==-1) return TRUE;

// See if current IRP being cancelled

PDEVICE_OBJECT fdo = dx->fdo;

PIRP Irp = fdo->CurrentIrp;

if (Irp==NULL) return TRUE;

BOOLEAN TxComplete = Irp->Cancel;

if (!TxComplete) {

// Run relevant set of commands

if (dx->TxIsWrite) TxComplete = RunWriteCmdsSynch(dx);

else TxComplete = RunReadCmdsSynch(dx);

}

// If all done, in error or being cancelled then call DPC to complete IRP

if (TxComplete) {

dx->Timeout = –1;

IoRequestDpc(fdo, Irp, dx);

}

return TRUE;

}

Deferred Procedure Calls

Code that runs at an elevated IRQL needs to run as quickly as possible. An elevated IRQL is any IRQL above DISPATCH_LEVEL (e.g., at Device IRQL in an interrupt service routine). Code that runs at an elevated IRQL cannot make most useful kernel calls.

The Windows kernel helps solve both these problems with Deferred Procedure Call (DPC) routines, that run at DISPATCH_LEVEL When an interrupt service routine has done all the jobs that must be performed, it should request that its DPC routine be run. This DPC routine should continue where the interrupt service routine left off.

A DPC typically either starts another transfer or completes an IRP.

In WdmIo, all the bytes are transferred in the interrupt handler. When the transfer is complete, WdmIo asks that its DPC be run to complete the IRP.

Other drivers may use their DPC routine to do data transfers. While WdmIo could use this technique, it would be slower. Processing the read or write commands in WdmIo is usually fairly quick, so it is simplest to get it over and done with [43] Actually, the commands could take a long time to run if the Win32 application includes large delay commands. However, moving the command processing to the DPC would not help, as a Critical section routine would have to be run, bringing the IRQL back up the DIRQL. .

Direct Memory Access (DMA) is a hardware facility for transferring many bytes of data from place to place without having to be handled by the processor. The DMA controller or the relevant device usually interrupts when the whole transfer has finished. The interrupt service routine usually runs a DPC routine to start its next transfer or complete the IRP. DMA transfers cannot be started at elevated IRQL, so the next transfer must be set up in a DPC.

An indeterminate amount of time elapses between a DPC being requested and when it is run. Do not defer any interrupt servicing to the DPC if data might be lost (e.g., read data being overwritten). If necessary, store any data in the device extension or some other preallocated nonpaged memory.

Using Basic DPCs

The Windows kernel makes it easy to use one DPC routine within a driver. If you want to use more than one DPC routine, check out the next section.

A standard device object contains the necessary KDPC object. However, you need to initialize it using IoInitializeDpcRequest , passing the name of your DPC routine. WdmIo makes this call in Pnp.cpp just after its FDO is created in its AddDevice routine, passing the name of its DPC routine, WdmIoDpcForIsr .

// Initialize our DPC for IRQ completion processing

IoInitializeDpcRequest(fdo, WdmIoDpcForIsr);

Asking for your DPC to be run is very easy — you just call IoRequestDpc, passing an IRP pointer and a context that you want passed to the DPC routine. As shown previously, WdmIo only asks for its DPC routine to be run when it has transferred all bytes or when an error has occurred. In both cases, the current IRP must be completed and the next queued IRP started.

As shown in Listing 17.4, WdmIoDpcForIsr starts by indicating that the transfer has stopped by setting the device extension Timeout field to –1. It then works out how many bytes have been transferred by subtracting the TxLeft field from TxTotal. If the I/O Manager wants the IRP cancelled, store STATUS_CANCELLED in the TxStatus return status field.

WdmIoDpcForIsr then removes the cancel routine, unlocks the device, completes the IRP, and starts the next queued IRP.

Listing 17.4 WdmIo Interrupt Deferred Procedure Call handler

VOID WdmIoDpcForIsr(IN PKDPC Dpc, IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN PWDMIO_DEVICE_EXTENSION dx) {

dx->Timeout = –1;

ULONG BytesTxd = dx->TxTotal - dx->TxLeft;

if (Irp->Cancel) dx->TxStatus = STATUS_CANCELLED;

DebugPrint("WdmIoDpcForIsr: Status %x Info %d", dx->TxStatus, BytesTxd);

// Remove cancel routine

KIRQL OldIrql;

IoAcqiureCancelSpinLock(&OldIrql);

IoSetCancelRoutine(Irp, NULL);

IoReleaseCancelSpinLock(OldIrql);

// Unlock device and complete

IRP UnlockDevice(dx);

CompleteIrp(Irp, dx->TxStatus, BytesTxd);

IoStartNextPacket(fdo, TRUE);

// Stop timer calls

dx->StopTimer = true;

}

DPC Gotchas

Even with this simple DPC for deferred interrupt processing, there are some potential problems that you have to look out for.

The first point to note is that if two or more calls to IoRequestDpc are made before the DPC can be run, the DPC is only run once. Suppose two interrupts occur in quick succession. If each interrupt handler calls IoRequestDpc , you might expect that the DPC is run twice. However, if there is a long time before the DPC is run, then it is only run once. You must cope with this. In this situation, it might be that one interrupt wants a read call completed, while the next wants a write call completed. Use a separate flag in the device extension to indicate each condition. The DPC routine should be prepared to handle both situations. An easier alternative might be to use a different DPC routine for each condition.

For the WdmIo driver, this problem should almost never arise. The only situation I can envision is one in which an IRP is cancelled just after the interrupt handler calls IoRequestDpc .

However, in this case, the late-running DPC routine will find that the IRP has been cancelled, which is correct.

The other potential problems regarding DPCs will only occur in multiprocessor systems.

• A DPC routine is running on one processor as a device interrupt is handled on another.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Writing Windows WDM Device Drivers»

Представляем Вашему вниманию похожие книги на «Writing Windows WDM Device Drivers» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Writing Windows WDM Device Drivers»

Обсуждение, отзывы о книге «Writing Windows WDM Device Drivers» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x