Merge remote branch 'vignatti/bus-cleanup'

This commit is contained in:
Keith Packard 2010-05-19 22:27:53 -07:00
commit 103507af0c
7 changed files with 325 additions and 442 deletions

View File

@ -64,7 +64,7 @@ extern _X_EXPORT ScrnInfoPtr *xf86Screens; /* List of pointers to ScrnInfoRecs *
extern _X_EXPORT const unsigned char byte_reversed[256];
extern _X_EXPORT Bool pciSlotClaimed;
extern _X_EXPORT Bool fbSlotClaimed;
#if defined(__sparc__) || defined(__sparc)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
extern _X_EXPORT Bool sbusSlotClaimed;
#endif
extern _X_EXPORT confDRIRec xf86ConfigDRI;
@ -104,7 +104,6 @@ extern _X_EXPORT void xf86FormatPciBusNumber(int busnum, char *buffer);
extern _X_EXPORT int xf86GetFbInfoForScreen(int scrnIndex);
extern _X_EXPORT int xf86ClaimFbSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
extern _X_EXPORT int xf86ClaimNoSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
extern _X_EXPORT void xf86EnableAccess(ScrnInfoPtr pScrn);
extern _X_EXPORT Bool xf86IsPrimaryPci(struct pci_device * pPci);
/* new RAC */
extern _X_EXPORT Bool xf86DriverHasEntities(DriverPtr drvp);

View File

@ -58,9 +58,139 @@ static int xf86EntityPrivateCount = 0;
BusRec primaryBus = { BUS_NONE, { 0 } };
static Bool xf86ResAccessEnter = FALSE;
/**
* Call the driver's correct probe function.
*
* If the driver implements the \c DriverRec::PciProbe entry-point and an
* appropriate PCI device (with matching Device section in the xorg.conf file)
* is found, it is called. If \c DriverRec::PciProbe or no devices can be
* successfully probed with it (e.g., only non-PCI devices are available),
* the driver's \c DriverRec::Probe function is called.
*
* \param drv Driver to probe
*
* \return
* If a device can be successfully probed by the driver, \c TRUE is
* returned. Otherwise, \c FALSE is returned.
*/
Bool
xf86CallDriverProbe( DriverPtr drv, Bool detect_only )
{
Bool foundScreen = FALSE;
static Bool doFramebufferMode = 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;
}
/**
* @return TRUE if all buses are configured and set up correctly and FALSE
* otherwise.
*/
Bool
xf86BusConfig(void)
{
screenLayoutPtr layout;
int i, j;
/* Enable full I/O access */
if (xorgHWAccess)
xorgHWAccess = xf86EnableIO();
/* Locate bus slot that had register IO enabled at server startup */
if (xorgHWAccess)
xf86FindPrimaryDevice();
/*
* Now call each of the Probe functions. Each successful probe will
* result in an extra entry added to the xf86Screens[] list for each
* instance of the hardware found.
*/
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 nothing was detected, return now */
if (xf86NumScreens == 0) {
xf86Msg(X_ERROR, "No devices detected.\n");
return FALSE;
}
xf86VGAarbiterInit();
/*
* Match up the screens found by the probes against those specified
* in the config file. Remove the ones that won't be used. Sort
* them in the order specified.
*
* What is the best way to do this?
*
* For now, go through the screens allocated by the probes, and
* look for screen config entry which refers to the same device
* section as picked out by the probe.
*
*/
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) {
/* A match has been found */
xf86Screens[i]->confScreen = layout->screen;
found = TRUE;
break;
}
}
if (found) break;
}
if (layout->screen == NULL) {
/* No match found */
xf86Msg(X_ERROR,
"Screen %d deleted because of no matching config section.\n", i);
xf86DeleteScreen(i--, 0);
}
}
/* If no screens left, return now. */
if (xf86NumScreens == 0) {
xf86Msg(X_ERROR,
"Device(s) detected, but none match those in the config file.\n");
return FALSE;
}
return TRUE;
}
/*
* Call the bus probes relevant to the architecture.
@ -112,21 +242,6 @@ StringToBusType(const char* busID, const char **retID)
return ret;
}
/*
* Entity related code.
*/
void
xf86EntityInit(void)
{
int i;
for (i = 0; i < xf86NumEntities; i++)
if (xf86Entities[i]->entityInit) {
xf86Entities[i]->entityInit(i,xf86Entities[i]->private);
}
}
int
xf86AllocateEntity(void)
{
@ -139,28 +254,6 @@ xf86AllocateEntity(void)
return (xf86NumEntities - 1);
}
static void
EntityEnter(void)
{
int i;
for (i = 0; i < xf86NumEntities; i++)
if (xf86Entities[i]->entityEnter) {
xf86Entities[i]->entityEnter(i,xf86Entities[i]->private);
}
}
static void
EntityLeave(void)
{
int i;
for (i = 0; i < xf86NumEntities; i++)
if (xf86Entities[i]->entityLeave) {
xf86Entities[i]->entityLeave(i,xf86Entities[i]->private);
}
}
Bool
xf86IsEntityPrimary(int entityIndex)
{
@ -385,16 +478,6 @@ xf86GetDevFromEntity(int entityIndex, int instance)
return xf86Entities[entityIndex]->devices[i];
}
/*
* xf86AccessInit() - set up everything needed for access control
* called only once on first server generation.
*/
void
xf86AccessInit(void)
{
xf86ResAccessEnter = TRUE;
}
/*
* xf86AccessEnter() -- gets called to save the text mode VGA IO
* resources when reentering the server after a VT switch.
@ -402,56 +485,23 @@ xf86AccessInit(void)
void
xf86AccessEnter(void)
{
if (xf86ResAccessEnter)
return;
int i;
for (i = 0; i < xf86NumEntities; i++)
if (xf86Entities[i]->entityEnter)
xf86Entities[i]->entityEnter(i,xf86Entities[i]->private);
/*
* on enter we simply disable routing of special resources
* to any bus and let the RAC code to "open" the right bridges.
*/
EntityEnter();
xf86EnterServerState(SETUP);
xf86ResAccessEnter = TRUE;
}
/*
* xf86AccessLeave() -- prepares access for and calls the
* entityLeave() functions.
* xf86AccessLeaveState() --- gets called to restore the
* access to the VGA IO resources when switching VT or on
* server exit.
* This was split to call xf86AccessLeaveState() from
* ddxGiveUp().
*/
void
xf86AccessLeave(void)
{
if (!xf86ResAccessEnter)
return;
EntityLeave();
}
int i;
/*
* xf86EnableAccess() -- enable access to controlled resources.
* To reduce latency when switching access the ScrnInfoRec has
* a linked list of the EntityAccPtr of all screen entities.
*/
/*
* switching access needs to be done in te following oder:
* disable
* 1. disable old entity
* 2. reroute bus
* 3. enable new entity
* Otherwise resources needed for access control might be shadowed
* by other resources!
*/
void
xf86EnableAccess(ScrnInfoPtr pScrn)
{
DebugF("Enable access %i\n",pScrn->scrnIndex);
return;
for (i = 0; i < xf86NumEntities; i++)
if (xf86Entities[i]->entityLeave)
xf86Entities[i]->entityLeave(i,xf86Entities[i]->private);
}
/*
@ -460,12 +510,17 @@ xf86EnableAccess(ScrnInfoPtr pScrn)
typedef enum { TRI_UNSET, TRI_TRUE, TRI_FALSE } TriState;
static void
SetSIGIOForState(xf86State state)
void
xf86EnterServerState(xf86State state)
{
static int sigio_state;
static TriState sigio_blocked = TRI_UNSET;
/*
* This is a good place to block SIGIO during SETUP state. SIGIO should be
* blocked in SETUP state otherwise (u)sleep() might get interrupted
* early. We take care not to call xf86BlockSIGIO() twice.
*/
if ((state == SETUP) && (sigio_blocked != TRI_TRUE)) {
sigio_state = xf86BlockSIGIO();
sigio_blocked = TRI_TRUE;
@ -475,24 +530,6 @@ SetSIGIOForState(xf86State state)
}
}
void
xf86EnterServerState(xf86State state)
{
/*
* This is a good place to block SIGIO during SETUP state.
* SIGIO should be blocked in SETUP state otherwise (u)sleep()
* might get interrupted early.
* We take care not to call xf86BlockSIGIO() twice.
*/
SetSIGIOForState(state);
if (state == SETUP)
DebugF("Entering SETUP state\n");
else
DebugF("Entering OPERATING state\n");
return;
}
/*
* xf86PostProbe() -- Allocate all non conflicting resources
* This function gets called by xf86Init().
@ -500,35 +537,25 @@ xf86EnterServerState(xf86State state)
void
xf86PostProbe(void)
{
if (fbSlotClaimed) {
if (pciSlotClaimed
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");
return;
} else {
xf86Msg(X_INFO,"Running in FRAMEBUFFER Mode\n");
doFramebufferMode = TRUE;
return;
}
}
for (i = 0; i < xf86NumEntities; i++)
if (xf86Entities[i]->entityInit)
xf86Entities[i]->entityInit(i,xf86Entities[i]->private);
}
void
xf86PostScreenInit(void)
{
if (doFramebufferMode) {
SetSIGIOForState(OPERATING);
return;
}
xf86VGAarbiterWrapFunctions();
DebugF("PostScreenInit generation: %i\n",serverGeneration);
xf86EnterServerState(OPERATING);
}

View File

@ -821,7 +821,6 @@ DoConfigure(void)
}
xf86PostProbe();
xf86EntityInit();
for (j = 0; j < xf86NumScreens; j++) {
xf86Screens[j]->scrnIndex = j;
@ -837,7 +836,6 @@ DoConfigure(void)
ConfiguredMonitor = NULL;
xf86EnableAccess(xf86Screens[dev2screen[j]]);
if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]],
PROBE_DETECT) &&
ConfiguredMonitor) {

View File

@ -76,6 +76,7 @@
#include "xf86InPriv.h"
#include "picturestr.h"
#include "xf86Bus.h"
#include "xf86VGAarbiter.h"
#include "globals.h"
@ -83,16 +84,8 @@
#include <X11/extensions/dpmsconst.h>
#include "dpmsproc.h"
#endif
#include <pciaccess.h>
#include "Pci.h"
#include "xf86Bus.h"
#include <hotplug.h>
/* forward declarations */
static Bool probe_devices_from_device_sections(DriverPtr drvp);
static Bool add_matching_devices_to_configure_list(DriverPtr drvp);
#ifdef XF86PM
void (*xf86OSPMClose)(void) = NULL;
@ -335,201 +328,6 @@ InstallSignalHandlers(void)
}
}
#define END_OF_MATCHES(m) \
(((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
Bool
probe_devices_from_device_sections(DriverPtr drvp)
{
int i, j;
struct pci_device * pPci;
Bool foundScreen = FALSE;
const struct pci_id_match * const devices = drvp->supported_devices;
GDevPtr *devList;
const unsigned numDevs = xf86MatchDevice(drvp->driverName, & devList);
for ( i = 0 ; i < numDevs ; i++ ) {
struct pci_device_iterator *iter;
unsigned device_id;
/* Find the pciVideoRec associated with this device section.
*/
iter = pci_id_match_iterator_create(NULL);
while ((pPci = pci_device_next(iter)) != NULL) {
if (devList[i]->busID && *devList[i]->busID) {
if (xf86ComparePciBusString(devList[i]->busID,
((pPci->domain << 8)
| pPci->bus),
pPci->dev,
pPci->func)) {
break;
}
}
else if (xf86IsPrimaryPci(pPci)) {
break;
}
}
pci_iterator_destroy(iter);
if (pPci == NULL) {
continue;
}
device_id = (devList[i]->chipID > 0)
? devList[i]->chipID : pPci->device_id;
/* Once the pciVideoRec is found, determine if the device is supported
* by the driver. If it is, probe it!
*/
for ( j = 0 ; ! END_OF_MATCHES( devices[j] ) ; j++ ) {
if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
&& PCI_ID_COMPARE( devices[j].device_id, device_id )
&& ((devices[j].device_class_mask & pPci->device_class)
== devices[j].device_class) ) {
int entry;
/* 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.
*
* FIXME Need to make sure that two different drivers don't
* FIXME claim the same screen > 0 instance.
*/
if ( (devList[i]->screen == 0) && !xf86CheckPciSlot( pPci ) )
continue;
DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
drvp->driverName, pPci->bus, pPci->dev, pPci->func);
/* Allocate an entry in the lists to be returned */
entry = xf86ClaimPciSlot(pPci, drvp, device_id,
devList[i], devList[i]->active);
if ((entry == -1) && (devList[i]->screen > 0)) {
unsigned k;
for ( k = 0; k < xf86NumEntities; k++ ) {
EntityPtr pEnt = xf86Entities[k];
if (pEnt->bus.type != BUS_PCI)
continue;
if (pEnt->bus.id.pci == pPci) {
entry = k;
xf86AddDevToEntity(k, devList[i]);
break;
}
}
}
if (entry != -1) {
if ((*drvp->PciProbe)(drvp, entry, pPci,
devices[j].match_data)) {
foundScreen = TRUE;
} else
xf86UnclaimPciSlot(pPci);
}
break;
}
}
}
free(devList);
return foundScreen;
}
Bool
add_matching_devices_to_configure_list(DriverPtr drvp)
{
const struct pci_id_match * const devices = drvp->supported_devices;
int j;
struct pci_device *pPci;
struct pci_device_iterator *iter;
int numFound = 0;
iter = pci_id_match_iterator_create(NULL);
while ((pPci = pci_device_next(iter)) != NULL) {
/* Determine if this device is supported by the driver. If it is,
* add it to the list of devices to configure.
*/
for (j = 0 ; ! END_OF_MATCHES(devices[j]) ; j++) {
if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
&& PCI_ID_COMPARE( devices[j].device_id, pPci->device_id )
&& ((devices[j].device_class_mask & pPci->device_class)
== devices[j].device_class) ) {
if (xf86CheckPciSlot(pPci)) {
GDevPtr pGDev = xf86AddBusDeviceToConfigure(
drvp->driverName, BUS_PCI, pPci, -1);
if (pGDev != NULL) {
/* After configure pass 1, chipID and chipRev are
* treated as over-rides, so clobber them here.
*/
pGDev->chipID = -1;
pGDev->chipRev = -1;
}
numFound++;
}
break;
}
}
}
pci_iterator_destroy(iter);
return (numFound != 0);
}
/**
* Call the driver's correct probe function.
*
* If the driver implements the \c DriverRec::PciProbe entry-point and an
* appropriate PCI device (with matching Device section in the xorg.conf file)
* is found, it is called. If \c DriverRec::PciProbe or no devices can be
* successfully probed with it (e.g., only non-PCI devices are available),
* the driver's \c DriverRec::Probe function is called.
*
* \param drv Driver to probe
*
* \return
* If a device can be successfully probed by the driver, \c TRUE is
* returned. Otherwise, \c FALSE is returned.
*/
Bool
xf86CallDriverProbe( DriverPtr drv, Bool detect_only )
{
Bool foundScreen = FALSE;
if ( drv->PciProbe != NULL ) {
if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
assert( detect_only );
foundScreen = add_matching_devices_to_configure_list( drv );
}
else {
assert( ! detect_only );
foundScreen = probe_devices_from_device_sections( 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;
}
/*
* InitOutput --
* Initialize screenInfo for all actually accessible framebuffers.
@ -542,7 +340,6 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
int i, j, k, scr_index;
char **modulelist;
pointer *optionlist;
screenLayoutPtr layout;
Pix24Flags screenpix24, pix24;
MessageType pix24From = X_DEFAULT;
Bool pix24Fail = FALSE;
@ -693,102 +490,10 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
else
xf86Info.dontVTSwitch = TRUE;
/* Enable full I/O access */
if (xorgHWAccess)
xorgHWAccess = xf86EnableIO();
/*
* Locate bus slot that had register IO enabled at server startup
*/
if (xorgHWAccess) {
xf86AccessInit();
xf86FindPrimaryDevice();
}
/*
* Now call each of the Probe functions. Each successful probe will
* result in an extra entry added to the xf86Screens[] list for each
* instance of the hardware found.
*/
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 nothing was detected, return now.
*/
if (xf86NumScreens == 0) {
xf86Msg(X_ERROR, "No devices detected.\n");
return;
}
xf86VGAarbiterInit();
/*
* Match up the screens found by the probes against those specified
* in the config file. Remove the ones that won't be used. Sort
* them in the order specified.
*/
/*
* What is the best way to do this?
*
* For now, go through the screens allocated by the probes, and
* look for screen config entry which refers to the same device
* section as picked out by the probe.
*
*/
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) {
/* A match has been found */
xf86Screens[i]->confScreen = layout->screen;
found = TRUE;
break;
}
}
if (found) break;
}
if (layout->screen == NULL) {
/* No match found */
xf86Msg(X_ERROR,
"Screen %d deleted because of no matching config section.\n", i);
xf86DeleteScreen(i--, 0);
}
}
/*
* If no screens left, return now.
*/
if (xf86NumScreens == 0) {
xf86Msg(X_ERROR,
"Device(s) detected, but none match those in the config file.\n");
return;
}
if (xf86BusConfig() == FALSE)
return;
xf86PostProbe();
xf86EntityInit();
/*
* Sort the drivers to match the requested ording. Using a slow
@ -1635,20 +1340,12 @@ ddxProcessArgument(int argc, char **argv, int i)
}
if (!strcmp(argv[i], "-isolateDevice"))
{
int bus, device, func;
CHECK_FOR_REQUIRED_ARGUMENT();
if (strncmp(argv[++i], "PCI:", 4)) {
FatalError("Bus types other than PCI not yet isolable\n");
}
if (sscanf(argv[i], "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
xf86IsolateDevice.dev = device;
xf86IsolateDevice.func = func;
return 2;
} else {
FatalError("Invalid isolated device specification\n");
}
xf86PciIsolateDevice(argv[i]);
return 2;
}
/* Notice cmdline xkbdir, but pass to dix as well */
if (!strcmp(argv[i], "-xkbdir"))

View File

@ -111,11 +111,10 @@ extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
/* xf86Bus.c */
extern _X_EXPORT Bool xf86BusConfig(void);
extern _X_EXPORT void xf86BusProbe(void);
extern _X_EXPORT void xf86AccessInit(void);
extern _X_EXPORT void xf86AccessEnter(void);
extern _X_EXPORT void xf86AccessLeave(void);
extern _X_EXPORT void xf86EntityInit(void);
extern _X_EXPORT void xf86FindPrimaryDevice(void);
/* new RAC */

View File

@ -420,4 +420,164 @@ xf86CheckPciSlot(const struct pci_device *d)
return TRUE;
}
#define END_OF_MATCHES(m) \
(((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
Bool
xf86PciAddMatchingDev(DriverPtr drvp)
{
const struct pci_id_match * const devices = drvp->supported_devices;
int j;
struct pci_device *pPci;
struct pci_device_iterator *iter;
int numFound = 0;
iter = pci_id_match_iterator_create(NULL);
while ((pPci = pci_device_next(iter)) != NULL) {
/* Determine if this device is supported by the driver. If it is,
* add it to the list of devices to configure.
*/
for (j = 0 ; ! END_OF_MATCHES(devices[j]) ; j++) {
if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
&& PCI_ID_COMPARE( devices[j].device_id, pPci->device_id )
&& ((devices[j].device_class_mask & pPci->device_class)
== devices[j].device_class) ) {
if (xf86CheckPciSlot(pPci)) {
GDevPtr pGDev = xf86AddBusDeviceToConfigure(
drvp->driverName, BUS_PCI, pPci, -1);
if (pGDev != NULL) {
/* After configure pass 1, chipID and chipRev are
* treated as over-rides, so clobber them here.
*/
pGDev->chipID = -1;
pGDev->chipRev = -1;
}
numFound++;
}
break;
}
}
}
pci_iterator_destroy(iter);
return (numFound != 0);
}
Bool
xf86PciProbeDev(DriverPtr drvp)
{
int i, j;
struct pci_device * pPci;
Bool foundScreen = FALSE;
const struct pci_id_match * const devices = drvp->supported_devices;
GDevPtr *devList;
const unsigned numDevs = xf86MatchDevice(drvp->driverName, & devList);
for ( i = 0 ; i < numDevs ; i++ ) {
struct pci_device_iterator *iter;
unsigned device_id;
/* Find the pciVideoRec associated with this device section.
*/
iter = pci_id_match_iterator_create(NULL);
while ((pPci = pci_device_next(iter)) != NULL) {
if (devList[i]->busID && *devList[i]->busID) {
if (xf86ComparePciBusString(devList[i]->busID,
((pPci->domain << 8)
| pPci->bus),
pPci->dev,
pPci->func)) {
break;
}
}
else if (xf86IsPrimaryPci(pPci)) {
break;
}
}
pci_iterator_destroy(iter);
if (pPci == NULL) {
continue;
}
device_id = (devList[i]->chipID > 0)
? devList[i]->chipID : pPci->device_id;
/* Once the pciVideoRec is found, determine if the device is supported
* by the driver. If it is, probe it!
*/
for ( j = 0 ; ! END_OF_MATCHES( devices[j] ) ; j++ ) {
if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
&& PCI_ID_COMPARE( devices[j].device_id, device_id )
&& ((devices[j].device_class_mask & pPci->device_class)
== devices[j].device_class) ) {
int entry;
/* 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.
*
* FIXME Need to make sure that two different drivers don't
* FIXME claim the same screen > 0 instance.
*/
if ((devList[i]->screen == 0) && !xf86CheckPciSlot(pPci))
continue;
DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
drvp->driverName, pPci->bus, pPci->dev, pPci->func);
/* Allocate an entry in the lists to be returned */
entry = xf86ClaimPciSlot(pPci, drvp, device_id,
devList[i], devList[i]->active);
if ((entry == -1) && (devList[i]->screen > 0)) {
unsigned k;
for (k = 0; k < xf86NumEntities; k++ ) {
EntityPtr pEnt = xf86Entities[k];
if (pEnt->bus.type != BUS_PCI)
continue;
if (pEnt->bus.id.pci == pPci) {
entry = k;
xf86AddDevToEntity(k, devList[i]);
break;
}
}
}
if (entry != -1) {
if ((*drvp->PciProbe)(drvp, entry, pPci,
devices[j].match_data)) {
foundScreen = TRUE;
} else
xf86UnclaimPciSlot(pPci);
}
break;
}
}
}
free(devList);
return foundScreen;
}
void
xf86PciIsolateDevice(char *argument)
{
int bus, device, func;
if (sscanf(argument, "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
xf86IsolateDevice.dev = device;
xf86IsolateDevice.func = func;
} else
FatalError("Invalid isolated device specification\n");
}

View File

@ -34,5 +34,8 @@
#define _XF86_PCI_BUS_H
void xf86PciProbe(void);
Bool xf86PciAddMatchingDev(DriverPtr drvp);
Bool xf86PciProbeDev(DriverPtr drvp);
void xf86PciIsolateDevice(char *argument);
#endif /* _XF86_PCI_BUS_H */