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