Secuencias de transferencia de E/S
La extensión del marco spB (SpbCx) admite secuencias de transferencia de E/S. Una secuencia de transferencia de E/S es un conjunto ordenado de transferencias de bus (operaciones de lectura y escritura) que se realiza como una única operación de bus atómico. Todas las transferencias de una secuencia de transferencia de E/S acceden al mismo dispositivo de destino en el bus. Mientras se realiza una secuencia, no se puede acceder a ningún otro dispositivo del bus, aunque el controlador del controlador SPB pueda recibir solicitudes de E/S para otros dispositivos antes de que se complete la secuencia de transferencia de E/S.
Un ejemplo de una secuencia de transferencia de E/S es una operación de lectura de escritura, que es una operación de escritura de bus seguida de una operación de lectura de bus. Un controlador de dispositivo periférico de cliente puede usar este tipo de secuencia para escribir en un registro de selección de función en un dispositivo periférico conectado a SPB y, a continuación, leer el valor de la función de dispositivo seleccionada. Estas dos transferencias pueden ser de diferentes longitudes. Por ejemplo, la operación de escritura podría transferir un byte de datos y la operación de lectura podría transferir muchos bytes de datos.
Tipos de secuencias de transferencia de E/S
Un cliente puede iniciar una secuencia de transferencia de E/S de una de estas maneras:
El cliente puede especificar toda la secuencia en una solicitud de control de E/S de IOCTL_SPB_EXECUTE_SEQUENCE . Esta solicitud permite al controlador del controlador SPB usar las optimizaciones de rendimiento específicas del hardware disponibles para realizar la secuencia de transferencia. Para obtener más información, vea Secuencias de solicitud única.
El cliente puede enviar una solicitud de control de E/S de IOCTL_SPB_LOCK_CONTROLLER para bloquear el controlador al principio de una secuencia y enviar un IOCTL_SPB_UNLOCK_CONTROLLER cuando se complete la secuencia. Mientras el controlador está bloqueado, el cliente envía una solicitud de E/S independiente (IRP_MJ_READ o IRP_MJ_WRITE) para cada operación de lectura o escritura en la secuencia. Para obtener más información, vea Secuencias implementadas por el cliente.
Siempre que sea posible, un cliente debe usar la solicitud de IOCTL_SPB_EXECUTE_SEQUENCE , que es más rápida, es menos propensa a errores y reduce significativamente el tiempo durante el cual otros clientes están bloqueados fuera del bus. Sin embargo, un cliente puede usar el IOCTL_SPB_LOCK_CONTROLLER y IOCTL_SPB_UNLOCK_CONTROLLER solicitudes si debe examinar el valor que se lee durante una de las transferencias de la secuencia para poder iniciar una transferencia posterior en la secuencia. En este caso, se requiere un diseño cuidadoso para evitar bloquear a otros clientes fuera del bus durante más tiempo de lo necesario, y un controlador periférico mal diseñado puede degradar el rendimiento general del sistema.
secuencias de Single-Request
Para mejorar el rendimiento, el controlador del controlador SPB debe implementar una función de devolución de llamada EvtSpbControllerIoSequence para controlar IOCTL_SPB_EXECUTE_SEQUENCE solicitudes. Este enfoque agrega cierta complejidad al controlador del controlador SPB, pero evita exigir al cliente que realice una secuencia de transferencia de E/S como una serie de operaciones individuales de lectura y escritura, mientras que otros clientes están bloqueados fuera del bus.
Nota
Se recomienda encarecidamente la implementación de una función EvtSpbControllerIoSequence y puede convertirse en un requisito para Windows 8.
La implementación de una secuencia de transferencia es similar a la de una operación simple de lectura o escritura, pero además requiere actualizaciones del estado almacenado de la operación de secuencia entre las transferencias individuales de la secuencia. Una vez completada la primera transferencia, el controlador del controlador SPB actualiza el estado de secuencia para seleccionar la siguiente transferencia de la secuencia. El estado de secuencia se almacena en el contexto del dispositivo e incluye el identificador SPBREQUEST que se pasa a la devolución de llamada EvtSpbControllerIoSequence . El controlador del controlador SPB usa este identificador para obtener los parámetros de búfer, longitud, dirección y posición para las transferencias individuales de la secuencia. Para obtener más información sobre cómo obtener estos parámetros, vea SpbRequestGetTransferParameters.
Si el controlador del controlador SPB no puede realizar la operación de IOCTL_SPB_EXECUTE_SEQUENCE solicitada, completa la solicitud con un código de error. Si se produce un error de este tipo, el cliente puede, como opción, bloquear el bus, realizar explícitamente la secuencia de transferencia de E/S como una serie de solicitudes de E/S simples y, a continuación, desbloquear el bus. Para obtener más información, vea Secuencias implementadas por el cliente.
SpbCx realiza la comprobación de parámetros en las solicitudes IOCTL_SPB_XXX que recibe de los controladores de dispositivos periféricos. Para las solicitudes IOCTL_SPB_EXECUTE_SEQUENCE , SpbCx rechaza secuencias vacías y secuencias que contienen punteros de búfer NULL o búferes de longitud cero.
El controlador del controlador SPB debe comprobar que la longitud de cada transferencia en una secuencia no supera el límite especificado por el controlador. Por ejemplo, el controlador de ejemplo SkeletonI2C del Kit de controladores de Windows (WDK) produce un error en una solicitud de IOCTL_SPB_EXECUTE_SEQUENCE que especifica una transferencia superior a 4K bytes y establece el código de estado de esta solicitud en STATUS_INVALID_PARAMETER. Antes de iniciar una operación de secuencia para una solicitud de IOCTL_SPB_EXECUTE_SEQUENCE , el controlador debe validar los parámetros de todas las transferencias de la secuencia para comprobar que la operación se puede completar correctamente.
SpbCx nunca precede a una devolución de llamada EvtSpbControllerIoSequence con una devolución de llamada EvtSpbControllerLock y nunca sigue una devolución de llamada EvtSpbControllerIoSequence con una devolución de llamada EvtSpbControllerUnlock .
secuencias de Client-Implemented
Un cliente de un controlador spb puede realizar explícitamente una secuencia de transferencia de E/S como una serie de lecturas y escrituras simples. El cliente puede ser un controlador en modo kernel o un controlador en modo de usuario que controla un dispositivo periférico conectado al bus. Antes de la primera transferencia de la secuencia, el cliente envía una solicitud IOCTL_SPB_LOCK_CONTROLLER al dispositivo de destino para evitar que se produzcan otros accesos de bus no relacionados entre las transferencias de la secuencia. A continuación, el cliente envía IRP_MJ_READ y IRP_MJ_WRITE solicitudes para realizar las transferencias en la secuencia. Por último, el cliente envía una solicitud de IOCTL_SPB_UNLOCK_CONTROLLER para liberar el bloqueo.
Es posible que un cliente tenga que implementar este tipo de secuencia de transferencia de E/S si una transferencia posterior en la secuencia tiene una dependencia de una transferencia anterior. Por ejemplo, la primera lectura podría indicar cuántos bytes más leer o escribir posteriormente. Sin embargo, si no existe dicha dependencia, el cliente debe enviar una solicitud de IOCTL_SPB_EXECUTE_SEQUENCE al controlador del controlador SPB, que puede realizar la secuencia de forma más eficaz.
Entre la solicitud de IOCTL_SPB_LOCK_CONTROLLER que inicia una secuencia implementada por el cliente y la solicitud de IOCTL_SPB_UNLOCK_CONTROLLER que finaliza la secuencia, las únicas solicitudes de E/S que el cliente puede enviar al dispositivo de destino son IRP_MJ_READ y IRP_MJ_WRITE solicitudes. Cualquier infracción de esta regla es un error.
Los bloqueos SPB solo se usan para garantizar que una secuencia de lecturas y escrituras se realice como una operación de bus atómico y se debe usar exclusivamente para ese propósito.
Para obtener más información, consulte Control de secuencias de Client-Implemented.