Comandi codec sincroni e asincroni

La routine TransferCodecVerbs consente ai driver di funzione di inviare comandi a codec audio e modem connessi a un controller audio HD. I comandi codec possono essere eseguiti in modo sincrono o asincrono:

  • Se una chiamata a TransferCodecVerbs invia un elenco di comandi da elaborare in modo sincrono, la routine restituisce solo dopo che il codec o i codec hanno elaborato tutti i comandi.

  • Se una chiamata a TransferCodecVerbs invia un elenco di comandi da elaborare in modo asincrono, la routine restituisce non appena il driver del bus audio HD aggiunge i comandi alla relativa coda di comandi interna, senza attendere che il codec o i codec elaborino i comandi. Dopo che i codec hanno elaborato i comandi, il driver del bus notifica al driver di funzione chiamando una routine di callback.

A seconda della natura dei comandi codec inviati, il driver di funzione usa una o più delle tecniche seguenti per recuperare le risposte da un codec:

  • Se il driver di funzione deve avere la risposta dal codec prima di poter eseguire qualsiasi ulteriore elaborazione, usa la modalità sincrona.

  • Se il driver di funzione non deve attendere il completamento dei comandi codec, per visualizzare le risposte del codec e per sapere quando i comandi vengono completati, usa la modalità asincrona, ignora la routine di callback (ad eccezione di liberare lo spazio di archiviazione per i comandi codec) e ignora o ignora le risposte ai comandi codec.

  • Se il driver di funzione deve sapere quando i comandi codec vengono completati, ma non è necessario visualizzare le risposte, usa la modalità asincrona e si basa sulla routine di callback per la notifica. Tuttavia, rimuove o ignora le risposte ai comandi codec. La routine di callback potrebbe usare un evento di streaming del kernel (KS) per inviare la notifica alla parte principale del driver.

  • Se il driver di funzione deve conoscere sia quando i comandi codec vengono completati che le risposte, ma devono riprendere immediatamente l'elaborazione anziché attendere il completamento dei comandi, usa la modalità asincrona ed evita di leggere le risposte fino a quando non riceve la routine di callback. La routine di callback o la parte principale del driver può controllare le risposte.

TransferCodecVerbs restituisce STATUS_SUCCESS se riesce ad aggiungere l'elenco di comandi alla coda dei comandi interna del driver del bus. Anche se la chiamata ha esito positivo, le risposte potrebbero essere ancora non valide. Il driver di funzione deve controllare i bit di stato nelle risposte codec per determinare se sono validi. Questa regola si applica sia alla modalità sincrona che alla modalità asincrona.

La causa di una risposta non valida è probabilmente una delle seguenti:

  • Il comando non ha raggiunto il codec.

  • Il codec ha risposto, ma la risposta è stata persa quando si è verificato un sovraccarico FIFO (First-In First-Out) in RIRB.

Il secondo problema indica che il FIFO DI RIRB è di dimensioni insufficienti.

Ogni risposta codec contiene un flag IsValid per indicare se la risposta è valida e un flag HasFifoOverrun per indicare se si è verificato un overrun FIFO DI RIRB. Se IsValid = 0, a indicare che una risposta non è valida, il flag HasFifoOverrun consente di identificare l'origine dell'errore:

  • Se HasFifoOverrun = 0, il codec non è riuscito a rispondere entro l'intervallo di tempo richiesto. La causa probabile è che il comando non ha mai raggiunto il codec.

  • Se HasFifoOverrun = 1, il comando probabilmente ha raggiunto il codec, ma la risposta è stata persa a causa di un sovraccarico FIFO.

Durante una chiamata a TransferCodecCommands, il chiamante fornisce un puntatore a una matrice di strutture HDAUDIO_CODEC_TRANSFER . Ogni struttura contiene un comando e fornisce spazio per una risposta. Il driver del bus scrive sempre ogni risposta nella struttura che contiene il comando che ha attivato la risposta.

Per ogni chiamata a TransferCodecCommands, l'ordine in cui vengono elaborati i comandi è determinato dall'ordine dei comandi nella matrice. L'elaborazione del primo comando nella matrice viene sempre completata prima dell'inizio dell'elaborazione del secondo comando e così via.

Inoltre, se un client effettua una chiamata asincrona a TransferCodecCommands e quindi chiama TransferCodecCommands una seconda volta senza attendere la routine di callback dalla prima chiamata, l'ordine relativo in cui i due gruppi di comandi delle due chiamate vengono elaborati viene definito dall'ordine in cui il client ha inviato i due gruppi di comandi. Di conseguenza, il driver del bus elabora tutti i comandi dalla prima chiamata prima di iniziare a elaborare i comandi dalla seconda chiamata.

Tuttavia, l'ordine relativo dei comandi inviati da due istanze diverse del driver di funzione non è definito. Ogni istanza ha un proprio oggetto dispositivo fisico. Ad esempio, se l'istanza 1 chiama TransferCodecCommands per inviare comandi A, B e C nell'ordine A-B-C e l'istanza 2 chiama TransferCodecCommands per inviare comandi X, Y e Z nell'ordine X-Y-Z, il driver del bus potrebbe eseguire i comandi nell'ordine A-X-Y-B-Z-C.

Quando i thread del driver di funzione separati condividono l'accesso allo stesso set di risorse hardware, l'ordine relativo dei comandi di thread driver diversi potrebbe essere importante. In tal caso, il driver di funzione è responsabile della sincronizzazione della condivisione delle risorse tra i thread.

Ad esempio, l'interfaccia hardware per la scrittura di una sequenza di byte di dati in un codec può essere costituita da un registro di indice e da un registro dati a 8 bit. Prima di tutto, il driver di funzione invia un comando codec per caricare l'indice iniziale nel registro di indice. Successivamente, il driver invia un comando per scrivere il primo byte di dati nel registro dati. Il registro di indice incrementa ogni scrittura successiva nel registro dati fino al completamento del trasferimento. Tuttavia, se due thread driver non riescono a sincronizzare correttamente l'accesso dell'indice e dei registri dati, l'ordine relativo dell'accesso al registro individuale da parte dei due thread non è definito e il risultato probabile è il danneggiamento dei dati o una configurazione hardware non valida.

La routine TransferCodecVerbs è disponibile in entrambe le versioni di HD Audio DDI.