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
xf86PciProbe(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
xf86ClaimPciSlot(struct pci_device * d,DriverPtr drvp,int chipset,GDevPtr dev,Bool active)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
xf86UnclaimPciSlot(struct pci_device * d,GDevPtr dev)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
xf86ParsePciBusString(const char * busID,int * bus,int * device,int * func)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
xf86ComparePciBusString(const char * busID,int bus,int device,int func)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
xf86IsPrimaryPci(struct pci_device * pPci)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 *
xf86GetPciInfoForEntity(int entityIndex)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
xf86CheckPciMemBase(struct pci_device * pPci,memType base)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
xf86CheckPciSlot(const struct pci_device * d)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
xf86PciAddMatchingDev(DriverPtr drvp)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
xf86PciProbeDev(DriverPtr drvp)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
xf86PciIsolateDevice(const char * argument)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
pciDeviceHasBars(struct pci_device * pci)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 indicies 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
xf86MatchPciInstances(const char * driverName,int vendorID,SymTabPtr chipsets,PciChipsets * PCIchipsets,GDevPtr * devList,int numDevs,DriverPtr drvp,int ** foundEntities)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
xf86ConfigPciEntityInactive(EntityInfoPtr pEnt,PciChipsets * p_chip,EntityProc init,EntityProc enter,EntityProc leave,void * private)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
xf86ConfigPciEntity(ScrnInfoPtr pScrn,int scrnFlag,int entityIndex,PciChipsets * p_chip,void * dummy,EntityProc init,EntityProc enter,EntityProc leave,void * private)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
xf86VideoPtrToDriverList(struct pci_device * dev,XF86MatchedDrivers * md)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
xchomp(char * line)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
xf86MatchDriverFromFiles(uint16_t match_vendor,uint16_t match_chip,XF86MatchedDrivers * md)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 }
1476