diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2007-08-28 07:25:21 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@moss-charon.epoch.ncsc.mil> | 2007-08-28 07:25:21 -0400 |
commit | 85547073265ae9bc4ae3af920a6d3214fd1ca0c5 (patch) | |
tree | 2e720a9d55fe3cf65e735c8ce66866fb8c749d18 /hw/xfree86/common/xf86Init.c | |
parent | 860a09cfb8afc0a293c7eb5e01762724eb86847a (diff) | |
parent | 7d54399cfdaa7f54e28828267a76b89c4e8e798f (diff) |
Merge branch 'master' into XACE-SELINUX
Conflicts:
include/miscstruct.h
mi/mibstore.c
mi/midispcur.c
os/Makefile.am
Diffstat (limited to 'hw/xfree86/common/xf86Init.c')
-rw-r--r-- | hw/xfree86/common/xf86Init.c | 260 |
1 files changed, 239 insertions, 21 deletions
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 27bc9ad0f..90f744c64 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -92,6 +92,9 @@ #include "dpmsproc.h" #endif +#include <pciaccess.h> +#include "Pci.h" +#include "xf86Bus.h" /* forward declarations */ @@ -101,15 +104,14 @@ static void xf86PrintDefaultModulePath(void); static void xf86PrintDefaultLibraryPath(void); static void xf86RunVtInit(void); +static Bool probe_devices_from_device_sections(DriverPtr drvp); +static Bool add_matching_devices_to_configure_list(DriverPtr drvp); +static Bool check_for_matching_devices(DriverPtr drvp); + #ifdef XF86PM void (*xf86OSPMClose)(void) = NULL; #endif -static char *baseModules[] = { - "pcidata", - NULL -}; - /* Common pixmap formats */ static PixmapFormatRec formats[MAXFORMATS] = { @@ -243,6 +245,233 @@ PostConfigInit(void) OsInitColors(); } + +#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; + +#ifdef DEBUG + ErrorF("%s: card at %d:%d:%d is claimed by a Device section\n", + drvp->driverName, pPci->bus, pPci->dev, pPci->func); +#endif + + /* 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->busType != 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; + } + } + + break; + } + } + } + + + 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 = + xf86AddDeviceToConfigure(drvp->driverName, 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 +check_for_matching_devices(DriverPtr drvp) +{ + const struct pci_id_match * const devices = drvp->supported_devices; + int j; + + + for (j = 0; ! END_OF_MATCHES(devices[j]); j++) { + struct pci_device_iterator *iter; + struct pci_device *dev; + + iter = pci_id_match_iterator_create(& devices[j]); + dev = pci_device_next(iter); + pci_iterator_destroy(iter); + + if (dev != NULL) { + return TRUE; + } + } + + + return 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 ( xf86DoProbe ) { + assert( detect_only ); + foundScreen = check_for_matching_devices( drv ); + } + else 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; +} + + void InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) { @@ -313,10 +542,6 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL); } - /* Force load mandatory base modules */ - if (!xf86LoadModules(baseModules, NULL)) - FatalError("Unable to load required base modules, Exiting...\n"); - xf86OpenConsole(); /* Do a general bus probe. This will be a PCI probe for x86 platforms */ @@ -433,16 +658,8 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) || NEED_IO_ENABLED(flags)) continue; } - - if (xf86DriverList[i]->Probe != NULL) - xf86DriverList[i]->Probe(xf86DriverList[i], PROBE_DEFAULT); - else { - xf86MsgVerb(X_WARNING, 0, - "Driver `%s' has no Probe function (ignoring)\n", - xf86DriverList[i]->driverName - ? xf86DriverList[i]->driverName : "noname"); - } - xf86SetPciVideo(NULL,NONE); + + xf86CallDriverProbe( xf86DriverList[i], FALSE ); } /* @@ -1501,8 +1718,9 @@ ddxProcessArgument(int argc, char **argv, int i) FatalError("Bus types other than PCI not yet isolable\n"); } if (sscanf(argv[i], "PCI:%d:%d:%d", &bus, &device, &func) == 3) { - xf86IsolateDevice.bus = bus; - xf86IsolateDevice.device = device; + xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus); + xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus); + xf86IsolateDevice.dev = device; xf86IsolateDevice.func = func; return 2; } else { |