Lines Matching +full:memcpy +full:- +full:bus +full:- +full:width

1 // SPDX-License-Identifier: GPL-2.0
79 /* UUID for XDomain discovery protocol: b638d70e-42ff-40bb-97c2-90e2c0b2ff07 */
92 switch (pkg->frame.eof) { in tb_xdomain_match()
97 const struct tb_xdp_header *res_hdr = pkg->buffer; in tb_xdomain_match()
98 const struct tb_xdp_header *req_hdr = req->request; in tb_xdomain_match()
100 if (pkg->frame.size < req->response_size / 4) in tb_xdomain_match()
104 if ((res_hdr->xd_hdr.route_hi & ~BIT(31)) != in tb_xdomain_match()
105 req_hdr->xd_hdr.route_hi) in tb_xdomain_match()
107 if ((res_hdr->xd_hdr.route_lo) != req_hdr->xd_hdr.route_lo) in tb_xdomain_match()
111 if (!uuid_equal(&res_hdr->uuid, &req_hdr->uuid)) in tb_xdomain_match()
125 memcpy(req->response, pkg->buffer, req->response_size); in tb_xdomain_copy()
126 req->result.err = 0; in tb_xdomain_copy()
142 return -ENOMEM; in __tb_xdomain_response()
144 req->match = tb_xdomain_match; in __tb_xdomain_response()
145 req->copy = tb_xdomain_copy; in __tb_xdomain_response()
146 req->request = response; in __tb_xdomain_response()
147 req->request_size = size; in __tb_xdomain_response()
148 req->request_type = type; in __tb_xdomain_response()
154 * tb_xdomain_response() - Send a XDomain response message
168 return __tb_xdomain_response(xd->tb->ctl, response, size, type); in tb_xdomain_response()
182 return -ENOMEM; in __tb_xdomain_request()
184 req->match = tb_xdomain_match; in __tb_xdomain_request()
185 req->copy = tb_xdomain_copy; in __tb_xdomain_request()
186 req->request = request; in __tb_xdomain_request()
187 req->request_size = request_size; in __tb_xdomain_request()
188 req->request_type = request_type; in __tb_xdomain_request()
189 req->response = response; in __tb_xdomain_request()
190 req->response_size = response_size; in __tb_xdomain_request()
191 req->response_type = response_type; in __tb_xdomain_request()
197 return res.err == 1 ? -EIO : res.err; in __tb_xdomain_request()
201 * tb_xdomain_request() - Send a XDomain request
222 return __tb_xdomain_request(xd->tb->ctl, request, request_size, in tb_xdomain_request()
233 length_sn = (size - sizeof(hdr->xd_hdr)) / 4; in tb_xdp_fill_header()
236 hdr->xd_hdr.route_hi = upper_32_bits(route); in tb_xdp_fill_header()
237 hdr->xd_hdr.route_lo = lower_32_bits(route); in tb_xdp_fill_header()
238 hdr->xd_hdr.length_sn = length_sn; in tb_xdp_fill_header()
239 hdr->type = type; in tb_xdp_fill_header()
240 memcpy(&hdr->uuid, &tb_xdp_uuid, sizeof(tb_xdp_uuid)); in tb_xdp_fill_header()
245 if (res->hdr.type != ERROR_RESPONSE) in tb_xdp_handle_error()
248 switch (res->error) { in tb_xdp_handle_error()
251 return -EIO; in tb_xdp_handle_error()
253 return -EOPNOTSUPP; in tb_xdp_handle_error()
255 return -EAGAIN; in tb_xdp_handle_error()
337 return -ENOMEM; in tb_xdp_properties_request()
342 memcpy(&req.src_uuid, src_uuid, sizeof(*src_uuid)); in tb_xdp_properties_request()
343 memcpy(&req.dst_uuid, dst_uuid, sizeof(*dst_uuid)); in tb_xdp_properties_request()
355 ret = tb_xdp_handle_error(&res->err); in tb_xdp_properties_request()
364 len = res->hdr.xd_hdr.length_sn & TB_XDOMAIN_LENGTH_MASK; in tb_xdp_properties_request()
366 ret = -EINVAL; in tb_xdp_properties_request()
370 len += sizeof(res->hdr.xd_hdr) / 4; in tb_xdp_properties_request()
371 len -= sizeof(*res) / 4; in tb_xdp_properties_request()
373 if (res->offset != req.offset) { in tb_xdp_properties_request()
374 ret = -EINVAL; in tb_xdp_properties_request()
383 data_len = res->data_length; in tb_xdp_properties_request()
385 ret = -E2BIG; in tb_xdp_properties_request()
391 ret = -ENOMEM; in tb_xdp_properties_request()
396 memcpy(data + req.offset, res->data, len * 4); in tb_xdp_properties_request()
401 *generation = res->generation; in tb_xdp_properties_request()
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()
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()
437 return -EINVAL; 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()
447 return -ENOMEM; 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()
454 res->offset = req->offset; in tb_xdp_properties_response()
455 uuid_copy(&res->src_uuid, xd->local_uuid); in tb_xdp_properties_response()
456 uuid_copy(&res->dst_uuid, &req->src_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()
527 return -EREMOTEIO; in tb_xdp_link_state_status_request()
546 tb_xdp_fill_header(&res.hdr, xd->route, sequence, in tb_xdp_link_state_status_response()
550 port->cap_phy + LANE_ADP_CS_0, ARRAY_SIZE(val)); in tb_xdp_link_state_status_response()
590 return res.status != 0 ? -EREMOTEIO : 0; in tb_xdp_link_state_change_request()
609 * tb_register_protocol_handler() - Register protocol handler
619 if (!handler->uuid || !handler->callback) in tb_register_protocol_handler()
620 return -EINVAL; in tb_register_protocol_handler()
621 if (uuid_equal(handler->uuid, &tb_xdp_uuid)) in tb_register_protocol_handler()
622 return -EINVAL; in tb_register_protocol_handler()
625 list_add_tail(&handler->list, &protocol_handlers); in tb_register_protocol_handler()
633 * tb_unregister_protocol_handler() - Unregister protocol handler
641 list_del_init(&handler->list); in tb_unregister_protocol_handler()
649 mutex_lock(&xd->lock); in update_property_block()
651 * If the local property block is not up-to-date, rebuild it now 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()
666 /* Fill in non-static properties now */ in update_property_block()
667 tb_property_add_text(dir, "deviceid", utsname()->nodename); in update_property_block()
668 tb_property_add_immediate(dir, "maxhopid", xd->local_max_hopid); 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()
708 xd->state = XDOMAIN_STATE_INIT; in start_handshake()
709 queue_delayed_work(xd->tb->wq, &xd->state_work, in start_handshake()
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()
723 cancel_delayed_work_sync(&xd->state_work); in stop_handshake()
730 const struct tb_xdp_header *pkg = xw->pkg; in tb_xdp_handle_request()
731 const struct tb_xdomain_header *xhdr = &pkg->xd_hdr; in tb_xdp_handle_request()
732 struct tb *tb = xw->tb; in tb_xdp_handle_request()
733 struct tb_ctl *ctl = tb->ctl; in tb_xdp_handle_request()
740 route = ((u64)xhdr->route_hi << 32 | xhdr->route_lo) & ~BIT_ULL(63); in tb_xdp_handle_request()
741 sequence = xhdr->length_sn & TB_XDOMAIN_SN_MASK; in tb_xdp_handle_request()
744 mutex_lock(&tb->lock); in tb_xdp_handle_request()
745 if (tb->root_switch) in tb_xdp_handle_request()
746 uuid = tb->root_switch->uuid; in tb_xdp_handle_request()
749 mutex_unlock(&tb->lock); in tb_xdp_handle_request()
760 switch (pkg->type) { 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()
817 if (xd && xd->state == XDOMAIN_STATE_BONDING_UUID_HIGH) { 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()
833 tb_dbg(tb, "%llx: unknown XDomain request %#x\n", route, pkg->type); in tb_xdp_handle_request()
843 pkg->type); in tb_xdp_handle_request()
847 kfree(xw->pkg); in tb_xdp_handle_request()
863 INIT_WORK(&xw->work, tb_xdp_handle_request); in tb_xdp_schedule_request()
864 xw->pkg = kmemdup(hdr, size, GFP_KERNEL); in tb_xdp_schedule_request()
865 if (!xw->pkg) { in tb_xdp_schedule_request()
869 xw->tb = tb_domain_get(tb); in tb_xdp_schedule_request()
871 schedule_work(&xw->work); in tb_xdp_schedule_request()
876 * tb_register_service_driver() - Register XDomain service driver
879 * Registers new service driver from @drv to the bus.
883 drv->driver.bus = &tb_bus_type; in tb_register_service_driver()
884 return driver_register(&drv->driver); in tb_register_service_driver()
889 * tb_unregister_service_driver() - Unregister XDomain service driver
892 * Unregisters XDomain service driver from the bus.
896 driver_unregister(&drv->driver); in tb_unregister_service_driver()
909 return sysfs_emit(buf, "%*pE\n", (int)strlen(svc->key), svc->key); in key_show()
915 return snprintf(buf, size, "tbsvc:k%sp%08Xv%08Xr%08X", svc->key, in get_modalias()
916 svc->prtcid, svc->prtcvers, svc->prtcrevs); in get_modalias()
925 get_modalias(svc, buf, PAGE_SIZE - 2); in modalias_show()
935 return sysfs_emit(buf, "%u\n", svc->prtcid); in prtcid_show()
944 return sysfs_emit(buf, "%u\n", svc->prtcvers); in prtcvers_show()
953 return sysfs_emit(buf, "%u\n", svc->prtcrevs); in prtcrevs_show()
962 return sysfs_emit(buf, "0x%08x\n", svc->prtcstns); in prtcstns_show()
1000 ida_free(&xd->service_ids, svc->id); in tb_service_release()
1001 kfree(svc->key); in tb_service_release()
1022 if (!tb_property_find(xd->remote_properties, svc->key, in remove_missing_service()
1038 return !strcmp(svc->key, p->key); in find_service()
1044 struct tb_property_dir *dir = property->value.dir; in populate_service()
1050 svc->prtcid = p->value.immediate; in populate_service()
1053 svc->prtcvers = p->value.immediate; in populate_service()
1056 svc->prtcrevs = p->value.immediate; in populate_service()
1059 svc->prtcstns = p->value.immediate; in populate_service()
1061 svc->key = kstrdup(property->key, GFP_KERNEL); in populate_service()
1062 if (!svc->key) in populate_service()
1063 return -ENOMEM; in populate_service()
1079 device_for_each_child_reverse(&xd->dev, xd, remove_missing_service); in enumerate_services()
1081 /* Then re-enumerate properties creating new services as we go */ in enumerate_services()
1082 tb_property_for_each(xd->remote_properties, p) { in enumerate_services()
1083 if (p->type != TB_PROPERTY_TYPE_DIRECTORY) 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()
1104 kfree(svc->key); in enumerate_services()
1108 svc->id = id; in enumerate_services()
1109 svc->dev.bus = &tb_bus_type; in enumerate_services()
1110 svc->dev.type = &tb_service_type; 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()
1116 if (device_register(&svc->dev)) { in enumerate_services()
1117 put_device(&svc->dev); in enumerate_services()
1131 return -EINVAL; in populate_properties()
1132 xd->device = p->value.immediate; in populate_properties()
1136 return -EINVAL; in populate_properties()
1137 xd->vendor = p->value.immediate; in populate_properties()
1141 * USB4 inter-domain spec suggests using 15 as HopID if the 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()
1175 if (xd->link_speed != ret) in tb_xdomain_update_link_attributes()
1178 xd->link_speed = ret; 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()
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()
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()
1209 return -EAGAIN; 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()
1235 return -ENODEV; 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()
1242 return -ENOMEM; in tb_xdomain_get_uuid()
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()
1264 return -EAGAIN; 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()
1274 return -EOPNOTSUPP; in tb_xdomain_get_link_status()
1281 unsigned int width) in tb_xdomain_link_state_change() argument
1284 struct tb *tb = xd->tb; in tb_xdomain_link_state_change()
1289 if (width == 2) in tb_xdomain_link_state_change()
1291 else if (width == 1) in tb_xdomain_link_state_change()
1294 return -EINVAL; in tb_xdomain_link_state_change()
1297 ret = tb_port_read(port, &val, TB_CFG_PORT, port->cap_phy + LANE_ADP_CS_1, 1); 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()
1311 return -EAGAIN; 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()
1323 unsigned int width, width_mask; in tb_xdomain_bond_lanes_uuid_high() local
1327 if (xd->target_link_width == LANE_ADP_CS_1_TARGET_WIDTH_SINGLE) { in tb_xdomain_bond_lanes_uuid_high()
1328 width = TB_LINK_WIDTH_SINGLE; in tb_xdomain_bond_lanes_uuid_high()
1329 width_mask = width; 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()
1331 width = TB_LINK_WIDTH_DUAL; in tb_xdomain_bond_lanes_uuid_high()
1332 width_mask = width | TB_LINK_WIDTH_ASYM_TX | TB_LINK_WIDTH_ASYM_RX; 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()
1337 return -EAGAIN; 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()
1340 return -ETIMEDOUT; in tb_xdomain_bond_lanes_uuid_high()
1348 * just set the width to both lane adapters and wait for the in tb_xdomain_bond_lanes_uuid_high()
1351 ret = tb_port_set_link_width(port->dual_link_port, width); in tb_xdomain_bond_lanes_uuid_high()
1353 tb_port_warn(port->dual_link_port, in tb_xdomain_bond_lanes_uuid_high()
1354 "failed to set link width to %d\n", width); in tb_xdomain_bond_lanes_uuid_high()
1358 ret = tb_port_set_link_width(port, width); in tb_xdomain_bond_lanes_uuid_high()
1360 tb_port_warn(port, "failed to set link width to %d\n", width); 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()
1372 port->bonded = width > TB_LINK_WIDTH_SINGLE; in tb_xdomain_bond_lanes_uuid_high()
1373 port->dual_link_port->bonded = width > TB_LINK_WIDTH_SINGLE; 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()
1385 struct tb *tb = xd->tb; 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()
1397 if (xd->state_retries-- > 0) { in tb_xdomain_get_properties()
1398 dev_dbg(&xd->dev, in tb_xdomain_get_properties()
1400 return -EAGAIN; 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()
1419 dev_err(&xd->dev, "failed to parse XDomain properties\n"); in tb_xdomain_get_properties()
1420 ret = -ENOMEM; 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()
1441 mutex_unlock(&xd->lock); in tb_xdomain_get_properties()
1447 * bus and let userspace know about it. If the device is already in tb_xdomain_get_properties()
1457 if (xd->bonding_possible) { in tb_xdomain_get_properties()
1461 if (!port->bonded) in tb_xdomain_get_properties()
1462 tb_port_disable(port->dual_link_port); 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()
1472 return -ENODEV; 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()
1482 kobject_uevent(&xd->dev.kobj, KOBJ_CHANGE); in tb_xdomain_get_properties()
1492 mutex_unlock(&xd->lock); in tb_xdomain_get_properties()
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()
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()
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()
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()
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()
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()
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()
1561 xd->state = XDOMAIN_STATE_ERROR; in tb_xdomain_failed()
1562 queue_delayed_work(xd->tb->wq, &xd->state_work, in tb_xdomain_failed()
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()
1590 if (ret == -EAGAIN) in tb_xdomain_state_work()
1595 if (xd->bonding_possible) in tb_xdomain_state_work()
1605 if (ret == -EAGAIN) in tb_xdomain_state_work()
1622 if (ret == -EAGAIN) in tb_xdomain_state_work()
1633 if (ret == -EAGAIN) in tb_xdomain_state_work()
1647 if (tb_xdomain_bond_lanes_uuid_high(xd) == -EAGAIN) in tb_xdomain_state_work()
1655 if (ret == -EAGAIN) in tb_xdomain_state_work()
1659 xd->state = XDOMAIN_STATE_ENUMERATED; in tb_xdomain_state_work()
1668 dev_dbg(&xd->dev, "discovery failed, stopping handshake\n"); 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()
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()
1714 return sysfs_emit(buf, "%#x\n", xd->device); in device_show()
1724 if (mutex_lock_interruptible(&xd->lock)) in device_name_show()
1725 return -ERESTARTSYS; 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()
1738 return sysfs_emit(buf, "%d\n", xd->remote_max_hopid); in maxhopid_show()
1747 return sysfs_emit(buf, "%#x\n", xd->vendor); in vendor_show()
1757 if (mutex_lock_interruptible(&xd->lock)) in vendor_name_show()
1758 return -ERESTARTSYS; 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()
1771 return sysfs_emit(buf, "%pUb\n", xd->remote_uuid); in unique_id_show()
1780 return sysfs_emit(buf, "%u.0 Gb/s\n", xd->link_speed); in speed_show()
1790 unsigned int width; in rx_lanes_show() local
1792 switch (xd->link_width) { in rx_lanes_show()
1795 width = 1; in rx_lanes_show()
1798 width = 2; in rx_lanes_show()
1801 width = 3; in rx_lanes_show()
1805 return -EINVAL; in rx_lanes_show()
1808 return sysfs_emit(buf, "%u\n", width); in rx_lanes_show()
1816 unsigned int width; in tx_lanes_show() local
1818 switch (xd->link_width) { in tx_lanes_show()
1821 width = 1; in tx_lanes_show()
1824 width = 2; in tx_lanes_show()
1827 width = 3; in tx_lanes_show()
1831 return -EINVAL; in tx_lanes_show()
1834 return sysfs_emit(buf, "%u\n", width); in tx_lanes_show()
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()
1905 if (!down->dual_link_port) in tb_xdomain_link_init()
1913 down->bonded = true; in tb_xdomain_link_init()
1914 down->dual_link_port->bonded = true; in tb_xdomain_link_init()
1916 xd->bonding_possible = true; in tb_xdomain_link_init()
1924 if (!down->dual_link_port) in tb_xdomain_link_exit()
1928 down->bonded = false; in tb_xdomain_link_exit()
1929 down->dual_link_port->bonded = false; in tb_xdomain_link_exit()
1930 } else if (xd->link_width > TB_LINK_WIDTH_SINGLE) { in tb_xdomain_link_exit()
1938 } else if (down->dual_link_port) { in tb_xdomain_link_exit()
1940 * Re-enable the lane 1 adapter we disabled at the end in tb_xdomain_link_exit()
1943 tb_port_enable(down->dual_link_port); in tb_xdomain_link_exit()
1948 * tb_xdomain_alloc() - Allocate new XDomain object
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()
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()
2023 kfree(xd->local_uuid); in tb_xdomain_alloc()
2031 * tb_xdomain_add() - Add XDomain to the bus
2035 * eventually adds the XDomain to the bus. After calling this function
2052 * tb_xdomain_remove() - Remove XDomain from the bus
2056 * along with any services from the bus. When the last reference to @xd
2065 device_for_each_child_reverse(&xd->dev, xd, unregister_service); in tb_xdomain_remove()
2071 * the XDomain was never added to the bus and thus device_del() 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()
2087 * tb_xdomain_lane_bonding_enable() - Enable lane bonding on XDomain
2103 if (!port->dual_link_port) in tb_xdomain_lane_bonding_enable()
2104 return -ENODEV; in tb_xdomain_lane_bonding_enable()
2106 ret = tb_port_enable(port->dual_link_port); in tb_xdomain_lane_bonding_enable()
2110 ret = tb_wait_for_port(port->dual_link_port, true); in tb_xdomain_lane_bonding_enable()
2114 return -ENOTCONN; in tb_xdomain_lane_bonding_enable()
2136 dev_dbg(&xd->dev, "lane bonding enabled\n"); in tb_xdomain_lane_bonding_enable()
2142 * tb_xdomain_lane_bonding_disable() - Disable lane bonding
2153 if (port->dual_link_port) { in tb_xdomain_lane_bonding_disable()
2158 if (ret == -ETIMEDOUT) in tb_xdomain_lane_bonding_disable()
2160 tb_port_disable(port->dual_link_port); in tb_xdomain_lane_bonding_disable()
2164 dev_dbg(&xd->dev, "lane bonding disabled\n"); in tb_xdomain_lane_bonding_disable()
2170 * tb_xdomain_alloc_in_hopid() - Allocate input HopID for tunneling
2172 * @hopid: Preferred HopID or %-1 for next available
2175 * %-ENOSPC if there are no more available HopIDs. Returned HopID is
2183 if (hopid < TB_PATH_MIN_HOPID || hopid > xd->local_max_hopid) in tb_xdomain_alloc_in_hopid()
2184 return -EINVAL; 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()
2192 * tb_xdomain_alloc_out_hopid() - Allocate output HopID for tunneling
2194 * @hopid: Preferred HopID or %-1 for next available
2197 * %-ENOSPC if there are no more available HopIDs. Returned HopID is
2205 if (hopid < TB_PATH_MIN_HOPID || hopid > xd->remote_max_hopid) in tb_xdomain_alloc_out_hopid()
2206 return -EINVAL; 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()
2214 * tb_xdomain_release_in_hopid() - Release input HopID
2220 ida_free(&xd->in_hopids, hopid); in tb_xdomain_release_in_hopid()
2225 * tb_xdomain_release_out_hopid() - Release output HopID
2231 ida_free(&xd->out_hopids, hopid); in tb_xdomain_release_out_hopid()
2236 * tb_xdomain_enable_paths() - Enable DMA paths for XDomain connection
2244 * return the caller can send and receive packets using high-speed DMA
2245 * path. If a transmit or receive path is not needed, pass %-1 for those
2254 return tb_domain_approve_xdomain_paths(xd->tb, xd, transmit_path, in tb_xdomain_enable_paths()
2261 * tb_xdomain_disable_paths() - Disable DMA paths for XDomain connection
2269 * this the caller is not expected to use the rings anymore. Passing %-1
2279 return tb_domain_disconnect_xdomain_paths(xd->tb, xd, transmit_path, in tb_xdomain_disable_paths()
2300 if (port->xdomain) { in switch_find_xdomain()
2301 xd = port->xdomain; in switch_find_xdomain()
2303 if (lookup->uuid) { 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()
2308 if (lookup->link && lookup->link == xd->link && in switch_find_xdomain()
2309 lookup->depth == xd->depth) in switch_find_xdomain()
2311 if (lookup->route && lookup->route == xd->route) in switch_find_xdomain()
2315 xd = switch_find_xdomain(port->remote->sw, lookup); in switch_find_xdomain()
2325 * tb_xdomain_find_by_uuid() - Find an XDomain by UUID
2335 * to the bus (handshake is still in progress).
2337 * The caller needs to hold @tb->lock.
2347 xd = switch_find_xdomain(tb->root_switch, &lookup); in tb_xdomain_find_by_uuid()
2353 * tb_xdomain_find_by_link_depth() - Find an XDomain by link and depth
2364 * to the bus (handshake is still in progress).
2366 * The caller needs to hold @tb->lock.
2378 xd = switch_find_xdomain(tb->root_switch, &lookup); in tb_xdomain_find_by_link_depth()
2383 * tb_xdomain_find_by_route() - Find an XDomain by route string
2393 * to the bus (handshake is still in progress).
2395 * The caller needs to hold @tb->lock.
2405 xd = switch_find_xdomain(tb->root_switch, &lookup); in tb_xdomain_find_by_route()
2419 length = hdr->xd_hdr.length_sn & TB_XDOMAIN_LENGTH_MASK; in tb_xdomain_handle_request()
2420 if (length != size / 4 - sizeof(hdr->xd_hdr) / 4) in tb_xdomain_handle_request()
2422 if (length < sizeof(*hdr) / 4 - sizeof(hdr->xd_hdr) / 4) in tb_xdomain_handle_request()
2430 if (uuid_equal(&hdr->uuid, &tb_xdp_uuid)) { in tb_xdomain_handle_request()
2438 if (!uuid_equal(&hdr->uuid, handler->uuid)) in tb_xdomain_handle_request()
2442 ret = handler->callback(buf, size, handler->data); in tb_xdomain_handle_request()
2459 queue_delayed_work(xd->tb->wq, &xd->properties_changed_work, in update_xdomain()
2477 if (p && p->value.dir == dir) { in remove_directory()
2485 * tb_register_property_dir() - Register property directory to the host
2491 * notified so they can re-read properties of this host if they are
2501 return -EAGAIN; in tb_register_property_dir()
2504 return -EINVAL; in tb_register_property_dir()
2509 ret = -EEXIST; in tb_register_property_dir()
2530 * tb_unregister_property_dir() - Removes property directory from host
2555 return -ENOMEM; in tb_xdomain_init()