Export the HalGetDmaAdapter callback and use some nice macros where appropriate.
authorFilip Navara <filip.navara@gmail.com>
Mon, 22 Aug 2005 10:47:29 +0000 (10:47 +0000)
committerFilip Navara <filip.navara@gmail.com>
Mon, 22 Aug 2005 10:47:29 +0000 (10:47 +0000)
svn path=/trunk/; revision=17472

reactos/hal/halx86/generic/dma.c
reactos/hal/halx86/include/haldma.h

index 12eec16..fd0e038 100644 (file)
@@ -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);
          }
       }
 
index 0c98a5a..163cd1f 100644 (file)
-#ifndef HALDMA_H\r
-#define HALDMA_H\r
-\r
-/*\r
- * DMA Page Register Structure  \r
- * 080     DMA        RESERVED\r
- * 081     DMA        Page Register (channel 2)\r
- * 082     DMA        Page Register (channel 3)\r
- * 083     DMA        Page Register (channel 1)\r
- * 084     DMA        RESERVED\r
- * 085     DMA        RESERVED\r
- * 086     DMA        RESERVED\r
- * 087     DMA        Page Register (channel 0)\r
- * 088     DMA        RESERVED\r
- * 089     PS/2-DMA   Page Register (channel 6)\r
- * 08A     PS/2-DMA   Page Register (channel 7)\r
- * 08B     PS/2-DMA   Page Register (channel 5)\r
- * 08C     PS/2-DMA   RESERVED\r
- * 08D     PS/2-DMA   RESERVED\r
- * 08E     PS/2-DMA   RESERVED\r
- * 08F     PS/2-DMA   Page Register (channel 4)\r
- */\r
-\r
-typedef struct _DMA_PAGE\r
-{\r
-   UCHAR Reserved1;\r
-   UCHAR Channel2;\r
-   UCHAR Channel3;\r
-   UCHAR Channel1;\r
-   UCHAR Reserved2[3];\r
-   UCHAR Channel0;\r
-   UCHAR Reserved3;\r
-   UCHAR Channel6;\r
-   UCHAR Channel7;\r
-   UCHAR Channel5;\r
-   UCHAR Reserved4[3];\r
-   UCHAR Channel4;\r
-} DMA_PAGE, *PDMA_PAGE;\r
-\r
-/*\r
- * DMA Channel Mask Register Structure\r
- *\r
- * MSB                             LSB\r
- *       x   x   x   x     x   x   x   x\r
- *       -------------------   -   -----\r
- *                |            |     |     00 - Select channel 0 mask bit\r
- *                |            |     \---- 01 - Select channel 1 mask bit\r
- *                |            |           10 - Select channel 2 mask bit\r
- *                |            |           11 - Select channel 3 mask bit\r
- *                |            |\r
- *                |            \----------  0 - Clear mask bit\r
- *                |                         1 - Set mask bit\r
- *                |\r
- *                \----------------------- xx - Reserved\r
- */\r
-\r
-typedef struct _DMA_CHANNEL_MASK\r
-{\r
-   UCHAR Channel: 2;\r
-   UCHAR SetMask: 1;\r
-   UCHAR Reserved: 5;\r
-} DMA_CHANNEL_MASK, *PDMA_CHANNEL_MASK;\r
-\r
-/*\r
- * DMA Mask Register Structure \r
- *\r
- * MSB                             LSB\r
- *    x   x   x   x     x   x   x   x\r
- *    \---/   -   -     -----   -----\r
- *      |     |   |       |       |     00 - Channel 0 select\r
- *      |     |   |       |       \---- 01 - Channel 1 select\r
- *      |     |   |       |             10 - Channel 2 select\r
- *      |     |   |       |             11 - Channel 3 select\r
- *      |     |   |       |\r
- *      |     |   |       |             00 - Verify transfer\r
- *      |     |   |       \------------ 01 - Write transfer\r
- *      |     |   |                     10 - Read transfer\r
- *      |     |   |\r
- *      |     |   \--------------------  0 - Autoinitialized\r
- *      |     |                          1 - Non-autoinitialized\r
- *      |     |\r
- *      |     \------------------------  0 - Address increment select\r
- *      |\r
- *      |                               00 - Demand mode\r
- *      \------------------------------ 01 - Single mode\r
- *                                      10 - Block mode\r
- *                                      11 - Cascade mode\r
- */\r
-\r
-typedef union _DMA_MODE\r
-{\r
-   struct\r
-   {\r
-      UCHAR Channel: 2;\r
-      UCHAR TransferType: 2;\r
-      UCHAR AutoInitialize: 1;\r
-      UCHAR AddressDecrement: 1;\r
-      UCHAR RequestMode: 2;\r
-   };\r
-   UCHAR Byte;\r
-} DMA_MODE, *PDMA_MODE;\r
-\r
-/*\r
- * DMA Extended Mode Register Structure \r
- *\r
- * MSB                             LSB\r
- *    x   x   x   x     x   x   x   x\r
- *    -   -   -----     -----   -----\r
- *    |   |     |         |       |     00 - Channel 0 select\r
- *    |   |     |         |       \---- 01 - Channel 1 select\r
- *    |   |     |         |             10 - Channel 2 select\r
- *    |   |     |         |             11 - Channel 3 select\r
- *    |   |     |         | \r
- *    |   |     |         |             00 - 8-bit I/O, by bytes\r
- *    |   |     |         \------------ 01 - 16-bit I/O, by words, address shifted\r
- *    |   |     |                       10 - 32-bit I/O, by bytes\r
- *    |   |     |                       11 - 16-bit I/O, by bytes\r
- *    |   |     |\r
- *    |   |     \---------------------- 00 - Compatible\r
- *    |   |                             01 - Type A\r
- *    |   |                             10 - Type B\r
- *    |   |                             11 - Burst\r
- *    |   |\r
- *    |   \---------------------------- 0 - Terminal Count is Output\r
- *    |                                 \r
- *    \---------------------------------0 - Disable Stop Register\r
- *                                      1 - Enable Stop Register\r
- */\r
-\r
-typedef union _DMA_EXTENDED_MODE\r
-{\r
-   struct\r
-   {\r
-      UCHAR ChannelNumber: 2;\r
-      UCHAR TransferSize: 2;\r
-      UCHAR TimingMode: 2;\r
-      UCHAR TerminalCountIsOutput: 1;\r
-      UCHAR EnableStopRegister: 1;\r
-   };\r
-   UCHAR Byte;\r
-} DMA_EXTENDED_MODE, *PDMA_EXTENDED_MODE;\r
-\r
-/* DMA Extended Mode Register Transfer Sizes */\r
-#define B_8BITS 0\r
-#define W_16BITS 1\r
-#define B_32BITS 2\r
-#define B_16BITS 3\r
-\r
-/* DMA Extended Mode Register Timing */\r
-#define COMPATIBLE_TIMING 0\r
-#define TYPE_A_TIMING 1\r
-#define TYPE_B_TIMING 2\r
-#define BURST_TIMING 3\r
-\r
-/* Channel Stop Registers for each Channel */\r
-typedef struct _DMA_CHANNEL_STOP\r
-{\r
-   UCHAR ChannelLow;\r
-   UCHAR ChannelMid;\r
-   UCHAR ChannelHigh;\r
-   UCHAR Reserved;\r
-} DMA_CHANNEL_STOP, *PDMA_CHANNEL_STOP;\r
-\r
-/* Transfer Types */\r
-#define VERIFY_TRANSFER 0x00\r
-#define READ_TRANSFER 0x01\r
-#define WRITE_TRANSFER 0x02\r
-\r
-/* Request Modes */\r
-#define DEMAND_REQUEST_MODE 0x00\r
-#define SINGLE_REQUEST_MODE 0x01\r
-#define BLOCK_REQUEST_MODE 0x02\r
-#define CASCADE_REQUEST_MODE 0x03\r
-\r
-#define DMA_SETMASK 4\r
-#define DMA_CLEARMASK 0\r
-#define DMA_READ 4\r
-#define DMA_WRITE 8\r
-#define DMA_SINGLE_TRANSFER 0x40\r
-#define DMA_AUTO_INIT 0x10\r
-\r
-typedef struct _DMA1_ADDRESS_COUNT\r
-{\r
-   UCHAR DmaBaseAddress;\r
-   UCHAR DmaBaseCount; \r
-} DMA1_ADDRESS_COUNT, *PDMA1_ADDRESS_COUNT;\r
-\r
-typedef struct _DMA2_ADDRESS_COUNT\r
-{\r
-   UCHAR DmaBaseAddress;\r
-   UCHAR Reserved1;\r
-   UCHAR DmaBaseCount; \r
-   UCHAR Reserved2;\r
-} DMA2_ADDRESS_COUNT, *PDMA2_ADDRESS_COUNT;\r
-\r
-typedef struct _DMA1_CONTROL\r
-{\r
-   DMA1_ADDRESS_COUNT DmaAddressCount[4];\r
-   UCHAR DmaStatus;\r
-   UCHAR DmaRequest;\r
-   UCHAR SingleMask; \r
-   UCHAR Mode;\r
-   UCHAR ClearBytePointer;\r
-   UCHAR MasterClear;\r
-   UCHAR ClearMask;\r
-   UCHAR AllMask; \r
-} DMA1_CONTROL, *PDMA1_CONTROL;\r
-\r
-typedef struct _DMA2_CONTROL\r
-{\r
-   DMA2_ADDRESS_COUNT DmaAddressCount[4];\r
-   UCHAR DmaStatus;\r
-   UCHAR Reserved1;\r
-   UCHAR DmaRequest;\r
-   UCHAR Reserved2;\r
-   UCHAR SingleMask;\r
-   UCHAR Reserved3;\r
-   UCHAR Mode;\r
-   UCHAR Reserved4;\r
-   UCHAR ClearBytePointer;\r
-   UCHAR Reserved5;\r
-   UCHAR MasterClear;\r
-   UCHAR Reserved6;\r
-   UCHAR ClearMask;\r
-   UCHAR Reserved7;\r
-   UCHAR AllMask;\r
-   UCHAR Reserved8;\r
-} DMA2_CONTROL, *PDMA2_CONTROL;\r
-\r
-/* This structure defines the I/O Map of the 82537 controller. */\r
-typedef struct _EISA_CONTROL\r
-{\r
-   /* DMA Controller 1 */\r
-   DMA1_CONTROL DmaController1;         /* 00h-0Fh */\r
-   UCHAR Reserved1[16];                 /* 0Fh-1Fh */ \r
-   \r
-   /* Interrupt Controller 1 (PIC) */\r
-   UCHAR Pic1Operation;                 /* 20h     */\r
-   UCHAR Pic1Interrupt;                 /* 21h     */\r
-   UCHAR Reserved2[30];                 /* 22h-3Fh */\r
-   \r
-   /* Timer */\r
-   UCHAR TimerCounter;                  /* 40h     */\r
-   UCHAR TimerMemoryRefresh;            /* 41h     */\r
-   UCHAR Speaker;                       /* 42h     */\r
-   UCHAR TimerOperation;                /* 43h     */\r
-   UCHAR TimerMisc;                     /* 44h     */\r
-   UCHAR Reserved3[2];                  /* 45-46h  */\r
-   UCHAR TimerCounterControl;           /* 47h     */\r
-   UCHAR TimerFailSafeCounter;          /* 48h     */\r
-   UCHAR Reserved4;                     /* 49h     */\r
-   UCHAR TimerCounter2;                 /* 4Ah     */\r
-   UCHAR TimerOperation2;               /* 4Bh     */\r
-   UCHAR Reserved5[20];                 /* 4Ch-5Fh */\r
-   \r
-   /* NMI / Keyboard / RTC */\r
-   UCHAR Keyboard;                      /* 60h     */\r
-   UCHAR NmiStatus;                     /* 61h     */\r
-   UCHAR Reserved6[14];                 /* 62h-6Fh */\r
-   UCHAR NmiEnable;                     /* 70h     */\r
-   UCHAR Reserved7[15];                 /* 71h-7Fh */\r
-   \r
-   /* DMA Page Registers Controller 1 */\r
-   DMA_PAGE DmaController1Pages;        /* 80h-8Fh */\r
-   UCHAR Reserved8[16];                 /* 90h-9Fh */\r
-   \r
-    /* Interrupt Controller 2 (PIC) */\r
-   UCHAR Pic2Operation;                 /* 0A0h      */\r
-   UCHAR Pic2Interrupt;                 /* 0A1h      */\r
-   UCHAR Reserved9[30];                 /* 0A2h-0BFh */\r
-   \r
-   /* DMA Controller 2 */\r
-   DMA1_CONTROL DmaController2;         /* 0C0h-0CFh */\r
-   \r
-   /* System Reserved Ports */\r
-   UCHAR SystemReserved[816];           /* 0D0h-3FFh */\r
-   \r
-   /* Extended DMA Registers, Controller 1 */\r
-   UCHAR DmaHighByteCount1[8];          /* 400h-407h */\r
-   UCHAR Reserved10[2];                 /* 408h-409h */\r
-   UCHAR DmaChainMode1;                 /* 40Ah      */\r
-   UCHAR DmaExtendedMode1;              /* 40Bh      */\r
-   UCHAR DmaBufferControl;              /* 40Ch      */\r
-   UCHAR Reserved11[84];                /* 40Dh-460h */\r
-   UCHAR ExtendedNmiControl;            /* 461h      */\r
-   UCHAR NmiCommand;                    /* 462h      */\r
-   UCHAR Reserved12;                    /* 463h      */\r
-   UCHAR BusMaster;                     /* 464h      */\r
-   UCHAR Reserved13[27];                /* 465h-47Fh */\r
-   \r
-   /* DMA Page Registers Controller 2 */\r
-   DMA_PAGE DmaController2Pages;        /* 480h-48Fh */\r
-   UCHAR Reserved14[48];                /* 490h-4BFh */\r
-   \r
-   /* Extended DMA Registers, Controller 2 */\r
-   UCHAR DmaHighByteCount2[16];         /* 4C0h-4CFh */\r
-   \r
-   /* Edge/Level Control Registers */\r
-   UCHAR Pic1EdgeLevel;                 /* 4D0h      */\r
-   UCHAR Pic2EdgeLevel;                 /* 4D1h      */\r
-   UCHAR Reserved15[2];                 /* 4D2h-4D3h */\r
-  \r
-   /* Extended DMA Registers, Controller 2 */\r
-   UCHAR DmaChainMode2;                 /* 4D4h      */\r
-   UCHAR Reserved16;                    /* 4D5h      */\r
-   UCHAR DmaExtendedMode2;              /* 4D6h      */\r
-   UCHAR Reserved17[9];                 /* 4D7h-4DFh */\r
-   \r
-   /* DMA Stop Registers */\r
-   DMA_CHANNEL_STOP DmaChannelStop[8];  /* 4E0h-4FFh */\r
-} EISA_CONTROL, *PEISA_CONTROL;\r
-\r
-typedef struct _MAP_REGISTER_ENTRY\r
-{\r
-   PVOID VirtualAddress;\r
-   PHYSICAL_ADDRESS PhysicalAddress;\r
-   ULONG Counter;\r
-} MAP_REGISTER_ENTRY, *PMAP_REGISTER_ENTRY;\r
-\r
-struct _ADAPTER_OBJECT {\r
-   /*\r
-    * New style DMA object definition. The fact that it is at the beginning\r
-    * of the ADAPTER_OBJECT structure allows us to easily implement the\r
-    * fallback implementation of IoGetDmaAdapter.\r
-    */\r
-   DMA_ADAPTER DmaHeader;\r
-\r
-   /*\r
-    * For normal adapter objects pointer to master adapter that takes care\r
-    * of channel allocation. For master adapter set to NULL.\r
-    */ \r
-   struct _ADAPTER_OBJECT *MasterAdapter;\r
-\r
-   ULONG MapRegistersPerChannel;\r
-   PVOID AdapterBaseVa;\r
-   PMAP_REGISTER_ENTRY MapRegisterBase;\r
-\r
-   ULONG NumberOfMapRegisters;\r
-   ULONG CommittedMapRegisters;\r
-\r
-   PWAIT_CONTEXT_BLOCK CurrentWcb;\r
-   KDEVICE_QUEUE ChannelWaitQueue;\r
-   PKDEVICE_QUEUE RegisterWaitQueue;\r
-   LIST_ENTRY AdapterQueue;\r
-   KSPIN_LOCK SpinLock;\r
-   PRTL_BITMAP MapRegisters;\r
-   PUCHAR PagePort;\r
-   UCHAR ChannelNumber;\r
-   UCHAR AdapterNumber;\r
-   USHORT DmaPortAddress;\r
-   DMA_MODE AdapterMode;\r
-   BOOLEAN NeedsMapRegisters;\r
-   BOOLEAN MasterDevice;\r
-   BOOLEAN Width16Bits;\r
-   BOOLEAN ScatterGather;\r
-   BOOLEAN IgnoreCount;\r
-   BOOLEAN Dma32BitAddresses;\r
-   BOOLEAN Dma64BitAddresses;\r
-   LIST_ENTRY AdapterList;\r
-} ADAPTER_OBJECT;\r
\r
-typedef struct _GROW_WORK_ITEM {\r
-   WORK_QUEUE_ITEM WorkQueueItem;\r
-   PADAPTER_OBJECT AdapterObject;\r
-   ULONG NumberOfMapRegisters;\r
-} GROW_WORK_ITEM, *PGROW_WORK_ITEM;\r
-\r
-#define MAP_BASE_SW_SG 1\r
-\r
-PADAPTER_OBJECT STDCALL\r
-HalpDmaAllocateMasterAdapter(VOID);\r
-\r
-VOID STDCALL\r
-HalPutDmaAdapter(\r
-   PADAPTER_OBJECT AdapterObject);\r
-\r
-ULONG STDCALL\r
-HalpDmaGetDmaAlignment(\r
-   PADAPTER_OBJECT AdapterObject);\r
-\r
-NTSTATUS STDCALL\r
-IoAllocateAdapterChannel(\r
-   IN PADAPTER_OBJECT AdapterObject,\r
-   IN PDEVICE_OBJECT DeviceObject,\r
-   IN ULONG NumberOfMapRegisters,\r
-   IN PDRIVER_CONTROL ExecutionRoutine,\r
-   IN PVOID Context);\r
-\r
-#endif /* HALDMA_H */\r
+#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 */