2 * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
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).
29 * This file contains the interfaces to the bus-specific code
31 #ifdef HAVE_XORG_CONFIG_H
32 #include <xorg-config.h>
39 #include <pciaccess.h>
44 #include "dirent.h" /* DIR, FILE type definitions */
46 /* Bus-specific headers */
50 #include "xf86_OSproc.h"
52 #define PCI_VENDOR_GENERIC 0x00FF
54 /* Bus-specific globals */
55 int pciSlotClaimed
= 0;
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)))) )
66 * PCI classes that have messages printed always. The others are only
67 * have a message printed when the vendor/dev IDs are recognised.
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)))) )
78 == ((PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8)))
80 static struct pci_slot_match xf86IsolateDevice
= {
81 PCI_MATCH_ANY
, PCI_MATCH_ANY
, PCI_MATCH_ANY
, PCI_MATCH_ANY
, 0
93 struct pci_device
*info
;
94 struct pci_device_iterator
*iter
;
95 struct pci_device
**xf86PciVideoInfo
= NULL
;
98 xf86PciVideoInfo
= NULL
;
102 iter
= pci_slot_match_iterator_create(&xf86IsolateDevice
);
103 while ((info
= pci_device_next(iter
)) != NULL
) {
104 if (PCIINFOCLASSES(info
->device_class
)) {
106 xf86PciVideoInfo
= xnfrealloc(xf86PciVideoInfo
,
107 (sizeof(struct pci_device
*)
109 xf86PciVideoInfo
[num
] = NULL
;
110 xf86PciVideoInfo
[num
- 1] = info
;
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
;
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
++) {
127 info
= xf86PciVideoInfo
[i
];
128 pci_device_cfg_read_u16(info
, &command
, 4);
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
;
138 "More than one possible primary device found\n");
139 primaryBus
.type
^= (BusType
) (-1);
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
;
150 info
= xf86PciVideoInfo
[k
];
152 if (!PCIALWAYSPRINTCLASSES(info
->device_class
))
155 if (xf86IsPrimaryPci(info
))
158 xf86Msg(X_PROBED
, "PCI:%s(%u:%u:%u:%u) %04x:%04x:%04x:%04x ", prim
,
159 info
->domain
, info
->bus
, info
->dev
, info
->func
,
160 info
->vendor_id
, info
->device_id
,
161 info
->subvendor_id
, info
->subdevice_id
);
163 xf86ErrorF("rev %d", info
->revision
);
165 for (i
= 0; i
< 6; i
++) {
166 struct pci_mem_region
*r
= &info
->regions
[i
];
168 if (r
->size
&& !r
->is_IO
) {
170 xf86ErrorF(", Mem @ ");
175 xf86ErrorF("0x%08lx/%ld", (long) r
->base_addr
, (long) r
->size
);
179 for (i
= 0; i
< 6; i
++) {
180 struct pci_mem_region
*r
= &info
->regions
[i
];
182 if (r
->size
&& r
->is_IO
) {
184 xf86ErrorF(", I/O @ ");
189 xf86ErrorF("0x%08lx/%ld", (long) r
->base_addr
, (long) r
->size
);
193 if (info
->rom_size
) {
194 xf86ErrorF(", BIOS @ 0x\?\?\?\?\?\?\?\?/%ld",
195 (long) info
->rom_size
);
200 free(xf86PciVideoInfo
);
204 * If the slot requested is already in use, return -1.
205 * Otherwise, claim the slot for the screen requesting it.
209 xf86ClaimPciSlot(struct pci_device
*d
, DriverPtr drvp
,
210 int chipset
, GDevPtr dev
, Bool active
)
215 if (xf86CheckPciSlot(d
)) {
216 num
= xf86AllocateEntity();
217 p
= xf86Entities
[num
];
219 p
->chipset
= chipset
;
220 p
->bus
.type
= BUS_PCI
;
225 xf86AddDevToEntity(num
, dev
);
235 * Unclaim PCI slot, e.g. if probing failed, so that a different driver can claim.
238 xf86UnclaimPciSlot(struct pci_device
*d
, GDevPtr dev
)
242 for (i
= 0; i
< xf86NumEntities
; i
++) {
243 const EntityPtr p
= xf86Entities
[i
];
245 if ((p
->bus
.type
== BUS_PCI
) && (p
->bus
.id
.pci
== d
)) {
246 /* Probably the slot should be deallocated? */
247 xf86RemoveDevFromEntity(i
, dev
);
249 p
->bus
.type
= BUS_NONE
;
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.
261 xf86ParsePciBusString(const char *busID
, int *bus
, int *device
, int *func
)
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.
273 if (StringToBusType(busID
, &id
) != BUS_PCI
)
278 if (p
== NULL
|| *p
== 0) {
285 for (i
= 0; d
[i
] != 0; i
++) {
286 if (!isdigit(d
[i
])) {
292 for (i
= 0; p
[i
] != 0; i
++) {
293 if (!isdigit(p
[i
])) {
299 if (d
!= NULL
&& *d
!= 0)
300 *bus
+= atoi(d
) << 8;
301 p
= strtok(NULL
, ":");
302 if (p
== NULL
|| *p
== 0) {
306 for (i
= 0; p
[i
] != 0; i
++) {
307 if (!isdigit(p
[i
])) {
314 p
= strtok(NULL
, ":");
315 if (p
== NULL
|| *p
== 0) {
319 for (i
= 0; p
[i
] != 0; i
++) {
320 if (!isdigit(p
[i
])) {
331 * Compare a BUS ID string with a PCI bus id. Return TRUE if they match.
335 xf86ComparePciBusString(const char *busID
, int bus
, int device
, int func
)
337 int ibus
, idevice
, ifunc
;
339 if (xf86ParsePciBusString(busID
, &ibus
, &idevice
, &ifunc
)) {
340 return bus
== ibus
&& device
== idevice
&& func
== ifunc
;
348 * xf86IsPrimaryPci() -- return TRUE if primary device
349 * is PCI and bus, dev and func numbers match.
353 xf86IsPrimaryPci(struct pci_device
*pPci
)
355 if (primaryBus
.type
== BUS_PCI
)
356 return pPci
== primaryBus
.id
.pci
;
357 #ifdef XSERVER_PLATFORM_BUS
358 if (primaryBus
.type
== BUS_PLATFORM
)
359 if (primaryBus
.id
.plat
->pdev
)
360 if (MATCH_PCI_DEVICES(primaryBus
.id
.plat
->pdev
, pPci
))
367 * xf86GetPciInfoForEntity() -- Get the pciVideoRec of entity.
370 xf86GetPciInfoForEntity(int entityIndex
)
374 if (entityIndex
>= xf86NumEntities
)
377 p
= xf86Entities
[entityIndex
];
378 switch (p
->bus
.type
) {
380 return p
->bus
.id
.pci
;
382 return p
->bus
.id
.plat
->pdev
;
390 * xf86CheckPciMemBase() checks that the memory base value matches one of the
391 * PCI base address register values for the given PCI device.
394 xf86CheckPciMemBase(struct pci_device
*pPci
, memType base
)
398 for (i
= 0; i
< 6; i
++)
399 if (base
== pPci
->regions
[i
].base_addr
)
405 * Check if the slot requested is free. If it is already in use, return FALSE.
409 xf86CheckPciSlot(const struct pci_device
*d
)
413 for (i
= 0; i
< xf86NumEntities
; i
++) {
414 const EntityPtr p
= xf86Entities
[i
];
416 if ((p
->bus
.type
== BUS_PCI
) && (p
->bus
.id
.pci
== d
)) {
419 #ifdef XSERVER_PLATFORM_BUS
420 if ((p
->bus
.type
== BUS_PLATFORM
) && (p
->bus
.id
.plat
->pdev
)) {
421 struct pci_device
*ud
= p
->bus
.id
.plat
->pdev
;
422 if (MATCH_PCI_DEVICES(ud
, d
))
430 #define END_OF_MATCHES(m) \
431 (((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
434 xf86PciAddMatchingDev(DriverPtr drvp
)
436 const struct pci_id_match
*const devices
= drvp
->supported_devices
;
438 struct pci_device
*pPci
;
439 struct pci_device_iterator
*iter
;
442 iter
= pci_id_match_iterator_create(NULL
);
443 while ((pPci
= pci_device_next(iter
)) != NULL
) {
444 /* Determine if this device is supported by the driver. If it is,
445 * add it to the list of devices to configure.
447 for (j
= 0; !END_OF_MATCHES(devices
[j
]); j
++) {
448 if (PCI_ID_COMPARE(devices
[j
].vendor_id
, pPci
->vendor_id
)
449 && PCI_ID_COMPARE(devices
[j
].device_id
, pPci
->device_id
)
450 && ((devices
[j
].device_class_mask
& pPci
->device_class
)
451 == devices
[j
].device_class
)) {
452 if (xf86CheckPciSlot(pPci
)) {
454 xf86AddBusDeviceToConfigure(drvp
->driverName
, BUS_PCI
,
457 /* After configure pass 1, chipID and chipRev are
458 * treated as over-rides, so clobber them here.
472 pci_iterator_destroy(iter
);
474 return numFound
!= 0;
478 xf86PciProbeDev(DriverPtr drvp
)
481 struct pci_device
*pPci
;
482 Bool foundScreen
= FALSE
;
483 const struct pci_id_match
*const devices
= drvp
->supported_devices
;
485 const unsigned numDevs
= xf86MatchDevice(drvp
->driverName
, &devList
);
487 for (i
= 0; i
< numDevs
; i
++) {
488 struct pci_device_iterator
*iter
;
491 /* Find the pciVideoRec associated with this device section.
493 iter
= pci_id_match_iterator_create(NULL
);
494 while ((pPci
= pci_device_next(iter
)) != NULL
) {
495 if (devList
[i
]->busID
&& *devList
[i
]->busID
) {
496 if (xf86ComparePciBusString(devList
[i
]->busID
,
499 pPci
->dev
, pPci
->func
)) {
503 else if (xf86IsPrimaryPci(pPci
)) {
508 pci_iterator_destroy(iter
);
513 device_id
= (devList
[i
]->chipID
> 0)
514 ? devList
[i
]->chipID
: pPci
->device_id
;
516 /* Once the pciVideoRec is found, determine if the device is supported
517 * by the driver. If it is, probe it!
519 for (j
= 0; !END_OF_MATCHES(devices
[j
]); j
++) {
520 if (PCI_ID_COMPARE(devices
[j
].vendor_id
, pPci
->vendor_id
)
521 && PCI_ID_COMPARE(devices
[j
].device_id
, device_id
)
522 && ((devices
[j
].device_class_mask
& pPci
->device_class
)
523 == devices
[j
].device_class
)) {
526 /* Allow the same entity to be used more than once for
527 * devices with multiple screens per entity. This assumes
528 * implicitly that there will be a screen == 0 instance.
530 * FIXME Need to make sure that two different drivers don't
531 * FIXME claim the same screen > 0 instance.
533 if ((devList
[i
]->screen
== 0) && !xf86CheckPciSlot(pPci
))
536 DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
537 drvp
->driverName
, pPci
->bus
, pPci
->dev
, pPci
->func
);
539 /* Allocate an entry in the lists to be returned */
540 entry
= xf86ClaimPciSlot(pPci
, drvp
, device_id
,
541 devList
[i
], devList
[i
]->active
);
543 if ((entry
== -1) && (devList
[i
]->screen
> 0)) {
546 for (k
= 0; k
< xf86NumEntities
; k
++) {
547 EntityPtr pEnt
= xf86Entities
[k
];
549 if (pEnt
->bus
.type
!= BUS_PCI
)
551 if (pEnt
->bus
.id
.pci
== pPci
) {
553 xf86AddDevToEntity(k
, devList
[i
]);
560 if ((*drvp
->PciProbe
) (drvp
, entry
, pPci
,
561 devices
[j
].match_data
)) {
565 xf86UnclaimPciSlot(pPci
, devList
[i
]);
578 xf86PciIsolateDevice(char *argument
)
580 int bus
, device
, func
;
582 if (sscanf(argument
, "PCI:%d:%d:%d", &bus
, &device
, &func
) == 3) {
583 xf86IsolateDevice
.domain
= PCI_DOM_FROM_BUS(bus
);
584 xf86IsolateDevice
.bus
= PCI_BUS_NO_DOMAIN(bus
);
585 xf86IsolateDevice
.dev
= device
;
586 xf86IsolateDevice
.func
= func
;
589 FatalError("Invalid isolated device specification\n");
593 pciDeviceHasBars(struct pci_device
*pci
)
597 for (i
= 0; i
< 6; i
++)
598 if (pci
->regions
[i
].size
)
608 struct pci_device
*pci
;
610 Bool foundHW
; /* PCIid in list of supported chipsets */
611 Bool claimed
; /* BusID matches with a device section */
617 * Find set of unclaimed devices matching a given vendor ID.
619 * Used by drivers to find as yet unclaimed devices matching the specified
622 * \param driverName Name of the driver. This is used to find Device
623 * sections in the config file.
624 * \param vendorID PCI vendor ID of associated devices. If zero, then
625 * the true vendor ID must be encoded in the \c PCIid
626 * fields of the \c PCIchipsets entries.
627 * \param chipsets Symbol table used to associate chipset names with
629 * \param devList List of Device sections parsed from the config file.
630 * \param numDevs Number of entries in \c devList.
631 * \param drvp Pointer the driver's control structure.
632 * \param foundEntities Returned list of entity indicies associated with the
636 * The number of elements in returned in \c foundEntities on success or zero
640 * This function does a bit more than short description says. Fill in some
641 * more of the details of its operation.
644 * The \c driverName parameter is redundant. It is the same as
645 * \c DriverRec::driverName. In a future version of this function, remove
649 xf86MatchPciInstances(const char *driverName
, int vendorID
,
650 SymTabPtr chipsets
, PciChipsets
* PCIchipsets
,
651 GDevPtr
* devList
, int numDevs
, DriverPtr drvp
,
655 struct pci_device
*pPci
;
656 struct pci_device_iterator
*iter
;
657 struct Inst
*instances
= NULL
;
658 int numClaimedInstances
= 0;
659 int allocatedInstances
= 0;
663 int *retEntities
= NULL
;
665 *foundEntities
= NULL
;
667 /* Each PCI device will contribute at least one entry. Each device
668 * section can contribute at most one entry. The sum of the two is
669 * guaranteed to be larger than the maximum possible number of entries.
670 * Do this calculation and memory allocation once now to eliminate the
671 * need for realloc calls inside the loop.
673 if (!(xf86DoConfigure
&& xf86DoConfigurePass1
)) {
674 unsigned max_entries
= numDevs
;
676 iter
= pci_slot_match_iterator_create(NULL
);
677 while ((pPci
= pci_device_next(iter
)) != NULL
) {
681 pci_iterator_destroy(iter
);
682 instances
= xnfalloc(max_entries
* sizeof(struct Inst
));
685 iter
= pci_slot_match_iterator_create(NULL
);
686 while ((pPci
= pci_device_next(iter
)) != NULL
) {
687 unsigned device_class
= pPci
->device_class
;
688 Bool foundVendor
= FALSE
;
690 /* Convert the pre-PCI 2.0 device class for a VGA adapter to the
691 * 2.0 version of the same class.
693 if (device_class
== 0x00000101) {
694 device_class
= 0x00030000;
697 /* Find PCI devices that match the given vendor ID. The vendor ID is
698 * either specified explicitly as a parameter to the function or
699 * implicitly encoded in the high bits of id->PCIid.
701 * The first device with a matching vendor is recorded, even if the
702 * device ID doesn't match. This is done because the Device section
703 * in the xorg.conf file can over-ride the device ID. A matching PCI
704 * ID might not be found now, but after the device ID over-ride is
705 * applied there /might/ be a match.
707 for (id
= PCIchipsets
; id
->PCIid
!= -1; id
++) {
708 const unsigned vendor_id
= ((id
->PCIid
& 0xFFFF0000) >> 16)
710 const unsigned device_id
= (id
->PCIid
& 0x0000FFFF);
711 const unsigned match_class
= 0x00030000 | id
->PCIid
;
713 if ((vendor_id
== pPci
->vendor_id
)
714 || ((vendorID
== PCI_VENDOR_GENERIC
) &&
715 (match_class
== device_class
))) {
716 if (!foundVendor
&& (instances
!= NULL
)) {
717 ++allocatedInstances
;
718 instances
[allocatedInstances
- 1].pci
= pPci
;
719 instances
[allocatedInstances
- 1].dev
= NULL
;
720 instances
[allocatedInstances
- 1].claimed
= FALSE
;
721 instances
[allocatedInstances
- 1].foundHW
= FALSE
;
722 instances
[allocatedInstances
- 1].screen
= 0;
727 if ((device_id
== pPci
->device_id
)
728 || ((vendorID
== PCI_VENDOR_GENERIC
)
729 && (match_class
== device_class
))) {
730 if (instances
!= NULL
) {
731 instances
[allocatedInstances
- 1].foundHW
= TRUE
;
732 instances
[allocatedInstances
- 1].chip
= id
->numChipset
;
735 if (xf86DoConfigure
&& xf86DoConfigurePass1
) {
736 if (xf86CheckPciSlot(pPci
)) {
738 xf86AddBusDeviceToConfigure(drvp
->driverName
,
742 /* After configure pass 1, chipID and chipRev
743 * are treated as over-rides, so clobber them
763 pci_iterator_destroy(iter
);
765 /* In "probe only" or "configure" mode (signaled by instances being NULL),
766 * our work is done. Return the number of detected devices.
768 if (instances
== NULL
) {
773 * This may be debatable, but if no PCI devices with a matching vendor
774 * type is found, return zero now. It is probably not desirable to
775 * allow the config file to override this.
777 if (allocatedInstances
<= 0) {
782 DebugF("%s instances found: %d\n", driverName
, allocatedInstances
);
785 * Check for devices that need duplicated instances. This is required
786 * when there is more than one screen per entity.
788 * XXX This currently doesn't work for cases where the BusID isn't
789 * specified explicitly in the config file.
792 for (j
= 0; j
< numDevs
; j
++) {
793 if (devList
[j
]->screen
> 0 && devList
[j
]->busID
&& *devList
[j
]->busID
) {
794 for (i
= 0; i
< allocatedInstances
; i
++) {
795 pPci
= instances
[i
].pci
;
796 if (xf86ComparePciBusString(devList
[j
]->busID
,
797 PCI_MAKE_BUS(pPci
->domain
,
798 pPci
->bus
), pPci
->dev
,
800 allocatedInstances
++;
801 instances
[allocatedInstances
- 1] = instances
[i
];
802 instances
[allocatedInstances
- 1].screen
=
811 for (i
= 0; i
< allocatedInstances
; i
++) {
813 GDevPtr devBus
= NULL
;
815 pPci
= instances
[i
].pci
;
816 for (j
= 0; j
< numDevs
; j
++) {
817 if (devList
[j
]->busID
&& *devList
[j
]->busID
) {
818 if (xf86ComparePciBusString(devList
[j
]->busID
,
819 PCI_MAKE_BUS(pPci
->domain
,
820 pPci
->bus
), pPci
->dev
,
822 devList
[j
]->screen
== instances
[i
].screen
) {
825 xf86MsgVerb(X_WARNING
, 0,
826 "%s: More than one matching Device section for "
827 "instances\n\t(BusID: %s) found: %s\n",
828 driverName
, devList
[j
]->busID
,
829 devList
[j
]->identifier
);
836 * if device section without BusID is found
837 * only assign to it to the primary device.
839 if (xf86IsPrimaryPci(pPci
)) {
840 xf86Msg(X_PROBED
, "Assigning device section with no busID"
841 " to primary device\n");
843 xf86MsgVerb(X_WARNING
, 0,
844 "%s: More than one matching Device section "
845 "found: %s\n", driverName
,
846 devList
[j
]->identifier
);
853 dev
= devBus
; /* busID preferred */
855 if (xf86CheckPciSlot(pPci
) && pciDeviceHasBars(pPci
)) {
856 xf86MsgVerb(X_WARNING
, 0, "%s: No matching Device section "
857 "for instance (BusID PCI:%u@%u:%u:%u) found\n",
858 driverName
, pPci
->domain
, pPci
->bus
, pPci
->dev
,
863 numClaimedInstances
++;
864 instances
[i
].claimed
= TRUE
;
865 instances
[i
].dev
= dev
;
868 DebugF("%s instances found: %d\n", driverName
, numClaimedInstances
);
870 * Now check that a chipset or chipID override in the device section
871 * is valid. Chipset has precedence over chipID.
872 * If chipset is not valid ignore BusSlot completely.
874 for (i
= 0; i
< allocatedInstances
&& numClaimedInstances
> 0; i
++) {
875 MessageType from
= X_PROBED
;
877 if (!instances
[i
].claimed
) {
880 if (instances
[i
].dev
->chipset
) {
881 for (c
= chipsets
; c
->token
>= 0; c
++) {
882 if (xf86NameCmp(c
->name
, instances
[i
].dev
->chipset
) == 0)
885 if (c
->token
== -1) {
886 instances
[i
].claimed
= FALSE
;
887 numClaimedInstances
--;
888 xf86MsgVerb(X_WARNING
, 0, "%s: Chipset \"%s\" in Device "
889 "section \"%s\" isn't valid for this driver\n",
890 driverName
, instances
[i
].dev
->chipset
,
891 instances
[i
].dev
->identifier
);
894 instances
[i
].chip
= c
->token
;
896 for (id
= PCIchipsets
; id
->numChipset
>= 0; id
++) {
897 if (id
->numChipset
== instances
[i
].chip
)
900 if (id
->numChipset
>= 0) {
901 xf86Msg(X_CONFIG
, "Chipset override: %s\n",
902 instances
[i
].dev
->chipset
);
906 instances
[i
].claimed
= FALSE
;
907 numClaimedInstances
--;
908 xf86MsgVerb(X_WARNING
, 0, "%s: Chipset \"%s\" in Device "
909 "section \"%s\" isn't a valid PCI chipset\n",
910 driverName
, instances
[i
].dev
->chipset
,
911 instances
[i
].dev
->identifier
);
915 else if (instances
[i
].dev
->chipID
> 0) {
916 for (id
= PCIchipsets
; id
->numChipset
>= 0; id
++) {
917 if (id
->PCIid
== instances
[i
].dev
->chipID
)
920 if (id
->numChipset
== -1) {
921 instances
[i
].claimed
= FALSE
;
922 numClaimedInstances
--;
923 xf86MsgVerb(X_WARNING
, 0, "%s: ChipID 0x%04X in Device "
924 "section \"%s\" isn't valid for this driver\n",
925 driverName
, instances
[i
].dev
->chipID
,
926 instances
[i
].dev
->identifier
);
929 instances
[i
].chip
= id
->numChipset
;
931 xf86Msg(X_CONFIG
, "ChipID override: 0x%04X\n",
932 instances
[i
].dev
->chipID
);
936 else if (!instances
[i
].foundHW
) {
938 * This means that there was no override and the PCI chipType
939 * doesn't match one that is supported
941 instances
[i
].claimed
= FALSE
;
942 numClaimedInstances
--;
944 if (instances
[i
].claimed
== TRUE
) {
945 for (c
= chipsets
; c
->token
>= 0; c
++) {
946 if (c
->token
== instances
[i
].chip
)
949 xf86Msg(from
, "Chipset %s found\n", c
->name
);
954 * Of the claimed instances, check that another driver hasn't already
958 for (i
= 0; i
< allocatedInstances
&& numClaimedInstances
> 0; i
++) {
959 if (!instances
[i
].claimed
)
961 pPci
= instances
[i
].pci
;
964 * Allow the same entity to be used more than once for devices with
965 * multiple screens per entity. This assumes implicitly that there
966 * will be a screen == 0 instance.
968 * XXX Need to make sure that two different drivers don't claim
969 * the same screen > 0 instance.
971 if (instances
[i
].screen
== 0 && !xf86CheckPciSlot(pPci
))
974 DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
975 driverName
, pPci
->bus
, pPci
->dev
, pPci
->func
);
977 /* Allocate an entry in the lists to be returned */
979 retEntities
= xnfrealloc(retEntities
, numFound
* sizeof(int));
980 retEntities
[numFound
- 1] = xf86ClaimPciSlot(pPci
, drvp
,
983 instances
[i
].dev
->active
);
984 if (retEntities
[numFound
- 1] == -1 && instances
[i
].screen
> 0) {
985 for (j
= 0; j
< xf86NumEntities
; j
++) {
986 EntityPtr pEnt
= xf86Entities
[j
];
988 if (pEnt
->bus
.type
!= BUS_PCI
)
990 if (pEnt
->bus
.id
.pci
== pPci
) {
991 retEntities
[numFound
- 1] = j
;
992 xf86AddDevToEntity(j
, instances
[i
].dev
);
1000 *foundEntities
= retEntities
;
1007 * xf86ConfigPciEntityInactive() -- This function can be used
1008 * to configure an inactive entity as well as to reconfigure an
1009 * previously active entity inactive. If the entity has been
1010 * assigned to a screen before it will be removed. If p_chip is
1011 * non-NULL all static resources listed there will be registered.
1014 xf86ConfigPciEntityInactive(EntityInfoPtr pEnt
, PciChipsets
* p_chip
,
1015 EntityProc init
, EntityProc enter
,
1016 EntityProc leave
, pointer
private)
1020 if ((pScrn
= xf86FindScreenForEntity(pEnt
->index
)))
1021 xf86RemoveEntityFromScreen(pScrn
, pEnt
->index
);
1023 /* shared resources are only needed when entity is active: remove */
1024 xf86SetEntityFuncs(pEnt
->index
, init
, enter
, leave
, private);
1028 xf86ConfigPciEntity(ScrnInfoPtr pScrn
, int scrnFlag
, int entityIndex
,
1029 PciChipsets
* p_chip
, void *dummy
, EntityProc init
,
1030 EntityProc enter
, EntityProc leave
, pointer
private)
1032 EntityInfoPtr pEnt
= xf86GetEntityInfo(entityIndex
);
1037 if (!(pEnt
->location
.type
== BUS_PCI
)
1038 || !xf86GetPciInfoForEntity(entityIndex
)) {
1042 if (!pEnt
->active
) {
1043 xf86ConfigPciEntityInactive(pEnt
, p_chip
, init
, enter
, leave
, private);
1049 pScrn
= xf86AllocateScreen(pEnt
->driver
, scrnFlag
);
1050 if (xf86IsEntitySharable(entityIndex
)) {
1051 xf86SetEntityShared(entityIndex
);
1053 xf86AddEntityToScreen(pScrn
, entityIndex
);
1054 if (xf86IsEntityShared(entityIndex
)) {
1059 xf86SetEntityFuncs(entityIndex
, init
, enter
, leave
, private);
1065 * OBSOLETE ! xf86ConfigActivePciEntity() is an obsolete function.
1066 * It is likely to be removed. Don't use!
1069 xf86ConfigActivePciEntity(ScrnInfoPtr pScrn
, int entityIndex
,
1070 PciChipsets
* p_chip
, void *dummy
, EntityProc init
,
1071 EntityProc enter
, EntityProc leave
, pointer
private)
1073 EntityInfoPtr pEnt
= xf86GetEntityInfo(entityIndex
);
1078 if (!pEnt
->active
|| !(pEnt
->location
.type
== BUS_PCI
)) {
1082 xf86AddEntityToScreen(pScrn
, entityIndex
);
1085 if (!xf86SetEntityFuncs(entityIndex
, init
, enter
, leave
, private))
1092 xf86VideoPtrToDriverList(struct pci_device
*dev
,
1093 char *returnList
[], int returnListMax
)
1097 /* Add more entries here if we ever return more than 4 drivers for
1099 const char *driverList
[5] = { NULL
, NULL
, NULL
, NULL
, NULL
};
1101 switch (dev
->vendor_id
) {
1104 if (dev
->device_id
== 0x2081)
1105 driverList
[0] = "geode";
1107 /* older Geode products acquired by AMD still carry an NSC vendor_id */
1109 if (dev
->device_id
== 0x0030) {
1110 /* NSC Geode GX2 specifically */
1111 driverList
[0] = "geode";
1112 /* GX2 support started its life in the NSC tree and was later
1113 forked by AMD for GEODE so we keep it as a backup */
1114 driverList
[1] = "nsc";
1117 /* other NSC variant e.g. 0x0104 (SC1400), 0x0504 (SCx200) */
1118 driverList
[0] = "nsc";
1120 /* Cyrix Geode GX1 */
1122 if (dev
->device_id
== 0x0104)
1123 driverList
[0] = "cyrix";
1126 driverList
[0] = "apm";
1129 driverList
[0] = "ark";
1132 driverList
[0] = "ast";
1135 driverList
[0] = "ati";
1138 driverList
[0] = "chips";
1141 driverList
[0] = "cirrus";
1144 driverList
[0] = "glint";
1147 driverList
[0] = "i128";
1150 switch (dev
->device_id
)
1155 driverList
[0] = "i740";
1157 /* GMA500/Poulsbo */
1160 /* Try psb driver on Poulsbo - if available */
1161 driverList
[0] = "psb";
1162 driverList
[1] = "psb_drv";
1164 /* GMA600/Oaktrail */
1173 /* Atom E620/Oaktrail */
1201 /* Use fbdev/vesa driver on Oaktrail, Medfield, CDV */
1204 driverList
[0] = "intel";
1209 driverList
[0] = "mga";
1212 driverList
[0] = "neomagic";
1220 driverList
[idx
++] = "nouveau";
1222 driverList
[idx
++] = "nv";
1226 driverList
[0] = "openchrome";
1229 driverList
[0] = "qxl";
1232 driverList
[0] = "rendition";
1235 switch (dev
->device_id
) {
1243 driverList
[0] = "s3";
1253 driverList
[0] = "s3virge";
1256 driverList
[0] = "savage";
1261 driverList
[0] = "sis";
1264 driverList
[0] = "siliconmotion";
1267 if (dev
->device_id
< 0x0003)
1268 driverList
[0] = "voodoo";
1270 driverList
[0] = "tdfx";
1273 driverList
[0] = "tga";
1276 driverList
[0] = "trident";
1279 driverList
[0] = "tseng";
1282 driverList
[0] = "vboxvideo";
1285 driverList
[0] = "vmware";
1288 if (dev
->device_id
== 0x47)
1289 driverList
[0] = "xgixp";
1291 driverList
[0] = "xgi";
1296 for (i
= 0; (i
< returnListMax
) && (driverList
[i
] != NULL
); i
++) {
1297 returnList
[i
] = xnfstrdup(driverList
[i
]);
1299 return i
; /* Number of entries added */
1313 if (line
[len
- 1] == '\n' && len
> 0) {
1314 line
[len
- 1] = '\0';
1319 /* This function is used to provide a workaround for binary drivers that
1320 * don't export their PCI ID's properly. If distros don't end up using this
1321 * feature it can and should be removed because the symbol-based resolution
1322 * scheme should be the primary one */
1324 xf86MatchDriverFromFiles(char **matches
, uint16_t match_vendor
, uint16_t match_chip
)
1328 struct dirent
*direntry
;
1332 char path_name
[256], vendor_str
[5], chip_str
[5];
1333 uint16_t vendor
, chip
;
1336 idsdir
= opendir(PCI_TXT_IDS_PATH
);
1341 "Scanning %s directory for additional PCI ID's supported by the drivers\n",
1343 direntry
= readdir(idsdir
);
1344 /* Read the directory */
1346 if (direntry
->d_name
[0] == '.') {
1347 direntry
= readdir(idsdir
);
1350 len
= strlen(direntry
->d_name
);
1351 /* A tiny bit of sanity checking. We should probably do better */
1352 if (strncmp(&(direntry
->d_name
[len
- 4]), ".ids", 4) == 0) {
1353 /* We need the full path name to open the file */
1354 snprintf(path_name
, sizeof(path_name
), "%s/%s",
1355 PCI_TXT_IDS_PATH
, direntry
->d_name
);
1356 fp
= fopen(path_name
, "r");
1358 xf86Msg(X_ERROR
, "Could not open %s for reading. Exiting.\n",
1364 while ((read
= getline(&line
, &len
, fp
)) != -1) {
1366 while ((line
= fgetln(fp
, &len
)) != (char *) NULL
) {
1367 #endif /* __GLIBC __ */
1369 if (isdigit(line
[0])) {
1370 strlcpy(vendor_str
, line
, sizeof(vendor_str
));
1371 vendor
= (int) strtol(vendor_str
, NULL
, 16);
1372 if ((strlen(&line
[4])) == 0) {
1377 /* Handle trailing whitespace */
1378 if (isspace(line
[4])) {
1383 /* Ok, it's a real ID */
1384 strlcpy(chip_str
, &line
[4], sizeof(chip_str
));
1385 chip
= (int) strtol(chip_str
, NULL
, 16);
1388 if (vendor
== match_vendor
&& chip
== match_chip
) {
1390 while (matches
[i
]) {
1394 (char *) malloc(sizeof(char) *
1395 strlen(direntry
->d_name
) - 3);
1398 "Could not allocate space for the module name. Exiting.\n");
1401 /* hack off the .ids suffix. This should guard
1402 * against other problems, but it will end up
1403 * taking off anything after the first '.' */
1404 for (j
= 0; j
< (strlen(direntry
->d_name
) - 3); j
++) {
1405 if (direntry
->d_name
[j
] == '.') {
1406 matches
[i
][j
] = '\0';
1410 matches
[i
][j
] = direntry
->d_name
[j
];
1413 xf86Msg(X_INFO
, "Matched %s from file name %s\n",
1414 matches
[i
], direntry
->d_name
);
1418 /* TODO Handle driver overrides here */
1423 direntry
= readdir(idsdir
);
1429 #endif /* __linux__ */
1432 * @return The numbers of found devices that match with the current system
1436 xf86PciMatchDriver(char *matches
[], int nmatches
)
1439 struct pci_device
*info
= NULL
;
1440 struct pci_device_iterator
*iter
;
1442 /* Find the primary device, and get some information about it. */
1443 iter
= pci_slot_match_iterator_create(NULL
);
1444 while ((info
= pci_device_next(iter
)) != NULL
) {
1445 if (xf86IsPrimaryPci(info
)) {
1450 pci_iterator_destroy(iter
);
1453 xf86MatchDriverFromFiles(matches
, info
->vendor_id
, info
->device_id
);
1456 for (i
= 0; (i
< nmatches
) && (matches
[i
]); i
++) {
1457 /* find end of matches list */
1460 if ((info
!= NULL
) && (i
< nmatches
)) {
1461 i
+= xf86VideoPtrToDriverList(info
, &(matches
[i
]), nmatches
- i
);
1468 xf86PciConfigure(void *busData
, struct pci_device
*pDev
)
1470 struct pci_device
*pVideo
= NULL
;
1472 pVideo
= (struct pci_device
*) busData
;
1474 (pDev
->domain
== pVideo
->domain
) &&
1475 (pDev
->bus
== pVideo
->bus
) &&
1476 (pDev
->dev
== pVideo
->dev
) && (pDev
->func
== pVideo
->func
))
1483 xf86PciConfigureNewDev(void *busData
, struct pci_device
*pVideo
,
1484 GDevRec
* GDev
, int *chipset
)
1488 pVideo
= (struct pci_device
*) busData
;
1490 if (pVideo
->bus
< 256)
1491 snprintf(busnum
, sizeof(busnum
), "%d", pVideo
->bus
);
1493 snprintf(busnum
, sizeof(busnum
), "%d@%d",
1494 pVideo
->bus
& 0x00ff, pVideo
->bus
>> 8);
1496 XNFasprintf(&GDev
->busID
, "PCI:%s:%d:%d",
1497 busnum
, pVideo
->dev
, pVideo
->func
);
1499 GDev
->chipID
= pVideo
->device_id
;
1500 GDev
->chipRev
= pVideo
->revision
;
1503 *chipset
= (pVideo
->vendor_id
<< 16) | pVideo
->device_id
;
1506 struct pci_io_handle
*
1507 xf86MapLegacyIO(struct pci_device
*dev
)
1509 return pci_legacy_open_io(dev
, 0, 64 * 1024);
1513 xf86UnmapLegacyIO(struct pci_device
*dev
, struct pci_io_handle
*handle
)
1515 pci_device_close_io(dev
, handle
);