Поделиться через


Работа с USB-каналами

Платформа представляет каждый канал в интерфейсе USB в виде объекта USB-канала платформы. Когда драйвер настраивает USB-устройство, платформа создает объект USB-канала платформы для каждого канала в каждом выбранном интерфейсе. Методы объекта конвейера позволяют драйверу выполнять следующие операции:

Получение сведений о канале

После вызова WdfUsbInterfaceGetConfiguredPipe для получения дескриптора объекта USB-канала платформы драйвер может вызвать следующие методы, определенные объектом USB-канала для получения сведений о USB-канале:

WdfUsbTargetPipeGetIoTarget
Возвращает дескриптор целевого объекта ввода-вывода, связанного с USB-каналом. Драйвер может передать этот дескриптор в WdfRequestSend.

WdfUsbTargetPipeGetInformation
Извлекает сведения о USB-канале и его конечной точке.

WdfUsbTargetPipeGetType
Возвращает тип USB-канала.

WdfUsbTargetPipeIsInEndpoint
Определяет, подключен ли USB-канал к конечной точке ввода.

WdfUsbTargetPipeIsOutEndpoint
Определяет, подключен ли USB-канал к выходной конечной точке.

WDF_USB_PIPE_DIRECTION_IN
Определяет, является ли конечная точка USB входной конечной точкой.

WDF_USB_PIPE_DIRECTION_OUT
Определяет, является ли конечная точка USB выходной конечной точкой.

Дополнительные сведения см. в разделе Перечисление USB-каналов.

Чтение из канала

Для чтения данных из входного USB-канала драйвер может использовать любой (или все) из следующих трех методов:

  • Синхронное чтение данных

    Чтобы синхронно считывать данные из входного USB-канала, драйвер может вызвать метод WdfUsbTargetPipeReadSynchronously . Этот метод создает и отправляет запрос на чтение и возвращается после завершения операции ввода-вывода.

  • Асинхронное чтение данных

    Чтобы асинхронно считывать данные из входного USB-канала, драйвер может вызвать метод WdfUsbTargetPipeFormatRequestForRead для создания запроса на чтение. Затем драйвер может вызвать WdfRequestSend , чтобы отправить запрос асинхронно (или синхронно).

  • Асинхронное и непрерывное чтение данных

    Непрерывное средство чтения — это механизм, предоставляемый платформой для обеспечения того, чтобы запрос на чтение всегда был доступен для USB-канала. Этот механизм гарантирует, что драйвер всегда будет готов к приему данных с устройства, которое предоставляет асинхронный незапрашиваемый входной поток. Например, драйвер сетевого интерфейса карта может использовать непрерывное средство чтения для получения входных данных.

    Чтобы настроить непрерывное средство чтения для входного канала, функция обратного вызова EvtDevicePrepareHardware драйвера должна вызвать метод WdfUsbTargetPipeConfigContinuousReader . Этот метод помещает в очередь набор запросов на чтение к целевому объекту ввода-вывода устройства.

    Кроме того, функция обратного вызова EvtDeviceD0Entry драйвера должна вызвать WdfIoTargetStart для запуска непрерывного средства чтения, а функция обратного вызова EvtDeviceD0Exit драйвера должна вызвать WdfIoTargetStop , чтобы остановить непрерывное средство чтения.

    Каждый раз, когда данные доступны с устройства, целевой объект ввода-вывода выполняет запрос на чтение, и платформа вызывает одну из двух функций обратного вызова: EvtUsbTargetPipeReadComplete, если целевой объект ввода-вывода успешно считывает данные, или EvtUsbTargetPipeReadersFailed, если целевой объект ввода-вывода сообщает об ошибке.

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

    После вызова драйвера WdfUsbTargetPipeConfigContinuousReader драйвер не может использовать WdfUsbTargetPipeReadSynchronously или WdfRequestSend для отправки запросов ввода-вывода в канал, если только функция обратного вызова EvtUsbTargetPipeReadersFailed драйвера не вызывается и не возвращает значение FALSE.

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

Связанные сведения:

Запись в канал

Чтобы записать данные в выходной USB-канал, драйвер может использовать один (или оба) из следующих методов:

  • Синхронная запись данных

    Чтобы синхронно записывать данные в выходной USB-канал, драйвер может вызвать метод WdfUsbTargetPipeWriteSynchronously . Этот метод создает и отправляет запрос на запись и возвращается после завершения операции ввода-вывода.

  • Асинхронная запись данных

    Для асинхронной записи данных во входной USB-канал драйвер может вызвать метод WdfUsbTargetPipeFormatRequestForWrite для создания запроса на запись. Затем драйвер может вызвать WdfRequestSend для асинхронной отправки запроса.

Дополнительные сведения см. в статье Отправка запросов на массовую передачу по USB.

Остановка и сброс канала

Драйвер может вызывать следующие методы для остановки или сброса USB-канала:

WdfUsbTargetPipeAbortSynchronously
Синхронно отправляет запрос на остановку USB-канала.

WdfUsbTargetPipeFormatRequestForAbort
Форматирует запрос на остановку USB-канала. Драйвер может вызвать WdfRequestSend для синхронной или асинхронной отправки запроса.

WdfUsbTargetPipeResetSynchronously
Синхронно отправляет запрос на сброс USB-канала.

WdfUsbTargetPipeFormatRequestForReset
Форматирует запрос на сброс USB-канала. Драйвер должен вызвать WdfRequestSend , чтобы отправить запрос синхронно или асинхронно.

Если usb-объект драйвера завершает запрос ввода-вывода со значением состояния ошибки, драйвер должен выполнить следующие действия:

  1. Остановите канал и отмените все дополнительные запросы ввода-вывода, отправленные драйвером в целевой объект USB, если целевой объект не выполнил запросы.

    Вызовите WdfIoTargetStop с установленным флагом WdfIoTargetCancelSentIo .

  2. Синхронно отправить запрос на прерывание в канал.

    Вызовите WdfUsbTargetPipeAbortSynchronously или вызовите WdfUsbTargetPipeFormatRequestForAbort и WdfRequestSend с установленным флагом WDF_REQUEST_SEND_OPTION_SYNCHRONOUS .

  3. Синхронно отправить запрос на сброс в канал.

    Вызовите WdfUsbTargetPipeResetSynchronously или вызовите WdfUsbTargetPipeFormatRequestForReset , за которым следует WdfRequestSend с установленным флагом WDF_REQUEST_SEND_OPTION_SYNCHRONOUS .

  4. Перезапустите канал.

    Вызовите WdfIoTargetStart.

  5. Повторно отправьте запрос ввода-вывода, который завершился сбоем, и все запросы ввода-вывода, которые последовали за неудачным запросом.

После значительного количества сбоев драйвер должен попытаться сбросить USB-порт, выполнив следующие действия.

  1. Остановите все активные каналы и отмените все дополнительные запросы ввода-вывода, отправленные драйвером на USB-порт каждого канала, если целевой объект не выполнил их.

    Для каждого активного канала вызовите WdfIoTargetStop с установленным флагом WdfIoTargetCancelSentIo .

  2. Синхронно отправьте запрос на сброс USB-порта.

    Вызовите WdfUsbTargetDeviceResetPortSynchronously.

  3. Перезапустите каналы.

    Вызовите WdfIoTargetStart для каждого канала, остановленного драйвером.

  4. Повторно отправьте последний запрос ввода-вывода, который завершился сбоем, и все запросы ввода-вывода, которые последовали за неудачным запросом.

Дополнительные сведения см. в разделе Восстановление после ошибок USB-канала.

Отправка URB в канал

Если драйвер KMDF взаимодействует с USB-каналом путем отправки запросов ввода-вывода, содержащих urb, драйвер может вызвать следующие методы:

WdfUsbTargetPipeSendUrbSynchronously (только KMDF)
Синхронно отправляет запрос ввода-вывода, содержащий URB.

WdfUsbTargetPipeFormatRequestForUrb (только KMDF)
Форматирует запрос ввода-вывода, содержащий URB. Драйвер может вызвать WdfRequestSend для синхронной или асинхронной отправки запроса.

WdfUsbTargetPipeWdmGetPipeHandle (только KMDF)
Возвращает дескриптор usbD-канала устройства. Для некоторых URI требуется этот дескриптор.