aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_dp_mst_topology.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-07-26 18:15:43 -0400
committerDave Airlie <airlied@redhat.com>2017-07-26 18:15:43 -0400
commit0eb2c0ae578ba00f97c7541e01abbce022d14909 (patch)
tree172db28b9232906ddac61b4bf20c4b0c60c85139 /drivers/gpu/drm/drm_dp_mst_topology.c
parent542aefb5a2da8f67b8fb74a24f60ecb3ec479a06 (diff)
parent520eccdfe187591a51ea9ab4c1a024ae4d0f68d9 (diff)
Backmerge tag 'v4.13-rc2' into drm-next
Linux 4.13-rc2 This is required for drm-misc fixing.
Diffstat (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c')
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index f7e292bf2baf..41b492f99955 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -332,6 +332,13 @@ static bool drm_dp_sideband_msg_build(struct drm_dp_sideband_msg_rx *msg,
332 return false; 332 return false;
333 } 333 }
334 334
335 /*
336 * ignore out-of-order messages or messages that are part of a
337 * failed transaction
338 */
339 if (!recv_hdr.somt && !msg->have_somt)
340 return false;
341
335 /* get length contained in this portion */ 342 /* get length contained in this portion */
336 msg->curchunk_len = recv_hdr.msg_len; 343 msg->curchunk_len = recv_hdr.msg_len;
337 msg->curchunk_hdrlen = hdrlen; 344 msg->curchunk_hdrlen = hdrlen;
@@ -2168,7 +2175,7 @@ out_unlock:
2168} 2175}
2169EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume); 2176EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
2170 2177
2171static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up) 2178static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
2172{ 2179{
2173 int len; 2180 int len;
2174 u8 replyblock[32]; 2181 u8 replyblock[32];
@@ -2183,12 +2190,12 @@ static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
2183 replyblock, len); 2190 replyblock, len);
2184 if (ret != len) { 2191 if (ret != len) {
2185 DRM_DEBUG_KMS("failed to read DPCD down rep %d %d\n", len, ret); 2192 DRM_DEBUG_KMS("failed to read DPCD down rep %d %d\n", len, ret);
2186 return; 2193 return false;
2187 } 2194 }
2188 ret = drm_dp_sideband_msg_build(msg, replyblock, len, true); 2195 ret = drm_dp_sideband_msg_build(msg, replyblock, len, true);
2189 if (!ret) { 2196 if (!ret) {
2190 DRM_DEBUG_KMS("sideband msg build failed %d\n", replyblock[0]); 2197 DRM_DEBUG_KMS("sideband msg build failed %d\n", replyblock[0]);
2191 return; 2198 return false;
2192 } 2199 }
2193 replylen = msg->curchunk_len + msg->curchunk_hdrlen; 2200 replylen = msg->curchunk_len + msg->curchunk_hdrlen;
2194 2201
@@ -2200,21 +2207,32 @@ static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
2200 ret = drm_dp_dpcd_read(mgr->aux, basereg + curreply, 2207 ret = drm_dp_dpcd_read(mgr->aux, basereg + curreply,
2201 replyblock, len); 2208 replyblock, len);
2202 if (ret != len) { 2209 if (ret != len) {
2203 DRM_DEBUG_KMS("failed to read a chunk\n"); 2210 DRM_DEBUG_KMS("failed to read a chunk (len %d, ret %d)\n",
2211 len, ret);
2212 return false;
2204 } 2213 }
2214
2205 ret = drm_dp_sideband_msg_build(msg, replyblock, len, false); 2215 ret = drm_dp_sideband_msg_build(msg, replyblock, len, false);
2206 if (ret == false) 2216 if (!ret) {
2207 DRM_DEBUG_KMS("failed to build sideband msg\n"); 2217 DRM_DEBUG_KMS("failed to build sideband msg\n");
2218 return false;
2219 }
2220
2208 curreply += len; 2221 curreply += len;
2209 replylen -= len; 2222 replylen -= len;
2210 } 2223 }
2224 return true;
2211} 2225}
2212 2226
2213static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) 2227static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
2214{ 2228{
2215 int ret = 0; 2229 int ret = 0;
2216 2230
2217 drm_dp_get_one_sb_msg(mgr, false); 2231 if (!drm_dp_get_one_sb_msg(mgr, false)) {
2232 memset(&mgr->down_rep_recv, 0,
2233 sizeof(struct drm_dp_sideband_msg_rx));
2234 return 0;
2235 }
2218 2236
2219 if (mgr->down_rep_recv.have_eomt) { 2237 if (mgr->down_rep_recv.have_eomt) {
2220 struct drm_dp_sideband_msg_tx *txmsg; 2238 struct drm_dp_sideband_msg_tx *txmsg;
@@ -2270,7 +2288,12 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
2270static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) 2288static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
2271{ 2289{
2272 int ret = 0; 2290 int ret = 0;
2273 drm_dp_get_one_sb_msg(mgr, true); 2291
2292 if (!drm_dp_get_one_sb_msg(mgr, true)) {
2293 memset(&mgr->up_req_recv, 0,
2294 sizeof(struct drm_dp_sideband_msg_rx));
2295 return 0;
2296 }
2274 2297
2275 if (mgr->up_req_recv.have_eomt) { 2298 if (mgr->up_req_recv.have_eomt) {
2276 struct drm_dp_sideband_msg_req_body msg; 2299 struct drm_dp_sideband_msg_req_body msg;
@@ -2322,7 +2345,9 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
2322 DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn); 2345 DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn);
2323 } 2346 }
2324 2347
2325 drm_dp_put_mst_branch_device(mstb); 2348 if (mstb)
2349 drm_dp_put_mst_branch_device(mstb);
2350
2326 memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx)); 2351 memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
2327 } 2352 }
2328 return ret; 2353 return ret;