Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Procedura MapTransferEx zainicjuje zestaw wcześniej przydzielonych zasobów DMA i uruchomi transfer DMA. Ta rutyna jest dostępna w wersji 3 interfejsu operacji DMA. Wersja 3 tego interfejsu jest obsługiwana od systemu Windows 8. Aby uzyskać więcej informacji na temat interfejsu operacji DMA, zobacz DMA_OPERATIONS.
Porównanie MapTransferEx z MapTransfer
MapTransferEx to ulepszona wersja procedury MapTransfer. MapTransfer jest dostępna we wszystkich wersjach interfejsu operacji DMA, począwszy od wersji 1 w systemie Windows 2000. Jedno wywołanie funkcji MapTransfer może zmapować jeden ciągły blok pamięci fizycznej z MDL. Jednak bufor danych dla złożonego transferu DMA może być opisany przez łańcuch MDL, a każdy MDL w łańcuchu może opisywać kilka bloków pamięci fizycznej. Aby użyć MapTransfer do transferu takiego buforu, sterownik musi wykonać wiele wywołań MapTransfer. Zazwyczaj te wywołania są wykonywane wewnątrz pary zagnieżdżonych pętli. Pętla wewnętrzna iteruje z jednego bloku ciągłej pamięci fizycznej do następnego w każdym MDL, a pętla zewnętrzna iteruje z jednego MDL do następnego w łańcuchu MDL.
Natomiast jedno wywołanie MapTransferEx może przenieść cały bufor danych na potrzeby złożonego transferu DMA. Następujące trzy parametry MapTransferEx opisują pamięć buforu do użycia na potrzeby transferu.
| Parametr | Opis |
|---|---|
| Mdl | Wskaźnik do pierwszego MDL w łańcuchu jednego lub więcej MDL. Aby uzyskać więcej informacji na temat łańcuchów MDL, zobacz Using MDLs. |
| Przesunięcie | Przesunięcie buforu (w bajtach) od początku pamięci, którą opisuje łańcuch MDL. |
| długość | Wskaźnik do lokalizacji zawierającej długość w bajtach buforu danych. |
Na początku wywołania MapTransferEx procedura MapTransferEx przechodzi przez łańcuch MDL, aby znaleźć początek buforu. Początek buforu jest określony przez parametr Przesunięcie. Następnie, przechodząc od początku buforu do końca, MapTransferEx tworzy listę rozproszoną/zebraną, w której każdy fragment buforu na liście reprezentuje fizycznie spójny blok pamięci z łańcucha MDL. Aby skonstruować tę listę, MapTransferEx przechodzi z jednego fizycznie ciągłego bloku pamięci do następnego w każdym MDL, a następnie od jednego MDL do kolejnego w łańcuchu MDL. Konstrukcja listy kończy się, gdy łączna ilość pamięci buforu opisanej przez listę scatter/gather jest równa liczbie bajtów określonych przez *Długość parametru wejściowego. Kolejność fragmentów buforu na wynikowej liście fragmentacji/zbierania odpowiada kolejności fizycznie ciągłych segmentów w łańcuchu MDL.
Wiele wywołań do mapTransferEx
MapTransferEx może nie zawsze być w stanie przesłać cały bufor danych DMA w jednym wywołaniu. Na poniższej liście opisano niektóre warunki, które mogą wymagać, aby MapTransferEx był wywoływany więcej niż raz w celu ukończenia transferu.
- Karta DMA wymaga rejestrów map, a liczba rejestrów map przypisanych do karty nie jest wystarczająca do opisania całego buforu.
- Magazyn przydzielony przez sterownik do przechowywania listy scatter/gather nie jest wystarczająco duży, aby pomieścić listę scatter/gather dla całego buforu.
- Transfer używa systemowego kontrolera DMA, który ogranicza liczbę fragmentów buforu, które można określić na sprzętowej liście scatter/gather.
We wszystkich tych przypadkach MapTransferEx mapuje tyle bufora danych, ile się da w jednym wywołaniu, i informuje sterownik, ile bufora zostało zamapowane przez wywołanie. Poprzednia lista nie zawiera innych warunków, takich jak zachowanie pamięci podręcznej specyficzne dla platformy, które mogą wymagać więcej niż jednego wywołania funkcji MapTransferEx w celu ukończenia transferu. Przyszłe platformy sprzętowe mogą nakładać dodatkowe ograniczenia dotyczące długości transferu DMA. Z tych powodów deweloperzy sterowników powinni zaprojektować sterowniki, aby prawidłowo obsługiwać przypadek, w którym MapTransferEx nie może mapować całego buforu danych DMA w jednym wywołaniu.
Przed wywołaniem MapTransferExobiekt wywołujący ustawia parametr *Length na liczbę bajtów w buforze danych DMA, które nadal muszą zostać zamapowane. Przed zwróceniem MapTransferEx ustawia *długość na liczbę bajtów w buforze, które zostały faktycznie zamapowane przez wywołanie. Jeśli wywołanie MapTransferEx nie może mapować całej długości buforu, zgodnie z wartością wejściową *długość, wartość wyjściowa *Długość jest mniejsza niż jej wartość wejściowa. Jeśli transfer DMA wymaga co najmniej dwóch wywołań MapTransferEx, sterownik wywołujący musi uzyskać *długość wartość wyjściową z jednego wywołania, zanim będzie mógł określić *długość wartość wejściową dla następnego wywołania.
Jeśli na przykład wywołanie MapTransferEx może przenieść tylko X bajtów do lub z buforu, dla którego Przesunięcie = B i *Długość = N (na wejściu), to po powrocie, *Długość = X. Dla następnego wywołania MapTransferExsterownik powinien ustawić Przesunięcie = B + X i *Długość = N - X. W obu wywołaniach ten sam łańcuch MDL jest używany bez modyfikacji.
Jeśli obiekt wywołujący określa DmaCompletionRoutine, wtedy MapTransferEx zapisuje wartość wyjściową *Długość przed zaplanowaniem uruchomienia DmaCompletionRoutine. Zaktualizowana wartość długości * jest zawsze dostępna, zanim uruchomi się DmaCompletionRoutine. Na przykład, jeśli transfer DMA wymaga dwóch wywołań MapTransferEx, DmaCompletionRoutine, które harmonogramy pierwszego wywołania mogą uzyskać *długość jako wartość wyjściową z pierwszego wywołania. Procedura może następnie użyć tej wartości, aby obliczyć *długość wartość wejściową dla drugiego wywołania. Zazwyczaj parametr długości wskazuje lokalizację wCompletionContext wartości, która jest dostarczana do DmaCompletionRoutine jako parametr.