Partilhar via


Requisitos de rotina do ControllerControl

Como o próprio nome indica, uma rotina ControllerControl está associada a um objeto controlador. Quando a rotina ControllerControl é executada, o hardware representado pelo objeto controller é livre 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:

  1. Atualiza ou inicializa qualquer contexto que o driver mantenha na extensão do objeto 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 DMA. Nessas circunstâncias, a rotina ControllerControl também é responsável por chamar AllocateAdapterChannel se o driver tiver uma rotina AdapterControl .

    Se o driver usa PIO, sua rotina ControllerControl também é responsável por dividir solicitações de transferência, se seu hardware exigir, em intervalos de transferência parcial e por chamar MmGetSystemAddressForMdlSafe com o MDL em Irp-MdlAddress>.

  2. Programa seu hardware para a operação de E/S solicitada

    Se a extensão do dispositivo ou do controlador puder ser acessada a partir do ISR, a rotina ControllerControl deverá usar uma rotina SynchCritSection que é 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á verificar o campo Irp-Cancel> para determinar se o IRP atual deve ser cancelado e seguir um destes procedimentos:

Se Irp-Cancel> estiver definido como TRUE, a rotina ControllerControl deverá fazer o seguinte:

  1. Defina STATUS_CANCELLED para Status e zero para Informações no bloco de status de E/S do IRP.

  2. Chame IoFreeController para liberar o objeto do controlador para que a próxima operação do dispositivo possa ser iniciada imediatamente.

  3. Chame IoStartNextPacket ou retire da fila o próximo IRP se o driver gerir a sua própria fila.

  4. Conclua o IRP cancelado com IoCompleteRequest e devolva o controlo.

Se Irp-Cancel> não estiver definido como TRUE, a rotina ControllerControl deverá fazer o seguinte:

  1. Chame IoSetCancelRoutine para redefinir o ponto de entrada de rotina Cancel para o IRP para NULL. Adquira o "cancel spin lock" para esta chamada se o driver usar a fila de dispositivos fornecida pelo gestor E/S no objeto de dispositivo.

  2. 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 conectados 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 a(s) operação(ões) de E/S para satisfazer a solicitação atual forem concluídas, a rotina que concluirá o IRP deve 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.