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.
Les données STORAGE_ADAPTER_DESCRIPTOR retournées à la routine GetDescriptor indiquent les fonctionnalités de transfert d’un HBA donné vers le pilote de classe. En particulier, ces données indiquent le MaximumTransferLength en octets et les MaximumPhysicalPages : autrement dit, le nombre de pages noncontigues que l’adaptateur HBA peut gérer dans la mémoire physique qui sauvegarde une mémoire tampon système (c’est-à-dire l’étendue de sa prise en charge de nuages de points/collectes).
La plupart des pilotes de classe stockent un pointeur vers ces données de configuration dans l’extension de périphérique de chaque objet de périphérique, car les pilotes de classe de stockage sont responsables du fractionnement de toutes les demandes de transfert qui dépassent la capacité de l’adaptateur HBA à transférer des données. En d'autres termes, la routine DispatchReadWrite d'un pilote de classe doit déterminer si chaque IRP demande un transfert qui dépasse la capacité du HBA à gérer dans une seule opération de transfert.
Par exemple, une telle routine DispatchReadWrite peut avoir du code similaire à ce qui suit :
PSTORAGE_ADAPTER_DESCRIPTOR adapterDescriptor =
commonExtension->PartitionZeroExtension->AdapterDescriptor;
ULONG transferPages;
ULONG maximumTransferLength =
adapterDescriptor->MaximumTransferLength;
: :
//
// Calculate number of pages in this transfer
//
transferPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(
MmGetMdlVirtualAddress(Irp->MdlAddress),
currentIrpStack->Parameters.Read.Length);
//
// Check whether requested length is greater than the maximum number
// of bytes that can be transferred in a single operation
//
if (currentIrpStack->Parameters.Read.Length > maximumTransferLength ||
transferPages > adapterDescriptor->MaximumPhysicalPages) {
transferPages = adapterDescriptor->MaximumPhysicalPages - 1;
if (maximumTransferLength > transferPages << PAGE_SHIFT) {
maximumTransferLength = transferPages << PAGE_SHIFT;
}
IoMarkIrpPending(Irp);
SplitTransferRequest(DeviceObject,
Irp,
maximumTransferLength);
return STATUS_PENDING;
}
: :
Le pilote de classe ne peut pas indiquer le nombre de sauts physiques que la mémoire tampon aura une fois qu’elle a été mappée. Il doit donc supposer que chaque page du transfert est discontiguante et compare le nombre de pages par rapport au nombre de sauts physiques autorisés.
Notez que la routine DispatchReadWrite d'un tel pilote appelle IoMarkIrpPending et retourne STATUS_PENDING immédiatement après avoir appelé sa routine SplitTransferRequest avec l'IRP d'origine.
Pour effectuer la demande de transfert d’origine, la routine SplitTransferRequest du pilote crée un ou plusieurs IRPs pour gérer les sous-tampons dimensionnés pour s'adapter aux capacités de HBA. Pour chacun de ces IRP, la routine SplitTransferRequest :
Configure un SRB, généralement en appelant une routine BuildRequest interne (voir routine BuildRequest du pilote de classe de stockage)
Copie l'adresse MDL de l'IRP d'origine vers le nouvel IRP
Définit DataBuffer dans le SRB sur un décalage en octets dans le MDL pour cette partie du transfert
Configure sa routine IoCompletion avant d’envoyer l’IRP sur le pilote de port avec IoCallDriver
Pour suivre chaque élément du transfert, SplitTransferRequest inscrit une routine IoCompletion pour chaque IRP alloué par le pilote qu’il transmet au pilote suivant. La routine IoCompletion gère le nombre de demandes de transfert partielles terminées dans l’IRP d’origine, en utilisant InterlockedIncrement et InterlockedDecrement pour garantir que le nombre est exact.
Une telle routine IoCompletion doit libérer tous les IRPs et/ou les SRBs que le pilote a alloués et doit terminer l’IRP d’origine lorsque toutes les données demandées ont été transférées ou lorsque le pilote de classe a épuisé les tentatives de réessai de l’IRP et cela doit échouer en raison d’erreurs de transfert de périphérique.