Commit 72ad366f authored by Andreas Noever's avatar Andreas Noever Committed by Greg Kroah-Hartman

thunderbolt: Clear hops before overwriting

Zero hops in tb_path_activate before writing a new path.

This fixes the following scenario:
 - Boot with a coldplugged device
 - Unplug device
 - Plug device back in
 - PCI hotplug fails

The hotplug operation fails because our new path matches the (now
defunct) path which was setup by the firmware for the coldplugged
device. By writing zeros before writing our path configuration we can
force thunderbolt to retrain the path.
Signed-off-by: default avatarAndreas Noever <andreas.noever@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8e8248b1
...@@ -150,7 +150,26 @@ int tb_path_activate(struct tb_path *path) ...@@ -150,7 +150,26 @@ int tb_path_activate(struct tb_path *path)
/* Activate hops. */ /* Activate hops. */
for (i = path->path_length - 1; i >= 0; i--) { for (i = path->path_length - 1; i >= 0; i--) {
struct tb_regs_hop hop; struct tb_regs_hop hop = { 0 };
/*
* We do (currently) not tear down paths setup by the firmeware.
* If a firmware device is unplugged and plugged in again then
* it can happen that we reuse some of the hops from the (now
* defunct) firmeware path. This causes the hotplug operation to
* fail (the pci device does not show up). Clearing the hop
* before overwriting it fixes the problem.
*
* Should be removed once we discover and tear down firmeware
* paths.
*/
res = tb_port_write(path->hops[i].in_port, &hop, TB_CFG_HOPS,
2 * path->hops[i].in_hop_index, 2);
if (res) {
__tb_path_deactivate_hops(path, i);
__tb_path_deallocate_nfc(path, 0);
goto err;
}
/* dword 0 */ /* dword 0 */
hop.next_hop = path->hops[i].next_hop_index; hop.next_hop = path->hops[i].next_hop_index;
......
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