Lines Matching +full:0 +full:xd
81 UUID_INIT(0xb638d70e, 0x42ff, 0x40bb,
82 0x97, 0xc2, 0x90, 0xe2, 0xc0, 0xb2, 0xff, 0x07);
126 req->result.err = 0; in tb_xdomain_copy()
155 * @xd: XDomain to send the message
163 * Return: %0 in case of success and negative errno in case of failure
165 int tb_xdomain_response(struct tb_xdomain *xd, const void *response, in tb_xdomain_response() argument
168 return __tb_xdomain_response(xd->tb->ctl, response, size, type); in tb_xdomain_response()
202 * @xd: XDomain to send the request
215 * Return: %0 in case of success and negative errno in case of failure
217 int tb_xdomain_request(struct tb_xdomain *xd, const void *request, in tb_xdomain_request() argument
222 return __tb_xdomain_request(xd->tb->ctl, request, request_size, in tb_xdomain_request()
246 return 0; in tb_xdp_handle_error()
260 return 0; in tb_xdp_handle_error()
270 memset(&req, 0, sizeof(req)); in tb_xdp_uuid_request()
274 memset(&res, 0, sizeof(res)); in tb_xdp_uuid_request()
289 return 0; in tb_xdp_uuid_request()
297 memset(&res, 0, sizeof(res)); in tb_xdp_uuid_response()
314 memset(&res, 0, sizeof(res)); in tb_xdp_error_response()
339 memset(&req, 0, sizeof(req)); in tb_xdp_properties_request()
345 data_len = 0; in tb_xdp_properties_request()
415 struct tb_xdomain *xd, u8 sequence, const struct tb_xdp_properties *req) in tb_xdp_properties_response() argument
427 if (!uuid_equal(xd->local_uuid, &req->dst_uuid)) { in tb_xdp_properties_response()
428 tb_xdp_error_response(ctl, xd->route, sequence, in tb_xdp_properties_response()
430 return 0; in tb_xdp_properties_response()
433 mutex_lock(&xd->lock); in tb_xdp_properties_response()
435 if (req->offset >= xd->local_property_block_len) { in tb_xdp_properties_response()
436 mutex_unlock(&xd->lock); in tb_xdp_properties_response()
440 len = xd->local_property_block_len - req->offset; in tb_xdp_properties_response()
446 mutex_unlock(&xd->lock); in tb_xdp_properties_response()
450 tb_xdp_fill_header(&res->hdr, xd->route, sequence, PROPERTIES_RESPONSE, in tb_xdp_properties_response()
452 res->generation = xd->local_property_block_gen; in tb_xdp_properties_response()
453 res->data_length = xd->local_property_block_len; in tb_xdp_properties_response()
455 uuid_copy(&res->src_uuid, xd->local_uuid); in tb_xdp_properties_response()
457 memcpy(res->data, &xd->local_property_block[req->offset], len * 4); in tb_xdp_properties_response()
459 mutex_unlock(&xd->lock); in tb_xdp_properties_response()
475 memset(&req, 0, sizeof(req)); in tb_xdp_properties_changed_request()
480 memset(&res, 0, sizeof(res)); in tb_xdp_properties_changed_request()
496 memset(&res, 0, sizeof(res)); in tb_xdp_properties_changed_response()
511 memset(&req, 0, sizeof(req)); in tb_xdp_link_state_status_request()
515 memset(&res, 0, sizeof(res)); in tb_xdp_link_state_status_request()
526 if (res.status != 0) in tb_xdp_link_state_status_request()
534 return 0; in tb_xdp_link_state_status_request()
538 struct tb_xdomain *xd, u8 sequence) in tb_xdp_link_state_status_response() argument
541 struct tb_port *port = tb_xdomain_downstream_port(xd); in tb_xdp_link_state_status_response()
545 memset(&res, 0, sizeof(res)); in tb_xdp_link_state_status_response()
546 tb_xdp_fill_header(&res.hdr, xd->route, sequence, in tb_xdp_link_state_status_response()
554 res.slw = (val[0] & LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK) >> in tb_xdp_link_state_status_response()
556 res.sls = (val[0] & LANE_ADP_CS_0_SUPPORTED_SPEED_MASK) >> in tb_xdp_link_state_status_response()
573 memset(&req, 0, sizeof(req)); in tb_xdp_link_state_change_request()
579 memset(&res, 0, sizeof(res)); in tb_xdp_link_state_change_request()
590 return res.status != 0 ? -EREMOTEIO : 0; in tb_xdp_link_state_change_request()
598 memset(&res, 0, sizeof(res)); in tb_xdp_link_state_change_response()
628 return 0; in tb_register_protocol_handler()
646 static void update_property_block(struct tb_xdomain *xd) in update_property_block() argument
649 mutex_lock(&xd->lock); in update_property_block()
654 if (!xd->local_property_block || in update_property_block()
655 xd->local_property_block_gen < xdomain_property_block_gen) { in update_property_block()
662 dev_warn(&xd->dev, "failed to copy properties\n"); in update_property_block()
668 tb_property_add_immediate(dir, "maxhopid", xd->local_max_hopid); in update_property_block()
670 ret = tb_property_format_dir(dir, NULL, 0); in update_property_block()
671 if (ret < 0) { in update_property_block()
672 dev_warn(&xd->dev, "local property block creation failed\n"); in update_property_block()
686 dev_warn(&xd->dev, "property block generation failed\n"); in update_property_block()
694 kfree(xd->local_property_block); in update_property_block()
696 xd->local_property_block = block; in update_property_block()
697 xd->local_property_block_len = block_len; in update_property_block()
698 xd->local_property_block_gen = xdomain_property_block_gen; in update_property_block()
702 mutex_unlock(&xd->lock); in update_property_block()
706 static void start_handshake(struct tb_xdomain *xd) in start_handshake() argument
708 xd->state = XDOMAIN_STATE_INIT; in start_handshake()
709 queue_delayed_work(xd->tb->wq, &xd->state_work, in start_handshake()
714 static void __stop_handshake(struct tb_xdomain *xd) in __stop_handshake() argument
716 cancel_delayed_work_sync(&xd->properties_changed_work); in __stop_handshake()
717 xd->properties_changed_retries = 0; in __stop_handshake()
718 xd->state_retries = 0; in __stop_handshake()
721 static void stop_handshake(struct tb_xdomain *xd) in stop_handshake() argument
723 cancel_delayed_work_sync(&xd->state_work); in stop_handshake()
724 __stop_handshake(xd); in stop_handshake()
734 struct tb_xdomain *xd; in tb_xdp_handle_request() local
736 int ret = 0; in tb_xdp_handle_request()
756 xd = tb_xdomain_find_by_route_locked(tb, route); in tb_xdp_handle_request()
757 if (xd) in tb_xdp_handle_request()
758 update_property_block(xd); in tb_xdp_handle_request()
763 if (xd) { in tb_xdp_handle_request()
764 ret = tb_xdp_properties_response(tb, ctl, xd, sequence, in tb_xdp_handle_request()
780 if (xd && device_is_registered(&xd->dev)) in tb_xdp_handle_request()
781 queue_delayed_work(tb->wq, &xd->state_work, in tb_xdp_handle_request()
794 if (!ret && xd && xd->state == XDOMAIN_STATE_ERROR) { in tb_xdp_handle_request()
795 dev_dbg(&xd->dev, "restarting handshake\n"); in tb_xdp_handle_request()
796 start_handshake(xd); in tb_xdp_handle_request()
804 if (xd) { in tb_xdp_handle_request()
805 ret = tb_xdp_link_state_status_response(tb, ctl, xd, in tb_xdp_handle_request()
817 if (xd && xd->state == XDOMAIN_STATE_BONDING_UUID_HIGH) { in tb_xdp_handle_request()
822 sequence, 0); in tb_xdp_handle_request()
823 xd->target_link_width = lsc->tlw; in tb_xdp_handle_request()
824 queue_delayed_work(tb->wq, &xd->state_work, in tb_xdp_handle_request()
839 tb_xdomain_put(xd); in tb_xdp_handle_request()
962 return sysfs_emit(buf, "0x%08x\n", svc->prtcstns); in prtcstns_show()
997 struct tb_xdomain *xd = tb_service_parent(svc); in tb_service_release() local
1000 ida_free(&xd->service_ids, svc->id); in tb_service_release()
1015 struct tb_xdomain *xd = data; in remove_missing_service() local
1020 return 0; in remove_missing_service()
1022 if (!tb_property_find(xd->remote_properties, svc->key, in remove_missing_service()
1026 return 0; in remove_missing_service()
1036 return 0; in find_service()
1065 return 0; in populate_service()
1068 static void enumerate_services(struct tb_xdomain *xd) in enumerate_services() argument
1079 device_for_each_child_reverse(&xd->dev, xd, remove_missing_service); in enumerate_services()
1082 tb_property_for_each(xd->remote_properties, p) { in enumerate_services()
1087 dev = device_find_child(&xd->dev, p, find_service); in enumerate_services()
1102 id = ida_alloc(&xd->service_ids, GFP_KERNEL); in enumerate_services()
1103 if (id < 0) { in enumerate_services()
1111 svc->dev.parent = &xd->dev; in enumerate_services()
1112 dev_set_name(&svc->dev, "%s.%d", dev_name(&xd->dev), svc->id); in enumerate_services()
1123 static int populate_properties(struct tb_xdomain *xd, in populate_properties() argument
1132 xd->device = p->value.immediate; in populate_properties()
1137 xd->vendor = p->value.immediate; in populate_properties()
1145 xd->remote_max_hopid = p ? p->value.immediate : XDOMAIN_DEFAULT_MAX_HOPID; in populate_properties()
1147 kfree(xd->device_name); in populate_properties()
1148 xd->device_name = NULL; in populate_properties()
1149 kfree(xd->vendor_name); in populate_properties()
1150 xd->vendor_name = NULL; in populate_properties()
1155 xd->device_name = kstrdup(p->value.text, GFP_KERNEL); in populate_properties()
1158 xd->vendor_name = kstrdup(p->value.text, GFP_KERNEL); in populate_properties()
1160 return 0; in populate_properties()
1163 static int tb_xdomain_update_link_attributes(struct tb_xdomain *xd) in tb_xdomain_update_link_attributes() argument
1169 port = tb_xdomain_downstream_port(xd); in tb_xdomain_update_link_attributes()
1172 if (ret < 0) in tb_xdomain_update_link_attributes()
1175 if (xd->link_speed != ret) in tb_xdomain_update_link_attributes()
1178 xd->link_speed = ret; in tb_xdomain_update_link_attributes()
1181 if (ret < 0) in tb_xdomain_update_link_attributes()
1184 if (xd->link_width != ret) in tb_xdomain_update_link_attributes()
1187 xd->link_width = ret; in tb_xdomain_update_link_attributes()
1190 kobject_uevent(&xd->dev.kobj, KOBJ_CHANGE); in tb_xdomain_update_link_attributes()
1192 return 0; in tb_xdomain_update_link_attributes()
1195 static int tb_xdomain_get_uuid(struct tb_xdomain *xd) in tb_xdomain_get_uuid() argument
1197 struct tb *tb = xd->tb; in tb_xdomain_get_uuid()
1202 dev_dbg(&xd->dev, "requesting remote UUID\n"); in tb_xdomain_get_uuid()
1204 ret = tb_xdp_uuid_request(tb->ctl, xd->route, xd->state_retries, &uuid, in tb_xdomain_get_uuid()
1206 if (ret < 0) { in tb_xdomain_get_uuid()
1207 if (xd->state_retries-- > 0) { in tb_xdomain_get_uuid()
1208 dev_dbg(&xd->dev, "failed to request UUID, retrying\n"); in tb_xdomain_get_uuid()
1211 dev_dbg(&xd->dev, "failed to read remote UUID\n"); in tb_xdomain_get_uuid()
1215 dev_dbg(&xd->dev, "got remote UUID %pUb\n", &uuid); in tb_xdomain_get_uuid()
1217 if (uuid_equal(&uuid, xd->local_uuid)) { in tb_xdomain_get_uuid()
1218 if (route == xd->route) in tb_xdomain_get_uuid()
1219 dev_dbg(&xd->dev, "loop back detected\n"); in tb_xdomain_get_uuid()
1221 dev_dbg(&xd->dev, "intra-domain loop detected\n"); in tb_xdomain_get_uuid()
1224 xd->bonding_possible = false; in tb_xdomain_get_uuid()
1232 if (xd->remote_uuid && !uuid_equal(&uuid, xd->remote_uuid)) { in tb_xdomain_get_uuid()
1233 dev_dbg(&xd->dev, "remote UUID is different, unplugging\n"); in tb_xdomain_get_uuid()
1234 xd->is_unplugged = true; in tb_xdomain_get_uuid()
1239 if (!xd->remote_uuid) { in tb_xdomain_get_uuid()
1240 xd->remote_uuid = kmemdup(&uuid, sizeof(uuid_t), GFP_KERNEL); in tb_xdomain_get_uuid()
1241 if (!xd->remote_uuid) in tb_xdomain_get_uuid()
1245 return 0; in tb_xdomain_get_uuid()
1248 static int tb_xdomain_get_link_status(struct tb_xdomain *xd) in tb_xdomain_get_link_status() argument
1250 struct tb *tb = xd->tb; in tb_xdomain_get_link_status()
1254 dev_dbg(&xd->dev, "sending link state status request to %pUb\n", in tb_xdomain_get_link_status()
1255 xd->remote_uuid); in tb_xdomain_get_link_status()
1257 ret = tb_xdp_link_state_status_request(tb->ctl, xd->route, in tb_xdomain_get_link_status()
1258 xd->state_retries, &slw, &tlw, &sls, in tb_xdomain_get_link_status()
1261 if (ret != -EOPNOTSUPP && xd->state_retries-- > 0) { in tb_xdomain_get_link_status()
1262 dev_dbg(&xd->dev, in tb_xdomain_get_link_status()
1266 dev_dbg(&xd->dev, "failed to receive remote link status\n"); in tb_xdomain_get_link_status()
1270 dev_dbg(&xd->dev, "remote link supports width %#x speed %#x\n", slw, sls); in tb_xdomain_get_link_status()
1273 dev_dbg(&xd->dev, "remote adapter is single lane only\n"); in tb_xdomain_get_link_status()
1277 return 0; in tb_xdomain_get_link_status()
1280 static int tb_xdomain_link_state_change(struct tb_xdomain *xd, in tb_xdomain_link_state_change() argument
1283 struct tb_port *port = tb_xdomain_downstream_port(xd); in tb_xdomain_link_state_change()
1284 struct tb *tb = xd->tb; in tb_xdomain_link_state_change()
1302 dev_dbg(&xd->dev, "sending link state change request with width %#x speed %#x\n", in tb_xdomain_link_state_change()
1305 ret = tb_xdp_link_state_change_request(tb->ctl, xd->route, in tb_xdomain_link_state_change()
1306 xd->state_retries, tlw, tls); in tb_xdomain_link_state_change()
1308 if (ret != -EOPNOTSUPP && xd->state_retries-- > 0) { in tb_xdomain_link_state_change()
1309 dev_dbg(&xd->dev, in tb_xdomain_link_state_change()
1313 dev_err(&xd->dev, "failed request link state change, aborting\n"); in tb_xdomain_link_state_change()
1317 dev_dbg(&xd->dev, "received link state change response\n"); in tb_xdomain_link_state_change()
1318 return 0; in tb_xdomain_link_state_change()
1321 static int tb_xdomain_bond_lanes_uuid_high(struct tb_xdomain *xd) in tb_xdomain_bond_lanes_uuid_high() argument
1327 if (xd->target_link_width == LANE_ADP_CS_1_TARGET_WIDTH_SINGLE) { in tb_xdomain_bond_lanes_uuid_high()
1330 } else if (xd->target_link_width == LANE_ADP_CS_1_TARGET_WIDTH_DUAL) { in tb_xdomain_bond_lanes_uuid_high()
1334 if (xd->state_retries-- > 0) { in tb_xdomain_bond_lanes_uuid_high()
1335 dev_dbg(&xd->dev, in tb_xdomain_bond_lanes_uuid_high()
1339 dev_dbg(&xd->dev, "timeout waiting for link change request\n"); in tb_xdomain_bond_lanes_uuid_high()
1343 port = tb_xdomain_downstream_port(xd); in tb_xdomain_bond_lanes_uuid_high()
1367 dev_warn(&xd->dev, "error waiting for link width to become %d\n", in tb_xdomain_bond_lanes_uuid_high()
1376 tb_xdomain_update_link_attributes(xd); in tb_xdomain_bond_lanes_uuid_high()
1378 dev_dbg(&xd->dev, "lane bonding %s\n", str_enabled_disabled(width == 2)); in tb_xdomain_bond_lanes_uuid_high()
1379 return 0; in tb_xdomain_bond_lanes_uuid_high()
1382 static int tb_xdomain_get_properties(struct tb_xdomain *xd) in tb_xdomain_get_properties() argument
1385 struct tb *tb = xd->tb; in tb_xdomain_get_properties()
1388 u32 gen = 0; in tb_xdomain_get_properties()
1391 dev_dbg(&xd->dev, "requesting remote properties\n"); in tb_xdomain_get_properties()
1393 ret = tb_xdp_properties_request(tb->ctl, xd->route, xd->local_uuid, in tb_xdomain_get_properties()
1394 xd->remote_uuid, xd->state_retries, in tb_xdomain_get_properties()
1396 if (ret < 0) { in tb_xdomain_get_properties()
1397 if (xd->state_retries-- > 0) { in tb_xdomain_get_properties()
1398 dev_dbg(&xd->dev, in tb_xdomain_get_properties()
1403 dev_err(&xd->dev, "failed read XDomain properties from %pUb\n", in tb_xdomain_get_properties()
1404 xd->remote_uuid); in tb_xdomain_get_properties()
1409 mutex_lock(&xd->lock); in tb_xdomain_get_properties()
1412 if (xd->remote_properties && gen <= xd->remote_property_block_gen) { in tb_xdomain_get_properties()
1413 ret = 0; in tb_xdomain_get_properties()
1419 dev_err(&xd->dev, "failed to parse XDomain properties\n"); in tb_xdomain_get_properties()
1424 ret = populate_properties(xd, dir); in tb_xdomain_get_properties()
1426 dev_err(&xd->dev, "missing XDomain properties in response\n"); in tb_xdomain_get_properties()
1431 if (xd->remote_properties) { in tb_xdomain_get_properties()
1432 tb_property_free_dir(xd->remote_properties); in tb_xdomain_get_properties()
1436 xd->remote_properties = dir; in tb_xdomain_get_properties()
1437 xd->remote_property_block_gen = gen; in tb_xdomain_get_properties()
1439 tb_xdomain_update_link_attributes(xd); in tb_xdomain_get_properties()
1441 mutex_unlock(&xd->lock); in tb_xdomain_get_properties()
1457 if (xd->bonding_possible) { in tb_xdomain_get_properties()
1460 port = tb_xdomain_downstream_port(xd); in tb_xdomain_get_properties()
1465 dev_dbg(&xd->dev, "current link speed %u.0 Gb/s\n", in tb_xdomain_get_properties()
1466 xd->link_speed); in tb_xdomain_get_properties()
1467 dev_dbg(&xd->dev, "current link width %s\n", in tb_xdomain_get_properties()
1468 tb_width_name(xd->link_width)); in tb_xdomain_get_properties()
1470 if (device_add(&xd->dev)) { in tb_xdomain_get_properties()
1471 dev_err(&xd->dev, "failed to add XDomain device\n"); in tb_xdomain_get_properties()
1474 dev_info(&xd->dev, "new host found, vendor=%#x device=%#x\n", in tb_xdomain_get_properties()
1475 xd->vendor, xd->device); in tb_xdomain_get_properties()
1476 if (xd->vendor_name && xd->device_name) in tb_xdomain_get_properties()
1477 dev_info(&xd->dev, "%s %s\n", xd->vendor_name, in tb_xdomain_get_properties()
1478 xd->device_name); in tb_xdomain_get_properties()
1480 tb_xdomain_debugfs_init(xd); in tb_xdomain_get_properties()
1482 kobject_uevent(&xd->dev.kobj, KOBJ_CHANGE); in tb_xdomain_get_properties()
1485 enumerate_services(xd); in tb_xdomain_get_properties()
1486 return 0; in tb_xdomain_get_properties()
1492 mutex_unlock(&xd->lock); in tb_xdomain_get_properties()
1497 static void tb_xdomain_queue_uuid(struct tb_xdomain *xd) in tb_xdomain_queue_uuid() argument
1499 xd->state = XDOMAIN_STATE_UUID; in tb_xdomain_queue_uuid()
1500 xd->state_retries = XDOMAIN_RETRIES; in tb_xdomain_queue_uuid()
1501 queue_delayed_work(xd->tb->wq, &xd->state_work, in tb_xdomain_queue_uuid()
1505 static void tb_xdomain_queue_link_status(struct tb_xdomain *xd) in tb_xdomain_queue_link_status() argument
1507 xd->state = XDOMAIN_STATE_LINK_STATUS; in tb_xdomain_queue_link_status()
1508 xd->state_retries = XDOMAIN_RETRIES; in tb_xdomain_queue_link_status()
1509 queue_delayed_work(xd->tb->wq, &xd->state_work, in tb_xdomain_queue_link_status()
1513 static void tb_xdomain_queue_link_status2(struct tb_xdomain *xd) in tb_xdomain_queue_link_status2() argument
1515 xd->state = XDOMAIN_STATE_LINK_STATUS2; in tb_xdomain_queue_link_status2()
1516 xd->state_retries = XDOMAIN_RETRIES; in tb_xdomain_queue_link_status2()
1517 queue_delayed_work(xd->tb->wq, &xd->state_work, in tb_xdomain_queue_link_status2()
1521 static void tb_xdomain_queue_bonding(struct tb_xdomain *xd) in tb_xdomain_queue_bonding() argument
1523 if (memcmp(xd->local_uuid, xd->remote_uuid, UUID_SIZE) > 0) { in tb_xdomain_queue_bonding()
1524 dev_dbg(&xd->dev, "we have higher UUID, other side bonds the lanes\n"); in tb_xdomain_queue_bonding()
1525 xd->state = XDOMAIN_STATE_BONDING_UUID_HIGH; in tb_xdomain_queue_bonding()
1527 dev_dbg(&xd->dev, "we have lower UUID, bonding lanes\n"); in tb_xdomain_queue_bonding()
1528 xd->state = XDOMAIN_STATE_LINK_STATE_CHANGE; in tb_xdomain_queue_bonding()
1531 xd->state_retries = XDOMAIN_RETRIES; in tb_xdomain_queue_bonding()
1532 queue_delayed_work(xd->tb->wq, &xd->state_work, in tb_xdomain_queue_bonding()
1536 static void tb_xdomain_queue_bonding_uuid_low(struct tb_xdomain *xd) in tb_xdomain_queue_bonding_uuid_low() argument
1538 xd->state = XDOMAIN_STATE_BONDING_UUID_LOW; in tb_xdomain_queue_bonding_uuid_low()
1539 xd->state_retries = XDOMAIN_RETRIES; in tb_xdomain_queue_bonding_uuid_low()
1540 queue_delayed_work(xd->tb->wq, &xd->state_work, in tb_xdomain_queue_bonding_uuid_low()
1544 static void tb_xdomain_queue_properties(struct tb_xdomain *xd) in tb_xdomain_queue_properties() argument
1546 xd->state = XDOMAIN_STATE_PROPERTIES; in tb_xdomain_queue_properties()
1547 xd->state_retries = XDOMAIN_RETRIES; in tb_xdomain_queue_properties()
1548 queue_delayed_work(xd->tb->wq, &xd->state_work, in tb_xdomain_queue_properties()
1552 static void tb_xdomain_queue_properties_changed(struct tb_xdomain *xd) in tb_xdomain_queue_properties_changed() argument
1554 xd->properties_changed_retries = XDOMAIN_RETRIES; in tb_xdomain_queue_properties_changed()
1555 queue_delayed_work(xd->tb->wq, &xd->properties_changed_work, in tb_xdomain_queue_properties_changed()
1559 static void tb_xdomain_failed(struct tb_xdomain *xd) in tb_xdomain_failed() argument
1561 xd->state = XDOMAIN_STATE_ERROR; in tb_xdomain_failed()
1562 queue_delayed_work(xd->tb->wq, &xd->state_work, in tb_xdomain_failed()
1568 struct tb_xdomain *xd = container_of(work, typeof(*xd), state_work.work); in tb_xdomain_state_work() local
1569 int ret, state = xd->state; in tb_xdomain_state_work()
1575 dev_dbg(&xd->dev, "running state %s\n", state_names[state]); in tb_xdomain_state_work()
1579 if (xd->needs_uuid) { in tb_xdomain_state_work()
1580 tb_xdomain_queue_uuid(xd); in tb_xdomain_state_work()
1582 tb_xdomain_queue_properties_changed(xd); in tb_xdomain_state_work()
1583 tb_xdomain_queue_properties(xd); in tb_xdomain_state_work()
1588 ret = tb_xdomain_get_uuid(xd); in tb_xdomain_state_work()
1592 tb_xdomain_failed(xd); in tb_xdomain_state_work()
1594 tb_xdomain_queue_properties_changed(xd); in tb_xdomain_state_work()
1595 if (xd->bonding_possible) in tb_xdomain_state_work()
1596 tb_xdomain_queue_link_status(xd); in tb_xdomain_state_work()
1598 tb_xdomain_queue_properties(xd); in tb_xdomain_state_work()
1603 ret = tb_xdomain_get_link_status(xd); in tb_xdomain_state_work()
1613 tb_xdomain_queue_properties(xd); in tb_xdomain_state_work()
1615 tb_xdomain_queue_bonding(xd); in tb_xdomain_state_work()
1620 ret = tb_xdomain_link_state_change(xd, 2); in tb_xdomain_state_work()
1624 tb_xdomain_queue_properties(xd); in tb_xdomain_state_work()
1626 tb_xdomain_queue_link_status2(xd); in tb_xdomain_state_work()
1631 ret = tb_xdomain_get_link_status(xd); in tb_xdomain_state_work()
1635 tb_xdomain_queue_properties(xd); in tb_xdomain_state_work()
1637 tb_xdomain_queue_bonding_uuid_low(xd); in tb_xdomain_state_work()
1642 tb_xdomain_lane_bonding_enable(xd); in tb_xdomain_state_work()
1643 tb_xdomain_queue_properties(xd); in tb_xdomain_state_work()
1647 if (tb_xdomain_bond_lanes_uuid_high(xd) == -EAGAIN) in tb_xdomain_state_work()
1649 tb_xdomain_queue_properties(xd); in tb_xdomain_state_work()
1653 ret = tb_xdomain_get_properties(xd); in tb_xdomain_state_work()
1657 tb_xdomain_failed(xd); in tb_xdomain_state_work()
1659 xd->state = XDOMAIN_STATE_ENUMERATED; in tb_xdomain_state_work()
1664 tb_xdomain_queue_properties(xd); in tb_xdomain_state_work()
1668 dev_dbg(&xd->dev, "discovery failed, stopping handshake\n"); in tb_xdomain_state_work()
1669 __stop_handshake(xd); in tb_xdomain_state_work()
1673 dev_warn(&xd->dev, "unexpected state %d\n", state); in tb_xdomain_state_work()
1680 queue_delayed_work(xd->tb->wq, &xd->state_work, in tb_xdomain_state_work()
1686 struct tb_xdomain *xd = container_of(work, typeof(*xd), in tb_xdomain_properties_changed() local
1690 dev_dbg(&xd->dev, "sending properties changed notification\n"); in tb_xdomain_properties_changed()
1692 ret = tb_xdp_properties_changed_request(xd->tb->ctl, xd->route, in tb_xdomain_properties_changed()
1693 xd->properties_changed_retries, xd->local_uuid); in tb_xdomain_properties_changed()
1695 if (xd->properties_changed_retries-- > 0) { in tb_xdomain_properties_changed()
1696 dev_dbg(&xd->dev, in tb_xdomain_properties_changed()
1698 queue_delayed_work(xd->tb->wq, in tb_xdomain_properties_changed()
1699 &xd->properties_changed_work, in tb_xdomain_properties_changed()
1702 dev_err(&xd->dev, "failed to send properties changed notification\n"); in tb_xdomain_properties_changed()
1706 xd->properties_changed_retries = XDOMAIN_RETRIES; in tb_xdomain_properties_changed()
1712 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in device_show() local
1714 return sysfs_emit(buf, "%#x\n", xd->device); in device_show()
1721 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in device_name_show() local
1724 if (mutex_lock_interruptible(&xd->lock)) in device_name_show()
1726 ret = sysfs_emit(buf, "%s\n", xd->device_name ?: ""); in device_name_show()
1727 mutex_unlock(&xd->lock); in device_name_show()
1736 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in maxhopid_show() local
1738 return sysfs_emit(buf, "%d\n", xd->remote_max_hopid); in maxhopid_show()
1745 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in vendor_show() local
1747 return sysfs_emit(buf, "%#x\n", xd->vendor); in vendor_show()
1754 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in vendor_name_show() local
1757 if (mutex_lock_interruptible(&xd->lock)) in vendor_name_show()
1759 ret = sysfs_emit(buf, "%s\n", xd->vendor_name ?: ""); in vendor_name_show()
1760 mutex_unlock(&xd->lock); in vendor_name_show()
1769 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in unique_id_show() local
1771 return sysfs_emit(buf, "%pUb\n", xd->remote_uuid); in unique_id_show()
1778 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in speed_show() local
1780 return sysfs_emit(buf, "%u.0 Gb/s\n", xd->link_speed); in speed_show()
1789 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in rx_lanes_show() local
1792 switch (xd->link_width) { in rx_lanes_show()
1815 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in tx_lanes_show() local
1818 switch (xd->link_width) { in tx_lanes_show()
1863 struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev); in tb_xdomain_release() local
1865 put_device(xd->dev.parent); in tb_xdomain_release()
1867 kfree(xd->local_property_block); in tb_xdomain_release()
1868 tb_property_free_dir(xd->remote_properties); in tb_xdomain_release()
1869 ida_destroy(&xd->out_hopids); in tb_xdomain_release()
1870 ida_destroy(&xd->in_hopids); in tb_xdomain_release()
1871 ida_destroy(&xd->service_ids); in tb_xdomain_release()
1873 kfree(xd->local_uuid); in tb_xdomain_release()
1874 kfree(xd->remote_uuid); in tb_xdomain_release()
1875 kfree(xd->device_name); in tb_xdomain_release()
1876 kfree(xd->vendor_name); in tb_xdomain_release()
1877 kfree(xd); in tb_xdomain_release()
1883 return 0; in tb_xdomain_suspend()
1889 return 0; in tb_xdomain_resume()
1903 static void tb_xdomain_link_init(struct tb_xdomain *xd, struct tb_port *down) in tb_xdomain_link_init() argument
1916 xd->bonding_possible = true; in tb_xdomain_link_init()
1920 static void tb_xdomain_link_exit(struct tb_xdomain *xd) in tb_xdomain_link_exit() argument
1922 struct tb_port *down = tb_xdomain_downstream_port(xd); in tb_xdomain_link_exit()
1930 } else if (xd->link_width > TB_LINK_WIDTH_SINGLE) { in tb_xdomain_link_exit()
1964 struct tb_xdomain *xd; in tb_xdomain_alloc() local
1971 xd = kzalloc(sizeof(*xd), GFP_KERNEL); in tb_xdomain_alloc()
1972 if (!xd) in tb_xdomain_alloc()
1975 xd->tb = tb; in tb_xdomain_alloc()
1976 xd->route = route; in tb_xdomain_alloc()
1977 xd->local_max_hopid = down->config.max_in_hop_id; in tb_xdomain_alloc()
1978 ida_init(&xd->service_ids); in tb_xdomain_alloc()
1979 ida_init(&xd->in_hopids); in tb_xdomain_alloc()
1980 ida_init(&xd->out_hopids); in tb_xdomain_alloc()
1981 mutex_init(&xd->lock); in tb_xdomain_alloc()
1982 INIT_DELAYED_WORK(&xd->state_work, tb_xdomain_state_work); in tb_xdomain_alloc()
1983 INIT_DELAYED_WORK(&xd->properties_changed_work, in tb_xdomain_alloc()
1986 xd->local_uuid = kmemdup(local_uuid, sizeof(uuid_t), GFP_KERNEL); in tb_xdomain_alloc()
1987 if (!xd->local_uuid) in tb_xdomain_alloc()
1991 xd->remote_uuid = kmemdup(remote_uuid, sizeof(uuid_t), in tb_xdomain_alloc()
1993 if (!xd->remote_uuid) in tb_xdomain_alloc()
1996 xd->needs_uuid = true; in tb_xdomain_alloc()
1998 tb_xdomain_link_init(xd, down); in tb_xdomain_alloc()
2001 device_initialize(&xd->dev); in tb_xdomain_alloc()
2002 xd->dev.parent = get_device(parent); in tb_xdomain_alloc()
2003 xd->dev.bus = &tb_bus_type; in tb_xdomain_alloc()
2004 xd->dev.type = &tb_xdomain_type; in tb_xdomain_alloc()
2005 xd->dev.groups = xdomain_attr_groups; in tb_xdomain_alloc()
2006 dev_set_name(&xd->dev, "%u-%llx", tb->index, route); in tb_xdomain_alloc()
2008 dev_dbg(&xd->dev, "local UUID %pUb\n", local_uuid); in tb_xdomain_alloc()
2010 dev_dbg(&xd->dev, "remote UUID %pUb\n", remote_uuid); in tb_xdomain_alloc()
2016 pm_runtime_set_active(&xd->dev); in tb_xdomain_alloc()
2017 pm_runtime_get_noresume(&xd->dev); in tb_xdomain_alloc()
2018 pm_runtime_enable(&xd->dev); in tb_xdomain_alloc()
2020 return xd; in tb_xdomain_alloc()
2023 kfree(xd->local_uuid); in tb_xdomain_alloc()
2025 kfree(xd); in tb_xdomain_alloc()
2032 * @xd: XDomain to add
2039 void tb_xdomain_add(struct tb_xdomain *xd) in tb_xdomain_add() argument
2042 start_handshake(xd); in tb_xdomain_add()
2048 return 0; in unregister_service()
2053 * @xd: XDomain to remove
2056 * along with any services from the bus. When the last reference to @xd
2059 void tb_xdomain_remove(struct tb_xdomain *xd) in tb_xdomain_remove() argument
2061 tb_xdomain_debugfs_remove(xd); in tb_xdomain_remove()
2063 stop_handshake(xd); in tb_xdomain_remove()
2065 device_for_each_child_reverse(&xd->dev, xd, unregister_service); in tb_xdomain_remove()
2067 tb_xdomain_link_exit(xd); in tb_xdomain_remove()
2074 pm_runtime_disable(&xd->dev); in tb_xdomain_remove()
2075 pm_runtime_put_noidle(&xd->dev); in tb_xdomain_remove()
2076 pm_runtime_set_suspended(&xd->dev); in tb_xdomain_remove()
2078 if (!device_is_registered(&xd->dev)) { in tb_xdomain_remove()
2079 put_device(&xd->dev); in tb_xdomain_remove()
2081 dev_info(&xd->dev, "host disconnected\n"); in tb_xdomain_remove()
2082 device_unregister(&xd->dev); in tb_xdomain_remove()
2088 * @xd: XDomain connection
2094 * Return: %0 in case of success and negative errno in case of error.
2096 int tb_xdomain_lane_bonding_enable(struct tb_xdomain *xd) in tb_xdomain_lane_bonding_enable() argument
2102 port = tb_xdomain_downstream_port(xd); in tb_xdomain_lane_bonding_enable()
2111 if (ret < 0) in tb_xdomain_lane_bonding_enable()
2134 tb_xdomain_update_link_attributes(xd); in tb_xdomain_lane_bonding_enable()
2136 dev_dbg(&xd->dev, "lane bonding enabled\n"); in tb_xdomain_lane_bonding_enable()
2137 return 0; in tb_xdomain_lane_bonding_enable()
2143 * @xd: XDomain connection
2148 void tb_xdomain_lane_bonding_disable(struct tb_xdomain *xd) in tb_xdomain_lane_bonding_disable() argument
2152 port = tb_xdomain_downstream_port(xd); in tb_xdomain_lane_bonding_disable()
2162 tb_xdomain_update_link_attributes(xd); in tb_xdomain_lane_bonding_disable()
2164 dev_dbg(&xd->dev, "lane bonding disabled\n"); in tb_xdomain_lane_bonding_disable()
2171 * @xd: XDomain connection
2179 int tb_xdomain_alloc_in_hopid(struct tb_xdomain *xd, int hopid) in tb_xdomain_alloc_in_hopid() argument
2181 if (hopid < 0) in tb_xdomain_alloc_in_hopid()
2183 if (hopid < TB_PATH_MIN_HOPID || hopid > xd->local_max_hopid) in tb_xdomain_alloc_in_hopid()
2186 return ida_alloc_range(&xd->in_hopids, hopid, xd->local_max_hopid, in tb_xdomain_alloc_in_hopid()
2193 * @xd: XDomain connection
2201 int tb_xdomain_alloc_out_hopid(struct tb_xdomain *xd, int hopid) in tb_xdomain_alloc_out_hopid() argument
2203 if (hopid < 0) in tb_xdomain_alloc_out_hopid()
2205 if (hopid < TB_PATH_MIN_HOPID || hopid > xd->remote_max_hopid) in tb_xdomain_alloc_out_hopid()
2208 return ida_alloc_range(&xd->out_hopids, hopid, xd->remote_max_hopid, in tb_xdomain_alloc_out_hopid()
2215 * @xd: XDomain connection
2218 void tb_xdomain_release_in_hopid(struct tb_xdomain *xd, int hopid) in tb_xdomain_release_in_hopid() argument
2220 ida_free(&xd->in_hopids, hopid); in tb_xdomain_release_in_hopid()
2226 * @xd: XDomain connection
2229 void tb_xdomain_release_out_hopid(struct tb_xdomain *xd, int hopid) in tb_xdomain_release_out_hopid() argument
2231 ida_free(&xd->out_hopids, hopid); in tb_xdomain_release_out_hopid()
2237 * @xd: XDomain connection
2248 * Return: %0 in case of success and negative errno in case of error
2250 int tb_xdomain_enable_paths(struct tb_xdomain *xd, int transmit_path, in tb_xdomain_enable_paths() argument
2254 return tb_domain_approve_xdomain_paths(xd->tb, xd, transmit_path, in tb_xdomain_enable_paths()
2262 * @xd: XDomain connection
2273 * Return: %0 in case of success and negative errno in case of error
2275 int tb_xdomain_disable_paths(struct tb_xdomain *xd, int transmit_path, in tb_xdomain_disable_paths() argument
2279 return tb_domain_disconnect_xdomain_paths(xd->tb, xd, transmit_path, in tb_xdomain_disable_paths()
2298 struct tb_xdomain *xd; in switch_find_xdomain() local
2301 xd = port->xdomain; in switch_find_xdomain()
2304 if (xd->remote_uuid && in switch_find_xdomain()
2305 uuid_equal(xd->remote_uuid, lookup->uuid)) in switch_find_xdomain()
2306 return xd; in switch_find_xdomain()
2308 if (lookup->link && lookup->link == xd->link && in switch_find_xdomain()
2309 lookup->depth == xd->depth) in switch_find_xdomain()
2310 return xd; in switch_find_xdomain()
2311 if (lookup->route && lookup->route == xd->route) in switch_find_xdomain()
2312 return xd; in switch_find_xdomain()
2315 xd = switch_find_xdomain(port->remote->sw, lookup); in switch_find_xdomain()
2316 if (xd) in switch_find_xdomain()
2317 return xd; in switch_find_xdomain()
2342 struct tb_xdomain *xd; in tb_xdomain_find_by_uuid() local
2344 memset(&lookup, 0, sizeof(lookup)); in tb_xdomain_find_by_uuid()
2347 xd = switch_find_xdomain(tb->root_switch, &lookup); in tb_xdomain_find_by_uuid()
2348 return tb_xdomain_get(xd); in tb_xdomain_find_by_uuid()
2372 struct tb_xdomain *xd; in tb_xdomain_find_by_link_depth() local
2374 memset(&lookup, 0, sizeof(lookup)); in tb_xdomain_find_by_link_depth()
2378 xd = switch_find_xdomain(tb->root_switch, &lookup); in tb_xdomain_find_by_link_depth()
2379 return tb_xdomain_get(xd); in tb_xdomain_find_by_link_depth()
2400 struct tb_xdomain *xd; in tb_xdomain_find_by_route() local
2402 memset(&lookup, 0, sizeof(lookup)); in tb_xdomain_find_by_route()
2405 xd = switch_find_xdomain(tb->root_switch, &lookup); in tb_xdomain_find_by_route()
2406 return tb_xdomain_get(xd); in tb_xdomain_find_by_route()
2416 int ret = 0; in tb_xdomain_handle_request()
2450 return ret > 0; in tb_xdomain_handle_request()
2455 struct tb_xdomain *xd; in update_xdomain() local
2457 xd = tb_to_xdomain(dev); in update_xdomain()
2458 if (xd) { in update_xdomain()
2459 queue_delayed_work(xd->tb->wq, &xd->properties_changed_work, in update_xdomain()
2463 return 0; in update_xdomain()
2494 * Return: %0 on success and negative errno on failure
2521 return 0; in tb_register_property_dir()
2539 int ret = 0; in tb_unregister_property_dir()
2568 tb_property_add_immediate(xdomain_property_dir, "deviceid", 0x1); in tb_xdomain_init()
2569 tb_property_add_immediate(xdomain_property_dir, "devicerv", 0x80000100); in tb_xdomain_init()
2572 return 0; in tb_xdomain_init()