Commit 37f49727 authored by Mika Westerberg's avatar Mika Westerberg

thunderbolt: Fail the failed bandwidth request properly

The USB4 spec says that if the Connection Manager writes Allocated_BW
that is smaller than Requested_BW, the DisplayPort IN adapter signals
this failure back to the DPTX (graphics driver). Implement this by
rewriting the same allocated bandwidth values back.
Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 2ec67a48
...@@ -2270,11 +2270,11 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, ...@@ -2270,11 +2270,11 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up,
*/ */
ret = tb_tunnel_maximum_bandwidth(tunnel, &max_up, &max_down); ret = tb_tunnel_maximum_bandwidth(tunnel, &max_up, &max_down);
if (ret) if (ret)
return ret; goto fail;
ret = usb4_dp_port_granularity(in); ret = usb4_dp_port_granularity(in);
if (ret < 0) if (ret < 0)
return ret; goto fail;
granularity = ret; granularity = ret;
max_up_rounded = roundup(max_up, granularity); max_up_rounded = roundup(max_up, granularity);
...@@ -2304,7 +2304,8 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, ...@@ -2304,7 +2304,8 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up,
"bandwidth request too high (%d/%d Mb/s > %d/%d Mb/s)\n", "bandwidth request too high (%d/%d Mb/s > %d/%d Mb/s)\n",
requested_up_corrected, requested_down_corrected, requested_up_corrected, requested_down_corrected,
max_up_rounded, max_down_rounded); max_up_rounded, max_down_rounded);
return -ENOBUFS; ret = -ENOBUFS;
goto fail;
} }
if ((*requested_up >= 0 && requested_up_corrected <= allocated_up) || if ((*requested_up >= 0 && requested_up_corrected <= allocated_up) ||
...@@ -2332,7 +2333,7 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, ...@@ -2332,7 +2333,7 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up,
*/ */
ret = tb_release_unused_usb3_bandwidth(tb, in, out); ret = tb_release_unused_usb3_bandwidth(tb, in, out);
if (ret) if (ret)
return ret; goto fail;
/* /*
* Then go over all tunnels that cross the same USB4 ports (they * Then go over all tunnels that cross the same USB4 ports (they
...@@ -2357,7 +2358,7 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, ...@@ -2357,7 +2358,7 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up,
*requested_down); *requested_down);
if (ret) { if (ret) {
tb_configure_sym(tb, in, out, 0, 0, true); tb_configure_sym(tb, in, out, 0, 0, true);
return ret; goto fail;
} }
ret = tb_tunnel_alloc_bandwidth(tunnel, requested_up, ret = tb_tunnel_alloc_bandwidth(tunnel, requested_up,
...@@ -2372,6 +2373,18 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, ...@@ -2372,6 +2373,18 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up,
reclaim: reclaim:
tb_reclaim_usb3_bandwidth(tb, in, out); tb_reclaim_usb3_bandwidth(tb, in, out);
fail:
if (ret && ret != -ENODEV) {
/*
* Write back the same allocated (so no change), this
* makes the DPTX request fail on graphics side.
*/
tb_tunnel_dbg(tunnel,
"failing the request by rewriting allocated %d/%d Mb/s\n",
allocated_up, allocated_down);
tb_tunnel_alloc_bandwidth(tunnel, &allocated_up, &allocated_down);
}
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment