1706f2543Smrg/*
2706f2543Smrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
3706f2543Smrg *
4706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5706f2543Smrg * copy of this software and associated documentation files (the "Software"),
6706f2543Smrg * to deal in the Software without restriction, including without limitation
7706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
9706f2543Smrg * Software is furnished to do so, subject to the following conditions:
10706f2543Smrg *
11706f2543Smrg * The above copyright notice and this permission notice shall be included in
12706f2543Smrg * all copies or substantial portions of the Software.
13706f2543Smrg *
14706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE.
21706f2543Smrg *
22706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s)
23706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote
24706f2543Smrg * the sale, use or other dealings in this Software without prior written
25706f2543Smrg * authorization from the copyright holder(s) and author(s).
26706f2543Smrg */
27706f2543Smrg
28706f2543Smrg/*
29706f2543Smrg * This file contains the interfaces to the bus-specific code
30706f2543Smrg */
31706f2543Smrg
32706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
33706f2543Smrg#include <xorg-config.h>
34706f2543Smrg#endif
35706f2543Smrg
36706f2543Smrg#include <ctype.h>
37706f2543Smrg#include <stdlib.h>
38706f2543Smrg#include <unistd.h>
39706f2543Smrg#include <X11/X.h>
40706f2543Smrg#include "os.h"
41706f2543Smrg#include "xf86.h"
42706f2543Smrg#include "xf86Priv.h"
43706f2543Smrg
44706f2543Smrg/* Bus-specific headers */
45706f2543Smrg
46706f2543Smrg#include "xf86Bus.h"
47706f2543Smrg
48706f2543Smrg#define XF86_OS_PRIVS
49706f2543Smrg#include "xf86_OSproc.h"
50706f2543Smrg#include "xf86VGAarbiter.h"
51706f2543Smrg
52706f2543Smrg/* Entity data */
53706f2543SmrgEntityPtr *xf86Entities = NULL;	/* Bus slots claimed by drivers */
54706f2543Smrgint xf86NumEntities = 0;
55706f2543Smrgstatic int xf86EntityPrivateCount = 0;
56706f2543Smrg
57706f2543SmrgBusRec primaryBus = { BUS_NONE, { 0 } };
58706f2543Smrg
59706f2543Smrg/**
60706f2543Smrg * Call the driver's correct probe function.
61706f2543Smrg *
62706f2543Smrg * If the driver implements the \c DriverRec::PciProbe entry-point and an
63706f2543Smrg * appropriate PCI device (with matching Device section in the xorg.conf file)
64706f2543Smrg * is found, it is called.  If \c DriverRec::PciProbe or no devices can be
65706f2543Smrg * successfully probed with it (e.g., only non-PCI devices are available),
66706f2543Smrg * the driver's \c DriverRec::Probe function is called.
67706f2543Smrg *
68706f2543Smrg * \param drv   Driver to probe
69706f2543Smrg *
70706f2543Smrg * \return
71706f2543Smrg * If a device can be successfully probed by the driver, \c TRUE is
72706f2543Smrg * returned.  Otherwise, \c FALSE is returned.
73706f2543Smrg */
74706f2543SmrgBool
75706f2543Smrgxf86CallDriverProbe( DriverPtr drv, Bool detect_only )
76706f2543Smrg{
77706f2543Smrg    Bool     foundScreen = FALSE;
78706f2543Smrg
79706f2543Smrg    if (drv->PciProbe != NULL) {
80706f2543Smrg        if (xf86DoConfigure && xf86DoConfigurePass1) {
81706f2543Smrg            assert(detect_only);
82706f2543Smrg            foundScreen = xf86PciAddMatchingDev(drv);
83706f2543Smrg        }
84706f2543Smrg        else {
85706f2543Smrg            assert(! detect_only);
86706f2543Smrg            foundScreen = xf86PciProbeDev(drv);
87706f2543Smrg        }
88706f2543Smrg    }
89706f2543Smrg
90706f2543Smrg    if (!foundScreen && (drv->Probe != NULL)) {
91706f2543Smrg        xf86Msg( X_WARNING, "Falling back to old probe method for %s\n",
92706f2543Smrg                             drv->driverName);
93706f2543Smrg        foundScreen = (*drv->Probe)(drv, (detect_only) ? PROBE_DETECT
94706f2543Smrg                                    : PROBE_DEFAULT);
95706f2543Smrg    }
96706f2543Smrg
97706f2543Smrg    return foundScreen;
98706f2543Smrg}
99706f2543Smrg
100706f2543Smrg/**
101706f2543Smrg * @return TRUE if all buses are configured and set up correctly and FALSE
102706f2543Smrg * otherwise.
103706f2543Smrg */
104706f2543SmrgBool
105706f2543Smrgxf86BusConfig(void)
106706f2543Smrg{
107706f2543Smrg    screenLayoutPtr layout;
108706f2543Smrg    int i, j;
109706f2543Smrg
110706f2543Smrg    /* Enable full I/O access */
111706f2543Smrg    if (xorgHWAccess)
112706f2543Smrg        xorgHWAccess = xf86EnableIO();
113706f2543Smrg
114706f2543Smrg    /*
115706f2543Smrg     * Now call each of the Probe functions.  Each successful probe will
116706f2543Smrg     * result in an extra entry added to the xf86Screens[] list for each
117706f2543Smrg     * instance of the hardware found.
118706f2543Smrg     */
119706f2543Smrg    for (i = 0; i < xf86NumDrivers; i++) {
120706f2543Smrg        xorgHWFlags flags;
121706f2543Smrg        if (!xorgHWAccess) {
122706f2543Smrg            if (!xf86DriverList[i]->driverFunc
123706f2543Smrg            || !xf86DriverList[i]->driverFunc(NULL,
124706f2543Smrg                             GET_REQUIRED_HW_INTERFACES,
125706f2543Smrg                              &flags)
126706f2543Smrg            || NEED_IO_ENABLED(flags))
127706f2543Smrg            continue;
128706f2543Smrg        }
129706f2543Smrg
130706f2543Smrg        xf86CallDriverProbe(xf86DriverList[i], FALSE);
131706f2543Smrg    }
132706f2543Smrg
133706f2543Smrg    /* If nothing was detected, return now */
134706f2543Smrg    if (xf86NumScreens == 0) {
135706f2543Smrg        xf86Msg(X_ERROR, "No devices detected.\n");
136706f2543Smrg        return FALSE;
137706f2543Smrg    }
138706f2543Smrg
139706f2543Smrg    xf86VGAarbiterInit();
140706f2543Smrg
141706f2543Smrg    /*
142706f2543Smrg     * Match up the screens found by the probes against those specified
143706f2543Smrg     * in the config file.  Remove the ones that won't be used.  Sort
144706f2543Smrg     * them in the order specified.
145706f2543Smrg     *
146706f2543Smrg     * What is the best way to do this?
147706f2543Smrg     *
148706f2543Smrg     * For now, go through the screens allocated by the probes, and
149706f2543Smrg     * look for screen config entry which refers to the same device
150706f2543Smrg     * section as picked out by the probe.
151706f2543Smrg     *
152706f2543Smrg     */
153706f2543Smrg    for (i = 0; i < xf86NumScreens; i++) {
154706f2543Smrg        for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
155706f2543Smrg             layout++) {
156706f2543Smrg            Bool found = FALSE;
157706f2543Smrg            for (j = 0; j < xf86Screens[i]->numEntities; j++) {
158706f2543Smrg
159706f2543Smrg                GDevPtr dev = xf86GetDevFromEntity(
160706f2543Smrg                                xf86Screens[i]->entityList[j],
161706f2543Smrg                                xf86Screens[i]->entityInstanceList[j]);
162706f2543Smrg                if (dev == layout->screen->device) {
163706f2543Smrg                    /* A match has been found */
164706f2543Smrg                    xf86Screens[i]->confScreen = layout->screen;
165706f2543Smrg                    found = TRUE;
166706f2543Smrg                    break;
167706f2543Smrg                }
168706f2543Smrg            }
169706f2543Smrg            if (found) break;
170706f2543Smrg        }
171706f2543Smrg        if (layout->screen == NULL) {
172706f2543Smrg            /* No match found */
173706f2543Smrg            xf86Msg(X_ERROR,
174706f2543Smrg            "Screen %d deleted because of no matching config section.\n", i);
175706f2543Smrg            xf86DeleteScreen(i--, 0);
176706f2543Smrg        }
177706f2543Smrg    }
178706f2543Smrg
179706f2543Smrg    /* If no screens left, return now.  */
180706f2543Smrg    if (xf86NumScreens == 0) {
181706f2543Smrg        xf86Msg(X_ERROR,
182706f2543Smrg        "Device(s) detected, but none match those in the config file.\n");
183706f2543Smrg        return FALSE;
184706f2543Smrg    }
185706f2543Smrg
186706f2543Smrg    return TRUE;
187706f2543Smrg}
188706f2543Smrg
189706f2543Smrg/*
190706f2543Smrg * Call the bus probes relevant to the architecture.
191706f2543Smrg *
192706f2543Smrg * The only one available so far is for PCI and SBUS.
193706f2543Smrg */
194706f2543Smrg
195706f2543Smrgvoid
196706f2543Smrgxf86BusProbe(void)
197706f2543Smrg{
198706f2543Smrg    xf86PciProbe();
199706f2543Smrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
200706f2543Smrg    xf86SbusProbe();
201706f2543Smrg#endif
202706f2543Smrg}
203706f2543Smrg
204706f2543Smrg/*
205706f2543Smrg * Determine what bus type the busID string represents.  The start of the
206706f2543Smrg * bus-dependent part of the string is returned as retID.
207706f2543Smrg */
208706f2543Smrg
209706f2543SmrgBusType
210706f2543SmrgStringToBusType(const char* busID, const char **retID)
211706f2543Smrg{
212706f2543Smrg    char *p, *s;
213706f2543Smrg    BusType ret = BUS_NONE;
214706f2543Smrg
215706f2543Smrg    /* If no type field, Default to PCI */
216706f2543Smrg    if (isdigit(busID[0])) {
217706f2543Smrg	if (retID)
218706f2543Smrg	    *retID = busID;
219706f2543Smrg	return BUS_PCI;
220706f2543Smrg    }
221706f2543Smrg
222706f2543Smrg    s = xstrdup(busID);
223706f2543Smrg    p = strtok(s, ":");
224706f2543Smrg    if (p == NULL || *p == 0) {
225706f2543Smrg	free(s);
226706f2543Smrg	return BUS_NONE;
227706f2543Smrg    }
228706f2543Smrg    if (!xf86NameCmp(p, "pci") || !xf86NameCmp(p, "agp"))
229706f2543Smrg	ret = BUS_PCI;
230706f2543Smrg    if (!xf86NameCmp(p, "sbus"))
231706f2543Smrg	ret = BUS_SBUS;
232706f2543Smrg    if (ret != BUS_NONE)
233706f2543Smrg	if (retID)
234706f2543Smrg	    *retID = busID + strlen(p) + 1;
235706f2543Smrg    free(s);
236706f2543Smrg    return ret;
237706f2543Smrg}
238706f2543Smrg
239706f2543Smrgint
240706f2543Smrgxf86AllocateEntity(void)
241706f2543Smrg{
242706f2543Smrg    xf86NumEntities++;
243706f2543Smrg    xf86Entities = xnfrealloc(xf86Entities,
244706f2543Smrg			      sizeof(EntityPtr) * xf86NumEntities);
245706f2543Smrg    xf86Entities[xf86NumEntities - 1] = xnfcalloc(1,sizeof(EntityRec));
246706f2543Smrg    xf86Entities[xf86NumEntities - 1]->entityPrivates =
247706f2543Smrg               xnfcalloc(sizeof(DevUnion) * xf86EntityPrivateCount, 1);
248706f2543Smrg    return xf86NumEntities - 1;
249706f2543Smrg}
250706f2543Smrg
251706f2543SmrgBool
252706f2543Smrgxf86IsEntityPrimary(int entityIndex)
253706f2543Smrg{
254706f2543Smrg    EntityPtr pEnt = xf86Entities[entityIndex];
255706f2543Smrg
256706f2543Smrg    if (primaryBus.type != pEnt->bus.type) return FALSE;
257706f2543Smrg
258706f2543Smrg    switch (pEnt->bus.type) {
259706f2543Smrg    case BUS_PCI:
260706f2543Smrg	return pEnt->bus.id.pci == primaryBus.id.pci;
261706f2543Smrg    case BUS_SBUS:
262706f2543Smrg	return pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum;
263706f2543Smrg    default:
264706f2543Smrg	return FALSE;
265706f2543Smrg    }
266706f2543Smrg}
267706f2543Smrg
268706f2543SmrgBool
269706f2543Smrgxf86SetEntityFuncs(int entityIndex, EntityProc init, EntityProc enter,
270706f2543Smrg		   EntityProc leave, pointer private)
271706f2543Smrg{
272706f2543Smrg    if (entityIndex >= xf86NumEntities)
273706f2543Smrg	return FALSE;
274706f2543Smrg    xf86Entities[entityIndex]->entityInit = init;
275706f2543Smrg    xf86Entities[entityIndex]->entityEnter = enter;
276706f2543Smrg    xf86Entities[entityIndex]->entityLeave = leave;
277706f2543Smrg    xf86Entities[entityIndex]->private = private;
278706f2543Smrg    return TRUE;
279706f2543Smrg}
280706f2543Smrg
281706f2543SmrgBool
282706f2543Smrgxf86DriverHasEntities(DriverPtr drvp)
283706f2543Smrg{
284706f2543Smrg    int i;
285706f2543Smrg    for (i = 0; i < xf86NumEntities; i++) {
286706f2543Smrg	if (xf86Entities[i]->driver == drvp)
287706f2543Smrg	    return TRUE;
288706f2543Smrg    }
289706f2543Smrg    return FALSE;
290706f2543Smrg}
291706f2543Smrg
292706f2543Smrgvoid
293706f2543Smrgxf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)
294706f2543Smrg{
295706f2543Smrg    if (entityIndex == -1)
296706f2543Smrg	return;
297706f2543Smrg    if (xf86Entities[entityIndex]->inUse &&
298706f2543Smrg	!(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL)) {
299706f2543Smrg	ErrorF("Requested Entity already in use!\n");
300706f2543Smrg	return;
301706f2543Smrg    }
302706f2543Smrg
303706f2543Smrg    pScrn->numEntities++;
304706f2543Smrg    pScrn->entityList = xnfrealloc(pScrn->entityList,
305706f2543Smrg				    pScrn->numEntities * sizeof(int));
306706f2543Smrg    pScrn->entityList[pScrn->numEntities - 1] = entityIndex;
307706f2543Smrg    xf86Entities[entityIndex]->inUse = TRUE;
308706f2543Smrg    pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList,
309706f2543Smrg				    pScrn->numEntities * sizeof(int));
310706f2543Smrg    pScrn->entityInstanceList[pScrn->numEntities - 1] = 0;
311706f2543Smrg    pScrn->domainIOBase = xf86Entities[entityIndex]->domainIO;
312706f2543Smrg}
313706f2543Smrg
314706f2543Smrgvoid
315706f2543Smrgxf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex, int instance)
316706f2543Smrg{
317706f2543Smrg    int i;
318706f2543Smrg
319706f2543Smrg    if (entityIndex == -1 || entityIndex >= xf86NumEntities)
320706f2543Smrg	return;
321706f2543Smrg
322706f2543Smrg    for (i = 0; i < pScrn->numEntities; i++) {
323706f2543Smrg	if (pScrn->entityList[i] == entityIndex) {
324706f2543Smrg	    pScrn->entityInstanceList[i] = instance;
325706f2543Smrg	    break;
326706f2543Smrg	}
327706f2543Smrg    }
328706f2543Smrg}
329706f2543Smrg
330706f2543Smrg/*
331706f2543Smrg * XXX  This needs to be updated for the case where a single entity may have
332706f2543Smrg * instances associated with more than one screen.
333706f2543Smrg */
334706f2543SmrgScrnInfoPtr
335706f2543Smrgxf86FindScreenForEntity(int entityIndex)
336706f2543Smrg{
337706f2543Smrg    int i,j;
338706f2543Smrg
339706f2543Smrg    if (entityIndex == -1) return NULL;
340706f2543Smrg
341706f2543Smrg    if (xf86Screens) {
342706f2543Smrg	for (i = 0; i < xf86NumScreens; i++) {
343706f2543Smrg	    for (j = 0; j < xf86Screens[i]->numEntities; j++) {
344706f2543Smrg		if ( xf86Screens[i]->entityList[j] == entityIndex )
345706f2543Smrg		    return xf86Screens[i];
346706f2543Smrg	    }
347706f2543Smrg	}
348706f2543Smrg    }
349706f2543Smrg    return NULL;
350706f2543Smrg}
351706f2543Smrg
352706f2543Smrgvoid
353706f2543Smrgxf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)
354706f2543Smrg{
355706f2543Smrg    int i;
356706f2543Smrg
357706f2543Smrg    for (i = 0; i < pScrn->numEntities; i++) {
358706f2543Smrg	if (pScrn->entityList[i] == entityIndex) {
359706f2543Smrg	    for (i++; i < pScrn->numEntities; i++)
360706f2543Smrg		pScrn->entityList[i-1] = pScrn->entityList[i];
361706f2543Smrg	    pScrn->numEntities--;
362706f2543Smrg	    xf86Entities[entityIndex]->inUse = FALSE;
363706f2543Smrg	    break;
364706f2543Smrg	}
365706f2543Smrg    }
366706f2543Smrg}
367706f2543Smrg
368706f2543Smrg/*
369706f2543Smrg * xf86ClearEntitiesForScreen() - called when a screen is deleted
370706f2543Smrg * to mark it's entities unused. Called by xf86DeleteScreen().
371706f2543Smrg */
372706f2543Smrgvoid
373706f2543Smrgxf86ClearEntityListForScreen(int scrnIndex)
374706f2543Smrg{
375706f2543Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
376706f2543Smrg    int i, entityIndex;
377706f2543Smrg
378706f2543Smrg    if (pScrn->entityList == NULL || pScrn->numEntities == 0) return;
379706f2543Smrg
380706f2543Smrg    for (i = 0; i < pScrn->numEntities; i++) {
381706f2543Smrg	entityIndex = pScrn->entityList[i];
382706f2543Smrg	xf86Entities[entityIndex]->inUse = FALSE;
383706f2543Smrg	/* disable resource: call the disable function */
384706f2543Smrg    }
385706f2543Smrg    free(pScrn->entityList);
386706f2543Smrg    free(pScrn->entityInstanceList);
387706f2543Smrg    pScrn->entityList = NULL;
388706f2543Smrg    pScrn->entityInstanceList = NULL;
389706f2543Smrg}
390706f2543Smrg
391706f2543Smrg/*
392706f2543Smrg * Add an extra device section (GDevPtr) to an entity.
393706f2543Smrg */
394706f2543Smrg
395706f2543Smrgvoid
396706f2543Smrgxf86AddDevToEntity(int entityIndex, GDevPtr dev)
397706f2543Smrg{
398706f2543Smrg    EntityPtr pEnt;
399706f2543Smrg
400706f2543Smrg    if (entityIndex >= xf86NumEntities)
401706f2543Smrg	return;
402706f2543Smrg
403706f2543Smrg    pEnt = xf86Entities[entityIndex];
404706f2543Smrg    pEnt->numInstances++;
405706f2543Smrg    pEnt->devices = xnfrealloc(pEnt->devices,
406706f2543Smrg				pEnt->numInstances * sizeof(GDevPtr));
407706f2543Smrg    pEnt->devices[pEnt->numInstances - 1] = dev;
408706f2543Smrg    dev->claimed = TRUE;
409706f2543Smrg}
410706f2543Smrg
411706f2543Smrg/*
412706f2543Smrg * xf86GetEntityInfo() -- This function hands information from the
413706f2543Smrg * EntityRec struct to the drivers. The EntityRec structure itself
414706f2543Smrg * remains invisible to the driver.
415706f2543Smrg */
416706f2543SmrgEntityInfoPtr
417706f2543Smrgxf86GetEntityInfo(int entityIndex)
418706f2543Smrg{
419706f2543Smrg    EntityInfoPtr pEnt;
420706f2543Smrg    int i;
421706f2543Smrg
422706f2543Smrg    if (entityIndex == -1)
423706f2543Smrg	return NULL;
424706f2543Smrg
425706f2543Smrg    if (entityIndex >= xf86NumEntities)
426706f2543Smrg	return NULL;
427706f2543Smrg
428706f2543Smrg    pEnt = xnfcalloc(1,sizeof(EntityInfoRec));
429706f2543Smrg    pEnt->index = entityIndex;
430706f2543Smrg    pEnt->location = xf86Entities[entityIndex]->bus;
431706f2543Smrg    pEnt->active = xf86Entities[entityIndex]->active;
432706f2543Smrg    pEnt->chipset = xf86Entities[entityIndex]->chipset;
433706f2543Smrg    pEnt->driver = xf86Entities[entityIndex]->driver;
434706f2543Smrg    if ( (xf86Entities[entityIndex]->devices) &&
435706f2543Smrg         (xf86Entities[entityIndex]->devices[0]) ) {
436706f2543Smrg	for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
437706f2543Smrg	    if (xf86Entities[entityIndex]->devices[i]->screen == 0)
438706f2543Smrg	        break;
439706f2543Smrg	pEnt->device = xf86Entities[entityIndex]->devices[i];
440706f2543Smrg    } else
441706f2543Smrg	pEnt->device = NULL;
442706f2543Smrg
443706f2543Smrg    return pEnt;
444706f2543Smrg}
445706f2543Smrg
446706f2543Smrgint
447706f2543Smrgxf86GetNumEntityInstances(int entityIndex)
448706f2543Smrg{
449706f2543Smrg    if (entityIndex >= xf86NumEntities)
450706f2543Smrg	return -1;
451706f2543Smrg
452706f2543Smrg    return xf86Entities[entityIndex]->numInstances;
453706f2543Smrg}
454706f2543Smrg
455706f2543SmrgGDevPtr
456706f2543Smrgxf86GetDevFromEntity(int entityIndex, int instance)
457706f2543Smrg{
458706f2543Smrg    int i;
459706f2543Smrg
460706f2543Smrg    /* We might not use AddDevtoEntity */
461706f2543Smrg    if ( (!xf86Entities[entityIndex]->devices) ||
462706f2543Smrg         (!xf86Entities[entityIndex]->devices[0]) )
463706f2543Smrg	return NULL;
464706f2543Smrg
465706f2543Smrg    if (entityIndex >= xf86NumEntities ||
466706f2543Smrg	instance >= xf86Entities[entityIndex]->numInstances)
467706f2543Smrg	return NULL;
468706f2543Smrg
469706f2543Smrg    for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
470706f2543Smrg	if (xf86Entities[entityIndex]->devices[i]->screen == instance)
471706f2543Smrg	    break;
472706f2543Smrg    return xf86Entities[entityIndex]->devices[i];
473706f2543Smrg}
474706f2543Smrg
475706f2543Smrg/*
476706f2543Smrg * xf86AccessEnter() -- gets called to save the text mode VGA IO
477706f2543Smrg * resources when reentering the server after a VT switch.
478706f2543Smrg */
479706f2543Smrgvoid
480706f2543Smrgxf86AccessEnter(void)
481706f2543Smrg{
482706f2543Smrg    int i;
483706f2543Smrg
484706f2543Smrg    for (i = 0; i < xf86NumEntities; i++)
485706f2543Smrg        if (xf86Entities[i]->entityEnter)
486706f2543Smrg		xf86Entities[i]->entityEnter(i,xf86Entities[i]->private);
487706f2543Smrg}
488706f2543Smrg
489706f2543Smrgvoid
490706f2543Smrgxf86AccessLeave(void)
491706f2543Smrg{
492706f2543Smrg    int i;
493706f2543Smrg
494706f2543Smrg    for (i = 0; i < xf86NumEntities; i++)
495706f2543Smrg        if (xf86Entities[i]->entityLeave)
496706f2543Smrg		xf86Entities[i]->entityLeave(i,xf86Entities[i]->private);
497706f2543Smrg}
498706f2543Smrg
499706f2543Smrg/*
500706f2543Smrg * xf86PostProbe() -- Allocate all non conflicting resources
501706f2543Smrg * This function gets called by xf86Init().
502706f2543Smrg */
503706f2543Smrgvoid
504706f2543Smrgxf86PostProbe(void)
505706f2543Smrg{
506706f2543Smrg    int i;
507706f2543Smrg
508706f2543Smrg    if (fbSlotClaimed && (pciSlotClaimed
509706f2543Smrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
510706f2543Smrg	    || sbusSlotClaimed
511706f2543Smrg#endif
512706f2543Smrg	    ))
513706f2543Smrg	    FatalError("Cannot run in framebuffer mode. Please specify busIDs "
514706f2543Smrg		       "       for all framebuffer devices\n");
515706f2543Smrg
516706f2543Smrg    for (i = 0; i < xf86NumEntities; i++)
517706f2543Smrg        if (xf86Entities[i]->entityInit)
518706f2543Smrg	    xf86Entities[i]->entityInit(i,xf86Entities[i]->private);
519706f2543Smrg}
520706f2543Smrg
521706f2543Smrgint
522706f2543Smrgxf86GetLastScrnFlag(int entityIndex)
523706f2543Smrg{
524706f2543Smrg    if(entityIndex < xf86NumEntities) {
525706f2543Smrg        return xf86Entities[entityIndex]->lastScrnFlag;
526706f2543Smrg    } else {
527706f2543Smrg        return -1;
528706f2543Smrg    }
529706f2543Smrg}
530706f2543Smrg
531706f2543Smrgvoid
532706f2543Smrgxf86SetLastScrnFlag(int entityIndex, int scrnIndex)
533706f2543Smrg{
534706f2543Smrg    if(entityIndex < xf86NumEntities) {
535706f2543Smrg        xf86Entities[entityIndex]->lastScrnFlag = scrnIndex;
536706f2543Smrg    }
537706f2543Smrg}
538706f2543Smrg
539706f2543SmrgBool
540706f2543Smrgxf86IsEntityShared(int entityIndex)
541706f2543Smrg{
542706f2543Smrg    if(entityIndex < xf86NumEntities) {
543706f2543Smrg        if(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL) {
544706f2543Smrg	    return TRUE;
545706f2543Smrg	}
546706f2543Smrg    }
547706f2543Smrg    return FALSE;
548706f2543Smrg}
549706f2543Smrg
550706f2543Smrgvoid
551706f2543Smrgxf86SetEntityShared(int entityIndex)
552706f2543Smrg{
553706f2543Smrg    if(entityIndex < xf86NumEntities) {
554706f2543Smrg        xf86Entities[entityIndex]->entityProp |= IS_SHARED_ACCEL;
555706f2543Smrg    }
556706f2543Smrg}
557706f2543Smrg
558706f2543SmrgBool
559706f2543Smrgxf86IsEntitySharable(int entityIndex)
560706f2543Smrg{
561706f2543Smrg    if(entityIndex < xf86NumEntities) {
562706f2543Smrg        if(xf86Entities[entityIndex]->entityProp & ACCEL_IS_SHARABLE) {
563706f2543Smrg	    return TRUE;
564706f2543Smrg	}
565706f2543Smrg    }
566706f2543Smrg    return FALSE;
567706f2543Smrg}
568706f2543Smrg
569706f2543Smrgvoid
570706f2543Smrgxf86SetEntitySharable(int entityIndex)
571706f2543Smrg{
572706f2543Smrg    if(entityIndex < xf86NumEntities) {
573706f2543Smrg        xf86Entities[entityIndex]->entityProp |= ACCEL_IS_SHARABLE;
574706f2543Smrg    }
575706f2543Smrg}
576706f2543Smrg
577706f2543SmrgBool
578706f2543Smrgxf86IsPrimInitDone(int entityIndex)
579706f2543Smrg{
580706f2543Smrg    if(entityIndex < xf86NumEntities) {
581706f2543Smrg        if(xf86Entities[entityIndex]->entityProp & SA_PRIM_INIT_DONE) {
582706f2543Smrg	    return TRUE;
583706f2543Smrg	}
584706f2543Smrg    }
585706f2543Smrg    return FALSE;
586706f2543Smrg}
587706f2543Smrg
588706f2543Smrgvoid
589706f2543Smrgxf86SetPrimInitDone(int entityIndex)
590706f2543Smrg{
591706f2543Smrg    if(entityIndex < xf86NumEntities) {
592706f2543Smrg        xf86Entities[entityIndex]->entityProp |= SA_PRIM_INIT_DONE;
593706f2543Smrg    }
594706f2543Smrg}
595706f2543Smrg
596706f2543Smrgvoid
597706f2543Smrgxf86ClearPrimInitDone(int entityIndex)
598706f2543Smrg{
599706f2543Smrg    if(entityIndex < xf86NumEntities) {
600706f2543Smrg        xf86Entities[entityIndex]->entityProp &= ~SA_PRIM_INIT_DONE;
601706f2543Smrg    }
602706f2543Smrg}
603706f2543Smrg
604706f2543Smrg
605706f2543Smrg/*
606706f2543Smrg * Allocate a private in the entities.
607706f2543Smrg */
608706f2543Smrg
609706f2543Smrgint
610706f2543Smrgxf86AllocateEntityPrivateIndex(void)
611706f2543Smrg{
612706f2543Smrg    int idx, i;
613706f2543Smrg    EntityPtr pEnt;
614706f2543Smrg    DevUnion *nprivs;
615706f2543Smrg
616706f2543Smrg    idx = xf86EntityPrivateCount++;
617706f2543Smrg    for (i = 0; i < xf86NumEntities; i++) {
618706f2543Smrg	pEnt = xf86Entities[i];
619706f2543Smrg	nprivs = xnfrealloc(pEnt->entityPrivates,
620706f2543Smrg			    xf86EntityPrivateCount * sizeof(DevUnion));
621706f2543Smrg	/* Zero the new private */
622706f2543Smrg	memset(&nprivs[idx], 0, sizeof(DevUnion));
623706f2543Smrg	pEnt->entityPrivates = nprivs;
624706f2543Smrg    }
625706f2543Smrg    return idx;
626706f2543Smrg}
627706f2543Smrg
628706f2543SmrgDevUnion *
629706f2543Smrgxf86GetEntityPrivate(int entityIndex, int privIndex)
630706f2543Smrg{
631706f2543Smrg    if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount)
632706f2543Smrg	return NULL;
633706f2543Smrg
634706f2543Smrg    return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
635706f2543Smrg}
636706f2543Smrg
637