Export the HalGetDmaAdapter callback and use some nice macros where appropriate.

svn path=/trunk/; revision=17472
This commit is contained in:
Filip Navara 2005-08-22 10:47:29 +00:00
parent 8872cc5e5d
commit 4fd4530977
2 changed files with 439 additions and 409 deletions

View 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);
}
}

View file

@ -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 */