summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2016-04-13 11:12:38 +0900
committerMichel Dänzer <michel@daenzer.net>2016-04-19 16:35:40 +0900
commitc801f9f10a5d72d935faf21e72f7e7808fb4f05f (patch)
tree4408860325680906cb00f3ef84c334cc3a84d3fb
parent1ca677309720e2f6c953c9e76f5b34c22a4416c6 (diff)
Handle Zaphod mode correctly in radeon_mode_hotplug
We need to scan both screens of the entity for existing connectors, and enumerate DVI & HDMI connectors consistently regardless of which screen they're assigned to. Fixes crash when hot-(un)plugging connectors in Zaphod mode. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93415 Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--src/drmmode_display.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 4c66ca70..84c07c66 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -36,6 +36,7 @@
#include "damagestr.h"
#include "micmap.h"
#include "xf86cmap.h"
+#include "xf86Priv.h"
#include "radeon.h"
#include "radeon_bo_helper.h"
#include "radeon_glamor.h"
@@ -2514,10 +2515,12 @@ void
radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
drmModeResPtr mode_res;
- int i, j;
+ int i, j, s;
Bool found;
Bool changed = FALSE;
+ int num_dvi = 0, num_hdmi = 0;
mode_res = drmModeGetResources(drmmode->fd);
if (!mode_res)
@@ -2553,21 +2556,43 @@ restart_destroy:
for (i = 0; i < mode_res->count_connectors; i++) {
found = FALSE;
- for (j = 0; j < config->num_output; j++) {
- xf86OutputPtr output = config->output[j];
- drmmode_output_private_ptr drmmode_output;
+ for (s = 0; !found && s < xf86NumScreens; s++) {
+ ScrnInfoPtr loop_scrn = xf86Screens[s];
+ xf86CrtcConfigPtr loop_config =
+ XF86_CRTC_CONFIG_PTR(loop_scrn);
- drmmode_output = output->driver_private;
- if (mode_res->connectors[i] == drmmode_output->output_id) {
- found = TRUE;
- break;
+ if (RADEONEntPriv(loop_scrn) != pRADEONEnt)
+ continue;
+
+ for (j = 0; !found && j < loop_config->num_output; j++) {
+ xf86OutputPtr output = loop_config->output[j];
+ drmmode_output_private_ptr drmmode_output;
+
+ drmmode_output = output->driver_private;
+ if (mode_res->connectors[i] ==
+ drmmode_output->output_id) {
+ found = TRUE;
+
+ switch(drmmode_output->mode_output->connector_type) {
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_DVID:
+ case DRM_MODE_CONNECTOR_DVIA:
+ num_dvi++;
+ break;
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ num_hdmi++;
+ break;
+ }
+ }
}
}
if (found)
continue;
- changed = TRUE;
- drmmode_output_init(scrn, drmmode, mode_res, i, NULL, NULL, 1);
+ if (drmmode_output_init(scrn, drmmode, mode_res, i, &num_dvi,
+ &num_hdmi, 1) != 0)
+ changed = TRUE;
}
if (changed) {