xfree86: remove all kind of bus and PCI dependency from the common helper file
Move all PCI procedures from xf86Helper.c to a more meaningful place (namely xf86pciBus.c). xf86Helper.c is free of PCI code now. Signed-off-by: Tiago Vignatti <tiago.vignatti@nokia.com> Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
This commit is contained in:
parent
610009cf39
commit
9d000a5509
|
@ -38,9 +38,6 @@
|
|||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#include <pciaccess.h>
|
||||
#include "Pci.h"
|
||||
|
||||
#include <X11/X.h>
|
||||
#include "os.h"
|
||||
#include "servermd.h"
|
||||
|
@ -57,7 +54,6 @@
|
|||
#include "xf86Xinput.h"
|
||||
#include "xf86InPriv.h"
|
||||
#include "mivalidate.h"
|
||||
#include "xf86Bus.h"
|
||||
#include "xf86Crtc.h"
|
||||
|
||||
/* For xf86GetClocks */
|
||||
|
@ -1506,420 +1502,6 @@ xf86MatchDevice(const char *drivername, GDevPtr **sectlist)
|
|||
return i;
|
||||
}
|
||||
|
||||
static Bool
|
||||
pciDeviceHasBars(struct pci_device *pci)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
if (pci->regions[i].size)
|
||||
return TRUE;
|
||||
|
||||
if (pci->rom_size)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct Inst {
|
||||
struct pci_device * pci;
|
||||
GDevPtr dev;
|
||||
Bool foundHW; /* PCIid in list of supported chipsets */
|
||||
Bool claimed; /* BusID matches with a device section */
|
||||
int chip;
|
||||
int screen;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Find set of unclaimed devices matching a given vendor ID.
|
||||
*
|
||||
* Used by drivers to find as yet unclaimed devices matching the specified
|
||||
* vendor ID.
|
||||
*
|
||||
* \param driverName Name of the driver. This is used to find Device
|
||||
* sections in the config file.
|
||||
* \param vendorID PCI vendor ID of associated devices. If zero, then
|
||||
* the true vendor ID must be encoded in the \c PCIid
|
||||
* fields of the \c PCIchipsets entries.
|
||||
* \param chipsets Symbol table used to associate chipset names with
|
||||
* PCI IDs.
|
||||
* \param devList List of Device sections parsed from the config file.
|
||||
* \param numDevs Number of entries in \c devList.
|
||||
* \param drvp Pointer the driver's control structure.
|
||||
* \param foundEntities Returned list of entity indicies associated with the
|
||||
* driver.
|
||||
*
|
||||
* \returns
|
||||
* The number of elements in returned in \c foundEntities on success or zero
|
||||
* on failure.
|
||||
*
|
||||
* \todo
|
||||
* This function does a bit more than short description says. Fill in some
|
||||
* more of the details of its operation.
|
||||
*
|
||||
* \todo
|
||||
* The \c driverName parameter is redundant. It is the same as
|
||||
* \c DriverRec::driverName. In a future version of this function, remove
|
||||
* that parameter.
|
||||
*/
|
||||
int
|
||||
xf86MatchPciInstances(const char *driverName, int vendorID,
|
||||
SymTabPtr chipsets, PciChipsets *PCIchipsets,
|
||||
GDevPtr *devList, int numDevs, DriverPtr drvp,
|
||||
int **foundEntities)
|
||||
{
|
||||
int i,j;
|
||||
struct pci_device * pPci;
|
||||
struct pci_device_iterator *iter;
|
||||
struct Inst *instances = NULL;
|
||||
int numClaimedInstances = 0;
|
||||
int allocatedInstances = 0;
|
||||
int numFound = 0;
|
||||
SymTabRec *c;
|
||||
PciChipsets *id;
|
||||
int *retEntities = NULL;
|
||||
|
||||
*foundEntities = NULL;
|
||||
|
||||
|
||||
/* Each PCI device will contribute at least one entry. Each device
|
||||
* section can contribute at most one entry. The sum of the two is
|
||||
* guaranteed to be larger than the maximum possible number of entries.
|
||||
* Do this calculation and memory allocation once now to eliminate the
|
||||
* need for realloc calls inside the loop.
|
||||
*/
|
||||
if (!(xf86DoConfigure && xf86DoConfigurePass1)) {
|
||||
unsigned max_entries = numDevs;
|
||||
|
||||
iter = pci_slot_match_iterator_create(NULL);
|
||||
while ((pPci = pci_device_next(iter)) != NULL) {
|
||||
max_entries++;
|
||||
}
|
||||
|
||||
pci_iterator_destroy(iter);
|
||||
instances = xnfalloc(max_entries * sizeof(struct Inst));
|
||||
}
|
||||
|
||||
iter = pci_slot_match_iterator_create(NULL);
|
||||
while ((pPci = pci_device_next(iter)) != NULL) {
|
||||
unsigned device_class = pPci->device_class;
|
||||
Bool foundVendor = FALSE;
|
||||
|
||||
|
||||
/* Convert the pre-PCI 2.0 device class for a VGA adapter to the
|
||||
* 2.0 version of the same class.
|
||||
*/
|
||||
if ( device_class == 0x00000101 ) {
|
||||
device_class = 0x00030000;
|
||||
}
|
||||
|
||||
|
||||
/* Find PCI devices that match the given vendor ID. The vendor ID is
|
||||
* either specified explicitly as a parameter to the function or
|
||||
* implicitly encoded in the high bits of id->PCIid.
|
||||
*
|
||||
* The first device with a matching vendor is recorded, even if the
|
||||
* device ID doesn't match. This is done because the Device section
|
||||
* in the xorg.conf file can over-ride the device ID. A matching PCI
|
||||
* ID might not be found now, but after the device ID over-ride is
|
||||
* applied there /might/ be a match.
|
||||
*/
|
||||
for (id = PCIchipsets; id->PCIid != -1; id++) {
|
||||
const unsigned vendor_id = ((id->PCIid & 0xFFFF0000) >> 16)
|
||||
| vendorID;
|
||||
const unsigned device_id = (id->PCIid & 0x0000FFFF);
|
||||
const unsigned match_class = 0x00030000 | id->PCIid;
|
||||
|
||||
if ((vendor_id == pPci->vendor_id)
|
||||
|| ((vendorID == PCI_VENDOR_GENERIC) && (match_class == device_class))) {
|
||||
if (!foundVendor && (instances != NULL)) {
|
||||
++allocatedInstances;
|
||||
instances[allocatedInstances - 1].pci = pPci;
|
||||
instances[allocatedInstances - 1].dev = NULL;
|
||||
instances[allocatedInstances - 1].claimed = FALSE;
|
||||
instances[allocatedInstances - 1].foundHW = FALSE;
|
||||
instances[allocatedInstances - 1].screen = 0;
|
||||
}
|
||||
|
||||
foundVendor = TRUE;
|
||||
|
||||
if ( (device_id == pPci->device_id)
|
||||
|| ((vendorID == PCI_VENDOR_GENERIC)
|
||||
&& (match_class == device_class)) ) {
|
||||
if ( instances != NULL ) {
|
||||
instances[allocatedInstances - 1].foundHW = TRUE;
|
||||
instances[allocatedInstances - 1].chip = id->numChipset;
|
||||
}
|
||||
|
||||
|
||||
if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
|
||||
if (xf86CheckPciSlot(pPci)) {
|
||||
GDevPtr pGDev =
|
||||
xf86AddBusDeviceToConfigure(drvp->driverName,
|
||||
BUS_PCI, pPci, -1);
|
||||
if (pGDev) {
|
||||
/* After configure pass 1, chipID and chipRev
|
||||
* are treated as over-rides, so clobber them
|
||||
* here.
|
||||
*/
|
||||
pGDev->chipID = -1;
|
||||
pGDev->chipRev = -1;
|
||||
}
|
||||
|
||||
numFound++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
numFound++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pci_iterator_destroy(iter);
|
||||
|
||||
|
||||
/* In "probe only" or "configure" mode (signaled by instances being NULL),
|
||||
* our work is done. Return the number of detected devices.
|
||||
*/
|
||||
if ( instances == NULL ) {
|
||||
return numFound;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This may be debatable, but if no PCI devices with a matching vendor
|
||||
* type is found, return zero now. It is probably not desirable to
|
||||
* allow the config file to override this.
|
||||
*/
|
||||
if (allocatedInstances <= 0) {
|
||||
free(instances);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DebugF("%s instances found: %d\n", driverName, allocatedInstances);
|
||||
|
||||
/*
|
||||
* Check for devices that need duplicated instances. This is required
|
||||
* when there is more than one screen per entity.
|
||||
*
|
||||
* XXX This currently doesn't work for cases where the BusID isn't
|
||||
* specified explicitly in the config file.
|
||||
*/
|
||||
|
||||
for (j = 0; j < numDevs; j++) {
|
||||
if (devList[j]->screen > 0 && devList[j]->busID
|
||||
&& *devList[j]->busID) {
|
||||
for (i = 0; i < allocatedInstances; i++) {
|
||||
pPci = instances[i].pci;
|
||||
if (xf86ComparePciBusString(devList[j]->busID,
|
||||
PCI_MAKE_BUS( pPci->domain, pPci->bus ),
|
||||
pPci->dev,
|
||||
pPci->func)) {
|
||||
allocatedInstances++;
|
||||
instances[allocatedInstances - 1] = instances[i];
|
||||
instances[allocatedInstances - 1].screen =
|
||||
devList[j]->screen;
|
||||
numFound++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < allocatedInstances; i++) {
|
||||
GDevPtr dev = NULL;
|
||||
GDevPtr devBus = NULL;
|
||||
|
||||
pPci = instances[i].pci;
|
||||
for (j = 0; j < numDevs; j++) {
|
||||
if (devList[j]->busID && *devList[j]->busID) {
|
||||
if (xf86ComparePciBusString(devList[j]->busID,
|
||||
PCI_MAKE_BUS( pPci->domain, pPci->bus ),
|
||||
pPci->dev,
|
||||
pPci->func) &&
|
||||
devList[j]->screen == instances[i].screen) {
|
||||
|
||||
if (devBus)
|
||||
xf86MsgVerb(X_WARNING,0,
|
||||
"%s: More than one matching Device section for "
|
||||
"instances\n\t(BusID: %s) found: %s\n",
|
||||
driverName, devList[j]->busID,
|
||||
devList[j]->identifier);
|
||||
else
|
||||
devBus = devList[j];
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* if device section without BusID is found
|
||||
* only assign to it to the primary device.
|
||||
*/
|
||||
if (xf86IsPrimaryPci(pPci)) {
|
||||
xf86Msg(X_PROBED, "Assigning device section with no busID"
|
||||
" to primary device\n");
|
||||
if (dev || devBus)
|
||||
xf86MsgVerb(X_WARNING, 0,
|
||||
"%s: More than one matching Device section "
|
||||
"found: %s\n", driverName, devList[j]->identifier);
|
||||
else
|
||||
dev = devList[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (devBus) dev = devBus; /* busID preferred */
|
||||
if (!dev) {
|
||||
if (xf86CheckPciSlot(pPci) && pciDeviceHasBars(pPci)) {
|
||||
xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
|
||||
"for instance (BusID PCI:%u@%u:%u:%u) found\n",
|
||||
driverName, pPci->domain, pPci->bus, pPci->dev,
|
||||
pPci->func);
|
||||
}
|
||||
} else {
|
||||
numClaimedInstances++;
|
||||
instances[i].claimed = TRUE;
|
||||
instances[i].dev = dev;
|
||||
}
|
||||
}
|
||||
DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
|
||||
/*
|
||||
* Now check that a chipset or chipID override in the device section
|
||||
* is valid. Chipset has precedence over chipID.
|
||||
* If chipset is not valid ignore BusSlot completely.
|
||||
*/
|
||||
for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
|
||||
MessageType from = X_PROBED;
|
||||
|
||||
if (!instances[i].claimed) {
|
||||
continue;
|
||||
}
|
||||
if (instances[i].dev->chipset) {
|
||||
for (c = chipsets; c->token >= 0; c++) {
|
||||
if (xf86NameCmp(c->name, instances[i].dev->chipset) == 0)
|
||||
break;
|
||||
}
|
||||
if (c->token == -1) {
|
||||
instances[i].claimed = FALSE;
|
||||
numClaimedInstances--;
|
||||
xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
|
||||
"section \"%s\" isn't valid for this driver\n",
|
||||
driverName, instances[i].dev->chipset,
|
||||
instances[i].dev->identifier);
|
||||
} else {
|
||||
instances[i].chip = c->token;
|
||||
|
||||
for (id = PCIchipsets; id->numChipset >= 0; id++) {
|
||||
if (id->numChipset == instances[i].chip)
|
||||
break;
|
||||
}
|
||||
if(id->numChipset >=0){
|
||||
xf86Msg(X_CONFIG,"Chipset override: %s\n",
|
||||
instances[i].dev->chipset);
|
||||
from = X_CONFIG;
|
||||
} else {
|
||||
instances[i].claimed = FALSE;
|
||||
numClaimedInstances--;
|
||||
xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
|
||||
"section \"%s\" isn't a valid PCI chipset\n",
|
||||
driverName, instances[i].dev->chipset,
|
||||
instances[i].dev->identifier);
|
||||
}
|
||||
}
|
||||
} else if (instances[i].dev->chipID > 0) {
|
||||
for (id = PCIchipsets; id->numChipset >= 0; id++) {
|
||||
if (id->PCIid == instances[i].dev->chipID)
|
||||
break;
|
||||
}
|
||||
if (id->numChipset == -1) {
|
||||
instances[i].claimed = FALSE;
|
||||
numClaimedInstances--;
|
||||
xf86MsgVerb(X_WARNING, 0, "%s: ChipID 0x%04X in Device "
|
||||
"section \"%s\" isn't valid for this driver\n",
|
||||
driverName, instances[i].dev->chipID,
|
||||
instances[i].dev->identifier);
|
||||
} else {
|
||||
instances[i].chip = id->numChipset;
|
||||
|
||||
xf86Msg( X_CONFIG,"ChipID override: 0x%04X\n",
|
||||
instances[i].dev->chipID);
|
||||
from = X_CONFIG;
|
||||
}
|
||||
} else if (!instances[i].foundHW) {
|
||||
/*
|
||||
* This means that there was no override and the PCI chipType
|
||||
* doesn't match one that is supported
|
||||
*/
|
||||
instances[i].claimed = FALSE;
|
||||
numClaimedInstances--;
|
||||
}
|
||||
if (instances[i].claimed == TRUE){
|
||||
for (c = chipsets; c->token >= 0; c++) {
|
||||
if (c->token == instances[i].chip)
|
||||
break;
|
||||
}
|
||||
xf86Msg(from,"Chipset %s found\n",
|
||||
c->name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Of the claimed instances, check that another driver hasn't already
|
||||
* claimed its slot.
|
||||
*/
|
||||
numFound = 0;
|
||||
for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
|
||||
|
||||
if (!instances[i].claimed)
|
||||
continue;
|
||||
pPci = instances[i].pci;
|
||||
|
||||
|
||||
/*
|
||||
* Allow the same entity to be used more than once for devices with
|
||||
* multiple screens per entity. This assumes implicitly that there
|
||||
* will be a screen == 0 instance.
|
||||
*
|
||||
* XXX Need to make sure that two different drivers don't claim
|
||||
* the same screen > 0 instance.
|
||||
*/
|
||||
if (instances[i].screen == 0 && !xf86CheckPciSlot( pPci ))
|
||||
continue;
|
||||
|
||||
DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
|
||||
driverName, pPci->bus, pPci->dev, pPci->func);
|
||||
|
||||
/* Allocate an entry in the lists to be returned */
|
||||
numFound++;
|
||||
retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
|
||||
retEntities[numFound - 1] = xf86ClaimPciSlot( pPci, drvp,
|
||||
instances[i].chip,
|
||||
instances[i].dev,
|
||||
instances[i].dev->active);
|
||||
if (retEntities[numFound - 1] == -1 && instances[i].screen > 0) {
|
||||
for (j = 0; j < xf86NumEntities; j++) {
|
||||
EntityPtr pEnt = xf86Entities[j];
|
||||
if (pEnt->bus.type != BUS_PCI)
|
||||
continue;
|
||||
if (pEnt->bus.id.pci == pPci) {
|
||||
retEntities[numFound - 1] = j;
|
||||
xf86AddDevToEntity(j, instances[i].dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(instances);
|
||||
if (numFound > 0) {
|
||||
*foundEntities = retEntities;
|
||||
}
|
||||
|
||||
return numFound;
|
||||
}
|
||||
|
||||
/*
|
||||
* xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
|
||||
*/
|
||||
|
@ -2349,28 +1931,6 @@ xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name,
|
|||
#define LoaderGetOS xf86GetOS
|
||||
#include "loader/os.c"
|
||||
|
||||
/* new RAC */
|
||||
/*
|
||||
* xf86ConfigPciEntityInactive() -- This function can be used
|
||||
* to configure an inactive entity as well as to reconfigure an
|
||||
* previously active entity inactive. If the entity has been
|
||||
* assigned to a screen before it will be removed. If p_chip is
|
||||
* non-NULL all static resources listed there will be registered.
|
||||
*/
|
||||
static void
|
||||
xf86ConfigPciEntityInactive(EntityInfoPtr pEnt, PciChipsets *p_chip,
|
||||
EntityProc init, EntityProc enter,
|
||||
EntityProc leave, pointer private)
|
||||
{
|
||||
ScrnInfoPtr pScrn;
|
||||
|
||||
if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
|
||||
xf86RemoveEntityFromScreen(pScrn,pEnt->index);
|
||||
|
||||
/* shared resources are only needed when entity is active: remove */
|
||||
xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
|
||||
EntityProc enter, EntityProc leave, pointer private)
|
||||
|
@ -2382,42 +1942,6 @@ xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
|
|||
xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
|
||||
}
|
||||
|
||||
ScrnInfoPtr
|
||||
xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
|
||||
PciChipsets *p_chip, void *dummy, EntityProc init,
|
||||
EntityProc enter, EntityProc leave, pointer private)
|
||||
{
|
||||
EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
|
||||
if (!pEnt) return pScrn;
|
||||
|
||||
if (!(pEnt->location.type == BUS_PCI)
|
||||
|| !xf86GetPciInfoForEntity(entityIndex)) {
|
||||
free(pEnt);
|
||||
return pScrn;
|
||||
}
|
||||
if (!pEnt->active) {
|
||||
xf86ConfigPciEntityInactive(pEnt, p_chip, init, enter,
|
||||
leave, private);
|
||||
free(pEnt);
|
||||
return pScrn;
|
||||
}
|
||||
|
||||
if (!pScrn)
|
||||
pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
|
||||
if (xf86IsEntitySharable(entityIndex)) {
|
||||
xf86SetEntityShared(entityIndex);
|
||||
}
|
||||
xf86AddEntityToScreen(pScrn,entityIndex);
|
||||
if (xf86IsEntityShared(entityIndex)) {
|
||||
return pScrn;
|
||||
}
|
||||
free(pEnt);
|
||||
|
||||
xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
|
||||
|
||||
return pScrn;
|
||||
}
|
||||
|
||||
ScrnInfoPtr
|
||||
xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
|
||||
EntityProc init, EntityProc enter, EntityProc leave,
|
||||
|
@ -2446,33 +1970,6 @@ xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
|
|||
return pScrn;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* OBSOLETE ! xf86ConfigActivePciEntity() is an obsolete function.
|
||||
* It is likely to be removed. Don't use!
|
||||
*/
|
||||
|
||||
Bool
|
||||
xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
|
||||
PciChipsets *p_chip, void *dummy, EntityProc init,
|
||||
EntityProc enter, EntityProc leave, pointer private)
|
||||
{
|
||||
EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
|
||||
if (!pEnt) return FALSE;
|
||||
|
||||
if (!pEnt->active || !(pEnt->location.type == BUS_PCI)) {
|
||||
free(pEnt);
|
||||
return FALSE;
|
||||
}
|
||||
xf86AddEntityToScreen(pScrn,entityIndex);
|
||||
|
||||
free(pEnt);
|
||||
if (!xf86SetEntityFuncs(entityIndex,init,enter,leave,private))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
xf86IsScreenPrimary(int scrnIndex)
|
||||
{
|
||||
|
|
|
@ -581,3 +581,497 @@ xf86PciIsolateDevice(char *argument)
|
|||
} else
|
||||
FatalError("Invalid isolated device specification\n");
|
||||
}
|
||||
|
||||
static Bool
|
||||
pciDeviceHasBars(struct pci_device *pci)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
if (pci->regions[i].size)
|
||||
return TRUE;
|
||||
|
||||
if (pci->rom_size)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct Inst {
|
||||
struct pci_device * pci;
|
||||
GDevPtr dev;
|
||||
Bool foundHW; /* PCIid in list of supported chipsets */
|
||||
Bool claimed; /* BusID matches with a device section */
|
||||
int chip;
|
||||
int screen;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Find set of unclaimed devices matching a given vendor ID.
|
||||
*
|
||||
* Used by drivers to find as yet unclaimed devices matching the specified
|
||||
* vendor ID.
|
||||
*
|
||||
* \param driverName Name of the driver. This is used to find Device
|
||||
* sections in the config file.
|
||||
* \param vendorID PCI vendor ID of associated devices. If zero, then
|
||||
* the true vendor ID must be encoded in the \c PCIid
|
||||
* fields of the \c PCIchipsets entries.
|
||||
* \param chipsets Symbol table used to associate chipset names with
|
||||
* PCI IDs.
|
||||
* \param devList List of Device sections parsed from the config file.
|
||||
* \param numDevs Number of entries in \c devList.
|
||||
* \param drvp Pointer the driver's control structure.
|
||||
* \param foundEntities Returned list of entity indicies associated with the
|
||||
* driver.
|
||||
*
|
||||
* \returns
|
||||
* The number of elements in returned in \c foundEntities on success or zero
|
||||
* on failure.
|
||||
*
|
||||
* \todo
|
||||
* This function does a bit more than short description says. Fill in some
|
||||
* more of the details of its operation.
|
||||
*
|
||||
* \todo
|
||||
* The \c driverName parameter is redundant. It is the same as
|
||||
* \c DriverRec::driverName. In a future version of this function, remove
|
||||
* that parameter.
|
||||
*/
|
||||
int
|
||||
xf86MatchPciInstances(const char *driverName, int vendorID,
|
||||
SymTabPtr chipsets, PciChipsets *PCIchipsets,
|
||||
GDevPtr *devList, int numDevs, DriverPtr drvp,
|
||||
int **foundEntities)
|
||||
{
|
||||
int i,j;
|
||||
struct pci_device * pPci;
|
||||
struct pci_device_iterator *iter;
|
||||
struct Inst *instances = NULL;
|
||||
int numClaimedInstances = 0;
|
||||
int allocatedInstances = 0;
|
||||
int numFound = 0;
|
||||
SymTabRec *c;
|
||||
PciChipsets *id;
|
||||
int *retEntities = NULL;
|
||||
|
||||
*foundEntities = NULL;
|
||||
|
||||
|
||||
/* Each PCI device will contribute at least one entry. Each device
|
||||
* section can contribute at most one entry. The sum of the two is
|
||||
* guaranteed to be larger than the maximum possible number of entries.
|
||||
* Do this calculation and memory allocation once now to eliminate the
|
||||
* need for realloc calls inside the loop.
|
||||
*/
|
||||
if (!(xf86DoConfigure && xf86DoConfigurePass1)) {
|
||||
unsigned max_entries = numDevs;
|
||||
|
||||
iter = pci_slot_match_iterator_create(NULL);
|
||||
while ((pPci = pci_device_next(iter)) != NULL) {
|
||||
max_entries++;
|
||||
}
|
||||
|
||||
pci_iterator_destroy(iter);
|
||||
instances = xnfalloc(max_entries * sizeof(struct Inst));
|
||||
}
|
||||
|
||||
iter = pci_slot_match_iterator_create(NULL);
|
||||
while ((pPci = pci_device_next(iter)) != NULL) {
|
||||
unsigned device_class = pPci->device_class;
|
||||
Bool foundVendor = FALSE;
|
||||
|
||||
|
||||
/* Convert the pre-PCI 2.0 device class for a VGA adapter to the
|
||||
* 2.0 version of the same class.
|
||||
*/
|
||||
if ( device_class == 0x00000101 ) {
|
||||
device_class = 0x00030000;
|
||||
}
|
||||
|
||||
|
||||
/* Find PCI devices that match the given vendor ID. The vendor ID is
|
||||
* either specified explicitly as a parameter to the function or
|
||||
* implicitly encoded in the high bits of id->PCIid.
|
||||
*
|
||||
* The first device with a matching vendor is recorded, even if the
|
||||
* device ID doesn't match. This is done because the Device section
|
||||
* in the xorg.conf file can over-ride the device ID. A matching PCI
|
||||
* ID might not be found now, but after the device ID over-ride is
|
||||
* applied there /might/ be a match.
|
||||
*/
|
||||
for (id = PCIchipsets; id->PCIid != -1; id++) {
|
||||
const unsigned vendor_id = ((id->PCIid & 0xFFFF0000) >> 16)
|
||||
| vendorID;
|
||||
const unsigned device_id = (id->PCIid & 0x0000FFFF);
|
||||
const unsigned match_class = 0x00030000 | id->PCIid;
|
||||
|
||||
if ((vendor_id == pPci->vendor_id)
|
||||
|| ((vendorID == PCI_VENDOR_GENERIC) && (match_class == device_class))) {
|
||||
if (!foundVendor && (instances != NULL)) {
|
||||
++allocatedInstances;
|
||||
instances[allocatedInstances - 1].pci = pPci;
|
||||
instances[allocatedInstances - 1].dev = NULL;
|
||||
instances[allocatedInstances - 1].claimed = FALSE;
|
||||
instances[allocatedInstances - 1].foundHW = FALSE;
|
||||
instances[allocatedInstances - 1].screen = 0;
|
||||
}
|
||||
|
||||
foundVendor = TRUE;
|
||||
|
||||
if ( (device_id == pPci->device_id)
|
||||
|| ((vendorID == PCI_VENDOR_GENERIC)
|
||||
&& (match_class == device_class)) ) {
|
||||
if ( instances != NULL ) {
|
||||
instances[allocatedInstances - 1].foundHW = TRUE;
|
||||
instances[allocatedInstances - 1].chip = id->numChipset;
|
||||
}
|
||||
|
||||
|
||||
if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
|
||||
if (xf86CheckPciSlot(pPci)) {
|
||||
GDevPtr pGDev =
|
||||
xf86AddBusDeviceToConfigure(drvp->driverName,
|
||||
BUS_PCI, pPci, -1);
|
||||
if (pGDev) {
|
||||
/* After configure pass 1, chipID and chipRev
|
||||
* are treated as over-rides, so clobber them
|
||||
* here.
|
||||
*/
|
||||
pGDev->chipID = -1;
|
||||
pGDev->chipRev = -1;
|
||||
}
|
||||
|
||||
numFound++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
numFound++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pci_iterator_destroy(iter);
|
||||
|
||||
|
||||
/* In "probe only" or "configure" mode (signaled by instances being NULL),
|
||||
* our work is done. Return the number of detected devices.
|
||||
*/
|
||||
if ( instances == NULL ) {
|
||||
return numFound;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This may be debatable, but if no PCI devices with a matching vendor
|
||||
* type is found, return zero now. It is probably not desirable to
|
||||
* allow the config file to override this.
|
||||
*/
|
||||
if (allocatedInstances <= 0) {
|
||||
free(instances);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DebugF("%s instances found: %d\n", driverName, allocatedInstances);
|
||||
|
||||
/*
|
||||
* Check for devices that need duplicated instances. This is required
|
||||
* when there is more than one screen per entity.
|
||||
*
|
||||
* XXX This currently doesn't work for cases where the BusID isn't
|
||||
* specified explicitly in the config file.
|
||||
*/
|
||||
|
||||
for (j = 0; j < numDevs; j++) {
|
||||
if (devList[j]->screen > 0 && devList[j]->busID
|
||||
&& *devList[j]->busID) {
|
||||
for (i = 0; i < allocatedInstances; i++) {
|
||||
pPci = instances[i].pci;
|
||||
if (xf86ComparePciBusString(devList[j]->busID,
|
||||
PCI_MAKE_BUS( pPci->domain, pPci->bus ),
|
||||
pPci->dev,
|
||||
pPci->func)) {
|
||||
allocatedInstances++;
|
||||
instances[allocatedInstances - 1] = instances[i];
|
||||
instances[allocatedInstances - 1].screen = devList[j]->screen;
|
||||
numFound++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < allocatedInstances; i++) {
|
||||
GDevPtr dev = NULL;
|
||||
GDevPtr devBus = NULL;
|
||||
|
||||
pPci = instances[i].pci;
|
||||
for (j = 0; j < numDevs; j++) {
|
||||
if (devList[j]->busID && *devList[j]->busID) {
|
||||
if (xf86ComparePciBusString(devList[j]->busID,
|
||||
PCI_MAKE_BUS( pPci->domain, pPci->bus ),
|
||||
pPci->dev,
|
||||
pPci->func) &&
|
||||
devList[j]->screen == instances[i].screen) {
|
||||
|
||||
if (devBus)
|
||||
xf86MsgVerb(X_WARNING,0,
|
||||
"%s: More than one matching Device section for "
|
||||
"instances\n\t(BusID: %s) found: %s\n",
|
||||
driverName, devList[j]->busID,
|
||||
devList[j]->identifier);
|
||||
else
|
||||
devBus = devList[j];
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* if device section without BusID is found
|
||||
* only assign to it to the primary device.
|
||||
*/
|
||||
if (xf86IsPrimaryPci(pPci)) {
|
||||
xf86Msg(X_PROBED, "Assigning device section with no busID"
|
||||
" to primary device\n");
|
||||
if (dev || devBus)
|
||||
xf86MsgVerb(X_WARNING, 0,
|
||||
"%s: More than one matching Device section "
|
||||
"found: %s\n", driverName, devList[j]->identifier);
|
||||
else
|
||||
dev = devList[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (devBus) dev = devBus; /* busID preferred */
|
||||
if (!dev) {
|
||||
if (xf86CheckPciSlot(pPci) && pciDeviceHasBars(pPci)) {
|
||||
xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
|
||||
"for instance (BusID PCI:%u@%u:%u:%u) found\n",
|
||||
driverName, pPci->domain, pPci->bus, pPci->dev,
|
||||
pPci->func);
|
||||
}
|
||||
} else {
|
||||
numClaimedInstances++;
|
||||
instances[i].claimed = TRUE;
|
||||
instances[i].dev = dev;
|
||||
}
|
||||
}
|
||||
DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
|
||||
/*
|
||||
* Now check that a chipset or chipID override in the device section
|
||||
* is valid. Chipset has precedence over chipID.
|
||||
* If chipset is not valid ignore BusSlot completely.
|
||||
*/
|
||||
for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
|
||||
MessageType from = X_PROBED;
|
||||
|
||||
if (!instances[i].claimed) {
|
||||
continue;
|
||||
}
|
||||
if (instances[i].dev->chipset) {
|
||||
for (c = chipsets; c->token >= 0; c++) {
|
||||
if (xf86NameCmp(c->name, instances[i].dev->chipset) == 0)
|
||||
break;
|
||||
}
|
||||
if (c->token == -1) {
|
||||
instances[i].claimed = FALSE;
|
||||
numClaimedInstances--;
|
||||
xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
|
||||
"section \"%s\" isn't valid for this driver\n",
|
||||
driverName, instances[i].dev->chipset,
|
||||
instances[i].dev->identifier);
|
||||
} else {
|
||||
instances[i].chip = c->token;
|
||||
|
||||
for (id = PCIchipsets; id->numChipset >= 0; id++) {
|
||||
if (id->numChipset == instances[i].chip)
|
||||
break;
|
||||
}
|
||||
if(id->numChipset >=0){
|
||||
xf86Msg(X_CONFIG,"Chipset override: %s\n",
|
||||
instances[i].dev->chipset);
|
||||
from = X_CONFIG;
|
||||
} else {
|
||||
instances[i].claimed = FALSE;
|
||||
numClaimedInstances--;
|
||||
xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
|
||||
"section \"%s\" isn't a valid PCI chipset\n",
|
||||
driverName, instances[i].dev->chipset,
|
||||
instances[i].dev->identifier);
|
||||
}
|
||||
}
|
||||
} else if (instances[i].dev->chipID > 0) {
|
||||
for (id = PCIchipsets; id->numChipset >= 0; id++) {
|
||||
if (id->PCIid == instances[i].dev->chipID)
|
||||
break;
|
||||
}
|
||||
if (id->numChipset == -1) {
|
||||
instances[i].claimed = FALSE;
|
||||
numClaimedInstances--;
|
||||
xf86MsgVerb(X_WARNING, 0, "%s: ChipID 0x%04X in Device "
|
||||
"section \"%s\" isn't valid for this driver\n",
|
||||
driverName, instances[i].dev->chipID,
|
||||
instances[i].dev->identifier);
|
||||
} else {
|
||||
instances[i].chip = id->numChipset;
|
||||
|
||||
xf86Msg( X_CONFIG,"ChipID override: 0x%04X\n",
|
||||
instances[i].dev->chipID);
|
||||
from = X_CONFIG;
|
||||
}
|
||||
} else if (!instances[i].foundHW) {
|
||||
/*
|
||||
* This means that there was no override and the PCI chipType
|
||||
* doesn't match one that is supported
|
||||
*/
|
||||
instances[i].claimed = FALSE;
|
||||
numClaimedInstances--;
|
||||
}
|
||||
if (instances[i].claimed == TRUE){
|
||||
for (c = chipsets; c->token >= 0; c++) {
|
||||
if (c->token == instances[i].chip)
|
||||
break;
|
||||
}
|
||||
xf86Msg(from,"Chipset %s found\n",
|
||||
c->name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Of the claimed instances, check that another driver hasn't already
|
||||
* claimed its slot.
|
||||
*/
|
||||
numFound = 0;
|
||||
for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
|
||||
if (!instances[i].claimed)
|
||||
continue;
|
||||
pPci = instances[i].pci;
|
||||
|
||||
|
||||
/*
|
||||
* Allow the same entity to be used more than once for devices with
|
||||
* multiple screens per entity. This assumes implicitly that there
|
||||
* will be a screen == 0 instance.
|
||||
*
|
||||
* XXX Need to make sure that two different drivers don't claim
|
||||
* the same screen > 0 instance.
|
||||
*/
|
||||
if (instances[i].screen == 0 && !xf86CheckPciSlot( pPci ))
|
||||
continue;
|
||||
|
||||
DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
|
||||
driverName, pPci->bus, pPci->dev, pPci->func);
|
||||
|
||||
/* Allocate an entry in the lists to be returned */
|
||||
numFound++;
|
||||
retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
|
||||
retEntities[numFound - 1] = xf86ClaimPciSlot( pPci, drvp,
|
||||
instances[i].chip,
|
||||
instances[i].dev,
|
||||
instances[i].dev->active);
|
||||
if (retEntities[numFound - 1] == -1 && instances[i].screen > 0) {
|
||||
for (j = 0; j < xf86NumEntities; j++) {
|
||||
EntityPtr pEnt = xf86Entities[j];
|
||||
if (pEnt->bus.type != BUS_PCI)
|
||||
continue;
|
||||
if (pEnt->bus.id.pci == pPci) {
|
||||
retEntities[numFound - 1] = j;
|
||||
xf86AddDevToEntity(j, instances[i].dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(instances);
|
||||
if (numFound > 0) {
|
||||
*foundEntities = retEntities;
|
||||
}
|
||||
|
||||
return numFound;
|
||||
}
|
||||
|
||||
/*
|
||||
* xf86ConfigPciEntityInactive() -- This function can be used
|
||||
* to configure an inactive entity as well as to reconfigure an
|
||||
* previously active entity inactive. If the entity has been
|
||||
* assigned to a screen before it will be removed. If p_chip is
|
||||
* non-NULL all static resources listed there will be registered.
|
||||
*/
|
||||
static void
|
||||
xf86ConfigPciEntityInactive(EntityInfoPtr pEnt, PciChipsets *p_chip,
|
||||
EntityProc init, EntityProc enter,
|
||||
EntityProc leave, pointer private)
|
||||
{
|
||||
ScrnInfoPtr pScrn;
|
||||
|
||||
if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
|
||||
xf86RemoveEntityFromScreen(pScrn,pEnt->index);
|
||||
|
||||
/* shared resources are only needed when entity is active: remove */
|
||||
xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
|
||||
}
|
||||
|
||||
ScrnInfoPtr
|
||||
xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
|
||||
PciChipsets *p_chip, void *dummy, EntityProc init,
|
||||
EntityProc enter, EntityProc leave, pointer private)
|
||||
{
|
||||
EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
|
||||
if (!pEnt) return pScrn;
|
||||
|
||||
if (!(pEnt->location.type == BUS_PCI)
|
||||
|| !xf86GetPciInfoForEntity(entityIndex)) {
|
||||
free(pEnt);
|
||||
return pScrn;
|
||||
}
|
||||
if (!pEnt->active) {
|
||||
xf86ConfigPciEntityInactive(pEnt, p_chip, init, enter,
|
||||
leave, private);
|
||||
free(pEnt);
|
||||
return pScrn;
|
||||
}
|
||||
|
||||
if (!pScrn)
|
||||
pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
|
||||
if (xf86IsEntitySharable(entityIndex)) {
|
||||
xf86SetEntityShared(entityIndex);
|
||||
}
|
||||
xf86AddEntityToScreen(pScrn,entityIndex);
|
||||
if (xf86IsEntityShared(entityIndex)) {
|
||||
return pScrn;
|
||||
}
|
||||
free(pEnt);
|
||||
|
||||
xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
|
||||
|
||||
return pScrn;
|
||||
}
|
||||
|
||||
/*
|
||||
* OBSOLETE ! xf86ConfigActivePciEntity() is an obsolete function.
|
||||
* It is likely to be removed. Don't use!
|
||||
*/
|
||||
Bool
|
||||
xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
|
||||
PciChipsets *p_chip, void *dummy, EntityProc init,
|
||||
EntityProc enter, EntityProc leave, pointer private)
|
||||
{
|
||||
EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
|
||||
if (!pEnt) return FALSE;
|
||||
|
||||
if (!pEnt->active || !(pEnt->location.type == BUS_PCI)) {
|
||||
free(pEnt);
|
||||
return FALSE;
|
||||
}
|
||||
xf86AddEntityToScreen(pScrn,entityIndex);
|
||||
|
||||
free(pEnt);
|
||||
if (!xf86SetEntityFuncs(entityIndex,init,enter,leave,private))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user