105b261ecSmrg/*
205b261ecSmrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
305b261ecSmrg *
405b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
505b261ecSmrg * copy of this software and associated documentation files (the "Software"),
605b261ecSmrg * to deal in the Software without restriction, including without limitation
705b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
805b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
905b261ecSmrg * Software is furnished to do so, subject to the following conditions:
1005b261ecSmrg *
1105b261ecSmrg * The above copyright notice and this permission notice shall be included in
1205b261ecSmrg * all copies or substantial portions of the Software.
1305b261ecSmrg *
1405b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1505b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1605b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1705b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1805b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1905b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2005b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE.
2105b261ecSmrg *
2205b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s)
2305b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote
2405b261ecSmrg * the sale, use or other dealings in this Software without prior written
2505b261ecSmrg * authorization from the copyright holder(s) and author(s).
2605b261ecSmrg */
2705b261ecSmrg
2805b261ecSmrg/*
2905b261ecSmrg * This file contains the interfaces to the bus-specific code
3005b261ecSmrg */
3105b261ecSmrg
3205b261ecSmrg#ifdef HAVE_XORG_CONFIG_H
3305b261ecSmrg#include <xorg-config.h>
3405b261ecSmrg#endif
3505b261ecSmrg
3605b261ecSmrg#include <ctype.h>
3705b261ecSmrg#include <stdlib.h>
3805b261ecSmrg#include <unistd.h>
3905b261ecSmrg#include <X11/X.h>
4005b261ecSmrg#include "os.h"
4105b261ecSmrg#include "xf86.h"
4205b261ecSmrg#include "xf86Priv.h"
4305b261ecSmrg
4405b261ecSmrg/* Bus-specific headers */
4505b261ecSmrg
4605b261ecSmrg#include "xf86Bus.h"
4705b261ecSmrg
4805b261ecSmrg#define XF86_OS_PRIVS
4905b261ecSmrg#include "xf86_OSproc.h"
50f7df2e56Smrg#ifdef XSERVER_LIBPCIACCESS
514202a189Smrg#include "xf86VGAarbiter.h"
52f7df2e56Smrg#endif
5305b261ecSmrg/* Entity data */
54f7df2e56SmrgEntityPtr *xf86Entities = NULL; /* Bus slots claimed by drivers */
5505b261ecSmrgint xf86NumEntities = 0;
5605b261ecSmrgstatic int xf86EntityPrivateCount = 0;
5705b261ecSmrg
58f7df2e56SmrgBusRec primaryBus = { BUS_NONE, {0} };
594202a189Smrg
604202a189Smrg/**
614202a189Smrg * Call the driver's correct probe function.
624202a189Smrg *
634202a189Smrg * If the driver implements the \c DriverRec::PciProbe entry-point and an
644202a189Smrg * appropriate PCI device (with matching Device section in the xorg.conf file)
654202a189Smrg * is found, it is called.  If \c DriverRec::PciProbe or no devices can be
664202a189Smrg * successfully probed with it (e.g., only non-PCI devices are available),
674202a189Smrg * the driver's \c DriverRec::Probe function is called.
684202a189Smrg *
694202a189Smrg * \param drv   Driver to probe
704202a189Smrg *
714202a189Smrg * \return
724202a189Smrg * If a device can be successfully probed by the driver, \c TRUE is
734202a189Smrg * returned.  Otherwise, \c FALSE is returned.
744202a189Smrg */
754202a189SmrgBool
76f7df2e56Smrgxf86CallDriverProbe(DriverPtr drv, Bool detect_only)
774202a189Smrg{
78f7df2e56Smrg    Bool foundScreen = FALSE;
79f7df2e56Smrg
80f7df2e56Smrg#ifdef XSERVER_PLATFORM_BUS
817e31ba66Smrg    /* xf86platformBus.c does not support Xorg -configure */
827e31ba66Smrg    if (!xf86DoConfigure && drv->platformProbe != NULL) {
83f7df2e56Smrg        foundScreen = xf86platformProbeDev(drv);
84f7df2e56Smrg    }
85f7df2e56Smrg#endif
864642e01fSmrg
87f7df2e56Smrg#ifdef XSERVER_LIBPCIACCESS
88f7df2e56Smrg    if (!foundScreen && (drv->PciProbe != NULL)) {
894202a189Smrg        if (xf86DoConfigure && xf86DoConfigurePass1) {
904202a189Smrg            assert(detect_only);
914202a189Smrg            foundScreen = xf86PciAddMatchingDev(drv);
924202a189Smrg        }
934202a189Smrg        else {
94f7df2e56Smrg            assert(!detect_only);
954202a189Smrg            foundScreen = xf86PciProbeDev(drv);
964202a189Smrg        }
974202a189Smrg    }
98f7df2e56Smrg#endif
994202a189Smrg    if (!foundScreen && (drv->Probe != NULL)) {
100f7df2e56Smrg        xf86Msg(X_WARNING, "Falling back to old probe method for %s\n",
101f7df2e56Smrg                drv->driverName);
102f7df2e56Smrg        foundScreen = (*drv->Probe) (drv, (detect_only) ? PROBE_DETECT
103f7df2e56Smrg                                     : PROBE_DEFAULT);
1044202a189Smrg    }
10505b261ecSmrg
1064202a189Smrg    return foundScreen;
1074202a189Smrg}
10805b261ecSmrg
1095a112b11Smrgstatic screenLayoutPtr
1105a112b11Smrgxf86BusConfigMatch(ScrnInfoPtr scrnInfo, Bool is_gpu) {
1115a112b11Smrg    screenLayoutPtr layout;
1125a112b11Smrg    int i, j;
1135a112b11Smrg
1145a112b11Smrg    for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
1155a112b11Smrg         layout++) {
1165a112b11Smrg        for (i = 0; i < scrnInfo->numEntities; i++) {
1175a112b11Smrg            GDevPtr dev =
1185a112b11Smrg                xf86GetDevFromEntity(scrnInfo->entityList[i],
1195a112b11Smrg                                     scrnInfo->entityInstanceList[i]);
1205a112b11Smrg
1215a112b11Smrg            if (is_gpu) {
1225a112b11Smrg                for (j = 0; j < layout->screen->num_gpu_devices; j++) {
1235a112b11Smrg                    if (dev == layout->screen->gpu_devices[j]) {
1245a112b11Smrg                        /* A match has been found */
1255a112b11Smrg                        return layout;
1265a112b11Smrg                    }
1275a112b11Smrg                }
1285a112b11Smrg            } else {
1295a112b11Smrg                if (dev == layout->screen->device) {
1305a112b11Smrg                    /* A match has been found */
1315a112b11Smrg                    return layout;
1325a112b11Smrg                }
1335a112b11Smrg            }
1345a112b11Smrg        }
1355a112b11Smrg    }
1365a112b11Smrg
1375a112b11Smrg    return NULL;
1385a112b11Smrg}
1395a112b11Smrg
1404202a189Smrg/**
1414202a189Smrg * @return TRUE if all buses are configured and set up correctly and FALSE
1424202a189Smrg * otherwise.
1434202a189Smrg */
1444202a189SmrgBool
1454202a189Smrgxf86BusConfig(void)
1464202a189Smrg{
1474202a189Smrg    screenLayoutPtr layout;
1485a112b11Smrg    int i;
14905b261ecSmrg
1504202a189Smrg    /*
1517e31ba66Smrg     * 3 step probe to (hopefully) ensure that we always find at least 1
1527e31ba66Smrg     * (non GPU) screen:
1537e31ba66Smrg     *
1547e31ba66Smrg     * 1. Call each drivers probe function normally,
1557e31ba66Smrg     *    Each successful probe will result in an extra entry added to the
1567e31ba66Smrg     *    xf86Screens[] list for each instance of the hardware found.
1574202a189Smrg     */
1584202a189Smrg    for (i = 0; i < xf86NumDrivers; i++) {
1594202a189Smrg        xf86CallDriverProbe(xf86DriverList[i], FALSE);
1604202a189Smrg    }
1614202a189Smrg
1627e31ba66Smrg    /*
1637e31ba66Smrg     * 2. If no Screens were found, call each drivers probe function with
1647e31ba66Smrg     *    ignorePrimary = TRUE, to ensure that we do actually get a
1655a112b11Smrg     *    Screen if there is at least one supported video card.
1667e31ba66Smrg     */
1677e31ba66Smrg    if (xf86NumScreens == 0) {
1687e31ba66Smrg        xf86ProbeIgnorePrimary = TRUE;
1697e31ba66Smrg        for (i = 0; i < xf86NumDrivers && xf86NumScreens == 0; i++) {
1707e31ba66Smrg            xf86CallDriverProbe(xf86DriverList[i], FALSE);
1717e31ba66Smrg        }
1727e31ba66Smrg        xf86ProbeIgnorePrimary = FALSE;
1737e31ba66Smrg    }
1747e31ba66Smrg
1757e31ba66Smrg    /*
1767e31ba66Smrg     * 3. Call xf86platformAddGPUDevices() to add any additional video cards as
1777e31ba66Smrg     *    GPUScreens (GPUScreens are only supported by platformBus drivers).
1787e31ba66Smrg     */
1797e31ba66Smrg    for (i = 0; i < xf86NumDrivers; i++) {
1807e31ba66Smrg        xf86platformAddGPUDevices(xf86DriverList[i]);
1817e31ba66Smrg    }
1827e31ba66Smrg
1834202a189Smrg    /* If nothing was detected, return now */
1844202a189Smrg    if (xf86NumScreens == 0) {
1854202a189Smrg        xf86Msg(X_ERROR, "No devices detected.\n");
1864202a189Smrg        return FALSE;
1874202a189Smrg    }
18805b261ecSmrg
1894202a189Smrg    xf86VGAarbiterInit();
19005b261ecSmrg
1914202a189Smrg    /*
1924202a189Smrg     * Match up the screens found by the probes against those specified
1934202a189Smrg     * in the config file.  Remove the ones that won't be used.  Sort
1944202a189Smrg     * them in the order specified.
1954202a189Smrg     *
1964202a189Smrg     * What is the best way to do this?
1974202a189Smrg     *
1984202a189Smrg     * For now, go through the screens allocated by the probes, and
1994202a189Smrg     * look for screen config entry which refers to the same device
2004202a189Smrg     * section as picked out by the probe.
2014202a189Smrg     *
2024202a189Smrg     */
2034202a189Smrg    for (i = 0; i < xf86NumScreens; i++) {
2045a112b11Smrg        layout = xf86BusConfigMatch(xf86Screens[i], FALSE);
2055a112b11Smrg        if (layout && layout->screen)
2065a112b11Smrg            xf86Screens[i]->confScreen = layout->screen;
2075a112b11Smrg        else {
2084202a189Smrg            /* No match found */
2094202a189Smrg            xf86Msg(X_ERROR,
210f7df2e56Smrg                    "Screen %d deleted because of no matching config section.\n",
211f7df2e56Smrg                    i);
212f7df2e56Smrg            xf86DeleteScreen(xf86Screens[i--]);
2134202a189Smrg        }
2144202a189Smrg    }
2154202a189Smrg
2165a112b11Smrg    /* bind GPU conf screen to the configured protocol screen, or 0 if not configured */
2175a112b11Smrg    for (i = 0; i < xf86NumGPUScreens; i++) {
2185a112b11Smrg        layout = xf86BusConfigMatch(xf86GPUScreens[i], TRUE);
2195a112b11Smrg        int scrnum = (layout && layout->screen) ? layout->screen->screennum : 0;
2205a112b11Smrg        xf86GPUScreens[i]->confScreen = xf86Screens[scrnum]->confScreen;
2215a112b11Smrg    }
222f7df2e56Smrg
2234202a189Smrg    /* If no screens left, return now.  */
2244202a189Smrg    if (xf86NumScreens == 0) {
2254202a189Smrg        xf86Msg(X_ERROR,
226f7df2e56Smrg                "Device(s) detected, but none match those in the config file.\n");
2274202a189Smrg        return FALSE;
2284202a189Smrg    }
22905b261ecSmrg
2304202a189Smrg    return TRUE;
2314202a189Smrg}
23205b261ecSmrg
23305b261ecSmrg/*
23405b261ecSmrg * Call the bus probes relevant to the architecture.
23505b261ecSmrg *
23605b261ecSmrg * The only one available so far is for PCI and SBUS.
23705b261ecSmrg */
23805b261ecSmrg
23905b261ecSmrgvoid
24005b261ecSmrgxf86BusProbe(void)
24105b261ecSmrg{
242f7df2e56Smrg#ifdef XSERVER_PLATFORM_BUS
243f7df2e56Smrg    xf86platformProbe();
244f7df2e56Smrg    if (ServerIsNotSeat0() && xf86_num_platform_devices > 0)
245f7df2e56Smrg        return;
246f7df2e56Smrg#endif
247f7df2e56Smrg#ifdef XSERVER_LIBPCIACCESS
24805b261ecSmrg    xf86PciProbe();
249f7df2e56Smrg#endif
25005b261ecSmrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
25105b261ecSmrg    xf86SbusProbe();
25205b261ecSmrg#endif
253f7df2e56Smrg#ifdef XSERVER_PLATFORM_BUS
254f7df2e56Smrg    xf86platformPrimary();
255f7df2e56Smrg#endif
25605b261ecSmrg}
25705b261ecSmrg
25805b261ecSmrg/*
25905b261ecSmrg * Determine what bus type the busID string represents.  The start of the
26005b261ecSmrg * bus-dependent part of the string is returned as retID.
26105b261ecSmrg */
26205b261ecSmrg
26305b261ecSmrgBusType
264f7df2e56SmrgStringToBusType(const char *busID, const char **retID)
26505b261ecSmrg{
26605b261ecSmrg    char *p, *s;
26705b261ecSmrg    BusType ret = BUS_NONE;
26805b261ecSmrg
26905b261ecSmrg    /* If no type field, Default to PCI */
27005b261ecSmrg    if (isdigit(busID[0])) {
271f7df2e56Smrg        if (retID)
272f7df2e56Smrg            *retID = busID;
273f7df2e56Smrg        return BUS_PCI;
27405b261ecSmrg    }
27505b261ecSmrg
27605b261ecSmrg    s = xstrdup(busID);
27705b261ecSmrg    p = strtok(s, ":");
27805b261ecSmrg    if (p == NULL || *p == 0) {
279f7df2e56Smrg        free(s);
280f7df2e56Smrg        return BUS_NONE;
28105b261ecSmrg    }
28205b261ecSmrg    if (!xf86NameCmp(p, "pci") || !xf86NameCmp(p, "agp"))
283f7df2e56Smrg        ret = BUS_PCI;
28405b261ecSmrg    if (!xf86NameCmp(p, "sbus"))
285f7df2e56Smrg        ret = BUS_SBUS;
286f7df2e56Smrg    if (!xf86NameCmp(p, "platform"))
287f7df2e56Smrg        ret = BUS_PLATFORM;
2885a112b11Smrg    if (!xf86NameCmp(p, "usb"))
2895a112b11Smrg        ret = BUS_USB;
29005b261ecSmrg    if (ret != BUS_NONE)
291f7df2e56Smrg        if (retID)
292f7df2e56Smrg            *retID = busID + strlen(p) + 1;
2934202a189Smrg    free(s);
29405b261ecSmrg    return ret;
29505b261ecSmrg}
29605b261ecSmrg
29705b261ecSmrgint
29805b261ecSmrgxf86AllocateEntity(void)
29905b261ecSmrg{
30005b261ecSmrg    xf86NumEntities++;
301f7df2e56Smrg    xf86Entities = xnfreallocarray(xf86Entities,
302f7df2e56Smrg                                   xf86NumEntities, sizeof(EntityPtr));
303f7df2e56Smrg    xf86Entities[xf86NumEntities - 1] = xnfcalloc(1, sizeof(EntityRec));
30405b261ecSmrg    xf86Entities[xf86NumEntities - 1]->entityPrivates =
305f7df2e56Smrg        xnfcalloc(xf86EntityPrivateCount, sizeof(DevUnion));
3064202a189Smrg    return xf86NumEntities - 1;
30705b261ecSmrg}
30805b261ecSmrg
3094202a189SmrgBool
31005b261ecSmrgxf86IsEntityPrimary(int entityIndex)
31105b261ecSmrg{
31205b261ecSmrg    EntityPtr pEnt = xf86Entities[entityIndex];
313f7df2e56Smrg
314f7df2e56Smrg#ifdef XSERVER_LIBPCIACCESS
315f7df2e56Smrg    if (primaryBus.type == BUS_PLATFORM && pEnt->bus.type == BUS_PCI)
3165a112b11Smrg        if (primaryBus.id.plat->pdev)
3175a112b11Smrg            return MATCH_PCI_DEVICES(pEnt->bus.id.pci, primaryBus.id.plat->pdev);
318f7df2e56Smrg#endif
319f7df2e56Smrg
320f7df2e56Smrg    if (primaryBus.type != pEnt->bus.type)
321f7df2e56Smrg        return FALSE;
32205b261ecSmrg
3234202a189Smrg    switch (pEnt->bus.type) {
32405b261ecSmrg    case BUS_PCI:
325f7df2e56Smrg        return pEnt->bus.id.pci == primaryBus.id.pci;
32605b261ecSmrg    case BUS_SBUS:
327f7df2e56Smrg        return pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum;
328f7df2e56Smrg    case BUS_PLATFORM:
329f7df2e56Smrg        return pEnt->bus.id.plat == primaryBus.id.plat;
33005b261ecSmrg    default:
331f7df2e56Smrg        return FALSE;
33205b261ecSmrg    }
33305b261ecSmrg}
334f7df2e56Smrg
33505b261ecSmrgBool
33605b261ecSmrgxf86DriverHasEntities(DriverPtr drvp)
33705b261ecSmrg{
33805b261ecSmrg    int i;
339f7df2e56Smrg
34005b261ecSmrg    for (i = 0; i < xf86NumEntities; i++) {
341f7df2e56Smrg        if (xf86Entities[i]->driver == drvp)
342f7df2e56Smrg            return TRUE;
34305b261ecSmrg    }
34405b261ecSmrg    return FALSE;
34505b261ecSmrg}
34605b261ecSmrg
3474202a189Smrgvoid
34805b261ecSmrgxf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)
34905b261ecSmrg{
35005b261ecSmrg    if (entityIndex == -1)
351f7df2e56Smrg        return;
35205b261ecSmrg    if (xf86Entities[entityIndex]->inUse &&
353f7df2e56Smrg        !(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL)) {
354f7df2e56Smrg        ErrorF("Requested Entity already in use!\n");
355f7df2e56Smrg        return;
3564642e01fSmrg    }
35705b261ecSmrg
35805b261ecSmrg    pScrn->numEntities++;
359f7df2e56Smrg    pScrn->entityList = xnfreallocarray(pScrn->entityList,
360f7df2e56Smrg                                        pScrn->numEntities, sizeof(int));
36105b261ecSmrg    pScrn->entityList[pScrn->numEntities - 1] = entityIndex;
36205b261ecSmrg    xf86Entities[entityIndex]->inUse = TRUE;
363f7df2e56Smrg    pScrn->entityInstanceList = xnfreallocarray(pScrn->entityInstanceList,
364f7df2e56Smrg                                                pScrn->numEntities,
365f7df2e56Smrg                                                sizeof(int));
36605b261ecSmrg    pScrn->entityInstanceList[pScrn->numEntities - 1] = 0;
36705b261ecSmrg}
36805b261ecSmrg
3694202a189Smrgvoid
37005b261ecSmrgxf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex, int instance)
37105b261ecSmrg{
37205b261ecSmrg    int i;
37305b261ecSmrg
37405b261ecSmrg    if (entityIndex == -1 || entityIndex >= xf86NumEntities)
375f7df2e56Smrg        return;
37605b261ecSmrg
37705b261ecSmrg    for (i = 0; i < pScrn->numEntities; i++) {
378f7df2e56Smrg        if (pScrn->entityList[i] == entityIndex) {
379f7df2e56Smrg            pScrn->entityInstanceList[i] = instance;
380f7df2e56Smrg            break;
381f7df2e56Smrg        }
38205b261ecSmrg    }
38305b261ecSmrg}
38405b261ecSmrg
38505b261ecSmrg/*
38605b261ecSmrg * XXX  This needs to be updated for the case where a single entity may have
38705b261ecSmrg * instances associated with more than one screen.
38805b261ecSmrg */
3894202a189SmrgScrnInfoPtr
39005b261ecSmrgxf86FindScreenForEntity(int entityIndex)
39105b261ecSmrg{
392f7df2e56Smrg    int i, j;
393f7df2e56Smrg
394f7df2e56Smrg    if (entityIndex == -1)
395f7df2e56Smrg        return NULL;
39605b261ecSmrg
39705b261ecSmrg    if (xf86Screens) {
398f7df2e56Smrg        for (i = 0; i < xf86NumScreens; i++) {
399f7df2e56Smrg            for (j = 0; j < xf86Screens[i]->numEntities; j++) {
400f7df2e56Smrg                if (xf86Screens[i]->entityList[j] == entityIndex)
401f7df2e56Smrg                    return xf86Screens[i];
402f7df2e56Smrg            }
403f7df2e56Smrg        }
40405b261ecSmrg    }
40505b261ecSmrg    return NULL;
40605b261ecSmrg}
40705b261ecSmrg
4084202a189Smrgvoid
40905b261ecSmrgxf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)
41005b261ecSmrg{
41105b261ecSmrg    int i;
412f7df2e56Smrg
41305b261ecSmrg    for (i = 0; i < pScrn->numEntities; i++) {
414f7df2e56Smrg        if (pScrn->entityList[i] == entityIndex) {
415f7df2e56Smrg            for (i++; i < pScrn->numEntities; i++)
416f7df2e56Smrg                pScrn->entityList[i - 1] = pScrn->entityList[i];
417f7df2e56Smrg            pScrn->numEntities--;
418f7df2e56Smrg            xf86Entities[entityIndex]->inUse = FALSE;
419f7df2e56Smrg            break;
420f7df2e56Smrg        }
42105b261ecSmrg    }
42205b261ecSmrg}
42305b261ecSmrg
42405b261ecSmrg/*
425f7df2e56Smrg * xf86ClearEntityListForScreen() - called when a screen is deleted
4265a112b11Smrg * to mark its entities unused. Called by xf86DeleteScreen().
42705b261ecSmrg */
42805b261ecSmrgvoid
429f7df2e56Smrgxf86ClearEntityListForScreen(ScrnInfoPtr pScrn)
43005b261ecSmrg{
43105b261ecSmrg    int i, entityIndex;
432f7df2e56Smrg
433f7df2e56Smrg    if (pScrn->entityList == NULL || pScrn->numEntities == 0)
434f7df2e56Smrg        return;
435f7df2e56Smrg
43605b261ecSmrg    for (i = 0; i < pScrn->numEntities; i++) {
437f7df2e56Smrg        entityIndex = pScrn->entityList[i];
438f7df2e56Smrg        xf86Entities[entityIndex]->inUse = FALSE;
439f7df2e56Smrg        /* disable resource: call the disable function */
44005b261ecSmrg    }
4414202a189Smrg    free(pScrn->entityList);
4424202a189Smrg    free(pScrn->entityInstanceList);
44305b261ecSmrg    pScrn->entityList = NULL;
44405b261ecSmrg    pScrn->entityInstanceList = NULL;
44505b261ecSmrg}
44605b261ecSmrg
44705b261ecSmrg/*
44805b261ecSmrg * Add an extra device section (GDevPtr) to an entity.
44905b261ecSmrg */
45005b261ecSmrg
45105b261ecSmrgvoid
45205b261ecSmrgxf86AddDevToEntity(int entityIndex, GDevPtr dev)
45305b261ecSmrg{
45405b261ecSmrg    EntityPtr pEnt;
455f7df2e56Smrg
45605b261ecSmrg    if (entityIndex >= xf86NumEntities)
457f7df2e56Smrg        return;
458f7df2e56Smrg
45905b261ecSmrg    pEnt = xf86Entities[entityIndex];
46005b261ecSmrg    pEnt->numInstances++;
461f7df2e56Smrg    pEnt->devices = xnfreallocarray(pEnt->devices,
462f7df2e56Smrg                                    pEnt->numInstances, sizeof(GDevPtr));
46305b261ecSmrg    pEnt->devices[pEnt->numInstances - 1] = dev;
46405b261ecSmrg    dev->claimed = TRUE;
46505b261ecSmrg}
46605b261ecSmrg
467f7df2e56Smrg
468f7df2e56Smrgvoid
469f7df2e56Smrgxf86RemoveDevFromEntity(int entityIndex, GDevPtr dev)
470f7df2e56Smrg{
471f7df2e56Smrg    EntityPtr pEnt;
472f7df2e56Smrg    int i, j;
473f7df2e56Smrg    if (entityIndex >= xf86NumEntities)
474f7df2e56Smrg        return;
475f7df2e56Smrg
476f7df2e56Smrg    pEnt = xf86Entities[entityIndex];
477f7df2e56Smrg    for (i = 0; i < pEnt->numInstances; i++) {
478f7df2e56Smrg        if (pEnt->devices[i] == dev) {
479f7df2e56Smrg            for (j = i; j < pEnt->numInstances - 1; j++)
480f7df2e56Smrg                pEnt->devices[j] = pEnt->devices[j + 1];
481f7df2e56Smrg            break;
482f7df2e56Smrg        }
483f7df2e56Smrg    }
484f7df2e56Smrg    pEnt->numInstances--;
485f7df2e56Smrg    dev->claimed = FALSE;
486f7df2e56Smrg}
48705b261ecSmrg/*
48805b261ecSmrg * xf86GetEntityInfo() -- This function hands information from the
48905b261ecSmrg * EntityRec struct to the drivers. The EntityRec structure itself
49005b261ecSmrg * remains invisible to the driver.
49105b261ecSmrg */
4924202a189SmrgEntityInfoPtr
49305b261ecSmrgxf86GetEntityInfo(int entityIndex)
49405b261ecSmrg{
49505b261ecSmrg    EntityInfoPtr pEnt;
49605b261ecSmrg    int i;
497f7df2e56Smrg
4984202a189Smrg    if (entityIndex == -1)
499f7df2e56Smrg        return NULL;
5004202a189Smrg
50105b261ecSmrg    if (entityIndex >= xf86NumEntities)
502f7df2e56Smrg        return NULL;
503f7df2e56Smrg
504f7df2e56Smrg    pEnt = xnfcalloc(1, sizeof(EntityInfoRec));
50505b261ecSmrg    pEnt->index = entityIndex;
50605b261ecSmrg    pEnt->location = xf86Entities[entityIndex]->bus;
50705b261ecSmrg    pEnt->active = xf86Entities[entityIndex]->active;
50805b261ecSmrg    pEnt->chipset = xf86Entities[entityIndex]->chipset;
50905b261ecSmrg    pEnt->driver = xf86Entities[entityIndex]->driver;
510f7df2e56Smrg    if ((xf86Entities[entityIndex]->devices) &&
511f7df2e56Smrg        (xf86Entities[entityIndex]->devices[0])) {
512f7df2e56Smrg        for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
513f7df2e56Smrg            if (xf86Entities[entityIndex]->devices[i]->screen == 0)
514f7df2e56Smrg                break;
515f7df2e56Smrg        pEnt->device = xf86Entities[entityIndex]->devices[i];
516f7df2e56Smrg    }
517f7df2e56Smrg    else
518f7df2e56Smrg        pEnt->device = NULL;
519f7df2e56Smrg
52005b261ecSmrg    return pEnt;
52105b261ecSmrg}
52205b261ecSmrg
5234202a189Smrgint
52405b261ecSmrgxf86GetNumEntityInstances(int entityIndex)
52505b261ecSmrg{
52605b261ecSmrg    if (entityIndex >= xf86NumEntities)
527f7df2e56Smrg        return -1;
528f7df2e56Smrg
52905b261ecSmrg    return xf86Entities[entityIndex]->numInstances;
53005b261ecSmrg}
53105b261ecSmrg
5324202a189SmrgGDevPtr
53305b261ecSmrgxf86GetDevFromEntity(int entityIndex, int instance)
53405b261ecSmrg{
53505b261ecSmrg    int i;
536f7df2e56Smrg
53705b261ecSmrg    /* We might not use AddDevtoEntity */
538f7df2e56Smrg    if ((!xf86Entities[entityIndex]->devices) ||
539f7df2e56Smrg        (!xf86Entities[entityIndex]->devices[0]))
540f7df2e56Smrg        return NULL;
54105b261ecSmrg
54205b261ecSmrg    if (entityIndex >= xf86NumEntities ||
543f7df2e56Smrg        instance >= xf86Entities[entityIndex]->numInstances)
544f7df2e56Smrg        return NULL;
545f7df2e56Smrg
54605b261ecSmrg    for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
547f7df2e56Smrg        if (xf86Entities[entityIndex]->devices[i]->screen == instance)
548d44ca368Smrg            return xf86Entities[entityIndex]->devices[i];
549d44ca368Smrg    return NULL;
55005b261ecSmrg}
55105b261ecSmrg
55205b261ecSmrg/*
5534202a189Smrg * xf86PostProbe() -- Allocate all non conflicting resources
5544202a189Smrg * This function gets called by xf86Init().
55505b261ecSmrg */
55605b261ecSmrgvoid
5574202a189Smrgxf86PostProbe(void)
55805b261ecSmrg{
559f7df2e56Smrg    if (fbSlotClaimed && (
5604202a189Smrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
561f7df2e56Smrg                             sbusSlotClaimed ||
5624202a189Smrg#endif
563f7df2e56Smrg#ifdef XSERVER_PLATFORM_BUS
564f7df2e56Smrg                             platformSlotClaimed ||
565f7df2e56Smrg#endif
566f7df2e56Smrg#ifdef XSERVER_LIBPCIACCESS
567f7df2e56Smrg                             pciSlotClaimed
568f7df2e56Smrg#else
569f7df2e56Smrg                             TRUE
570f7df2e56Smrg#endif
571f7df2e56Smrg        ))
572f7df2e56Smrg        FatalError("Cannot run in framebuffer mode. Please specify busIDs "
573f7df2e56Smrg                   "       for all framebuffer devices\n");
57405b261ecSmrg}
57505b261ecSmrg
5764202a189SmrgBool
5774202a189Smrgxf86IsEntityShared(int entityIndex)
5784202a189Smrg{
579f7df2e56Smrg    if (entityIndex < xf86NumEntities) {
580f7df2e56Smrg        if (xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL) {
581f7df2e56Smrg            return TRUE;
582f7df2e56Smrg        }
58305b261ecSmrg    }
5844202a189Smrg    return FALSE;
58505b261ecSmrg}
58605b261ecSmrg
5874202a189Smrgvoid
5884202a189Smrgxf86SetEntityShared(int entityIndex)
58905b261ecSmrg{
590f7df2e56Smrg    if (entityIndex < xf86NumEntities) {
5914202a189Smrg        xf86Entities[entityIndex]->entityProp |= IS_SHARED_ACCEL;
59205b261ecSmrg    }
5934202a189Smrg}
59405b261ecSmrg
5954202a189SmrgBool
5964202a189Smrgxf86IsEntitySharable(int entityIndex)
5974202a189Smrg{
598f7df2e56Smrg    if (entityIndex < xf86NumEntities) {
599f7df2e56Smrg        if (xf86Entities[entityIndex]->entityProp & ACCEL_IS_SHARABLE) {
600f7df2e56Smrg            return TRUE;
601f7df2e56Smrg        }
60205b261ecSmrg    }
6034202a189Smrg    return FALSE;
60405b261ecSmrg}
60505b261ecSmrg
6064202a189Smrgvoid
6074202a189Smrgxf86SetEntitySharable(int entityIndex)
60805b261ecSmrg{
609f7df2e56Smrg    if (entityIndex < xf86NumEntities) {
6104202a189Smrg        xf86Entities[entityIndex]->entityProp |= ACCEL_IS_SHARABLE;
6114202a189Smrg    }
61205b261ecSmrg}
61305b261ecSmrg
6144202a189SmrgBool
6154202a189Smrgxf86IsPrimInitDone(int entityIndex)
61605b261ecSmrg{
617f7df2e56Smrg    if (entityIndex < xf86NumEntities) {
618f7df2e56Smrg        if (xf86Entities[entityIndex]->entityProp & SA_PRIM_INIT_DONE) {
619f7df2e56Smrg            return TRUE;
620f7df2e56Smrg        }
62105b261ecSmrg    }
6224202a189Smrg    return FALSE;
62305b261ecSmrg}
62405b261ecSmrg
6254202a189Smrgvoid
6264202a189Smrgxf86SetPrimInitDone(int entityIndex)
62705b261ecSmrg{
628f7df2e56Smrg    if (entityIndex < xf86NumEntities) {
6294202a189Smrg        xf86Entities[entityIndex]->entityProp |= SA_PRIM_INIT_DONE;
63005b261ecSmrg    }
63105b261ecSmrg}
63205b261ecSmrg
6334202a189Smrgvoid
6344202a189Smrgxf86ClearPrimInitDone(int entityIndex)
63505b261ecSmrg{
636f7df2e56Smrg    if (entityIndex < xf86NumEntities) {
6374202a189Smrg        xf86Entities[entityIndex]->entityProp &= ~SA_PRIM_INIT_DONE;
63805b261ecSmrg    }
63905b261ecSmrg}
6404202a189Smrg
64105b261ecSmrg/*
6424202a189Smrg * Allocate a private in the entities.
64305b261ecSmrg */
64405b261ecSmrg
6454202a189Smrgint
64605b261ecSmrgxf86AllocateEntityPrivateIndex(void)
64705b261ecSmrg{
64805b261ecSmrg    int idx, i;
64905b261ecSmrg    EntityPtr pEnt;
65005b261ecSmrg    DevUnion *nprivs;
65105b261ecSmrg
65205b261ecSmrg    idx = xf86EntityPrivateCount++;
65305b261ecSmrg    for (i = 0; i < xf86NumEntities; i++) {
654f7df2e56Smrg        pEnt = xf86Entities[i];
655f7df2e56Smrg        nprivs = xnfreallocarray(pEnt->entityPrivates,
656f7df2e56Smrg                                 xf86EntityPrivateCount, sizeof(DevUnion));
657f7df2e56Smrg        /* Zero the new private */
658f7df2e56Smrg        memset(&nprivs[idx], 0, sizeof(DevUnion));
659f7df2e56Smrg        pEnt->entityPrivates = nprivs;
66005b261ecSmrg    }
66105b261ecSmrg    return idx;
66205b261ecSmrg}
66305b261ecSmrg
6644202a189SmrgDevUnion *
66505b261ecSmrgxf86GetEntityPrivate(int entityIndex, int privIndex)
66605b261ecSmrg{
66705b261ecSmrg    if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount)
668f7df2e56Smrg        return NULL;
66905b261ecSmrg
67005b261ecSmrg    return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
67105b261ecSmrg}
672