Partilhar via


Como enviar estruturas de MDL encadeadas

Este artigo descreve a funcionalidade de MDLs encadeadas na pilha do driver USB e como um driver cliente pode enviar um buffer de transferência como uma cadeia de estruturas de MDL .

A maioria dos controladores de host USB exige que o buffer de transferência seja virtualmente contíguo. Virtualmente contíguo significa que o buffer pode iniciar e terminar em qualquer lugar em uma página, mas o restante do buffer deve iniciar e terminar em um limite de página. Muitos drivers de cliente USB são capazes de atender a esse requisito. No entanto, para determinados drivers de cliente, particularmente aqueles que precisam adicionar ou remover dados adicionais de ou para o buffer, alocar memória virtualmente contígua para o buffer de transferência não é preferível.

Por exemplo, considere uma pilha de rede de três drivers, um driver de protocolo de rede, um driver intermediário e um driver de miniporte. O driver de protocolo inicia uma transferência e envia um pacote para o próximo driver na pilha: o driver intermediário. O driver intermediário deseja adicionar um cabeçalho personalizado (contido em um bloco de memória separado) ao pacote. O driver intermediário envia esse cabeçalho e o pacote recebido para o próximo driver na pilha: o driver de miniporto. As interfaces do driver de miniporto com a pilha do driver USB e, portanto, devem preparar um buffer de transferência virtualmente contíguo. Para criar esse buffer, o driver de miniporto aloca um buffer grande, adiciona o cabeçalho personalizado e copia o conteúdo. Como a carga normalmente é grande, copiar toda a carga pode ter um impacto significativo no desempenho.

O driver do cliente pode superar esse impacto no desempenho enviando o buffer de transferência como uma cadeia de MDLs ( lista de descritores de memória ). A nova pilha de driver USB em Windows 8 é capaz de aceitar um MDL encadeado (consulte MDL) do driver cliente. Ao fornecer um MDL encadeado, o driver do cliente pode referenciar páginas discontiguas na memória em vez de executar operações de cópia desnecessárias. A funcionalidade remove restrições no número, tamanho e alinhamento de buffers, permitindo que o buffer de transferência seja segmentado na memória física.

Para usar MDLs encadeados, o driver cliente deve detectar se a pilha de driver USB subjacente, carregada pelo Windows, dá suporte à funcionalidade e, em seguida, criar uma cadeia de MDLs em uma ordem adequada.

Antes de começar

A funcionalidade de MDL encadeada só tem suporte para transferências em massa, isócronas e de interrupção. Antes de consultar a funcionalidade de MDL encadeada, verifique se o driver cliente tem um identificador USBD para o registro do driver com a pilha do driver USB. Para criar um identificador USBD, chame USBD_CreateHandle. Normalmente, o driver cliente cria o identificador USBD em sua rotina AddDevice .

Você pode consultar a funcionalidade de MDL encadeada no manipulador de IRP_MN_START_DEVICE do driver cliente ou a qualquer momento posterior. O driver do cliente não deve consultar essa funcionalidade em sua rotina AddDevice .

Instruções

  1. Chame a rotina de USBD_QueryUsbCapability para determinar se a pilha de driver USB dá suporte à funcionalidade de MDLs encadeadas. Para consultar essa funcionalidade, especifique UsbCapabilityChainedMdls como o GUID. Defina o parâmetro OutputBuffer como NULL e o parâmetro OutputBufferSize como 0.

  2. Verifique o valor NTSTATUS retornado por USBD_QueryUsbCapability e avalie o resultado. Se a rotina for concluída com êxito, a funcionalidade de MDLs encadeada terá suporte. Qualquer outro valor indica que não há suporte para a funcionalidade.

  3. Crie a cadeia de MDLs. Cada MDL tem um ponteiro Next que aponta para outro MDL.

    O driver pode criar um MDL de cadeia definindo manualmente o ponteiro Next .

    No exemplo anterior, o driver de protocolo envia o pacote como um MDL. O driver intermediário pode criar outro MDL que referencie o bloco de memória com os dados de cabeçalho. Para criar uma cadeia, o driver intermediário pode apontar o ponteiro Next do cabeçalho MDL para o MDL recebido do driver de protocolo. Em seguida, o driver intermediário pode encaminhar a cadeia de dois MDLs para o driver de miniporto, que fornece uma referência ao MDL encadeado na URB para a solicitação e envia a solicitação para a pilha de driver USB. Para obter mais informações, consulte Usando MDLs.

  4. Ao criar um URB para uma solicitação de E/S que usa MDLs encadeados, defina o membro TransferBufferMDL da estrutura URB associada (como _URB_BULK_OR_INTERRUPT_TRANSFER ou _URB_ISOCH_TRANSFER) como o primeiro MDL na cadeia e defina TransferBufferLength como o número total de bytes a serem transferidos. Os dados podem abranger mais de uma entrada MDL na cadeia de MDL.

    Em Windows 8, foram adicionados dois novos tipos de funções URB que permitem que um driver cliente use MDLs encadeados para transferências de dados. Se você quiser usar essa funcionalidade, certifique-se de que definir o membro function do cabeçalho URB está definido como uma das seguintes funções URB:

    • URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER_USING_CHAINED_MDL
    • URB_FUNCTION_ISOCH_TRANSFER_USING_CHAINED_MDL

    Para obter informações sobre essas funções URB, consulte _URB_HEADER.

Comentários

Para obter um exemplo de código que consulta a pilha de driver USB subjacente para determinar se a pilha de driver pode aceitar MDLs encadeadas, consulte USBD_QueryUsbCapability.