Запросы ввода-вывода SPB

Предоставленный системой макрос CTL_CODE, описанный в разделе Определение кодов управления вводом-выводом, используется для определения кодов элементов управления IOCTL_SPB_* в spb.h.

Код элемента управления IOCTL_SPB_EXECUTE_SEQUENCE

Код IOCTL_SPB_EXECUTE_SEQUENCE управления вводом-выводом позволяет клиенту (драйверу периферийного устройства) драйвера контроллера SPB выполнять последовательность передач (операций чтения и записи) в виде одной атомарной операции с одним запросом ввода-вывода. Указанное устройство в шине является целевым объектом для всех передач в последовательности.

Задав последовательность передач с фиксированной длиной в виде одной атомарной операции, IOCTL_SPB_EXECUTE_SEQUENCE запрос управления вводом-выводом позволяет драйверу контроллера оптимизировать передачу ввода-вывода и повысить производительность.

Клиент отправляет этот управляющий запрос ввода-вывода в файловый объект для целевого устройства.

Драйвер контроллера SPB регистрирует функцию обратного вызова EvtSpbControllerIoSequence для выполнения передачи шины для последовательности передачи ввода-вывода. Расширение платформы SPB (SpbCx) вызывает эту функцию для передачи IOCTL_SPB_EXECUTE_SEQUENCE запроса драйверу контроллера SPB для обработки.

входной буфер IOCTL_SPB_EXECUTE_SEQUENCE

Входной буфер — это структура SPB_TRANSFER_LIST, содержащая список указателей на буферы данных клиента. Этот список содержит буфер данных для каждой передачи (чтения или записи) в последовательности передачи ввода-вывода.

длина входного буфера IOCTL_SPB_EXECUTE_SEQUENCE

Размер структуры SPB_TRANSFER_LIST.

блок состояния IOCTL_SPB_EXECUTE_SEQUENCE

Если операция выполнена успешно, драйвер контроллера устанавливает для элемента Status значение STATUS_SUCCESS, а для элемента Information — общее количество байтов, переданных во время последовательности.

Эта операция может завершиться ошибкой по различным причинам, включая нехватку ресурсов, недопустимый ввод данных клиента и неисправность устройства.

Если драйвер контроллера начинает обрабатывать запрос ввода-вывода, но во время одной из передач в последовательности возникает ошибка (например, целевое устройство сигнализирует NACK об отклонении передачи), драйвер контроллера прерывает остальные передачи в последовательности. Затем драйвер задает состояние завершения STATUS_SUCCESS, задает для элемента Information количество байтов, которые были успешно переданы до возникновения ошибки, и завершает запрос.

код элемента управления IOCTL_SPB_FULL_DUPLEX

Код элемента управления IOCTL_SPB_FULL_DUPLEX используется клиентом (драйвером периферийных устройств) для запроса полнодуплексной операции ввода-вывода. Полнодуплексные операции ввода-вывода поддерживаются контроллерами для шин, такими как SPI, которые могут одновременно считывать и записывать данные. Предоставленный системой макрос CTL_CODE, описанный в разделе Определение кодов управления вводом-выводом, используется для определения IOCTL_SPB_FULL_DUPLEX следующим образом.

Драйвер пользовательского режима или драйвер режима ядра для устройства в шине отправляет этот запрос на управление вводом-выводом в файловый объект для целевого устройства.

Этот IOCTL поддерживается только драйверами контроллера SPB для автобусов, например SPI, которые могут одновременно считывать и записывать данные.

Буферы записи и чтения для полнодуплексной передачи описываются структурой SPB_TRANSFER_LIST. Эта структура должна использовать следующий формат:

  • Массив структур SPB_TRANSFER_LIST_ENTRY содержит ровно два элемента. Первый элемент описывает буфер записи (Direction = SpbTransferDirectionToDevice). Второй элемент описывает буфер чтения (Direction = SpbTransferDirectionFromDevice).

  • Элементы DelayInUs двух структур SPB_TRANSFER_LIST_ENTRY должны быть равны нулю. Буферные форматы буфера записи и чтения могут иметь любой из следующих форматов:

    • SpbTransferBufferFormatSimple
    • SpbTransferBufferFormatList
    • SpbTransferBufferFormatSimpleNonPaged
    • SpbTransferBufferFormatMdl

    Последние два формата в предыдущем списке могут использоваться только клиентами в режиме ядра. Форматы буферов записи и чтения не обязательно должны быть одинаковыми. Дополнительные сведения об этих форматах буфера см. в разделе SPB_TRANSFER_BUFFER_FORMAT.

Успешная операция может присвоить элементу Information значение, которое меньше суммы размеров буфера записи и буфера чтения, что может произойти, если запрос отменен, операция не может записать полное содержимое буфера записи на устройство или полностью заполнить буфер чтения данными, считываемыми с устройства.

Размеры буферов записи и чтения не обязательно должны быть одинаковыми. Если буфер записи больше буфера чтения, операция продолжает запись данных из буфера записи после заполнения буфера чтения. Если буфер чтения больше буфера записи, операция продолжает заполнять буфер чтения после очистки буфера записи.

Если драйвер контроллера SPB регистрирует функцию обратного вызова EvtSpbControllerIoOther, расширение платформы SPB (SpbCx) вызывает эту функцию для передачи IOCTL_SPB_FULL_DUPLEX запроса драйверу контроллера SPB для обработки. SpbCx не выполняет проверку параметров, проверку списка передачи или другую обработку для запроса IOCTL_SPB_FULL_DUPLEX.

Дополнительные сведения о том, как драйвер контроллера SPB реализует поддержку этого IOCTL, см. в разделе Обработка запросов IOCTL_SPB_FULL_DUPLEX.

входной буфер IOCTL_SPB_FULL_DUPLEX

Указатель на структуру SPB_TRANSFER_LIST, содержащую указатели на буферы входных и выходных данных клиента. Эта структура содержит массив Transfers, состоящий из двух элементов. Первый элемент описывает буфер, содержащий данные для записи на устройство. Второй элемент описывает буфер, используемый для хранения данных, считыванных с устройства. Дополнительные сведения о том, как драйвер контроллера SPB реализует запрос пользовательского элемента управления вводом-выводом (IOCTL), который использует SPB_TRANSFER_LIST структуры для описания буферов, см. в разделе Использование структуры SPB_TRANSFER_LIST для пользовательских ICTL.

длина входного буфера IOCTL_SPB_FULL_DUPLEX

Размер структуры SPB_TRANSFER_LIST.

блок состояния IOCTL_SPB_FULL_DUPLEX

Если операция выполнена успешно, драйвер контроллера устанавливает для элемента Status значение STATUS_SUCCESS, а для элемента Information — общее количество переданных байтов (байтов чтения и записи байтов) во время полнодуплексной операции.

Эта операция может завершиться ошибкой по различным причинам, включая нехватку ресурсов, недопустимый ввод данных клиента и неисправность устройства.

Код элемента управления IOCTL_SPB_LOCK_CONNECTION

Код IOCTL_SPB_LOCK_CONNECTION управления используется клиентом (драйвером периферийного устройства) для получения блокировки подключения на целевом устройстве, подключенном к SPB, которое совместно используется другим клиентом. Пока клиент удерживает блокировку подключения, он имеет монопольный доступ к устройству. Предоставленный системой CTL_CODE макрос, описанный в разделе Определение кодов управления вводом-выводом, используется для определения IOCTL_SPB_LOCK_CONNECTION следующим образом.

Запросы IOCTL_SPB_LOCK_CONNECTION и IOCTL_SPB_UNLOCK_CONNECTION получают и освобождают блокировку подключения на целевом устройстве, подключенном к простой периферийной шине. Большинство клиентов не используют эти запросы управления вводом-выводом. Эти запросы используются только в том случае, если два клиента совместно используют доступ к одному целевому устройству. Дополнительные сведения см. в разделе Блокировки подключений SPB.

Два клиента могут открывать отдельные логические подключения к одному и тому же целевому устройству и использовать блокировку подключения, когда одному из клиентов требуется монопольный доступ к устройству. Когда один клиент удерживает блокировку, запросы ввода-вывода на устройство от второго клиента автоматически откладываются до тех пор, пока первый клиент не спустит блокировку.

Клиент может одновременно удерживать блокировку подключения на целевом устройстве и блокировку контроллера на контроллере SPB. Запросы IOCTL_SPB_LOCK_CONTROLLER и IOCTL_SPB_UNLOCK_CONTROLLER получают и освобождают блокировку контроллера. Клиент должен получить блокировку подключения перед получением блокировки контроллера и освободить блокировку контроллера перед освобождением блокировки подключения. Клиент использует блокировку контроллера для выполнения упорядоченного набора операций передачи шины (операций чтения и записи) в виде одной атомарной операции шины. Дополнительные сведения см. в разделе Последовательности передачи ввода-вывода.

Блокировка подключения автоматически завершается, если запрос IRP_MJ_CLEANUP отправляется на целевое устройство, когда подключение заблокировано на устройстве. Запрос на очистку отправляется на целевое устройство, когда клиент закрывает дескриптор файла на устройстве.

блок состояния IOCTL_SPB_LOCK_CONNECTION

Если операция выполнена успешно, для элемента Status устанавливается значение STATUS_SUCCESS.

Если операция завершается сбоем, члену Состояния присваивается соответствующий код состояния ошибки.

Если клиент уже удерживает либо блокировку подключения на целевом устройстве, либо блокировку контроллера на контроллере SPB, эта операция завершается ошибкой с состоянием = STATUS_INVALID_DEVICE_REQUEST. Эта операция может завершиться ошибкой по другим причинам, которые могут включать нехватку ресурсов, недопустимые входные данные клиента и неисправность устройства.

код элемента управления IOCTL_SPB_LOCK_CONTROLLER

Код IOCTL_SPB_LOCK_CONTROLLER управления используется клиентом (драйвером периферийного устройства) для блокировки контроллера SPB. Пока контроллер заблокирован, клиент имеет монопольное использование шины для доступа к указанному целевому устройству для блокировки. Предоставленный системой макрос CTL_CODE, описанный в разделе Определение кодов управления вводом-выводом, используется для определения IOCTL_SPB_LOCK_CONTROLLER следующим образом.

Чтобы получить монопольное использование шины для доступа к целевому устройству, клиент (драйвер периферийного устройства) отправляет этот IOCTL в файловый объект для целевого объекта. После завершения этого IOCTL контроллер блокируется, и все операции ввода-вывода (чтение или запись) в шине обращаются к назначенному целевому объекту. Между передачами контроллер сохраняет выбранное целевое устройство, но останавливает часы.

Контроллер остается заблокированным, пока клиент не отправит IOCTL_SPB_UNLOCK_CONTROLLER запрос на разблокировку контроллера. После завершения клиентской последовательности передачи данных на целевое устройство или с целевого устройства клиент должен разблокировать контроллер, чтобы контроллер смог обрабатывать запросы ввода-вывода для других целевых объектов в шине.

Блокировка автоматически прекращается, если запрос IRP_MJ_CLEANUP отправляется на целевое устройство, когда контроллер заблокирован на целевом устройстве. Запрос на очистку отправляется в целевой объект, когда клиент закрывает свой дескриптор для целевого объекта.

Контроллеры SPB не обязаны поддерживать запросы IOCTL_SPB_LOCK_CONTROLLER и IOCTL_SPB_UNLOCK_CONTROLLER, а драйверы периферийных устройств не должны предполагать, что они поддерживаются.

Если драйвер контроллера SPB регистрирует функцию обратного вызова EvtSpbControllerLock, расширение платформы SPB (SpbCx) вызывает эту функцию для передачи IOCTL_SPB_LOCK_CONTROLLER запроса драйверу контроллера SPB для обработки.

блок состояния IOCTL_SPB_LOCK_CONTROLLER

Если операция выполнена успешно, для элемента Status устанавливается значение STATUS_SUCCESS. Этот IOCTL может возвращать состояние ошибки по ряду причин, включая сбой настройки контроллера для работы в режиме монопольного доступа. В этом режиме контроллер сохраняет выбор целевого устройства, чтобы оно было монопольным целевым объектом для всех операций ввода-вывода в шине. Контроллер остается в этом режиме до тех пор, пока он не будет разблокирован.

Код элемента управления IOCTL_SPB_UNLOCK_CONNECTION

Код управления IOCTL_SPB_UNLOCK_CONNECTION ввода-вывода используется клиентом (драйвером периферии) для снятия блокировки подключения на целевом устройстве, подключенном к SPB, которое совместно используется другим клиентом. Клиент ранее отправил IOCTL_SPB_LOCK_CONNECTION запрос на получение монопольного доступа к устройству.

Запросы IOCTL_SPB_LOCK_CONNECTION и IOCTL_SPB_UNLOCK_CONNECTION получают и освобождают блокировку подключения на целевом устройстве, подключенном к простой периферийной шине. Большинство клиентов не используют эти запросы управления вводом-выводом. Эти запросы используются только в том случае, если два клиента совместно используют доступ к одному целевому устройству. Дополнительные сведения см. в разделе Блокировки подключений SPB.

После того как клиент (драйвер периферийного устройства) отправляет запрос IOCTL_SPB_LOCK_CONNECTION на целевое устройство в шине и запрос успешно завершается, подключение остается заблокированным до тех пор, пока клиент не отправит IOCTL_SPB_UNLOCK_CONNECTION запрос на разблокировку подключения.

Клиент отправляет IOCTL_SPB_UNLOCK_CONNECTION запрос на освобождение блокировки подключения к целевому устройству, когда клиенту больше не требуется монопольный доступ к устройству. Подключение должно быть разблокировано, чтобы другой клиент смог получить доступ к устройству.

блок состояния IOCTL_SPB_UNLOCK_CONNECTION

Если операция выполнена успешно, для элемента Status устанавливается значение STATUS_SUCCESS.

Если операция завершается сбоем, члену Состояния присваивается соответствующий код состояния ошибки. Если клиент не удерживает блокировку подключения на целевом устройстве или клиент по-прежнему удерживает блокировку подключения на контроллере SPB, эта операция завершается ошибкой с состоянием = STATUS_INVALID_DEVICE_REQUEST. Эта операция может завершиться ошибкой по другим причинам, которые могут включать нехватку ресурсов, недопустимые входные данные клиента и неисправность устройства.

Код элемента управления IOCTL_SPB_UNLOCK_CONTROLLER

Код элемента управления IOCTL_SPB_UNLOCK_CONTROLLER ввода-вывода используется клиентом (периферийным драйвером) для разблокировки контроллера SPB. Клиент ранее заблокировал контроллер, чтобы получить монопольное использование шины для доступа к целевому устройству в шине.

После того как клиент (драйвер периферийного устройства) отправляет запрос на управление IOCTL_SPB_LOCK_CONTROLLER на целевое устройство в шине, контроллер остается заблокированным, пока клиент не отправит запрос IOCTL_SPB_UNLOCK_CONTROLLER управления вводом-выводом для разблокировки контроллера. Клиент отправляет эти запросы управления вводом-выводом в файловый объект для целевого устройства.

Клиент отправляет запрос IOCTL_SPB_UNLOCK_CONTROLLER после завершения последовательности передач в шине и хочет освободить целевое устройство. Контроллер должен быть разблокирован, чтобы он обрабатывал запросы ввода-вывода для других целевых объектов в шине.

Контроллеры SPB не обязаны поддерживать запросы IOCTL_SPB_LOCK_CONTROLLER и IOCTL_SPB_UNLOCK_CONTROLLER, а драйверы периферийных устройств не должны предполагать, что они поддерживаются.

Расширение платформы SPB (SpbCx) вызывает необязательную функцию обратного вызова драйвера контроллера SPB EvtSpbControllerUnlock для передачи IOCTL_SPB_LOCK_CONTROLLER запроса драйверу контроллера SPB для обработки.

блок состояния IOCTL_SPB_UNLOCK_CONTROLLER

Если операция выполнена успешно, для элемента Status устанавливается значение STATUS_SUCCESS.

Этот IOCTL может завершиться ошибкой, только если он отправлен клиентом, у которых контроллер не заблокирован для монопольного доступа к назначенному целевому объекту.