Uso delle pipe USB
Il framework rappresenta ogni pipe in un'interfaccia USB come oggetto pipe USB del framework. Quando un driver configura un dispositivo USB, il framework crea un oggetto pipe USB framework per ogni pipe in ogni interfaccia selezionata. I metodi dell'oggetto pipe consentono a un driver di eseguire le operazioni seguenti:
Recupero delle informazioni sulla pipe
Dopo aver chiamato WdfUsbInterfaceGetConfiguredPipe per ottenere un handle a un oggetto pipe USB del framework, il driver può chiamare i metodi seguenti definiti dall'oggetto pipe USB per ottenere informazioni sulla pipe USB:
WdfUsbTargetPipeGetIoTarget
Restituisce un handle all'oggetto di destinazione di I/O associato a una pipe USB. Il driver può passare questo handle a WdfRequestSend.
WdfUsbTargetPipeGetInformation
Recupera informazioni su una pipe USB e il relativo endpoint.
WdfUsbTargetPipeGetType
Restituisce il tipo di una pipe USB.
WdfUsbTargetPipeIsInEndpoint
Determina se una pipe USB è connessa a un endpoint di input.
WdfUsbTargetPipeIsOutEndpoint
Determina se una pipe USB è connessa a un endpoint di output.
WDF_USB_PIPE_DIRECTION_IN
Determina se un endpoint USB è un endpoint di input.
WDF_USB_PIPE_DIRECTION_OUT
Determina se un endpoint USB è un endpoint di output.
Per informazioni correlate, vedere Come enumerare pipe USB.
Lettura da una pipe
Per leggere i dati da una pipe di input USB, il driver può usare qualsiasi (o tutte) delle tre tecniche seguenti:
Leggere i dati in modo sincrono
Per leggere i dati in modo sincrono da una pipe di input USB, il driver può chiamare il metodo WdfUsbTargetPipeReadSynchronously . Questo metodo compila e invia una richiesta di lettura e restituisce dopo il completamento dell'operazione di I/O.
Leggere i dati in modo asincrono
Per leggere i dati in modo asincrono da una pipe di input USB, il driver può chiamare il metodo WdfUsbTargetPipeFormatRequestForRead per compilare una richiesta di lettura. Il driver può quindi chiamare WdfRequestSend per inviare la richiesta in modo asincrono (o in modo sincrono).
Leggere i dati in modo asincrono e continuo
Un lettore continuo è un meccanismo fornito dal framework per garantire che una richiesta di lettura sia sempre disponibile per una pipe USB. Questo meccanismo garantisce che il driver sia sempre pronto a ricevere dati da un dispositivo che fornisce un flusso di input asincrono e non richiesto. Ad esempio, un driver per una scheda di interfaccia di rete (NIC) può usare un lettore continuo per ricevere i dati di input.
Per configurare un lettore continuo per una pipe di input, la funzione di callback EvtDevicePrepareHardware del driver deve chiamare il metodo WdfUsbTargetPipeConfigContinuousReader . Questo metodo accoda un set di richieste di lettura alla destinazione di I/O del dispositivo.
Inoltre, la funzione di callback EvtDeviceD0Entry del driver deve chiamare WdfIoTargetStart per avviare il lettore continuo e la funzione di callback EvtDeviceD0Exit del driver deve chiamare WdfIoTargetStop per arrestare il lettore continuo.
Ogni volta che i dati sono disponibili dal dispositivo, la destinazione di I/O completerà una richiesta di lettura e il framework chiamerà una delle due funzioni di callback : EvtUsbTargetPipeReadComplete, se la destinazione di I/O legge correttamente i dati o EvtUsbTargetPipeReadersFailed, se la destinazione di I/O segnala un errore.
Se non si specifica il callback EvtUsbTargetPipeReadersFailed facoltativo, il framework risponde a un tentativo di lettura non riuscito inviando un'altra richiesta di lettura. Pertanto, se il bus è in uno stato in cui non accetta letture, il framework invia continuamente nuove richieste per il ripristino da una lettura non riuscita.
Dopo che un driver ha chiamato WdfUsbTargetPipeConfigContinuousReader, il driver non può usare WdfUsbTargetPipeReadSynchronously o WdfRequestSend per inviare richieste di I/O alla pipe a meno che la funzione di callback EvtUsbTargetPipeReadersFailed del driver non venga chiamata e restituisce FALSE.
Per impostazione predefinita, il framework segnala un errore se il driver specifica un buffer di lettura che non è un multiplo delle dimensioni massime del pacchetto della pipe. Il driver può chiamare WdfUsbTargetPipeSetNoMaximumPacketSizeCheck per disabilitare questo test delle dimensioni del buffer di lettura.
Per informazioni correlate, vedere:
- Come inviare richieste di trasferimento bulk USB
- Come trasferire i dati agli endpoint isocroni USB
- Come usare il lettore continuo per la lettura dei dati da una pipe USB
Scrittura in una pipe
Per scrivere dati in una pipe di output USB, il driver può usare una o entrambe le tecniche seguenti:
Scrivere i dati in modo sincrono
Per scrivere i dati in modo sincrono in una pipe di output USB, il driver può chiamare il metodo WdfUsbTargetPipeWriteSynchronously . Questo metodo compila e invia una richiesta di scrittura e restituisce dopo il completamento dell'operazione di I/O.
Scrivere dati in modo asincrono
Per scrivere dati in modo asincrono in una pipe di input USB, il driver può chiamare il metodo WdfUsbTargetPipeFormatRequestForWrite per compilare una richiesta di scrittura. Il driver può quindi chiamare WdfRequestSend per inviare la richiesta in modo asincrono.
Per informazioni correlate, vedere Come inviare richieste di trasferimento bulk USB.
Arresto e reimpostazione di una pipe
Il driver può chiamare i metodi seguenti per arrestare o reimpostare una pipe USB:
WdfUsbTargetPipeAbortSynchronously
Invia in modo sincrono una richiesta per arrestare una pipe USB.
WdfUsbTargetPipeFormatRequestForAbort
Formatta una richiesta per arrestare una pipe USB. Il driver può chiamare WdfRequestSend per inviare la richiesta in modo sincrono o asincrono.
WdfUsbTargetPipeResetSynchronously
Invia in modo sincrono una richiesta per reimpostare una pipe USB.
WdfUsbTargetPipeFormatRequestForReset
Formatta una richiesta per reimpostare una pipe USB. Il driver deve chiamare WdfRequestSend per inviare la richiesta in modo sincrono o asincrono.
Se la destinazione USB del driver completa una richiesta di I/O con un valore di stato di errore, il driver deve eseguire le operazioni seguenti:
Arrestare la pipe e annullare eventuali richieste di I/O aggiuntive inviate dal driver alla destinazione USB, se la destinazione non ha completato le richieste.
Chiamare WdfIoTargetStop con il flag WdfIoTargetCancelSentIo impostato.
Inviare in modo sincrono una richiesta di interruzione alla pipe.
Chiamare WdfUsbTargetPipeAbortSynchronously o chiamare WdfUsbTargetPipeFormatRequestForAbort seguito da WdfRequestSend con il flag WDF_REQUEST_SEND_OPTION_SYNCHRONOUS impostato.
Inviare in modo sincrono una richiesta di reimpostazione alla pipe.
Chiamare WdfUsbTargetPipeResetSynchronously o chiamare WdfUsbTargetPipeFormatRequestForReset seguito da WdfRequestSend con il flag WDF_REQUEST_SEND_OPTION_SYNCHRONOUS impostato.
Riavviare la pipe.
Chiamare WdfIoTargetStart.
Inviare nuovamente la richiesta di I/O non riuscita e tutte le richieste di I/O che hanno seguito la richiesta non riuscita.
Dopo un numero significativo di errori multipli, il driver deve tentare di reimpostare la porta USB eseguendo le operazioni seguenti:
Arrestare tutte le pipe attive e annullare eventuali richieste di I/O aggiuntive inviate dal driver alla destinazione USB di ogni pipe, se la destinazione non li ha completati.
Per ogni pipe attiva, chiamare WdfIoTargetStop con il set di flag WdfIoTargetCancelSentIo .
Inviare in modo sincrono una richiesta per reimpostare la porta USB.
Chiamare WdfUsbTargetDeviceResetPortSynchronously.
Riavviare i pipe.
Chiamare WdfIoTargetStart per ogni pipe arrestata dal driver.
Eseguire nuovamente l'ultima richiesta di I/O non riuscita e tutte le richieste di I/O che hanno seguito la richiesta non riuscita.
Per informazioni correlate, vedere Come recuperare dagli errori della pipe USB.
Invio di UN'ISTANZA a una pipe
Se il driver KMDF comunica con una pipe USB inviando richieste di I/O contenenti URL, il driver può chiamare i metodi seguenti:
WdfUsbTargetPipeSendUrbSynchronously (solo KMDF)
Invia in modo sincrono una richiesta di I/O che contiene UN'istanza di URB.
WdfUsbTargetPipeFormatRequestForUrb (solo KMDF)
Formatta una richiesta di I/O che contiene UN'istanza DI. Il driver può chiamare WdfRequestSend per inviare la richiesta in modo sincrono o asincrono.
WdfUsbTargetPipeWdmGetPipeHandle (solo KMDF)
Restituisce l'handle della pipe USBD di un dispositivo. Alcuni URL richiedono questo handle.