Avvio di un dispositivo in un driver di funzione
Un driver di funzione imposta una routine IoCompletion , passa una richiesta di IRP_MN_START_DEVICE nello stack di dispositivi e rimanda le operazioni di avvio fino a quando tutti i driver inferiori non sono stati completati con l'IRP. Per informazioni dettagliate sull'uso di un evento kernel e una routine IoCompletion per rinviare l'elaborazione IRP, vedere Postponing PnP IRP Processing (Postponing PnP IRP Processing Until Lower Drivers Finish) per informazioni dettagliate sull'uso di un evento kernel e una routine IoCompletion per rinviare l'elaborazione di IRP.
Quando la routine DispatchPnP recupera il controllo dopo che tutti i driver inferiori sono stati completati con l'IRP, il driver di funzione esegue le sue attività per avviare il dispositivo. Un driver di funzione avvia il dispositivo con una procedura simile alla seguente:
Se un driver inferiore ha avuto esito negativo sull'IRP (IoCallDriver ha restituito un errore), non continuare a elaborare l'IRP. Eseguire qualsiasi pulizia necessaria e tornare dalla routine DispatchPnP (passare all'ultimo passaggio in questo elenco).
Se i driver inferiori hanno elaborato correttamente l'IRP, avviare il dispositivo.
I passaggi esatti per avviare un dispositivo variano da dispositivo a dispositivo. Tali passaggi possono includere il mapping dello spazio di I/O, l'inizializzazione dei registri hardware, l'impostazione del dispositivo nello stato di alimentazione D0 e la connessione dell'interruzione con IoConnectInterrupt. Se il driver viene riavviato un dispositivo dopo una richiesta di IRP_MN_STOP_DEVICE , il driver potrebbe avere lo stato del dispositivo da ripristinare.
Il dispositivo deve essere attivato prima che tutti i driver possano accedervi. Per altre informazioni, vedere Alimentazione di un dispositivo .
Se il dispositivo deve essere abilitato per la riattivazione, il proprietario dei criteri di alimentazione (in genere il driver di funzione) deve inviare un'IRP di attesa/riattivazione dopo aver attivato il dispositivo e prima di completare la richiesta di IRP_MN_START_DEVICE . Per informazioni dettagliate, vedere Invio di un'IRP di attesa/riattivazione.
Avviare irP nella coda di archiviazione di IRP.
Cancellare il flag di HOLD_NEW_REQUESTS definito dal driver e avviare gli indirizzi IP nella coda di gestione indirizzi IP. I driver devono eseguire questa operazione quando si avvia un dispositivo per la prima volta e quando si riavvia un dispositivo dopo un'interruzione di query o arrestare LRP. Per altre informazioni, vedere La conservazione di IRP in ingresso quando un dispositivo viene sospeso .
[Facoltativo] Abilitare le interfacce per il dispositivo chiamando IoSetDeviceInterfaceState.
Abilitare le interfacce, se presenti, che il driver registrato in precedenza nella routine AddDevice (o in un inF o in un altro componente, ad esempio un co-programma di installazione).
In Windows 2000 e versioni successive di Windows, il gestore PnP non invia notifica agli arrivi dell'interfaccia dispositivo fino al completamento dell'IRP_MN_START_DEVICE IRP, che indica che tutti i driver per il dispositivo hanno completato le operazioni di avvio. Il gestore PnP non riesce anche a creare richieste che arrivano prima che tutti i driver per il dispositivo completino l'IRP di avvio.
Completare l'IRP.
La routine IoCompletion del driver di funzione ha restituito STATUS_MORE_PROCESSING_REQUIRED, come descritto in Postponing PnP IRP Processing Until Lower Driver Finish, quindi la routine DispatchPnP del driver di funzione deve chiamare IoCompleteRequest per riprendere l'elaborazione del completamento di I/O.
Se le operazioni di avvio del driver di funzione hanno avuto esito positivo, il driver imposta Irp-IoStatus.Status> su STATUS_SUCCESS, chiama IoCompleteRequest con una priorità di IO_NO_INCREMENT e restituisce STATUS_SUCCESS dalla routine DispatchPnP.
Se il driver di funzione riscontra un errore durante le operazioni di avvio, il driver imposta uno stato di errore nell'IRP, chiama IoCompleteRequest con IO_NO_INCREMENT e restituisce l'errore dalla routine DispatchPnP .
Se un driver inferiore ha avuto esito negativo sull'IRP (IoCallDriver ha restituito un errore), il driver di funzione chiama IoCompleteRequest con IO_NO_INCREMENT e restituisce l'errore IoCallDriver dalla routine DispatchPnP . Il driver di funzione non imposta Irp-IoStatus.Status> in questo caso perché lo stato è già stato impostato dal driver inferiore che ha avuto esito negativo sull'IRP.
Quando un driver di funzione riceve una richiesta di IRP_MN_START_DEVICE, deve esaminare le strutture in IrpSp-Parameters.StartDevice.AllocateResources> e IrpSp-Parameters.StartDevice.AllocateResourcesTranslated>, che descrivono rispettivamente le risorse non elaborate e tradotte, che il gestore PnP ha assegnato al dispositivo. I driver devono salvare una copia di ogni elenco di risorse nell'estensione del dispositivo come supporto per il debug.
Gli elenchi di risorse sono associati CM_RESOURCE_LIST strutture, in cui ogni elemento dell'elenco non elaborato corrisponde allo stesso elemento dell'elenco tradotto. Ad esempio, se AllocateResources.List[0] descrive un intervallo di porte I/O non elaborato, allocatoResourcesTranslated.List[0] descrive lo stesso intervallo dopo la traduzione. Ogni risorsa tradotta include un indirizzo fisico e il tipo della risorsa.
Se viene assegnato un driver a una risorsa di memoria tradotta (CmResourceTypeMemory), deve chiamare MmMapIoSpace per eseguire il mapping dell'indirizzo fisico in un indirizzo virtuale tramite il quale può accedere ai registri dei dispositivi. Affinché un driver funzioni in modo indipendente dalla piattaforma, deve controllare ogni risorsa restituita, tradotta e mapparla, se necessario.
Un driver di funzione deve eseguire le operazioni seguenti in risposta a un IRP_MN_START_DEVICE per garantire l'accesso a tutte le risorse del dispositivo:
Copiare IrpSp-Parameters.StartDevice.AllocateResources> nell'estensione del dispositivo.
Copiare IrpSp-Parameters.StartDevice.AllocateResourcesTranslated> nell'estensione del dispositivo.
In un ciclo esaminare ogni elemento descrittore in AllocateResourcesTranslated. Se il tipo di risorsa descrittore è CmResourceTypeMemory, chiamare MmMapIoSpace, passando l'indirizzo fisico e la lunghezza della risorsa tradotta.
Quando il driver riceve un IRP_MN_STOP_DEVICE, IRP_MN_REMOVE_DEVICEo IRP_MN_SURPRISE_REMOVAL richiesta, deve rilasciare i mapping chiamando MmUnmapIoSpace in un ciclo simile. Il driver deve anche chiamare MmUnmapIoSpace se deve non riuscire la richiesta di IRP_MN_START_DEVICE .
Per altre informazioni, vedere Mapping di indirizzi Bus-Relative a indirizzi virtuali .