:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[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->TranslateBusAddress =
174         (pTranslateBusAddress)HalpTranslateIsaBusAddress;
175
176
177   /* add MicroChannel bus handler */
178   BusHandler = HalpAllocateBusHandler(MicroChannel,
179                                       Pos,
180                                       0);
181    if (BusHandler == NULL)
182      return;
183
184   BusHandler->GetBusData = (pGetSetBusData)HalpGetMicroChannelData;
185 }
186
187
188 PBUS_HANDLER FASTCALL
189 HaliHandlerForBus(INTERFACE_TYPE InterfaceType,
190                   ULONG BusNumber)
191 {
192    PBUS_HANDLER BusHandler;
193    PLIST_ENTRY CurrentEntry;
194    KIRQL OldIrql;
195
196    KeAcquireSpinLock(&HalpBusHandlerSpinLock,
197                      &OldIrql);
198
199    CurrentEntry = HalpBusHandlerList.Flink;
200    while (CurrentEntry != &HalpBusHandlerList)
201      {
202         BusHandler = (PBUS_HANDLER)CurrentEntry;
203         if (BusHandler->InterfaceType == InterfaceType &&
204             BusHandler->BusNumber == BusNumber)
205           {
206              KeReleaseSpinLock(&HalpBusHandlerSpinLock,
207                                OldIrql);
208              return BusHandler;
209           }
210         CurrentEntry = CurrentEntry->Flink;
211      }
212    KeReleaseSpinLock(&HalpBusHandlerSpinLock,
213                      OldIrql);
214
215    return NULL;
216 }
217
218
219 PBUS_HANDLER FASTCALL
220 HaliHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
221                           ULONG BusNumber)
222 {
223    PBUS_HANDLER BusHandler;
224    PLIST_ENTRY CurrentEntry;
225    KIRQL OldIrql;
226
227    KeAcquireSpinLock(&HalpBusHandlerSpinLock,
228                      &OldIrql);
229
230    CurrentEntry = HalpBusHandlerList.Flink;
231    while (CurrentEntry != &HalpBusHandlerList)
232      {
233         BusHandler = (PBUS_HANDLER)CurrentEntry;
234         if (BusHandler->BusDataType == BusDataType &&
235             BusHandler->BusNumber == BusNumber)
236           {
237              KeReleaseSpinLock(&HalpBusHandlerSpinLock,
238                                OldIrql);
239              return BusHandler;
240           }
241         CurrentEntry = CurrentEntry->Flink;
242      }
243    KeReleaseSpinLock(&HalpBusHandlerSpinLock,
244                      OldIrql);
245
246    return NULL;
247 }
248
249
250 PBUS_HANDLER FASTCALL
251 HaliReferenceHandlerForBus(INTERFACE_TYPE InterfaceType,
252                            ULONG BusNumber)
253 {
254    PBUS_HANDLER BusHandler;
255    PLIST_ENTRY CurrentEntry;
256    KIRQL OldIrql;
257
258    KeAcquireSpinLock(&HalpBusHandlerSpinLock,
259                      &OldIrql);
260
261    CurrentEntry = HalpBusHandlerList.Flink;
262    while (CurrentEntry != &HalpBusHandlerList)
263      {
264         BusHandler = (PBUS_HANDLER)CurrentEntry;
265         if (BusHandler->InterfaceType == InterfaceType &&
266             BusHandler->BusNumber == BusNumber)
267           {
268              BusHandler->RefCount++;
269              KeReleaseSpinLock(&HalpBusHandlerSpinLock,
270                                OldIrql);
271              return BusHandler;
272           }
273         CurrentEntry = CurrentEntry->Flink;
274      }
275    KeReleaseSpinLock(&HalpBusHandlerSpinLock,
276                      OldIrql);
277
278    return NULL;
279 }
280
281
282 PBUS_HANDLER FASTCALL
283 HaliReferenceHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
284                                    ULONG BusNumber)
285 {
286    PBUS_HANDLER BusHandler;
287    PLIST_ENTRY CurrentEntry;
288    KIRQL OldIrql;
289
290    KeAcquireSpinLock(&HalpBusHandlerSpinLock,
291                      &OldIrql);
292
293    CurrentEntry = HalpBusHandlerList.Flink;
294    while (CurrentEntry != &HalpBusHandlerList)
295      {
296         BusHandler = (PBUS_HANDLER)CurrentEntry;
297         if (BusHandler->BusDataType == BusDataType &&
298             BusHandler->BusNumber == BusNumber)
299           {
300              BusHandler->RefCount++;
301              KeReleaseSpinLock(&HalpBusHandlerSpinLock,
302                                OldIrql);
303              return BusHandler;
304           }
305         CurrentEntry = CurrentEntry->Flink;
306      }
307    KeReleaseSpinLock(&HalpBusHandlerSpinLock,
308                      OldIrql);
309
310    return NULL;
311 }
312
313
314 VOID FASTCALL
315 HaliDereferenceBusHandler(PBUS_HANDLER BusHandler)
316 {
317    KIRQL OldIrql;
318
319    KeAcquireSpinLock(&HalpBusHandlerSpinLock,
320                      &OldIrql);
321    BusHandler->RefCount--;
322    KeReleaseSpinLock(&HalpBusHandlerSpinLock,
323                      OldIrql);
324 }
325
326
327 NTSTATUS STDCALL
328 HalAdjustResourceList(PCM_RESOURCE_LIST Resources)
329 {
330    PBUS_HANDLER BusHandler;
331    NTSTATUS Status;
332
333    BusHandler = HaliReferenceHandlerForBus(Resources->List[0].InterfaceType,
334                                            Resources->List[0].BusNumber);
335    if (BusHandler == NULL)
336      return STATUS_SUCCESS;
337
338    Status = BusHandler->AdjustResourceList(BusHandler,
339                                            Resources->List[0].BusNumber,
340                                            Resources);
341    HaliDereferenceBusHandler (BusHandler);
342
343    return Status;
344 }
345
346
347 NTSTATUS STDCALL
348 HalAssignSlotResources(PUNICODE_STRING RegistryPath,
349                        PUNICODE_STRING DriverClassName,
350                        PDRIVER_OBJECT DriverObject,
351                        PDEVICE_OBJECT DeviceObject,
352                        INTERFACE_TYPE BusType,
353                        ULONG BusNumber,
354                        ULONG SlotNumber,
355                        PCM_RESOURCE_LIST *AllocatedResources)
356 {
357    PBUS_HANDLER BusHandler;
358    NTSTATUS Status;
359
360    BusHandler = HaliReferenceHandlerForBus(BusType,
361                                            BusNumber);
362    if (BusHandler == NULL)
363      return STATUS_NOT_FOUND;
364
365    Status = BusHandler->AssignSlotResources(BusHandler,
366                                             BusNumber,
367                                             RegistryPath,
368                                             DriverClassName,
369                                             DriverObject,
370                                             DeviceObject,
371                                             SlotNumber,
372                                             AllocatedResources);
373
374    HaliDereferenceBusHandler(BusHandler);
375
376    return Status;
377 }
378
379
380 ULONG STDCALL
381 HalGetBusData(BUS_DATA_TYPE BusDataType,
382               ULONG BusNumber,
383               ULONG SlotNumber,
384               PVOID Buffer,
385               ULONG Length)
386 {
387    return (HalGetBusDataByOffset(BusDataType,
388                                  BusNumber,
389                                  SlotNumber,
390                                  Buffer,
391                                  0,
392                                  Length));
393 }
394
395
396 ULONG STDCALL
397 HalGetBusDataByOffset(BUS_DATA_TYPE BusDataType,
398                       ULONG BusNumber,
399                       ULONG SlotNumber,
400                       PVOID Buffer,
401                       ULONG Offset,
402                       ULONG Length)
403 {
404    PBUS_HANDLER BusHandler;
405    ULONG Result;
406
407    BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
408                                                    BusNumber);
409    if (BusHandler == NULL)
410      return 0;
411
412    Result = BusHandler->GetBusData(BusHandler,
413                                    BusNumber,
414                                    SlotNumber,
415                                    Buffer,
416                                    Offset,
417                                    Length);
418
419    HaliDereferenceBusHandler (BusHandler);
420
421    return Result;
422 }
423
424
425 ULONG STDCALL
426 HalGetInterruptVector(INTERFACE_TYPE InterfaceType,
427                       ULONG BusNumber,
428                       ULONG BusInterruptLevel,
429                       ULONG BusInterruptVector,
430                       PKIRQL Irql,
431                       PKAFFINITY Affinity)
432 {
433    PBUS_HANDLER BusHandler;
434    ULONG Result;
435
436    BusHandler = HaliReferenceHandlerForBus(InterfaceType,
437                                            BusNumber);
438    if (BusHandler == NULL)
439      return 0;
440
441    Result = BusHandler->GetInterruptVector(BusHandler,
442                                            BusNumber,
443                                            BusInterruptLevel,
444                                            BusInterruptVector,
445                                            Irql,
446                                            Affinity);
447
448    HaliDereferenceBusHandler(BusHandler);
449
450    return Result;
451 }
452
453
454 ULONG STDCALL
455 HalSetBusData(BUS_DATA_TYPE BusDataType,
456               ULONG BusNumber,
457               ULONG SlotNumber,
458               PVOID Buffer,
459               ULONG Length)
460 {
461    return (HalSetBusDataByOffset(BusDataType,
462                                  BusNumber,
463                                  SlotNumber,
464                                  Buffer,
465                                  0,
466                                  Length));
467 }
468
469
470 ULONG STDCALL
471 HalSetBusDataByOffset(BUS_DATA_TYPE BusDataType,
472                       ULONG BusNumber,
473                       ULONG SlotNumber,
474                       PVOID Buffer,
475                       ULONG Offset,
476                       ULONG Length)
477 {
478    PBUS_HANDLER BusHandler;
479    ULONG Result;
480
481    BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
482                                                    BusNumber);
483    if (BusHandler == NULL)
484      return 0;
485
486    Result = BusHandler->SetBusData(BusHandler,
487                                    BusNumber,
488                                    SlotNumber,
489                                    Buffer,
490                                    Offset,
491                                    Length);
492
493    HaliDereferenceBusHandler(BusHandler);
494
495    return Result;
496 }
497
498
499 BOOLEAN STDCALL
500 HalTranslateBusAddress(INTERFACE_TYPE InterfaceType,
501                        ULONG BusNumber,
502                        PHYSICAL_ADDRESS BusAddress,
503                        PULONG AddressSpace,
504                        PPHYSICAL_ADDRESS TranslatedAddress)
505 {
506    PBUS_HANDLER BusHandler;
507    BOOLEAN Result;
508
509    BusHandler = HaliReferenceHandlerForBus(InterfaceType,
510                                            BusNumber);
511    if (BusHandler == NULL)
512      return FALSE;
513
514    Result = BusHandler->TranslateBusAddress(BusHandler,
515                                             BusNumber,
516                                             BusAddress,
517                                             AddressSpace,
518                                             TranslatedAddress);
519
520    HaliDereferenceBusHandler(BusHandler);
521
522    return Result;
523 }
524
525 /* EOF */