diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index 68c3744f9..d8629a84d 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -41,8 +41,6 @@ #include #endif -#include - #include "xf86str.h" #include "xf86Opt.h" #include @@ -62,7 +60,6 @@ extern _X_EXPORT DevPrivateKey xf86CreateRootWindowKey; extern _X_EXPORT DevPrivateKey xf86PixmapKey; 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)) && !defined(__OpenBSD__) extern _X_EXPORT Bool sbusSlotClaimed; @@ -91,21 +88,39 @@ extern _X_EXPORT Bool VTSwitchEnabled; /* kbd driver */ /* Function Prototypes */ #ifndef _NO_XF86_PROTOTYPES +/* PCI related */ +#include +extern _X_EXPORT Bool pciSlotClaimed; + +extern _X_EXPORT Bool xf86CheckPciSlot(const struct pci_device *); +extern _X_EXPORT int xf86ClaimPciSlot(struct pci_device *, DriverPtr drvp, + int chipset, GDevPtr dev, Bool active); +extern _X_EXPORT void xf86UnclaimPciSlot(struct pci_device *); +extern _X_EXPORT Bool xf86ParsePciBusString(const char *busID, int *bus, + int *device, int *func); +extern _X_EXPORT Bool xf86ComparePciBusString(const char *busID, int bus, + int device, int func); +extern _X_EXPORT void xf86FormatPciBusNumber(int busnum, char *buffer); +extern _X_EXPORT Bool xf86IsPrimaryPci(struct pci_device * pPci); +extern _X_EXPORT Bool xf86CheckPciMemBase(struct pci_device * pPci, + memType base); +extern _X_EXPORT struct pci_device * xf86GetPciInfoForEntity(int entityIndex); +extern _X_EXPORT int xf86MatchPciInstances(const char *driverName, + int vendorID, SymTabPtr chipsets, PciChipsets *PCIchipsets, + GDevPtr *devList, int numDevs, DriverPtr drvp, int **foundEntities); +extern _X_EXPORT ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn, + int scrnFlag, int entityIndex,PciChipsets *p_chip, void *dummy, + EntityProc init, EntityProc enter, EntityProc leave, pointer private); +/* Obsolete! don't use */ +extern _X_EXPORT Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, + int entityIndex,PciChipsets *p_chip, void *dummy, EntityProc init, + EntityProc enter, EntityProc leave, pointer private); + /* xf86Bus.c */ -extern _X_EXPORT Bool xf86CheckPciSlot( const struct pci_device * ); -extern _X_EXPORT int xf86ClaimPciSlot( struct pci_device *, DriverPtr drvp, - int chipset, GDevPtr dev, Bool active); -extern _X_EXPORT void xf86UnclaimPciSlot(struct pci_device *); -extern _X_EXPORT Bool xf86ParsePciBusString(const char *busID, int *bus, int *device, - int *func); -extern _X_EXPORT Bool xf86ComparePciBusString(const char *busID, int bus, int device, int func); -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 Bool xf86IsPrimaryPci(struct pci_device * pPci); -/* new RAC */ extern _X_EXPORT Bool xf86DriverHasEntities(DriverPtr drvp); extern _X_EXPORT void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex); extern _X_EXPORT void xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex, @@ -114,10 +129,8 @@ extern _X_EXPORT int xf86GetNumEntityInstances(int entityIndex); extern _X_EXPORT GDevPtr xf86GetDevFromEntity(int entityIndex, int instance); extern _X_EXPORT void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex); extern _X_EXPORT EntityInfoPtr xf86GetEntityInfo(int entityIndex); -extern _X_EXPORT struct pci_device * xf86GetPciInfoForEntity(int entityIndex); extern _X_EXPORT Bool xf86SetEntityFuncs(int entityIndex, EntityProc init, EntityProc enter, EntityProc leave, pointer); -extern _X_EXPORT Bool xf86CheckPciMemBase(struct pci_device * pPci, memType base); extern _X_EXPORT Bool xf86IsEntityPrimary(int entityIndex); extern _X_EXPORT void xf86EnterServerState(xf86State state); extern _X_EXPORT ScrnInfoPtr xf86FindScreenForEntity(int entityIndex); @@ -223,10 +236,6 @@ extern _X_EXPORT void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from); extern _X_EXPORT void xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips); extern _X_EXPORT int xf86MatchDevice(const char *drivername, GDevPtr **driversectlist); -extern _X_EXPORT int xf86MatchPciInstances(const char *driverName, int vendorID, - SymTabPtr chipsets, PciChipsets *PCIchipsets, - GDevPtr *devList, int numDevs, DriverPtr drvp, - int **foundEntities); extern _X_EXPORT void xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int), void (*ProtectRegs)(ScrnInfoPtr, Bool), @@ -265,23 +274,11 @@ extern _X_EXPORT void xf86SetSilkenMouse(ScreenPtr pScreen); extern _X_EXPORT pointer xf86FindXvOptions(int scrnIndex, int adapt_index, char *port_name, char **adaptor_name, pointer *adaptor_options); extern _X_EXPORT void xf86GetOS(const char **name, int *major, int *minor, int *teeny); -extern _X_EXPORT ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, - int entityIndex,PciChipsets *p_chip, - void *dummy, EntityProc init, - EntityProc enter, EntityProc leave, - pointer private); extern _X_EXPORT ScrnInfoPtr xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex, EntityProc init, EntityProc enter, EntityProc leave, pointer private); -/* Obsolete! don't use */ -extern _X_EXPORT Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, - int entityIndex,PciChipsets *p_chip, - void *dummy, EntityProc init, - EntityProc enter, EntityProc leave, - pointer private); - extern _X_EXPORT Bool xf86IsScreenPrimary(int scrnIndex); extern _X_EXPORT int xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type, int format, unsigned long len, diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index 896f6950c..8947a4f06 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -39,10 +39,10 @@ #include "xf86Config.h" #include "xf86Priv.h" #include "xf86_OSlib.h" +#include "xf86pciBus.h" #ifdef __sparc__ # include "xf86sbusBus.h" #endif -#include "dirent.h" #ifdef sun # include @@ -140,102 +140,6 @@ AppendToConfig(const char *s) AppendToList(s, &builtinConfig, &builtinLines); } -static int -videoPtrToDriverList(struct pci_device *dev, - char *returnList[], int returnListMax) -{ - int i; - /* Add more entries here if we ever return more than 4 drivers for - any device */ - char *driverList[5] = { NULL, NULL, NULL, NULL, NULL }; - - switch (dev->vendor_id) - { - /* AMD Geode LX */ - case 0x1022: - if (dev->device_id == 0x2081) - driverList[0] = "geode"; - break; - /* older Geode products acquired by AMD still carry an NSC vendor_id */ - case 0x100b: - if (dev->device_id == 0x0030) { - /* NSC Geode GX2 specifically */ - driverList[0] = "geode"; - /* GX2 support started its life in the NSC tree and was later - forked by AMD for GEODE so we keep it as a backup */ - driverList[1] = "nsc"; - } else - /* other NSC variant e.g. 0x0104 (SC1400), 0x0504 (SCx200) */ - driverList[0] = "nsc"; - break; - /* Cyrix Geode GX1 */ - case 0x1078: - if (dev->device_id == 0x0104) - driverList[0] = "cyrix"; - break; - case 0x1142: driverList[0] = "apm"; break; - case 0xedd8: driverList[0] = "ark"; break; - case 0x1a03: driverList[0] = "ast"; break; - case 0x1002: driverList[0] = "ati"; break; - case 0x102c: driverList[0] = "chips"; break; - case 0x1013: driverList[0] = "cirrus"; break; - case 0x3d3d: driverList[0] = "glint"; break; - case 0x105d: driverList[0] = "i128"; break; - case 0x8086: - if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800)) { - driverList[0] = "i740"; - } else if (dev->device_id == 0x8108) { - break; /* "hooray" for poulsbo */ - } else { - driverList[0] = "intel"; - } - break; - case 0x102b: driverList[0] = "mga"; break; - case 0x10c8: driverList[0] = "neomagic"; break; - case 0x10de: case 0x12d2: driverList[0] = "nv"; break; - case 0x1106: driverList[0] = "openchrome"; break; - case 0x1b36: driverList[0] = "qxl"; break; - case 0x1163: driverList[0] = "rendition"; break; - case 0x5333: - switch (dev->device_id) - { - case 0x88d0: case 0x88d1: case 0x88f0: case 0x8811: - case 0x8812: case 0x8814: case 0x8901: - driverList[0] = "s3"; break; - case 0x5631: case 0x883d: case 0x8a01: case 0x8a10: - case 0x8c01: case 0x8c03: case 0x8904: case 0x8a13: - driverList[0] = "s3virge"; break; - default: - driverList[0] = "savage"; break; - } - break; - case 0x1039: driverList[0] = "sis"; break; - case 0x126f: driverList[0] = "siliconmotion"; break; - case 0x121a: - if (dev->device_id < 0x0003) - driverList[0] = "voodoo"; - else - driverList[0] = "tdfx"; - break; - case 0x1011: driverList[0] = "tga"; break; - case 0x1023: driverList[0] = "trident"; break; - case 0x100c: driverList[0] = "tseng"; break; - case 0x80ee: driverList[0] = "vboxvideo"; break; - case 0x15ad: driverList[0] = "vmware"; break; - case 0x18ca: - if (dev->device_id == 0x47) - driverList[0] = "xgixp"; - else - driverList[0] = "xgi"; - break; - default: break; - } - for (i = 0; (i < returnListMax) && (driverList[i] != NULL); i++) { - returnList[i] = xnfstrdup(driverList[i]); - } - return i; /* Number of entries added */ -} - Bool xf86AutoConfig(void) { @@ -285,132 +189,9 @@ xf86AutoConfig(void) return (ret == CONFIG_OK); } -static int -xchomp(char *line) -{ - size_t len = 0; - - if (!line) { - return 1; - } - - len = strlen(line); - if (line[len - 1] == '\n' && len > 0) { - line[len - 1] = '\0'; - } - return 0; -} - -#ifdef __linux__ -/* This function is used to provide a workaround for binary drivers that - * don't export their PCI ID's properly. If distros don't end up using this - * feature it can and should be removed because the symbol-based resolution - * scheme should be the primary one */ -static void -matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip) -{ - DIR *idsdir; - FILE *fp; - struct dirent *direntry; - char *line = NULL; - size_t len; - ssize_t read; - char path_name[256], vendor_str[5], chip_str[5]; - uint16_t vendor, chip; - int i, j; - - idsdir = opendir(PCI_TXT_IDS_PATH); - if (!idsdir) - return; - - xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH); - direntry = readdir(idsdir); - /* Read the directory */ - while (direntry) { - if (direntry->d_name[0] == '.') { - direntry = readdir(idsdir); - continue; - } - len = strlen(direntry->d_name); - /* A tiny bit of sanity checking. We should probably do better */ - if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) { - /* We need the full path name to open the file */ - strncpy(path_name, PCI_TXT_IDS_PATH, 256); - strncat(path_name, "/", 1); - strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1)); - fp = fopen(path_name, "r"); - if (fp == NULL) { - xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name); - goto end; - } - /* Read the file */ -#ifdef __GLIBC__ - while ((read = getline(&line, &len, fp)) != -1) { -#else - while ((line = fgetln(fp, &len)) != (char *)NULL) { -#endif /* __GLIBC __ */ - xchomp(line); - if (isdigit(line[0])) { - strncpy(vendor_str, line, 4); - vendor_str[4] = '\0'; - vendor = (int)strtol(vendor_str, NULL, 16); - if ((strlen(&line[4])) == 0) { - chip_str[0] = '\0'; - chip = -1; - } else { - /* Handle trailing whitespace */ - if (isspace(line[4])) { - chip_str[0] = '\0'; - chip = -1; - } else { - /* Ok, it's a real ID */ - strncpy(chip_str, &line[4], 4); - chip_str[4] = '\0'; - chip = (int)strtol(chip_str, NULL, 16); - } - } - if (vendor == match_vendor && chip == match_chip ) { - i = 0; - while (matches[i]) { - i++; - } - matches[i] = (char*)malloc(sizeof(char) * strlen(direntry->d_name) - 3); - if (!matches[i]) { - xf86Msg(X_ERROR, "Could not allocate space for the module name. Exiting.\n"); - goto end; - } - /* hack off the .ids suffix. This should guard - * against other problems, but it will end up - * taking off anything after the first '.' */ - for (j = 0; j < (strlen(direntry->d_name) - 3) ; j++) { - if (direntry->d_name[j] == '.') { - matches[i][j] = '\0'; - break; - } else { - matches[i][j] = direntry->d_name[j]; - } - } - xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name); - } - } else { - /* TODO Handle driver overrides here */ - } - } - fclose(fp); - } - direntry = readdir(idsdir); - } - end: - free(line); - closedir(idsdir); -} -#endif /* __linux__ */ - static void listPossibleVideoDrivers(char *matches[], int nmatches) { - struct pci_device * info = NULL; - struct pci_device_iterator *iter; int i; for (i = 0 ; i < nmatches ; i++) { @@ -476,32 +257,7 @@ listPossibleVideoDrivers(char *matches[], int nmatches) } #endif - /* Find the primary device, and get some information about it. */ - iter = pci_slot_match_iterator_create(NULL); - while ((info = pci_device_next(iter)) != NULL) { - if (xf86IsPrimaryPci(info)) { - break; - } - } - - pci_iterator_destroy(iter); - - if (!info) { - ErrorF("Primary device is not PCI\n"); - } -#ifdef __linux__ - else { - matchDriverFromFiles(matches, info->vendor_id, info->device_id); - } -#endif /* __linux__ */ - - for (i = 0; (i < nmatches) && (matches[i]); i++) { - /* find end of matches list */ - } - - if ((info != NULL) && (i < nmatches)) { - i += videoPtrToDriverList(info, &(matches[i]), nmatches - i); - } + xf86PciMatchDriver(matches, nmatches); /* Fallback to platform default hardware */ if (i < (nmatches - 1)) { diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c index 8a73925b2..8276257c8 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -49,8 +49,6 @@ #include "xf86_OSproc.h" #include "xf86VGAarbiter.h" -#include "Pci.h" - /* Entity data */ EntityPtr *xf86Entities = NULL; /* Bus slots claimed by drivers */ int xf86NumEntities = 0; @@ -113,10 +111,6 @@ xf86BusConfig(void) 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 @@ -559,39 +553,6 @@ xf86PostScreenInit(void) xf86EnterServerState(OPERATING); } -/* - * xf86FindPrimaryDevice() - Find the display device which - * was active when the server was started. - */ -void -xf86FindPrimaryDevice(void) -{ - if (primaryBus.type != BUS_NONE) { - char *bus; - char loc[16]; - - switch (primaryBus.type) { - case BUS_PCI: - bus = "PCI"; - snprintf(loc, sizeof(loc), " %2.2x@%2.2x:%2.2x:%1.1x", - primaryBus.id.pci->bus, - primaryBus.id.pci->domain, - primaryBus.id.pci->dev, - primaryBus.id.pci->func); - break; - case BUS_SBUS: - bus = "SBUS"; - snprintf(loc, sizeof(loc), " %2.2x", primaryBus.id.sbus.fbNum); - break; - default: - bus = ""; - loc[0] = '\0'; - } - - xf86MsgVerb(X_INFO, 2, "Primary Device is: %s%s\n",bus,loc); - } -} - int xf86GetLastScrnFlag(int entityIndex) { diff --git a/hw/xfree86/common/xf86Bus.h b/hw/xfree86/common/xf86Bus.h index b22e2e772..e161c7f4c 100644 --- a/hw/xfree86/common/xf86Bus.h +++ b/hw/xfree86/common/xf86Bus.h @@ -54,7 +54,6 @@ typedef struct { Bool active; Bool inUse; BusRec bus; - pointer busAcc; int lastScrnFlag; DevUnion * entityPrivates; int numInstances; diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c index 301332153..2f93bb13b 100644 --- a/hw/xfree86/common/xf86Configure.c +++ b/hw/xfree86/common/xf86Configure.c @@ -681,8 +681,6 @@ DoConfigure(void) xorgHWAccess = FALSE; } - xf86FindPrimaryDevice(); - /* Create XF86Config file structure */ xf86config = calloc(1, sizeof(XF86ConfigRec)); diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c index 9ec594144..bde80eacd 100644 --- a/hw/xfree86/common/xf86Helper.c +++ b/hw/xfree86/common/xf86Helper.c @@ -38,9 +38,6 @@ #include #endif -#include -#include "Pci.h" - #include #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 */ @@ -1444,8 +1440,6 @@ xf86MatchDevice(const char *drivername, GDevPtr **sectlist) if (sectlist) *sectlist = NULL; - if (xf86DoConfigure && xf86DoConfigurePass1) return 1; - /* * This is a very important function that matches the device sections * as they show up in the config file with the drivers that the server @@ -1506,420 +1500,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 +1929,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 +1940,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 +1968,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) { diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index d2073ae24..b5e7a45e5 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -110,14 +110,10 @@ extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable; #ifndef _NO_XF86_PROTOTYPES /* xf86Bus.c */ - extern _X_EXPORT Bool xf86BusConfig(void); extern _X_EXPORT void xf86BusProbe(void); extern _X_EXPORT void xf86AccessEnter(void); extern _X_EXPORT void xf86AccessLeave(void); - -extern _X_EXPORT void xf86FindPrimaryDevice(void); -/* new RAC */ extern _X_EXPORT void xf86PostProbe(void); extern _X_EXPORT void xf86ClearEntityListForScreen(int scrnIndex); extern _X_EXPORT void xf86AddDevToEntity(int entityIndex, GDevPtr dev); diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 4656f1ae4..085be0143 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -41,6 +41,7 @@ #include "Pci.h" #include "xf86.h" #include "xf86Priv.h" +#include "dirent.h" /* DIR, FILE type definitions */ /* Bus-specific headers */ #include "xf86Bus.h" @@ -581,3 +582,748 @@ 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; +} + +static int +videoPtrToDriverList(struct pci_device *dev, + char *returnList[], int returnListMax) +{ + int i; + /* Add more entries here if we ever return more than 4 drivers for + any device */ + char *driverList[5] = { NULL, NULL, NULL, NULL, NULL }; + + switch (dev->vendor_id) + { + /* AMD Geode LX */ + case 0x1022: + if (dev->device_id == 0x2081) + driverList[0] = "geode"; + break; + /* older Geode products acquired by AMD still carry an NSC vendor_id */ + case 0x100b: + if (dev->device_id == 0x0030) { + /* NSC Geode GX2 specifically */ + driverList[0] = "geode"; + /* GX2 support started its life in the NSC tree and was later + forked by AMD for GEODE so we keep it as a backup */ + driverList[1] = "nsc"; + } else + /* other NSC variant e.g. 0x0104 (SC1400), 0x0504 (SCx200) */ + driverList[0] = "nsc"; + break; + /* Cyrix Geode GX1 */ + case 0x1078: + if (dev->device_id == 0x0104) + driverList[0] = "cyrix"; + break; + case 0x1142: driverList[0] = "apm"; break; + case 0xedd8: driverList[0] = "ark"; break; + case 0x1a03: driverList[0] = "ast"; break; + case 0x1002: driverList[0] = "ati"; break; + case 0x102c: driverList[0] = "chips"; break; + case 0x1013: driverList[0] = "cirrus"; break; + case 0x3d3d: driverList[0] = "glint"; break; + case 0x105d: driverList[0] = "i128"; break; + case 0x8086: + if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800)) { + driverList[0] = "i740"; + } else if (dev->device_id == 0x8108) { + break; /* "hooray" for poulsbo */ + } else { + driverList[0] = "intel"; + } + break; + case 0x102b: driverList[0] = "mga"; break; + case 0x10c8: driverList[0] = "neomagic"; break; + case 0x10de: case 0x12d2: driverList[0] = "nv"; break; + case 0x1106: driverList[0] = "openchrome"; break; + case 0x1b36: driverList[0] = "qxl"; break; + case 0x1163: driverList[0] = "rendition"; break; + case 0x5333: + switch (dev->device_id) + { + case 0x88d0: case 0x88d1: case 0x88f0: case 0x8811: + case 0x8812: case 0x8814: case 0x8901: + driverList[0] = "s3"; break; + case 0x5631: case 0x883d: case 0x8a01: case 0x8a10: + case 0x8c01: case 0x8c03: case 0x8904: case 0x8a13: + driverList[0] = "s3virge"; break; + default: + driverList[0] = "savage"; break; + } + break; + case 0x1039: driverList[0] = "sis"; break; + case 0x126f: driverList[0] = "siliconmotion"; break; + case 0x121a: + if (dev->device_id < 0x0003) + driverList[0] = "voodoo"; + else + driverList[0] = "tdfx"; + break; + case 0x1011: driverList[0] = "tga"; break; + case 0x1023: driverList[0] = "trident"; break; + case 0x100c: driverList[0] = "tseng"; break; + case 0x80ee: driverList[0] = "vboxvideo"; break; + case 0x15ad: driverList[0] = "vmware"; break; + case 0x18ca: + if (dev->device_id == 0x47) + driverList[0] = "xgixp"; + else + driverList[0] = "xgi"; + break; + default: break; + } + for (i = 0; (i < returnListMax) && (driverList[i] != NULL); i++) { + returnList[i] = xnfstrdup(driverList[i]); + } + return i; /* Number of entries added */ +} + +static int +xchomp(char *line) +{ + size_t len = 0; + + if (!line) { + return 1; + } + + len = strlen(line); + if (line[len - 1] == '\n' && len > 0) { + line[len - 1] = '\0'; + } + return 0; +} + +#ifdef __linux__ +/* This function is used to provide a workaround for binary drivers that + * don't export their PCI ID's properly. If distros don't end up using this + * feature it can and should be removed because the symbol-based resolution + * scheme should be the primary one */ +static void +matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip) +{ + DIR *idsdir; + FILE *fp; + struct dirent *direntry; + char *line = NULL; + size_t len; + ssize_t read; + char path_name[256], vendor_str[5], chip_str[5]; + uint16_t vendor, chip; + int i, j; + + idsdir = opendir(PCI_TXT_IDS_PATH); + if (!idsdir) + return; + + xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH); + direntry = readdir(idsdir); + /* Read the directory */ + while (direntry) { + if (direntry->d_name[0] == '.') { + direntry = readdir(idsdir); + continue; + } + len = strlen(direntry->d_name); + /* A tiny bit of sanity checking. We should probably do better */ + if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) { + /* We need the full path name to open the file */ + strncpy(path_name, PCI_TXT_IDS_PATH, 256); + strncat(path_name, "/", 1); + strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1)); + fp = fopen(path_name, "r"); + if (fp == NULL) { + xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name); + goto end; + } + /* Read the file */ +#ifdef __GLIBC__ + while ((read = getline(&line, &len, fp)) != -1) { +#else + while ((line = fgetln(fp, &len)) != (char *)NULL) { +#endif /* __GLIBC __ */ + xchomp(line); + if (isdigit(line[0])) { + strncpy(vendor_str, line, 4); + vendor_str[4] = '\0'; + vendor = (int)strtol(vendor_str, NULL, 16); + if ((strlen(&line[4])) == 0) { + chip_str[0] = '\0'; + chip = -1; + } else { + /* Handle trailing whitespace */ + if (isspace(line[4])) { + chip_str[0] = '\0'; + chip = -1; + } else { + /* Ok, it's a real ID */ + strncpy(chip_str, &line[4], 4); + chip_str[4] = '\0'; + chip = (int)strtol(chip_str, NULL, 16); + } + } + if (vendor == match_vendor && chip == match_chip ) { + i = 0; + while (matches[i]) { + i++; + } + matches[i] = (char*)malloc(sizeof(char) * strlen(direntry->d_name) - 3); + if (!matches[i]) { + xf86Msg(X_ERROR, "Could not allocate space for the module name. Exiting.\n"); + goto end; + } + /* hack off the .ids suffix. This should guard + * against other problems, but it will end up + * taking off anything after the first '.' */ + for (j = 0; j < (strlen(direntry->d_name) - 3) ; j++) { + if (direntry->d_name[j] == '.') { + matches[i][j] = '\0'; + break; + } else { + matches[i][j] = direntry->d_name[j]; + } + } + xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name); + } + } else { + /* TODO Handle driver overrides here */ + } + } + fclose(fp); + } + direntry = readdir(idsdir); + } + end: + free(line); + closedir(idsdir); +} +#endif /* __linux__ */ + +void +xf86PciMatchDriver(char* matches[], int nmatches) { + int i; + struct pci_device * info = NULL; + struct pci_device_iterator *iter; + + /* Find the primary device, and get some information about it. */ + iter = pci_slot_match_iterator_create(NULL); + while ((info = pci_device_next(iter)) != NULL) { + if (xf86IsPrimaryPci(info)) { + break; + } + } + + pci_iterator_destroy(iter); + + if (!info) { + ErrorF("Primary device is not PCI\n"); + } +#ifdef __linux__ + else { + matchDriverFromFiles(matches, info->vendor_id, info->device_id); + } +#endif /* __linux__ */ + + for (i = 0; (i < nmatches) && (matches[i]); i++) { + /* find end of matches list */ + } + + if ((info != NULL) && (i < nmatches)) { + i += videoPtrToDriverList(info, &(matches[i]), nmatches - i); + } +} diff --git a/hw/xfree86/common/xf86pciBus.h b/hw/xfree86/common/xf86pciBus.h index 69c005aae..f84a496df 100644 --- a/hw/xfree86/common/xf86pciBus.h +++ b/hw/xfree86/common/xf86pciBus.h @@ -37,5 +37,6 @@ void xf86PciProbe(void); Bool xf86PciAddMatchingDev(DriverPtr drvp); Bool xf86PciProbeDev(DriverPtr drvp); void xf86PciIsolateDevice(char *argument); +void xf86PciMatchDriver(char* matches[], int nmatches); #endif /* _XF86_PCI_BUS_H */ diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h index de1f1b60a..22f0261b4 100644 --- a/hw/xfree86/common/xf86str.h +++ b/hw/xfree86/common/xf86str.h @@ -338,7 +338,6 @@ typedef struct _DriverRec { /* Tolerate prior #include */ #if defined(linux) && defined(_INPUT_H) #undef BUS_NONE -#undef BUS_ISA #undef BUS_PCI #undef BUS_SBUS #undef BUS_last @@ -346,7 +345,6 @@ typedef struct _DriverRec { typedef enum { BUS_NONE, - BUS_ISA, BUS_PCI, BUS_SBUS, BUS_last /* Keep last */ diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c index b7fa25f71..a0a597d87 100644 --- a/hw/xfree86/os-support/bus/Pci.c +++ b/hw/xfree86/os-support/bus/Pci.c @@ -126,7 +126,6 @@ #include #include -#include #include "compiler.h" #include "xf86.h" #include "xf86Priv.h" diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h index b52a6cfae..e001c304f 100644 --- a/hw/xfree86/os-support/bus/Pci.h +++ b/hw/xfree86/os-support/bus/Pci.h @@ -107,8 +107,6 @@ #ifndef _PCI_H #define _PCI_H 1 -#include -#include #include "xf86Pci.h" #include "xf86PciInfo.h" @@ -121,9 +119,6 @@ #define PCI_DOM_MASK 0x0ffu #endif -#define DEVID(vendor, device) \ - ((CARD32)((PCI_##device << 16) | PCI_##vendor)) - #ifndef PCI_DOM_MASK # define PCI_DOM_MASK 0x0ffu #endif @@ -143,9 +138,6 @@ #define PCI_DEV_FROM_TAG(tag) (((tag) & 0x0000f800u) >> 11) #define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8) -#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00u) >> 8) -#define PCI_BDEV_FROM_TAG(tag) ((tag) & 0x00fff800u) - #define PCI_DOM_FROM_BUS(bus) (((bus) >> 8) & (PCI_DOM_MASK)) #define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu) #define PCI_TAG_NO_DOMAIN(tag) ((tag) & 0x00ffff00u) diff --git a/hw/xfree86/vbe/vbe.c b/hw/xfree86/vbe/vbe.c index 9f9b74355..3840bfeb4 100644 --- a/hw/xfree86/vbe/vbe.c +++ b/hw/xfree86/vbe/vbe.c @@ -17,7 +17,6 @@ #include "xf86.h" #include "vbe.h" -#include #include #define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x)