Последовательности передачи ввода-вывода
Расширение платформы SPB (SpbCx) поддерживает последовательности передачи ввода-вывода. Последовательность передачи операций ввода-вывода — это упорядоченный набор операций передачи шины (операций чтения и записи), который выполняется в виде одной атомарной операции шины. Все передачи в последовательности передачи ввода-вывода обращаются к одному и тому же целевому устройству в шине. Во время выполнения последовательности другие устройства в шине не могут быть доступны, даже если драйвер контроллера SPB может получать запросы ввода-вывода для других устройств до завершения последовательности передачи ввода-вывода.
Примером последовательности передачи ввода-вывода является операция записи и чтения, которая представляет собой операцию записи в шине, за которой следует операция чтения в шине. Драйвер клиентского периферийного устройства может использовать этот тип последовательности для записи в регистр выбора функции на периферийном устройстве, подключенном к SPB, а затем считывать значение выбранной функции устройства. Эти две передачи могут быть разной длины. Например, операция записи может передавать один байт данных, а операция чтения — много байтов данных.
Типы последовательностей передачи ввода-вывода
Клиент может инициировать последовательность передачи ввода-вывода одним из следующих способов:
Клиент может указать всю последовательность в запросе управления IOCTL_SPB_EXECUTE_SEQUENCE ввода-вывода. Этот запрос позволяет драйверу контроллера SPB использовать любые аппаратные оптимизации производительности, доступные для выполнения последовательности передачи. Дополнительные сведения см. в разделе Последовательности с одним запросом.
Клиент может отправить IOCTL_SPB_LOCK_CONTROLLER запрос на управление вводом-выводом для блокировки контроллера в начале последовательности и отправить IOCTL_SPB_UNLOCK_CONTROLLER после завершения последовательности. Пока контроллер заблокирован, клиент отправляет отдельный запрос ввода-вывода (IRP_MJ_READ или IRP_MJ_WRITE) для каждой операции чтения или записи в последовательности. Дополнительные сведения см. в разделе Реализованные клиентом последовательности.
По возможности клиент должен использовать запрос IOCTL_SPB_EXECUTE_SEQUENCE , который выполняется быстрее, менее подвержен ошибкам и значительно сокращает время, в течение которого другие клиенты блокируются в шине. Однако клиент может использовать IOCTL_SPB_LOCK_CONTROLLER и IOCTL_SPB_UNLOCK_CONTROLLER запросов, если ему необходимо просмотреть значение, считываемое во время одной из передач в последовательности, прежде чем инициировать более позднюю передачу в последовательности. В этом случае требуется тщательное проектирование, чтобы избежать блокировки других клиентов из шины дольше, чем это необходимо, а плохо спроектированный периферийный драйвер может снизить общую производительность системы.
Последовательности Single-Request
Чтобы повысить производительность, драйвер контроллера SPB должен реализовать функцию обратного вызова EvtSpbControllerIoSequence для обработки запросов IOCTL_SPB_EXECUTE_SEQUENCE . Этот подход усложняет работу драйвера контроллера SPB, но не требует от клиента выполнения последовательности передачи ввода-вывода в виде ряда отдельных операций чтения и записи, в то время как другие клиенты заблокированы в шине.
Примечание
Настоятельно рекомендуется реализовать функцию EvtSpbControllerIoSequence, и она может стать требованием для Windows 8.
Реализация последовательности передачи аналогична реализации простой операции чтения или записи, но дополнительно требует обновления сохраненного состояния операции последовательности между отдельными передачами в последовательности. После завершения первой передачи драйвер контроллера SPB обновляет состояние последовательности, чтобы выбрать следующую передачу в последовательности. Состояние последовательности хранится в контексте устройства и включает дескриптор SPBREQUEST , который передается обратному вызову EvtSpbControllerIoSequence . Драйвер контроллера SPB использует этот дескриптор для получения параметров буфера, длины, направления и положения для отдельных передач в последовательности. Дополнительные сведения о получении этих параметров см. в разделе SpbRequestGetTransferParameters.
Если драйвер контроллера SPB не может выполнить запрошенную операцию IOCTL_SPB_EXECUTE_SEQUENCE , он завершает запрос с кодом сбоя. В случае такого сбоя клиент может, как вариант, заблокировать шину, явно выполнить последовательность передачи ввода-вывода как ряд простых запросов ввода-вывода, а затем разблокировать шину. Дополнительные сведения см. в разделе Реализованные клиентом последовательности.
SpbCx выполняет проверку параметров в запросах IOCTL_SPB_XXX, получаемых от драйверов периферийных устройств. Для запросов IOCTL_SPB_EXECUTE_SEQUENCE SpbCx отклоняет как пустые последовательности, так и последовательности, содержащие указатели буфера NULL или буферы нулевой длины.
Драйвер контроллера SPB должен убедиться, что длина каждой передачи в последовательности не превышает заданное драйвером ограничение. Например, пример драйвера SkeletonI2C в комплекте драйверов Windows (WDK) завершается сбоем запроса IOCTL_SPB_EXECUTE_SEQUENCE , который указывает передачу, превышающую 4 КБ байт, и задает код состояния для этого запроса STATUS_INVALID_PARAMETER. Прежде чем инициировать операцию последовательности для запроса IOCTL_SPB_EXECUTE_SEQUENCE , драйвер должен проверить параметры для всех передач в последовательности, чтобы убедиться, что операция может быть успешно завершена.
SpbCx никогда не предшествует обратному вызову EvtSpbControllerIoSequence с обратным вызовом EvtSpbControllerLock и никогда не следует за обратным вызовом EvtSpbControllerIoSequence с обратным вызовом EvtSpbControllerUnlock .
Последовательности Client-Implemented
Клиент драйвера контроллера SPB может явно выполнять последовательность передачи ввода-вывода в виде ряда простых операций чтения и записи. Клиент может быть драйвером в режиме ядра или драйвером пользовательского режима, который управляет периферийным устройством, подключенным к шине. Перед первой передачей в последовательности клиент отправляет запрос IOCTL_SPB_LOCK_CONTROLLER на целевое устройство, чтобы предотвратить другие, несвязанные доступы между передачами в последовательности. Затем клиент отправляет IRP_MJ_READ и IRP_MJ_WRITE запросы на выполнение передачи в последовательности. Наконец, клиент отправляет IOCTL_SPB_UNLOCK_CONTROLLER запрос на освобождение блокировки.
Клиенту может потребоваться реализовать этот тип последовательности передачи ввода-вывода, если более поздняя передача в последовательности зависит от предыдущей передачи. Например, первое чтение может указать, сколько еще байтов для последующего чтения или записи. Однако если такой зависимости не существует, клиент должен отправить IOCTL_SPB_EXECUTE_SEQUENCE запрос драйверу контроллера SPB, который может выполнять последовательность более эффективно.
Между запросом IOCTL_SPB_LOCK_CONTROLLER , который запускает реализованную клиентом последовательность, и запросом IOCTL_SPB_UNLOCK_CONTROLLER , который завершает последовательность, единственными запросами ввода-вывода, которые клиент может отправить на целевое устройство, являются IRP_MJ_READ и IRP_MJ_WRITE запросы. Любое нарушение этого правила является ошибкой.
Блокировки SPB используются только для того, чтобы гарантировать, что последовательность операций чтения и записи выполняется как атомарная шина и должна использоваться исключительно для этой цели.
Дополнительные сведения см. в разделе Обработка последовательностей Client-Implemented.