diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index 7dd693feb..ab0e045dc 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -1,3 +1,4 @@ + /* * Copyright (c) 1997-2003 by The XFree86 Project, Inc. * @@ -127,6 +128,8 @@ extern _X_EXPORT void xf86DeallocateResourcesForEntity(int entityIndex, unsigned extern _X_EXPORT resPtr xf86RegisterResources(int entityIndex, resList list, unsigned long Access); extern _X_EXPORT Bool xf86CheckPciMemBase(struct pci_device * pPci, memType base); +extern _X_EXPORT void xf86SetAccessFuncs(EntityInfoPtr pEnt, xf86SetAccessFuncPtr funcs, + xf86SetAccessFuncPtr oldFuncs); extern _X_EXPORT Bool xf86IsEntityPrimary(int entityIndex); extern _X_EXPORT resPtr xf86SetOperatingState(resList list, int entityIndex, int mask); extern _X_EXPORT void xf86EnterServerState(xf86State state); diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c index f5b535c68..8040f580b 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -792,6 +792,24 @@ xf86SetCurrentAccess(Bool Enable, ScrnInfoPtr pScrn) } } +void +xf86SetAccessFuncs(EntityInfoPtr pEnt, xf86SetAccessFuncPtr funcs, + xf86SetAccessFuncPtr oldFuncs) +{ + AccessFuncPtr rac; + + if (!xf86Entities[pEnt->index]->rac) + xf86Entities[pEnt->index]->rac = xnfcalloc(1,sizeof(AccessFuncRec)); + + rac = xf86Entities[pEnt->index]->rac; + + rac->mem_new = funcs->mem; + rac->io_new = funcs->io; + rac->io_mem_new = funcs->io_mem; + + rac->old = oldFuncs; +} + /* * Conflict checking */ @@ -1374,11 +1392,30 @@ busTypeSpecific(EntityPtr pEnt, xf86AccessPtr *acc_mem, static void setAccess(EntityPtr pEnt, xf86State state) { + xf86AccessPtr acc_mem, acc_io, acc_mem_io; + xf86AccessPtr org_mem = NULL, org_io = NULL, org_mem_io = NULL; int prop; busTypeSpecific(pEnt, &acc_mem, &acc_io, &acc_mem_io); + /* The replacement function needs to handle _all_ shared resources */ + /* unless they are handeled locally and disabled otherwise */ + if (pEnt->rac) { + if (pEnt->rac->io_new) { + org_io = acc_io; + acc_io = pEnt->rac->io_new; + } + if (pEnt->rac->mem_new) { + org_mem = acc_mem; + acc_mem = pEnt->rac->mem_new; + } + if (pEnt->rac->io_mem_new) { + org_mem_io = acc_mem_io; + acc_mem_io = pEnt->rac->io_mem_new; + } + } + if (state == OPERATING) { prop = pEnt->entityProp; switch(pEnt->entityProp & NEED_SHARED) { @@ -1414,6 +1451,39 @@ setAccess(EntityPtr pEnt, xf86State state) break; } + if (org_io) { + /* does the driver want the old access func? */ + if (pEnt->rac->old) { + /* give it to the driver, leave state disabled */ + pEnt->rac->old->io = org_io; + } else { + /* driver doesn't want it - enable generic access */ + org_io->AccessEnable(org_io->arg); + } + } + + if (org_mem_io) { + /* does the driver want the old access func? */ + if (pEnt->rac->old) { + /* give it to the driver, leave state disabled */ + pEnt->rac->old->io_mem = org_mem_io; + } else { + /* driver doesn't want it - enable generic access */ + org_mem_io->AccessEnable(org_mem_io->arg); + } + } + + if (org_mem) { + /* does the driver want the old access func? */ + if (pEnt->rac->old) { + /* give it to the driver, leave state disabled */ + pEnt->rac->old->mem = org_mem; + } else { + /* driver doesn't want it - enable generic access */ + org_mem->AccessEnable(org_mem->arg); + } + } + if (!(prop & NEED_MEM_SHARED)){ if (prop & NEED_MEM) { if (acc_mem) diff --git a/hw/xfree86/common/xf86Bus.h b/hw/xfree86/common/xf86Bus.h index dfc417659..83ba83c85 100644 --- a/hw/xfree86/common/xf86Bus.h +++ b/hw/xfree86/common/xf86Bus.h @@ -47,6 +47,7 @@ typedef struct racInfo { xf86AccessPtr mem_new; xf86AccessPtr io_new; xf86AccessPtr io_mem_new; + xf86SetAccessFuncPtr old; } AccessFuncRec, *AccessFuncPtr; @@ -63,6 +64,7 @@ typedef struct { Bool inUse; BusRec bus; EntityAccessPtr access; + AccessFuncPtr rac; pointer busAcc; int lastScrnFlag; DevUnion * entityPrivates; diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h index 511181f6e..904c369a6 100644 --- a/hw/xfree86/common/xf86str.h +++ b/hw/xfree86/common/xf86str.h @@ -582,6 +582,12 @@ typedef struct _AccessRec { void *arg; } xf86AccessRec, *xf86AccessPtr; +typedef struct { + xf86AccessPtr mem; + xf86AccessPtr io; + xf86AccessPtr io_mem; +} xf86SetAccessFuncRec, *xf86SetAccessFuncPtr; + /* bus-access-related types */ typedef enum { NONE,