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