diff options
author | Dave Airlie <airlied@redhat.com> | 2017-07-26 18:15:43 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-07-26 18:15:43 -0400 |
commit | 0eb2c0ae578ba00f97c7541e01abbce022d14909 (patch) | |
tree | 172db28b9232906ddac61b4bf20c4b0c60c85139 /drivers/gpu/drm/drm_dp_mst_topology.c | |
parent | 542aefb5a2da8f67b8fb74a24f60ecb3ec479a06 (diff) | |
parent | 520eccdfe187591a51ea9ab4c1a024ae4d0f68d9 (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.c | 41 |
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 | } |
2169 | EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume); | 2176 | EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume); |
2170 | 2177 | ||
2171 | static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up) | 2178 | static 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 | ||
2213 | static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) | 2227 | static 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) | |||
2270 | static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) | 2288 | static 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; |