Commit 7586ac6e authored by Adam Jackson's avatar Adam Jackson 💣

Bug #2216: Multiseat support. From various Debian and Ubuntu patches by

    Aivils Stoss, Andreas Schuldei, Branden Robinson, and Daniel Stone.
parent ba011dc7
......@@ -1657,6 +1657,20 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
return TRUE;
}
typedef enum {
LAYOUT_ISOLATEDEVICE,
LAYOUT_SINGLECARD
} LayoutValues;
static OptionInfoRec LayoutOptions[] = {
{ LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
{0}, FALSE },
{ LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
{0}, FALSE },
{ -1, NULL, OPTV_NONE,
{0}, FALSE },
};
/*
* figure out which layout is active, which screens are used in that layout,
* which drivers and monitors are used in these screens
......@@ -2540,6 +2554,8 @@ xf86HandleConfigFile(Bool autoconfig)
const char *filename;
char *searchpath;
MessageType from = X_DEFAULT;
char *scanptr;
Bool singlecard = 0;
if (!autoconfig) {
if (getuid() == 0)
......@@ -2613,6 +2629,29 @@ xf86HandleConfigFile(Bool autoconfig)
}
}
xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
; /* IsolateDevice specified; overrides SingleCard */
} else {
xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
if (singlecard)
scanptr = xf86ConfigLayout.screens->screen->device->busID;
}
if (scanptr) {
int bus, device, func, stroffset = 0;
if (strncmp(scanptr, "PCI:", 4) != 0) {
xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
"\tIgnoring IsolateDevice option.\n");
} else if (sscanf(scanptr, "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
xf86IsolateDevice.bus = bus;
xf86IsolateDevice.device = device;
xf86IsolateDevice.func = func;
xf86Msg(X_INFO,
"Isolating PCI bus \"%d:%d:%d\"\n", bus, device, func);
}
}
/* Now process everything else */
if (!configFiles(xf86configptr->conf_files) ||
......
......@@ -243,6 +243,7 @@ Bool xf86MiscModInDevAllowNonLocal = FALSE;
RootWinPropPtr *xf86RegisteredPropertiesTable = NULL;
Bool xf86inSuspend = FALSE;
Bool xorgHWAccess = FALSE;
PciBusId xf86IsolateDevice;
#ifdef DLOPEN_HACK
/*
......
......@@ -1681,6 +1681,25 @@ ddxProcessArgument(int argc, char **argv, int i)
xf86AllowMouseOpenFail = TRUE;
return 1;
}
if (!strcmp(argv[i], "-isolateDevice"))
{
int bus, device, func;
if (++i >= argc)
return 0;
if (strncmp(argv[i], "PCI:", 4)) {
ErrorF("Bus types other than PCI not yet isolable\n");
return 0;
}
if (sscanf(argv[i], "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
xf86IsolateDevice.bus = bus;
xf86IsolateDevice.device = device;
xf86IsolateDevice.func = func;
return 2;
} else {
ErrorF("Invalid isolated device specifiation\n");
return 0;
}
}
/* OS-specific processing */
return xf86ProcessArgument(argc, argv, i);
}
......@@ -1745,6 +1764,7 @@ ddxUseMsg()
#endif
ErrorF("-bestRefresh choose modes with the best refresh rate\n");
ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
ErrorF("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n");
ErrorF("-version show the server version\n");
/* OS-specific usage */
xf86UseMsg();
......
......@@ -80,6 +80,7 @@ extern Bool xf86BestRefresh;
extern Gamma xf86Gamma;
extern char *xf86ServerName;
extern Bool xf86ShowUnresolved;
extern PciBusId xf86IsolateDevice;
/* Other parameters */
......
......@@ -194,7 +194,10 @@ FindPCIVideoInfo(void)
int i = 0, j, k;
int num = 0;
pciVideoPtr info;
int DoIsolateDeviceCheck = 0;
if (xf86IsolateDevice.bus || xf86IsolateDevice.device || xf86IsolateDevice.func)
DoIsolateDeviceCheck = 1;
pcrpp = xf86PciInfo = xf86scanpci(0);
getPciClassFlags(pcrpp);
......@@ -216,7 +219,11 @@ FindPCIVideoInfo(void)
subclass = pcrp->pci_sub_class;
}
if (PCIINFOCLASSES(baseclass, subclass)) {
if (PCIINFOCLASSES(baseclass, subclass) &&
(DoIsolateDeviceCheck ?
(xf86IsolateDevice.bus == pcrp->busnum &&
xf86IsolateDevice.device == pcrp->devnum &&
xf86IsolateDevice.func == pcrp->funcnum) : 1)) {
num++;
xf86PciVideoInfo = xnfrealloc(xf86PciVideoInfo,
sizeof(pciVideoPtr) * (num + 1));
......
.\" $XdotOrg$
.\" $XdotOrg: xc/programs/Xserver/hw/xfree86/Xorg.man,v 1.2 2004/04/23 19:20:02 eich Exp $
.TH __xservername__ __appmansuffix__ __vendorversion__
.SH NAME
__xservername__ - X11R6 X server
......@@ -257,6 +257,19 @@ that the server does not have. When this option is specified, mismatches
like this are downgraded from fatal errors to warnings. This option
should be used with care.
.TP 8
.B \-isolateDevice \fIbus\-id\fP
Restrict device resets to the device at
.IR bus\-id .
The
.I bus\-id
string has the form
.IB bustype : bus : device : function
(e.g., \(oqPCI:1:0:0\(cq).
At present, only isolation of PCI devices is supported; i.e., this option
is ignored if
.I bustype
is anything other than \(oqPCI\(cq.
.TP 8
.B \-keeptty
Prevent the server from detaching its initial controlling terminal.
This option is only useful when debugging the server. Not all platforms
......
.\" $XdotOrg: xc/programs/Xserver/hw/xfree86/xorg.conf.man,v 1.2 2004/04/23 19:20:02 eich Exp $
.\" $XdotOrg: xc/programs/Xserver/hw/xfree86/xorg.conf.man,v 1.3 2005/03/22 21:30:43 ajax Exp $
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH __xconfigfile__ __filemansuffix__ __vendorversion__
......@@ -375,7 +375,7 @@ where
is the display number for the __xservername__ server.
..
.SH SERVERFLAGS SECTION
The
In addition to options specific to this section (described below), the
.B ServerFlags
section is used to specify some global
__xservername__ server options. All of the entries in this section are
......@@ -1779,12 +1779,30 @@ and core keyboard devices respectively.
.RE
.TP 7
.B Options
Any option permitted in the
In addition to the following, any option permitted in the
.B ServerFlags
section may also be specified here. When the same option appears in both
places, the value given here overrides the one given in the
.B ServerFlags
section.
.TP 7
.BI "Option \*qIsolateDevice\*q \*q" bus\-id \*q
Restrict device resets to the specified
.IR bus\-id .
See the
.B BusID
option (described in
.BR "DEVICE SECTION" ,
above) for the format of the
.I bus\-id
parameter. This option overrides
.BR SingleCard ,
if specified. At present, only PCI devices can be isolated in this manner.
.TP 7
.BI "Option \*qSingleCard\*q \*q" boolean \*q
As
.BR IsolateDevice ,
except that the bus ID of the first device in the layout is used.
.PP
Here is an example of a
.B ServerLayout
......
......@@ -50,6 +50,8 @@ char *fb_dev_name;
static Bool KeepTty = FALSE;
static int VTnum = -1;
static Bool VTSwitch = TRUE;
static Bool ShareVTs = FALSE;
static int activeVT = -1;
static int vtPermSave[4];
......@@ -125,26 +127,37 @@ xf86OpenConsole(void)
"xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
strerror(errno));
if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
(xf86Info.vtno == -1)) {
FatalError("xf86OpenConsole: Cannot find a free VT: %s\n",
strerror(errno));
}
if (ShareVTs)
{
if (ioctl(fd, VT_GETSTATE, &vts) == 0)
xf86Info.vtno = vts.v_active;
else
FatalError("xf86OpenConsole: Cannot find the current"
" VT (%s)\n", strerror(errno));
} else {
if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
(xf86Info.vtno == -1))
FatalError("xf86OpenConsole: Cannot find a free VT: %s\n",
strerror(errno));
}
close(fd);
}
#ifdef USE_DEV_FB
fb_dev_name=getenv("FRAMEBUFFER");
if (!fb_dev_name)
fb_dev_name="/dev/fb0current";
if (!ShareVTs)
{
fb_dev_name=getenv("FRAMEBUFFER");
if (!fb_dev_name)
fb_dev_name="/dev/fb0current";
if ((fbfd = open(fb_dev_name, O_RDONLY)) < 0)
FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
fb_dev_name, strerror(errno));
if ((fbfd = open(fb_dev_name, O_RDONLY)) < 0)
FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
fb_dev_name, strerror(errno));
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var) < 0)
FatalError("xf86OpenConsole: Unable to get screen info %s\n",
strerror(errno));
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var) < 0)
FatalError("xf86OpenConsole: Unable to get screen info %s\n",
strerror(errno));
}
#endif
xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
......@@ -180,28 +193,31 @@ xf86OpenConsole(void)
FatalError("xf86OpenConsole: Cannot open virtual console"
" %d (%s)\n", xf86Info.vtno, strerror(errno));
/*
* Grab the vt ownership before we overwrite it.
* Hard coded /dev/tty0 into this function as well for below.
*/
if (!saveVtPerms())
xf86Msg(X_WARNING,
"xf86OpenConsole: Could not save ownership of VT\n");
if (!ShareVTs)
{
/*
* Grab the vt ownership before we overwrite it.
* Hard coded /dev/tty0 into this function as well for below.
*/
if (!saveVtPerms())
xf86Msg(X_WARNING,
"xf86OpenConsole: Could not save ownership of VT\n");
/* change ownership of the vt */
if (chown(vtname, getuid(), getgid()) < 0)
xf86Msg(X_WARNING,"xf86OpenConsole: chown %s failed: %s\n",
vtname, strerror(errno));
/* change ownership of the vt */
if (chown(vtname, getuid(), getgid()) < 0)
xf86Msg(X_WARNING,"xf86OpenConsole: chown %s failed: %s\n",
vtname, strerror(errno));
/*
* the current VT device we're running on is not "console", we want
* to grab all consoles too
*
* Why is this needed??
*/
if (chown("/dev/tty0", getuid(), getgid()) < 0)
xf86Msg(X_WARNING,"xf86OpenConsole: chown /dev/tty0 failed: %s\n",
strerror(errno));
/*
* the current VT device we're running on is not "console", we want
* to grab all consoles too
*
* Why is this needed??
*/
if (chown("/dev/tty0", getuid(), getgid()) < 0)
xf86Msg(X_WARNING,"xf86OpenConsole: chown /dev/tty0 failed: %s\n",
strerror(errno));
}
/*
* Linux doesn't switch to an active vt after the last close of a vt,
......@@ -224,61 +240,69 @@ xf86OpenConsole(void)
}
}
#endif
if (!ShareVTs)
{
#if defined(DO_OS_FONTRESTORE)
lnx_savefont();
lnx_savefont();
#endif
/*
* now get the VT
*/
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed: %s\n",
strerror(errno));
/*
* now get the VT
*/
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed: %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed: %s\n",
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed: %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
strerror(errno));
signal(SIGUSR1, xf86VTRequest);
signal(SIGUSR1, xf86VTRequest);
VT.mode = VT_PROCESS;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
VT.mode = VT_PROCESS;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
strerror(errno));
/* we really should have a InitOSInputDevices() function instead
* of Init?$#*&Device(). So I just place it here */
/* we really should have a InitOSInputDevices() function instead
* of Init?$#*&Device(). So I just place it here */
#ifdef USE_DEV_FB
/* copy info to new console */
var.yoffset=0;
var.xoffset=0;
if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var))
FatalError("Unable to set screen info\n");
close(fbfd);
/* copy info to new console */
var.yoffset=0;
var.xoffset=0;
if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var))
FatalError("Unable to set screen info\n");
close(fbfd);
#endif
} else { /* ShareVTs */
close(xf86Info.consoleFd);
}
} else { /* serverGeneration != 1 */
/*
* now get the VT
*/
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed %s\n",
strerror(errno));
if (!ShareVTs && VTSwitch)
{
/*
* now get the VT
*/
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed %s\n",
strerror(errno));
}
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed %s\n",
strerror(errno));
}
return;
}
......@@ -290,7 +314,11 @@ xf86CloseConsole()
#if defined(DO_OS_FONTRESTORE)
struct vt_stat vts;
int vtno = -1;
#endif
if (ShareVTs) return;
#if defined(DO_OS_FONTRESTORE)
if (ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts) < 0)
xf86Msg(X_WARNING, "xf86CloseConsole: VT_GETSTATE failed: %s\n",
strerror(errno));
......@@ -314,21 +342,24 @@ xf86CloseConsole()
strerror(errno));
}
/*
* Perform a switch back to the active VT when we were started
*/
if (activeVT >= 0) {
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, activeVT) < 0)
xf86Msg(X_WARNING, "xf86CloseConsole: VT_ACTIVATE failed: %s\n",
strerror(errno));
activeVT = -1;
}
if (VTSwitch)
{
/*
* Perform a switch back to the active VT when we were started
*/
if (activeVT >= 0) {
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, activeVT) < 0)
xf86Msg(X_WARNING, "xf86CloseConsole: VT_ACTIVATE failed: %s\n",
strerror(errno));
activeVT = -1;
}
#if defined(DO_OS_FONTRESTORE)
if (xf86Info.vtno == vtno) /* check if we are active */
lnx_restorefont();
lnx_freefontdata();
if (xf86Info.vtno == vtno) /* check if we are active */
lnx_restorefont();
lnx_freefontdata();
#endif
}
close(xf86Info.consoleFd); /* make the vt-manager happy */
restoreVtPerms(); /* restore the permissions */
......@@ -348,6 +379,16 @@ xf86ProcessArgument(int argc, char *argv[], int i)
KeepTty = TRUE;
return(1);
}
if (!strcmp(argv[i], "-novtswitch"))
{
VTSwitch = FALSE;
return(1);
}
if (!strcmp(argv[i], "-sharevts"))
{
ShareVTs = TRUE;
return(1);
}
if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
{
if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
......@@ -367,5 +408,7 @@ xf86UseMsg()
ErrorF("vtXX use the specified VT number\n");
ErrorF("-keeptty ");
ErrorF("don't detach controlling tty (for debugging only)\n");
ErrorF("-novtswitch don't immediately switch to new VT\n");
ErrorF("-sharevts share VTs with another X server\n");
return;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment