Написание процедур DPC

Основные обязанности процедур DpcForIsr и CustomDpc — обеспечение оперативного запуска следующей операции ввода-вывода устройства и завершение текущего IRP.

Дополнительные действия, выполняемые любой подпрограммой DpcForIsr или CustomDpc , зависят от дизайна драйвера и характера устройства. Например, подпрограмма DpcForIsr или CustomDpc также может выполнять одно из следующих действий:

  • Повторите операцию, которая истекла или завершилась сбоем.

  • Вызовите IoAllocateErrorLogEntry, настройте пакет журнала ошибок, чтобы сообщить об ошибке ввода-вывода устройства, и вызовите IoWriteErrorLogEntry.

    Дополнительные сведения об обработке ошибок ввода-вывода см. в разделе Ошибки ведения журнала.

  • Если драйвер использует буферизованные операции ввода-вывода или IRP указывает операцию управления устройством, передайте данные, считываемые с устройства, в системный буфер по адресу Irp-AssociatedIrp.SystemBuffer> перед завершением IRP.

  • Если драйвер использует прямой ввод-вывод и должен разбить большие передачи на более мелкие части, сохраните состояние каждой только что завершенной операции частичной передачи, вычислите следующий диапазон частичной передачи и используйте предоставленную драйвером процедуру SynchCritSection , чтобы запрограммировать устройство для следующей операции частичной передачи.

    Даже драйверу, использующим буферизированные операции ввода-вывода, может потребоваться разделить запрос на передачу, если его устройство имеет ограниченные возможности передачи.

  • Если драйвер использует DMA на основе пакетов, вызовите FlushAdapterBuffers после каждой операции передачи устройства и вызовите FreeAdapterChannel или FreeMapRegisters , когда последовательность частичных передач выполнена и запрос полной передачи будет выполнен.

    Если запрошенная передача выполняется только частично одной операцией DMA, подпрограмма DpcForIsr или CustomDpc обычно отвечает за настройку одной или нескольких операций DMA до тех пор, пока указанное число байтов IRP не будет полностью передано.

    Дополнительные сведения об использовании DMA см. в разделе Объекты адаптера и DMA.

  • Если драйвер использует запрограммированный ввод-вывод ( PIO), вызовите KeFlushIoBuffers в конце каждой операции передачи, если текущий IRP запрашивает чтение.

    Если запрошенная передача частично удовлетворяется одной операцией piO, подпрограмма DpcForIsr или CustomDpc обычно отвечает за настройку одной или нескольких операций передачи до тех пор, пока указанное число байтов IRP не будет полностью передано.

    Дополнительные сведения об использовании PIO см. в разделе Использование прямого ввода-вывода.

  • Если драйвер, отличный от WDM, имеет подпрограмму ControllerControl , вызовите IoFreeController по завершении запрошенной операции.

Обратите внимание, что подпрограмма DpcForIsr или CustomDpc обычно выполняет большую часть обработки ввода-вывода устройства драйвера для удовлетворения irp. Эти процедуры также разделяют некоторые обязанности по постановке в очередь IRP на устройство с подпрограммами диспетчеризации водителя.

Рассмотрим следующие общие рекомендации по проектированию.

  • Любая подпрограмма DpcForIsr или CustomDpc должна вызывать IoStartNextPacket , как только сможет безопасно выполнить этот вызов, то есть, не вызывая конфликта ресурсов или состояния гонки с подпрограммой StartIo драйвера или с любой другой процедурой, вызываемой подпрограммой StartIo .

  • Если драйвер управляет собственной очередью IRP, его подпрограмма DpcForIsr или CustomDpc должна уведомить драйвер, как только будет безопасно вывести из очереди следующий IRP и настроить устройство для следующего запроса.

Подпрограмма DpcForIsr или CustomDpc должна вызывать IoStartNextPacket или иным образом уведомлять соответствующую подпрограмму драйвера при запуске обработки ввода-вывода устройства для следующего запроса. В зависимости от драйвера и устройства это может произойти задолго до того, как подпрограмма DpcForIsr или CustomDpc завершит текущую IRP с помощью IoCompleteRequest, или это может произойти непосредственно перед завершением текущей процедуры IRP и возвратом управления.