Usos de exemplo de filas de E/S

Para cada dispositivo conectado a um sistema e com suporte por um driver específico, o driver pode usar as seguintes combinações de filas de E/S e manipuladores de solicitação:

  • Uma única fila de E/S padrão e um único manipulador de solicitação, EvtIoDefault. A estrutura fornecerá todas as solicitações do dispositivo para a fila padrão e chamará o manipulador EvtIoDefault do driver para entregar cada solicitação ao driver.

  • Uma fila de E/S padrão e vários manipuladores de solicitação, como EvtIoRead, EvtIoWrite e EvtIoDeviceControl. A estrutura fornecerá todas as solicitações do dispositivo para a fila padrão. Ele chamará o manipulador EvtIoRead do driver para fornecer solicitações de leitura, o manipulador EvtIoWrite para fornecer solicitações de gravação e o manipulador EvtIoDeviceControl para fornecer solicitações de controle de E/S do dispositivo.

  • Várias filas de E/S, como uma para solicitações de leitura e outra para solicitações de gravação. Para cada fila, o driver fornece apenas um manipulador de solicitação porque a fila recebe apenas um tipo de solicitação.

  • Várias filas de E/S, cada uma com vários manipuladores de solicitação.

Alguns cenários de exemplo incluem:

Uma fila de E/S sequencial única

Se você estiver escrevendo um driver de função para uma unidade de disco que só pode atender a solicitações de leitura e gravação uma de cada vez, o driver de função precisará apenas de uma fila de E/S por dispositivo.

O driver pode usar a fila de E/S padrão que a estrutura cria quando o driver chama WdfIoQueueCreate e define DefaultQueue como TRUE na estrutura WDF_IO_QUEUE_CONFIG da fila. Na estrutura WDF_IO_QUEUE_CONFIG, o driver também deve especificar:

  • WdfIoQueueDispatchSequential como o método de expedição, portanto, a fila de E/S padrão fornecerá solicitações de E/S ao driver de forma síncrona.

  • Uma única função de retorno de chamada de evento, EvtIoDefault, que receberá todas as solicitações de E/S.

Sempre que uma solicitação de E/S estiver disponível na fila de E/S padrão do driver, a estrutura fornecerá a solicitação ao driver chamando o manipulador de solicitação EvtIoDefault do driver. Se outra solicitação ficar disponível na fila, a estrutura não a entregará até que o driver chame WdfRequestComplete para a solicitação entregue anteriormente.

Várias filas de E/S sequenciais e uma fila manual

Considere um dispositivo de porta serial que tenha as seguintes características:

  • Ele pode executar simultaneamente uma operação de leitura e uma operação de gravação.

  • Ele não pode executar várias operações de leitura ou gravação de forma assíncrona.

  • Ele pode receber solicitações de controle de E/S do dispositivo para status informações. O driver do dispositivo pode levar muito tempo para concluir algumas dessas solicitações (como uma solicitação para aguardar uma alteração status).

Um driver de função para esse dispositivo pode usar várias filas de E/S sequenciais por dispositivo. O driver chamaria WdfIoQueueCreate três vezes: uma para criar uma fila padrão e duas vezes para criar duas filas de E/S adicionais. Na estrutura WDF_IO_QUEUE_CONFIG para cada uma dessas filas, o driver deve especificar:

  • WdfIoQueueDispatchSequential como o método de expedição para cada fila, para que a estrutura forneça solicitações de E/S ao driver de forma síncrona.

  • Um manipulador de solicitação diferente para cada fila (EvtIoDefault, EvtIoRead e EvtIoWrite), que receberá as solicitações de E/S da fila.

Depois de chamar WdfIoQueueCreate, o driver pode chamar WdfDeviceConfigureRequestDispatching duas vezes – para encaminhar todas as solicitações de leitura para uma das filas adicionais e todas as solicitações de gravação para a outra.

Com essa configuração, a função de retorno de chamada EvtIoDefault da fila de E/S padrão do dispositivo receberá apenas as solicitações de controle de E/S do dispositivo para status informações.

Se o driver precisar manter uma solicitação de status por um longo tempo, ele poderá criar uma quarta fila e especificar WdfIoQueueDispatchManual como o método de expedição. Quando o driver recebe uma solicitação de informações que deve aguardar, ele pode colocar a solicitação nessa fila extra até que as informações de status fiquem disponíveis. Em seguida, o driver pode recuperar a solicitação da fila e concluí-la. Enquanto isso, a fila padrão pode entregar outra solicitação ao driver.

Uma única fila de E/S paralela

Os controladores de disco IDE podem sobrepor algumas operações de E/S, mas não outras. Por exemplo, enquanto um controlador está processando uma operação de leitura ou gravação em um disco, ele pode enviar um comando seek para outro disco. Por outro lado, não há suporte para vários comandos simultâneos de leitura e gravação.

Um driver de função para esse controlador deve examinar cada solicitação de E/S. Se o driver receber um comando seek, ele deverá determinar se o comando seek pode ser processado. O comando seek não poderá ser processado se:

  • A unidade de disco especificada já está ocupada.

  • Uma unidade de disco está sendo formatada e, portanto, nenhuma outra unidade pode estar ativa.

Para cada dispositivo conectado ao controlador, o driver pode chamar WdfIoQueueCreate para criar uma fila de E/S padrão. Na estrutura WDF_IO_QUEUE_CONFIG para cada uma dessas filas, o driver deve especificar:

  • WdfIoQueueDispatchParallel como o método de expedição para cada fila, para que a estrutura forneça solicitações de E/S ao driver de forma assíncrona.

  • Uma função de retorno de chamada de evento EvtIoDefault para cada fila, que receberá as solicitações de E/S da fila.

Com essa configuração, uma única fila de E/S paralela é atribuída a cada dispositivo. O driver deve examinar cada solicitação de E/S que a estrutura entrega de cada fila de E/S. Se o driver puder processar a solicitação imediatamente, ele o fará. Caso contrário, o driver chama WdfIoQueueStop, o que faz com que a estrutura pare de fornecer solicitações até que o driver chame WdfIoQueueStart.

Várias filas de E/S paralelas

Um adaptador de host SCSI é um exemplo de um dispositivo que dá suporte a operações de E/S assíncronas e sobrepostas. Até 32 dispositivos podem ser conectados ao adaptador. Considere um sistema com a seguinte configuração:

  • Alguns dos dispositivos conectados ao adaptador SCSI dão suporte à "reseleção" e outros não. Se um dispositivo SCSI der suporte à reseleção, durante uma operação de E/S, o dispositivo poderá liberar temporariamente o adaptador para que o adaptador possa atender a outro dispositivo. O primeiro dispositivo posteriormente se reeleita para concluir sua operação.

  • O adaptador SCSI usa caixas de correio de hardware para passar solicitações e respostas entre o driver e os dispositivos. Se um dispositivo estiver pronto para uma solicitação, mas não houver caixas de correio disponíveis, o dispositivo deverá aguardar.

Para obter o melhor desempenho, o driver de função para esse adaptador de host SCSI deve receber solicitações de E/S da estrutura assim que estiverem disponíveis. O driver deve examinar cada solicitação e determinar se ela pode ser iniciada imediatamente ou deve ser adiada até que o dispositivo e os recursos (como a memória da caixa de correio) estejam disponíveis.

O driver provavelmente deve usar várias filas de E/S paralelas. Para cada dispositivo conectado ao adaptador, o driver chamaria WdfIoQueueCreate para criar uma fila de E/S padrão. Na estrutura WDF_IO_QUEUE_CONFIG para cada uma dessas filas, o driver deve especificar:

  • WdfIoQueueDispatchParallel como o método de expedição para cada fila, para que a estrutura forneça solicitações de E/S ao driver de forma assíncrona.

  • Uma função de retorno de chamada de evento EvtIoDefault para cada fila, que receberá as solicitações de E/S da fila.

A função de retorno de chamada EvtIoDefault de cada fila de E/S deve examinar as solicitações de E/S da fila, pois elas são entregues e determinar se cada uma pode ser atendida imediatamente. Se os recursos do dispositivo e do sistema estiverem disponíveis, o driver iniciará a operação de E/S. Se o dispositivo ou os recursos não estiverem disponíveis, o driver deverá chamar WdfIoQueueStop para interromper a entrega de solicitações adicionais até que a atual possa ser processada.

Opcionalmente, o driver pode chamar WdfIoQueueCreate para criar filas adicionais para cada dispositivo. Em seguida, o driver pode chamar WdfRequestForwardToIoQueue para redirecionar alguns tipos de solicitações para as filas adicionais. Quando a estrutura fornece solicitações de uma fila adicional, o driver pode chamar WdfIoQueueStop, se necessário, nessa fila em vez da fila padrão, minimizando assim o número ou o tipo de solicitações para as quais a entrega é adiada.