Solicitudes digitales seguras que utilizan E/S directa
En el ejemplo de código siguiente se muestra cómo un controlador usa una solicitud de comando para recuperar el contenido del registro básico (FBR) de la función de un dispositivo. Dado que la cantidad de datos recuperados es pequeña, en el ejemplo se usa un comando de E/S directo (denominado CMD52 en la especificación SD), que indica al controlador de bus que transmita los datos a través de la línea CMD. Para ver un ejemplo de código que muestra cómo usar E/S extendida (denominada CMD53 en la especificación SD), consulte Secure Digital Requests That Use Extended I/O.
const SDCMD_DESCRIPTOR ReadIoDirectDesc =
{SDCMD_IO_RW_DIRECT, SDCC_STANDARD, SDTD_READ,
SDTT_CMD_ONLY, SDRT_5};
PSDBUS_REQUEST_PACKET sdrp = NULL;
SD_RW_DIRECT_ARGUMENT sdIoArgument;
sdrp = ExAllocatePool(NonPagedPool,
sizeof(SDBUS_REQUEST_PACKET));
if (!sdrp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(sdrp, sizeof(SDBUS_REQUEST_PACKET));
sdrp->RequestFunction = SDRF_DEVICE_COMMAND;
sdrp->Parameters.DeviceCommand.CmdDesc = ReadIoDirectDesc;
// Set up the argument and command descriptor
sdIoArgument.u.AsULONG = 0;
sdIoArgument.u.bits.Address = Offset;
// Function # must be initialized by SdBus GetProperty call
sdIoArgument.u.bits.Function = pDevExt->FunctionNumber;
sdrp->Parameters.DeviceCommand.Argument = sdIoArgument.u.AsULONG;
// Submit the request
status = SdBusSubmitRequest(pDevExt->BusInterface.Context, sdrp);
if (NT_SUCCESS(status)) {
// for direct I/O, the data comes in the response
*Data = sdrp->ResponseData.AsUCHAR[0];
}
ExFreePool(sdrp);
Para leer el FBR, el ejemplo de código realiza los pasos siguientes:
Inicializar el descriptor
El primer paso para enviar una solicitud device-command es definir un descriptor de comandos SD, SDCMD_DESCRIPTOR. Normalmente, un descriptor se define como una estructura de datos constante. El descriptor del ejemplo de código define una operación de lectura con los siguientes elementos:
Elemento Descripción La operación definida por el descriptor lee un solo byte de datos del FBR, por lo que el ejemplo de código usa un comando de E/S directo (CMD52), que indica a la tarjeta que notifique los datos solicitados a través de la línea CMD y no las líneas DAT. El ejemplo de código indica un comando de E/S directo asignando un valor de SDCMD_IO_RW_DIRECT a este miembro.
Las operaciones de lectura pertenecen al conjunto de comandos estándar (códigos de comando 0 a 63), por lo que el valor asignado a este miembro del descriptor es SDCC_STANDARD.
Las operaciones de lectura requieren una transferencia del dispositivo al host, por lo que el valor asignado a este miembro del descriptor es SDTD_READ.
Esta operación lee una pequeña cantidad de datos de un registro a través de la línea CMD. La tarjeta no tiene que enviar datos a través de las líneas DAT, por lo que a este miembro se le asigna un valor de SDTT_CMD_ONLY.
El descriptor especifica un tipo de respuesta de SDRT_5, lo que significa que la tarjeta debe notificar al host que la operación se ha completado con una solicitud de interrupción. Para obtener una explicación de la respuesta R5, consulte la especificación de la Asociación de Tarjetas MultiMedia.
Inicializar el paquete de solicitud completando los pasos siguientes:
Definir la función de solicitud:
Después de crear un descriptor SD, el ejemplo de código inicializa el paquete de solicitud, SDBUS_REQUEST_PACKET. El RequestFunction miembro del paquete de solicitud especifica si la solicitud contiene un comando de dispositivo (valor de SDRF_DEVICE_COMMAND) o una operación de propiedad (valor de SDRF_GET_PROPERTY o SDRF_SET_PROPERTY). El ejemplo de código inicia un comando de dispositivo, por lo que configura el miembro RequestFunction en SDRF_DEVICE_COMMAND.
Cargar el descriptor de comandos: Siguiente, el ejemplo de código almacena el descriptor recién inicializado como miembro del Parameters.DeviceCommand.CmdDesc del paquete de solicitud.
Inicializar el argumento de lectura y escritura:
El paquete de solicitud contiene una estructura SD_RW_DIRECT_ARGUMENT que contiene la ubicación de los datos que recupera el controlador de bus. Esta estructura también almacena el número de la función cuyo espacio de E/S utiliza el controlador de bus para leer. El código de ejemplo recupera el número de función de la extensión del dispositivo, lo que implica que el controlador recuperó previamente la información de la tarjeta (probablemente cuando inició el dispositivo) con una solicitud de SDRF_GET_PROPERTY y la almacenó en la extensión del dispositivo.
Enviar la solicitud
Después de inicializar el descriptor y el paquete de solicitud, el ejemplo de código usa la rutina de solicitud sincrónica, SdBusSubmitRequest, para enviar la solicitud. La rutina de solicitud pasa el paquete de solicitud y la información de contexto de interfaz que el sistema proporcionó al controlador cuando el sistema abrió la interfaz SD. Dado que se trata de una solicitud sincrónica, el controlador debe ejecutarse en IRQL menor que DISPATCH_LEVEL.
Resultados del comando
Dado que en el ejemplo de código se usa E/S directa, no se requiere ningún búfer de datos distinto del campo ResponseData del paquete de solicitud SD.