Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
The I/O manager usually (except for FSDs) creates an associated device queue object when a driver calls IoCreateDevice. It also provides IoStartPacket and IoStartNextPacket, which drivers can call to have the I/O manager insert IRPs into the associated device queue or call their StartIo routines.
Par conséquent, il est rarement nécessaire ou utile pour un pilote de configurer ses propres objets de file d’attente d’appareils pour les irps. Les candidats probables sont des pilotes qui doivent coordonner les IRPs entrants à partir d’un certain nombre de pilotes de classe étroitement couplés pour les appareils hétérogènes qui sont serviceés via un seul contrôleur ou adaptateur de bus. Par exemple, un tel pilote est le pilote de port SCSI.
En d’autres termes, un pilote pour un contrôleur de tableau de disques est plus susceptible d’utiliser un objet de contrôleur créé par le pilote que de configurer des objets de file d’attente de périphériques supplémentaires, tandis qu’un pilote pour un adaptateur de bus de module complémentaire et d’un ensemble de pilotes de classe est légèrement plus susceptible d’utiliser des files d’attente de périphériques supplémentaires.
Utilisation de files d’attente d’appareils supplémentaires avec une routine StartIo
By calling IoStartPacket and IoStartNextPacket, a driver's Dispatch and DpcForIsr (or CustomDpc) routines synchronize calls to its StartIo routine using the device queue that the I/O manager created when the driver created the device object. For a port driver with a StartIo routine, IoStartPacket and IoStartNextPacket insert and remove IRPs in the device queue for the port driver's shared device controller/adapter. If the port driver also sets up supplemental device queues to hold requests coming in from closely coupled higher-level class drivers, it must "sort" incoming IRPs into its supplemental device queues, usually in its StartIo routine.
Le pilote de port doit déterminer la file d’attente de périphérique supplémentaire dans laquelle appartient chaque IRP avant d’essayer d’insérer cet IRP dans la file d’attente appropriée. Un pointeur vers l’objet de périphérique cible est passé avec l’IRP à la routine Dispatch du pilote. Le pilote doit enregistrer le pointeur à utiliser dans le « tri » des irPs entrants. The device object pointer passed to the StartIo routine is the driver's own device object, which represents the device controller/adapter, so it can't be used for this purpose.
Une fois que le pilote met en file d’attente n’importe quel irps, il programme son contrôleur/adaptateur partagé pour effectuer la demande. Thus, the port driver can process incoming requests for all devices on a first-come, first-served basis until a call to KeInsertDeviceQueue puts an IRP into a particular class driver's device queue.
By using its own device queue for all IRPs to be processed through its StartIo routine, the underlying port driver serializes operations through the shared device (or bus) controller/adapter to all attached devices. En tenant parfois des IRPs pour chaque appareil pris en charge dans une file d’attente d’appareils distincte, ce pilote de port empêche le traitement des IRPs pour un appareil déjà occupé tout en augmentant le débit d’E/S pour chaque autre appareil qui effectue des E/S via son matériel partagé.
In response to the call to IoStartPacket from the port driver's Dispatch routine, the I/O manager either calls that driver's StartIo routine immediately or puts the IRP into the device queue associated with the device object for the port driver's shared controller/adapter.
Le pilote de port doit conserver ses propres informations d’état sur chacun des appareils hétérogènes qu’il services via le contrôleur/adaptateur d’appareil partagé.
Gardez à l’esprit les points suivants lors de la conception de pilotes de classe/port avec des files d’attente de périphériques supplémentaires :
Un pilote ne peut pas facilement obtenir un pointeur vers un objet d’appareil créé par n’importe quel pilote superposé au-dessus de lui-même, à l’exception de l’objet d’appareil situé en haut de sa pile d’appareils.
Par conception, le gestionnaire d’E/S ne fournit pas de routine de support pour obtenir un tel pointeur. De plus, l’ordre dans lequel les pilotes sont chargés rend impossible pour les pilotes inférieurs d’obtenir des pointeurs pour les objets de périphérique des pilotes de niveau supérieur, qui ne sont pas encore créés quand un pilote de niveau inférieur ajoute son appareil.
Although IoGetAttachedDeviceReference returns a pointer to the highest-level device object in a driver's stack, a driver should use this pointer only to designate a target for I/O requests to its stack. Un pilote ne doit pas tenter de lire ou d’écrire l’objet de périphérique.
Un pilote ne peut pas utiliser de pointeur vers un objet de périphérique créé par un pilote superposé au-dessus de lui-même, sauf pour envoyer des requêtes en haut de sa propre pile d’appareils.
Il n’existe aucun moyen de synchroniser l’accès à un seul objet de périphérique (et son extension de périphérique) entre deux pilotes d’une manière multiprocesseur sécurisée. Aucun des pilotes ne peut faire d’hypothèses sur ce que traite actuellement l’E/S de l’autre pilote.
Even for closely coupled class/port drivers, each class driver should use the pointer to the port driver's device objects only to pass on IRPs using IoCallDriver. Le pilote de port sous-jacent doit conserver son propre état, probablement dans l’extension de périphérique du pilote de port, concernant les demandes qu’il traite pour les périphériques de classe étroitement couplés.
Gestion des files d’attente de périphériques supplémentaires entre les routines de pilotes
Tout pilote de port qui met en file d’attente les fournisseurs d’intégration dans des files d’attente de périphériques supplémentaires pour un ensemble étroitement couplé de pilotes de classe doit également gérer efficacement la situation suivante :
Ses routines Dispatch insèrent des IRPs pour un appareil particulier dans la file d’attente d’appareils créée par le pilote pour cet appareil.
IRPs for other devices continue to come in, to be queued to the driver's StartIo routine with IoStartPacket, and to be processed through the shared device controller.
The device controller doesn't become idle, but each IRP held in the driver-created device queue also must be queued to the driver's StartIo routine as soon as possible.
So, the port driver's DpcForIsr routine must attempt to transfer an IRP from the driver's internal device queue for a particular device into the device queue for the shared adapter/controller whenever the port driver completes an IRP, as follows:
The DpcForIsr routine calls IoStartNextPacket to have the StartIo routine begin processing the next IRP queued to the shared device controller.
The DpcForIsr routine calls KeRemoveDeviceQueue to dequeue the next IRP (if any) that it's holding in its internal device queue for the device on whose behalf it's about to complete an IRP.
If KeRemoveDeviceQueue returns a non-NULL pointer, the DpcForIsr routine calls IoStartPacket with the dequeued IRP to have it queued to the shared device controller/adapter. Otherwise, the call to KeRemoveDeviceQueue simply resets the state of the device queue object to Not-Busy, and the DpcForIsr routine omits the call to IoStartPacket.
Then, the DpcForIsr routine calls IoCompleteRequest with the input IRP for which the port driver has just completed I/O processing, either by setting the I/O status block with an error or by satisfying the I/O request.
The preceding sequence implies that the DpcForIsr routine also must determine the device for which it's completing the current (input) IRP in order to manage internal queuing of IRPs efficiently.
Si le pilote de port tente d’attendre que son contrôleur/adaptateur partagé soit inactif avant la mise en file d’attente des adresses IP virtuelles contenues dans ses files d’attente d’appareils supplémentaires, le pilote risque de mourir de faim d’un appareil pour lequel il y avait une forte demande d’E/S alors qu’il a rapidement servicené tous les autres appareils pour lesquels la demande d’E/S actuelle était réellement beaucoup plus légère.