Forward compatibility: build relative-base link libraries where needed
[AROS.git] / workbench / libs / prometheus / prometheus_init.c
bloba88788158feffa6a435a3203e759e723a85226ee
1 /*
2 Copyright © 2005-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Prometheus initialisation code.
6 Lang: English.
7 */
9 #include <exec/types.h>
10 #include <exec/resident.h>
11 #include <utility/utility.h>
13 #include <proto/exec.h>
14 #include <proto/oop.h>
15 #include <proto/alib.h>
17 #include LC_LIBDEFS_FILE
18 #include "prometheus_intern.h"
19 #include <aros/symbolsets.h>
21 #undef HiddPCIDriverAttrBase
22 #define HiddPCIDriverAttrBase (base->pcidriver_attr_base)
24 /* Private prototypes */
26 AROS_UFP3(static VOID, EnumHook, AROS_UFPA(struct Hook *, hook, A0),
27 AROS_UFPA(OOP_Object *, aros_board, A2), AROS_UFPA(APTR, message, A1));
28 static int DeleteLibrary(LIBBASETYPE *base);
30 static int LibInit(LIBBASETYPEPTR base)
32 BOOL success = TRUE;
34 base->kernelBase = OpenResource("kernel.resource");
35 if (!base->kernelBase)
36 return FALSE;
38 NewList((APTR)&base->boards);
40 /* Open HIDDs */
41 base->pci_hidd = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
42 base->pcidevice_attr_base = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
43 base->pcidriver_attr_base = OOP_ObtainAttrBase(IID_Hidd_PCIDriver);
44 base->pcidevice_method_base = OOP_GetMethodID(IID_Hidd_PCIDevice, 0);
45 if (base->pci_hidd == NULL || base->pcidevice_attr_base == 0 ||
46 base->pcidriver_attr_base == 0)
47 success = FALSE;
49 /* Make a list of all boards in the system */
50 if(success)
52 struct Hook hook;
54 hook.h_Entry = (APTR)EnumHook;
55 hook.h_Data = base;
56 hook.h_SubEntry = (APTR)TRUE; /* (Ab)use this as success indicator */
58 HIDD_PCI_EnumDevices(base->pci_hidd, &hook, NULL);
60 success = (IPTR)hook.h_SubEntry;
63 if(!success)
64 DeleteLibrary(base);
66 return success;
71 AROS_UFH3(static VOID, EnumHook, AROS_UFHA(struct Hook *, hook, A0),
72 AROS_UFHA(OOP_Object *, aros_board, A2), AROS_UFHA(APTR, message, A1))
74 AROS_USERFUNC_INIT
76 LIBBASETYPE *base = hook->h_Data;
77 struct PCIBoard *board;
78 OOP_Object *driver;
79 IPTR direct;
82 * We have no map/unmap calls, so we can work only with "direct" buses.
83 * An alternative would be to map regions on first access, but
84 * this could be a significant resource hog (like the same region being
85 * mapped several times by several different APIs).
86 */
87 OOP_GetAttr(aros_board, aHidd_PCIDevice_Driver, (IPTR *)&driver);
88 OOP_GetAttr(driver, aHidd_PCIDriver_DirectBus, &direct);
89 if (!direct)
90 return;
92 /* Add board to our list */
93 board = AllocMem(sizeof(struct PCIBoard), MEMF_PUBLIC | MEMF_CLEAR);
94 if (board != NULL)
97 * FIXME: Here we should parse device's memory regions and map them all
98 * using MapPCI method. Without this drivers will not work on systems
99 * with complex memory protection, as well as on Linux-hosted.
100 * However, there's another problem with this. What if the device is already
101 * owned by somebody else, and its region is already mapped ? How can we
102 * know ?
103 * Actually this is significant design problem. Alternately we can add some
104 * attribute to the driver telling that "we have no permanent mapping".
105 * In this case prometheus.library simply will not work. However it is better
106 * than crashing.
108 board->aros_board = aros_board;
109 AddTail((APTR)&base->boards, (APTR)board);
111 else
112 hook->h_SubEntry = NULL;
114 AROS_USERFUNC_EXIT
119 static int DeleteLibrary(LIBBASETYPE *base)
121 struct PCIBoard *board;
123 /* Free the list of boards */
125 while((board = (APTR)RemTail((struct List *)&base->boards)) != NULL)
126 FreeMem(board, sizeof(struct PCIBoard));
128 /* Close HIDDs */
130 if(base->pcidevice_attr_base != 0)
131 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
132 if(base->pcidriver_attr_base != 0)
133 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
134 if(base->pci_hidd != NULL)
135 OOP_DisposeObject(base->pci_hidd);
137 return TRUE;
142 ADD2INITLIB(LibInit, 0);
143 ADD2EXPUNGELIB(DeleteLibrary, 0);