diff options
-rw-r--r-- | hw/xfree86/common/xf86.h | 3 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Bus.c | 283 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Configure.c | 2 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Init.c | 313 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Priv.h | 3 | ||||
-rw-r--r-- | hw/xfree86/common/xf86pciBus.c | 160 | ||||
-rw-r--r-- | hw/xfree86/common/xf86pciBus.h | 3 |
7 files changed, 325 insertions, 442 deletions
diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index 4544a4f7e..68c3744f9 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -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); diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c index 39e531a59..8a73925b2 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -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; + + 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); + } + } -static Bool doFramebufferMode = FALSE; + /* 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) { @@ -386,72 +479,29 @@ xf86GetDevFromEntity(int entityIndex, int instance) } /* - * 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. */ 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(); -} - -/* - * 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); + int i; - 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); } diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c index 7d4c3410d..301332153 100644 --- a/hw/xfree86/common/xf86Configure.c +++ b/hw/xfree86/common/xf86Configure.c @@ -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) { diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 39d229b9a..db88f706d 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -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")) diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 0612c9c4e..d2073ae24 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -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 */ diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 3b30d720e..4656f1ae4 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -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"); +} diff --git a/hw/xfree86/common/xf86pciBus.h b/hw/xfree86/common/xf86pciBus.h index 3125e0db8..69c005aae 100644 --- a/hw/xfree86/common/xf86pciBus.h +++ b/hw/xfree86/common/xf86pciBus.h @@ -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 */ |