xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xf86pciBus.c (46010B)


      1 /*
      2  * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20  * OTHER DEALINGS IN THE SOFTWARE.
     21  *
     22  * Except as contained in this notice, the name of the copyright holder(s)
     23  * and author(s) shall not be used in advertising or otherwise to promote
     24  * the sale, use or other dealings in this Software without prior written
     25  * authorization from the copyright holder(s) and author(s).
     26  */
     27 
     28 /*
     29  * This file contains the interfaces to the bus-specific code
     30  */
     31 #ifdef HAVE_XORG_CONFIG_H
     32 #include <xorg-config.h>
     33 #endif
     34 
     35 #include <ctype.h>
     36 #include <stdlib.h>
     37 #include <unistd.h>
     38 #include <X11/X.h>
     39 #include <pciaccess.h>
     40 #include "os.h"
     41 #include "Pci.h"
     42 #include "xf86.h"
     43 #include "xf86Priv.h"
     44 #include "dirent.h"             /* DIR, FILE type definitions */
     45 
     46 /* Bus-specific headers */
     47 #include "xf86Bus.h"
     48 
     49 #define XF86_OS_PRIVS
     50 #include "xf86_OSproc.h"
     51 
     52 #define PCI_VENDOR_GENERIC		0x00FF
     53 
     54 /* Bus-specific globals */
     55 int pciSlotClaimed = 0;
     56 
     57 #define PCIINFOCLASSES(c) \
     58     ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) \
     59       || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
     60       || ((((c) & 0x00ffff00) \
     61 	   == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) \
     62       || ((((c) & 0x00ffff00) \
     63 	   == ((PCI_CLASS_PROCESSOR << 16) | (PCI_SUBCLASS_PROCESSOR_COPROC << 8)))) )
     64 
     65 /*
     66  * PCI classes that have messages printed always.  The others are only
     67  * have a message printed when the vendor/dev IDs are recognised.
     68  */
     69 #define PCIALWAYSPRINTCLASSES(c) \
     70     ( (((c) & 0x00ffff00) \
     71        == ((PCI_CLASS_PREHISTORIC << 16) | (PCI_SUBCLASS_PREHISTORIC_VGA << 8))) \
     72       || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
     73       || ((((c) & 0x00ffff00) \
     74 	   == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) )
     75 
     76 #define IS_VGA(c) \
     77     (((c) & 0x00ffff00) \
     78 	 == ((PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8)))
     79 
     80 static struct pci_slot_match xf86IsolateDevice = {
     81     PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0
     82 };
     83 
     84 /*
     85  * xf86Bus.c interface
     86  */
     87 
     88 void
     89 xf86PciProbe(void)
     90 {
     91     int i = 0, k;
     92     int num = 0;
     93     struct pci_device *info;
     94     struct pci_device_iterator *iter;
     95     struct pci_device **xf86PciVideoInfo = NULL;
     96 
     97     if (!xf86scanpci()) {
     98         xf86PciVideoInfo = NULL;
     99         return;
    100     }
    101 
    102     iter = pci_slot_match_iterator_create(&xf86IsolateDevice);
    103     while ((info = pci_device_next(iter)) != NULL) {
    104         if (PCIINFOCLASSES(info->device_class)) {
    105             num++;
    106             xf86PciVideoInfo = xnfreallocarray(xf86PciVideoInfo,
    107                                                num + 1,
    108                                                sizeof(struct pci_device *));
    109             xf86PciVideoInfo[num] = NULL;
    110             xf86PciVideoInfo[num - 1] = info;
    111 
    112             pci_device_probe(info);
    113             if (primaryBus.type == BUS_NONE && pci_device_is_boot_vga(info)) {
    114                 primaryBus.type = BUS_PCI;
    115                 primaryBus.id.pci = info;
    116             }
    117             info->user_data = 0;
    118         }
    119     }
    120     free(iter);
    121 
    122     /* If we haven't found a primary device try a different heuristic */
    123     if (primaryBus.type == BUS_NONE && num) {
    124         for (i = 0; i < num; i++) {
    125             uint16_t command;
    126 
    127             info = xf86PciVideoInfo[i];
    128             pci_device_cfg_read_u16(info, &command, 4);
    129 
    130             if ((command & PCI_CMD_MEM_ENABLE)
    131                 && ((num == 1) || IS_VGA(info->device_class))) {
    132                 if (primaryBus.type == BUS_NONE) {
    133                     primaryBus.type = BUS_PCI;
    134                     primaryBus.id.pci = info;
    135                 }
    136                 else {
    137                     xf86Msg(X_NOTICE,
    138                             "More than one possible primary device found\n");
    139                     primaryBus.type ^= (BusType) (-1);
    140                 }
    141             }
    142         }
    143     }
    144 
    145     /* Print a summary of the video devices found */
    146     for (k = 0; k < num; k++) {
    147         const char *prim = " ";
    148         Bool memdone = FALSE, iodone = FALSE;
    149 
    150         info = xf86PciVideoInfo[k];
    151 
    152         if (!PCIALWAYSPRINTCLASSES(info->device_class))
    153             continue;
    154 
    155         if (xf86IsPrimaryPci(info))
    156             prim = "*";
    157 
    158         xf86Msg(X_PROBED, "PCI:%s(%u@%u:%u:%u) %04x:%04x:%04x:%04x ", prim,
    159                 info->bus, info->domain, info->dev, info->func,
    160                 info->vendor_id, info->device_id,
    161                 info->subvendor_id, info->subdevice_id);
    162 
    163         xf86ErrorF("rev %d", info->revision);
    164 
    165         for (i = 0; i < 6; i++) {
    166             struct pci_mem_region *r = &info->regions[i];
    167 
    168             if (r->size && !r->is_IO) {
    169                 if (!memdone) {
    170                     xf86ErrorF(", Mem @ ");
    171                     memdone = TRUE;
    172                 }
    173                 else
    174                     xf86ErrorF(", ");
    175                 xf86ErrorF("0x%08lx/%ld", (long) r->base_addr, (long) r->size);
    176             }
    177         }
    178 
    179         for (i = 0; i < 6; i++) {
    180             struct pci_mem_region *r = &info->regions[i];
    181 
    182             if (r->size && r->is_IO) {
    183                 if (!iodone) {
    184                     xf86ErrorF(", I/O @ ");
    185                     iodone = TRUE;
    186                 }
    187                 else
    188                     xf86ErrorF(", ");
    189                 xf86ErrorF("0x%08lx/%ld", (long) r->base_addr, (long) r->size);
    190             }
    191         }
    192 
    193         if (info->rom_size) {
    194             xf86ErrorF(", BIOS @ 0x\?\?\?\?\?\?\?\?/%ld",
    195                        (long) info->rom_size);
    196         }
    197 
    198         xf86ErrorF("\n");
    199     }
    200     free(xf86PciVideoInfo);
    201 }
    202 
    203 /*
    204  * If the slot requested is already in use, return -1.
    205  * Otherwise, claim the slot for the screen requesting it.
    206  */
    207 
    208 int
    209 xf86ClaimPciSlot(struct pci_device *d, DriverPtr drvp,
    210                  int chipset, GDevPtr dev, Bool active)
    211 {
    212     EntityPtr p = NULL;
    213     int num;
    214 
    215     if (xf86CheckPciSlot(d)) {
    216         num = xf86AllocateEntity();
    217         p = xf86Entities[num];
    218         p->driver = drvp;
    219         p->chipset = chipset;
    220         p->bus.type = BUS_PCI;
    221         p->bus.id.pci = d;
    222         p->active = active;
    223         p->inUse = FALSE;
    224         if (dev)
    225             xf86AddDevToEntity(num, dev);
    226         pciSlotClaimed++;
    227 
    228         return num;
    229     }
    230     else
    231         return -1;
    232 }
    233 
    234 /*
    235  * Unclaim PCI slot, e.g. if probing failed, so that a different driver can claim.
    236  */
    237 void
    238 xf86UnclaimPciSlot(struct pci_device *d, GDevPtr dev)
    239 {
    240     int i;
    241 
    242     for (i = 0; i < xf86NumEntities; i++) {
    243         const EntityPtr p = xf86Entities[i];
    244 
    245         if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
    246             /* Probably the slot should be deallocated? */
    247             xf86RemoveDevFromEntity(i, dev);
    248             pciSlotClaimed--;
    249             p->bus.type = BUS_NONE;
    250             return;
    251         }
    252     }
    253 }
    254 
    255 /*
    256  * Parse a BUS ID string, and return the PCI bus parameters if it was
    257  * in the correct format for a PCI bus id.
    258  */
    259 
    260 Bool
    261 xf86ParsePciBusString(const char *busID, int *bus, int *device, int *func)
    262 {
    263     /*
    264      * The format is assumed to be "bus[@domain]:device[:func]", where domain,
    265      * bus, device and func are decimal integers.  domain and func may be
    266      * omitted and assumed to be zero, although doing this isn't encouraged.
    267      */
    268 
    269     char *p, *s, *d;
    270     const char *id;
    271     int i;
    272 
    273     if (StringToBusType(busID, &id) != BUS_PCI)
    274         return FALSE;
    275 
    276     s = xstrdup(id);
    277     p = strtok(s, ":");
    278     if (p == NULL || *p == 0) {
    279         free(s);
    280         return FALSE;
    281     }
    282     d = strpbrk(p, "@");
    283     if (d != NULL) {
    284         *(d++) = 0;
    285         for (i = 0; d[i] != 0; i++) {
    286             if (!isdigit(d[i])) {
    287                 free(s);
    288                 return FALSE;
    289             }
    290         }
    291     }
    292     for (i = 0; p[i] != 0; i++) {
    293         if (!isdigit(p[i])) {
    294             free(s);
    295             return FALSE;
    296         }
    297     }
    298     *bus = atoi(p);
    299     if (d != NULL && *d != 0)
    300         *bus += atoi(d) << 8;
    301     p = strtok(NULL, ":");
    302     if (p == NULL || *p == 0) {
    303         free(s);
    304         return FALSE;
    305     }
    306     for (i = 0; p[i] != 0; i++) {
    307         if (!isdigit(p[i])) {
    308             free(s);
    309             return FALSE;
    310         }
    311     }
    312     *device = atoi(p);
    313     *func = 0;
    314     p = strtok(NULL, ":");
    315     if (p == NULL || *p == 0) {
    316         free(s);
    317         return TRUE;
    318     }
    319     for (i = 0; p[i] != 0; i++) {
    320         if (!isdigit(p[i])) {
    321             free(s);
    322             return FALSE;
    323         }
    324     }
    325     *func = atoi(p);
    326     free(s);
    327     return TRUE;
    328 }
    329 
    330 /*
    331  * Compare a BUS ID string with a PCI bus id.  Return TRUE if they match.
    332  */
    333 
    334 Bool
    335 xf86ComparePciBusString(const char *busID, int bus, int device, int func)
    336 {
    337     int ibus, idevice, ifunc;
    338 
    339     if (xf86ParsePciBusString(busID, &ibus, &idevice, &ifunc)) {
    340         return bus == ibus && device == idevice && func == ifunc;
    341     }
    342     else {
    343         return FALSE;
    344     }
    345 }
    346 
    347 /*
    348  * xf86IsPrimaryPci() -- return TRUE if primary device
    349  * is PCI and bus, dev and func numbers match.
    350  */
    351 
    352 Bool
    353 xf86IsPrimaryPci(struct pci_device *pPci)
    354 {
    355     /* Add max. 1 screen for the IgnorePrimary fallback path */
    356     if (xf86ProbeIgnorePrimary && xf86NumScreens == 0)
    357         return TRUE;
    358 
    359     if (primaryBus.type == BUS_PCI)
    360         return pPci == primaryBus.id.pci;
    361 #ifdef XSERVER_PLATFORM_BUS
    362     if (primaryBus.type == BUS_PLATFORM)
    363         if (primaryBus.id.plat->pdev)
    364             if (MATCH_PCI_DEVICES(primaryBus.id.plat->pdev, pPci))
    365                 return TRUE;
    366 #endif
    367     return FALSE;
    368 }
    369 
    370 /*
    371  * xf86GetPciInfoForEntity() -- Get the pciVideoRec of entity.
    372  */
    373 struct pci_device *
    374 xf86GetPciInfoForEntity(int entityIndex)
    375 {
    376     EntityPtr p;
    377 
    378     if (entityIndex >= xf86NumEntities)
    379         return NULL;
    380 
    381     p = xf86Entities[entityIndex];
    382     switch (p->bus.type) {
    383     case BUS_PCI:
    384         return p->bus.id.pci;
    385     case BUS_PLATFORM:
    386         return p->bus.id.plat->pdev;
    387     default:
    388         break;
    389     }
    390     return NULL;
    391 }
    392 
    393 /*
    394  * xf86CheckPciMemBase() checks that the memory base value matches one of the
    395  * PCI base address register values for the given PCI device.
    396  */
    397 Bool
    398 xf86CheckPciMemBase(struct pci_device *pPci, memType base)
    399 {
    400     int i;
    401 
    402     for (i = 0; i < 6; i++)
    403         if (base == pPci->regions[i].base_addr)
    404             return TRUE;
    405     return FALSE;
    406 }
    407 
    408 /*
    409  * Check if the slot requested is free.  If it is already in use, return FALSE.
    410  */
    411 
    412 Bool
    413 xf86CheckPciSlot(const struct pci_device *d)
    414 {
    415     int i;
    416 
    417     for (i = 0; i < xf86NumEntities; i++) {
    418         const EntityPtr p = xf86Entities[i];
    419 
    420         if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
    421             return FALSE;
    422         }
    423 #ifdef XSERVER_PLATFORM_BUS
    424         if ((p->bus.type == BUS_PLATFORM) && (p->bus.id.plat->pdev)) {
    425             struct pci_device *ud = p->bus.id.plat->pdev;
    426             if (MATCH_PCI_DEVICES(ud, d))
    427                 return FALSE;
    428         }
    429 #endif
    430     }
    431     return TRUE;
    432 }
    433 
    434 #define END_OF_MATCHES(m) \
    435     (((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
    436 
    437 Bool
    438 xf86PciAddMatchingDev(DriverPtr drvp)
    439 {
    440     const struct pci_id_match *const devices = drvp->supported_devices;
    441     int j;
    442     struct pci_device *pPci;
    443     struct pci_device_iterator *iter;
    444     int numFound = 0;
    445 
    446     iter = pci_id_match_iterator_create(NULL);
    447     while ((pPci = pci_device_next(iter)) != NULL) {
    448         /* Determine if this device is supported by the driver.  If it is,
    449          * add it to the list of devices to configure.
    450          */
    451         for (j = 0; !END_OF_MATCHES(devices[j]); j++) {
    452             if (PCI_ID_COMPARE(devices[j].vendor_id, pPci->vendor_id)
    453                 && PCI_ID_COMPARE(devices[j].device_id, pPci->device_id)
    454                 && ((devices[j].device_class_mask & pPci->device_class)
    455                     == devices[j].device_class)) {
    456                 if (xf86CheckPciSlot(pPci)) {
    457                     GDevPtr pGDev =
    458                         xf86AddBusDeviceToConfigure(drvp->driverName, BUS_PCI,
    459                                                     pPci, -1);
    460                     if (pGDev != NULL) {
    461                         /* After configure pass 1, chipID and chipRev are
    462                          * treated as over-rides, so clobber them here.
    463                          */
    464                         pGDev->chipID = -1;
    465                         pGDev->chipRev = -1;
    466                     }
    467 
    468                     numFound++;
    469                 }
    470 
    471                 break;
    472             }
    473         }
    474     }
    475 
    476     pci_iterator_destroy(iter);
    477 
    478     return numFound != 0;
    479 }
    480 
    481 Bool
    482 xf86PciProbeDev(DriverPtr drvp)
    483 {
    484     int i, j;
    485     struct pci_device *pPci;
    486     Bool foundScreen = FALSE;
    487     const struct pci_id_match *const devices = drvp->supported_devices;
    488     GDevPtr *devList;
    489     const unsigned numDevs = xf86MatchDevice(drvp->driverName, &devList);
    490 
    491     for (i = 0; i < numDevs; i++) {
    492         struct pci_device_iterator *iter;
    493         unsigned device_id;
    494 
    495         /* Find the pciVideoRec associated with this device section.
    496          */
    497         iter = pci_id_match_iterator_create(NULL);
    498         while ((pPci = pci_device_next(iter)) != NULL) {
    499             if (devList[i]->busID && *devList[i]->busID) {
    500                 if (xf86ComparePciBusString(devList[i]->busID,
    501                                             ((pPci->domain << 8)
    502                                              | pPci->bus),
    503                                             pPci->dev, pPci->func)) {
    504                     break;
    505                 }
    506             }
    507             else if (xf86IsPrimaryPci(pPci)) {
    508                 break;
    509             }
    510         }
    511 
    512         pci_iterator_destroy(iter);
    513 
    514         if (pPci == NULL) {
    515             continue;
    516         }
    517         device_id = (devList[i]->chipID > 0)
    518             ? devList[i]->chipID : pPci->device_id;
    519 
    520         /* Once the pciVideoRec is found, determine if the device is supported
    521          * by the driver.  If it is, probe it!
    522          */
    523         for (j = 0; !END_OF_MATCHES(devices[j]); j++) {
    524             if (PCI_ID_COMPARE(devices[j].vendor_id, pPci->vendor_id)
    525                 && PCI_ID_COMPARE(devices[j].device_id, device_id)
    526                 && ((devices[j].device_class_mask & pPci->device_class)
    527                     == devices[j].device_class)) {
    528                 int entry;
    529 
    530                 /* Allow the same entity to be used more than once for
    531                  * devices with multiple screens per entity.  This assumes
    532                  * implicitly that there will be a screen == 0 instance.
    533                  *
    534                  * FIXME Need to make sure that two different drivers don't
    535                  * FIXME claim the same screen > 0 instance.
    536                  */
    537                 if ((devList[i]->screen == 0) && !xf86CheckPciSlot(pPci))
    538                     continue;
    539 
    540                 DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
    541                        drvp->driverName, pPci->bus, pPci->dev, pPci->func);
    542 
    543                 /* Allocate an entry in the lists to be returned */
    544                 entry = xf86ClaimPciSlot(pPci, drvp, device_id,
    545                                          devList[i], devList[i]->active);
    546 
    547                 if ((entry == -1) && (devList[i]->screen > 0)) {
    548                     unsigned k;
    549 
    550                     for (k = 0; k < xf86NumEntities; k++) {
    551                         EntityPtr pEnt = xf86Entities[k];
    552 
    553                         if (pEnt->bus.type != BUS_PCI)
    554                             continue;
    555                         if (pEnt->bus.id.pci == pPci) {
    556                             entry = k;
    557                             xf86AddDevToEntity(k, devList[i]);
    558                             break;
    559                         }
    560                     }
    561                 }
    562 
    563                 if (entry != -1) {
    564                     if ((*drvp->PciProbe) (drvp, entry, pPci,
    565                                            devices[j].match_data)) {
    566                         foundScreen = TRUE;
    567                     }
    568                     else
    569                         xf86UnclaimPciSlot(pPci, devList[i]);
    570                 }
    571 
    572                 break;
    573             }
    574         }
    575     }
    576     free(devList);
    577 
    578     return foundScreen;
    579 }
    580 
    581 void
    582 xf86PciIsolateDevice(const char *argument)
    583 {
    584     int bus, device, func;
    585 
    586     if (sscanf(argument, "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
    587         xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
    588         xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
    589         xf86IsolateDevice.dev = device;
    590         xf86IsolateDevice.func = func;
    591     }
    592     else
    593         FatalError("Invalid isolated device specification\n");
    594 }
    595 
    596 static Bool
    597 pciDeviceHasBars(struct pci_device *pci)
    598 {
    599     int i;
    600 
    601     for (i = 0; i < 6; i++)
    602         if (pci->regions[i].size)
    603             return TRUE;
    604 
    605     if (pci->rom_size)
    606         return TRUE;
    607 
    608     return FALSE;
    609 }
    610 
    611 struct Inst {
    612     struct pci_device *pci;
    613     GDevPtr dev;
    614     Bool foundHW;               /* PCIid in list of supported chipsets */
    615     Bool claimed;               /* BusID matches with a device section */
    616     int chip;
    617     int screen;
    618 };
    619 
    620 /**
    621  * Find set of unclaimed devices matching a given vendor ID.
    622  *
    623  * Used by drivers to find as yet unclaimed devices matching the specified
    624  * vendor ID.
    625  *
    626  * \param driverName     Name of the driver.  This is used to find Device
    627  *                       sections in the config file.
    628  * \param vendorID       PCI vendor ID of associated devices.  If zero, then
    629  *                       the true vendor ID must be encoded in the \c PCIid
    630  *                       fields of the \c PCIchipsets entries.
    631  * \param chipsets       Symbol table used to associate chipset names with
    632  *                       PCI IDs.
    633  * \param devList        List of Device sections parsed from the config file.
    634  * \param numDevs        Number of entries in \c devList.
    635  * \param drvp           Pointer the driver's control structure.
    636  * \param foundEntities  Returned list of entity indices associated with the
    637  *                       driver.
    638  *
    639  * \returns
    640  * The number of elements in returned in \c foundEntities on success or zero
    641  * on failure.
    642  *
    643  * \todo
    644  * This function does a bit more than short description says.  Fill in some
    645  * more of the details of its operation.
    646  *
    647  * \todo
    648  * The \c driverName parameter is redundant.  It is the same as
    649  * \c DriverRec::driverName.  In a future version of this function, remove
    650  * that parameter.
    651  */
    652 int
    653 xf86MatchPciInstances(const char *driverName, int vendorID,
    654                       SymTabPtr chipsets, PciChipsets * PCIchipsets,
    655                       GDevPtr * devList, int numDevs, DriverPtr drvp,
    656                       int **foundEntities)
    657 {
    658     int i, j;
    659     struct pci_device *pPci;
    660     struct pci_device_iterator *iter;
    661     struct Inst *instances = NULL;
    662     int numClaimedInstances = 0;
    663     int allocatedInstances = 0;
    664     int numFound = 0;
    665     SymTabRec *c;
    666     PciChipsets *id;
    667     int *retEntities = NULL;
    668 
    669     *foundEntities = NULL;
    670 
    671     /* Each PCI device will contribute at least one entry.  Each device
    672      * section can contribute at most one entry.  The sum of the two is
    673      * guaranteed to be larger than the maximum possible number of entries.
    674      * Do this calculation and memory allocation once now to eliminate the
    675      * need for realloc calls inside the loop.
    676      */
    677     if (!(xf86DoConfigure && xf86DoConfigurePass1)) {
    678         unsigned max_entries = numDevs;
    679 
    680         iter = pci_slot_match_iterator_create(NULL);
    681         while ((pPci = pci_device_next(iter)) != NULL) {
    682             max_entries++;
    683         }
    684 
    685         pci_iterator_destroy(iter);
    686         instances = xnfallocarray(max_entries, sizeof(struct Inst));
    687     }
    688 
    689     iter = pci_slot_match_iterator_create(NULL);
    690     while ((pPci = pci_device_next(iter)) != NULL) {
    691         unsigned device_class = pPci->device_class;
    692         Bool foundVendor = FALSE;
    693 
    694         /* Convert the pre-PCI 2.0 device class for a VGA adapter to the
    695          * 2.0 version of the same class.
    696          */
    697         if (device_class == 0x00000101) {
    698             device_class = 0x00030000;
    699         }
    700 
    701         /* Find PCI devices that match the given vendor ID.  The vendor ID is
    702          * either specified explicitly as a parameter to the function or
    703          * implicitly encoded in the high bits of id->PCIid.
    704          *
    705          * The first device with a matching vendor is recorded, even if the
    706          * device ID doesn't match.  This is done because the Device section
    707          * in the xorg.conf file can over-ride the device ID.  A matching PCI
    708          * ID might not be found now, but after the device ID over-ride is
    709          * applied there /might/ be a match.
    710          */
    711         for (id = PCIchipsets; id->PCIid != -1; id++) {
    712             const unsigned vendor_id = ((id->PCIid & 0xFFFF0000) >> 16)
    713                 | vendorID;
    714             const unsigned device_id = (id->PCIid & 0x0000FFFF);
    715             const unsigned match_class = 0x00030000 | id->PCIid;
    716 
    717             if ((vendor_id == pPci->vendor_id)
    718                 || ((vendorID == PCI_VENDOR_GENERIC) &&
    719                     (match_class == device_class))) {
    720                 if (!foundVendor && (instances != NULL)) {
    721                     ++allocatedInstances;
    722                     instances[allocatedInstances - 1].pci = pPci;
    723                     instances[allocatedInstances - 1].dev = NULL;
    724                     instances[allocatedInstances - 1].claimed = FALSE;
    725                     instances[allocatedInstances - 1].foundHW = FALSE;
    726                     instances[allocatedInstances - 1].screen = 0;
    727                 }
    728 
    729                 foundVendor = TRUE;
    730 
    731                 if ((device_id == pPci->device_id)
    732                     || ((vendorID == PCI_VENDOR_GENERIC)
    733                         && (match_class == device_class))) {
    734                     if (instances != NULL) {
    735                         instances[allocatedInstances - 1].foundHW = TRUE;
    736                         instances[allocatedInstances - 1].chip = id->numChipset;
    737                     }
    738 
    739                     if (xf86DoConfigure && xf86DoConfigurePass1) {
    740                         if (xf86CheckPciSlot(pPci)) {
    741                             GDevPtr pGDev =
    742                                 xf86AddBusDeviceToConfigure(drvp->driverName,
    743                                                             BUS_PCI, pPci, -1);
    744 
    745                             if (pGDev) {
    746                                 /* After configure pass 1, chipID and chipRev
    747                                  * are treated as over-rides, so clobber them
    748                                  * here.
    749                                  */
    750                                 pGDev->chipID = -1;
    751                                 pGDev->chipRev = -1;
    752                             }
    753 
    754                             numFound++;
    755                         }
    756                     }
    757                     else {
    758                         numFound++;
    759                     }
    760 
    761                     break;
    762                 }
    763             }
    764         }
    765     }
    766 
    767     pci_iterator_destroy(iter);
    768 
    769     /* In "probe only" or "configure" mode (signaled by instances being NULL),
    770      * our work is done.  Return the number of detected devices.
    771      */
    772     if (instances == NULL) {
    773         return numFound;
    774     }
    775 
    776     /*
    777      * This may be debatable, but if no PCI devices with a matching vendor
    778      * type is found, return zero now.  It is probably not desirable to
    779      * allow the config file to override this.
    780      */
    781     if (allocatedInstances <= 0) {
    782         free(instances);
    783         return 0;
    784     }
    785 
    786     DebugF("%s instances found: %d\n", driverName, allocatedInstances);
    787 
    788     /*
    789      * Check for devices that need duplicated instances.  This is required
    790      * when there is more than one screen per entity.
    791      *
    792      * XXX This currently doesn't work for cases where the BusID isn't
    793      * specified explicitly in the config file.
    794      */
    795 
    796     for (j = 0; j < numDevs; j++) {
    797         if (devList[j]->screen > 0 && devList[j]->busID && *devList[j]->busID) {
    798             for (i = 0; i < allocatedInstances; i++) {
    799                 pPci = instances[i].pci;
    800                 if (xf86ComparePciBusString(devList[j]->busID,
    801                                             PCI_MAKE_BUS(pPci->domain,
    802                                                          pPci->bus), pPci->dev,
    803                                             pPci->func)) {
    804                     allocatedInstances++;
    805                     instances[allocatedInstances - 1] = instances[i];
    806                     instances[allocatedInstances - 1].screen =
    807                         devList[j]->screen;
    808                     numFound++;
    809                     break;
    810                 }
    811             }
    812         }
    813     }
    814 
    815     for (i = 0; i < allocatedInstances; i++) {
    816         GDevPtr dev = NULL;
    817         GDevPtr devBus = NULL;
    818 
    819         pPci = instances[i].pci;
    820         for (j = 0; j < numDevs; j++) {
    821             if (devList[j]->busID && *devList[j]->busID) {
    822                 if (xf86ComparePciBusString(devList[j]->busID,
    823                                             PCI_MAKE_BUS(pPci->domain,
    824                                                          pPci->bus), pPci->dev,
    825                                             pPci->func) &&
    826                     devList[j]->screen == instances[i].screen) {
    827 
    828                     if (devBus)
    829                         xf86MsgVerb(X_WARNING, 0,
    830                                     "%s: More than one matching Device section for "
    831                                     "instances\n\t(BusID: %s) found: %s\n",
    832                                     driverName, devList[j]->busID,
    833                                     devList[j]->identifier);
    834                     else
    835                         devBus = devList[j];
    836                 }
    837             }
    838             else {
    839                 /*
    840                  * if device section without BusID is found
    841                  * only assign to it to the primary device.
    842                  */
    843                 if (xf86IsPrimaryPci(pPci)) {
    844                     xf86Msg(X_PROBED, "Assigning device section with no busID"
    845                             " to primary device\n");
    846                     if (dev || devBus)
    847                         xf86MsgVerb(X_WARNING, 0,
    848                                     "%s: More than one matching Device section "
    849                                     "found: %s\n", driverName,
    850                                     devList[j]->identifier);
    851                     else
    852                         dev = devList[j];
    853                 }
    854             }
    855         }
    856         if (devBus)
    857             dev = devBus;       /* busID preferred */
    858         if (!dev) {
    859             if (xf86CheckPciSlot(pPci) && pciDeviceHasBars(pPci)) {
    860                 xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
    861                             "for instance (BusID PCI:%u@%u:%u:%u) found\n",
    862                             driverName, pPci->bus, pPci->domain, pPci->dev,
    863                             pPci->func);
    864             }
    865         }
    866         else {
    867             numClaimedInstances++;
    868             instances[i].claimed = TRUE;
    869             instances[i].dev = dev;
    870         }
    871     }
    872     DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
    873     /*
    874      * Now check that a chipset or chipID override in the device section
    875      * is valid.  Chipset has precedence over chipID.
    876      * If chipset is not valid ignore BusSlot completely.
    877      */
    878     for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
    879         MessageType from = X_PROBED;
    880 
    881         if (!instances[i].claimed) {
    882             continue;
    883         }
    884         if (instances[i].dev->chipset) {
    885             for (c = chipsets; c->token >= 0; c++) {
    886                 if (xf86NameCmp(c->name, instances[i].dev->chipset) == 0)
    887                     break;
    888             }
    889             if (c->token == -1) {
    890                 instances[i].claimed = FALSE;
    891                 numClaimedInstances--;
    892                 xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
    893                             "section \"%s\" isn't valid for this driver\n",
    894                             driverName, instances[i].dev->chipset,
    895                             instances[i].dev->identifier);
    896             }
    897             else {
    898                 instances[i].chip = c->token;
    899 
    900                 for (id = PCIchipsets; id->numChipset >= 0; id++) {
    901                     if (id->numChipset == instances[i].chip)
    902                         break;
    903                 }
    904                 if (id->numChipset >= 0) {
    905                     xf86Msg(X_CONFIG, "Chipset override: %s\n",
    906                             instances[i].dev->chipset);
    907                     from = X_CONFIG;
    908                 }
    909                 else {
    910                     instances[i].claimed = FALSE;
    911                     numClaimedInstances--;
    912                     xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
    913                                 "section \"%s\" isn't a valid PCI chipset\n",
    914                                 driverName, instances[i].dev->chipset,
    915                                 instances[i].dev->identifier);
    916                 }
    917             }
    918         }
    919         else if (instances[i].dev->chipID > 0) {
    920             for (id = PCIchipsets; id->numChipset >= 0; id++) {
    921                 if (id->PCIid == instances[i].dev->chipID)
    922                     break;
    923             }
    924             if (id->numChipset == -1) {
    925                 instances[i].claimed = FALSE;
    926                 numClaimedInstances--;
    927                 xf86MsgVerb(X_WARNING, 0, "%s: ChipID 0x%04X in Device "
    928                             "section \"%s\" isn't valid for this driver\n",
    929                             driverName, instances[i].dev->chipID,
    930                             instances[i].dev->identifier);
    931             }
    932             else {
    933                 instances[i].chip = id->numChipset;
    934 
    935                 xf86Msg(X_CONFIG, "ChipID override: 0x%04X\n",
    936                         instances[i].dev->chipID);
    937                 from = X_CONFIG;
    938             }
    939         }
    940         else if (!instances[i].foundHW) {
    941             /*
    942              * This means that there was no override and the PCI chipType
    943              * doesn't match one that is supported
    944              */
    945             instances[i].claimed = FALSE;
    946             numClaimedInstances--;
    947         }
    948         if (instances[i].claimed == TRUE) {
    949             for (c = chipsets; c->token >= 0; c++) {
    950                 if (c->token == instances[i].chip)
    951                     break;
    952             }
    953             xf86Msg(from, "Chipset %s found\n", c->name);
    954         }
    955     }
    956 
    957     /*
    958      * Of the claimed instances, check that another driver hasn't already
    959      * claimed its slot.
    960      */
    961     numFound = 0;
    962     for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
    963         if (!instances[i].claimed)
    964             continue;
    965         pPci = instances[i].pci;
    966 
    967         /*
    968          * Allow the same entity to be used more than once for devices with
    969          * multiple screens per entity.  This assumes implicitly that there
    970          * will be a screen == 0 instance.
    971          *
    972          * XXX Need to make sure that two different drivers don't claim
    973          * the same screen > 0 instance.
    974          */
    975         if (instances[i].screen == 0 && !xf86CheckPciSlot(pPci))
    976             continue;
    977 
    978         DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
    979                driverName, pPci->bus, pPci->dev, pPci->func);
    980 
    981         /* Allocate an entry in the lists to be returned */
    982         numFound++;
    983         retEntities = xnfreallocarray(retEntities, numFound, sizeof(int));
    984         retEntities[numFound - 1] = xf86ClaimPciSlot(pPci, drvp,
    985                                                      instances[i].chip,
    986                                                      instances[i].dev,
    987                                                      instances[i].dev->active);
    988         if (retEntities[numFound - 1] == -1 && instances[i].screen > 0) {
    989             for (j = 0; j < xf86NumEntities; j++) {
    990                 EntityPtr pEnt = xf86Entities[j];
    991 
    992                 if (pEnt->bus.type != BUS_PCI)
    993                     continue;
    994                 if (pEnt->bus.id.pci == pPci) {
    995                     retEntities[numFound - 1] = j;
    996                     xf86AddDevToEntity(j, instances[i].dev);
    997                     break;
    998                 }
    999             }
   1000         }
   1001     }
   1002     free(instances);
   1003     if (numFound > 0) {
   1004         *foundEntities = retEntities;
   1005     }
   1006 
   1007     return numFound;
   1008 }
   1009 
   1010 /*
   1011  * xf86ConfigPciEntityInactive() -- This function can be used
   1012  * to configure an inactive entity as well as to reconfigure an
   1013  * previously active entity inactive. If the entity has been
   1014  * assigned to a screen before it will be removed. If p_chip is
   1015  * non-NULL all static resources listed there will be registered.
   1016  */
   1017 static void
   1018 xf86ConfigPciEntityInactive(EntityInfoPtr pEnt, PciChipsets * p_chip,
   1019                             EntityProc init, EntityProc enter,
   1020                             EntityProc leave, void *private)
   1021 {
   1022     ScrnInfoPtr pScrn;
   1023 
   1024     if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
   1025         xf86RemoveEntityFromScreen(pScrn, pEnt->index);
   1026 }
   1027 
   1028 ScrnInfoPtr
   1029 xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
   1030                     PciChipsets * p_chip, void *dummy, EntityProc init,
   1031                     EntityProc enter, EntityProc leave, void *private)
   1032 {
   1033     EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
   1034 
   1035     if (dummy || init || enter || leave)
   1036         FatalError("Legacy entity access functions are unsupported\n");
   1037 
   1038     if (!pEnt)
   1039         return pScrn;
   1040 
   1041     if (!(pEnt->location.type == BUS_PCI)
   1042         || !xf86GetPciInfoForEntity(entityIndex)) {
   1043         free(pEnt);
   1044         return pScrn;
   1045     }
   1046     if (!pEnt->active) {
   1047         xf86ConfigPciEntityInactive(pEnt, p_chip, init, enter, leave, private);
   1048         free(pEnt);
   1049         return pScrn;
   1050     }
   1051 
   1052     if (!pScrn)
   1053         pScrn = xf86AllocateScreen(pEnt->driver, scrnFlag);
   1054     if (xf86IsEntitySharable(entityIndex)) {
   1055         xf86SetEntityShared(entityIndex);
   1056     }
   1057     xf86AddEntityToScreen(pScrn, entityIndex);
   1058     if (xf86IsEntityShared(entityIndex)) {
   1059         return pScrn;
   1060     }
   1061     free(pEnt);
   1062 
   1063     return pScrn;
   1064 }
   1065 
   1066 void
   1067 xf86VideoPtrToDriverList(struct pci_device *dev, XF86MatchedDrivers *md)
   1068 {
   1069     int i;
   1070 
   1071     /* Add more entries here if we ever return more than 4 drivers for
   1072        any device */
   1073     const char *driverList[5] = { NULL, NULL, NULL, NULL, NULL };
   1074 
   1075     switch (dev->vendor_id) {
   1076         /* AMD Geode LX */
   1077     case 0x1022:
   1078         if (dev->device_id == 0x2081)
   1079             driverList[0] = "geode";
   1080         break;
   1081         /* older Geode products acquired by AMD still carry an NSC vendor_id */
   1082     case 0x100b:
   1083         if (dev->device_id == 0x0030) {
   1084             /* NSC Geode GX2 specifically */
   1085             driverList[0] = "geode";
   1086             /* GX2 support started its life in the NSC tree and was later
   1087                forked by AMD for GEODE so we keep it as a backup */
   1088             driverList[1] = "nsc";
   1089         }
   1090         else
   1091             /* other NSC variant e.g. 0x0104 (SC1400), 0x0504 (SCx200) */
   1092             driverList[0] = "nsc";
   1093         break;
   1094         /* Cyrix Geode GX1 */
   1095     case 0x1078:
   1096         if (dev->device_id == 0x0104)
   1097             driverList[0] = "cyrix";
   1098         break;
   1099     case 0x1142:
   1100         driverList[0] = "apm";
   1101         break;
   1102     case 0xedd8:
   1103         driverList[0] = "ark";
   1104         break;
   1105     case 0x1a03:
   1106         driverList[0] = "ast";
   1107         break;
   1108     case 0x1002:
   1109         driverList[0] = "ati";
   1110         break;
   1111     case 0x102c:
   1112         driverList[0] = "chips";
   1113         break;
   1114     case 0x1013:
   1115         driverList[0] = "cirrus";
   1116         break;
   1117     case 0x3d3d:
   1118         driverList[0] = "glint";
   1119         break;
   1120     case 0x105d:
   1121         driverList[0] = "i128";
   1122         break;
   1123     case 0x8086:
   1124 	switch (dev->device_id)
   1125 	{
   1126 		/* Intel i740 */
   1127 		case 0x00d1:
   1128 		case 0x7800:
   1129 			driverList[0] = "i740";
   1130 			break;
   1131 		/* GMA500/Poulsbo */
   1132 		case 0x8108:
   1133 		case 0x8109:
   1134 			/* Try psb driver on Poulsbo - if available */
   1135 			driverList[0] = "psb";
   1136 			driverList[1] = "psb_drv";
   1137 			break;
   1138 		/* GMA600/Oaktrail */
   1139 		case 0x4100:
   1140 		case 0x4101:
   1141 		case 0x4102:
   1142 		case 0x4103:
   1143 		case 0x4104:
   1144 		case 0x4105:
   1145 		case 0x4106:
   1146 		case 0x4107:
   1147 		/* Atom E620/Oaktrail */
   1148 		case 0x4108:
   1149 		/* Medfield */
   1150 		case 0x0130:
   1151 		case 0x0131:
   1152 		case 0x0132:
   1153 		case 0x0133:
   1154 		case 0x0134:
   1155 		case 0x0135:
   1156 		case 0x0136:
   1157 		case 0x0137:
   1158 		/* GMA 3600/CDV */
   1159 		case 0x0be0:
   1160 		case 0x0be1:
   1161 		case 0x0be2:
   1162 		case 0x0be3:
   1163 		case 0x0be4:
   1164 		case 0x0be5:
   1165 		case 0x0be6:
   1166 		case 0x0be7:
   1167 		case 0x0be8:
   1168 		case 0x0be9:
   1169 		case 0x0bea:
   1170 		case 0x0beb:
   1171 		case 0x0bec:
   1172 		case 0x0bed:
   1173 		case 0x0bee:
   1174 		case 0x0bef:
   1175 			/* Use fbdev/vesa driver on Oaktrail, Medfield, CDV */
   1176 			break;
   1177 		default:
   1178 			driverList[0] = "intel";
   1179 			break;
   1180         }
   1181         break;
   1182     case 0x102b:
   1183         driverList[0] = "mga";
   1184         break;
   1185     case 0x10c8:
   1186         driverList[0] = "neomagic";
   1187         break;
   1188     case 0x10de:
   1189     case 0x12d2:
   1190     {
   1191         int idx = 0;
   1192 
   1193 #if defined(__linux__) || defined(__NetBSD__)
   1194         driverList[idx++] = "nouveau";
   1195 #endif
   1196         driverList[idx++] = "nv";
   1197         break;
   1198     }
   1199     case 0x1106:
   1200         driverList[0] = "openchrome";
   1201         break;
   1202     case 0x1b36:
   1203         driverList[0] = "qxl";
   1204         break;
   1205     case 0x1163:
   1206         driverList[0] = "rendition";
   1207         break;
   1208     case 0x5333:
   1209         switch (dev->device_id) {
   1210         case 0x88d0:
   1211         case 0x88d1:
   1212         case 0x88f0:
   1213         case 0x8811:
   1214         case 0x8812:
   1215         case 0x8814:
   1216         case 0x8901:
   1217             driverList[0] = "s3";
   1218             break;
   1219         case 0x5631:
   1220         case 0x883d:
   1221         case 0x8a01:
   1222         case 0x8a10:
   1223         case 0x8c01:
   1224         case 0x8c03:
   1225         case 0x8904:
   1226         case 0x8a13:
   1227             driverList[0] = "s3virge";
   1228             break;
   1229         default:
   1230             driverList[0] = "savage";
   1231             break;
   1232         }
   1233         break;
   1234     case 0x1039:
   1235         driverList[0] = "sis";
   1236         break;
   1237     case 0x126f:
   1238         driverList[0] = "siliconmotion";
   1239         break;
   1240     case 0x121a:
   1241         if (dev->device_id < 0x0003)
   1242             driverList[0] = "voodoo";
   1243         else
   1244             driverList[0] = "tdfx";
   1245         break;
   1246     case 0x1011:
   1247         driverList[0] = "tga";
   1248         break;
   1249     case 0x1023:
   1250         driverList[0] = "trident";
   1251         break;
   1252     case 0x100c:
   1253         driverList[0] = "tseng";
   1254         break;
   1255     case 0x80ee:
   1256         driverList[0] = "vboxvideo";
   1257         break;
   1258     case 0x15ad:
   1259         driverList[0] = "vmware";
   1260         break;
   1261     case 0x18ca:
   1262         if (dev->device_id == 0x47)
   1263             driverList[0] = "xgixp";
   1264         else
   1265             driverList[0] = "xgi";
   1266         break;
   1267     default:
   1268         break;
   1269     }
   1270     for (i = 0; driverList[i] != NULL; i++) {
   1271         xf86AddMatchedDriver(md, driverList[i]);
   1272     }
   1273 }
   1274 
   1275 #ifdef __linux__
   1276 static int
   1277 xchomp(char *line)
   1278 {
   1279     size_t len = 0;
   1280 
   1281     if (!line) {
   1282         return 1;
   1283     }
   1284 
   1285     len = strlen(line);
   1286     if (line[len - 1] == '\n' && len > 0) {
   1287         line[len - 1] = '\0';
   1288     }
   1289     return 0;
   1290 }
   1291 
   1292 /* This function is used to provide a workaround for binary drivers that
   1293  * don't export their PCI ID's properly. If distros don't end up using this
   1294  * feature it can and should be removed because the symbol-based resolution
   1295  * scheme should be the primary one */
   1296 void
   1297 xf86MatchDriverFromFiles(uint16_t match_vendor, uint16_t match_chip,
   1298                          XF86MatchedDrivers *md)
   1299 {
   1300     DIR *idsdir;
   1301     FILE *fp;
   1302     struct dirent *direntry;
   1303     char *line = NULL, *tmpMatch;
   1304     size_t len;
   1305     ssize_t read;
   1306     char path_name[512], vendor_str[5], chip_str[5];
   1307     uint16_t vendor, chip;
   1308     int j;
   1309 
   1310     idsdir = opendir(PCI_TXT_IDS_PATH);
   1311     if (!idsdir)
   1312         return;
   1313 
   1314     xf86Msg(X_INFO,
   1315             "Scanning %s directory for additional PCI ID's supported by the drivers\n",
   1316             PCI_TXT_IDS_PATH);
   1317     direntry = readdir(idsdir);
   1318     /* Read the directory */
   1319     while (direntry) {
   1320         if (direntry->d_name[0] == '.') {
   1321             direntry = readdir(idsdir);
   1322             continue;
   1323         }
   1324         len = strlen(direntry->d_name);
   1325         /* A tiny bit of sanity checking. We should probably do better */
   1326         if (strncmp(&(direntry->d_name[len - 4]), ".ids", 4) == 0) {
   1327             /* We need the full path name to open the file */
   1328             snprintf(path_name, sizeof(path_name), "%s/%s",
   1329                      PCI_TXT_IDS_PATH, direntry->d_name);
   1330             fp = fopen(path_name, "r");
   1331             if (fp == NULL) {
   1332                 xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n",
   1333                         path_name);
   1334                 goto end;
   1335             }
   1336             /* Read the file */
   1337 #ifdef __GLIBC__
   1338             while ((read = getline(&line, &len, fp)) != -1) {
   1339 #else
   1340             while ((line = fgetln(fp, &len)) != (char *) NULL) {
   1341 #endif                          /* __GLIBC __ */
   1342                 xchomp(line);
   1343                 if (isdigit(line[0])) {
   1344                     strlcpy(vendor_str, line, sizeof(vendor_str));
   1345                     vendor = (int) strtol(vendor_str, NULL, 16);
   1346                     if ((strlen(&line[4])) == 0) {
   1347                         chip_str[0] = '\0';
   1348                         chip = -1;
   1349                     }
   1350                     else {
   1351                         /* Handle trailing whitespace */
   1352                         if (isspace(line[4])) {
   1353                             chip_str[0] = '\0';
   1354                             chip = -1;
   1355                         }
   1356                         else {
   1357                             /* Ok, it's a real ID */
   1358                             strlcpy(chip_str, &line[4], sizeof(chip_str));
   1359                             chip = (int) strtol(chip_str, NULL, 16);
   1360                         }
   1361                     }
   1362                     if (vendor == match_vendor && chip == match_chip) {
   1363                         tmpMatch =
   1364                             (char *) malloc(sizeof(char) *
   1365                                             strlen(direntry->d_name) - 3);
   1366                         if (!tmpMatch) {
   1367                             xf86Msg(X_ERROR,
   1368                                     "Could not allocate space for the module name. Exiting.\n");
   1369                             goto end;
   1370                         }
   1371                         /* hack off the .ids suffix. This should guard
   1372                          * against other problems, but it will end up
   1373                          * taking off anything after the first '.' */
   1374                         for (j = 0; j < (strlen(direntry->d_name) - 3); j++) {
   1375                             if (direntry->d_name[j] == '.') {
   1376                                 tmpMatch[j] = '\0';
   1377                                 break;
   1378                             }
   1379                             else {
   1380                                 tmpMatch[j] = direntry->d_name[j];
   1381                             }
   1382                         }
   1383                         xf86AddMatchedDriver(md, tmpMatch);
   1384                         xf86Msg(X_INFO, "Matched %s from file name %s\n",
   1385                                 tmpMatch, direntry->d_name);
   1386                         free(tmpMatch);
   1387                     }
   1388                 }
   1389                 else {
   1390                     /* TODO Handle driver overrides here */
   1391                 }
   1392             }
   1393             fclose(fp);
   1394         }
   1395         direntry = readdir(idsdir);
   1396     }
   1397  end:
   1398     free(line);
   1399     closedir(idsdir);
   1400 }
   1401 #endif                          /* __linux__ */
   1402 
   1403 void
   1404 xf86PciMatchDriver(XF86MatchedDrivers *md)
   1405 {
   1406     struct pci_device *info = NULL;
   1407     struct pci_device_iterator *iter;
   1408 
   1409     /* Find the primary device, and get some information about it. */
   1410     iter = pci_slot_match_iterator_create(NULL);
   1411     while ((info = pci_device_next(iter)) != NULL) {
   1412         if (xf86IsPrimaryPci(info)) {
   1413             break;
   1414         }
   1415     }
   1416 
   1417     pci_iterator_destroy(iter);
   1418 #ifdef __linux__
   1419     if (info)
   1420         xf86MatchDriverFromFiles(info->vendor_id, info->device_id, md);
   1421 #endif
   1422 
   1423     if (info != NULL) {
   1424         xf86VideoPtrToDriverList(info, md);
   1425     }
   1426 }
   1427 
   1428 Bool
   1429 xf86PciConfigure(void *busData, struct pci_device *pDev)
   1430 {
   1431     struct pci_device *pVideo = NULL;
   1432 
   1433     pVideo = (struct pci_device *) busData;
   1434     if (pDev &&
   1435         (pDev->domain == pVideo->domain) &&
   1436         (pDev->bus == pVideo->bus) &&
   1437         (pDev->dev == pVideo->dev) && (pDev->func == pVideo->func))
   1438         return 0;
   1439 
   1440     return 1;
   1441 }
   1442 
   1443 void
   1444 xf86PciConfigureNewDev(void *busData, struct pci_device *pVideo,
   1445                        GDevRec * GDev, int *chipset)
   1446 {
   1447     char busnum[8];
   1448     char *tmp;
   1449 
   1450     pVideo = (struct pci_device *) busData;
   1451 
   1452     snprintf(busnum, sizeof(busnum), "%d", pVideo->bus);
   1453 
   1454     XNFasprintf(&tmp, "PCI:%s:%d:%d",
   1455                 busnum, pVideo->dev, pVideo->func);
   1456     GDev->busID = tmp;
   1457 
   1458     GDev->chipID = pVideo->device_id;
   1459     GDev->chipRev = pVideo->revision;
   1460 
   1461     if (*chipset < 0)
   1462         *chipset = (pVideo->vendor_id << 16) | pVideo->device_id;
   1463 }
   1464 
   1465 char *
   1466 DRICreatePCIBusID(const struct pci_device *dev)
   1467 {
   1468     char *busID;
   1469 
   1470     if (asprintf(&busID, "pci:%04x:%02x:%02x.%d",
   1471                  dev->domain, dev->bus, dev->dev, dev->func) == -1)
   1472         return NULL;
   1473 
   1474     return busID;
   1475 }