Обработка последовательностей Client-Implemented
Необязательные функции обратного вызова событий EvtSpbControllerLock и EvtSpbControllerUnlock выполняют дополнительные операции. Функция EvtSpbControllerLock является обработчиком для IOCTL_SPB_LOCK_CONTROLLER запросов. Функция EvtSpbControllerUnlock является обработчиком для IOCTL_SPB_UNLOCK_CONTROLLER запросов. Клиент (т. е. драйвер для периферийного устройства в шине) отправляет эти запросы для запуска и завершения последовательностей передачи ввода-вывода. Большинство драйверов контроллера SPB не поддерживают запросы IOCTL_SPB_LOCK_CONTROLLER и IOCTL_SPB_UNLOCK_CONTROLLER и, следовательно, не реализуют функции EvtSpbControllerLock и EvtSpbControllerUnlock .
Клиент может выполнять последовательность передачи операций ввода-вывода в виде ряда простых запросов на передачу (т. е. IRP_MJ_READ и IRP_MJ_WRITE запросов). Первой передаче в последовательности должен предшествовать запрос IOCTL_SPB_LOCK_CONTROLLER . Этот запрос указывает драйверу контроллера SPB заблокировать шину на время последовательности передачи ввода-вывода. За последней передачей должен следовать запрос IOCTL_SPB_UNLOCK_CONTROLLER , который сообщает водителю, чтобы разблокировать автобус. Этот тип последовательности передачи ввода-вывода называется реализованной клиентом последовательностью, чтобы отличить ее от последовательности с одним запросом, в которой вместо IOCTL_SPB_LOCK_CONTROLLER и IOCTL_SPB_UNLOCK_CONTROLLER запросов используется запрос IOCTL_SPB_EXECUTE_SEQUENCE.
В то время как водитель периферийного устройства удерживает блокировку в шине, контроллер шины разрешает доступ к другим периферийным устройствам в шине. Сведения об операции блокировки шины зависят от типа шины. Для контроллера I2C изменение направления передачи (чтение с последующим записью или наоборот) требует операции перезапуска I2C. Для контроллера SPI выбор микросхемы для целевого устройства должен оставаться в силе, пока блокировка контроллера остается в силе. Дополнительные сведения см. в разделе Атомарные операции шины.
Поддержка реализованных клиентом последовательностей передачи необязательна. Драйвер контроллера SPB должен утверждать, что поддерживает их, только если контроллер может выполнять следующие действия:
- Блокировка шины на время реализации клиентом последовательности.
- Разблокируйте автобус в любое время. Например, если между передачами байтов возникает запрос на разблокировку, контроллер должен иметь возможность разблокировать шину, не дожидаясь следующей передачи байтов по шине.
Пока шина заблокирована, клиент может отправить произвольную последовательность простых запросов на передачу. То есть последовательность может быть произвольной длины и может быть любой комбинацией операций чтения и записи.
Чтобы указать поддержку реализованных клиентом последовательностей, драйвер контроллера SPB реализует функцию EvtSpbControllerUnlock . Если драйвер реализует эту функцию, расширение платформы SPB (SpbCx) принимает IOCTL_SPB_LOCK_CONTROLLER и IOCTL_SPB_UNLOCK_CONTROLLER запросы от клиентов. В противном случае SpbCx завершает эти запросы с помощью кода состояния STATUS_NOT_SUPPORTED.
Драйвер контроллера SPB, реализующий функцию EvtSpbControllerUnlock , не требуется для реализации функции EvtSpbControllerLock . Однако драйвер контроллера SPB, реализующий функцию EvtSpbControllerLock , также должен реализовывать функцию EvtSpbControllerUnlock .
Если драйвер реализует функцию EvtSpbControllerUnlock , но не функцию EvtSpbControllerLock , SpbCx вызывает функцию EvtSpbControllerUnlock для обработки запросов IOCTL_SPB_UNLOCK_CONTROLLER , но просто завершает запросы IOCTL_SPB_LOCK_CONTROLLER с STATUS_SUCCESS кодами состояния.
Драйвер имеет два способа обнаружения начала реализованной клиентом последовательности. Во-первых, если драйвер реализует функцию EvtSpbControllerLock , SpbCx вызывает эту функцию для обработки запросов IOCTL_SPB_LOCK_CONTROLLER от клиента. Драйвер может полагаться на этот вызов, выполняемый до первого запроса на передачу в последовательности. Во-вторых, если драйвер не реализует функцию EvtSpbControllerLock , драйвер может вызвать метод SpbRequestGetParameters , когда драйвер обрабатывает простой запрос на передачу от клиента. Чтобы указать, что запрошенная передача является первой передачей в последовательности, этот метод присваивает члену Position в структуре выходных данных метода значение SpbRequestSequencePositionFirst.
Обратный вызов EvtSpbControllerUnlock — единственный способ, которым драйвер может определить, когда заканчивается последовательность. Драйвер, который не реализует функцию EvtSpbControllerUnlock, не поддерживает реализованные клиентом последовательности.