Control de secuencias de Client-Implemented
Las funciones opcionales de devolución de llamada de eventos EvtSpbControllerLock y EvtSpbControllerUnlock realizan operaciones complementarias. La función EvtSpbControllerLock es un controlador para solicitudes IOCTL_SPB_LOCK_CONTROLLER . La función EvtSpbControllerUnlock es un controlador para IOCTL_SPB_UNLOCK_CONTROLLER solicitudes. Un cliente (es decir, el controlador de un dispositivo periférico en el bus) envía estas solicitudes para iniciar y finalizar secuencias de transferencia de E/S. La mayoría de los controladores de controlador SPB no admiten solicitudes de IOCTL_SPB_LOCK_CONTROLLER y IOCTL_SPB_UNLOCK_CONTROLLER y, por lo tanto, no implementan las funciones EvtSpbControllerLock y EvtSpbControllerUnlock .
Un cliente puede realizar una secuencia de transferencia de E/S como una serie de solicitudes de transferencia simples (es decir, solicitudes de IRP_MJ_READ y IRP_MJ_WRITE ). La primera transferencia de la secuencia debe ir precedida de una solicitud de IOCTL_SPB_LOCK_CONTROLLER : esta solicitud indica al controlador del controlador SPB que bloquee el bus mientras dure la secuencia de transferencia de E/S. La última transferencia debe ir seguida de una solicitud de IOCTL_SPB_UNLOCK_CONTROLLER , que indica al conductor que desbloquee el autobús. Este tipo de secuencia de transferencia de E/S se denomina secuencia implementada por el cliente para distinguirla de una secuencia de solicitud única, que usa una solicitud de IOCTL_SPB_EXECUTE_SEQUENCE en lugar de IOCTL_SPB_LOCK_CONTROLLER y solicitudes IOCTL_SPB_UNLOCK_CONTROLLER .
Mientras que el controlador de un dispositivo periférico contiene un bloqueo en el bus, el controlador de bus permite el acceso a ningún otro dispositivo periférico en el bus. Los detalles de la operación de bloqueo de bus dependen del tipo de bus. Para un controlador I2C, un cambio en la dirección de transferencia (una lectura seguida de una escritura, o viceversa) requiere una operación de reinicio de I2C. En el caso de un controlador SPI, el chip-select en el dispositivo de destino debe permanecer asertivo mientras el bloqueo del controlador permanece en vigor. Para obtener más información, consulte Atomic Bus Operations.
La compatibilidad con secuencias de transferencia implementadas por el cliente es opcional. El controlador del controlador SPB debe reclamar que solo los admita si el controlador puede hacer lo siguiente:
- Bloquee el bus durante la secuencia implementada por el cliente.
- Desbloquee el autobús en cualquier momento. Por ejemplo, si se produce una solicitud de desbloqueo entre transferencias de bytes, el controlador debe poder desbloquear el bus sin esperar a la transferencia de bytes siguiente sobre el bus.
Mientras el bus está bloqueado, el cliente puede enviar una secuencia arbitraria de solicitudes de transferencia simples. Es decir, la secuencia puede tener una longitud arbitraria y puede ser cualquier combinación de lecturas y escrituras.
Para indicar la compatibilidad con secuencias implementadas por el cliente, un controlador de controlador SPB implementa una función EvtSpbControllerUnlock . Si el controlador implementa esta función, la extensión de marco de SPB (SpbCx) acepta IOCTL_SPB_LOCK_CONTROLLER y IOCTL_SPB_UNLOCK_CONTROLLER solicitudes de clientes. De lo contrario, SpbCx produce un error en estas solicitudes al completarlas con el código de estado STATUS_NOT_SUPPORTED.
No es necesario un controlador de controlador SPB que implemente una función EvtSpbControllerUnlock para implementar una función EvtSpbControllerLock . Sin embargo, un controlador de controlador SPB que implementa una función EvtSpbControllerLock también debe implementar una función EvtSpbControllerUnlock .
Si el controlador implementa una función EvtSpbControllerUnlock pero no una función EvtSpbControllerLock , SpbCx llama a la función EvtSpbControllerUnlock para controlar las solicitudes de IOCTL_SPB_UNLOCK_CONTROLLER , pero simplemente completa las solicitudes de IOCTL_SPB_LOCK_CONTROLLER con códigos de estado STATUS_SUCCESS.
El controlador tiene dos maneras de detectar el inicio de una secuencia implementada por el cliente. En primer lugar, si el controlador implementa una función EvtSpbControllerLock , SpbCx llama a esta función para controlar una IOCTL_SPB_LOCK_CONTROLLER solicitudes de un cliente. El controlador puede confiar en esta llamada que se produce antes de la primera solicitud de transferencia en una secuencia. En segundo lugar, si el controlador no implementa una función EvtSpbControllerLock , el controlador puede llamar al método SpbRequestGetParameters cuando el controlador controla una solicitud de transferencia simple del cliente. Para indicar que la transferencia solicitada es la primera transferencia de una secuencia, este método establece el miembro Position en la estructura de salida del método en SpbRequestSequencePositionFirst.
La devolución de llamada EvtSpbControllerUnlock es la única manera en que un controlador puede determinar cuándo finaliza una secuencia. Un controlador que no implementa una función EvtSpbControllerUnlock no puede admitir secuencias implementadas por el cliente.