From 4fd45309773c02439cc52257c5c96bed14f17f41 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 22 Aug 2005 10:47:29 +0000 Subject: [PATCH] Export the HalGetDmaAdapter callback and use some nice macros where appropriate. svn path=/trunk/; revision=17472 --- reactos/hal/halx86/generic/dma.c | 64 ++- reactos/hal/halx86/include/haldma.h | 784 ++++++++++++++-------------- 2 files changed, 439 insertions(+), 409 deletions(-) diff --git a/reactos/hal/halx86/generic/dma.c b/reactos/hal/halx86/generic/dma.c index 12eec1637c9..fd0e03863aa 100644 --- a/reactos/hal/halx86/generic/dma.c +++ b/reactos/hal/halx86/generic/dma.c @@ -139,6 +139,13 @@ HalpInitDma(VOID) KeInitializeEvent(&HalpDmaLock, NotificationEvent, TRUE); HalpMasterAdapter = HalpDmaAllocateMasterAdapter(); + + /* + * Setup the HalDispatchTable callback for creating PnP DMA adapters. It's + * used by IoGetDmaAdapter in the kernel. + */ + + HalGetDmaAdapter = HalpGetDmaAdapter; } /** @@ -760,6 +767,24 @@ HalGetAdapter( return AdapterObject; } +/** + * @name HalpGetDmaAdapter + * + * Internal routine to allocate PnP DMA adapter object. It's exported through + * HalDispatchTable and used by IoGetDmaAdapter. + * + * @see HalGetAdapter + */ + +PDMA_ADAPTER STDCALL +HalpGetDmaAdapter( + IN PVOID Context, + IN PDEVICE_DESCRIPTION DeviceDescription, + OUT PULONG NumberOfMapRegisters) +{ + return &HalGetAdapter(DeviceDescription, NumberOfMapRegisters)->DmaHeader; +} + /** * @name HalPutDmaAdapter * @@ -1431,7 +1456,7 @@ HalpCopyBufferMap( { ULONG CurrentLength; ULONG_PTR CurrentAddress; - ULONG PageOffset; + ULONG ByteOffset; PVOID VirtualAddress; VirtualAddress = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority); @@ -1446,20 +1471,20 @@ HalpCopyBufferMap( KEBUGCHECK(0); } - CurrentAddress = (ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa - - Mdl->ByteOffset; + CurrentAddress = (ULONG_PTR)CurrentVa - + (ULONG_PTR)MmGetMdlVirtualAddress(Mdl); while (Length > 0) { - PageOffset = CurrentAddress & (PAGE_SIZE - 1); - CurrentLength = PAGE_SIZE - PageOffset; + ByteOffset = BYTE_OFFSET(CurrentAddress); + CurrentLength = PAGE_SIZE - ByteOffset; if (CurrentLength > Length) CurrentLength = Length; if (WriteToDevice) { RtlCopyMemory( - (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + PageOffset), + (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset), (PVOID)CurrentAddress, CurrentLength); } @@ -1467,7 +1492,7 @@ HalpCopyBufferMap( { RtlCopyMemory( (PVOID)CurrentAddress, - (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + PageOffset), + (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset), CurrentLength); } @@ -1613,9 +1638,9 @@ IoMapTransfer( IN OUT PULONG Length, IN BOOLEAN WriteToDevice) { - PPFN_TYPE MdlPagesPtr; - PFN_TYPE MdlPage1, MdlPage2; - ULONG PageOffset; + PPFN_NUMBER MdlPagesPtr; + PFN_NUMBER MdlPage1, MdlPage2; + ULONG ByteOffset; ULONG TransferOffset; ULONG TransferLength; BOOLEAN UseMapRegisters; @@ -1629,7 +1654,7 @@ IoMapTransfer( /* * Precalculate some values that are used in all cases. * - * PageOffset is offset inside the page at which the transfer starts. + * ByteOffset is offset inside the page at which the transfer starts. * MdlPagesPtr is pointer inside the MDL page chain at the page where the * transfer start. * PhysicalAddress is physical address corresponding to the transfer @@ -1641,15 +1666,15 @@ IoMapTransfer( * takes place below. These are just initial values. */ - PageOffset = (ULONG_PTR)CurrentVa & (PAGE_SIZE - 1); + ByteOffset = BYTE_OFFSET(CurrentVa); - MdlPagesPtr = (PPFN_TYPE)(Mdl + 1); + MdlPagesPtr = MmGetMdlPfnArray(Mdl); MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT; PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT; - PhysicalAddress.QuadPart += PageOffset; + PhysicalAddress.QuadPart += ByteOffset; - TransferLength = PAGE_SIZE - PageOffset; + TransferLength = PAGE_SIZE - ByteOffset; /* * Special case for bus master adapters with S/G support. We can directly @@ -1720,7 +1745,7 @@ IoMapTransfer( { UseMapRegisters = TRUE; PhysicalAddress = RealMapRegisterBase->PhysicalAddress; - PhysicalAddress.QuadPart += PageOffset; + PhysicalAddress.QuadPart += ByteOffset; TransferLength = *Length; RealMapRegisterBase->Counter = ~0; Counter = 0; @@ -1735,8 +1760,7 @@ IoMapTransfer( UseMapRegisters = FALSE; Counter = RealMapRegisterBase->Counter; - RealMapRegisterBase->Counter += - (PageOffset + TransferLength + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + RealMapRegisterBase->Counter += BYTES_TO_PAGES(ByteOffset + TransferLength); /* * Check if the buffer doesn't exceed the highest phisical address @@ -1750,7 +1774,7 @@ IoMapTransfer( { UseMapRegisters = TRUE; PhysicalAddress = RealMapRegisterBase->PhysicalAddress; - PhysicalAddress.QuadPart += PageOffset; + PhysicalAddress.QuadPart += ByteOffset; } } @@ -1791,7 +1815,7 @@ IoMapTransfer( if (AdapterObject->IgnoreCount) { RtlZeroMemory((PUCHAR)RealMapRegisterBase[Counter].VirtualAddress + - PageOffset, TransferLength); + ByteOffset, TransferLength); } } diff --git a/reactos/hal/halx86/include/haldma.h b/reactos/hal/halx86/include/haldma.h index 0c98a5a4fef..163cd1f7d8d 100644 --- a/reactos/hal/halx86/include/haldma.h +++ b/reactos/hal/halx86/include/haldma.h @@ -1,389 +1,395 @@ -#ifndef HALDMA_H -#define HALDMA_H - -/* - * DMA Page Register Structure - * 080 DMA RESERVED - * 081 DMA Page Register (channel 2) - * 082 DMA Page Register (channel 3) - * 083 DMA Page Register (channel 1) - * 084 DMA RESERVED - * 085 DMA RESERVED - * 086 DMA RESERVED - * 087 DMA Page Register (channel 0) - * 088 DMA RESERVED - * 089 PS/2-DMA Page Register (channel 6) - * 08A PS/2-DMA Page Register (channel 7) - * 08B PS/2-DMA Page Register (channel 5) - * 08C PS/2-DMA RESERVED - * 08D PS/2-DMA RESERVED - * 08E PS/2-DMA RESERVED - * 08F PS/2-DMA Page Register (channel 4) - */ - -typedef struct _DMA_PAGE -{ - UCHAR Reserved1; - UCHAR Channel2; - UCHAR Channel3; - UCHAR Channel1; - UCHAR Reserved2[3]; - UCHAR Channel0; - UCHAR Reserved3; - UCHAR Channel6; - UCHAR Channel7; - UCHAR Channel5; - UCHAR Reserved4[3]; - UCHAR Channel4; -} DMA_PAGE, *PDMA_PAGE; - -/* - * DMA Channel Mask Register Structure - * - * MSB LSB - * x x x x x x x x - * ------------------- - ----- - * | | | 00 - Select channel 0 mask bit - * | | \---- 01 - Select channel 1 mask bit - * | | 10 - Select channel 2 mask bit - * | | 11 - Select channel 3 mask bit - * | | - * | \---------- 0 - Clear mask bit - * | 1 - Set mask bit - * | - * \----------------------- xx - Reserved - */ - -typedef struct _DMA_CHANNEL_MASK -{ - UCHAR Channel: 2; - UCHAR SetMask: 1; - UCHAR Reserved: 5; -} DMA_CHANNEL_MASK, *PDMA_CHANNEL_MASK; - -/* - * DMA Mask Register Structure - * - * MSB LSB - * x x x x x x x x - * \---/ - - ----- ----- - * | | | | | 00 - Channel 0 select - * | | | | \---- 01 - Channel 1 select - * | | | | 10 - Channel 2 select - * | | | | 11 - Channel 3 select - * | | | | - * | | | | 00 - Verify transfer - * | | | \------------ 01 - Write transfer - * | | | 10 - Read transfer - * | | | - * | | \-------------------- 0 - Autoinitialized - * | | 1 - Non-autoinitialized - * | | - * | \------------------------ 0 - Address increment select - * | - * | 00 - Demand mode - * \------------------------------ 01 - Single mode - * 10 - Block mode - * 11 - Cascade mode - */ - -typedef union _DMA_MODE -{ - struct - { - UCHAR Channel: 2; - UCHAR TransferType: 2; - UCHAR AutoInitialize: 1; - UCHAR AddressDecrement: 1; - UCHAR RequestMode: 2; - }; - UCHAR Byte; -} DMA_MODE, *PDMA_MODE; - -/* - * DMA Extended Mode Register Structure - * - * MSB LSB - * x x x x x x x x - * - - ----- ----- ----- - * | | | | | 00 - Channel 0 select - * | | | | \---- 01 - Channel 1 select - * | | | | 10 - Channel 2 select - * | | | | 11 - Channel 3 select - * | | | | - * | | | | 00 - 8-bit I/O, by bytes - * | | | \------------ 01 - 16-bit I/O, by words, address shifted - * | | | 10 - 32-bit I/O, by bytes - * | | | 11 - 16-bit I/O, by bytes - * | | | - * | | \---------------------- 00 - Compatible - * | | 01 - Type A - * | | 10 - Type B - * | | 11 - Burst - * | | - * | \---------------------------- 0 - Terminal Count is Output - * | - * \---------------------------------0 - Disable Stop Register - * 1 - Enable Stop Register - */ - -typedef union _DMA_EXTENDED_MODE -{ - struct - { - UCHAR ChannelNumber: 2; - UCHAR TransferSize: 2; - UCHAR TimingMode: 2; - UCHAR TerminalCountIsOutput: 1; - UCHAR EnableStopRegister: 1; - }; - UCHAR Byte; -} DMA_EXTENDED_MODE, *PDMA_EXTENDED_MODE; - -/* DMA Extended Mode Register Transfer Sizes */ -#define B_8BITS 0 -#define W_16BITS 1 -#define B_32BITS 2 -#define B_16BITS 3 - -/* DMA Extended Mode Register Timing */ -#define COMPATIBLE_TIMING 0 -#define TYPE_A_TIMING 1 -#define TYPE_B_TIMING 2 -#define BURST_TIMING 3 - -/* Channel Stop Registers for each Channel */ -typedef struct _DMA_CHANNEL_STOP -{ - UCHAR ChannelLow; - UCHAR ChannelMid; - UCHAR ChannelHigh; - UCHAR Reserved; -} DMA_CHANNEL_STOP, *PDMA_CHANNEL_STOP; - -/* Transfer Types */ -#define VERIFY_TRANSFER 0x00 -#define READ_TRANSFER 0x01 -#define WRITE_TRANSFER 0x02 - -/* Request Modes */ -#define DEMAND_REQUEST_MODE 0x00 -#define SINGLE_REQUEST_MODE 0x01 -#define BLOCK_REQUEST_MODE 0x02 -#define CASCADE_REQUEST_MODE 0x03 - -#define DMA_SETMASK 4 -#define DMA_CLEARMASK 0 -#define DMA_READ 4 -#define DMA_WRITE 8 -#define DMA_SINGLE_TRANSFER 0x40 -#define DMA_AUTO_INIT 0x10 - -typedef struct _DMA1_ADDRESS_COUNT -{ - UCHAR DmaBaseAddress; - UCHAR DmaBaseCount; -} DMA1_ADDRESS_COUNT, *PDMA1_ADDRESS_COUNT; - -typedef struct _DMA2_ADDRESS_COUNT -{ - UCHAR DmaBaseAddress; - UCHAR Reserved1; - UCHAR DmaBaseCount; - UCHAR Reserved2; -} DMA2_ADDRESS_COUNT, *PDMA2_ADDRESS_COUNT; - -typedef struct _DMA1_CONTROL -{ - DMA1_ADDRESS_COUNT DmaAddressCount[4]; - UCHAR DmaStatus; - UCHAR DmaRequest; - UCHAR SingleMask; - UCHAR Mode; - UCHAR ClearBytePointer; - UCHAR MasterClear; - UCHAR ClearMask; - UCHAR AllMask; -} DMA1_CONTROL, *PDMA1_CONTROL; - -typedef struct _DMA2_CONTROL -{ - DMA2_ADDRESS_COUNT DmaAddressCount[4]; - UCHAR DmaStatus; - UCHAR Reserved1; - UCHAR DmaRequest; - UCHAR Reserved2; - UCHAR SingleMask; - UCHAR Reserved3; - UCHAR Mode; - UCHAR Reserved4; - UCHAR ClearBytePointer; - UCHAR Reserved5; - UCHAR MasterClear; - UCHAR Reserved6; - UCHAR ClearMask; - UCHAR Reserved7; - UCHAR AllMask; - UCHAR Reserved8; -} DMA2_CONTROL, *PDMA2_CONTROL; - -/* This structure defines the I/O Map of the 82537 controller. */ -typedef struct _EISA_CONTROL -{ - /* DMA Controller 1 */ - DMA1_CONTROL DmaController1; /* 00h-0Fh */ - UCHAR Reserved1[16]; /* 0Fh-1Fh */ - - /* Interrupt Controller 1 (PIC) */ - UCHAR Pic1Operation; /* 20h */ - UCHAR Pic1Interrupt; /* 21h */ - UCHAR Reserved2[30]; /* 22h-3Fh */ - - /* Timer */ - UCHAR TimerCounter; /* 40h */ - UCHAR TimerMemoryRefresh; /* 41h */ - UCHAR Speaker; /* 42h */ - UCHAR TimerOperation; /* 43h */ - UCHAR TimerMisc; /* 44h */ - UCHAR Reserved3[2]; /* 45-46h */ - UCHAR TimerCounterControl; /* 47h */ - UCHAR TimerFailSafeCounter; /* 48h */ - UCHAR Reserved4; /* 49h */ - UCHAR TimerCounter2; /* 4Ah */ - UCHAR TimerOperation2; /* 4Bh */ - UCHAR Reserved5[20]; /* 4Ch-5Fh */ - - /* NMI / Keyboard / RTC */ - UCHAR Keyboard; /* 60h */ - UCHAR NmiStatus; /* 61h */ - UCHAR Reserved6[14]; /* 62h-6Fh */ - UCHAR NmiEnable; /* 70h */ - UCHAR Reserved7[15]; /* 71h-7Fh */ - - /* DMA Page Registers Controller 1 */ - DMA_PAGE DmaController1Pages; /* 80h-8Fh */ - UCHAR Reserved8[16]; /* 90h-9Fh */ - - /* Interrupt Controller 2 (PIC) */ - UCHAR Pic2Operation; /* 0A0h */ - UCHAR Pic2Interrupt; /* 0A1h */ - UCHAR Reserved9[30]; /* 0A2h-0BFh */ - - /* DMA Controller 2 */ - DMA1_CONTROL DmaController2; /* 0C0h-0CFh */ - - /* System Reserved Ports */ - UCHAR SystemReserved[816]; /* 0D0h-3FFh */ - - /* Extended DMA Registers, Controller 1 */ - UCHAR DmaHighByteCount1[8]; /* 400h-407h */ - UCHAR Reserved10[2]; /* 408h-409h */ - UCHAR DmaChainMode1; /* 40Ah */ - UCHAR DmaExtendedMode1; /* 40Bh */ - UCHAR DmaBufferControl; /* 40Ch */ - UCHAR Reserved11[84]; /* 40Dh-460h */ - UCHAR ExtendedNmiControl; /* 461h */ - UCHAR NmiCommand; /* 462h */ - UCHAR Reserved12; /* 463h */ - UCHAR BusMaster; /* 464h */ - UCHAR Reserved13[27]; /* 465h-47Fh */ - - /* DMA Page Registers Controller 2 */ - DMA_PAGE DmaController2Pages; /* 480h-48Fh */ - UCHAR Reserved14[48]; /* 490h-4BFh */ - - /* Extended DMA Registers, Controller 2 */ - UCHAR DmaHighByteCount2[16]; /* 4C0h-4CFh */ - - /* Edge/Level Control Registers */ - UCHAR Pic1EdgeLevel; /* 4D0h */ - UCHAR Pic2EdgeLevel; /* 4D1h */ - UCHAR Reserved15[2]; /* 4D2h-4D3h */ - - /* Extended DMA Registers, Controller 2 */ - UCHAR DmaChainMode2; /* 4D4h */ - UCHAR Reserved16; /* 4D5h */ - UCHAR DmaExtendedMode2; /* 4D6h */ - UCHAR Reserved17[9]; /* 4D7h-4DFh */ - - /* DMA Stop Registers */ - DMA_CHANNEL_STOP DmaChannelStop[8]; /* 4E0h-4FFh */ -} EISA_CONTROL, *PEISA_CONTROL; - -typedef struct _MAP_REGISTER_ENTRY -{ - PVOID VirtualAddress; - PHYSICAL_ADDRESS PhysicalAddress; - ULONG Counter; -} MAP_REGISTER_ENTRY, *PMAP_REGISTER_ENTRY; - -struct _ADAPTER_OBJECT { - /* - * New style DMA object definition. The fact that it is at the beginning - * of the ADAPTER_OBJECT structure allows us to easily implement the - * fallback implementation of IoGetDmaAdapter. - */ - DMA_ADAPTER DmaHeader; - - /* - * For normal adapter objects pointer to master adapter that takes care - * of channel allocation. For master adapter set to NULL. - */ - struct _ADAPTER_OBJECT *MasterAdapter; - - ULONG MapRegistersPerChannel; - PVOID AdapterBaseVa; - PMAP_REGISTER_ENTRY MapRegisterBase; - - ULONG NumberOfMapRegisters; - ULONG CommittedMapRegisters; - - PWAIT_CONTEXT_BLOCK CurrentWcb; - KDEVICE_QUEUE ChannelWaitQueue; - PKDEVICE_QUEUE RegisterWaitQueue; - LIST_ENTRY AdapterQueue; - KSPIN_LOCK SpinLock; - PRTL_BITMAP MapRegisters; - PUCHAR PagePort; - UCHAR ChannelNumber; - UCHAR AdapterNumber; - USHORT DmaPortAddress; - DMA_MODE AdapterMode; - BOOLEAN NeedsMapRegisters; - BOOLEAN MasterDevice; - BOOLEAN Width16Bits; - BOOLEAN ScatterGather; - BOOLEAN IgnoreCount; - BOOLEAN Dma32BitAddresses; - BOOLEAN Dma64BitAddresses; - LIST_ENTRY AdapterList; -} ADAPTER_OBJECT; - -typedef struct _GROW_WORK_ITEM { - WORK_QUEUE_ITEM WorkQueueItem; - PADAPTER_OBJECT AdapterObject; - ULONG NumberOfMapRegisters; -} GROW_WORK_ITEM, *PGROW_WORK_ITEM; - -#define MAP_BASE_SW_SG 1 - -PADAPTER_OBJECT STDCALL -HalpDmaAllocateMasterAdapter(VOID); - -VOID STDCALL -HalPutDmaAdapter( - PADAPTER_OBJECT AdapterObject); - -ULONG STDCALL -HalpDmaGetDmaAlignment( - PADAPTER_OBJECT AdapterObject); - -NTSTATUS STDCALL -IoAllocateAdapterChannel( - IN PADAPTER_OBJECT AdapterObject, - IN PDEVICE_OBJECT DeviceObject, - IN ULONG NumberOfMapRegisters, - IN PDRIVER_CONTROL ExecutionRoutine, - IN PVOID Context); - -#endif /* HALDMA_H */ +#ifndef HALDMA_H +#define HALDMA_H + +/* + * DMA Page Register Structure + * 080 DMA RESERVED + * 081 DMA Page Register (channel 2) + * 082 DMA Page Register (channel 3) + * 083 DMA Page Register (channel 1) + * 084 DMA RESERVED + * 085 DMA RESERVED + * 086 DMA RESERVED + * 087 DMA Page Register (channel 0) + * 088 DMA RESERVED + * 089 PS/2-DMA Page Register (channel 6) + * 08A PS/2-DMA Page Register (channel 7) + * 08B PS/2-DMA Page Register (channel 5) + * 08C PS/2-DMA RESERVED + * 08D PS/2-DMA RESERVED + * 08E PS/2-DMA RESERVED + * 08F PS/2-DMA Page Register (channel 4) + */ + +typedef struct _DMA_PAGE +{ + UCHAR Reserved1; + UCHAR Channel2; + UCHAR Channel3; + UCHAR Channel1; + UCHAR Reserved2[3]; + UCHAR Channel0; + UCHAR Reserved3; + UCHAR Channel6; + UCHAR Channel7; + UCHAR Channel5; + UCHAR Reserved4[3]; + UCHAR Channel4; +} DMA_PAGE, *PDMA_PAGE; + +/* + * DMA Channel Mask Register Structure + * + * MSB LSB + * x x x x x x x x + * ------------------- - ----- + * | | | 00 - Select channel 0 mask bit + * | | \---- 01 - Select channel 1 mask bit + * | | 10 - Select channel 2 mask bit + * | | 11 - Select channel 3 mask bit + * | | + * | \---------- 0 - Clear mask bit + * | 1 - Set mask bit + * | + * \----------------------- xx - Reserved + */ + +typedef struct _DMA_CHANNEL_MASK +{ + UCHAR Channel: 2; + UCHAR SetMask: 1; + UCHAR Reserved: 5; +} DMA_CHANNEL_MASK, *PDMA_CHANNEL_MASK; + +/* + * DMA Mask Register Structure + * + * MSB LSB + * x x x x x x x x + * \---/ - - ----- ----- + * | | | | | 00 - Channel 0 select + * | | | | \---- 01 - Channel 1 select + * | | | | 10 - Channel 2 select + * | | | | 11 - Channel 3 select + * | | | | + * | | | | 00 - Verify transfer + * | | | \------------ 01 - Write transfer + * | | | 10 - Read transfer + * | | | + * | | \-------------------- 0 - Autoinitialized + * | | 1 - Non-autoinitialized + * | | + * | \------------------------ 0 - Address increment select + * | + * | 00 - Demand mode + * \------------------------------ 01 - Single mode + * 10 - Block mode + * 11 - Cascade mode + */ + +typedef union _DMA_MODE +{ + struct + { + UCHAR Channel: 2; + UCHAR TransferType: 2; + UCHAR AutoInitialize: 1; + UCHAR AddressDecrement: 1; + UCHAR RequestMode: 2; + }; + UCHAR Byte; +} DMA_MODE, *PDMA_MODE; + +/* + * DMA Extended Mode Register Structure + * + * MSB LSB + * x x x x x x x x + * - - ----- ----- ----- + * | | | | | 00 - Channel 0 select + * | | | | \---- 01 - Channel 1 select + * | | | | 10 - Channel 2 select + * | | | | 11 - Channel 3 select + * | | | | + * | | | | 00 - 8-bit I/O, by bytes + * | | | \------------ 01 - 16-bit I/O, by words, address shifted + * | | | 10 - 32-bit I/O, by bytes + * | | | 11 - 16-bit I/O, by bytes + * | | | + * | | \---------------------- 00 - Compatible + * | | 01 - Type A + * | | 10 - Type B + * | | 11 - Burst + * | | + * | \---------------------------- 0 - Terminal Count is Output + * | + * \---------------------------------0 - Disable Stop Register + * 1 - Enable Stop Register + */ + +typedef union _DMA_EXTENDED_MODE +{ + struct + { + UCHAR ChannelNumber: 2; + UCHAR TransferSize: 2; + UCHAR TimingMode: 2; + UCHAR TerminalCountIsOutput: 1; + UCHAR EnableStopRegister: 1; + }; + UCHAR Byte; +} DMA_EXTENDED_MODE, *PDMA_EXTENDED_MODE; + +/* DMA Extended Mode Register Transfer Sizes */ +#define B_8BITS 0 +#define W_16BITS 1 +#define B_32BITS 2 +#define B_16BITS 3 + +/* DMA Extended Mode Register Timing */ +#define COMPATIBLE_TIMING 0 +#define TYPE_A_TIMING 1 +#define TYPE_B_TIMING 2 +#define BURST_TIMING 3 + +/* Channel Stop Registers for each Channel */ +typedef struct _DMA_CHANNEL_STOP +{ + UCHAR ChannelLow; + UCHAR ChannelMid; + UCHAR ChannelHigh; + UCHAR Reserved; +} DMA_CHANNEL_STOP, *PDMA_CHANNEL_STOP; + +/* Transfer Types */ +#define VERIFY_TRANSFER 0x00 +#define READ_TRANSFER 0x01 +#define WRITE_TRANSFER 0x02 + +/* Request Modes */ +#define DEMAND_REQUEST_MODE 0x00 +#define SINGLE_REQUEST_MODE 0x01 +#define BLOCK_REQUEST_MODE 0x02 +#define CASCADE_REQUEST_MODE 0x03 + +#define DMA_SETMASK 4 +#define DMA_CLEARMASK 0 +#define DMA_READ 4 +#define DMA_WRITE 8 +#define DMA_SINGLE_TRANSFER 0x40 +#define DMA_AUTO_INIT 0x10 + +typedef struct _DMA1_ADDRESS_COUNT +{ + UCHAR DmaBaseAddress; + UCHAR DmaBaseCount; +} DMA1_ADDRESS_COUNT, *PDMA1_ADDRESS_COUNT; + +typedef struct _DMA2_ADDRESS_COUNT +{ + UCHAR DmaBaseAddress; + UCHAR Reserved1; + UCHAR DmaBaseCount; + UCHAR Reserved2; +} DMA2_ADDRESS_COUNT, *PDMA2_ADDRESS_COUNT; + +typedef struct _DMA1_CONTROL +{ + DMA1_ADDRESS_COUNT DmaAddressCount[4]; + UCHAR DmaStatus; + UCHAR DmaRequest; + UCHAR SingleMask; + UCHAR Mode; + UCHAR ClearBytePointer; + UCHAR MasterClear; + UCHAR ClearMask; + UCHAR AllMask; +} DMA1_CONTROL, *PDMA1_CONTROL; + +typedef struct _DMA2_CONTROL +{ + DMA2_ADDRESS_COUNT DmaAddressCount[4]; + UCHAR DmaStatus; + UCHAR Reserved1; + UCHAR DmaRequest; + UCHAR Reserved2; + UCHAR SingleMask; + UCHAR Reserved3; + UCHAR Mode; + UCHAR Reserved4; + UCHAR ClearBytePointer; + UCHAR Reserved5; + UCHAR MasterClear; + UCHAR Reserved6; + UCHAR ClearMask; + UCHAR Reserved7; + UCHAR AllMask; + UCHAR Reserved8; +} DMA2_CONTROL, *PDMA2_CONTROL; + +/* This structure defines the I/O Map of the 82537 controller. */ +typedef struct _EISA_CONTROL +{ + /* DMA Controller 1 */ + DMA1_CONTROL DmaController1; /* 00h-0Fh */ + UCHAR Reserved1[16]; /* 0Fh-1Fh */ + + /* Interrupt Controller 1 (PIC) */ + UCHAR Pic1Operation; /* 20h */ + UCHAR Pic1Interrupt; /* 21h */ + UCHAR Reserved2[30]; /* 22h-3Fh */ + + /* Timer */ + UCHAR TimerCounter; /* 40h */ + UCHAR TimerMemoryRefresh; /* 41h */ + UCHAR Speaker; /* 42h */ + UCHAR TimerOperation; /* 43h */ + UCHAR TimerMisc; /* 44h */ + UCHAR Reserved3[2]; /* 45-46h */ + UCHAR TimerCounterControl; /* 47h */ + UCHAR TimerFailSafeCounter; /* 48h */ + UCHAR Reserved4; /* 49h */ + UCHAR TimerCounter2; /* 4Ah */ + UCHAR TimerOperation2; /* 4Bh */ + UCHAR Reserved5[20]; /* 4Ch-5Fh */ + + /* NMI / Keyboard / RTC */ + UCHAR Keyboard; /* 60h */ + UCHAR NmiStatus; /* 61h */ + UCHAR Reserved6[14]; /* 62h-6Fh */ + UCHAR NmiEnable; /* 70h */ + UCHAR Reserved7[15]; /* 71h-7Fh */ + + /* DMA Page Registers Controller 1 */ + DMA_PAGE DmaController1Pages; /* 80h-8Fh */ + UCHAR Reserved8[16]; /* 90h-9Fh */ + + /* Interrupt Controller 2 (PIC) */ + UCHAR Pic2Operation; /* 0A0h */ + UCHAR Pic2Interrupt; /* 0A1h */ + UCHAR Reserved9[30]; /* 0A2h-0BFh */ + + /* DMA Controller 2 */ + DMA1_CONTROL DmaController2; /* 0C0h-0CFh */ + + /* System Reserved Ports */ + UCHAR SystemReserved[816]; /* 0D0h-3FFh */ + + /* Extended DMA Registers, Controller 1 */ + UCHAR DmaHighByteCount1[8]; /* 400h-407h */ + UCHAR Reserved10[2]; /* 408h-409h */ + UCHAR DmaChainMode1; /* 40Ah */ + UCHAR DmaExtendedMode1; /* 40Bh */ + UCHAR DmaBufferControl; /* 40Ch */ + UCHAR Reserved11[84]; /* 40Dh-460h */ + UCHAR ExtendedNmiControl; /* 461h */ + UCHAR NmiCommand; /* 462h */ + UCHAR Reserved12; /* 463h */ + UCHAR BusMaster; /* 464h */ + UCHAR Reserved13[27]; /* 465h-47Fh */ + + /* DMA Page Registers Controller 2 */ + DMA_PAGE DmaController2Pages; /* 480h-48Fh */ + UCHAR Reserved14[48]; /* 490h-4BFh */ + + /* Extended DMA Registers, Controller 2 */ + UCHAR DmaHighByteCount2[16]; /* 4C0h-4CFh */ + + /* Edge/Level Control Registers */ + UCHAR Pic1EdgeLevel; /* 4D0h */ + UCHAR Pic2EdgeLevel; /* 4D1h */ + UCHAR Reserved15[2]; /* 4D2h-4D3h */ + + /* Extended DMA Registers, Controller 2 */ + UCHAR DmaChainMode2; /* 4D4h */ + UCHAR Reserved16; /* 4D5h */ + UCHAR DmaExtendedMode2; /* 4D6h */ + UCHAR Reserved17[9]; /* 4D7h-4DFh */ + + /* DMA Stop Registers */ + DMA_CHANNEL_STOP DmaChannelStop[8]; /* 4E0h-4FFh */ +} EISA_CONTROL, *PEISA_CONTROL; + +typedef struct _MAP_REGISTER_ENTRY +{ + PVOID VirtualAddress; + PHYSICAL_ADDRESS PhysicalAddress; + ULONG Counter; +} MAP_REGISTER_ENTRY, *PMAP_REGISTER_ENTRY; + +struct _ADAPTER_OBJECT { + /* + * New style DMA object definition. The fact that it is at the beginning + * of the ADAPTER_OBJECT structure allows us to easily implement the + * fallback implementation of IoGetDmaAdapter. + */ + DMA_ADAPTER DmaHeader; + + /* + * For normal adapter objects pointer to master adapter that takes care + * of channel allocation. For master adapter set to NULL. + */ + struct _ADAPTER_OBJECT *MasterAdapter; + + ULONG MapRegistersPerChannel; + PVOID AdapterBaseVa; + PMAP_REGISTER_ENTRY MapRegisterBase; + + ULONG NumberOfMapRegisters; + ULONG CommittedMapRegisters; + + PWAIT_CONTEXT_BLOCK CurrentWcb; + KDEVICE_QUEUE ChannelWaitQueue; + PKDEVICE_QUEUE RegisterWaitQueue; + LIST_ENTRY AdapterQueue; + KSPIN_LOCK SpinLock; + PRTL_BITMAP MapRegisters; + PUCHAR PagePort; + UCHAR ChannelNumber; + UCHAR AdapterNumber; + USHORT DmaPortAddress; + DMA_MODE AdapterMode; + BOOLEAN NeedsMapRegisters; + BOOLEAN MasterDevice; + BOOLEAN Width16Bits; + BOOLEAN ScatterGather; + BOOLEAN IgnoreCount; + BOOLEAN Dma32BitAddresses; + BOOLEAN Dma64BitAddresses; + LIST_ENTRY AdapterList; +} ADAPTER_OBJECT; + +typedef struct _GROW_WORK_ITEM { + WORK_QUEUE_ITEM WorkQueueItem; + PADAPTER_OBJECT AdapterObject; + ULONG NumberOfMapRegisters; +} GROW_WORK_ITEM, *PGROW_WORK_ITEM; + +#define MAP_BASE_SW_SG 1 + +PADAPTER_OBJECT STDCALL +HalpDmaAllocateMasterAdapter(VOID); + +PDMA_ADAPTER STDCALL +HalpGetDmaAdapter( + IN PVOID Context, + IN PDEVICE_DESCRIPTION DeviceDescription, + OUT PULONG NumberOfMapRegisters); + +VOID STDCALL +HalPutDmaAdapter( + PADAPTER_OBJECT AdapterObject); + +ULONG STDCALL +HalpDmaGetDmaAlignment( + PADAPTER_OBJECT AdapterObject); + +NTSTATUS STDCALL +IoAllocateAdapterChannel( + IN PADAPTER_OBJECT AdapterObject, + IN PDEVICE_OBJECT DeviceObject, + IN ULONG NumberOfMapRegisters, + IN PDRIVER_CONTROL ExecutionRoutine, + IN PVOID Context); + +#endif /* HALDMA_H */