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.
Aby wykonać transfer DMA, który używa procedur w wersji 3 interfejsu operacji DMA, sterownik powinien wykonać kroki opisane na poniższej liście. Te kroki są wspólne zarówno dla urządzeń podrzędnych, jak i urządzeń głównych magistrali. Wersja 3 tego interfejsu jest dostępna od systemu Windows 8. Aby uzyskać więcej informacji na temat procedur w tym interfejsie, zobacz DMA_OPERATIONS.
Krok 1: Uzyskiwanie obiektu adaptera DMA
W ramach przygotowań do transferu DMA sterownik wywołuje procedurę IoGetDmaAdapter w celu uzyskania obiektu karty DMA. Obiekt karty DMA to obiekt oprogramowania reprezentujący urządzenie główne magistrali lub wiersz żądania na kontrolerze DMA systemu. Ten obiekt zawiera interfejs operacji DMA dla magistrali używanej do transferu danych do lub z urządzenia. Ponadto ten obiekt synchronizuje dostęp sterownika do udostępnionych zasobów wymaganych do przeprowadzenia transferu. Aby uzyskać więcej informacji, zobacz Wprowadzenie do obiektów adaptera.
Krok 2. Uzyskiwanie opisu wymaganych zasobów DMA
Sterownik wywołuje procedurę GetDmaTransferInfo , aby uzyskać opis zasobów DMA, które muszą wykonać transfer.
Parametry wejściowe tego wywołania opisują bufor pamięci używany do transferu oraz kierunek transferu (odczyt lub zapis).
Wymagania dotyczące zasobów uzyskane z tego wywołania obejmują liczbę rejestrów map i rozmiar listy punktowej/zbierania, która jest wymagana do opisania buforu danych na potrzeby transferu. W kolejnym wywołaniu procedury AllocateAdapterChannelEx (zobacz krok 3) sterownik dostarcza liczbę rejestrów map jako parametr wejściowy.
Krok 3: Żądanie wymaganych zasobów DMA
Sterownik wywołuje procedurę AllocateAdapterChannelEx , aby przydzielić zasoby do przypisania do obiektu karty DMA. Te zasoby obejmują kanał DMA i rejestry map.
Wywołanie AllocateAdapterChannelEx może być asynchroniczne lub synchroniczne.
Jeśli flaga DMA_SYNCHRONOUS_CALLBACK nie jest ustawiona, wywołanie jest asynchroniczne. W takim przypadku parametr ExecutionRoutine wskazuje procedurę wykonywania dostarczoną przez obiekt wywołujący, która jest wywoływana, gdy żądane zasoby są dostępne. Jeśli operacja powiedzie się, asynchroniczne wywołanie AllocateAdapterChannelEx zwraca STATUS_SUCCESS bez oczekiwania na uruchomienie procedury wykonywania.
Jeśli flaga DMA_SYNCHRONOUS_CALLBACK jest ustawiona, wywołanie AllocateAdapterChannelEx jest synchroniczne. W takim przypadku parametr ExecutionRoutine w wywołaniu jest opcjonalny, a element AllocateAdapterChannelEx zachowuje się w następujący sposób:
Jeśli parametr ExecutionRoutine ma wartość inną niż NULL, a zasoby DMA można przydzielić natychmiast, funkcja AllocateAdapterChannelEx wywołuje procedurę wykonywania w kontekście wątku wywołującego. Po zakończeniu procedury wykonywania funkcja AllocateAdapterChannelEx zwraca STATUS_SUCCESS. Jeśli zasoby nie są natychmiast dostępne, funkcja AllocateAdapterChannelEx kończy się niepowodzeniem i zwraca kod stanu błędu STATUS_INSUFFICIENT_RESOURCES.
Jeśli parametr ExecutionRoutine ma wartość NULL, a element AllocateAdapterChannelEx może natychmiast przydzielić zasoby DMA, funkcja AllocateAdapterChannelEx zwraca STATUS_SUCCESS. Jeśli wszystkie zasoby nie są natychmiast dostępne, wywołanie zakończy się niepowodzeniem z kodem stanu błędu STATUS_INSUFFICIENT_RESOURCES.
W przypadku wywołań synchronicznych, które zwracają STATUS_SUCCESS, jeśli parametr MapRegisterBase w funkcji AllocateAdapterChannelEx ma wartość inną niż NULL, AllocateAdapterChannelEx zapisuje adres bazowy przydzielonych rejestrów mapowania na adres wskazywany przez parametr MapRegisterBase. Jeśli parametr ExecutionRoutine ma wartość NULL, baza MapRegisterBase musi mieć wartość inną niż NULL. Jeśli ExecutionRoutine ma wartość inną niż NULL, parametr MapRegisterBase w wywołaniu AllocateAdapterChannelEx jest opcjonalny, a rutyna wykonawcza otrzymuje podstawowy adres rejestru mapy jako parametr wejściowy.
W przypadku wywołań asynchronicznych AllocateAdapterChannelExparametr ExecutionRoutine musi mieć wartość inną niż NULL, a procedura wykonywania odbiera adres podstawowy rejestru mapy jako parametr wejściowy.
W kolejnych wywołaniach procedury MapTransferEx (patrz krok 5) sterownik dostarcza podstawowy adres rejestru mapy jako parametr wejściowy.
Jeśli parametr ExecutionRoutine jest inny niż NULL, procedura wykonywania zwraca wartość stanu, aby wskazać dyspozycję przydzielonych zasobów. W przypadku systemowych transferów DMA ta wartość zwracana musi mieć wartość KeepObject. Ta wartość informuje system operacyjny, że obiekt adaptera (i wszystkie przydzielone zasoby) jest używany i nie powinien być zwolniony. Jeśli nie podano procedury wykonywania, sterownik musi wywołać procedurę FreeAdapterObject i podać keepObject jako parametr AllocationOption .
Krok 4. W razie potrzeby anuluj oczekujące żądanie zasobu
Po wywołaniu AllocateAdapterChannelEx, które kolekuje adapter DMA do oczekiwania na zasoby DMA, sterownik może, jeśli to konieczne, wywołać procedurę CancelAdapterChannel, aby anulować oczekujące żądanie zasobów.
Jeśli funkcja CancelAdapterChannel zwróci wartość TRUE, żądanie zasobu zostanie pomyślnie anulowane. Jeśli w wywołaniu AllocateAdapterChannelEx podano procedurę wykonywania, ta rutyna nie jest uruchamiana.
Jeśli funkcja CancelAdapterChannel zwraca wartość FALSE, nie można anulować żądania zasobu, ponieważ zostało już przyznane. Jeśli w wywołaniu AllocateAdapterChannelEx podano procedurę wykonywania, ta rutyna zostanie wywołana.
Krok 5. Inicjowanie zasobów dma i uruchamianie transferu DMA
Sterownik wywołuje narzędzie MapTransferEx , aby zainicjować zasoby DMA i uruchomić transfer DMA. To wywołanie może wystąpić w tym samym wątku sterownika, który wywołuje AllocateAdapterChannelEx, lub może wystąpić w rutynie wykonania, którą sterownik dostarcza do AllocateAdapterChannelEx. Jeśli do przeniesienia całego buforu danych DMA jest wymagane więcej niż jedno wywołanie MapTransferEx , może wystąpić późniejsze wywołanie MapTransferEx w procedurze uzupełniania dla poprzedniego wywołania MapTransferEx .
Funkcja MapTransferEx obsługuje łańcuchowe listy MDL jako parametry wejściowe. Każdy język MDL opisuje region buforu DMA, który jest ciągły w pamięci wirtualnej. Gdy MapTransferEx kompiluje listę rozrzutu/zebrania, automatycznie obsługuje przejścia z jednego praktycznie ciągłego regionu bufora do następnego bez interwencji sterownika. Aby uzyskać więcej informacji, zobacz Using the MapTransferEx Routine (Używanie procedury MapTransferEx).
W przypadku transferu systemowego DMA wskaźnik do procedury zakończenia DMA można przekazać do MapTransferEx w opcjonalnym parametrze DmaCompletionRoutine. Ta rutyna jest zaplanowana do uruchomienia na poziomie dispatch w odpowiedzi na przerwanie z systemowego kontrolera DMA, które wskazuje zakończenie transferu DMA.
Jeśli narzędzie MapTransferEx nie może zamapować całego żądanego rozmiaru transferu, ustawi parametr wyjściowy *Length na długość zamapowanego i zwróci STATUS_SUCCESS.
Krok 6. W razie potrzeby wykonaj operacje specyficzne dla sprzętu
Funkcja MapTransferEx zwraca STATUS_SUCCESS, aby wskazać, że transfer DMA został pomyślnie zainicjowany. Na niektórych platformach sterownik może wymagać wykonania dodatkowej akcji poza wywołaniem MapTransferEx , aby rozpocząć transfer, ale ten typ opóźnionego uruchamiania nie jest wymagany dla wszystkich platform. Sterowniki nie mogą zależeć od takich opóźnień w podejmowaniu decyzji dotyczących korzystania z przydzielonych zasobów i zwalniania ich.
Rutyny w interfejsie operacji DMA utrzymują spójność pamięci podręcznej dla transferów DMA w sposób przezroczysty dla sterowników korzystających z tych rutyn. Na platformach, które nie wymuszają współistnienia pamięci podręcznej na sprzęcie, MapTransferEx gwarantuje, że pamięci podręczne danych procesora są opróżniane przed zapisem (pamięć do urządzenia). W przypadku transferów odczytu (urządzenie do pamięci) pamięci podręczne zostają unieważnione podczas wywołania rutyny FlushAdapterBuffersEx, które następuje po każdym wywołaniu MapTransferEx (zobacz krok 8).
Krok 7. Otrzymywanie powiadomień po zakończeniu transferu DMA
Po zakończeniu transferu DMA sterownik jest powiadamiany na jeden z następujących dwóch sposobów:
- Przerwanie sterownika urządzenia dla urządzenia głównego magistrali
- Wykonywanie procedury kończącej dostarczonej przez sterownik dla urządzenia podrzędnego, które korzysta z systemowego kontrolera DMA
W przypadku systemowego transferu DMA sterownik może dostarczyć procedurę zakończenia do MapTransferEx jako parametr wejściowy.
Krok 8. Opróżnianie wszystkich danych, które pozostają w pamięci podręcznej
Po zakończeniu transferu DMA sterownik musi wywołać procedurę FlushAdapterBuffersEx , aby opróżnić wszystkie dane, które pozostają w pamięci podręcznej. Sterownik musi wywołać funkcję FlushAdapterBuffersEx po każdym wywołaniu MapTransferEx .
Jeśli wywołanie MapTransferEx mapuje tylko część buforu danych DMA, sterownik musi wywołać funkcję MapTransferEx ponownie, aby zamapować pozostałe dane. Złożony transfer może wymagać kilku wywołań MapTransferEx . Dla każdego dodatkowego wywołania MapTransferEx powtórz kroki od 5 do 8.
Krok 9. Zwolnij kanał DMA i rejestry mapy
Po pomyślnym zamapowaniu całego bufora danych DMA i zakończeniu ostatecznego transferu, sterownik musi wywołać procedurę FreeAdapterChannel, aby zwolnić kanał DMA i wszystkie wcześniej przydzielone rejestry map.
Krok 10: Zwolnij obiekt adaptera DMA
Po zakończeniu wszystkich transferów DMA i gdy wszystkie wcześniej przydzielone rejestry map zostają zwolnione, sterownik wywołuje procedurę PutDmaAdapter, aby zwolnić obiekt adaptera.