Obtención de un objeto adapter

En el inicio del dispositivo, un controlador que usa DMA del sistema o maestro de bus llama a IoGetDmaAdapter para obtener un puntero a un objeto de adaptador y determinar el número máximo de registros de mapa disponibles para cada operación de transferencia. Cuando un controlador llama a IoGetDmaAdapter, el administrador de E/S, a su vez, llama a HAL para obtener la información específica de la plataforma necesaria.

Un controlador debe proporcionar cierta información en una estructura de DEVICE_DESCRIPTION definida por el sistema en su llamada a IoGetDmaAdapter. Los controladores deben usar RtlZeroMemory para inicializar la estructura DEVICE_DESCRIPTION con ceros antes de establecer valores en él.

Los datos necesarios incluyen información sobre las características del dispositivo del controlador, como si el dispositivo es un maestro de bus, si tiene funcionalidades de dispersión y recopilación, y cuántos bytes de datos puede transferir el dispositivo a la vez (MaximumLength).

Los datos de descripción del dispositivo necesarios también incluyen información específica de la plataforma, como el número específico de la plataforma y el número asignado por el sistema del bus que controla un controlador de un dispositivo bus-master. Un controlador puede obtener esta información llamando a IoGetDeviceProperty.

La estructura de DEVICE_DESCRIPTION incluye algunos campos que podrían ser irrelevantes para algunos controladores o dispositivos DMA. Por ejemplo, el campo BusNumber no se usa en controladores WDM. Cada controlador debe proporcionar valores para los miembros de la estructura pertinentes y debe establecer los valores de todos los demás miembros en cero.

El controlador de un dispositivo subordinado no debe pasar TRUE en el campo ScatterGather a menos que el dispositivo pueda esperar a que el controlador DMA del sistema se reprograme cuando una solicitud debe dividirse en dos o más operaciones DMA.

IoGetDmaAdapter devuelve un puntero a un objeto de adaptador y un valor específico de la plataforma o específico del dispositivo que indica cuántos registros de mapa están disponibles con el objeto de adaptador para cada operación de transferencia de DMA.

El objeto de adaptador devuelto contiene tres campos a los que se puede acceder a los controladores:

  • Número de versión (versión)

  • Tamaño (tamaño)

  • Puntero a una estructura de DMA_OPERATIONS (DmaOperations)

La estructura de DMA_OPERATIONS consta de una tabla de punteros a funciones que el controlador debe usar para realizar operaciones DMA en su dispositivo. Las funciones solo son accesibles a través de los punteros de esta estructura de datos; un controlador no puede llamarlos directamente por su nombre. (Tenga en cuenta que estas rutinas reemplazan a las rutinas HalXxx admitidas en versiones anteriores de Windows NT. Para garantizar la compatibilidad con los controladores heredados, los archivos de encabezado Wdm.h y Ntddk.h proporcionan macros con los nombres obsoletos, pero los nuevos controladores siempre deben llamar a las funciones a través de la estructura de datos).

El número de registros de mapa puede variar de dispositivo a dispositivo y de plataforma a plataforma. Por lo general, el HAL asigna una serie de registros de mapa según los criterios siguientes:

  • Si es posible, HAL devuelve un valor que es uno más que el número de registros de mapa necesarios para transferir los bytes MaximumLength , como se especifica en la llamada del controlador a IoGetDmaAdapter.

  • De lo contrario, HAL devuelve un valor menor que es lo más grande posible para la plataforma en particular.

En otras palabras, HAL normalmente proporciona a cada controlador suficientes registros de mapa para maximizar el rendimiento de DMA para su dispositivo, pero hal puede devolver un valor menor en algunas plataformas Windows. No hay ninguna garantía de que un controlador obtenga el número de registros de mapa que solicita, por lo que los controladores siempre deben comprobar el valor devuelto.

Cualquier controlador de dispositivo DMA debe proporcionar almacenamiento para el puntero del objeto de adaptador y el valor NumberOfMapRegisters devuelto por IoGetDmaAdapter. Este puntero es un parámetro necesario para las rutinas de soporte técnico proporcionadas por el sistema que se usan para DMA. Dado que se debe llamar a muchas de estas rutinas de soporte técnico en IRQL = DISPATCH_LEVEL, el almacenamiento asignado por el controlador debe ser residente. La mayoría de los controladores DMA proporcionan el almacenamiento necesario en una extensión de dispositivo. Sin embargo, el almacenamiento puede estar en una extensión de controlador si el controlador también usa un objeto de controlador o en un grupo no paginado asignado por el controlador. Consulte Asignar System-Space memoria y administrar prioridades de hardware para obtener más información.

Cuando el controlador ha completado todas las operaciones DMA, llama a PutDmaAdapter para liberar el objeto de adaptador.

En las secciones siguientes se describe el uso de DMA del sistema y el uso de Bus-Master DMA) cómo los controladores monolíticos de los dispositivos DMA usan rutinas de soporte técnico para satisfacer las solicitudes de transferencia. En estas secciones se supone que el controlador tiene lo siguiente:

  • Una rutina StartIo estándar, en lugar de configurar y administrar una cola interna de IRP

  • Una rutina interna para dividir las solicitudes de transferencia para las que está disponible un número insuficiente de registros de mapa

  • No hay restricciones DMA específicas del dispositivo

En otras palabras, en estas secciones se describe la técnica más sencilla posible para las operaciones DMA de los controladores, pero los controladores individuales no usan necesariamente exactamente las mismas técnicas. Para cualquier controlador de un dispositivo DMA, qué rutinas de controlador deben dividir las solicitudes de transferencia de DMA grandes depende del modelo de controlador (clase/puerto o monolítico), en las características del dispositivo y en las restricciones DMA específicas del dispositivo que el controlador debe controlar.