From 42639ba554655c280ae6cb72df0522b1201f2961 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 3 Aug 2015 17:24:10 +0200 Subject: drm/dp-mst: Remove debug WARN_ON Apparently been in there since forever and fairly easy to hit when hotplugging really fast. I can do that since my mst hub has a manual button to flick the hpd line for reprobing. The resulting WARNING spam isn't pretty. Cc: Dave Airlie Cc: stable@vger.kernel.org Reviewed-by: Thierry Reding Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_dp_mst_topology.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 778bbb6425b8..b0487c9f018c 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1294,7 +1294,6 @@ retry: goto retry; } DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret); - WARN(1, "fail\n"); return -EIO; } -- cgit v1.2.3-70-g09d2 From 4772ff03df8094fd99d28de5fcf5df3a3e9c68bb Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 11 Aug 2015 09:54:29 +0200 Subject: drm/dp/mst: Remove port after removing connector. The port is removed synchronously, but the connector delayed. This causes a use after free which can cause a kernel BUG with slug_debug=FPZU. This is fixed by freeing the port after the connector. This fixes a regression introduced with 6b8eeca65b18ae77e175cc2b6571731f0ee413bf "drm/dp/mst: close deadlock in connector destruction." Cc: stable@vger.kernel.org Cc: Dave Airlie Signed-off-by: Maarten Lankhorst Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/drm_dp_mst_topology.c | 19 +++++++++++++------ include/drm/drm_crtc.h | 2 -- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 778bbb6425b8..1325eecb0510 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -873,9 +873,10 @@ static void drm_dp_destroy_port(struct kref *kref) from an EDID retrieval */ if (port->connector) { mutex_lock(&mgr->destroy_connector_lock); - list_add(&port->connector->destroy_list, &mgr->destroy_connector_list); + list_add(&port->next, &mgr->destroy_connector_list); mutex_unlock(&mgr->destroy_connector_lock); schedule_work(&mgr->destroy_connector_work); + return; } drm_dp_port_teardown_pdt(port, port->pdt); @@ -2660,7 +2661,7 @@ static void drm_dp_tx_work(struct work_struct *work) static void drm_dp_destroy_connector_work(struct work_struct *work) { struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work); - struct drm_connector *connector; + struct drm_dp_mst_port *port; /* * Not a regular list traverse as we have to drop the destroy @@ -2669,15 +2670,21 @@ static void drm_dp_destroy_connector_work(struct work_struct *work) */ for (;;) { mutex_lock(&mgr->destroy_connector_lock); - connector = list_first_entry_or_null(&mgr->destroy_connector_list, struct drm_connector, destroy_list); - if (!connector) { + port = list_first_entry_or_null(&mgr->destroy_connector_list, struct drm_dp_mst_port, next); + if (!port) { mutex_unlock(&mgr->destroy_connector_lock); break; } - list_del(&connector->destroy_list); + list_del(&port->next); mutex_unlock(&mgr->destroy_connector_lock); - mgr->cbs->destroy_connector(mgr, connector); + mgr->cbs->destroy_connector(mgr, port->connector); + + drm_dp_port_teardown_pdt(port, port->pdt); + + if (!port->input && port->vcpi.vcpi > 0) + drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); + kfree(port); } } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 57ca8cc383a6..3b4d8a4a23fb 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -743,8 +743,6 @@ struct drm_connector { uint8_t num_h_tile, num_v_tile; uint8_t tile_h_loc, tile_v_loc; uint16_t tile_h_size, tile_v_size; - - struct list_head destroy_list; }; /** -- cgit v1.2.3-70-g09d2 From 44790462d041d3037d60b3bf88f30837a72006ff Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 14 Jul 2015 11:33:31 +1000 Subject: drm/dp/mst: dump branch OUI in debugfs (v2) It appears some MST docks are worse than other, but the only way to know is to see the sw revisions in here, so dump the branch OUI so we can look at the sw revision. v2: Thierry made me feel guilty, so I parsed the branch OUI. Reviewed-by: Thierry Reding Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_dp_mst_topology.c | 10 ++++++++++ include/drm/drm_dp_helper.h | 1 + 2 files changed, 11 insertions(+) (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index b0487c9f018c..86bc9ade5fc4 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -2631,6 +2631,16 @@ void drm_dp_mst_dump_topology(struct seq_file *m, seq_printf(m, "%02x ", buf[i]); seq_printf(m, "\n"); + /* dump the standard OUI branch header */ + ret = drm_dp_dpcd_read(mgr->aux, DP_BRANCH_OUI, buf, DP_BRANCH_OUI_HEADER_SIZE); + seq_printf(m, "branch oui: "); + for (i = 0; i < 0x3; i++) + seq_printf(m, "%02x", buf[i]); + seq_printf(m, " devid: "); + for (i = 0x3; i < 0x8; i++) + seq_printf(m, "%c", buf[i]); + seq_printf(m, " revision: hw: %x.%x sw: %x.%x", buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]); + seq_printf(m, "\n"); bret = dump_dp_payload_table(mgr, buf); if (bret == true) { seq_printf(m, "payload table: "); diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 94898f6ea02a..499e9f625aef 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -578,6 +578,7 @@ u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE], u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE], int lane); +#define DP_BRANCH_OUI_HEADER_SIZE 0xc #define DP_RECEIVER_CAP_SIZE 0xf #define EDP_PSR_RECEIVER_CAP_SIZE 2 -- cgit v1.2.3-70-g09d2