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
32 #ifdef HAVE_XORG_CONFIG_H
33 #include <xorg-config.h>
44 /* Bus-specific headers */
49 #include "xf86_OSproc.h"
50 #ifdef XSERVER_LIBPCIACCESS
51 #include "xf86VGAarbiter.h"
54 EntityPtr
*xf86Entities
= NULL
; /* Bus slots claimed by drivers */
55 int xf86NumEntities
= 0;
56 static int xf86EntityPrivateCount
= 0;
58 BusRec primaryBus
= { BUS_NONE
, {0} };
61 * Call the driver's correct probe function.
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.
69 * \param drv Driver to probe
72 * If a device can be successfully probed by the driver, \c TRUE is
73 * returned. Otherwise, \c FALSE is returned.
76 xf86CallDriverProbe(DriverPtr drv
, Bool detect_only
)
78 Bool foundScreen
= FALSE
;
80 #ifdef XSERVER_PLATFORM_BUS
81 if (drv
->platformProbe
!= NULL
) {
82 foundScreen
= xf86platformProbeDev(drv
);
84 if (ServerIsNotSeat0())
88 #ifdef XSERVER_LIBPCIACCESS
89 if (!foundScreen
&& (drv
->PciProbe
!= NULL
)) {
90 if (xf86DoConfigure
&& xf86DoConfigurePass1
) {
92 foundScreen
= xf86PciAddMatchingDev(drv
);
96 foundScreen
= xf86PciProbeDev(drv
);
100 if (!foundScreen
&& (drv
->Probe
!= NULL
)) {
101 xf86Msg(X_WARNING
, "Falling back to old probe method for %s\n",
103 foundScreen
= (*drv
->Probe
) (drv
, (detect_only
) ? PROBE_DETECT
111 * @return TRUE if all buses are configured and set up correctly and FALSE
117 screenLayoutPtr layout
;
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.
125 for (i
= 0; i
< xf86NumDrivers
; i
++) {
126 xf86CallDriverProbe(xf86DriverList
[i
], FALSE
);
129 /* If nothing was detected, return now */
130 if (xf86NumScreens
== 0) {
131 xf86Msg(X_ERROR
, "No devices detected.\n");
135 xf86VGAarbiterInit();
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.
142 * What is the best way to do this?
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.
149 for (i
= 0; i
< xf86NumScreens
; i
++) {
150 for (layout
= xf86ConfigLayout
.screens
; layout
->screen
!= NULL
;
154 for (j
= 0; j
< xf86Screens
[i
]->numEntities
; j
++) {
157 xf86GetDevFromEntity(xf86Screens
[i
]->entityList
[j
],
158 xf86Screens
[i
]->entityInstanceList
[j
]);
160 if (dev
== layout
->screen
->device
) {
161 /* A match has been found */
162 xf86Screens
[i
]->confScreen
= layout
->screen
;
170 if (layout
->screen
== NULL
) {
173 "Screen %d deleted because of no matching config section.\n",
175 xf86DeleteScreen(xf86Screens
[i
--]);
179 /* bind GPU conf screen to protocol screen 0 */
180 for (i
= 0; i
< xf86NumGPUScreens
; i
++)
181 xf86GPUScreens
[i
]->confScreen
= xf86Screens
[0]->confScreen
;
183 /* If no screens left, return now. */
184 if (xf86NumScreens
== 0) {
186 "Device(s) detected, but none match those in the config file.\n");
194 * Call the bus probes relevant to the architecture.
196 * The only one available so far is for PCI and SBUS.
202 #ifdef XSERVER_PLATFORM_BUS
204 if (ServerIsNotSeat0())
207 #ifdef XSERVER_LIBPCIACCESS
210 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
216 * Determine what bus type the busID string represents. The start of the
217 * bus-dependent part of the string is returned as retID.
221 StringToBusType(const char *busID
, const char **retID
)
224 BusType ret
= BUS_NONE
;
226 /* If no type field, Default to PCI */
227 if (isdigit(busID
[0])) {
235 if (p
== NULL
|| *p
== 0) {
239 if (!xf86NameCmp(p
, "pci") || !xf86NameCmp(p
, "agp"))
241 if (!xf86NameCmp(p
, "sbus"))
243 if (!xf86NameCmp(p
, "platform"))
247 *retID
= busID
+ strlen(p
) + 1;
253 xf86AllocateEntity(void)
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;
265 xf86IsEntityPrimary(int entityIndex
)
267 EntityPtr pEnt
= xf86Entities
[entityIndex
];
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
);
274 if (primaryBus
.type
!= pEnt
->bus
.type
)
277 switch (pEnt
->bus
.type
) {
279 return pEnt
->bus
.id
.pci
== primaryBus
.id
.pci
;
281 return pEnt
->bus
.id
.sbus
.fbNum
== primaryBus
.id
.sbus
.fbNum
;
283 return pEnt
->bus
.id
.plat
== primaryBus
.id
.plat
;
290 xf86SetEntityFuncs(int entityIndex
, EntityProc init
, EntityProc enter
,
291 EntityProc leave
, pointer
private)
293 if (entityIndex
>= xf86NumEntities
)
295 xf86Entities
[entityIndex
]->entityInit
= init
;
296 xf86Entities
[entityIndex
]->entityEnter
= enter
;
297 xf86Entities
[entityIndex
]->entityLeave
= leave
;
298 xf86Entities
[entityIndex
]->private = private;
303 xf86DriverHasEntities(DriverPtr drvp
)
307 for (i
= 0; i
< xf86NumEntities
; i
++) {
308 if (xf86Entities
[i
]->driver
== drvp
)
315 xf86AddEntityToScreen(ScrnInfoPtr pScrn
, int entityIndex
)
317 if (entityIndex
== -1)
319 if (xf86Entities
[entityIndex
]->inUse
&&
320 !(xf86Entities
[entityIndex
]->entityProp
& IS_SHARED_ACCEL
)) {
321 ErrorF("Requested Entity already in use!\n");
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;
336 xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn
, int entityIndex
, int instance
)
340 if (entityIndex
== -1 || entityIndex
>= xf86NumEntities
)
343 for (i
= 0; i
< pScrn
->numEntities
; i
++) {
344 if (pScrn
->entityList
[i
] == entityIndex
) {
345 pScrn
->entityInstanceList
[i
] = instance
;
352 * XXX This needs to be updated for the case where a single entity may have
353 * instances associated with more than one screen.
356 xf86FindScreenForEntity(int entityIndex
)
360 if (entityIndex
== -1)
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
];
375 xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn
, int entityIndex
)
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
;
391 * xf86ClearEntityListForScreen() - called when a screen is deleted
392 * to mark it's entities unused. Called by xf86DeleteScreen().
395 xf86ClearEntityListForScreen(ScrnInfoPtr pScrn
)
399 if (pScrn
->entityList
== NULL
|| pScrn
->numEntities
== 0)
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 */
407 free(pScrn
->entityList
);
408 free(pScrn
->entityInstanceList
);
409 pScrn
->entityList
= NULL
;
410 pScrn
->entityInstanceList
= NULL
;
414 * Add an extra device section (GDevPtr) to an entity.
418 xf86AddDevToEntity(int entityIndex
, GDevPtr dev
)
422 if (entityIndex
>= xf86NumEntities
)
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
;
435 xf86RemoveDevFromEntity(int entityIndex
, GDevPtr dev
)
439 if (entityIndex
>= xf86NumEntities
)
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];
450 pEnt
->numInstances
--;
451 dev
->claimed
= FALSE
;
454 * xf86GetEntityInfo() -- This function hands information from the
455 * EntityRec struct to the drivers. The EntityRec structure itself
456 * remains invisible to the driver.
459 xf86GetEntityInfo(int entityIndex
)
464 if (entityIndex
== -1)
467 if (entityIndex
>= xf86NumEntities
)
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)
481 pEnt
->device
= xf86Entities
[entityIndex
]->devices
[i
];
490 xf86GetNumEntityInstances(int entityIndex
)
492 if (entityIndex
>= xf86NumEntities
)
495 return xf86Entities
[entityIndex
]->numInstances
;
499 xf86GetDevFromEntity(int entityIndex
, int instance
)
503 /* We might not use AddDevtoEntity */
504 if ((!xf86Entities
[entityIndex
]->devices
) ||
505 (!xf86Entities
[entityIndex
]->devices
[0]))
508 if (entityIndex
>= xf86NumEntities
||
509 instance
>= xf86Entities
[entityIndex
]->numInstances
)
512 for (i
= 0; i
< xf86Entities
[entityIndex
]->numInstances
; i
++)
513 if (xf86Entities
[entityIndex
]->devices
[i
]->screen
== instance
)
515 return xf86Entities
[entityIndex
]->devices
[i
];
519 * xf86AccessEnter() -- gets called to save the text mode VGA IO
520 * resources when reentering the server after a VT switch.
523 xf86AccessEnter(void)
527 for (i
= 0; i
< xf86NumEntities
; i
++)
528 if (xf86Entities
[i
]->entityEnter
)
529 xf86Entities
[i
]->entityEnter(i
, xf86Entities
[i
]->private);
533 xf86AccessLeave(void)
537 for (i
= 0; i
< xf86NumEntities
; i
++)
538 if (xf86Entities
[i
]->entityLeave
)
539 xf86Entities
[i
]->entityLeave(i
, xf86Entities
[i
]->private);
543 * xf86PostProbe() -- Allocate all non conflicting resources
544 * This function gets called by xf86Init().
551 if (fbSlotClaimed
&& (
552 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
555 #ifdef XSERVER_PLATFORM_BUS
556 platformSlotClaimed
||
558 #ifdef XSERVER_LIBPCIACCESS
564 FatalError("Cannot run in framebuffer mode. Please specify busIDs "
565 " for all framebuffer devices\n");
567 for (i
= 0; i
< xf86NumEntities
; i
++)
568 if (xf86Entities
[i
]->entityInit
)
569 xf86Entities
[i
]->entityInit(i
, xf86Entities
[i
]->private);
573 xf86GetLastScrnFlag(int entityIndex
)
575 if (entityIndex
< xf86NumEntities
) {
576 return xf86Entities
[entityIndex
]->lastScrnFlag
;
584 xf86SetLastScrnFlag(int entityIndex
, int scrnIndex
)
586 if (entityIndex
< xf86NumEntities
) {
587 xf86Entities
[entityIndex
]->lastScrnFlag
= scrnIndex
;
592 xf86IsEntityShared(int entityIndex
)
594 if (entityIndex
< xf86NumEntities
) {
595 if (xf86Entities
[entityIndex
]->entityProp
& IS_SHARED_ACCEL
) {
603 xf86SetEntityShared(int entityIndex
)
605 if (entityIndex
< xf86NumEntities
) {
606 xf86Entities
[entityIndex
]->entityProp
|= IS_SHARED_ACCEL
;
611 xf86IsEntitySharable(int entityIndex
)
613 if (entityIndex
< xf86NumEntities
) {
614 if (xf86Entities
[entityIndex
]->entityProp
& ACCEL_IS_SHARABLE
) {
622 xf86SetEntitySharable(int entityIndex
)
624 if (entityIndex
< xf86NumEntities
) {
625 xf86Entities
[entityIndex
]->entityProp
|= ACCEL_IS_SHARABLE
;
630 xf86IsPrimInitDone(int entityIndex
)
632 if (entityIndex
< xf86NumEntities
) {
633 if (xf86Entities
[entityIndex
]->entityProp
& SA_PRIM_INIT_DONE
) {
641 xf86SetPrimInitDone(int entityIndex
)
643 if (entityIndex
< xf86NumEntities
) {
644 xf86Entities
[entityIndex
]->entityProp
|= SA_PRIM_INIT_DONE
;
649 xf86ClearPrimInitDone(int entityIndex
)
651 if (entityIndex
< xf86NumEntities
) {
652 xf86Entities
[entityIndex
]->entityProp
&= ~SA_PRIM_INIT_DONE
;
657 * Allocate a private in the entities.
661 xf86AllocateEntityPrivateIndex(void)
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
;
680 xf86GetEntityPrivate(int entityIndex
, int privIndex
)
682 if (entityIndex
>= xf86NumEntities
|| privIndex
>= xf86EntityPrivateCount
)
685 return &(xf86Entities
[entityIndex
]->entityPrivates
[privIndex
]);