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