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