Fixed some hal dispatch table issues.
[reactos.git] / reactos / hal / halx86 / bus.c
1 /* $Id: bus.c,v 1.6 2003/02/26 14:14:03 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/hal/x86/bus.c
6 * PURPOSE: Bus functions
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 *
11 *
12 * TODO:
13 * - Add bus handler functions for all busses
14 */
15
16 /* INCLUDES *****************************************************************/
17
18 #include <ddk/ntddk.h>
19 #include <hal.h>
20 #include <bus.h>
21
22 #define NDEBUG
23 #include <internal/debug.h>
24
25 /* GLOBALS *******************************************************************/
26
27 #define TAG_BUS TAG('B', 'U', 'S', 'H')
28
29 KSPIN_LOCK HalpBusHandlerSpinLock = {0,};
30 LIST_ENTRY HalpBusHandlerList;
31
32
33 /* FUNCTIONS *****************************************************************/
34
35 static NTSTATUS STDCALL
36 HalpNoAdjustResourceList(PBUS_HANDLER BusHandler,
37 ULONG BusNumber,
38 PCM_RESOURCE_LIST Resources)
39 {
40 return STATUS_UNSUCCESSFUL;
41 }
42
43
44 static NTSTATUS STDCALL
45 HalpNoAssignSlotResources(PBUS_HANDLER BusHandler,
46 ULONG BusNumber,
47 PUNICODE_STRING RegistryPath,
48 PUNICODE_STRING DriverClassName,
49 PDRIVER_OBJECT DriverObject,
50 PDEVICE_OBJECT DeviceObject,
51 ULONG SlotNumber,
52 PCM_RESOURCE_LIST *AllocatedResources)
53 {
54 return STATUS_NOT_SUPPORTED;
55 }
56
57
58 static ULONG STDCALL
59 HalpNoBusData(PBUS_HANDLER BusHandler,
60 ULONG BusNumber,
61 ULONG SlotNumber,
62 PVOID Buffer,
63 ULONG Offset,
64 ULONG Length)
65 {
66 return 0;
67 }
68
69
70 static ULONG STDCALL
71 HalpNoGetInterruptVector(PBUS_HANDLER BusHandler,
72 ULONG BusNumber,
73 ULONG BusInterruptLevel,
74 ULONG BusInterruptVector,
75 PKIRQL Irql,
76 PKAFFINITY Affinity)
77 {
78 return 0;
79 }
80
81
82 static ULONG STDCALL
83 HalpNoTranslateBusAddress(PBUS_HANDLER BusHandler,
84 ULONG BusNumber,
85 PHYSICAL_ADDRESS BusAddress,
86 PULONG AddressSpace,
87 PPHYSICAL_ADDRESS TranslatedAddress)
88 {
89 return 0;
90 }
91
92
93 PBUS_HANDLER
94 HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType,
95 BUS_DATA_TYPE BusDataType,
96 ULONG BusNumber)
97 {
98 PBUS_HANDLER BusHandler = NULL;
99
100 DPRINT("HalpAllocateBusHandler()\n");
101
102 BusHandler = ExAllocatePoolWithTag(NonPagedPool,
103 sizeof(BUS_HANDLER),
104 TAG_BUS);
105 if (BusHandler == NULL)
106 return NULL;
107
108 RtlZeroMemory(BusHandler,
109 sizeof(BUS_HANDLER));
110
111 InsertTailList(&HalpBusHandlerList,
112 &BusHandler->Entry);
113
114 BusHandler->InterfaceType = InterfaceType;
115 BusHandler->BusDataType = BusDataType;
116 BusHandler->BusNumber = BusNumber;
117
118 /* initialize default bus handler functions */
119 BusHandler->GetBusData = HalpNoBusData;
120 BusHandler->SetBusData = HalpNoBusData;
121 BusHandler->AdjustResourceList = HalpNoAdjustResourceList;
122 BusHandler->AssignSlotResources = HalpNoAssignSlotResources;
123 BusHandler->GetInterruptVector = HalpNoGetInterruptVector;
124 BusHandler->TranslateBusAddress = HalpNoTranslateBusAddress;
125
126 /* any more ?? */
127
128 DPRINT("HalpAllocateBusHandler() done\n");
129
130 return BusHandler;
131 }
132
133
134 VOID
135 HalpInitBusHandlers(VOID)
136 {
137 PBUS_HANDLER BusHandler;
138
139 /* General preparations */
140 KeInitializeSpinLock(&HalpBusHandlerSpinLock);
141 InitializeListHead(&HalpBusHandlerList);
142
143 /* Initialize hal dispatch tables */
144 HalQuerySystemInformation = HalpQuerySystemInformation;
145
146 #if 0
147 HalSetSystemInformation = HalpSetSystemInformation;
148
149 HalQueryBusSlots = HalpQueryBusSlots;
150 #endif
151
152 /* Add system bus handler */
153 BusHandler = HalpAllocateBusHandler(Internal,
154 ConfigurationSpaceUndefined,
155 0);
156 if (BusHandler == NULL)
157 return;
158 BusHandler->GetInterruptVector =
159 (pGetInterruptVector)HalpGetSystemInterruptVector;
160 BusHandler->TranslateBusAddress =
161 (pTranslateBusAddress)HalpTranslateSystemBusAddress;
162
163 /* Add cmos bus handler */
164 BusHandler = HalpAllocateBusHandler(InterfaceTypeUndefined,
165 Cmos,
166 0);
167 if (BusHandler == NULL)
168 return;
169 BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData;
170 BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData;
171
172 /* Add isa bus handler */
173 BusHandler = HalpAllocateBusHandler(Isa,
174 ConfigurationSpaceUndefined,
175 0);
176 if (BusHandler == NULL)
177 return;
178
179 BusHandler->GetInterruptVector =
180 (pGetInterruptVector)HalpGetIsaInterruptVector;
181 BusHandler->TranslateBusAddress =
182 (pTranslateBusAddress)HalpTranslateIsaBusAddress;
183
184 /* Add MicroChannel bus handler */
185 BusHandler = HalpAllocateBusHandler(MicroChannel,
186 Pos,
187 0);
188 if (BusHandler == NULL)
189 return;
190
191 BusHandler->GetBusData = (pGetSetBusData)HalpGetMicroChannelData;
192 }
193
194
195 PBUS_HANDLER FASTCALL
196 HaliHandlerForBus(INTERFACE_TYPE InterfaceType,
197 ULONG BusNumber)
198 {
199 PBUS_HANDLER BusHandler;
200 PLIST_ENTRY CurrentEntry;
201 KIRQL OldIrql;
202
203 KeAcquireSpinLock(&HalpBusHandlerSpinLock,
204 &OldIrql);
205
206 CurrentEntry = HalpBusHandlerList.Flink;
207 while (CurrentEntry != &HalpBusHandlerList)
208 {
209 BusHandler = (PBUS_HANDLER)CurrentEntry;
210 if (BusHandler->InterfaceType == InterfaceType &&
211 BusHandler->BusNumber == BusNumber)
212 {
213 KeReleaseSpinLock(&HalpBusHandlerSpinLock,
214 OldIrql);
215 return BusHandler;
216 }
217 CurrentEntry = CurrentEntry->Flink;
218 }
219 KeReleaseSpinLock(&HalpBusHandlerSpinLock,
220 OldIrql);
221
222 return NULL;
223 }
224
225
226 PBUS_HANDLER FASTCALL
227 HaliHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
228 ULONG BusNumber)
229 {
230 PBUS_HANDLER BusHandler;
231 PLIST_ENTRY CurrentEntry;
232 KIRQL OldIrql;
233
234 KeAcquireSpinLock(&HalpBusHandlerSpinLock,
235 &OldIrql);
236
237 CurrentEntry = HalpBusHandlerList.Flink;
238 while (CurrentEntry != &HalpBusHandlerList)
239 {
240 BusHandler = (PBUS_HANDLER)CurrentEntry;
241 if (BusHandler->BusDataType == BusDataType &&
242 BusHandler->BusNumber == BusNumber)
243 {
244 KeReleaseSpinLock(&HalpBusHandlerSpinLock,
245 OldIrql);
246 return BusHandler;
247 }
248 CurrentEntry = CurrentEntry->Flink;
249 }
250 KeReleaseSpinLock(&HalpBusHandlerSpinLock,
251 OldIrql);
252
253 return NULL;
254 }
255
256
257 PBUS_HANDLER FASTCALL
258 HaliReferenceHandlerForBus(INTERFACE_TYPE InterfaceType,
259 ULONG BusNumber)
260 {
261 PBUS_HANDLER BusHandler;
262 PLIST_ENTRY CurrentEntry;
263 KIRQL OldIrql;
264
265 KeAcquireSpinLock(&HalpBusHandlerSpinLock,
266 &OldIrql);
267
268 CurrentEntry = HalpBusHandlerList.Flink;
269 while (CurrentEntry != &HalpBusHandlerList)
270 {
271 BusHandler = (PBUS_HANDLER)CurrentEntry;
272 if (BusHandler->InterfaceType == InterfaceType &&
273 BusHandler->BusNumber == BusNumber)
274 {
275 BusHandler->RefCount++;
276 KeReleaseSpinLock(&HalpBusHandlerSpinLock,
277 OldIrql);
278 return BusHandler;
279 }
280 CurrentEntry = CurrentEntry->Flink;
281 }
282 KeReleaseSpinLock(&HalpBusHandlerSpinLock,
283 OldIrql);
284
285 return NULL;
286 }
287
288
289 PBUS_HANDLER FASTCALL
290 HaliReferenceHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
291 ULONG BusNumber)
292 {
293 PBUS_HANDLER BusHandler;
294 PLIST_ENTRY CurrentEntry;
295 KIRQL OldIrql;
296
297 KeAcquireSpinLock(&HalpBusHandlerSpinLock,
298 &OldIrql);
299
300 CurrentEntry = HalpBusHandlerList.Flink;
301 while (CurrentEntry != &HalpBusHandlerList)
302 {
303 BusHandler = (PBUS_HANDLER)CurrentEntry;
304 if (BusHandler->BusDataType == BusDataType &&
305 BusHandler->BusNumber == BusNumber)
306 {
307 BusHandler->RefCount++;
308 KeReleaseSpinLock(&HalpBusHandlerSpinLock,
309 OldIrql);
310 return BusHandler;
311 }
312 CurrentEntry = CurrentEntry->Flink;
313 }
314 KeReleaseSpinLock(&HalpBusHandlerSpinLock,
315 OldIrql);
316
317 return NULL;
318 }
319
320
321 VOID FASTCALL
322 HaliDereferenceBusHandler(PBUS_HANDLER BusHandler)
323 {
324 KIRQL OldIrql;
325
326 KeAcquireSpinLock(&HalpBusHandlerSpinLock,
327 &OldIrql);
328 BusHandler->RefCount--;
329 KeReleaseSpinLock(&HalpBusHandlerSpinLock,
330 OldIrql);
331 }
332
333
334 NTSTATUS STDCALL
335 HalAdjustResourceList(PCM_RESOURCE_LIST Resources)
336 {
337 PBUS_HANDLER BusHandler;
338 NTSTATUS Status;
339
340 BusHandler = HaliReferenceHandlerForBus(Resources->List[0].InterfaceType,
341 Resources->List[0].BusNumber);
342 if (BusHandler == NULL)
343 return STATUS_SUCCESS;
344
345 Status = BusHandler->AdjustResourceList(BusHandler,
346 Resources->List[0].BusNumber,
347 Resources);
348 HaliDereferenceBusHandler (BusHandler);
349
350 return Status;
351 }
352
353
354 NTSTATUS STDCALL
355 HalAssignSlotResources(PUNICODE_STRING RegistryPath,
356 PUNICODE_STRING DriverClassName,
357 PDRIVER_OBJECT DriverObject,
358 PDEVICE_OBJECT DeviceObject,
359 INTERFACE_TYPE BusType,
360 ULONG BusNumber,
361 ULONG SlotNumber,
362 PCM_RESOURCE_LIST *AllocatedResources)
363 {
364 PBUS_HANDLER BusHandler;
365 NTSTATUS Status;
366
367 BusHandler = HaliReferenceHandlerForBus(BusType,
368 BusNumber);
369 if (BusHandler == NULL)
370 return STATUS_NOT_FOUND;
371
372 Status = BusHandler->AssignSlotResources(BusHandler,
373 BusNumber,
374 RegistryPath,
375 DriverClassName,
376 DriverObject,
377 DeviceObject,
378 SlotNumber,
379 AllocatedResources);
380
381 HaliDereferenceBusHandler(BusHandler);
382
383 return Status;
384 }
385
386
387 ULONG STDCALL
388 HalGetBusData(BUS_DATA_TYPE BusDataType,
389 ULONG BusNumber,
390 ULONG SlotNumber,
391 PVOID Buffer,
392 ULONG Length)
393 {
394 return (HalGetBusDataByOffset(BusDataType,
395 BusNumber,
396 SlotNumber,
397 Buffer,
398 0,
399 Length));
400 }
401
402
403 ULONG STDCALL
404 HalGetBusDataByOffset(BUS_DATA_TYPE BusDataType,
405 ULONG BusNumber,
406 ULONG SlotNumber,
407 PVOID Buffer,
408 ULONG Offset,
409 ULONG Length)
410 {
411 PBUS_HANDLER BusHandler;
412 ULONG Result;
413
414 BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
415 BusNumber);
416 if (BusHandler == NULL)
417 return 0;
418
419 Result = BusHandler->GetBusData(BusHandler,
420 BusNumber,
421 SlotNumber,
422 Buffer,
423 Offset,
424 Length);
425
426 HaliDereferenceBusHandler (BusHandler);
427
428 return Result;
429 }
430
431
432 ULONG STDCALL
433 HalGetInterruptVector(INTERFACE_TYPE InterfaceType,
434 ULONG BusNumber,
435 ULONG BusInterruptLevel,
436 ULONG BusInterruptVector,
437 PKIRQL Irql,
438 PKAFFINITY Affinity)
439 {
440 PBUS_HANDLER BusHandler;
441 ULONG Result;
442
443 BusHandler = HaliReferenceHandlerForBus(InterfaceType,
444 BusNumber);
445 if (BusHandler == NULL)
446 return 0;
447
448 Result = BusHandler->GetInterruptVector(BusHandler,
449 BusNumber,
450 BusInterruptLevel,
451 BusInterruptVector,
452 Irql,
453 Affinity);
454
455 HaliDereferenceBusHandler(BusHandler);
456
457 return Result;
458 }
459
460
461 ULONG STDCALL
462 HalSetBusData(BUS_DATA_TYPE BusDataType,
463 ULONG BusNumber,
464 ULONG SlotNumber,
465 PVOID Buffer,
466 ULONG Length)
467 {
468 return (HalSetBusDataByOffset(BusDataType,
469 BusNumber,
470 SlotNumber,
471 Buffer,
472 0,
473 Length));
474 }
475
476
477 ULONG STDCALL
478 HalSetBusDataByOffset(BUS_DATA_TYPE BusDataType,
479 ULONG BusNumber,
480 ULONG SlotNumber,
481 PVOID Buffer,
482 ULONG Offset,
483 ULONG Length)
484 {
485 PBUS_HANDLER BusHandler;
486 ULONG Result;
487
488 BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
489 BusNumber);
490 if (BusHandler == NULL)
491 return 0;
492
493 Result = BusHandler->SetBusData(BusHandler,
494 BusNumber,
495 SlotNumber,
496 Buffer,
497 Offset,
498 Length);
499
500 HaliDereferenceBusHandler(BusHandler);
501
502 return Result;
503 }
504
505
506 BOOLEAN STDCALL
507 HalTranslateBusAddress(INTERFACE_TYPE InterfaceType,
508 ULONG BusNumber,
509 PHYSICAL_ADDRESS BusAddress,
510 PULONG AddressSpace,
511 PPHYSICAL_ADDRESS TranslatedAddress)
512 {
513 PBUS_HANDLER BusHandler;
514 BOOLEAN Result;
515
516 BusHandler = HaliReferenceHandlerForBus(InterfaceType,
517 BusNumber);
518 if (BusHandler == NULL)
519 return FALSE;
520
521 Result = BusHandler->TranslateBusAddress(BusHandler,
522 BusNumber,
523 BusAddress,
524 AddressSpace,
525 TranslatedAddress);
526
527 HaliDereferenceBusHandler(BusHandler);
528
529 return Result;
530 }
531
532 /* EOF */