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 를 두 번째로 호출하는 경우 두 호출의 두 명령 그룹이 처리되는 상대 순서는 클라이언트가 두 명령 그룹을 제출한 순서에 따라 정의됩니다. 따라서 버스 드라이버는 두 번째 호출에서 명령 처리를 시작하기 전에 첫 번째 호출에서 모든 명령을 처리합니다.
그러나 서로 다른 두 함수 드라이버 인스턴스에서 보낸 명령의 상대적 순서는 정의되지 않습니다. (각 인스턴스에는 고유한 물리적 디바이스 개체가 있습니다.) 예를 들어 인스턴스 1이 TransferCodecCommands 를 호출하여 A-B-C 순서로 명령 A, B 및 C를 보내고 인스턴스 2가 TransferCodecCommands 를 호출하여 X-Y-Z 순서로 X, Y 및 Z 명령을 보내는 경우 버스 드라이버는 A-X-Y-B-Z-C 순서로 명령을 실행할 수 있습니다.
별도의 함수 드라이버 스레드가 동일한 하드웨어 리소스 집합에 대한 액세스를 공유하는 경우 다른 드라이버 스레드에서 명령의 상대적 순서가 중요할 수 있습니다. 이 경우 함수 드라이버는 스레드 간에 리소스 공유를 동기화하는 역할을 담당합니다.
예를 들어 코덱에 데이터 바이트 시퀀스를 쓰기 위한 하드웨어 인터페이스는 인덱스 레지스터와 8비트 데이터 레지스터로 구성될 수 있습니다. 먼저 함수 드라이버는 시작 인덱스를 인덱스 레지스터에 로드하는 코덱 명령을 제출합니다. 다음으로, 드라이버는 데이터 레지스터에 데이터의 첫 번째 바이트를 쓰는 명령을 제출합니다. 인덱스 레지스터는 전송이 완료될 때까지 데이터 레지스터에 대한 각 연속 쓰기 다음에 증가합니다. 그러나 두 드라이버 스레드가 인덱스 및 데이터 레지스터의 액세스를 제대로 동기화하지 못하는 경우 두 스레드에 의한 개별 레지스터 액세스의 상대적 순서는 정의되지 않으며 가능한 결과는 데이터 손상 또는 잘못된 하드웨어 구성입니다.
TransferCodecVerbs 루틴은 두 버전의 HD 오디오 DDI에서 모두 사용할 수 있습니다.