drm/dp/mst: reject DPCD read/write on ports with ddps=0

DP v2.1b specifies that REMOTE_DPCD_READ and REMOTE_DPCD_WRITE
transactions should only be issued to downstream ports where ddps=1
(device plug status indicates a device is connected). Issuing these
transactions to empty ports (ddps=0) is non-compliant and causes
problems in practice: some MST hubs NAK the request, and all hubs
introduce a delay waiting for the transaction to complete or fail
before the driver can proceed, increasing link training latency.

Guard drm_dp_mst_dpcd_read() and drm_dp_mst_dpcd_write() with a
ddps check and return -EIO immediately for unoccupied ports. This
avoids the spurious sideband transactions without changing connector
lifetime semantics — connectors for all output ports are still
created at enumeration time, regardless of ddps.

Signed-off-by: Xiao Lu <xiaolu.xie@intel.com>

Changes in v2:
- Instead of skipping connector creation for ddps=0 ports (v1),
  keep connectors around and guard DPCD transactions at the
  drm_dp_mst_dpcd_read/write level. This avoids changing connector
  lifetime semantics visible to userspace, per Lyude's review.

Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260920022144.2209244-1-xiaolu.xie@intel.com
This commit is contained in:
Xiao Lu 2026-09-20 10:21:44 +08:00 committed by Lyude Paul
parent 63e91c1997
commit 744f262401

View File

@ -2161,6 +2161,9 @@ ssize_t drm_dp_mst_dpcd_read(struct drm_dp_aux *aux,
struct drm_dp_mst_port *port = container_of(aux, struct drm_dp_mst_port,
aux);
if (!port->ddps)
return -EIO;
return drm_dp_send_dpcd_read(port->mgr, port,
offset, size, buffer);
}
@ -2184,6 +2187,9 @@ ssize_t drm_dp_mst_dpcd_write(struct drm_dp_aux *aux,
struct drm_dp_mst_port *port = container_of(aux, struct drm_dp_mst_port,
aux);
if (!port->ddps)
return -EIO;
return drm_dp_send_dpcd_write(port->mgr, port,
offset, size, buffer);
}