xf86Bus.c revision 65b04b38
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 32#ifdef HAVE_XORG_CONFIG_H 33#include <xorg-config.h> 34#endif 35 36#include <ctype.h> 37#include <stdlib.h> 38#include <unistd.h> 39#include <X11/X.h> 40#include "os.h" 41#include "xf86.h" 42#include "xf86Priv.h" 43 44/* Bus-specific headers */ 45 46#include "xf86Bus.h" 47 48#define XF86_OS_PRIVS 49#include "xf86_OSproc.h" 50#include "xf86VGAarbiter.h" 51 52/* Entity data */ 53EntityPtr *xf86Entities = NULL; /* Bus slots claimed by drivers */ 54int xf86NumEntities = 0; 55static int xf86EntityPrivateCount = 0; 56 57BusRec primaryBus = { BUS_NONE, { 0 } }; 58 59/** 60 * Call the driver's correct probe function. 61 * 62 * If the driver implements the \c DriverRec::PciProbe entry-point and an 63 * appropriate PCI device (with matching Device section in the xorg.conf file) 64 * is found, it is called. If \c DriverRec::PciProbe or no devices can be 65 * successfully probed with it (e.g., only non-PCI devices are available), 66 * the driver's \c DriverRec::Probe function is called. 67 * 68 * \param drv Driver to probe 69 * 70 * \return 71 * If a device can be successfully probed by the driver, \c TRUE is 72 * returned. Otherwise, \c FALSE is returned. 73 */ 74Bool 75xf86CallDriverProbe( DriverPtr drv, Bool detect_only ) 76{ 77 Bool foundScreen = FALSE; 78 79 if (drv->PciProbe != NULL) { 80 if (xf86DoConfigure && xf86DoConfigurePass1) { 81 assert(detect_only); 82 foundScreen = xf86PciAddMatchingDev(drv); 83 } 84 else { 85 assert(! detect_only); 86 foundScreen = xf86PciProbeDev(drv); 87 } 88 } 89 90 if (!foundScreen && (drv->Probe != NULL)) { 91 xf86Msg( X_WARNING, "Falling back to old probe method for %s\n", 92 drv->driverName); 93 foundScreen = (*drv->Probe)(drv, (detect_only) ? PROBE_DETECT 94 : PROBE_DEFAULT); 95 } 96 97 return foundScreen; 98} 99 100/** 101 * @return TRUE if all buses are configured and set up correctly and FALSE 102 * otherwise. 103 */ 104Bool 105xf86BusConfig(void) 106{ 107 screenLayoutPtr layout; 108 int i, j; 109 110 /* Enable full I/O access */ 111 if (xorgHWAccess) 112 xorgHWAccess = xf86EnableIO(); 113 114 /* 115 * Now call each of the Probe functions. Each successful probe will 116 * result in an extra entry added to the xf86Screens[] list for each 117 * instance of the hardware found. 118 */ 119 for (i = 0; i < xf86NumDrivers; i++) { 120 xorgHWFlags flags; 121 if (!xorgHWAccess) { 122 if (!xf86DriverList[i]->driverFunc 123 || !xf86DriverList[i]->driverFunc(NULL, 124 GET_REQUIRED_HW_INTERFACES, 125 &flags) 126 || NEED_IO_ENABLED(flags)) 127 continue; 128 } 129 130 xf86CallDriverProbe(xf86DriverList[i], FALSE); 131 } 132 133 /* If nothing was detected, return now */ 134 if (xf86NumScreens == 0) { 135 xf86Msg(X_ERROR, "No devices detected.\n"); 136 return FALSE; 137 } 138 139 xf86VGAarbiterInit(); 140 141 /* 142 * Match up the screens found by the probes against those specified 143 * in the config file. Remove the ones that won't be used. Sort 144 * them in the order specified. 145 * 146 * What is the best way to do this? 147 * 148 * For now, go through the screens allocated by the probes, and 149 * look for screen config entry which refers to the same device 150 * section as picked out by the probe. 151 * 152 */ 153 for (i = 0; i < xf86NumScreens; i++) { 154 for (layout = xf86ConfigLayout.screens; layout->screen != NULL; 155 layout++) { 156 Bool found = FALSE; 157 for (j = 0; j < xf86Screens[i]->numEntities; j++) { 158 159 GDevPtr dev = xf86GetDevFromEntity( 160 xf86Screens[i]->entityList[j], 161 xf86Screens[i]->entityInstanceList[j]); 162 if (dev == layout->screen->device) { 163 /* A match has been found */ 164 xf86Screens[i]->confScreen = layout->screen; 165 found = TRUE; 166 break; 167 } 168 } 169 if (found) break; 170 } 171 if (layout->screen == NULL) { 172 /* No match found */ 173 xf86Msg(X_ERROR, 174 "Screen %d deleted because of no matching config section.\n", i); 175 xf86DeleteScreen(i--, 0); 176 } 177 } 178 179 /* If no screens left, return now. */ 180 if (xf86NumScreens == 0) { 181 xf86Msg(X_ERROR, 182 "Device(s) detected, but none match those in the config file.\n"); 183 return FALSE; 184 } 185 186 return TRUE; 187} 188 189/* 190 * Call the bus probes relevant to the architecture. 191 * 192 * The only one available so far is for PCI and SBUS. 193 */ 194 195void 196xf86BusProbe(void) 197{ 198 xf86PciProbe(); 199#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 200 xf86SbusProbe(); 201#endif 202} 203 204/* 205 * Determine what bus type the busID string represents. The start of the 206 * bus-dependent part of the string is returned as retID. 207 */ 208 209BusType 210StringToBusType(const char* busID, const char **retID) 211{ 212 char *p, *s; 213 BusType ret = BUS_NONE; 214 215 /* If no type field, Default to PCI */ 216 if (isdigit(busID[0])) { 217 if (retID) 218 *retID = busID; 219 return BUS_PCI; 220 } 221 222 s = xstrdup(busID); 223 p = strtok(s, ":"); 224 if (p == NULL || *p == 0) { 225 free(s); 226 return BUS_NONE; 227 } 228 if (!xf86NameCmp(p, "pci") || !xf86NameCmp(p, "agp")) 229 ret = BUS_PCI; 230 if (!xf86NameCmp(p, "sbus")) 231 ret = BUS_SBUS; 232 if (ret != BUS_NONE) 233 if (retID) 234 *retID = busID + strlen(p) + 1; 235 free(s); 236 return ret; 237} 238 239int 240xf86AllocateEntity(void) 241{ 242 xf86NumEntities++; 243 xf86Entities = xnfrealloc(xf86Entities, 244 sizeof(EntityPtr) * xf86NumEntities); 245 xf86Entities[xf86NumEntities - 1] = xnfcalloc(1,sizeof(EntityRec)); 246 xf86Entities[xf86NumEntities - 1]->entityPrivates = 247 xnfcalloc(sizeof(DevUnion) * xf86EntityPrivateCount, 1); 248 return xf86NumEntities - 1; 249} 250 251Bool 252xf86IsEntityPrimary(int entityIndex) 253{ 254 EntityPtr pEnt = xf86Entities[entityIndex]; 255 256 if (primaryBus.type != pEnt->bus.type) return FALSE; 257 258 switch (pEnt->bus.type) { 259 case BUS_PCI: 260 return pEnt->bus.id.pci == primaryBus.id.pci; 261 case BUS_SBUS: 262 return pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum; 263 default: 264 return FALSE; 265 } 266} 267 268Bool 269xf86SetEntityFuncs(int entityIndex, EntityProc init, EntityProc enter, 270 EntityProc leave, pointer private) 271{ 272 if (entityIndex >= xf86NumEntities) 273 return FALSE; 274 xf86Entities[entityIndex]->entityInit = init; 275 xf86Entities[entityIndex]->entityEnter = enter; 276 xf86Entities[entityIndex]->entityLeave = leave; 277 xf86Entities[entityIndex]->private = private; 278 return TRUE; 279} 280 281Bool 282xf86DriverHasEntities(DriverPtr drvp) 283{ 284 int i; 285 for (i = 0; i < xf86NumEntities; i++) { 286 if (xf86Entities[i]->driver == drvp) 287 return TRUE; 288 } 289 return FALSE; 290} 291 292void 293xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex) 294{ 295 if (entityIndex == -1) 296 return; 297 if (xf86Entities[entityIndex]->inUse && 298 !(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL)) { 299 ErrorF("Requested Entity already in use!\n"); 300 return; 301 } 302 303 pScrn->numEntities++; 304 pScrn->entityList = xnfrealloc(pScrn->entityList, 305 pScrn->numEntities * sizeof(int)); 306 pScrn->entityList[pScrn->numEntities - 1] = entityIndex; 307 xf86Entities[entityIndex]->inUse = TRUE; 308 pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList, 309 pScrn->numEntities * sizeof(int)); 310 pScrn->entityInstanceList[pScrn->numEntities - 1] = 0; 311 pScrn->domainIOBase = xf86Entities[entityIndex]->domainIO; 312} 313 314void 315xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex, int instance) 316{ 317 int i; 318 319 if (entityIndex == -1 || entityIndex >= xf86NumEntities) 320 return; 321 322 for (i = 0; i < pScrn->numEntities; i++) { 323 if (pScrn->entityList[i] == entityIndex) { 324 pScrn->entityInstanceList[i] = instance; 325 break; 326 } 327 } 328} 329 330/* 331 * XXX This needs to be updated for the case where a single entity may have 332 * instances associated with more than one screen. 333 */ 334ScrnInfoPtr 335xf86FindScreenForEntity(int entityIndex) 336{ 337 int i,j; 338 339 if (entityIndex == -1) return NULL; 340 341 if (xf86Screens) { 342 for (i = 0; i < xf86NumScreens; i++) { 343 for (j = 0; j < xf86Screens[i]->numEntities; j++) { 344 if ( xf86Screens[i]->entityList[j] == entityIndex ) 345 return xf86Screens[i]; 346 } 347 } 348 } 349 return NULL; 350} 351 352void 353xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex) 354{ 355 int i; 356 357 for (i = 0; i < pScrn->numEntities; i++) { 358 if (pScrn->entityList[i] == entityIndex) { 359 for (i++; i < pScrn->numEntities; i++) 360 pScrn->entityList[i-1] = pScrn->entityList[i]; 361 pScrn->numEntities--; 362 xf86Entities[entityIndex]->inUse = FALSE; 363 break; 364 } 365 } 366} 367 368/* 369 * xf86ClearEntitiesForScreen() - called when a screen is deleted 370 * to mark it's entities unused. Called by xf86DeleteScreen(). 371 */ 372void 373xf86ClearEntityListForScreen(int scrnIndex) 374{ 375 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 376 int i, entityIndex; 377 378 if (pScrn->entityList == NULL || pScrn->numEntities == 0) return; 379 380 for (i = 0; i < pScrn->numEntities; i++) { 381 entityIndex = pScrn->entityList[i]; 382 xf86Entities[entityIndex]->inUse = FALSE; 383 /* disable resource: call the disable function */ 384 } 385 free(pScrn->entityList); 386 free(pScrn->entityInstanceList); 387 pScrn->entityList = NULL; 388 pScrn->entityInstanceList = NULL; 389} 390 391/* 392 * Add an extra device section (GDevPtr) to an entity. 393 */ 394 395void 396xf86AddDevToEntity(int entityIndex, GDevPtr dev) 397{ 398 EntityPtr pEnt; 399 400 if (entityIndex >= xf86NumEntities) 401 return; 402 403 pEnt = xf86Entities[entityIndex]; 404 pEnt->numInstances++; 405 pEnt->devices = xnfrealloc(pEnt->devices, 406 pEnt->numInstances * sizeof(GDevPtr)); 407 pEnt->devices[pEnt->numInstances - 1] = dev; 408 dev->claimed = TRUE; 409} 410 411/* 412 * xf86GetEntityInfo() -- This function hands information from the 413 * EntityRec struct to the drivers. The EntityRec structure itself 414 * remains invisible to the driver. 415 */ 416EntityInfoPtr 417xf86GetEntityInfo(int entityIndex) 418{ 419 EntityInfoPtr pEnt; 420 int i; 421 422 if (entityIndex == -1) 423 return NULL; 424 425 if (entityIndex >= xf86NumEntities) 426 return NULL; 427 428 pEnt = xnfcalloc(1,sizeof(EntityInfoRec)); 429 pEnt->index = entityIndex; 430 pEnt->location = xf86Entities[entityIndex]->bus; 431 pEnt->active = xf86Entities[entityIndex]->active; 432 pEnt->chipset = xf86Entities[entityIndex]->chipset; 433 pEnt->driver = xf86Entities[entityIndex]->driver; 434 if ( (xf86Entities[entityIndex]->devices) && 435 (xf86Entities[entityIndex]->devices[0]) ) { 436 for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++) 437 if (xf86Entities[entityIndex]->devices[i]->screen == 0) 438 break; 439 pEnt->device = xf86Entities[entityIndex]->devices[i]; 440 } else 441 pEnt->device = NULL; 442 443 return pEnt; 444} 445 446int 447xf86GetNumEntityInstances(int entityIndex) 448{ 449 if (entityIndex >= xf86NumEntities) 450 return -1; 451 452 return xf86Entities[entityIndex]->numInstances; 453} 454 455GDevPtr 456xf86GetDevFromEntity(int entityIndex, int instance) 457{ 458 int i; 459 460 /* We might not use AddDevtoEntity */ 461 if ( (!xf86Entities[entityIndex]->devices) || 462 (!xf86Entities[entityIndex]->devices[0]) ) 463 return NULL; 464 465 if (entityIndex >= xf86NumEntities || 466 instance >= xf86Entities[entityIndex]->numInstances) 467 return NULL; 468 469 for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++) 470 if (xf86Entities[entityIndex]->devices[i]->screen == instance) 471 break; 472 return xf86Entities[entityIndex]->devices[i]; 473} 474 475/* 476 * xf86AccessEnter() -- gets called to save the text mode VGA IO 477 * resources when reentering the server after a VT switch. 478 */ 479void 480xf86AccessEnter(void) 481{ 482 int i; 483 484 for (i = 0; i < xf86NumEntities; i++) 485 if (xf86Entities[i]->entityEnter) 486 xf86Entities[i]->entityEnter(i,xf86Entities[i]->private); 487} 488 489void 490xf86AccessLeave(void) 491{ 492 int i; 493 494 for (i = 0; i < xf86NumEntities; i++) 495 if (xf86Entities[i]->entityLeave) 496 xf86Entities[i]->entityLeave(i,xf86Entities[i]->private); 497} 498 499/* 500 * xf86PostProbe() -- Allocate all non conflicting resources 501 * This function gets called by xf86Init(). 502 */ 503void 504xf86PostProbe(void) 505{ 506 int i; 507 508 if (fbSlotClaimed && (pciSlotClaimed 509#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 510 || sbusSlotClaimed 511#endif 512 )) 513 FatalError("Cannot run in framebuffer mode. Please specify busIDs " 514 " for all framebuffer devices\n"); 515 516 for (i = 0; i < xf86NumEntities; i++) 517 if (xf86Entities[i]->entityInit) 518 xf86Entities[i]->entityInit(i,xf86Entities[i]->private); 519} 520 521int 522xf86GetLastScrnFlag(int entityIndex) 523{ 524 if(entityIndex < xf86NumEntities) { 525 return xf86Entities[entityIndex]->lastScrnFlag; 526 } else { 527 return -1; 528 } 529} 530 531void 532xf86SetLastScrnFlag(int entityIndex, int scrnIndex) 533{ 534 if(entityIndex < xf86NumEntities) { 535 xf86Entities[entityIndex]->lastScrnFlag = scrnIndex; 536 } 537} 538 539Bool 540xf86IsEntityShared(int entityIndex) 541{ 542 if(entityIndex < xf86NumEntities) { 543 if(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL) { 544 return TRUE; 545 } 546 } 547 return FALSE; 548} 549 550void 551xf86SetEntityShared(int entityIndex) 552{ 553 if(entityIndex < xf86NumEntities) { 554 xf86Entities[entityIndex]->entityProp |= IS_SHARED_ACCEL; 555 } 556} 557 558Bool 559xf86IsEntitySharable(int entityIndex) 560{ 561 if(entityIndex < xf86NumEntities) { 562 if(xf86Entities[entityIndex]->entityProp & ACCEL_IS_SHARABLE) { 563 return TRUE; 564 } 565 } 566 return FALSE; 567} 568 569void 570xf86SetEntitySharable(int entityIndex) 571{ 572 if(entityIndex < xf86NumEntities) { 573 xf86Entities[entityIndex]->entityProp |= ACCEL_IS_SHARABLE; 574 } 575} 576 577Bool 578xf86IsPrimInitDone(int entityIndex) 579{ 580 if(entityIndex < xf86NumEntities) { 581 if(xf86Entities[entityIndex]->entityProp & SA_PRIM_INIT_DONE) { 582 return TRUE; 583 } 584 } 585 return FALSE; 586} 587 588void 589xf86SetPrimInitDone(int entityIndex) 590{ 591 if(entityIndex < xf86NumEntities) { 592 xf86Entities[entityIndex]->entityProp |= SA_PRIM_INIT_DONE; 593 } 594} 595 596void 597xf86ClearPrimInitDone(int entityIndex) 598{ 599 if(entityIndex < xf86NumEntities) { 600 xf86Entities[entityIndex]->entityProp &= ~SA_PRIM_INIT_DONE; 601 } 602} 603 604 605/* 606 * Allocate a private in the entities. 607 */ 608 609int 610xf86AllocateEntityPrivateIndex(void) 611{ 612 int idx, i; 613 EntityPtr pEnt; 614 DevUnion *nprivs; 615 616 idx = xf86EntityPrivateCount++; 617 for (i = 0; i < xf86NumEntities; i++) { 618 pEnt = xf86Entities[i]; 619 nprivs = xnfrealloc(pEnt->entityPrivates, 620 xf86EntityPrivateCount * sizeof(DevUnion)); 621 /* Zero the new private */ 622 memset(&nprivs[idx], 0, sizeof(DevUnion)); 623 pEnt->entityPrivates = nprivs; 624 } 625 return idx; 626} 627 628DevUnion * 629xf86GetEntityPrivate(int entityIndex, int privIndex) 630{ 631 if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount) 632 return NULL; 633 634 return &(xf86Entities[entityIndex]->entityPrivates[privIndex]); 635} 636 637