in xdomain.c [574:654]
static void tb_xdp_handle_request(struct work_struct *work)
{
struct xdomain_request_work *xw = container_of(work, typeof(*xw), work);
const struct tb_xdp_header *pkg = xw->pkg;
const struct tb_xdomain_header *xhdr = &pkg->xd_hdr;
struct tb *tb = xw->tb;
struct tb_ctl *ctl = tb->ctl;
struct tb_xdomain *xd;
const uuid_t *uuid;
int ret = 0;
u32 sequence;
u64 route;
route = ((u64)xhdr->route_hi << 32 | xhdr->route_lo) & ~BIT_ULL(63);
sequence = xhdr->length_sn & TB_XDOMAIN_SN_MASK;
sequence >>= TB_XDOMAIN_SN_SHIFT;
mutex_lock(&tb->lock);
if (tb->root_switch)
uuid = tb->root_switch->uuid;
else
uuid = NULL;
mutex_unlock(&tb->lock);
if (!uuid) {
tb_xdp_error_response(ctl, route, sequence, ERROR_NOT_READY);
goto out;
}
tb_dbg(tb, "%llx: received XDomain request %#x\n", route, pkg->type);
xd = tb_xdomain_find_by_route_locked(tb, route);
if (xd)
update_property_block(xd);
switch (pkg->type) {
case PROPERTIES_REQUEST:
if (xd) {
ret = tb_xdp_properties_response(tb, ctl, xd, sequence,
(const struct tb_xdp_properties *)pkg);
}
break;
case PROPERTIES_CHANGED_REQUEST:
ret = tb_xdp_properties_changed_response(ctl, route, sequence);
/*
* Since the properties have been changed, let's update
* the xdomain related to this connection as well in
* case there is a change in services it offers.
*/
if (xd && device_is_registered(&xd->dev)) {
queue_delayed_work(tb->wq, &xd->get_properties_work,
msecs_to_jiffies(50));
}
break;
case UUID_REQUEST_OLD:
case UUID_REQUEST:
ret = tb_xdp_uuid_response(ctl, route, sequence, uuid);
break;
default:
tb_xdp_error_response(ctl, route, sequence,
ERROR_NOT_SUPPORTED);
break;
}
tb_xdomain_put(xd);
if (ret) {
tb_warn(tb, "failed to send XDomain response for %#x\n",
pkg->type);
}
out:
kfree(xw->pkg);
kfree(xw);
tb_domain_put(tb);
}