$Id: 080_pci_isolate_device_feature.diff 1325 2004-04-28 08:41:01Z branden $ Implement IsolateDevice and SingleCard layout options for XF86Config, and -isolateDevice command-line flag for XFree86 X server. Useful for multi-card setups where different X servers run on each card. This patch by Aivils Stoss ; copyright and license as below. Minor modifications by Andreas Schuldei and Branden Robinson; documentation added by Branden Robinson. Copyright 2003 Aivils Stoss.   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 COPYRIGHT HOLDER(S) 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. --- xc/programs/Xserver/hw/xfree86/xorg.conf.man~ 2004-03-26 18:10:22.000000000 -0500 +++ xc/programs/Xserver/hw/xfree86/xorg.conf.man 2004-03-26 18:53:20.000000000 -0500 @@ -1592,7 +1592,7 @@ section provides information specific to the whole session, including session-specific .BR Options . -The +In addition to options specific to this section (described below), the .B ServerFlags options (described above) may be specified here, and ones given here override those given in the @@ -1678,12 +1678,30 @@ .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 --- xc/programs/Xserver/hw/xfree86/Xorg.man~ 2004-03-26 19:04:30.000000000 -0500 +++ xc/programs/Xserver/hw/xfree86/Xorg.man 2004-03-26 19:10:42.000000000 -0500 @@ -192,6 +192,19 @@ 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 diff -urN xc/programs/Xserver/hw/xfree86/common~/xf86Config.c xc/programs/Xserver/hw/xfree86/common/xf86Config.c --- xc/programs/Xserver/hw/xfree86/common~/xf86Config.c 2004-03-26 18:29:19.000000000 -0500 +++ xc/programs/Xserver/hw/xfree86/common/xf86Config.c 2004-03-26 19:02:42.000000000 -0500 @@ -1416,6 +1416,20 @@ 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 @@ -2213,6 +2227,8 @@ const char *filename; char *searchpath; MessageType from = X_DEFAULT; + char *scanptr; + Bool singlecard = 0; if (getuid() == 0) searchpath = ROOT_CONFIGPATH; @@ -2283,6 +2299,29 @@ } } + 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) || diff -urN xc/programs/Xserver/hw/xfree86/common~/xf86Globals.c xc/programs/Xserver/hw/xfree86/common/xf86Globals.c --- xc/programs/Xserver/hw/xfree86/common~/xf86Globals.c 2004-03-26 18:29:19.000000000 -0500 +++ xc/programs/Xserver/hw/xfree86/common/xf86Globals.c 2004-03-26 18:29:40.000000000 -0500 @@ -215,6 +215,7 @@ #endif PropertyPtr *xf86RegisteredPropertiesTable = NULL; Bool xf86inSuspend = FALSE; +PciBusId xf86IsolateDevice; #ifdef DLOPEN_HACK /* diff -urN xc/programs/Xserver/hw/xfree86/common~/xf86Init.c xc/programs/Xserver/hw/xfree86/common/xf86Init.c --- xc/programs/Xserver/hw/xfree86/common~/xf86Init.c 2004-03-26 18:29:19.000000000 -0500 +++ xc/programs/Xserver/hw/xfree86/common/xf86Init.c 2004-03-26 19:17:21.000000000 -0500 @@ -1590,6 +1590,25 @@ 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); } @@ -1650,6 +1669,7 @@ #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(); diff -urN xc/programs/Xserver/hw/xfree86/common~/xf86Priv.h xc/programs/Xserver/hw/xfree86/common/xf86Priv.h --- xc/programs/Xserver/hw/xfree86/common~/xf86Priv.h 2004-03-26 18:29:19.000000000 -0500 +++ xc/programs/Xserver/hw/xfree86/common/xf86Priv.h 2004-03-26 18:29:40.000000000 -0500 @@ -53,6 +53,7 @@ extern Gamma xf86Gamma; extern char *xf86ServerName; extern Bool xf86ShowUnresolved; +extern PciBusId xf86IsolateDevice; /* Other parameters */ diff -urN xc/programs/Xserver/hw/xfree86/common~/xf86pciBus.c xc/programs/Xserver/hw/xfree86/common/xf86pciBus.c --- xc/programs/Xserver/hw/xfree86/common~/xf86pciBus.c 2004-03-26 18:29:19.000000000 -0500 +++ xc/programs/Xserver/hw/xfree86/common/xf86pciBus.c 2004-03-26 19:04:03.000000000 -0500 @@ -160,7 +160,10 @@ int num = 0; pciVideoPtr info; Bool mem64 = FALSE; + int DoIsolateDeviceCheck = 0; + if (xf86IsolateDevice.bus || xf86IsolateDevice.device || xf86IsolateDevice.func) + DoIsolateDeviceCheck = 1; pcrpp = xf86PciInfo = xf86scanpci(0); getPciClassFlags(pcrpp); @@ -182,7 +185,11 @@ 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));