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