diff options
Diffstat (limited to 'hw/xfree86/common/xf86Init.c')
-rw-r--r-- | hw/xfree86/common/xf86Init.c | 276 |
1 files changed, 252 insertions, 24 deletions
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index bf7dac6da..bf577e6ad 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 */ @@ -347,6 +572,16 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) } /* Load all driver modules specified in the config file */ + /* If there aren't any specified in the config file, autoconfig them */ + /* FIXME: Does not handle multiple active screen sections, but I'm not + * sure if we really want to handle that case*/ + GDevPtr configured_device = xf86ConfigLayout.screens->screen->device; + if ((!configured_device) || (!configured_device->driver)) { + if (!autoConfigDevice(configured_device)) { + xf86Msg(X_ERROR, "Automatic driver configuration failed\n"); + return ; + } + } if ((modulelist = xf86DriverlistFromConfig())) { xf86LoadModules(modulelist, NULL); xfree(modulelist); @@ -433,16 +668,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 +1728,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 { @@ -1603,7 +1831,7 @@ xf86PrintBanner() "latest version in the X.Org Foundation git repository.\n" "See http://wiki.x.org/wiki/GitPage for git access instructions.\n"); #endif - ErrorF("\nX Window System Version %d.%d.%d", + ErrorF("\nX.Org X Server %d.%d.%d", XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH); @@ -1637,8 +1865,8 @@ xf86PrintBanner() #define XORG_DATE XF86_DATE #endif ErrorF("\nRelease Date: %s\n", XORG_DATE); - ErrorF("X Protocol Version %d, Revision %d, %s\n", - X_PROTOCOL, X_PROTOCOL_REVISION, XORG_RELEASE ); + ErrorF("X Protocol Version %d, Revision %d\n", + X_PROTOCOL, X_PROTOCOL_REVISION); ErrorF("Build Operating System: %s %s\n", OSNAME, OSVENDOR); #ifdef HAS_UTSNAME { |