USB 파이프 작업

프레임워크는 USB 인터페이스의 각 파이프를 프레임워크 USB 파이프 개체로 나타냅니다. 드라이버가 USB 디바이스를 구성하는 경우 프레임워크는 선택한 각 인터페이스에서 각 파이프에 대한 프레임워크 USB 파이프 개체를 만듭니다. 파이프 개체 메서드를 사용하면 드라이버가 다음 작업을 수행할 수 있습니다.

파이프 정보 가져오기

WdfUsbInterfaceGetConfiguredPipe를 호출하여 프레임워크 USB 파이프 개체에 대한 핸들을 가져온 후 드라이버는 USB 파이프 개체가 USB 파이프에 대한 정보를 얻기 위해 정의하는 다음 메서드를 호출할 수 있습니다.

WdfUsbTargetPipeGetIoTarget
USB 파이프와 연결된 I/O 대상 개체에 대한 핸들을 반환합니다. 드라이버는 이 핸들을 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 메서드를 호출할 수 있습니다. 이 메서드는 읽기 요청을 빌드하고 보내며 I/O 작업이 완료된 후 반환됩니다.

  • 비동기적으로 데이터 읽기

    USB 입력 파이프에서 비동기적으로 데이터를 읽으려면 드라이버가 WdfUsbTargetPipeFormatRequestForRead 메서드를 호출하여 읽기 요청을 작성할 수 있습니다. 그런 다음 드라이버는 WdfRequestSend 를 호출하여 요청을 비동기적으로(또는 동기적으로) 보낼 수 있습니다.

  • 비동기 및 지속적으로 데이터 읽기

    연속 판독기는 USB 파이프에서 읽기 요청을 항상 사용할 수 있도록 하는 프레임워크 제공 메커니즘입니다. 이 메커니즘은 드라이버가 항상 비동기, 원치 않는 입력 스트림을 제공하는 디바이스에서 데이터를 받을 준비가 되도록 보장합니다. 예를 들어 NIC(네트워크 인터페이스 카드)의 드라이버는 연속 판독기를 사용하여 입력 데이터를 수신할 수 있습니다.

    입력 파이프에 대한 연속 판독기를 구성하려면 드라이버의 EvtDevicePrepareHardware 콜백 함수가 WdfUsbTargetPipeConfigContinuousReader 메서드를 호출해야 합니다. 이 메서드는 디바이스의 I/O 대상에 대한 읽기 요청 집합을 큐에 대기합니다.

    또한 드라이버의 EvtDeviceD0Entry 콜백 함수는 WdfIoTargetStart 를 호출하여 연속 판독기를 시작해야 하며 드라이버의 EvtDeviceD0Exit 콜백 함수는 WdfIoTargetStop 을 호출하여 연속 판독기를 중지해야 합니다.

    디바이스에서 데이터를 사용할 수 있을 때마다 I/O 대상은 읽기 요청을 완료하고 I/O 대상이 데이터를 성공적으로 읽은 경우 EvtUsbTargetPipeReadComplete, I/O 대상이 오류를 보고하는 경우 EvtUsbTargetPipeReadersFailed라는 두 가지 콜백 함수 중 하나를 호출합니다.

    선택적 EvtUsbTargetPipeReadersFailed 콜백을 제공하지 않으면 프레임워크는 다른 읽기 요청을 전송하여 실패한 읽기 시도에 응답합니다. 따라서 버스가 읽기를 수락하지 않는 상태에 있는 경우 프레임워크는 실패한 읽기에서 복구하기 위해 지속적으로 새 요청을 보냅니다.

    드라이버가 WdfUsbTargetPipeConfigContinuousReader를 호출한 후에는 드라이버의 EvtUsbTargetPipeReadersFailed 콜백 함수가 호출되고 FALSE를 반환하지 않는 한 드라이버가 WdfUsbTargetPipeReadSynchronously 또는 WdfRequestSend를 사용하여 파이프에 I/O 요청을 보낼 수 없습니다.

기본적으로 프레임워크는 드라이버가 파이프의 최대 패킷 크기의 배수가 아닌 읽기 버퍼를 지정하는 경우 오류를 보고합니다. 드라이버는 WdfUsbTargetPipeSetNoMaximumPacketSizeCheck 를 호출하여 읽기 버퍼 크기의 이 테스트를 사용하지 않도록 설정할 수 있습니다.

관련 정보는 다음을 참조하세요.

파이프에 쓰기

USB 출력 파이프에 데이터를 쓰려면 드라이버는 다음 기술 중 하나(또는 둘 다)를 사용할 수 있습니다.

  • 동기적으로 데이터 쓰기

    USB 출력 파이프에 동기적으로 데이터를 쓰려면 드라이버가 WdfUsbTargetPipeWriteSynchronously 메서드를 호출할 수 있습니다. 이 메서드는 쓰기 요청을 빌드하고 보내며 I/O 작업이 완료된 후 반환됩니다.

  • 비동기적으로 데이터 쓰기

    USB 입력 파이프에 비동기적으로 데이터를 쓰려면 드라이버가 WdfUsbTargetPipeFormatRequestForWrite 메서드를 호출하여 쓰기 요청을 작성할 수 있습니다. 그런 다음 드라이버는 WdfRequestSend 를 호출하여 요청을 비동기적으로 보낼 수 있습니다.

관련 정보는 USB 대량 전송 요청을 보내는 방법을 참조하세요.

파이프 중지 및 초기화

드라이버는 다음 메서드를 호출하여 USB 파이프를 중지하거나 다시 설정할 수 있습니다.

WdfUsbTargetPipeAbortSynchronously
USB 파이프를 중지하라는 요청을 동기적으로 보냅니다.

WdfUsbTargetPipeFormatRequestForAbort
USB 파이프를 중지하는 요청의 형식을 지정합니다. 드라이버는 WdfRequestSend 를 호출하여 요청을 동기적으로 또는 비동기적으로 보낼 수 있습니다.

WdfUsbTargetPipeResetSynchronously
USB 파이프를 다시 설정하라는 요청을 동기적으로 보냅니다.

WdfUsbTargetPipeFormatRequestForReset
USB 파이프를 다시 설정하기 위한 요청의 형식을 지정합니다. 드라이버는 WdfRequestSend 를 호출하여 요청을 동기적으로 또는 비동기적으로 보내야 합니다.

드라이버의 USB 대상이 오류 상태 값으로 I/O 요청을 완료하는 경우 드라이버는 다음을 수행해야 합니다.

  1. 대상에서 요청을 완료하지 않은 경우 파이프를 중지하고 드라이버가 USB 대상으로 보낸 추가 I/O 요청을 취소합니다.

    WdfIoTargetCancelSentIo 플래그 집합을 사용하여 WdfIoTargetStop을 호출합니다.

  2. 파이프에 중단 요청을 동기적으로 보냅니다.

    WdfUsbTargetPipeAbortSynchronously를 호출하거나 WdfUsbTargetPipeFormatRequestForAbort를 호출한 다음, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS 플래그가 설정된 WdfRequestSend를 호출합니다.

  3. 파이프에 재설정 요청을 동기적으로 보냅니다.

    WdfUsbTargetPipeResetSynchronously를 호출하거나 WdfUsbTargetPipeFormatRequestForReset을 호출한 다음, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS 플래그가 설정된 WdfRequestSend를 호출합니다.

  4. 파이프를 다시 시작합니다.

    WdfIoTargetStart를 호출합니다.

  5. 실패한 I/O 요청과 실패한 요청 이후의 모든 I/O 요청을 다시 보냅니다.

많은 수의 오류가 발생한 후 드라이버는 다음을 수행하여 USB 포트를 다시 설정하려고 시도해야 합니다.

  1. 모든 활성 파이프를 중지하고, 대상이 완료되지 않은 경우 드라이버가 각 파이프의 USB 대상으로 보낸 추가 I/O 요청을 취소합니다.

    각 활성 파이프에 대해 WdfIoTargetCancelSentIo 플래그가 설정된 WdfIoTargetStop을 호출합니다.

  2. USB 포트를 다시 설정하라는 요청을 동기적으로 보냅니다.

    WdfUsbTargetDeviceResetPortSynchronously를 호출합니다.

  3. 파이프를 다시 시작합니다.

    드라이버가 중지된 각 파이프에 대해 WdfIoTargetStart 를 호출합니다.

  4. 실패한 마지막 I/O 요청과 실패한 요청을 따른 모든 I/O 요청을 다시 보냅니다.

관련 정보는 USB 파이프 오류에서 복구하는 방법을 참조하세요.

파이프에 URB 보내기

KMDF 드라이버가 URL이 포함된 I/O 요청을 전송하여 USB 파이프와 통신하는 경우 드라이버는 다음 메서드를 호출할 수 있습니다.

WdfUsbTargetPipeSendUrbSynchronously(KMDF에만 해당)
URB를 포함하는 I/O 요청을 동기적으로 보냅니다.

WdfUsbTargetPipeFormatRequestForUrb(KMDF에만 해당)
URB를 포함하는 I/O 요청의 형식을 지정합니다. 드라이버는 WdfRequestSend 를 호출하여 요청을 동기적으로 또는 비동기적으로 보낼 수 있습니다.

WdfUsbTargetPipeWdmGetPipeHandle(KMDF에만 해당)
디바이스의 USBD 파이프 핸들을 반환합니다. 일부 URL에는 이 핸들이 필요합니다.