712bf129ba3a85ed41a694f26f91b4aaaa155d7d
[reactos.git] / reactos / ntoskrnl / io / pnpdma.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/pnpdma.c
6 * PURPOSE: PnP manager DMA routines
7 *
8 * PROGRAMMERS: Filip Navara (xnavara@volny.cz)
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16 #include <ddk/wdmguid.h>
17
18 typedef struct _DMA_ADAPTER_INTERNAL {
19 USHORT Version;
20 USHORT Size;
21 PDMA_OPERATIONS DmaOperations;
22 PADAPTER_OBJECT HalAdapter;
23 } DMA_ADAPTER_INTERNAL, *PDMA_ADAPTER_INTERNAL;
24
25 /* FUNCTIONS *****************************************************************/
26
27 VOID
28 STDCALL
29 IopPutDmaAdapter(
30 PDMA_ADAPTER DmaAdapter)
31 {
32 DPRINT("IopPutDmaAdapter\n");
33 ExFreePool(DmaAdapter);
34 }
35
36
37 PVOID
38 STDCALL
39 IopAllocateCommonBuffer(
40 IN PDMA_ADAPTER DmaAdapter,
41 IN ULONG Length,
42 OUT PPHYSICAL_ADDRESS LogicalAddress,
43 IN BOOLEAN CacheEnabled)
44 {
45 DPRINT("IopAllocateCommonBuffer\n");
46 return HalAllocateCommonBuffer(
47 ((PDMA_ADAPTER_INTERNAL)DmaAdapter)->HalAdapter,
48 Length, LogicalAddress, CacheEnabled);
49 }
50
51
52 VOID
53 STDCALL
54 IopFreeCommonBuffer(
55 IN PDMA_ADAPTER DmaAdapter,
56 IN ULONG Length,
57 IN PHYSICAL_ADDRESS LogicalAddress,
58 IN PVOID VirtualAddress,
59 IN BOOLEAN CacheEnabled)
60 {
61 DPRINT("IopFreeCommonBuffer\n");
62 HalFreeCommonBuffer(
63 ((PDMA_ADAPTER_INTERNAL)DmaAdapter)->HalAdapter,
64 Length, LogicalAddress, VirtualAddress, CacheEnabled);
65 }
66
67
68 NTSTATUS
69 STDCALL
70 IopAllocateAdapterChannel(
71 IN PDMA_ADAPTER DmaAdapter,
72 IN PDEVICE_OBJECT DeviceObject,
73 IN ULONG NumberOfMapRegisters,
74 IN PDRIVER_CONTROL ExecutionRoutine,
75 IN PVOID Context)
76 {
77 DPRINT("IopAllocateAdapterChannel\n");
78 return IoAllocateAdapterChannel(
79 ((PDMA_ADAPTER_INTERNAL)DmaAdapter)->HalAdapter,
80 DeviceObject, NumberOfMapRegisters, ExecutionRoutine, Context);
81 }
82
83
84 BOOLEAN
85 STDCALL
86 IopFlushAdapterBuffers(
87 IN PDMA_ADAPTER DmaAdapter,
88 IN PMDL Mdl,
89 IN PVOID MapRegisterBase,
90 IN PVOID CurrentVa,
91 IN ULONG Length,
92 IN BOOLEAN WriteToDevice)
93 {
94 DPRINT("IopFlushAdapterBuffers\n");
95 return IoFlushAdapterBuffers(
96 ((PDMA_ADAPTER_INTERNAL)DmaAdapter)->HalAdapter,
97 Mdl, MapRegisterBase, CurrentVa, Length, WriteToDevice);
98 }
99
100
101 VOID
102 STDCALL
103 IopFreeAdapterChannel(
104 IN PDMA_ADAPTER DmaAdapter)
105 {
106 DPRINT("IopFreeAdapterChannel\n");
107 IoFreeAdapterChannel(((PDMA_ADAPTER_INTERNAL)DmaAdapter)->HalAdapter);
108 }
109
110
111 VOID
112 STDCALL
113 IopFreeMapRegisters(
114 IN PDMA_ADAPTER DmaAdapter,
115 PVOID MapRegisterBase,
116 ULONG NumberOfMapRegisters)
117 {
118 DPRINT("IopFreeMapRegisters\n");
119 IoFreeMapRegisters(
120 ((PDMA_ADAPTER_INTERNAL)DmaAdapter)->HalAdapter,
121 MapRegisterBase, NumberOfMapRegisters);
122 }
123
124
125 PHYSICAL_ADDRESS
126 STDCALL
127 IopMapTransfer(
128 IN PDMA_ADAPTER DmaAdapter,
129 IN PMDL Mdl,
130 IN PVOID MapRegisterBase,
131 IN PVOID CurrentVa,
132 IN OUT PULONG Length,
133 IN BOOLEAN WriteToDevice)
134 {
135 DPRINT("IopMapTransfer\n");
136 return IoMapTransfer(
137 ((PDMA_ADAPTER_INTERNAL)DmaAdapter)->HalAdapter,
138 Mdl, MapRegisterBase, CurrentVa, Length, WriteToDevice);
139 }
140
141
142 ULONG
143 STDCALL
144 IopGetDmaAlignment(
145 IN PDMA_ADAPTER DmaAdapter)
146 {
147 DPRINT("IopGetDmaAlignment\n");
148 /* FIXME: This is actually true only on i386 and Amd64 */
149 return 1L;
150 }
151
152
153 ULONG
154 STDCALL
155 IopReadDmaCounter(
156 IN PDMA_ADAPTER DmaAdapter)
157 {
158 DPRINT("IopReadDmaCounter\n");
159 return HalReadDmaCounter(((PDMA_ADAPTER_INTERNAL)DmaAdapter)->HalAdapter);
160 }
161
162
163 NTSTATUS
164 STDCALL
165 IopGetScatterGatherList(
166 IN PDMA_ADAPTER DmaAdapter,
167 IN PDEVICE_OBJECT DeviceObject,
168 IN PMDL Mdl,
169 IN PVOID CurrentVa,
170 IN ULONG Length,
171 IN PDRIVER_LIST_CONTROL ExecutionRoutine,
172 IN PVOID Context,
173 IN BOOLEAN WriteToDevice)
174 {
175 DPRINT("IopGetScatterGatherList\n");
176 /* FIXME */
177 return STATUS_UNSUCCESSFUL;
178 }
179
180
181 VOID
182 STDCALL
183 IopPutScatterGatherList(
184 IN PDMA_ADAPTER DmaAdapter,
185 IN PSCATTER_GATHER_LIST ScatterGather,
186 IN BOOLEAN WriteToDevice)
187 {
188 DPRINT("IopPutScatterGatherList\n");
189 /* FIXME */
190 }
191
192 /*
193 * @implemented
194 */
195 PDMA_ADAPTER
196 STDCALL
197 IoGetDmaAdapter(
198 IN PDEVICE_OBJECT PhysicalDeviceObject,
199 IN PDEVICE_DESCRIPTION DeviceDescription,
200 IN OUT PULONG NumberOfMapRegisters)
201 {
202 static DMA_OPERATIONS HalDmaOperations = {
203 sizeof(DMA_OPERATIONS),
204 IopPutDmaAdapter,
205 IopAllocateCommonBuffer,
206 IopFreeCommonBuffer,
207 IopAllocateAdapterChannel,
208 IopFlushAdapterBuffers,
209 IopFreeAdapterChannel,
210 IopFreeMapRegisters,
211 IopMapTransfer,
212 IopGetDmaAlignment,
213 IopReadDmaCounter,
214 IopGetScatterGatherList,
215 IopPutScatterGatherList
216 };
217 NTSTATUS Status;
218 ULONG ResultLength;
219 BUS_INTERFACE_STANDARD BusInterface;
220 IO_STATUS_BLOCK IoStatusBlock;
221 IO_STACK_LOCATION Stack;
222 DEVICE_DESCRIPTION PrivateDeviceDescription;
223 PDMA_ADAPTER Result = NULL;
224 PDMA_ADAPTER_INTERNAL ResultInternal = NULL;
225 PADAPTER_OBJECT HalAdapter;
226
227 DPRINT("IoGetDmaAdapter called\n");
228
229 /*
230 * Try to create DMA adapter through bus driver
231 */
232 if (PhysicalDeviceObject != NULL)
233 {
234 if (DeviceDescription->InterfaceType == 0x0F /*PNPBus*/ ||
235 DeviceDescription->InterfaceType == (INTERFACE_TYPE)0xFFFFFFFF)
236 {
237 RtlCopyMemory(&PrivateDeviceDescription, DeviceDescription,
238 sizeof(DEVICE_DESCRIPTION));
239 Status = IoGetDeviceProperty(PhysicalDeviceObject,
240 DevicePropertyLegacyBusType, sizeof(INTERFACE_TYPE),
241 &PrivateDeviceDescription.InterfaceType, &ResultLength);
242 if (!NT_SUCCESS(Status))
243 {
244 PrivateDeviceDescription.InterfaceType = Internal;
245 }
246 DeviceDescription = &PrivateDeviceDescription;
247 }
248
249 Stack.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
250 Stack.Parameters.QueryInterface.Version = 1;
251 Stack.Parameters.QueryInterface.Interface = (PINTERFACE)&BusInterface;
252 Stack.Parameters.QueryInterface.InterfaceType =
253 &GUID_BUS_INTERFACE_STANDARD;
254 Status = IopInitiatePnpIrp(PhysicalDeviceObject, &IoStatusBlock,
255 IRP_MN_QUERY_INTERFACE, &Stack);
256 if (NT_SUCCESS(Status))
257 {
258 Result = BusInterface.GetDmaAdapter(BusInterface.Context,
259 DeviceDescription, NumberOfMapRegisters);
260 BusInterface.InterfaceDereference(BusInterface.Context);
261 if (Result != NULL)
262 return Result;
263 }
264 }
265
266 /*
267 * Fallback to HAL
268 */
269
270 HalAdapter = HalGetAdapter(DeviceDescription, NumberOfMapRegisters);
271 if (HalAdapter == NULL)
272 return NULL;
273
274 ResultInternal = ExAllocatePool(PagedPool, sizeof(DMA_ADAPTER_INTERNAL));
275 if (ResultInternal == NULL)
276 return NULL;
277
278 ResultInternal->Version = DEVICE_DESCRIPTION_VERSION;
279 ResultInternal->Size = sizeof(DMA_ADAPTER);
280 ResultInternal->DmaOperations = &HalDmaOperations;
281 ResultInternal->HalAdapter = HalAdapter;
282
283 return (PDMA_ADAPTER)ResultInternal;
284 }
285
286 /* EOF */