Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo descrive le varie attività eseguite da un driver client del controller di funzione durante l'interazione con l'estensione del controller di funzione USB (UFX).
API importanti
Descrive le varie attività eseguite da un driver client del controller di funzione durante l'interazione con l'estensione del controller di funzione USB (UFX). UFX e il driver client comunicano tra loro usando metodi di esportazione e funzioni di callback degli eventi. I metodi di esportazione (denominati UfxDeviceXxx o UfxEndpointXxx) vengono esportati da UFX e richiamati dal driver client. Le funzioni di callback (denominate EVT_UFX_Xxx) vengono implementate nel driver client e richiamate da UFX.
UFX chiama in modo asincrono tutte le funzioni di callback del driver client e un callback alla volta per ogni oggetto. Ad esempio, è presente un oggetto dispositivo USB e tre oggetti endpoint. Al massimo quattro funzioni di callback (una per il dispositivo e una per ogni endpoint) possono essere chiamate alla volta. Per ogni metodo di callback, UFX attende fino a quando il driver client chiama UfxDeviceEventComplete per indicare che il driver ha completato la richiesta. L'altro unico metodo di esportazione che UFX ascolta mentre attende queste esportazioni è UfxDeviceNotifyHardwareFailure. Molte funzioni di callback client sono facoltative. Le funzioni obbligatorie sono le seguenti:
- EVT_UFX_DEVICE_DEFAULT_ENDPOINT_ADD
- EVT_UFX_DEVICE_ENDPOINT_ADD
- EVT_UFX_DEVICE_HOST_CONNECT
- EVT_UFX_DEVICE_HOST_DISCONNECT
- EVT_UFX_DEVICE_ADDRESSED
Inizializzazione
- Il driver client del controller di funzione avvia il processo di inizializzazione quando Windows Driver Foundation (WDF) richiama l'implementazione del driver client del EVT_WDF_DRIVER_DEVICE_ADD callback. In tale implementazione, il driver client dovrebbe chiamare UfxFdoInit e quindi creare l'oggetto dispositivo chiamando WdfDeviceCreate.
- Il driver client chiama UfxDeviceCreate per creare l'oggetto dispositivo USB e recuperare l'handle UFXDEVICE.
- Il driver client chiama UfxDeviceNotifyHardwareReady per indicare a UFX che ora può richiamare le funzioni di callback del driver client.
- UFX esegue attività di inizializzazione come:
- UFX chiama l'implementazione EVT_UFX_DEVICE_DEFAULT_ENDPOINT_ADD del driver client per creare l'endpoint predefinito.
- UFX crea oggetti dispositivo fisico figlio (PDO) per le interfacce supportate dal dispositivo.
- UFX attende l'attivazione del driver di classe di dispositivo quando invia la richiesta IOCTL_INTERNAL_USBFN_ACTIVATE_USB_BUS. Attende inoltre che il driver client chiami UfxDeviceNotifyAttach che indica che il dispositivo è stato collegato.
Notifica del driver di classe
Per ricevere una notifica dei pacchetti di installazione e dello stato del bus, un driver di classe deve inviare un IOCTL_INTERNAL_USBFN_ACTIVATE_USB_BUS richieste. UFX accoda queste richieste in code di notifica specifiche per il driver di classe. Quando riceve una notifica relativa a un evento bus dal driver client, UFX viene visualizzato da ogni coda appropriata e completa la richiesta. Per impedire ai driver di classe di ricevere notifiche mancanti, UFX mantiene una coda di notifiche a dimensione fissa per il driver di classe.
Eventi di collegamento e scollegamento del dispositivo
UFX presuppone che il dispositivo venga scollegato fino a quando il driver client del controller di funzione chiama UfxDeviceNotifyAttach.
Dopo questa chiamata, UFX imposta lo stato del dispositivo su Powered come definito nella specifica USB. Per notificare al driver client la modifica dello stato, UFX richiama l'implementazione EVT_UFX_DEVICE_USB_STATE_CHANGE del driver client.
UFX invia una notifica al driver del caricabatterie (Cad.sys) per facilitare la ricarica del dispositivo. UFX notifica anche i driver di classe, completando le richieste IOCTL_INTERNAL_USBFN_BUS_EVENT_NOTIFICATION inviate in precedenza dai driver di classe.
Il driver client deve chiamare UfxDeviceNotifyDetach quando il bus viene scollegato. Il client deve chiamare detach una sola volta dopo ogni chiamata a UfxDeviceNotifyAttach. Dopo la chiamata UfxDeviceNotifyDetach , UFX chiama EVT_UFX_DEVICE_HOST_DISCONNECT (se non si tratta di una modifica dell'interfaccia). UFX procede quindi con tutte le attività di pulizia, ad esempio l'eliminazione di tutte le code degli endpoint e l'avvio della coda di endpoint predefinita. UFX chiama EVT_UFX_DEVICE_USB_STATE_CHANGE e invia una notifica ai driver di classe completando IOCTL_INTERNAL_USBFN_BUS_EVENT_NOTIFICATION richieste.
Errore hardware
Se si verifica un errore hardware, il driver client dovrebbe chiamare UfxDeviceNotifyHardwareFailure. In risposta, UFX smonterà lo stack di dispositivi e potrebbe tentare di eseguire il ripristino da questa situazione chiamando il driver client EVT_UFX_DEVICE_CONTROLLER_RESET. Il client deve reimpostare lo stato iniziale del controller. Se si verifica un altro errore hardware, il client deve chiamare nuovamente UfxDeviceNotifyHardwareFailure. Nella seconda chiamata UFX registrerà lo stato e il controllo dei bug.
Rilevamento delle porte
Il rilevamento delle porte viene eseguito da UFX. Chiama la funzione di callback del driver client del controller di funzione EVT_UFX_DEVICE_PORT_DETECT per determinare il tipo di porta a cui è collegato il dispositivo. Il client risponde chiamando UfxDevicePortDetectComplete o UfxDevicePortDetectCompleteEx con uno dei tipi di porta definiti in USBFN_PORT_TYPE.
Se il client non riesce a determinare il tipo di porta, il client deve segnalare UsbfnUnknownPort. Se la porta è sconosciuta o una porta downstream, UFX chiama la funzione di EVT_UFX_DEVICE_HOST_CONNECT del driver client. UFX ascolta i suoni dell'autobus per qualche tempo. Se la porta è sconosciuta, ma è presente traffico, ad esempio un pacchetto di installazione, UFX assumerà UsbfnStandardDownstreamPort. In caso contrario, UFX assegna la porta a UsbfnInvalidDedicatedChargingPort. Dopo aver determinato un tipo di porta, UFX invia una notifica Cad.sys e chiama la funzione EVT_UFX_DEVICE_PORT_CHANGE del driver client. Nella funzione si prevede che il driver client modifichi lo stato hardware in modo che corrisponda al tipo di porta UFX.
Creazione dell'endpoint
UFX crea l'endpoint predefinito (endpoint 0) chiamando il EVT_UFX_DEVICE_DEFAULT_ENDPOINT_ADD del driver client in modo che possa gestire i pacchetti di installazione inviati dall'host. UFX crea altri endpoint chiamando EVT_UFX_DEVICE_ENDPOINT_ADD. UFX crea l'endpoint solo dopo che il driver client chiama UfxDeviceNotifyHardwareReady. In queste funzioni di callback, il driver client dovrebbe chiamare UfxEndpointCreate all'oggetto endpoint e ottenere il relativo handle UFXENDPOINT. UFX imposta l'elemento padre sul PDO del driver di classe associato all'interfaccia a cui appartiene l'endpoint. L'elemento padre dell'endpoint predefinito è l'oggetto dispositivo USB. Un endpoint contiene due oggetti coda del framework: una coda di trasferimento e una coda di comandi, entrambi accessibili solo quando il dispositivo si trova nello stato Configurato (ad eccezione dell'endpoint 0, accessibile dopo le chiamate UFX EVT_UFX_DEVICE_HOST_CONNECT).
- Richieste della coda dei comandi
- IOCTL_INTERNAL_USBFN_GET_PIPE_STATE
- IOCTL_INTERNAL_USBFN_SET_PIPE_STATE
- IOCTL_INTERNAL_USBFN_DESCRIPTOR_UPDATE
- Trasferire le richieste di accodamento
- IOCTL_INTERNAL_USBFN_TRANSFER_IN
- IOCTL_INTERNAL_USBFN_TRANSFER_IN_APPEND_ZERO_PKT
- IOCTL_INTERNAL_USBFN_TRANSFER_OUT
- IOCTL_INTERNAL_USBFN_CONTROL_STATUS_HANDSHAKE_IN
- IOCTL_INTERNAL_USBFN_CONTROL_STATUS_HANDSHAKE_OUT
Enumerazione dispositivo
Il driver client non deve consentire le connessioni a un host prima che UFX chiami il EVT_UFX_DEVICE_HOST_CONNECT del driver. L'enumerazione del dispositivo inizia quando il driver client chiama UfxDeviceNotifyReset. Nello stato predefinito UFX gestisce i pacchetti di installazione standard.
Reset (Ripristina)
UFX elimina tutte le code degli endpoint e invia una richiesta di IOCTL_INTERNAL_USBFN_DESCRIPTOR_UPDATE al driver client per aggiornare wMaxPacketSize dell'endpoint 0. UFX avvia la coda dell'endpoint predefinito e imposta lo stato su Predefinito.
Impostazione predefinita
UFX chiama la funzione EVT_UFX_DEVICE_USB_STATE_CHANGE del driver client. Notifica anche i driver di classe dello stato. Dopo che UFX riceve il pacchetto di installazione standard SET_ADDRESS, UFX imposta lo stato su Risolto.
Affrontato
UFX chiama la funzione EVT_UFX_DEVICE_ADDRESSED del driver client per indicare al client l'indirizzo da usare. - Se l'indirizzo è 0, UFX imposta nuovamente lo stato su Default e chiama EVT_UFX_DEVICE_USB_STATE_CHANGE e notifica i driver di classe. Quando si riceve il pacchetto di installazione standard di SET_CONFIGURATION, UFX imposta lo stato su Configurato.
Configurato
Se la configurazione selezionata è 0, UFX elimina gli endpoint dell'interfaccia e imposta lo stato su Indirizzato. UFX invia una richiesta di IOCTL_INTERNAL_USBFN_DESCRIPTOR_UPDATE al driver client per aggiornare wMaxPacketSize degli endpoint dell'interfaccia. UFX assicura che tutte le code degli endpoint dell'interfaccia abbiano terminato l'eliminazione e l'avvio delle code degli endpoint dell'interfaccia. Se il tipo di porta non è UsbfnStandardDownstreamPort o UsbfnChargingDownstreamPort, UFX modifica il tipo di porta in UsbfnStandardDownstreamPort e informa Cad.sys; il driver client chiamando EVT_UFX_DEVICE_PORT_CHANGE e EVT_UFX_DEVICE_USB_STATE_CHANGE per aggiornare lo stato; driver di classe dello stato configurato.
Trasferimenti standard di controllo
UFX può gestire i trasferimenti di controllo sull'endpoint predefinito in qualsiasi momento dopo aver chiamato EVT_UFX_DEVICE_DEFAULT_ENDPOINT_ADD, in cui il driver client crea l'endpoint predefinito usando. Tutti i trasferimenti di controllo iniziano con un pacchetto di installazione a 8 byte. Per inviare un pacchetto di installazione all'host, il driver client deve chiamare UfxEndpointNotifySetup. I trasferimenti di controllo standard vengono completati da UFX. Se sono presenti dati associati al trasferimento del controllo, UFX legge e scrive nell'endpoint di controllo predefinito in base alle esigenze.
Trasferimenti di controlli non standard
Se UFX non è in grado di gestire un trasferimento di controllo, il trasferimento viene inoltrato al driver di classe appropriato completando una richiesta di IOCTL_INTERNAL_USBFN_BUS_EVENT_NOTIFICATION . I trasferimenti di controllo possono verificarsi in qualsiasi endpoint definito come endpoint di controllo nel descrittore dell'endpoint. I trasferimenti di controllo sugli endpoint diversi dall'endpoint di controllo predefinito sono sempre trasferimenti di controllo non standard. Se l'endpoint di controllo è l'endpoint di controllo predefinito, UFX informerà i driver di classe dei pacchetti di installazione contrassegnati come richieste di classe per tale driver di classe. Se l'endpoint di controllo appartiene a un'interfaccia, UFX invia una notifica al driver di classe associato a tale interfaccia. Se necessario, i driver di classe sono tenuti a leggere e scrivere nell'endpoint di controllo.
Trasferimenti di dati
I trasferimenti di dati vengono avviati dai driver di classe inviando richieste di IOCTL_INTERNAL_USBFN_TRANSFER_IN, IOCTL_INTERNAL_USBFN_TRANSFER_IN_APPEND_ZERO_PKT o IOCTL_INTERNAL_USBFN_TRANSFER_OUT . Dopo aver convalidato ognuna di queste richieste, UFX lo inoltra alla coda di endpoint appropriata per essere gestita dal driver client. È previsto che il driver client esegua una convalida aggiuntiva. Il driver client riceve le richieste di trasferimento nelle code degli endpoint. Il driver client può recuperare quante più richieste necessarie da questa coda per ottimizzare l'utilizzo del bus. Il driver client deve completare le richieste riuscite con STATUS_SUCCESS. Il driver deve fare del proprio meglio per annullare le richieste e completare le richieste annullate con STATUS_CANCELLED se annullate. Se vengono passati parametri non validi, il driver client completa la richiesta con STATUS_INVALID_PARAMETER.
Controllare i trasferimenti
I trasferimenti di controllo iniziano con un pacchetto di installazione a 8 byte. Per inviare un pacchetto di installazione all'host, il driver client deve chiamare UfxEndpointNotifySetup. UFX notifica i driver di classe dei trasferimenti di controlli non standard completando le richieste di notifica. Sia i client che UFX usano IOCTL_INTERNAL_USBFN_TRANSFER_IN, IOCTL_INTERNAL_USBFN_TRANSFER_IN_APPEND_ZERO_PKT o IOCTL_INTERNAL_USBFN_TRANSFER_OUT per leggere e scrivere nell'endpoint di controllo predefinito. Tuttavia, un'interfaccia può definire altri endpoint di controllo, che possono essere usati solo dal driver di classe corrispondente. Gli endpoint di controllo possono essere bloccati in risposta a un pacchetto di installazione. I driver di classe inviano la richiesta IOCTL_INTERNAL_USBFN_SET_PIPE_STATE per sospendere l'endpoint. È previsto che l'hardware o il driver client riprenda immediatamente il traffico sull'endpoint dopo che è stato inviato lo stallo. Gli endpoint di controllo possono anche inviare e ricevere pacchetti di lunghezza zero (ZLP) senza dati precedenti. Il driver client e UFX possono eseguire questa operazione usando IOCTL_INTERNAL_USBFN_CONTROL_STATUS_HANDSHAKE_IN e IOCTL_INTERNAL_USBFN_CONTROL_STATUS_HANDSHAKE_OUT.
Trasferimenti in blocco e interrupt
I trasferimenti in blocco garantiscono il recapito dei dati e vengono usati per inviare grandi quantità di dati. I trasferimenti possono essere inviati in un endpoint in blocco usando IOCTL_INTERNAL_USBFN_TRANSFER_IN, IOCTL_INTERNAL_USBFN_TRANSFER_IN_APPEND_ZERO_PKT o IOCTL_INTERNAL_USBFN_TRANSFER_OUT. Gli endpoint in blocco possono essere bloccati in modo analogo agli endpoint di controllo tramite IOCTL_INTERNAL_USBFN_SET_PIPE_STATE. Il driver client deve inviare un pacchetto STALL in risposta a tutte le richieste host e contenere le richieste IOCTL. A differenza degli endpoint di controllo, un endpoint bulk rimane bloccato fino a quando lo stato di stallo non viene cancellato in modo esplicito.
I trasferimenti di interrupt interrompono i trasferimenti sono come i trasferimenti in blocco, ma hanno una latenza garantita. I trasferimenti di interrupt hanno la stessa interfaccia dei trasferimenti in blocco, ma non dispongono di funzionalità di streaming.
Trasferimenti isocroni
Il driver client non deve supportare trasferimenti isocroni in questa versione.
Risparmio energia
Il driver client gestisce tutti gli aspetti della gestione dell'alimentazione. Poiché le funzioni di callback sono asincrone, il driver client dovrebbe tornare a uno stato di alimentazione appropriato e completare la richiesta prima di chiamare la funzione di esportazione completa dell'evento appropriata, ad esempio UfxDeviceEventComplete.
UFX è in uno stato Working se lo stato del dispositivo (definito in USBFN_DEVICE_STATE) è UsbfnDeviceStateSuspended e UsbfnDeviceStateAttached e non ha segnalato un tipo di porta. In alternativa, UFX ha segnalato il tipo di porta (definito in USBFN_PORT_TYPE) UsbfnStandardDownstreamPort o UsbfnChargingDownstreamPort.
UFX entra ed esce da uno stato working chiamando EVT_UFX_DEVICE_USB_STATE_CHANGE o implementazioni di EVT_UFX_DEVICE_PORT_CHANGE . La transizione da o verso uno stato Working viene completata quando il driver client chiama UfxDeviceEventComplete.
In uno stato di funzionamento, UFX può chiamare qualsiasi callback. Anche se non nello stato Working, UFX chiama solo EVT_UFX_DEVICE_USB_STATE_CHANGE per entrare in uno stato di lavoro; EVT_UFX_DEVICE_REMOTE_WAKEUP_SIGNAL eseguire una riattivazione remota durante la sospensione (se supportato).
Sospensione del dispositivo
La sospensione del dispositivo si verifica quando non è presente traffico sul bus per 3 millisecondi. In questo caso, il driver client deve informare UFX quando rileva la sospensione e la ripresa chiamando UfxDeviceNotifySuspend e UfxDeviceNotifyResume. Quando ricevono tali chiamate, UFX chiama EVT_UFX_DEVICE_USB_STATE_CHANGE e notifica i driver di classe completando IOCTL_INTERNAL_USBFN_BUS_EVENT_NOTIFICATION richieste. Se la riattivazione remota è supportata dal dispositivo e abilitata dall'host, UFX può chiamare le chiamate EVT_UFX_DEVICE_USB_STATE_CHANGE mentre è sospesa per emettere un segnale di riattivazione remota.