branch update for HEAD-2003050101
[reactos.git] / hal / halx86 / 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 <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 */