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