thunderbolt: Do not handle ICM events after domain is stopped

If there is a long chain of devices connected when the driver is loaded
ICM sends device connected event for each and those are put to tb->wq
for later processing. Now if the driver gets unloaded in the middle, so
that the work queue is not yet empty it gets flushed by tb_domain_stop().
However, by that time the root switch is already removed so the driver
crashes when it tries to dereference it in ICM event handling callbacks.

Fix this by checking whether the root switch is already removed. If it
is we know that the domain is stopped and we should merely skip handling
the event.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by Mika Westerberg and committed by Greg Kroah-Hartman 86da809d 70120405

+20 -29
+20 -29
drivers/thunderbolt/icm.c
··· 738 u8 link, depth; 739 u64 route; 740 741 - /* 742 - * After NVM upgrade adding root switch device fails because we 743 - * initiated reset. During that time ICM might still send 744 - * XDomain connected message which we ignore here. 745 - */ 746 - if (!tb->root_switch) 747 - return; 748 - 749 link = pkg->link_info & ICM_LINK_INFO_LINK_MASK; 750 depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >> 751 ICM_LINK_INFO_DEPTH_SHIFT; ··· 1027 * packet for now. 1028 */ 1029 if (pkg->hdr.packet_id) 1030 - return; 1031 - 1032 - /* 1033 - * After NVM upgrade adding root switch device fails because we 1034 - * initiated reset. During that time ICM might still send device 1035 - * connected message which we ignore here. 1036 - */ 1037 - if (!tb->root_switch) 1038 return; 1039 1040 route = get_route(pkg->route_hi, pkg->route_lo); ··· 1392 1393 mutex_lock(&tb->lock); 1394 1395 - switch (n->pkg->code) { 1396 - case ICM_EVENT_DEVICE_CONNECTED: 1397 - icm->device_connected(tb, n->pkg); 1398 - break; 1399 - case ICM_EVENT_DEVICE_DISCONNECTED: 1400 - icm->device_disconnected(tb, n->pkg); 1401 - break; 1402 - case ICM_EVENT_XDOMAIN_CONNECTED: 1403 - icm->xdomain_connected(tb, n->pkg); 1404 - break; 1405 - case ICM_EVENT_XDOMAIN_DISCONNECTED: 1406 - icm->xdomain_disconnected(tb, n->pkg); 1407 - break; 1408 } 1409 1410 mutex_unlock(&tb->lock);
··· 738 u8 link, depth; 739 u64 route; 740 741 link = pkg->link_info & ICM_LINK_INFO_LINK_MASK; 742 depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >> 743 ICM_LINK_INFO_DEPTH_SHIFT; ··· 1035 * packet for now. 1036 */ 1037 if (pkg->hdr.packet_id) 1038 return; 1039 1040 route = get_route(pkg->route_hi, pkg->route_lo); ··· 1408 1409 mutex_lock(&tb->lock); 1410 1411 + /* 1412 + * When the domain is stopped we flush its workqueue but before 1413 + * that the root switch is removed. In that case we should treat 1414 + * the queued events as being canceled. 1415 + */ 1416 + if (tb->root_switch) { 1417 + switch (n->pkg->code) { 1418 + case ICM_EVENT_DEVICE_CONNECTED: 1419 + icm->device_connected(tb, n->pkg); 1420 + break; 1421 + case ICM_EVENT_DEVICE_DISCONNECTED: 1422 + icm->device_disconnected(tb, n->pkg); 1423 + break; 1424 + case ICM_EVENT_XDOMAIN_CONNECTED: 1425 + icm->xdomain_connected(tb, n->pkg); 1426 + break; 1427 + case ICM_EVENT_XDOMAIN_DISCONNECTED: 1428 + icm->xdomain_disconnected(tb, n->pkg); 1429 + break; 1430 + } 1431 } 1432 1433 mutex_unlock(&tb->lock);