--- trunk/reactos/hal/halx86/generic/dma.c 2005-08-22 10:29:51 UTC (rev 17471)
+++ trunk/reactos/hal/halx86/generic/dma.c 2005-08-22 10:47:29 UTC (rev 17472)
@@ -139,6 +139,13 @@
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;
}
/**
@@ -761,6 +768,24 @@
}
/**
+ * @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
*
* Internal routine to free DMA adapter and resources for reuse. It's exported
@@ -1431,7 +1456,7 @@
{
ULONG CurrentLength;
ULONG_PTR CurrentAddress;
- ULONG PageOffset;
+ ULONG ByteOffset;
PVOID VirtualAddress;
VirtualAddress = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority);
@@ -1446,20 +1471,20 @@
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 @@
{
RtlCopyMemory(
(PVOID)CurrentAddress,
- (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + PageOffset),
+ (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
CurrentLength);
}
@@ -1613,9 +1638,9 @@
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 @@
/*
* 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 @@
* 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 @@
{
UseMapRegisters = TRUE;
PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
- PhysicalAddress.QuadPart += PageOffset;
+ PhysicalAddress.QuadPart += ByteOffset;
TransferLength = *Length;
RealMapRegisterBase->Counter = ~0;
Counter = 0;
@@ -1735,8 +1760,7 @@
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 @@
{
UseMapRegisters = TRUE;
PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
- PhysicalAddress.QuadPart += PageOffset;
+ PhysicalAddress.QuadPart += ByteOffset;
}
}
@@ -1791,7 +1815,7 @@
if (AdapterObject->IgnoreCount)
{
RtlZeroMemory((PUCHAR)RealMapRegisterBase[Counter].VirtualAddress +
- PageOffset, TransferLength);
+ ByteOffset, TransferLength);
}
}
--- trunk/reactos/hal/halx86/include/haldma.h 2005-08-22 10:29:51 UTC (rev 17471)
+++ trunk/reactos/hal/halx86/include/haldma.h 2005-08-22 10:47:29 UTC (rev 17472)
@@ -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 */