Gestione delle sequenze di Client-Implemented
Le funzioni di callback degli eventi EvtSpbControllerLock e EvtSpbControllerUnlock eseguono operazioni complementari. La funzione EvtSpbControllerLock è un gestore per le richieste di IOCTL_SPB_LOCK_CONTROLLER . La funzione EvtSpbControllerUnlock è un gestore per le richieste di IOCTL_SPB_UNLOCK_CONTROLLER . Un client ,ovvero il driver per un dispositivo periferico nel bus, invia queste richieste per avviare e terminare le sequenze di trasferimento di I/O. La maggior parte dei driver del controller SPB non supporta IOCTL_SPB_LOCK_CONTROLLERe IOCTL_SPB_UNLOCK_CONTROLLER richieste e, pertanto, non implementare le funzioni EvtSpbControllerLock e EvtSpbControllerUnlock.
Un client può eseguire una sequenza di trasferimento di I/O come una serie di richieste di trasferimento semplici, ovvero IRP_MJ_READ e richieste di IRP_MJ_WRITE . Il primo trasferimento nella sequenza deve essere preceduto da una richiesta di IOCTL_SPB_LOCK_CONTROLLER : questa richiesta indica al driver del controller SPB di bloccare il bus per la durata della sequenza di trasferimento di I/O. L'ultimo trasferimento deve essere seguito da una richiesta di IOCTL_SPB_UNLOCK_CONTROLLER , che indica al conducente di sbloccare il bus. Questo tipo di sequenza di trasferimento di I/O viene chiamata sequenza implementata dal client per distinguerla da una sequenza di richieste singole, che usa una richiesta di IOCTL_SPB_EXECUTE_SEQUENCE anziché IOCTL_SPB_LOCK_CONTROLLER e richieste di IOCTL_SPB_UNLOCK_CONTROLLER .
Mentre il driver per un dispositivo periferico contiene un blocco sul bus, il controller del bus consente l'accesso a nessun altro dispositivo periferico sul bus. I dettagli dell'operazione di blocco del bus dipendono dal tipo di bus. Per un controller I2C, una modifica nella direzione di trasferimento (una lettura seguita da una scrittura o viceversa) richiede un'operazione di riavvio I2C. Per un controller SPI, il chip-select nel dispositivo di destinazione deve rimanere asserzionato mentre il blocco del controller rimane effettivo. Per altre informazioni, vedere Operazioni del bus atomico.
Il supporto per le sequenze di trasferimento implementate dal client è facoltativo. Il driver del controller SPB deve richiedere di supportarli solo se il controller può eseguire le operazioni seguenti:
- Bloccare il bus per la durata della sequenza implementata dal client.
- Sbloccare il bus in qualsiasi momento. Ad esempio, se si verifica una richiesta di sblocco tra i trasferimenti di byte, il controller deve essere in grado di sbloccare il bus senza attendere il trasferimento di byte successivo sul bus.
Mentre il bus è bloccato, il client può inviare una sequenza arbitraria di richieste di trasferimento semplici. Vale a dire, la sequenza può essere di lunghezza arbitraria e può essere qualsiasi combinazione di letture e scritture.
Per indicare il supporto per le sequenze implementate dal client, un driver del controller SPB implementa una funzione EvtSpbControllerUnlock . Se il driver implementa questa funzione, l'estensione del framework SPB (SpbCx) accetta IOCTL_SPB_LOCK_CONTROLLER e IOCTL_SPB_UNLOCK_CONTROLLER richieste dai client. In caso contrario, SpbCx non riesce queste richieste completandole con il codice di stato STATUS_NOT_SUPPORTED.
Un driver del controller SPB che implementa una funzione EvtSpbControllerUnlock non è necessaria per implementare una funzione EvtSpbControllerLock . Tuttavia, un driver del controller SPB che implementa una funzione EvtSpbControllerLock deve anche implementare una funzione EvtSpbControllerUnlock.
Se il driver implementa una funzione EvtSpbControllerUnlock ma non una funzione EvtSpbControllerLock, SpbCx chiama la funzione EvtSpbControllerUnlock per gestire le richieste IOCTL_SPB_UNLOCK_CONTROLLER, ma semplicemente completa le richieste IOCTL_SPB_LOCK_CONTROLLER con STATUS_SUCCESS codici di stato.
Il driver ha due modi per rilevare l'inizio di una sequenza implementata dal client. Prima di tutto, se il driver implementa una funzione EvtSpbControllerLock, SpbCx chiama questa funzione per gestire una IOCTL_SPB_LOCK_CONTROLLER richieste da un client. Il driver può basarsi su questa chiamata prima della prima richiesta di trasferimento in una sequenza. In secondo luogo, se il driver non implementa una funzione EvtSpbControllerLock , il driver può chiamare il metodo SpbRequestGetParameters quando il driver gestisce una semplice richiesta di trasferimento dal client. Per indicare che il trasferimento richiesto è il primo trasferimento in una sequenza, questo metodo imposta il membro Position nella struttura di output del metodo su SpbRequestSequencePositionFirst.
Il callback EvtSpbControllerUnlock è l'unico modo in cui un driver può determinare quando termina una sequenza. Un driver che non implementa una funzione EvtSpbControllerUnlock non può supportare sequenze implementate dal client.