Requisitos de rotina controllercontrol
Como o nome indica, uma rotina ControllerControl é associada a um objeto do controlador. Quando a rotina ControllerControl é executada, o hardware representado pelo objeto do controlador é gratuito e a extensão do controlador geralmente não está sendo acessada por outra rotina de driver, a menos que a extensão do controlador contenha contexto compartilhado com o ISR do driver.
Normalmente, uma rotina ControllerControl faz pelo menos o seguinte:
Atualizações ou inicializa qualquer contexto que o driver mantenha na extensão do dispositivo do objeto de dispositivo de destino e na extensão do controlador
Se o driver usa DMA, sua rotina ControllerControl geralmente é responsável por determinar se uma determinada solicitação de transferência deve ser dividida em transferências parciais devido a quaisquer limitações impostas pelo sistema ou pelo dispositivo no tamanho de cada transferência de DMA. Nessas circunstâncias, a rotina ControllerControl também será responsável por chamar AllocateAdapterChannel se o driver tiver uma rotina AdapterControl .
Se o driver usar PIO, sua rotina ControllerControl também será responsável por dividir as solicitações de transferência, se o hardware exigir isso, em intervalos de transferência parcial e por chamar MmGetSystemAddressForMdlSafe com o MDL em Irp-MdlAddress>.
Programa seu hardware para a operação de E/S solicitada
Se a extensão de dispositivo ou controlador puder ser acessada do ISR, a rotina ControllerControl deverá usar uma rotina SynchCritSection invocada chamando KeSynchronizeExecution. Para obter mais informações, consulte Usando seções críticas.
Se o driver tiver uma rotina Cancelar, sua rotina ControllerControl também deverá marcar o campo Irp-Cancel> para determinar se o IRP atual deve ser cancelado e fazer um dos seguintes procedimentos:
Se Irp-Cancel> estiver definido como TRUE, a rotina ControllerControl deverá fazer o seguinte:
Defina STATUS_CANCELLED para Status e zero para Informações no bloco status de E/S do IRP.
Chame IoFreeController para liberar o objeto do controlador para que a próxima operação do dispositivo possa ser iniciada imediatamente.
Chame IoStartNextPacket ou remova o próximo IRP se o driver gerenciar seu próprio enfileiramento.
Conclua o IRP cancelado com IoCompleteRequest e controle de retorno.
Se Irp-Cancel> não estiver definido como TRUE, a rotina ControllerControl deverá fazer o seguinte:
Chame IoSetCancelRoutine para redefinir o ponto de entrada de rotina Cancelar para IRP como NULL. Adquira o bloqueio de rotação de cancelamento para essa chamada se o driver usar a fila de dispositivos fornecida pelo gerenciador de E/S no objeto do dispositivo.
Programe o hardware para a operação de E/S solicitada usando uma rotina SynchCritSection que é invocada chamando KeSynchronizeExecution. Para obter mais informações, consulte Usando seções críticas
Para obter mais informações sobre como lidar com IRPs canceláveis, consulte Cancelando IRPs.
Para a maioria das operações de E/S controladas por interrupção, exceto operações sobrepostas em diferentes dispositivos anexados ao controlador/adaptador físico, uma rotina ControllerControl deve retornar KeepObject porque a rotina DpcForIsr ou CustomDpc conclui a operação e o IRP.
Assim que as operações de E/S para atender à solicitação atual forem feitas, a rotina que concluirá o IRP deverá chamar IoFreeController e IoStartNextPacket para que a próxima solicitação possa ser processada o mais rápido possível.
Se a própria rotina ControllerControl concluir um IRP ou se puder configurar uma operação, como uma busca de disco, para um objeto de dispositivo de destino (disco) que possa ser sobreposto a uma operação para outro objeto de dispositivo, a rotina ControllerControl deverá retornar DeallocateObject.