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