#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/X.h>
#include "os.h"
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86Bus.h"
#define XF86_OS_PRIVS
#include "xf86_OSproc.h"
#include "xf86VGAarbiter.h"
EntityPtr *xf86Entities = NULL;
int xf86NumEntities = 0;
static int xf86EntityPrivateCount = 0;
BusRec primaryBus = { BUS_NONE, { 0 } };
Bool
xf86CallDriverProbe( DriverPtr drv, Bool detect_only )
{
Bool foundScreen = FALSE;
if (drv->PciProbe != NULL) {
if (xf86DoConfigure && xf86DoConfigurePass1) {
assert(detect_only);
foundScreen = xf86PciAddMatchingDev(drv);
}
else {
assert(! detect_only);
foundScreen = xf86PciProbeDev(drv);
}
}
if (!foundScreen && (drv->Probe != NULL)) {
xf86Msg( X_WARNING, "Falling back to old probe method for %s\n",
drv->driverName);
foundScreen = (*drv->Probe)(drv, (detect_only) ? PROBE_DETECT
: PROBE_DEFAULT);
}
return foundScreen;
}
Bool
xf86BusConfig(void)
{
screenLayoutPtr layout;
int i, j;
if (xorgHWAccess)
xorgHWAccess = xf86EnableIO();
for (i = 0; i < xf86NumDrivers; i++) {
xorgHWFlags flags;
if (!xorgHWAccess) {
if (!xf86DriverList[i]->driverFunc
|| !xf86DriverList[i]->driverFunc(NULL,
GET_REQUIRED_HW_INTERFACES,
&flags)
|| NEED_IO_ENABLED(flags))
continue;
}
xf86CallDriverProbe(xf86DriverList[i], FALSE);
}
if (xf86NumScreens == 0) {
xf86Msg(X_ERROR, "No devices detected.\n");
return FALSE;
}
xf86VGAarbiterInit();
for (i = 0; i < xf86NumScreens; i++) {
for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
layout++) {
Bool found = FALSE;
for (j = 0; j < xf86Screens[i]->numEntities; j++) {
GDevPtr dev = xf86GetDevFromEntity(
xf86Screens[i]->entityList[j],
xf86Screens[i]->entityInstanceList[j]);
if (dev == layout->screen->device) {
xf86Screens[i]->confScreen = layout->screen;
found = TRUE;
break;
}
}
if (found) break;
}
if (layout->screen == NULL) {
xf86Msg(X_ERROR,
"Screen %d deleted because of no matching config section.\n", i);
xf86DeleteScreen(i--, 0);
}
}
if (xf86NumScreens == 0) {
xf86Msg(X_ERROR,
"Device(s) detected, but none match those in the config file.\n");
return FALSE;
}
return TRUE;
}
void
xf86BusProbe(void)
{
xf86PciProbe();
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
xf86SbusProbe();
#endif
}
BusType
StringToBusType(const char* busID, const char **retID)
{
char *p, *s;
BusType ret = BUS_NONE;
if (isdigit(busID[0])) {
if (retID)
*retID = busID;
return BUS_PCI;
}
s = xstrdup(busID);
p = strtok(s, ":");
if (p == NULL || *p == 0) {
free(s);
return BUS_NONE;
}
if (!xf86NameCmp(p, "pci") || !xf86NameCmp(p, "agp"))
ret = BUS_PCI;
if (!xf86NameCmp(p, "sbus"))
ret = BUS_SBUS;
if (ret != BUS_NONE)
if (retID)
*retID = busID + strlen(p) + 1;
free(s);
return ret;
}
int
xf86AllocateEntity(void)
{
xf86NumEntities++;
xf86Entities = xnfrealloc(xf86Entities,
sizeof(EntityPtr) * xf86NumEntities);
xf86Entities[xf86NumEntities - 1] = xnfcalloc(1,sizeof(EntityRec));
xf86Entities[xf86NumEntities - 1]->entityPrivates =
xnfcalloc(sizeof(DevUnion) * xf86EntityPrivateCount, 1);
return xf86NumEntities - 1;
}
Bool
xf86IsEntityPrimary(int entityIndex)
{
EntityPtr pEnt = xf86Entities[entityIndex];
if (primaryBus.type != pEnt->bus.type) return FALSE;
switch (pEnt->bus.type) {
case BUS_PCI:
return pEnt->bus.id.pci == primaryBus.id.pci;
case BUS_SBUS:
return pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum;
default:
return FALSE;
}
}
Bool
xf86SetEntityFuncs(int entityIndex, EntityProc init, EntityProc enter,
EntityProc leave, pointer private)
{
if (entityIndex >= xf86NumEntities)
return FALSE;
xf86Entities[entityIndex]->entityInit = init;
xf86Entities[entityIndex]->entityEnter = enter;
xf86Entities[entityIndex]->entityLeave = leave;
xf86Entities[entityIndex]->private = private;
return TRUE;
}
Bool
xf86DriverHasEntities(DriverPtr drvp)
{
int i;
for (i = 0; i < xf86NumEntities; i++) {
if (xf86Entities[i]->driver == drvp)
return TRUE;
}
return FALSE;
}
void
xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)
{
if (entityIndex == -1)
return;
if (xf86Entities[entityIndex]->inUse &&
!(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL)) {
ErrorF("Requested Entity already in use!\n");
return;
}
pScrn->numEntities++;
pScrn->entityList = xnfrealloc(pScrn->entityList,
pScrn->numEntities * sizeof(int));
pScrn->entityList[pScrn->numEntities - 1] = entityIndex;
xf86Entities[entityIndex]->inUse = TRUE;
pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList,
pScrn->numEntities * sizeof(int));
pScrn->entityInstanceList[pScrn->numEntities - 1] = 0;
pScrn->domainIOBase = xf86Entities[entityIndex]->domainIO;
}
void
xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex, int instance)
{
int i;
if (entityIndex == -1 || entityIndex >= xf86NumEntities)
return;
for (i = 0; i < pScrn->numEntities; i++) {
if (pScrn->entityList[i] == entityIndex) {
pScrn->entityInstanceList[i] = instance;
break;
}
}
}
ScrnInfoPtr
xf86FindScreenForEntity(int entityIndex)
{
int i,j;
if (entityIndex == -1) return NULL;
if (xf86Screens) {
for (i = 0; i < xf86NumScreens; i++) {
for (j = 0; j < xf86Screens[i]->numEntities; j++) {
if ( xf86Screens[i]->entityList[j] == entityIndex )
return xf86Screens[i];
}
}
}
return NULL;
}
void
xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)
{
int i;
for (i = 0; i < pScrn->numEntities; i++) {
if (pScrn->entityList[i] == entityIndex) {
for (i++; i < pScrn->numEntities; i++)
pScrn->entityList[i-1] = pScrn->entityList[i];
pScrn->numEntities--;
xf86Entities[entityIndex]->inUse = FALSE;
break;
}
}
}
void
xf86ClearEntityListForScreen(int scrnIndex)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
int i, entityIndex;
if (pScrn->entityList == NULL || pScrn->numEntities == 0) return;
for (i = 0; i < pScrn->numEntities; i++) {
entityIndex = pScrn->entityList[i];
xf86Entities[entityIndex]->inUse = FALSE;
}
free(pScrn->entityList);
free(pScrn->entityInstanceList);
pScrn->entityList = NULL;
pScrn->entityInstanceList = NULL;
}
void
xf86AddDevToEntity(int entityIndex, GDevPtr dev)
{
EntityPtr pEnt;
if (entityIndex >= xf86NumEntities)
return;
pEnt = xf86Entities[entityIndex];
pEnt->numInstances++;
pEnt->devices = xnfrealloc(pEnt->devices,
pEnt->numInstances * sizeof(GDevPtr));
pEnt->devices[pEnt->numInstances - 1] = dev;
dev->claimed = TRUE;
}
EntityInfoPtr
xf86GetEntityInfo(int entityIndex)
{
EntityInfoPtr pEnt;
int i;
if (entityIndex == -1)
return NULL;
if (entityIndex >= xf86NumEntities)
return NULL;
pEnt = xnfcalloc(1,sizeof(EntityInfoRec));
pEnt->index = entityIndex;
pEnt->location = xf86Entities[entityIndex]->bus;
pEnt->active = xf86Entities[entityIndex]->active;
pEnt->chipset = xf86Entities[entityIndex]->chipset;
pEnt->driver = xf86Entities[entityIndex]->driver;
if ( (xf86Entities[entityIndex]->devices) &&
(xf86Entities[entityIndex]->devices[0]) ) {
for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
if (xf86Entities[entityIndex]->devices[i]->screen == 0)
break;
pEnt->device = xf86Entities[entityIndex]->devices[i];
} else
pEnt->device = NULL;
return pEnt;
}
int
xf86GetNumEntityInstances(int entityIndex)
{
if (entityIndex >= xf86NumEntities)
return -1;
return xf86Entities[entityIndex]->numInstances;
}
GDevPtr
xf86GetDevFromEntity(int entityIndex, int instance)
{
int i;
if ( (!xf86Entities[entityIndex]->devices) ||
(!xf86Entities[entityIndex]->devices[0]) )
return NULL;
if (entityIndex >= xf86NumEntities ||
instance >= xf86Entities[entityIndex]->numInstances)
return NULL;
for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
if (xf86Entities[entityIndex]->devices[i]->screen == instance)
break;
return xf86Entities[entityIndex]->devices[i];
}
void
xf86AccessEnter(void)
{
int i;
for (i = 0; i < xf86NumEntities; i++)
if (xf86Entities[i]->entityEnter)
xf86Entities[i]->entityEnter(i,xf86Entities[i]->private);
}
void
xf86AccessLeave(void)
{
int i;
for (i = 0; i < xf86NumEntities; i++)
if (xf86Entities[i]->entityLeave)
xf86Entities[i]->entityLeave(i,xf86Entities[i]->private);
}
void
xf86PostProbe(void)
{
int i;
if (fbSlotClaimed && (pciSlotClaimed
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
|| sbusSlotClaimed
#endif
))
FatalError("Cannot run in framebuffer mode. Please specify busIDs "
" for all framebuffer devices\n");
for (i = 0; i < xf86NumEntities; i++)
if (xf86Entities[i]->entityInit)
xf86Entities[i]->entityInit(i,xf86Entities[i]->private);
}
int
xf86GetLastScrnFlag(int entityIndex)
{
if(entityIndex < xf86NumEntities) {
return xf86Entities[entityIndex]->lastScrnFlag;
} else {
return -1;
}
}
void
xf86SetLastScrnFlag(int entityIndex, int scrnIndex)
{
if(entityIndex < xf86NumEntities) {
xf86Entities[entityIndex]->lastScrnFlag = scrnIndex;
}
}
Bool
xf86IsEntityShared(int entityIndex)
{
if(entityIndex < xf86NumEntities) {
if(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL) {
return TRUE;
}
}
return FALSE;
}
void
xf86SetEntityShared(int entityIndex)
{
if(entityIndex < xf86NumEntities) {
xf86Entities[entityIndex]->entityProp |= IS_SHARED_ACCEL;
}
}
Bool
xf86IsEntitySharable(int entityIndex)
{
if(entityIndex < xf86NumEntities) {
if(xf86Entities[entityIndex]->entityProp & ACCEL_IS_SHARABLE) {
return TRUE;
}
}
return FALSE;
}
void
xf86SetEntitySharable(int entityIndex)
{
if(entityIndex < xf86NumEntities) {
xf86Entities[entityIndex]->entityProp |= ACCEL_IS_SHARABLE;
}
}
Bool
xf86IsPrimInitDone(int entityIndex)
{
if(entityIndex < xf86NumEntities) {
if(xf86Entities[entityIndex]->entityProp & SA_PRIM_INIT_DONE) {
return TRUE;
}
}
return FALSE;
}
void
xf86SetPrimInitDone(int entityIndex)
{
if(entityIndex < xf86NumEntities) {
xf86Entities[entityIndex]->entityProp |= SA_PRIM_INIT_DONE;
}
}
void
xf86ClearPrimInitDone(int entityIndex)
{
if(entityIndex < xf86NumEntities) {
xf86Entities[entityIndex]->entityProp &= ~SA_PRIM_INIT_DONE;
}
}
int
xf86AllocateEntityPrivateIndex(void)
{
int idx, i;
EntityPtr pEnt;
DevUnion *nprivs;
idx = xf86EntityPrivateCount++;
for (i = 0; i < xf86NumEntities; i++) {
pEnt = xf86Entities[i];
nprivs = xnfrealloc(pEnt->entityPrivates,
xf86EntityPrivateCount * sizeof(DevUnion));
memset(&nprivs[idx], 0, sizeof(DevUnion));
pEnt->entityPrivates = nprivs;
}
return idx;
}
DevUnion *
xf86GetEntityPrivate(int entityIndex, int privIndex)
{
if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount)
return NULL;
return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
}