Merge remote-tracking branch 'airlied/for-keithp-stage1'

This commit is contained in:
Keith Packard 2012-07-06 12:17:17 -07:00
commit 4d24192bd2
38 changed files with 1397 additions and 86 deletions

View File

@ -36,6 +36,7 @@ BOOL device_is_duplicate(const char *config_info);
int config_udev_pre_init(void);
int config_udev_init(void);
void config_udev_fini(void);
void config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback);
#else
#ifdef CONFIG_NEED_DBUS

View File

@ -85,6 +85,14 @@ config_fini(void)
#endif
}
void
config_odev_probe(config_odev_probe_proc_ptr probe_callback)
{
#if defined(CONFIG_UDEV_KMS)
config_udev_odev_probe(probe_callback);
#endif
}
static void
remove_device(const char *backend, DeviceIntPtr dev)
{
@ -133,3 +141,51 @@ device_is_duplicate(const char *config_info)
return FALSE;
}
struct OdevAttributes *
config_odev_allocate_attribute_list(void)
{
struct OdevAttributes *attriblist;
attriblist = malloc(sizeof(struct OdevAttributes));
if (!attriblist)
return NULL;
xorg_list_init(&attriblist->list);
return attriblist;
}
void
config_odev_free_attribute_list(struct OdevAttributes *attribs)
{
config_odev_free_attributes(attribs);
free(attribs);
}
Bool
config_odev_add_attribute(struct OdevAttributes *attribs, int attrib,
const char *attrib_name)
{
struct OdevAttribute *oa;
oa = malloc(sizeof(struct OdevAttribute));
if (!oa)
return FALSE;
oa->attrib_id = attrib;
oa->attrib_name = strdup(attrib_name);
xorg_list_append(&oa->member, &attribs->list);
return TRUE;
}
void
config_odev_free_attributes(struct OdevAttributes *attribs)
{
struct OdevAttribute *iter, *safe;
xorg_list_for_each_entry_safe(iter, safe, &attribs->list, member) {
xorg_list_del(&iter->member);
free(iter->attrib_name);
free(iter);
}
}

View File

@ -52,6 +52,12 @@
static struct udev_monitor *udev_monitor;
#ifdef CONFIG_UDEV_KMS
static Bool
config_udev_odev_setup_attribs(const char *path, const char *syspath,
config_odev_probe_proc_ptr probe_callback);
#endif
static void
device_added(struct udev_device *udev_device)
{
@ -85,6 +91,20 @@ device_added(struct udev_device *udev_device)
if (!SeatId && strcmp(dev_seat, "seat0"))
return;
#ifdef CONFIG_UDEV_KMS
if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) {
const char *sysname = udev_device_get_sysname(udev_device);
if (strncmp(sysname, "card", 4) != 0)
return;
LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
config_udev_odev_setup_attribs(path, syspath, NewGPUDeviceRequest);
return;
}
#endif
if (!udev_device_get_property_value(udev_device, "ID_INPUT")) {
LogMessageVerb(X_INFO, 10,
"config/udev: ignoring device %s without "
@ -240,6 +260,22 @@ device_removed(struct udev_device *device)
char *value;
const char *syspath = udev_device_get_syspath(device);
#ifdef CONFIG_UDEV_KMS
if (!strcmp(udev_device_get_subsystem(device), "drm")) {
const char *sysname = udev_device_get_sysname(device);
const char *path = udev_device_get_devnode(device);
if (strncmp(sysname,"card", 4) != 0)
return;
ErrorF("removing GPU device %s %d\n", syspath, path);
if (!path)
return;
config_udev_odev_setup_attribs(path, syspath, DeleteGPUDeviceRequest);
return;
}
#endif
if (asprintf(&value, "udev:%s", syspath) == -1)
return;
@ -296,6 +332,9 @@ config_udev_pre_init(void)
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input",
NULL);
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL); /* For Wacom serial devices */
#ifdef CONFIG_UDEV_KMS
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "drm", NULL); /* For output GPU devices */
#endif
#ifdef HAVE_UDEV_MONITOR_FILTER_ADD_MATCH_TAG
if (SeatId && strcmp(SeatId, "seat0"))
@ -322,6 +361,9 @@ config_udev_init(void)
udev_enumerate_add_match_subsystem(enumerate, "input");
udev_enumerate_add_match_subsystem(enumerate, "tty");
#ifdef CONFIG_UDEV_KMS
udev_enumerate_add_match_subsystem(enumerate, "drm");
#endif
#ifdef HAVE_UDEV_ENUMERATE_ADD_MATCH_TAG
if (SeatId && strcmp(SeatId, "seat0"))
@ -366,3 +408,72 @@ config_udev_fini(void)
udev_monitor = NULL;
udev_unref(udev);
}
#ifdef CONFIG_UDEV_KMS
static Bool
config_udev_odev_setup_attribs(const char *path, const char *syspath,
config_odev_probe_proc_ptr probe_callback)
{
struct OdevAttributes *attribs = config_odev_allocate_attribute_list();
int ret;
if (!attribs)
return FALSE;
ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_PATH, path);
if (ret == FALSE)
goto fail;
ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_SYSPATH, syspath);
if (ret == FALSE)
goto fail;
/* ownership of attribs is passed to probe layer */
probe_callback(attribs);
return TRUE;
fail:
config_odev_free_attributes(attribs);
free(attribs);
return FALSE;
}
void
config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
{
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *device;
udev = udev_monitor_get_udev(udev_monitor);
enumerate = udev_enumerate_new(udev);
if (!enumerate)
return;
udev_enumerate_add_match_subsystem(enumerate, "drm");
udev_enumerate_add_match_sysname(enumerate, "card[0-9]*");
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
udev_list_entry_foreach(device, devices) {
const char *syspath = udev_list_entry_get_name(device);
struct udev_device *udev_device = udev_device_new_from_syspath(udev, syspath);
const char *path = udev_device_get_devnode(udev_device);
const char *sysname = udev_device_get_sysname(udev_device);
if (!path || !syspath)
goto no_probe;
else if (strcmp(udev_device_get_subsystem(udev_device), "drm") != 0)
goto no_probe;
else if (strncmp(sysname, "card", 4) != 0)
goto no_probe;
config_udev_odev_setup_attribs(path, syspath, probe_callback);
no_probe:
udev_device_unref(udev_device);
}
udev_enumerate_unref(enumerate);
return;
}
#endif

View File

@ -615,6 +615,7 @@ AC_ARG_ENABLE(dbe, AS_HELP_STRING([--disable-dbe], [Build DBE extensi
AC_ARG_ENABLE(xf86bigfont, AS_HELP_STRING([--enable-xf86bigfont], [Build XF86 Big Font extension (default: disabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=no])
AC_ARG_ENABLE(dpms, AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
AC_ARG_ENABLE(config-udev, AS_HELP_STRING([--enable-config-udev], [Build udev support (default: auto)]), [CONFIG_UDEV=$enableval], [CONFIG_UDEV=auto])
AC_ARG_ENABLE(config-udev-kms, AS_HELP_STRING([--enable-config-udev-kms], [Build udev kms support (default: auto)]), [CONFIG_UDEV_KMS=$enableval], [CONFIG_UDEV_KMS=auto])
AC_ARG_ENABLE(config-dbus, AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no])
AC_ARG_ENABLE(config-hal, AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto])
AC_ARG_ENABLE(config-wscons, AS_HELP_STRING([--enable-config-wscons], [Build wscons config support (default: auto)]), [CONFIG_WSCONS=$enableval], [CONFIG_WSCONS=auto])
@ -704,6 +705,7 @@ case $host_os in
CONFIG_DBUS_API=no
CONFIG_HAL=no
CONFIG_UDEV=no
CONFIG_UDEV_KMS=no
DGA=no
DRI2=no
INT10MODULE=no
@ -838,11 +840,16 @@ AM_CONDITIONAL(CONFIG_UDEV, [test "x$CONFIG_UDEV" = xyes])
if test "x$CONFIG_UDEV" = xyes; then
CONFIG_DBUS_API=no
CONFIG_HAL=no
if test "x$CONFIG_UDEV_KMS" = xauto; then
CONFIG_UDEV_KMS="$HAVE_LIBUDEV"
fi
if ! test "x$HAVE_LIBUDEV" = xyes; then
AC_MSG_ERROR([udev configuration API requested, but libudev is not installed])
fi
AC_DEFINE(CONFIG_UDEV, 1, [Use libudev for input hotplug])
if test "x$CONFIG_UDEV_KMS" = xyes; then
AC_DEFINE(CONFIG_UDEV_KMS, 1, [Use libudev for kms enumeration])
fi
SAVE_LIBS=$LIBS
SAVE_CFLAGS=$CFLAGS
CFLAGS=$UDEV_CFLAGS
@ -852,6 +859,7 @@ if test "x$CONFIG_UDEV" = xyes; then
LIBS=$SAVE_LIBS
CFLAGS=$SAVE_CFLAGS
fi
AM_CONDITIONAL(CONFIG_UDEV_KMS, [test "x$CONFIG_UDEV_KMS" = xyes])
dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
@ -1099,7 +1107,7 @@ case "$DRI2,$HAVE_DRI2PROTO" in
esac
AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
if test "x$DRI" = xyes || test "x$DRI2" = xyes; then
if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$CONFIG_UDEV_KMS" = xyes; then
if test "x$DRM" = xyes; then
AC_DEFINE(WITH_LIBDRM, 1, [Building with libdrm support])
PKG_CHECK_MODULES([LIBDRM], $LIBDRM)
@ -1650,7 +1658,7 @@ if test "x$XORG" = xyes; then
PKG_CHECK_MODULES([PCIACCESS], $LIBPCIACCESS)
SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $LIBPCIACCESS"
XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $GLX_SYS_LIBS"
XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $GLX_SYS_LIBS $LIBDRM_LIBS"
XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS"
AC_DEFINE(XSERVER_LIBPCIACCESS, 1, [Use libpciaccess for all pci manipulation])
@ -1668,6 +1676,10 @@ if test "x$XORG" = xyes; then
fi
AC_MSG_RESULT([$PCI])
if test "x$CONFIG_UDEV_KMS" = xyes; then
AC_DEFINE(XSERVER_PLATFORM_BUS, 1, [X server supports platform device enumeration])
fi
AC_MSG_RESULT([$XSERVER_PLATFORM_BUS])
dnl ===================================================================
dnl ==================== end of PCI configuration =====================
dnl ===================================================================
@ -1856,7 +1868,7 @@ AM_CONDITIONAL([SOLARIS_ASM_INLINE], [test "x$solaris_asm_inline" = xyes])
AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])
AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
AM_CONDITIONAL([XORG_BUS_PLATFORM], [test "x$CONFIG_UDEV_KMS" = xyes])
dnl XWin DDX
AC_MSG_CHECKING([whether to build XWin DDX])

View File

@ -3724,32 +3724,20 @@ with its screen number, a pointer to its ScreenRec, argc, and argv.
*/
int
AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
int /*argc */ ,
char ** /*argv */
), int argc, char **argv)
static int init_screen(ScreenPtr pScreen, int i, Bool gpu)
{
int i;
int scanlinepad, format, depth, bitsPerPixel, j, k;
ScreenPtr pScreen;
i = screenInfo.numScreens;
if (i == MAXSCREENS)
return -1;
pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
if (!pScreen)
return -1;
dixInitScreenSpecificPrivates(pScreen);
if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) {
free(pScreen);
return -1;
}
pScreen->myNum = i;
if (gpu) {
pScreen->myNum += GPU_SCREEN_OFFSET;
pScreen->isGPU = TRUE;
}
pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */
pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
pScreen->CreateScreenResources = 0;
@ -3784,7 +3772,33 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
PixmapWidthPaddingInfo[depth].notPower2 = 0;
}
}
return 0;
}
int
AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
int /*argc */ ,
char ** /*argv */
), int argc, char **argv)
{
int i;
ScreenPtr pScreen;
Bool ret;
i = screenInfo.numScreens;
if (i == MAXSCREENS)
return -1;
pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
if (!pScreen)
return -1;
ret = init_screen(pScreen, i, FALSE);
if (ret != 0) {
free(pScreen);
return ret;
}
/* This is where screen specific stuff gets initialized. Load the
screen structure, call the hardware, whatever.
This is also where the default colormap should be allocated and
@ -3810,3 +3824,68 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
return i;
}
int
AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
int /*argc */ ,
char ** /*argv */
),
int argc, char **argv)
{
int i;
ScreenPtr pScreen;
Bool ret;
i = screenInfo.numGPUScreens;
if (i == MAXGPUSCREENS)
return -1;
pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
if (!pScreen)
return -1;
ret = init_screen(pScreen, i, TRUE);
if (ret != 0) {
free(pScreen);
return ret;
}
/* This is where screen specific stuff gets initialized. Load the
screen structure, call the hardware, whatever.
This is also where the default colormap should be allocated and
also pixel values for blackPixel, whitePixel, and the cursor
Note that InitScreen is NOT allowed to modify argc, argv, or
any of the strings pointed to by argv. They may be passed to
multiple screens.
*/
screenInfo.gpuscreens[i] = pScreen;
screenInfo.numGPUScreens++;
if (!(*pfnInit) (pScreen, argc, argv)) {
dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
free(pScreen);
screenInfo.numGPUScreens--;
return -1;
}
update_desktop_dimensions();
return i;
}
void
RemoveGPUScreen(ScreenPtr pScreen)
{
int idx, j;
if (!pScreen->isGPU)
return;
idx = pScreen->myNum - GPU_SCREEN_OFFSET;
for (j = idx; j < screenInfo.numGPUScreens - 1; j++) {
screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1];
screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET;
}
screenInfo.numGPUScreens--;
free(pScreen);
}

View File

@ -386,6 +386,9 @@ BlockHandler(pointer pTimeout, pointer pReadmask)
for (i = 0; i < screenInfo.numScreens; i++)
(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i],
pTimeout, pReadmask);
for (i = 0; i < screenInfo.numGPUScreens; i++)
(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i],
pTimeout, pReadmask);
for (i = 0; i < numHandlers; i++)
if (!handlers[i].deleted)
(*handlers[i].BlockHandler) (handlers[i].blockData,
@ -422,6 +425,9 @@ WakeupHandler(int result, pointer pReadmask)
for (i = 0; i < screenInfo.numScreens; i++)
(*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i],
result, pReadmask);
for (i = 0; i < screenInfo.numGPUScreens; i++)
(*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i],
result, pReadmask);
if (handlerDeleted) {
for (i = 0; i < numHandlers;)
if (handlers[i].deleted) {

View File

@ -207,6 +207,12 @@ main(int argc, char *argv[], char *envp[])
FatalError("no screens found");
InitExtensions(argc, argv);
for (i = 0; i < screenInfo.numGPUScreens; i++) {
ScreenPtr pScreen = screenInfo.gpuscreens[i];
if (!CreateScratchPixmapsForScreen(pScreen))
FatalError("failed to create scratch pixmaps");
}
for (i = 0; i < screenInfo.numScreens; i++) {
ScreenPtr pScreen = screenInfo.screens[i];
@ -336,6 +342,15 @@ main(int argc, char *argv[], char *envp[])
screenInfo.numScreens = i;
}
for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) {
ScreenPtr pScreen = screenInfo.gpuscreens[i];
FreeScratchPixmapsForScreen(pScreen);
(*pScreen->CloseScreen) (pScreen);
dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
free(pScreen);
screenInfo.numGPUScreens = i;
}
ReleaseClientIds(serverClient);
dixFreePrivates(serverClient->devPrivates, PRIVATE_CLIENT);
serverClient->devPrivates = NULL;

View File

@ -222,6 +222,10 @@ fixupScreens(FixupFunc fixup, unsigned bytes)
for (s = 0; s < screenInfo.numScreens; s++)
if (!fixupOneScreen (screenInfo.screens[s], fixup, bytes))
return FALSE;
for (s = 0; s < screenInfo.numGPUScreens; s++)
if (!fixupOneScreen (screenInfo.gpuscreens[s], fixup, bytes))
return FALSE;
return TRUE;
}

View File

@ -22,9 +22,13 @@ if DGA
DGASOURCES = xf86DGA.c
endif
if XORG_BUS_PLATFORM
PLATSOURCES = xf86platformBus.c
endif
RANDRSOURCES = xf86RandR.c
BUSSOURCES = xf86fbBus.c xf86noBus.c $(PCI_SOURCES) $(SBUS_SOURCES)
BUSSOURCES = xf86fbBus.c xf86noBus.c $(PCI_SOURCES) $(SBUS_SOURCES) $(PLATSOURCES)
MODEDEFSOURCES = $(srcdir)/vesamodes $(srcdir)/extramodes
@ -56,7 +60,7 @@ sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \
xf86PciInfo.h xf86Priv.h xf86Privstr.h \
xf86cmap.h xf86fbman.h xf86str.h xf86Xinput.h xisb.h \
$(XVSDKINCS) $(XF86VMODE_SDK) xorgVersion.h \
xf86sbusBus.h xf86VGAarbiter.h xf86Optionstr.h
xf86sbusBus.h xf86VGAarbiter.h xf86Optionstr.h xf86platformBus.h
DISTCLEANFILES = xf86Build.h
CLEANFILES = $(BUILT_SOURCES)

View File

@ -71,6 +71,11 @@ extern _X_EXPORT Bool fbSlotClaimed;
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
extern _X_EXPORT Bool sbusSlotClaimed;
#endif
#if defined(XSERVER_PLATFORM_BUS)
extern _X_EXPORT int platformSlotClaimed;
#endif
extern _X_EXPORT confDRIRec xf86ConfigDRI;
extern _X_EXPORT Bool xf86DRI2Enabled(void);
@ -460,4 +465,7 @@ extern _X_EXPORT ScreenPtr xf86ScrnToScreen(ScrnInfoPtr pScrn);
#define XF86_SCRN_INTERFACE 1 /* define for drivers to use in api compat */
/* flags passed to xf86 allocate screen */
#define XF86_ALLOCATE_GPU_SCREEN 1
#endif /* _XF86_H */

View File

@ -198,10 +198,13 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
}
i = 0;
#ifdef XSERVER_PLATFORM_BUS
i = xf86PlatformMatchDriver(matches, nmatches);
#endif
#ifdef sun
/* Check for driver type based on /dev/fb type and if valid, use
it instead of PCI bus probe results */
if (xf86Info.consoleFd >= 0) {
if (xf86Info.consoleFd >= 0 && (i < (nmatches - 1))) {
struct vis_identifier visid;
const char *cp;
extern char xf86SolarisFbDev[PATH_MAX];
@ -251,6 +254,7 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
}
#endif
#ifdef __sparc__
if (i < (nmatches - 1))
{
char *sbusDriver = sparcDriverName();
@ -259,7 +263,8 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
}
#endif
#ifdef XSERVER_LIBPCIACCESS
i = xf86PciMatchDriver(matches, nmatches);
if (i < (nmatches - 1))
i = xf86PciMatchDriver(matches, nmatches);
#endif
/* Fallback to platform default hardware */
if (i < (nmatches - 1)) {

View File

@ -77,8 +77,14 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only)
{
Bool foundScreen = FALSE;
#ifdef XSERVER_PLATFORM_BUS
if (drv->platformProbe != NULL) {
foundScreen = xf86platformProbeDev(drv);
}
#endif
#ifdef XSERVER_LIBPCIACCESS
if (drv->PciProbe != NULL) {
if (!foundScreen && (drv->PciProbe != NULL)) {
if (xf86DoConfigure && xf86DoConfigurePass1) {
assert(detect_only);
foundScreen = xf86PciAddMatchingDev(drv);
@ -183,6 +189,10 @@ xf86BusConfig(void)
}
}
/* bind GPU conf screen to protocol screen 0 */
for (i = 0; i < xf86NumGPUScreens; i++)
xf86GPUScreens[i]->confScreen = xf86Screens[0]->confScreen;
/* If no screens left, return now. */
if (xf86NumScreens == 0) {
xf86Msg(X_ERROR,
@ -202,6 +212,9 @@ xf86BusConfig(void)
void
xf86BusProbe(void)
{
#ifdef XSERVER_PLATFORM_BUS
xf86platformProbe();
#endif
#ifdef XSERVER_LIBPCIACCESS
xf86PciProbe();
#endif
@ -238,6 +251,8 @@ StringToBusType(const char *busID, const char **retID)
ret = BUS_PCI;
if (!xf86NameCmp(p, "sbus"))
ret = BUS_SBUS;
if (!xf86NameCmp(p, "platform"))
ret = BUS_PLATFORM;
if (ret != BUS_NONE)
if (retID)
*retID = busID + strlen(p) + 1;
@ -270,6 +285,8 @@ xf86IsEntityPrimary(int entityIndex)
return pEnt->bus.id.pci == primaryBus.id.pci;
case BUS_SBUS:
return pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum;
case BUS_PLATFORM:
return pEnt->bus.id.plat == primaryBus.id.plat;
default:
return FALSE;
}
@ -541,6 +558,9 @@ xf86PostProbe(void)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
sbusSlotClaimed ||
#endif
#ifdef XSERVER_PLATFORM_BUS
platformSlotClaimed ||
#endif
#ifdef XSERVER_LIBPCIACCESS
pciSlotClaimed
#else

View File

@ -42,6 +42,7 @@
#if defined(__sparc__) || defined(__sparc)
#include "xf86sbusBus.h"
#endif
#include "xf86platformBus.h"
typedef struct {
DriverPtr driver;

View File

@ -712,7 +712,8 @@ typedef enum {
FLAG_AUTO_ENABLE_DEVICES,
FLAG_GLX_VISUALS,
FLAG_DRI2,
FLAG_USE_SIGIO
FLAG_USE_SIGIO,
FLAG_AUTO_ADD_GPU,
} FlagValues;
/**
@ -770,6 +771,8 @@ static OptionInfoRec FlagOptions[] = {
{0}, FALSE},
{FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
{0}, FALSE},
{FLAG_AUTO_ADD_GPU, "AutoAddGPU", OPTV_BOOLEAN,
{0}, FALSE},
{-1, NULL, OPTV_NONE,
{0}, FALSE},
};
@ -862,6 +865,16 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
xf86Msg(from, "%sutomatically enabling devices\n",
xf86Info.autoEnableDevices ? "A" : "Not a");
if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_GPU)) {
xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_GPU,
&xf86Info.autoAddGPU);
from = X_CONFIG;
}
else {
from = X_DEFAULT;
}
xf86Msg(from, "%sutomatically adding GPU devices\n",
xf86Info.autoAddGPU ? "A" : "Not a");
/*
* Set things up based on the config file information. Some of these
* settings may be overridden later when the command line options are

View File

@ -51,6 +51,7 @@ DevPrivateKeyRec xf86CreateRootWindowKeyRec;
DevPrivateKeyRec xf86ScreenKeyRec;
ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */
ScrnInfoPtr *xf86GPUScreens = NULL; /* List of ScrnInfos */
const unsigned char byte_reversed[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
@ -125,11 +126,16 @@ xf86InfoRec xf86Info = {
#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS)
.forceInputDevices = FALSE,
.autoAddDevices = TRUE,
.autoEnableDevices = TRUE
.autoEnableDevices = TRUE,
#else
.forceInputDevices = TRUE,
.autoAddDevices = FALSE,
.autoEnableDevices = FALSE
.autoEnableDevices = FALSE,
#endif
#if defined(CONFIG_UDEV_KMS)
.autoAddGPU = TRUE,
#else
.autoAddGPU = FALSE,
#endif
};
@ -153,6 +159,7 @@ int xf86NumDrivers = 0;
InputDriverPtr *xf86InputDriverList = NULL;
int xf86NumInputDrivers = 0;
int xf86NumScreens = 0;
int xf86NumGPUScreens = 0;
const char *xf86VisualNames[] = {
"StaticGray",

View File

@ -167,29 +167,43 @@ ScrnInfoPtr
xf86AllocateScreen(DriverPtr drv, int flags)
{
int i;
ScrnInfoPtr pScrn;
if (xf86Screens == NULL)
xf86NumScreens = 0;
if (flags & XF86_ALLOCATE_GPU_SCREEN) {
if (xf86GPUScreens == NULL)
xf86NumGPUScreens = 0;
i = xf86NumGPUScreens++;
xf86GPUScreens = xnfrealloc(xf86GPUScreens, xf86NumGPUScreens * sizeof(ScrnInfoPtr));
xf86GPUScreens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
pScrn = xf86GPUScreens[i];
pScrn->scrnIndex = i + GPU_SCREEN_OFFSET; /* Changes when a screen is removed */
pScrn->is_gpu = TRUE;
} else {
if (xf86Screens == NULL)
xf86NumScreens = 0;
i = xf86NumScreens++;
xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */
xf86Screens[i]->origIndex = i; /* This never changes */
xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
xf86ScrnInfoPrivateCount);
i = xf86NumScreens++;
xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
pScrn = xf86Screens[i];
pScrn->scrnIndex = i; /* Changes when a screen is removed */
}
pScrn->origIndex = pScrn->scrnIndex; /* This never changes */
pScrn->privates = xnfcalloc(sizeof(DevUnion), xf86ScrnInfoPrivateCount);
/*
* EnableDisableFBAccess now gets initialized in InitOutput()
* xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
* pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
*/
xf86Screens[i]->drv = drv;
pScrn->drv = drv;
drv->refCount++;
xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
pScrn->module = DuplicateModule(drv->module, NULL);
xf86Screens[i]->DriverFunc = drv->driverFunc;
pScrn->DriverFunc = drv->driverFunc;
return xf86Screens[i];
return pScrn;
}
/*
@ -202,10 +216,17 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
{
int i;
int scrnIndex;
/* First check if the screen is valid */
if (xf86NumScreens == 0 || xf86Screens == NULL)
return;
Bool is_gpu = FALSE;
if (pScrn->is_gpu) {
/* First check if the screen is valid */
if (xf86NumGPUScreens == 0 || xf86GPUScreens == NULL)
return;
is_gpu = TRUE;
} else {
/* First check if the screen is valid */
if (xf86NumScreens == 0 || xf86Screens == NULL)
return;
}
if (!pScrn)
return;
@ -237,12 +258,23 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
/* Move the other entries down, updating their scrnIndex fields */
xf86NumScreens--;
if (is_gpu) {
xf86NumGPUScreens--;
scrnIndex -= GPU_SCREEN_OFFSET;
for (i = scrnIndex; i < xf86NumGPUScreens; i++) {
xf86GPUScreens[i] = xf86GPUScreens[i + 1];
xf86GPUScreens[i]->scrnIndex = i + GPU_SCREEN_OFFSET;
/* Also need to take care of the screen layout settings */
}
}
else {
xf86NumScreens--;
for (i = scrnIndex; i < xf86NumScreens; i++) {
xf86Screens[i] = xf86Screens[i + 1];
xf86Screens[i]->scrnIndex = i;
/* Also need to take care of the screen layout settings */
for (i = scrnIndex; i < xf86NumScreens; i++) {
xf86Screens[i] = xf86Screens[i + 1];
xf86Screens[i]->scrnIndex = i;
/* Also need to take care of the screen layout settings */
}
}
}
@ -266,6 +298,14 @@ xf86AllocateScrnInfoPrivateIndex(void)
memset(&nprivs[idx], 0, sizeof(DevUnion));
pScr->privates = nprivs;
}
for (i = 0; i < xf86NumGPUScreens; i++) {
pScr = xf86GPUScreens[i];
nprivs = xnfrealloc(pScr->privates,
xf86ScrnInfoPrivateCount * sizeof(DevUnion));
/* Zero the new private */
memset(&nprivs[idx], 0, sizeof(DevUnion));
pScr->privates = nprivs;
}
return idx;
}
@ -1058,6 +1098,11 @@ xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
xf86Screens[scrnIndex]->name)
LogHdrMessageVerb(type, verb, format, args, "%s(%d): ",
xf86Screens[scrnIndex]->name, scrnIndex);
else if (scrnIndex >= GPU_SCREEN_OFFSET &&
scrnIndex < GPU_SCREEN_OFFSET + xf86NumGPUScreens &&
xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name)
LogHdrMessageVerb(type, verb, format, args, "%s(G%d): ",
xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name, scrnIndex - GPU_SCREEN_OFFSET);
else
LogVMessageVerb(type, verb, format, args);
}
@ -1833,13 +1878,23 @@ xf86MotionHistoryAllocate(InputInfoPtr pInfo)
ScrnInfoPtr
xf86ScreenToScrn(ScreenPtr pScreen)
{
assert(pScreen->myNum < xf86NumScreens);
return xf86Screens[pScreen->myNum];
if (pScreen->isGPU) {
assert(pScreen->myNum - GPU_SCREEN_OFFSET < xf86NumGPUScreens);
return xf86GPUScreens[pScreen->myNum - GPU_SCREEN_OFFSET];
} else {
assert(pScreen->myNum < xf86NumScreens);
return xf86Screens[pScreen->myNum];
}
}
ScreenPtr
xf86ScrnToScreen(ScrnInfoPtr pScrn)
{
assert(pScrn->scrnIndex < screenInfo.numScreens);
return screenInfo.screens[pScrn->scrnIndex];
if (pScrn->is_gpu) {
assert(pScrn->scrnIndex - GPU_SCREEN_OFFSET < screenInfo.numGPUScreens);
return screenInfo.gpuscreens[pScrn->scrnIndex - GPU_SCREEN_OFFSET];
} else {
assert(pScrn->scrnIndex < screenInfo.numScreens);
return screenInfo.screens[pScrn->scrnIndex];
}
}

View File

@ -593,6 +593,18 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
if (!xf86Screens[i]->configured)
xf86DeleteScreen(xf86Screens[i--]);
for (i = 0; i < xf86NumGPUScreens; i++) {
xf86VGAarbiterScrnInit(xf86GPUScreens[i]);
xf86VGAarbiterLock(xf86GPUScreens[i]);
if (xf86GPUScreens[i]->PreInit &&
xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
xf86GPUScreens[i]->configured = TRUE;
xf86VGAarbiterUnlock(xf86GPUScreens[i]);
}
for (i = 0; i < xf86NumGPUScreens; i++)
if (!xf86GPUScreens[i]->configured)
xf86DeleteScreen(xf86GPUScreens[i--]);
/*
* If no screens left, return now.
*/
@ -818,6 +830,36 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
!dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
FatalError("Cannot register DDX private keys");
for (i = 0; i < xf86NumGPUScreens; i++) {
ScrnInfoPtr pScrn = xf86GPUScreens[i];
xf86VGAarbiterLock(pScrn);
/*
* Almost everything uses these defaults, and many of those that
* don't, will wrap them.
*/
pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
#ifdef XFreeXDGA
pScrn->SetDGAMode = xf86SetDGAMode;
#endif
pScrn->DPMSSet = NULL;
pScrn->LoadPalette = NULL;
pScrn->SetOverscan = NULL;
pScrn->DriverFunc = NULL;
pScrn->pScreen = NULL;
scr_index = AddGPUScreen(pScrn->ScreenInit, argc, argv);
xf86VGAarbiterUnlock(pScrn);
if (scr_index == i) {
dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates,
xf86ScreenKey, xf86GPUScreens[i]);
pScrn->pScreen = screenInfo.gpuscreens[scr_index];
/* The driver should set this, but make sure it is set anyway */
pScrn->vtSema = TRUE;
} else {
FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index);
}
}
for (i = 0; i < xf86NumScreens; i++) {
xf86VGAarbiterLock(xf86Screens[i]);
/*

View File

@ -95,6 +95,8 @@ extern _X_EXPORT Bool xorgHWAccess;
extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
extern ScrnInfoPtr *xf86GPUScreens; /* List of pointers to ScrnInfoRecs */
extern int xf86NumGPUScreens;
#ifndef DEFAULT_VERBOSE
#define DEFAULT_VERBOSE 0
#endif

View File

@ -110,6 +110,8 @@ typedef struct {
Bool dri2;
MessageType dri2From;
Bool autoAddGPU;
} xf86InfoRec, *xf86InfoPtr;
#ifdef DPMSExtension

View File

@ -54,6 +54,10 @@ xf86ClaimFbSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active)
EntityPtr p;
int num;
#ifdef XSERVER_PLATFORM_BUS
if (platformSlotClaimed)
return -1;
#endif
#ifdef XSERVER_LIBPCIACCESS
if (pciSlotClaimed)
return -1;

View File

@ -110,7 +110,7 @@ xf86PciProbe(void)
xf86PciVideoInfo[num - 1] = info;
pci_device_probe(info);
if (pci_device_is_boot_vga(info)) {
if (primaryBus.type == BUS_NONE && pci_device_is_boot_vga(info)) {
primaryBus.type = BUS_PCI;
primaryBus.id.pci = info;
}
@ -352,7 +352,15 @@ xf86ComparePciBusString(const char *busID, int bus, int device, int func)
Bool
xf86IsPrimaryPci(struct pci_device *pPci)
{
return ((primaryBus.type == BUS_PCI) && (pPci == primaryBus.id.pci));
if (primaryBus.type == BUS_PCI)
return pPci == primaryBus.id.pci;
#ifdef XSERVER_PLATFORM_BUS
if (primaryBus.type == BUS_PLATFORM)
if (primaryBus.id.plat->pdev)
if (MATCH_PCI_DEVICES(primaryBus.id.plat->pdev, pPci))
return TRUE;
#endif
return FALSE;
}
/*
@ -367,7 +375,15 @@ xf86GetPciInfoForEntity(int entityIndex)
return NULL;
p = xf86Entities[entityIndex];
return (p->bus.type == BUS_PCI) ? p->bus.id.pci : NULL;
switch (p->bus.type) {
case BUS_PCI:
return p->bus.id.pci;
case BUS_PLATFORM:
return p->bus.id.plat->pdev;
default:
break;
}
return NULL;
}
/*
@ -400,6 +416,13 @@ xf86CheckPciSlot(const struct pci_device *d)
if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
return FALSE;
}
#ifdef XSERVER_PLATFORM_BUS
if ((p->bus.type == BUS_PLATFORM) && (p->bus.id.plat->pdev)) {
struct pci_device *ud = p->bus.id.plat->pdev;
if (MATCH_PCI_DEVICES(ud, d))
return FALSE;
}
#endif
}
return TRUE;
}
@ -1065,8 +1088,8 @@ xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
return TRUE;
}
static int
videoPtrToDriverList(struct pci_device *dev,
int
xf86VideoPtrToDriverList(struct pci_device *dev,
char *returnList[], int returnListMax)
{
int i;
@ -1249,8 +1272,8 @@ xchomp(char *line)
* don't export their PCI ID's properly. If distros don't end up using this
* feature it can and should be removed because the symbol-based resolution
* scheme should be the primary one */
static void
matchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_chip)
void
xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_chip)
{
DIR *idsdir;
FILE *fp;
@ -1379,7 +1402,7 @@ xf86PciMatchDriver(char *matches[], int nmatches)
pci_iterator_destroy(iter);
#ifdef __linux__
if (info)
matchDriverFromFiles(matches, info->vendor_id, info->device_id);
xf86MatchDriverFromFiles(matches, info->vendor_id, info->device_id);
#endif
for (i = 0; (i < nmatches) && (matches[i]); i++) {
@ -1387,7 +1410,7 @@ xf86PciMatchDriver(char *matches[], int nmatches)
}
if ((info != NULL) && (i < nmatches)) {
i += videoPtrToDriverList(info, &(matches[i]), nmatches - i);
i += xf86VideoPtrToDriverList(info, &(matches[i]), nmatches - i);
}
return i;

View File

@ -42,4 +42,14 @@ Bool xf86PciConfigure(void *busData, struct pci_device *pDev);
void xf86PciConfigureNewDev(void *busData, struct pci_device *pVideo,
GDevRec * GDev, int *chipset);
#define MATCH_PCI_DEVICES(x, y) (((x)->domain == (y)->domain) && \
((x)->bus == (y)->bus) && \
((x)->func == (y)->func) && \
((x)->dev == (y)->dev))
void
xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_chip);
int
xf86VideoPtrToDriverList(struct pci_device *dev,
char *returnList[], int returnListMax);
#endif /* _XF86_PCI_BUS_H */

View File

@ -0,0 +1,489 @@
/*
* Copyright © 2012 Red Hat.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Author: Dave Airlie <airlied@redhat.com>
*/
/*
* This file contains the interfaces to the bus-specific code
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#ifdef XSERVER_PLATFORM_BUS
#include <errno.h>
#include <pciaccess.h>
#include <fcntl.h>
#include <unistd.h>
#include "os.h"
#include "hotplug.h"
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Priv.h"
#include "xf86str.h"
#include "xf86Bus.h"
#include "Pci.h"
#include "xf86platformBus.h"
int platformSlotClaimed;
int xf86_num_platform_devices;
static struct xf86_platform_device *xf86_platform_devices;
int
xf86_add_platform_device(struct OdevAttributes *attribs)
{
xf86_platform_devices = xnfrealloc(xf86_platform_devices,
(sizeof(struct xf86_platform_device)
* (xf86_num_platform_devices + 1)));
xf86_platform_devices[xf86_num_platform_devices].attribs = attribs;
xf86_platform_devices[xf86_num_platform_devices].pdev = NULL;
xf86_num_platform_devices++;
return 0;
}
int
xf86_remove_platform_device(int dev_index)
{
int j;
config_odev_free_attribute_list(xf86_platform_devices[dev_index].attribs);
for (j = dev_index; j < xf86_num_platform_devices - 1; j++)
memcpy(&xf86_platform_devices[j], &xf86_platform_devices[j + 1], sizeof(struct xf86_platform_device));
xf86_num_platform_devices--;
return 0;
}
Bool
xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_name)
{
struct xf86_platform_device *device = &xf86_platform_devices[index];
return config_odev_add_attribute(device->attribs, attrib_id, attrib_name);
}
char *
xf86_get_platform_attrib(int index, int attrib_id)
{
struct xf86_platform_device *device = &xf86_platform_devices[index];
struct OdevAttribute *oa;
xorg_list_for_each_entry(oa, &device->attribs->list, member) {
if (oa->attrib_id == attrib_id)
return oa->attrib_name;
}
return NULL;
}
char *
xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id)
{
struct OdevAttribute *oa;
xorg_list_for_each_entry(oa, &device->attribs->list, member) {
if (oa->attrib_id == attrib_id)
return oa->attrib_name;
}
return NULL;
}
/*
* xf86IsPrimaryPlatform() -- return TRUE if primary device
* is a platform device and it matches this one.
*/
static Bool
xf86IsPrimaryPlatform(struct xf86_platform_device *plat)
{
return ((primaryBus.type == BUS_PLATFORM) && (plat == primaryBus.id.plat));
}
static void
platform_find_pci_info(struct xf86_platform_device *pd, char *busid)
{
struct pci_slot_match devmatch;
struct pci_device *info;
struct pci_device_iterator *iter;
int ret;
ret = sscanf(busid, "pci:%04x:%02x:%02x.%u",
&devmatch.domain, &devmatch.bus, &devmatch.dev,
&devmatch.func);
if (ret != 4)
return;
iter = pci_slot_match_iterator_create(&devmatch);
info = pci_device_next(iter);
if (info) {
pd->pdev = info;
pci_device_probe(info);
if (pci_device_is_boot_vga(info)) {
primaryBus.type = BUS_PLATFORM;
primaryBus.id.plat = pd;
}
}
pci_iterator_destroy(iter);
}
static Bool
xf86_check_platform_slot(const struct xf86_platform_device *pd)
{
int i;
for (i = 0; i < xf86NumEntities; i++) {
const EntityPtr u = xf86Entities[i];
if (pd->pdev && u->bus.type == BUS_PCI)
return !MATCH_PCI_DEVICES(pd->pdev, u->bus.id.pci);
if ((u->bus.type == BUS_PLATFORM) && (pd == u->bus.id.plat)) {
return FALSE;
}
}
return TRUE;
}
/**
* @return The numbers of found devices that match with the current system
* drivers.
*/
int
xf86PlatformMatchDriver(char *matches[], int nmatches)
{
int i, j = 0;
struct pci_device *info = NULL;
int pass = 0;
for (pass = 0; pass < 2; pass++) {
for (i = 0; i < xf86_num_platform_devices; i++) {
if (xf86IsPrimaryPlatform(&xf86_platform_devices[i]) && (pass == 1))
continue;
else if (!xf86IsPrimaryPlatform(&xf86_platform_devices[i]) && (pass == 0))
continue;
info = xf86_platform_devices[i].pdev;
#ifdef __linux__
if (info)
xf86MatchDriverFromFiles(matches, info->vendor_id, info->device_id);
#endif
for (j = 0; (j < nmatches) && (matches[j]); j++) {
/* find end of matches list */
}
if ((info != NULL) && (j < nmatches)) {
j += xf86VideoPtrToDriverList(info, &(matches[j]), nmatches - j);
}
}
}
return j;
}
int
xf86platformProbe(void)
{
int i;
Bool pci = TRUE;
if (!xf86scanpci()) {
pci = FALSE;
}
config_odev_probe(&xf86PlatformDeviceProbe);
for (i = 0; i < xf86_num_platform_devices; i++) {
char *busid = xf86_get_platform_attrib(i, ODEV_ATTRIB_BUSID);
if (pci && (strncmp(busid, "pci:", 4) == 0)) {
platform_find_pci_info(&xf86_platform_devices[i], busid);
}
}
return 0;
}
static int
xf86ClaimPlatformSlot(struct xf86_platform_device * d, DriverPtr drvp,
int chipset, GDevPtr dev, Bool active)
{
EntityPtr p = NULL;
int num;
if (xf86_check_platform_slot(d)) {
num = xf86AllocateEntity();
p = xf86Entities[num];
p->driver = drvp;
p->chipset = chipset;
p->bus.type = BUS_PLATFORM;
p->bus.id.plat = d;
p->active = active;
p->inUse = FALSE;
if (dev)
xf86AddDevToEntity(num, dev);
platformSlotClaimed++;
return num;
}
else
return -1;
}
static int
xf86UnclaimPlatformSlot(struct xf86_platform_device *d, GDevPtr dev)
{
int i;
for (i = 0; i < xf86NumEntities; i++) {
const EntityPtr p = xf86Entities[i];
if ((p->bus.type == BUS_PLATFORM) && (p->bus.id.plat == d)) {
if (dev)
xf86RemoveDevFromEntity(i, dev);
platformSlotClaimed--;
p->bus.type = BUS_NONE;
return 0;
}
}
return 0;
}
#define END_OF_MATCHES(m) \
(((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
static Bool doPlatformProbe(struct xf86_platform_device *dev, DriverPtr drvp,
GDevPtr gdev, int flags, intptr_t match_data)
{
Bool foundScreen = FALSE;
int entity;
if (gdev->screen == 0 && !xf86_check_platform_slot(dev))
return FALSE;
entity = xf86ClaimPlatformSlot(dev, drvp, 0,
gdev, gdev->active);
if ((entity == -1) && (gdev->screen > 0)) {
unsigned nent;
for (nent = 0; nent < xf86NumEntities; nent++) {
EntityPtr pEnt = xf86Entities[nent];
if (pEnt->bus.type != BUS_PLATFORM)
continue;
if (pEnt->bus.id.plat == dev) {
entity = nent;
xf86AddDevToEntity(nent, gdev);
break;
}
}
}
if (entity != -1) {
if (drvp->platformProbe(drvp, entity, flags, dev, match_data))
foundScreen = TRUE;
else
xf86UnclaimPlatformSlot(dev, gdev);
}
return foundScreen;
}
static Bool
probeSingleDevice(struct xf86_platform_device *dev, DriverPtr drvp, GDevPtr gdev, int flags)
{
int k;
Bool foundScreen = FALSE;
struct pci_device *pPci;
const struct pci_id_match *const devices = drvp->supported_devices;
if (dev->pdev && devices) {
int device_id = dev->pdev->device_id;
pPci = dev->pdev;
for (k = 0; !END_OF_MATCHES(devices[k]); k++) {
if (PCI_ID_COMPARE(devices[k].vendor_id, pPci->vendor_id)
&& PCI_ID_COMPARE(devices[k].device_id, device_id)
&& ((devices[k].device_class_mask & pPci->device_class)
== devices[k].device_class)) {
foundScreen = doPlatformProbe(dev, drvp, gdev, flags, devices[k].match_data);
if (foundScreen)
break;
}
}
}
else if (dev->pdev && !devices)
return FALSE;
else
foundScreen = doPlatformProbe(dev, drvp, gdev, flags, 0);
return foundScreen;
}
int
xf86platformProbeDev(DriverPtr drvp)
{
Bool foundScreen = FALSE;
GDevPtr *devList;
const unsigned numDevs = xf86MatchDevice(drvp->driverName, &devList);
int i, j;
/* find the main device or any device specificed in xorg.conf */
for (i = 0; i < numDevs; i++) {
for (j = 0; j < xf86_num_platform_devices; j++) {
if (devList[i]->busID && *devList[i]->busID) {
if (xf86PlatformDeviceCheckBusID(&xf86_platform_devices[j], devList[i]->busID))
break;
}
else {
if (xf86_platform_devices[j].pdev) {
if (xf86IsPrimaryPlatform(&xf86_platform_devices[j]))
break;
}
}
}
if (j == xf86_num_platform_devices)
continue;
foundScreen = probeSingleDevice(&xf86_platform_devices[j], drvp, devList[i], 0);
if (!foundScreen)
continue;
}
/* if autoaddgpu devices is enabled then go find a few more and add them as GPU screens */
if (xf86Info.autoAddGPU && numDevs) {
for (j = 0; j < xf86_num_platform_devices; j++) {
probeSingleDevice(&xf86_platform_devices[j], drvp, devList[0], PLATFORM_PROBE_GPU_SCREEN);
}
}
return foundScreen;
}
int
xf86platformAddDevice(int index)
{
int i, old_screens, scr_index;
DriverPtr drvp = NULL;
int entity;
screenLayoutPtr layout;
static char *hotplug_driver_name = "modesetting";
/* force load the driver for now */
xf86LoadOneModule(hotplug_driver_name, NULL);
for (i = 0; i < xf86NumDrivers; i++) {
if (!xf86DriverList[i])
continue;
if (!strcmp(xf86DriverList[i]->driverName, hotplug_driver_name)) {
drvp = xf86DriverList[i];
break;
}
}
if (i == xf86NumDrivers)
return -1;
old_screens = xf86NumGPUScreens;
entity = xf86ClaimPlatformSlot(&xf86_platform_devices[index],
drvp, 0, 0, 0);
if (!drvp->platformProbe(drvp, entity, PLATFORM_PROBE_GPU_SCREEN, &xf86_platform_devices[index], 0)) {
xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
}
if (old_screens == xf86NumGPUScreens)
return -1;
i = old_screens;
for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
layout++) {
xf86GPUScreens[i]->confScreen = layout->screen;
break;
}
if (xf86GPUScreens[i]->PreInit &&
xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
xf86GPUScreens[i]->configured = TRUE;
if (!xf86GPUScreens[i]->configured) {
ErrorF("hotplugged device %d didn't configure\n", i);
xf86DeleteScreen(xf86GPUScreens[i]);
return -1;
}
scr_index = AddGPUScreen(xf86GPUScreens[i]->ScreenInit, 0, NULL);
dixSetPrivate(&xf86GPUScreens[i]->pScreen->devPrivates,
xf86ScreenKey, xf86GPUScreens[i]);
CreateScratchPixmapsForScreen(xf86GPUScreens[i]->pScreen);
return 0;
}
void
xf86platformRemoveDevice(int index)
{
EntityPtr entity;
int ent_num, i, j;
Bool found;
for (ent_num = 0; ent_num < xf86NumEntities; ent_num++) {
entity = xf86Entities[ent_num];
if (entity->bus.type == BUS_PLATFORM &&
entity->bus.id.plat == &xf86_platform_devices[index])
break;
}
if (ent_num == xf86NumEntities)
goto out;
found = FALSE;
for (i = 0; i < xf86NumGPUScreens; i++) {
for (j = 0; j < xf86GPUScreens[i]->numEntities; j++)
if (xf86GPUScreens[i]->entityList[j] == ent_num) {
found = TRUE;
break;
}
if (found)
break;
}
if (!found) {
ErrorF("failed to find screen to remove\n");
goto out;
}
xf86GPUScreens[i]->pScreen->CloseScreen(xf86GPUScreens[i]->pScreen);
RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
xf86DeleteScreen(xf86GPUScreens[i]);
xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
xf86_remove_platform_device(index);
out:
return;
}
#endif

View File

@ -0,0 +1,64 @@
/*
* Copyright © 2012 Red Hat.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Author: Dave Airlie <airlied@redhat.com>
*/
#ifndef XF86_PLATFORM_BUS_H
#define XF86_PLATFORM_BUS_H
#include "hotplug.h"
struct xf86_platform_device {
struct OdevAttributes *attribs;
/* for PCI devices */
struct pci_device *pdev;
};
#ifdef XSERVER_PLATFORM_BUS
int xf86platformProbe(void);
int xf86platformProbeDev(DriverPtr drvp);
extern int xf86_num_platform_devices;
extern char *
xf86_get_platform_attrib(int index, int attrib_id);
extern int
xf86_add_platform_device(struct OdevAttributes *attribs);
extern int
xf86_remove_platform_device(int dev_index);
extern Bool
xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str);
extern int
xf86platformAddDevice(int index);
extern void
xf86platformRemoveDevice(int index);
extern _X_EXPORT char *
xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id);
extern _X_EXPORT Bool
xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid);
extern _X_EXPORT int
xf86PlatformMatchDriver(char *matches[], int nmatches);
#endif
#endif

View File

@ -311,6 +311,7 @@ struct _SymTabRec;
struct _PciChipsets;
struct pci_device;
struct xf86_platform_device;
typedef struct _DriverRec {
int driverVersion;
@ -325,8 +326,15 @@ typedef struct _DriverRec {
const struct pci_id_match *supported_devices;
Bool (*PciProbe) (struct _DriverRec * drv, int entity_num,
struct pci_device * dev, intptr_t match_data);
Bool (*platformProbe) (struct _DriverRec * drv, int entity_num, int flags,
struct xf86_platform_device * dev, intptr_t match_data);
} DriverRec, *DriverPtr;
/*
* platform probe flags
*/
#define PLATFORM_PROBE_GPU_SCREEN 1
/*
* AddDriver flags
*/
@ -343,6 +351,7 @@ typedef struct _DriverRec {
#undef BUS_NONE
#undef BUS_PCI
#undef BUS_SBUS
#undef BUS_PLATFORM
#undef BUS_last
#endif
@ -350,6 +359,7 @@ typedef enum {
BUS_NONE,
BUS_PCI,
BUS_SBUS,
BUS_PLATFORM,
BUS_last /* Keep last */
} BusType;
@ -362,6 +372,7 @@ typedef struct _bus {
union {
struct pci_device *pci;
SbusBusId sbus;
struct xf86_platform_device *plat;
} id;
} BusRec, *BusPtr;
@ -802,6 +813,7 @@ typedef struct _ScrnInfoRec {
*/
funcPointer reservedFuncs[NUM_RESERVED_FUNCS];
Bool is_gpu;
} ScrnInfoRec;
typedef struct {

View File

@ -22,7 +22,7 @@ XORG_CFLAGS += -DHAVE_APM
endif
liblinux_la_SOURCES = lnx_init.c lnx_video.c \
lnx_agp.c lnx_kmod.c lnx_bell.c \
lnx_agp.c lnx_kmod.c lnx_bell.c lnx_platform.c \
$(srcdir)/../shared/bios_mmap.c \
$(srcdir)/../shared/VTsw_usl.c \
$(srcdir)/../shared/posix_tty.c \

View File

@ -0,0 +1,179 @@
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#ifdef XSERVER_PLATFORM_BUS
#include <xf86drm.h>
#include <fcntl.h>
#include <unistd.h>
/* Linux platform device support */
#include "xf86_OSproc.h"
#include "xf86.h"
#include "xf86platformBus.h"
#include "xf86Bus.h"
#include "hotplug.h"
static Bool
get_drm_info(struct OdevAttributes *attribs, char *path)
{
drmSetVersion sv;
char *buf;
int fd;
fd = open(path, O_RDWR, O_CLOEXEC);
if (fd == -1)
return FALSE;
sv.drm_di_major = 1;
sv.drm_di_minor = 4;
sv.drm_dd_major = -1; /* Don't care */
sv.drm_dd_minor = -1; /* Don't care */
if (drmSetInterfaceVersion(fd, &sv)) {
ErrorF("setversion 1.4 failed\n");
return FALSE;
}
xf86_add_platform_device(attribs);
buf = drmGetBusid(fd);
xf86_add_platform_device_attrib(xf86_num_platform_devices - 1,
ODEV_ATTRIB_BUSID, buf);
drmFreeBusid(buf);
close(fd);
return TRUE;
}
Bool
xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid)
{
struct OdevAttribute *attrib;
const char *syspath = NULL;
BusType bustype;
const char *id;
xorg_list_for_each_entry(attrib, &device->attribs->list, member) {
if (attrib->attrib_id == ODEV_ATTRIB_SYSPATH) {
syspath = attrib->attrib_name;
break;
}
}
if (!syspath)
return FALSE;
bustype = StringToBusType(busid, &id);
if (bustype == BUS_PCI) {
struct pci_device *pPci = device->pdev;
if (xf86ComparePciBusString(busid,
((pPci->domain << 8)
| pPci->bus),
pPci->dev, pPci->func)) {
return TRUE;
}
}
else if (bustype == BUS_PLATFORM) {
/* match on the minimum string */
int len = strlen(id);
if (strlen(syspath) < strlen(id))
len = strlen(syspath);
if (strncmp(id, syspath, len))
return FALSE;
return TRUE;
}
return FALSE;
}
void
xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
{
struct OdevAttribute *attrib;
int i;
char *path = NULL;
Bool ret;
xorg_list_for_each_entry(attrib, &attribs->list, member) {
if (attrib->attrib_id == ODEV_ATTRIB_PATH) {
path = attrib->attrib_name;
break;
}
}
if (!path)
goto out_free;
for (i = 0; i < xf86_num_platform_devices; i++) {
char *dpath;
dpath = xf86_get_platform_attrib(i, ODEV_ATTRIB_PATH);
if (!strcmp(path, dpath))
break;
}
if (i != xf86_num_platform_devices)
goto out_free;
LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n",
path);
ret = get_drm_info(attribs, path);
if (ret == FALSE)
goto out_free;
return;
out_free:
config_odev_free_attribute_list(attribs);
}
void NewGPUDeviceRequest(struct OdevAttributes *attribs)
{
int old_num = xf86_num_platform_devices;
int ret;
xf86PlatformDeviceProbe(attribs);
if (old_num == xf86_num_platform_devices)
return;
ret = xf86platformAddDevice(xf86_num_platform_devices-1);
if (ret == -1)
xf86_remove_platform_device(xf86_num_platform_devices-1);
ErrorF("xf86: found device %d\n", xf86_num_platform_devices);
return;
}
void DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
{
struct OdevAttribute *attrib;
int index;
char *syspath = NULL;
xorg_list_for_each_entry(attrib, &attribs->list, member) {
if (attrib->attrib_id == ODEV_ATTRIB_SYSPATH) {
syspath = attrib->attrib_name;
break;
}
}
for (index = 0; index < xf86_num_platform_devices; index++) {
char *dspath;
dspath = xf86_get_platform_attrib(index, ODEV_ATTRIB_SYSPATH);
if (!strcmp(syspath, dspath))
break;
}
if (index == xf86_num_platform_devices)
goto out;
ErrorF("xf86: remove device %d %s\n", index, syspath);
xf86platformRemoveDevice(index);
out:
config_odev_free_attribute_list(attribs);
}
#endif

View File

@ -0,0 +1,23 @@
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#ifdef XSERVER_PLATFORM_BUS
/* noop platform device support */
#include "xf86_OSproc.h"
#include "xf86.h"
#include "xf86platformBus.h"
Bool
xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid)
{
return FALSE;
}
void xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
{
}
#endif

View File

@ -221,6 +221,12 @@ extern _X_EXPORT void xf86InitVidMem(void);
#endif /* XF86_OS_PRIVS */
#ifdef XSERVER_PLATFORM_BUS
#include "hotplug.h"
void
xf86PlatformDeviceProbe(struct OdevAttributes *attribs);
#endif
_XFUNCPROTOEND
#endif /* NO_OSLIB_PROTOTYPES */
#endif /* _XF86_OSPROC_H */

View File

@ -336,28 +336,19 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
if (!infoPtr->pScrn->vtSema)
ScreenPriv->SavedCursor = pCurs;
if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
if (infoPtr->pScrn->vtSema &&
(ScreenPriv->ForceHWCursorCount ||
((
#ifdef ARGB_CURSOR
pCurs->
bits->
argb
&&
infoPtr->
UseHWCursorARGB
&&
(*infoPtr->
UseHWCursorARGB)
(pScreen,
pCurs))
||
(pCurs->
bits->
argb
== 0
&&
pCurs->bits->argb &&
infoPtr->UseHWCursorARGB &&
(*infoPtr->UseHWCursorARGB)(pScreen, pCurs)) ||
(pCurs->bits->argb == 0 &&
#endif
(pCurs->bits->height <= infoPtr->MaxHeight) && (pCurs->bits->width <= infoPtr->MaxWidth) && (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, pCurs)))))) {
(pCurs->bits->height <= infoPtr->MaxHeight) &&
(pCurs->bits->width <= infoPtr->MaxWidth) &&
(!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, pCurs)))))) {
if (ScreenPriv->SWCursor) /* remove the SW cursor */
(*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
NullCursor, x, y);

View File

@ -390,6 +390,9 @@
/* Use libudev for input hotplug */
#undef CONFIG_UDEV
/* Use libudev for kms enumeration */
#undef CONFIG_UDEV_KMS
/* Use udev_monitor_filter_add_match_tag() */
#undef HAVE_UDEV_MONITOR_FILTER_ADD_MATCH_TAG

View File

@ -26,8 +26,47 @@
#ifndef HOTPLUG_H
#define HOTPLUG_H
#include "list.h"
extern _X_EXPORT void config_pre_init(void);
extern _X_EXPORT void config_init(void);
extern _X_EXPORT void config_fini(void);
struct OdevAttribute {
struct xorg_list member;
int attrib_id;
char *attrib_name;
};
struct OdevAttributes {
struct xorg_list list;
};
struct OdevAttributes *
config_odev_allocate_attribute_list(void);
void
config_odev_free_attribute_list(struct OdevAttributes *attribs);
Bool
config_odev_add_attribute(struct OdevAttributes *attribs, int attrib,
const char *attrib_name);
void
config_odev_free_attributes(struct OdevAttributes *attribs);
/* path to kernel device node - Linux e.g. /dev/dri/card0 */
#define ODEV_ATTRIB_PATH 1
/* system device path - Linux e.g. /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1 */
#define ODEV_ATTRIB_SYSPATH 2
/* DRI-style bus id */
#define ODEV_ATTRIB_BUSID 3
typedef void (*config_odev_probe_proc_ptr)(struct OdevAttributes *attribs);
void config_odev_probe(config_odev_probe_proc_ptr probe_callback);
#ifdef CONFIG_UDEV_KMS
void NewGPUDeviceRequest(struct OdevAttributes *attribs);
void DeleteGPUDeviceRequest(struct OdevAttributes *attribs);
#endif
#endif /* HOTPLUG_H */

View File

@ -83,10 +83,14 @@ OF THIS SOFTWARE.
#ifndef MAXSCREENS
#define MAXSCREENS 16
#endif
#ifndef MAXGPUSCREENS
#define MAXGPUSCREENS 16
#endif
#define MAXCLIENTS 256
#define MAXEXTENSIONS 128
#define MAXFORMATS 8
#define MAXDEVICES 40 /* input devices */
#define GPU_SCREEN_OFFSET 256
/* 128 event opcodes for core + extension events, excluding GE */
#define MAXEVENTS 128

View File

@ -62,6 +62,15 @@ extern _X_EXPORT int AddScreen(Bool (* /*pfnInit */ )(
int /*argc */ ,
char ** /*argv */ );
extern _X_EXPORT int AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
int /*argc */ ,
char ** /*argv */
),
int argc, char **argv);
extern _X_EXPORT void RemoveGPUScreen(ScreenPtr pScreen);
typedef struct _ColormapRec *ColormapPtr;
#endif /* SCREENINT_H */

View File

@ -477,6 +477,8 @@ typedef struct _Screen {
* malicious users to steal framebuffer's content if that would be the
* default */
Bool canDoBGNoneRoot;
Bool isGPU;
} ScreenRec;
static inline RegionPtr
@ -494,6 +496,8 @@ typedef struct _ScreenInfo {
PixmapFormatRec formats[MAXFORMATS];
int numScreens;
ScreenPtr screens[MAXSCREENS];
int numGPUScreens;
ScreenPtr gpuscreens[MAXGPUSCREENS];
int x; /* origin */
int y; /* origin */
int width; /* total width of all screens together */

View File

@ -136,4 +136,7 @@
/* Have getresuid */
#undef HAVE_GETRESUID
/* Have X server platform bus support */
#undef XSERVER_PLATFORM_BUS
#endif /* _XORG_CONFIG_H_ */

View File

@ -205,6 +205,9 @@
/* X Access Control Extension */
#undef XACE
/* Have X server platform bus support */
#undef XSERVER_PLATFORM_BUS
#ifdef _LP64
#define _XSERVER64 1
#endif

View File

@ -687,6 +687,8 @@ miGlyphs(CARD8 op,
PicturePtr GetGlyphPicture(GlyphPtr glyph, ScreenPtr pScreen)
{
if (pScreen->isGPU)
return NULL;
return GlyphPicture(glyph)[pScreen->myNum];
}