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.
In questo argomento vengono descritti i passaggi per l'emissione di una richiesta di interfaccia select per attivare un'impostazione alternativa in un'interfaccia USB. Il driver client deve emettere questa richiesta dopo aver selezionato una configurazione USB. Se si seleziona una configurazione, per impostazione predefinita, viene attivata anche la prima impostazione alternativa in ogni interfaccia di tale configurazione.
Ogni configurazione USB deve supportare una o più interfacce USB. Ogni interfaccia espone uno o più endpoint usati per trasferire i dati da e verso il dispositivo. Le interfacce USB devono avere un indice di interfaccia definito dal dispositivo usato per identificare l'interfaccia. L'interfaccia deve avere anche una o più impostazioni alternative che raggruppano gli endpoint dell'interfaccia. Come parte della configurazione del dispositivo, il driver client deve selezionare una delle impostazioni alternative nell'interfaccia. Poiché gli endpoint possono essere condivisi tra impostazioni alternative, solo un'impostazione può essere attiva in un determinato momento. Dopo che l'impostazione alternativa è attiva, gli endpoint diventano disponibili per i trasferimenti di dati.
Per un dispositivo a più interfacce, due interfacce possono essere attive in un determinato momento. Il driver client deve attivare un'impostazione alternativa in ogni interfaccia. Gli endpoint non vengono condivisi tra interfacce e pertanto ogni trasferimento di dati simultaneo può essere eseguito su ogni interfaccia.
Le impostazioni alternative sono definite dal dispositivo e identificate con un numero denominato indice di impostazione. L'impostazione alternativa in corrispondenza dell'indice 0 è denominata impostazione alternativa predefinita in questo set di documentazione. Un'impostazione alternativa è descritta in una struttura USB_INTERFACE_DESCRIPTOR . La struttura contiene l'indice dell'interfaccia a cui è associata l'impostazione e il numero di endpoint definiti dall'impostazione. Contiene anche informazioni sulla specifica della classe a cui è conforme la funzionalità dell'interfaccia. Il modo in cui gli endpoint sono raggruppati dipende dalla funzionalità del dispositivo.
Ad esempio, un'interfaccia espone due endpoint isocroni e due endpoint bulk tramite tre impostazioni alternative (indice 0, 1, 2). L'impostazione alternativa 0 non definisce alcun endpoint; L'impostazione alternativa 1 definisce gli endpoint in blocco; L'impostazione alternativa 2 definisce gli endpoint isocroni. Poiché l'impostazione alternativa 0 non ha alcun endpoint, il driver client può selezionare questa impostazione per disabilitare il trasferimento dei dati per risparmiare larghezza di banda. Quando una delle altre impostazioni è attiva, il dispositivo è pronto per i trasferimenti di dati. L'impostazione alternativa 1 può essere usata per trasferire i dati in blocco. È possibile selezionare l'impostazione alternativa 2 quando il dispositivo è in modalità di streaming. Pertanto, le impostazioni alternative offrono al driver client la flessibilità di modificare la configurazione del dispositivo come e quando necessario. In questo esempio, il driver client può cambiare la funzionalità del dispositivo da un trasferimento in blocco allo streaming, semplicemente selezionando un'impostazione alternativa.
È anche possibile usare impostazioni alternative per impostare i requisiti di larghezza di banda. Per un esempio, vedi Layout dispositivo USB.
Windows Driver Foundation (WDF) fornisce metodi in Kernel-Mode Driver Framework e User-Mode Driver Framework che il driver client può chiamare per selezionare un'impostazione alternativa diversa. Il driver client KMDF può selezionare un'impostazione specificando l'indice di impostazione, il descrittore dell'interfaccia dell'impostazione o inviando un'istruzione ODBC contenente la richiesta. Il driver client UMDF può selezionare solo un'impostazione alternativa specificandone l'indice di impostazione.
Al termine di una richiesta di selezione della configurazione completata con successo, l'impostazione alternativa precedentemente attiva viene disattivata.
Cosa è necessario sapere
Questo articolo usa i framework seguenti:
Prima di iniziare
Prima che il driver client possa selezionare un'impostazione alternativa, assicurarsi che siano soddisfatti questi requisiti:
Il driver client deve aver creato l'oggetto dispositivo di destinazione USB del framework.
Un driver client KMDF deve ottenere un handle WDFUSBDEVICE chiamando il metodo WdfUsbTargetDeviceCreateWithParameters. Per ulteriori informazioni, vedere "Codice sorgente del dispositivo" in Informazioni sulla struttura del codice del driver client USB (KMDF).
Un driver client UMDF deve ottenere un puntatore IWDFUsbTargetDevice attraverso una query sull'oggetto dispositivo di destinazione del framework. Per altre informazioni, vedere "Implementazione IPnpCallbackHardware e attività specifiche dell'USB" in Informazioni sulla struttura del codice del driver client USB (UMDF)
Se si usano i modelli USB forniti con Microsoft Visual Studio Professional 2012, il codice del modello esegue tali attività. Il codice del modello ottiene l'handle per l'oggetto dispositivo di destinazione e lo archivia nel contesto del dispositivo.
Il dispositivo deve avere una configurazione attiva.
Un driver client KMDF deve chiamare il metodo WdfUsbTargetDeviceSelectConfig.
Per un driver client UMDF, il framework seleziona la prima configurazione e l'impostazione alternativa predefinita per ogni interfaccia in tale configurazione.
Se si usano modelli USB, il codice seleziona la prima configurazione e l'impostazione alternativa predefinita in ogni interfaccia.
Selezionare un'impostazione alternativa in un driver client KMDF
Ottenere un handle WDFUSBINTERFACE per l'interfaccia che ha l'impostazione alternativa.
Per ottenere l'handle, ottenere prima di tutto il numero di interfacce della configurazione selezionata chiamando WdfUsbTargetDeviceGetNumInterfaces e quindi enumerando le interfacce in un ciclo. In ogni iterazione chiamare il metodo WdfUsbTargetDeviceGetInterface e incrementare l'indice (a partire da zero).
Nota Durante l'enumerazione del dispositivo, lo stack di driver USB assegna numeri alle impostazioni alternative. I numeri di interfaccia sono in base zero e sequenziale. Questi numeri potrebbero essere diversi dall'indice delle impostazioni definite dal dispositivo. Per ottenere l'indice delle impostazioni definite dal dispositivo, chiamare il metodo WdfUsbInterfaceGetInterfaceNumber .
Avviare una richiesta di interfaccia select chiamando il metodo WdfUsbInterfaceSelectSetting . Nel parametro Params della chiamata scegliere una delle opzioni seguenti:
Specificare il numero di impostazione alternativo assegnato dallo stack di driver USB. In genere, si passa lo stesso indice usato nel passaggio 1 per enumerare le impostazioni.
Specificare un puntatore al descrittore di interfaccia che descrive l'impostazione alternativa. Il driver può quindi ottenere descrittori di interfaccia durante l'enumerazione di impostazioni alternative nell'interfaccia chiamando il metodo WdfUsbInterfaceGetDescriptor . Al termine dell'enumerazione, il driver ottiene informazioni su tutte le impostazioni alternative enumerate nella struttura USB_INTERFACE_DESCRIPTOR .
Specificare un puntatore a un URB che contiene tutte le informazioni necessarie per la richiesta select-interface.
- Allocare una matrice di strutture USBD_INTERFACE_LIST_ENTRY . Il numero di elementi in questa matrice dipende dal numero di interfacce nella configurazione selezionata. Per informazioni sull'inizializzazione di questo array, vedere How to Select a Configuration for a USB Device.
- Allocare un URB per la richiesta di interfaccia selezionata chiamando la routine USBD_SelectInterfaceUrbAllocateAndBuild. In questa chiamata specificare l'array dell'elenco di interfacce e l'handle di configurazione ottenuto a seguito di aver selezionato una configurazione. È possibile ottenere tale handle chiamando il metodo WdfUsbTargetDeviceWdmGetConfigurationHandle .
- Chiamare WdfUsbInterfaceSelectSetting e specificare l'URB.
**Driver WDM:** Per inviare l'URB, associare l'URB a un IRP e inviare l'IRP allo stack di driver USB. Per ulteriori informazioni, vedere How to Submit an URB.
Le opzioni nell'elenco offrono al driver client la flessibilità necessaria per specificare i criteri di selezione. Se si è già a conoscenza delle funzionalità dell'endpoint dell'impostazione alternativa, scegliere la prima opzione (con il numero dell'impostazione alternativa) nell'elenco. In caso contrario, scegliere la seconda opzione che specifica il descrittore di interfaccia. Esaminare USB_INTERFACE_DESCRIPTOR strutture per tutte le impostazioni alternative. Per ogni impostazione, enumerare gli endpoint e le relative caratteristiche, ad esempio il tipo di endpoint, le dimensioni massime dei pacchetti e così via. Quando si trova il set di endpoint necessari per i trasferimenti di dati, chiamare WdfUsbInterfaceSelectSetting specificando un puntatore a tale descrittore di interfaccia. In genere, non sarà necessaria la terza opzione a meno che non siate un driver client basato su WDM che può inviare richieste solo allo stack di driver USB mediante la sottomissione di URB.
In base alle informazioni fornite dal driver client, lo stack di driver USB compila quindi una richiesta di controllo standard (SET INTERFACE) e la invia al dispositivo. Se la richiesta viene completata correttamente, lo stack di driver USB acquisisce gli handle delle pipe agli endpoint dell'impostazione alternativa.
Dopo aver selezionato un'impostazione alternativa, il driver client deve sempre ottenere gli handle di pipe per gli endpoint nella nuova impostazione. Il mancato rispetto di ciò potrebbe causare al driver l'invio di richieste di trasferimento dati utilizzando handle di pipe obsoleti. Per informazioni sul recupero di handle pipe, vedere Come enumerare le pipe USB.
NTSTATUS FX3SelectInterfaceSetting(
_In_ WDFDEVICE Device,
_In_ UCHAR SettingIndex)
{
NTSTATUS status;
PDEVICE_CONTEXT pDeviceContext;
WDF_OBJECT_ATTRIBUTES pipeAttributes;
WDF_USB_INTERFACE_SELECT_SETTING_PARAMS settingParams;
PAGED_CODE();
pDeviceContext = GetDeviceContext(Device);
if (pDeviceContext->UsbInterface == NULL)
{
status = USBD_STATUS_BAD_NUMBER_OF_INTERFACES;
goto Exit;
}
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&pipeAttributes, PIPE_CONTEXT);
pipeAttributes.EvtCleanupCallback = FX3EvtPipeContextCleanup;
WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING (&settingParams, SettingIndex);
status = WdfUsbInterfaceSelectSetting (
pDeviceContext->UsbInterface,
&pipeAttributes,
&settingParams);
if (status != STATUS_SUCCESS)
{
goto Exit;
}
if (WdfUsbInterfaceGetNumConfiguredPipes (pDeviceContext->UsbInterface) > 0)
{
status = FX3EnumeratePipes (Device);
if (status != STATUS_SUCCESS)
{
goto Exit;
}
}
Exit:
return status;
}
Selezionare un'impostazione alternativa in un driver client UMDF
Ottenere il numero di interfacce USB supportate dalla configurazione attiva chiamando il metodo IWDFUsbTargetDevice::GetNumInterfaces .
Ottieni un puntatore IWDFUsbInterface per ogni interfaccia nella configurazione.
Enumerare tutte le interfacce chiamando il metodo IWDFUsbTargetDevice::RetrieveUsbInterface in un ciclo fino a quando la funzione non restituisce NULL. Con ogni iterazione, incrementare l'indice del membro a partire da zero. Il ciclo recupera i puntatori IWDFUsbInterface a tutte le interfacce enumerate.
Per ogni interfaccia, ottenere l'handle WinUSB chiamando IWDFUsbInterface::GetWinUsbHandle. Questo handle è richiesto dal passaggio successivo.
Chiamare WinUsb_GetAssociatedInterface per ottenere un handle all'interfaccia. Nel parametro AssociatedInterfaceIndex specificare l'indice nel passaggio 2.
Determinare il numero di impostazioni alternative nell'interfaccia.
Chiamare la funzione WinUsb_QueryInterfaceSettings in un ciclo e incrementare l'indice (in base zero) in ogni iterazione. Quando vengono enumerate tutte le impostazioni, la funzione restituisce ERROR_NO_MORE_ITEMS. La funzione restituisce anche descrittori di interfaccia per ogni impostazione.
Usando il valore ricevuto nel membro bNumEndpoints di ogni descrittore di interfaccia ed enumerare i relativi endpoint. Esaminare i descrittori di endpoint e determinare quale impostazione soddisfa le esigenze.
Avviare una richiesta di interfaccia selezionata chiamando la funzione WinUsb_SetCurrentAlternateSetting. Nella chiamata specificare il numero di impostazione alternativo associato all'indice nel passaggio 4.
Rilasciare l'handle di interfaccia ottenuto nel passaggio 4 chiamando la funzione WinUsb_Free .
Rilasciare l'handle WinUSB ottenuto nel passaggio 3 chiamando la funzione WinUsb_Free .
Se si finisce di usare i metodi IWDFUsbInterface , rilasciare tutti i puntatori di interfaccia recuperati nel passaggio 2.
Osservazioni:
Per un driver client KMDF, nella sua chiamata WdfUsbInterfaceSelectSetting, il driver può fornire un puntatore a un contesto di pipe definito dallo stesso driver. Il driver client può archiviare informazioni sulle pipe nel contesto della pipe. Per ulteriori informazioni sulle pipe USB, vedere Come enumerare le pipe USB.