summaryrefslogtreecommitdiff
path: root/hw/xfree86/common
diff options
context:
space:
mode:
authorZoltán Böszörményi <zboszor@gmail.com>2020-02-12 21:29:52 +0000
committerAdam Jackson <ajax@nwnk.net>2020-02-12 21:29:52 +0000
commit42aaf37241fedfd6a0f72b255f2d45d6ea34d8c6 (patch)
tree606323f703d145f0461aab46a4e4c3c79d42d9e2 /hw/xfree86/common
parenta542224ea28e2e8ccaf5e0df85bf6c603e97599a (diff)
Fix modesetting device matching through kmsdev device path
xf86platformProbeDev didn't check the device path, fix it. This is a problem when trying to set up a non-PCI device via explicit xorg.conf.d configuration. An USB DisplayLink device, being non-PCI was always set up as a GPU device assigned to screen 0 instead of a regular framebuffer, potentially having its own dedicated screen, despite such configuration as below. Only the relevant parts of the configuration are quoted, it's part of a larger context with an Intel chip that has 3 outputs: * DP1 connected to an LCD panel, * VGA1 connected to an external monitor, * HDMI1 unconnected and having no user visible connector Section "ServerFlags" Option "AutoBindGPU" "false" EndSection ... Section "Device" Identifier "Intel2" Driver "intel" BusID "PCI:0:2:0" Screen 2 Option "Monitor-HDMI1" "HDMI1" Option "ZaphodHeads" "HDMI1" EndSection Section "Device" Identifier "UDL" Driver "modesetting" Option "kmsdev" "/dev/dri/card0" #BusID "usb:0:1.2:1.0" Option "Monitor-DVI-I-1" "DVI-I-1" Option "ShadowFB" "on" Option "DoubleShadow" "on" EndSection ... Section "Screen" Identifier "SCREEN2" Option "AutoServerLayout" "on" Device "UDL" GPUDevice "Intel2" Monitor "Monitor-DVI-I-1" SubSection "Display" Modes "1024x768" Depth 24 EndSubSection EndSection Section "ServerLayout" Identifier "LAYOUT" Option "AutoServerLayout" "on" Screen 0 "SCREEN" Screen 1 "SCREEN1" RightOf "SCREEN" Screen 2 "SCREEN2" RightOf "SCREEN1" EndSection On the particular machine I was trying to set up an UDL device, I found the following structure was being used to match the device to a platform device while I was debugging the issue: xf86_platform_devices[0] == Intel, /dev/dri/card1, primary platform device xf86_platform_devices[1] == UDL, /dev/dri/card0 devList[0] == "Intel0", ZaphodHeads: DP1 devList[1] == "Intel1", ZaphodHeads: VGA1 devList[2] == "UDL" devList[3] == "Intel2", ZaphodHeads: HDMI1 (intended GPU device to UDL) When xf86platformProbeDev() matched the UDL device, the BusID check failed in both cases of: * BusID "usb:0:1.2:1.0" was specified * Option "kmsdev" "/dev/dri/card0" was specified As a result, xf86platformProbeDev() went on to call probeSingleDevice() with xf86_platform_devices[0] and devList[2], resulting in the UDL device being set up as a GPU device assigned to the first screen instead of as a framebuffer on the third screen as the configuration specified. Checking Option "kmsdev" in code code may be a layering violation. But the modesetting driver is actually part of the Xorg sources instead of being an external driver, so he "kmsdev" path knowledge may be used here. Signed-off-by: Böszörményi Zoltán <zboszor@pr.hu>
Diffstat (limited to 'hw/xfree86/common')
-rw-r--r--hw/xfree86/common/xf86platformBus.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 23dffc9d6..f87760b63 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -536,12 +536,20 @@ xf86platformProbeDev(DriverPtr drvp)
/* find the main device or any device specificed in xorg.conf */
for (i = 0; i < numDevs; i++) {
+ const char *devpath;
+
/* skip inactive devices */
if (!devList[i]->active)
continue;
+ /* This is specific to modesetting. */
+ devpath = xf86FindOptionValue(devList[i]->options, "kmsdev");
+
for (j = 0; j < xf86_num_platform_devices; j++) {
- if (devList[i]->busID && *devList[i]->busID) {
+ if (devpath && *devpath) {
+ if (strcmp(xf86_platform_devices[j].attribs->path, devpath) == 0)
+ break;
+ } else if (devList[i]->busID && *devList[i]->busID) {
if (xf86PlatformDeviceCheckBusID(&xf86_platform_devices[j], devList[i]->busID))
break;
}