Compartir a través de


Cómo enviar estructuras MDL encadenadas

En este artículo se describe la funcionalidad mdL encadenada en la pila de controladores USB y cómo un controlador cliente puede enviar un búfer de transferencia como una cadena de estructuras MDL .

La mayoría de los controladores de host USB requieren que el búfer de transferencia sea prácticamente contiguo. Prácticamente contiguo significa que el búfer puede iniciarse y finalizar en cualquier parte de una página, pero el resto del búfer debe iniciarse y finalizar en un límite de página. Muchos controladores de cliente USB pueden cumplir ese requisito. Sin embargo, para determinados controladores de cliente, especialmente aquellos que necesitan agregar o quitar datos adicionales al búfer o desde el búfer, la asignación de memoria virtualmente contigua para el búfer de transferencia no es preferible.

Por ejemplo, considere una pila de redes de tres controladores, un controlador de protocolo de red, un controlador intermedio y un controlador de minipuerto. El controlador de protocolo inicia una transferencia y envía un paquete al siguiente controlador de la pila: el controlador intermedio. El controlador intermedio quiere agregar un encabezado personalizado (contenido en un bloque de memoria independiente) al paquete. El controlador intermedio envía ese encabezado y el paquete recibido al siguiente controlador de la pila: el controlador de minipuerto. Las interfaces del controlador miniporte con la pila del controlador USB y, por tanto, deben preparar un búfer de transferencia virtualmente contiguo. Para crear este búfer, el controlador de minipuerto asigna un búfer grande, agrega el encabezado personalizado y, a continuación, copia la carga. Dado que la carga suele ser grande, copiar toda la carga puede tener un impacto significativo en el rendimiento.

El controlador cliente puede superar ese impacto en el rendimiento mediante el envío del búfer de transferencia como una cadena de lista de descriptores de memoria (MDL). La nueva pila de controladores USB en Windows 8, es capaz de aceptar una MDL encadenada (consulte MDL) del controlador cliente. Al proporcionar una MDL encadenada, el controlador de cliente puede hacer referencia a páginas desconcertantes en la memoria en lugar de realizar operaciones de copia extrañas. La funcionalidad quita las restricciones en el número, el tamaño y la alineación de los búferes, lo que permite segmentar el búfer de transferencia en memoria física.

Para usar MDL encadenadas, el controlador cliente debe detectar si la pila de controladores USB subyacente, cargada por Windows, admite la funcionalidad y, a continuación, crea una cadena de MDL en un orden adecuado.

Antes de empezar

La funcionalidad MDL encadenada solo se admite para transferencias masivas, isócrónicas e interrupciones. Antes de consultar la funcionalidad MDL encadenada, asegúrese de que el controlador cliente tiene un identificador USBD para el registro del controlador con la pila de controladores USB. Para crear un identificador USBD, llame a USBD_CreateHandle. Normalmente, el controlador cliente crea el controlador USBD en su rutina AddDevice .

Puede consultar la funcionalidad MDL encadenada en el controlador de IRP_MN_START_DEVICE del controlador de cliente o en cualquier momento posterior. El controlador cliente no debe consultar esta funcionalidad en su rutina AddDevice .

Instrucciones

  1. Llame a la rutina USBD_QueryUsbCapability para determinar si la pila del controlador USB admite la funcionalidad mdL encadenada. Para consultar esa funcionalidad, especifique UsbCapabilityChainedMdls como GUID. Establezca el parámetro OutputBuffer en NULL y OutputBufferSize en 0.

  2. Compruebe el valor NTSTATUS devuelto por USBD_QueryUsbCapability y evalúe el resultado. Si la rutina se completa correctamente, se admite la funcionalidad MDL encadenada. Cualquier otro valor indica que no se admite la funcionalidad.

  3. Cree la cadena de MDL. Cada MDL tiene un puntero Next que apunta a otro MDL.

    El controlador puede crear una cadena MDL estableciendo manualmente el puntero Siguiente .

    En el ejemplo anterior, el controlador de protocolo envía el paquete como MDL. El controlador intermedio puede crear otra MDL que haga referencia al bloque de memoria con los datos de encabezado. Para crear una cadena, el controlador intermedio puede apuntar el puntero Next del encabezado MDL al MDL recibido del controlador de protocolo. A continuación, el controlador intermedio puede reenviar la cadena de dos MDL al controlador de minipuerto, que proporciona una referencia a la MDL encadenada en la URB para la solicitud y envía la solicitud a la pila del controlador USB. Para obtener más información, consulte Uso de MDL.

  4. Al compilar un URB para una solicitud de E/S que usa MDL encadenadas, establezca el miembro TransferBufferMDL de la estructura URB asociada (por ejemplo, _URB_BULK_OR_INTERRUPT_TRANSFER o _URB_ISOCH_TRANSFER) en la primera MDL de la cadena y establezca TransferBufferLength en el número total de bytes que se van a transferir. Los datos pueden abarcar más de una entrada MDL en la cadena MDL.

    En Windows 8, se han agregado dos nuevos tipos de funciones URB que permiten a un controlador cliente usar MDL encadenados para las transferencias de datos. Si desea usar esta funcionalidad, asegúrese de establecer el miembro Function del encabezado URB establecido en una de las siguientes funciones URB:

    • URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER_USING_CHAINED_MDL
    • URB_FUNCTION_ISOCH_TRANSFER_USING_CHAINED_MDL

    Para obtener información sobre esas funciones URB, consulte _URB_HEADER.

Comentarios

Para obtener un ejemplo de código que consulta la pila de controladores USB subyacente para determinar si la pila de controladores puede aceptar MDL encadenadas, consulte USBD_QueryUsbCapability.