다음을 통해 공유


동기 및 비동기 코덱 명령

TransferCodecVerbs 루틴을 사용하면 함수 드라이버가 HD 오디오 컨트롤러에 연결된 오디오 및 모뎀 코덱에 명령을 보낼 수 있습니다. 코덱 명령은 동기적으로 또는 비동기적으로 실행할 수 있습니다.

  • TransferCodecVerbs 호출이 동기적으로 처리할 명령 목록을 제출하는 경우 루틴은 코덱 또는 코덱이 모든 명령을 처리한 후에만 반환됩니다.

  • TransferCodecVerbs 호출에서 비동기적으로 처리할 명령 목록을 제출하면 HD Audio Bus 드라이버가 코덱 또는 코덱이 명령을 처리할 때까지 기다리지 않고 명령을 내부 명령 큐에 추가하는 즉시 루틴이 반환됩니다. 코덱이 명령을 처리한 후 버스 드라이버는 콜백 루틴을 호출하여 함수 드라이버에 알 수 있습니다.

보내는 코덱 명령의 특성에 따라 함수 드라이버는 다음 기술 중 하나 이상을 사용하여 코덱에서 응답을 검색합니다.

  • 함수 드라이버가 추가 처리를 수행하기 전에 코덱의 응답이 있어야 하는 경우 동기 모드를 사용합니다.

  • 함수 드라이버가 코덱 명령이 완료되기를 기다릴 필요가 없고, 코덱 응답을 보고, 명령이 완료되는 시기를 알 필요가 없는 경우 비동기 모드를 사용하고, 콜백 루틴을 무시하고(코덱 명령에 대한 스토리지 해제 제외), 코덱 명령에 대한 응답을 무시하거나 무시합니다.

  • 함수 드라이버가 코덱 명령이 완료된 시기를 알아야 하지만 응답을 볼 필요가 없는 경우 비동기 모드를 사용하고 콜백 루틴을 사용하여 알림을 수신합니다. 그러나 코덱 명령에 대한 응답을 삭제하거나 무시합니다. 콜백 루틴은 KS(커널 스트리밍) 이벤트를 사용하여 드라이버의 기본 부분에 알림을 보낼 수 있습니다.

  • 함수 드라이버가 코덱 명령이 완료될 때와 응답이 무엇인지 모두 알고 있어야 하지만 명령이 완료될 때까지 기다리지 않고 즉시 처리를 다시 시작해야 하는 경우 비동기 모드를 사용하고 콜백 루틴을 받을 때까지 응답을 읽지 않습니다. 콜백 루틴 또는 드라이버의 기본 부분은 응답을 검사할 수 있습니다.

TransferCodecVerbs 는 버스 드라이버의 내부 명령 큐에 명령 목록을 추가하는 데 성공하면 STATUS_SUCCESS 반환합니다. 호출이 성공하더라도 응답은 여전히 유효하지 않을 수 있습니다. 함수 드라이버는 코덱 응답에서 상태 비트를 검사 유효한지 여부를 확인해야 합니다. 이 규칙은 동기 모드와 비동기 모드 모두에 적용됩니다.

잘못된 응답의 원인은 다음 중 하나일 수 있습니다.

  • 명령이 코덱에 도달하지 못했습니다.

  • 코덱이 응답했지만 RIRB에서 FIFO(선제) 오버런이 발생했을 때 응답이 손실되었습니다.

후자의 문제는 RIRB FIFO의 크기가 부족하다는 것을 나타냅니다.

각 코덱 응답에는 응답이 유효한지 여부를 나타내는 IsValid 플래그와 RIRB FIFO 오버런이 발생했는지 여부를 나타내는 HasFifoOverrun 플래그가 포함됩니다. 응답이 유효하지 않음을 나타내는 IsValid = 0인 경우 HasFifoOverrun 플래그는 오류의 원인을 식별하는 데 도움이 됩니다.

  • HasFifoOverrun = 0이면 코덱이 필요한 시간 간격 내에 응답하지 못했습니다. 가능한 원인은 명령이 코덱에 도달하지 않았기 때문일 수 있습니다.

  • HasFifoOverrun = 1이면 명령이 코덱에 도달했지만 FIFO 오버런으로 인해 응답이 손실되었습니다.

TransferCodecCommands를 호출하는 동안 호출자는 HDAUDIO_CODEC_TRANSFER 구조체 배열에 대한 포인터를 제공합니다. 각 구조체는 명령을 포함하고 응답 공간을 제공합니다. 버스 드라이버는 항상 응답을 트리거한 명령이 포함된 구조체에 각 응답을 씁니다.

TransferCodecCommands에 대한 각 호출에 대해 명령이 처리되는 순서는 배열의 명령 순서에 따라 결정됩니다. 배열의 첫 번째 명령 처리는 두 번째 명령 처리가 시작되기 전에 항상 완료됩니다.

또한 클라이언트가 TransferCodecCommands 를 비동기적으로 호출한 다음 첫 번째 호출에서 콜백 루틴을 기다리지 않고 TransferCodecCommands 를 두 번째로 호출하는 경우 두 호출의 두 명령 그룹이 처리되는 상대 순서는 클라이언트가 두 명령 그룹을 제출한 순서로 정의됩니다. 따라서 버스 드라이버는 두 번째 호출에서 명령 처리를 시작하기 전에 첫 번째 호출에서 모든 명령을 처리합니다.

그러나 서로 다른 두 함수 드라이버 인스턴스에서 보낸 명령의 상대적 순서는 정의되지 않습니다. (각 instance 고유한 물리적 디바이스 개체가 있습니다.) 예를 들어 instance 1이 TransferCodecCommands를 호출하여 A-B-C 순서로 A, B 및 C 명령을 보내고 instance 2가 TransferCodecCommands를 호출하여 X-Y-Z 순서로 명령을 보내는 경우 버스 드라이버는 A-X-Y-B-Z-C 순서로 명령을 실행할 수 있습니다.

별도의 함수 드라이버 스레드가 동일한 하드웨어 리소스 집합에 대한 액세스를 공유하는 경우 다른 드라이버 스레드에서 명령의 상대적 순서가 중요할 수 있습니다. 이 경우 함수 드라이버는 스레드 간에 리소스 공유를 동기화해야 합니다.

예를 들어 코덱에 데이터 바이트 시퀀스를 쓰기 위한 하드웨어 인터페이스는 인덱스 레지스터와 8비트 데이터 레지스터로 구성될 수 있습니다. 먼저 함수 드라이버는 코덱 명령을 제출하여 시작 인덱스를 인덱스 레지스터에 로드합니다. 다음으로, 드라이버는 데이터의 첫 번째 바이트를 데이터 레지스터에 쓰는 명령을 제출합니다. 인덱스 레지스터는 전송이 완료될 때까지 데이터 레지스터에 대한 각 연속 쓰기에 따라 증가합니다. 그러나 두 드라이버 스레드가 인덱스 및 데이터 레지스터의 액세스를 제대로 동기화하지 못하면 두 스레드에 의한 개별 레지스터 액세스의 상대 순서가 정의되지 않으며 가능한 결과는 데이터 손상 또는 잘못된 하드웨어 구성입니다.

TransferCodecVerbs 루틴은 두 버전의 HD 오디오 DDI에서 모두 사용할 수 있습니다.