// SPDX-License-Identifier: GPL-2.0
/*
 * Thunderbolt XDomain discovery protocol support
 *
 * Copyright (C) 2017, Intel Corporation
 * Authors: Michael Jamet <michael.jamet@intel.com>
 *          Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/device.h>
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/utsname.h>
#include <linux/uuid.h>
#include <linux/workqueue.h>

#include "tb.h"

#define XDOMAIN_DEFAULT_TIMEOUT			5000 /* ms */
#define XDOMAIN_UUID_RETRIES			10
#define XDOMAIN_PROPERTIES_RETRIES		60
#define XDOMAIN_PROPERTIES_CHANGED_RETRIES	10

struct xdomain_request_work {
	struct work_struct work;
	struct tb_xdp_header *pkg;
	struct tb *tb;
};

/* Serializes access to the properties and protocol handlers below */
static DEFINE_MUTEX(xdomain_lock);

/* Properties exposed to the remote domains */
static struct tb_property_dir *xdomain_property_dir;
static u32 *xdomain_property_block;
static u32 xdomain_property_block_len;
static u32 xdomain_property_block_gen;

/* Additional protocol handlers */
static LIST_HEAD(protocol_handlers);

/* UUID for XDomain discovery protocol: b638d70e-42ff-40bb-97c2-90e2c0b2ff07 */
static const uuid_t tb_xdp_uuid =
	UUID_INIT(0xb638d70e, 0x42ff, 0x40bb,
		  0x97, 0xc2, 0x90, 0xe2, 0xc0, 0xb2, 0xff, 0x07);

static bool tb_xdomain_match(const struct tb_cfg_request *req,
			     const struct ctl_pkg *pkg)
{
	switch (pkg->frame.eof) {
	case TB_CFG_PKG_ERROR:
		return true;

	case TB_CFG_PKG_XDOMAIN_RESP: {
		const struct tb_xdp_header *res_hdr = pkg->buffer;
		const struct tb_xdp_header *req_hdr = req->request;

		if (pkg->frame.size < req->response_size / 4)
			return false;

		/* Make sure route matches */
		if ((res_hdr->xd_hdr.route_hi & ~BIT(31)) !=
		     req_hdr->xd_hdr.route_hi)
			return false;
		if ((res_hdr->xd_hdr.route_lo) != req_hdr->xd_hdr.route_lo)
			return false;

		/* Check that the XDomain protocol matches */
		if (!uuid_equal(&res_hdr->uuid, &req_hdr->uuid))
			return false;

		return true;
	}

	default:
		return false;
	}
}

static bool tb_xdomain_copy(struct tb_cfg_request *req,
			    const struct ctl_pkg *pkg)
{
	memcpy(req->response, pkg->buffer, req->response_size);
	req->result.err = 0;
	return true;
}

static void response_ready(void *data)
{
	tb_cfg_request_put(data);
}

static int __tb_xdomain_response(struct tb_ctl *ctl, const void *response,
				 size_t size, enum tb_cfg_pkg_type type)
{
	struct tb_cfg_request *req;

	req = tb_cfg_request_alloc();
	if (!req)
		return -ENOMEM;

	req->match = tb_xdomain_match;
	req->copy = tb_xdomain_copy;
	req->request = response;
	req->request_size = size;
	req->request_type = type;

	return tb_cfg_request(ctl, req, response_ready, req);
}

/**
 * tb_xdomain_response() - Send a XDomain response message
 * @xd: XDomain to send the message
 * @response: Response to send
 * @size: Size of the response
 * @type: PDF type of the response
 *
 * This can be used to send a XDomain response message to the other
 * domain. No response for the message is expected.
 *
 * Return: %0 in case of success and negative errno in case of failure
 */
int tb_xdomain_response(struct tb_xdomain *xd, const void *response,
			size_t size, enum tb_cfg_pkg_type type)
{
	return __tb_xdomain_response(xd->tb->ctl, response, size, type);
}
EXPORT_SYMBOL_GPL(tb_xdomain_response);

static int __tb_xdomain_request(struct tb_ctl *ctl, const void *request,
	size_t request_size, enum tb_cfg_pkg_type request_type, void *response,
	size_t response_size, enum tb_cfg_pkg_type response_type,
	unsigned int timeout_msec)
{
	struct tb_cfg_request *req;
	struct tb_cfg_result res;

	req = tb_cfg_request_alloc();
	if (!req)
		return -ENOMEM;

	req->match = tb_xdomain_match;
	req->copy = tb_xdomain_copy;
	req->request = request;
	req->request_size = request_size;
	req->request_type = request_type;
	req->response = response;
	req->response_size = response_size;
	req->response_type = response_type;

	res = tb_cfg_request_sync(ctl, req, timeout_msec);

	tb_cfg_request_put(req);

	return res.err == 1 ? -EIO : res.err;
}

/**
 * tb_xdomain_request() - Send a XDomain request
 * @xd: XDomain to send the request
 * @request: Request to send
 * @request_size: Size of the request in bytes
 * @request_type: PDF type of the request
 * @response: Response is copied here
 * @response_size: Expected size of the response in bytes
 * @response_type: Expected PDF type of the response
 * @timeout_msec: Timeout in milliseconds to wait for the response
 *
 * This function can be used to send XDomain control channel messages to
 * the other domain. The function waits until the response is received
 * or when timeout triggers. Whichever comes first.
 *
 * Return: %0 in case of success and negative errno in case of failure
 */
int tb_xdomain_request(struct tb_xdomain *xd, const void *request,
	size_t request_size, enum tb_cfg_pkg_type request_type,
	void *response, size_t response_size,
	enum tb_cfg_pkg_type response_type, unsigned int timeout_msec)
{
	return __tb_xdomain_request(xd->tb->ctl, request, request_size,
				    request_type, response, response_size,
				    response_type, timeout_msec);
}
EXPORT_SYMBOL_GPL(tb_xdomain_request);

static inline void tb_xdp_fill_header(struct tb_xdp_header *hdr, u64 route,
	u8 sequence, enum tb_xdp_type type, size_t size)
{
	u32 length_sn;

	length_sn = (size - sizeof(hdr->xd_hdr)) / 4;
	length_sn |= (sequence << TB_XDOMAIN_SN_SHIFT) & TB_XDOMAIN_SN_MASK;

	hdr->xd_hdr.route_hi = upper_32_bits(route);
	hdr->xd_hdr.route_lo = lower_32_bits(route);
	hdr->xd_hdr.length_sn = length_sn;
	hdr->type = type;
	memcpy(&hdr->uuid, &tb_xdp_uuid, sizeof(tb_xdp_uuid));
}

static int tb_xdp_handle_error(const struct tb_xdp_header *hdr)
{
	const struct tb_xdp_error_response *error;

	if (hdr->type != ERROR_RESPONSE)
		return 0;

	error = (const struct tb_xdp_error_response *)hdr;

	switch (error->error) {
	case ERROR_UNKNOWN_PACKET:
	case ERROR_UNKNOWN_DOMAIN:
		return -EIO;
	case ERROR_NOT_SUPPORTED:
		return -ENOTSUPP;
	case ERROR_NOT_READY:
		return -EAGAIN;
	default:
		break;
	}

	return 0;
}

static int tb_xdp_uuid_request(struct tb_ctl *ctl, u64 route, int retry,
			       uuid_t *uuid)
{
	struct tb_xdp_uuid_response res;
	struct tb_xdp_uuid req;
	int ret;

	memset(&req, 0, sizeof(req));
	tb_xdp_fill_header(&req.hdr, route, retry % 4, UUID_REQUEST,
			   sizeof(req));

	memset(&res, 0, sizeof(res));
	ret = __tb_xdomain_request(ctl, &req, sizeof(req),
				   TB_CFG_PKG_XDOMAIN_REQ, &res, sizeof(res),
				   TB_CFG_PKG_XDOMAIN_RESP,
				   XDOMAIN_DEFAULT_TIMEOUT);
	if (ret)
		return ret;

	ret = tb_xdp_handle_error(&res.hdr);
	if (ret)
		return ret;

	uuid_copy(uuid, &res.src_uuid);
	return 0;
}

static int tb_xdp_uuid_response(struct tb_ctl *ctl, u64 route, u8 sequence,
				const uuid_t *uuid)
{
	struct tb_xdp_uuid_response res;

	memset(&res, 0, sizeof(res));
	tb_xdp_fill_header(&res.hdr, route, sequence, UUID_RESPONSE,
			   sizeof(res));

	uuid_copy(&res.src_uuid, uuid);
	res.src_route_hi = upper_32_bits(route);
	res.src_route_lo = lower_32_bits(route);

	return __tb_xdomain_response(ctl, &res, sizeof(res),
				     TB_CFG_PKG_XDOMAIN_RESP);
}

static int tb_xdp_error_response(struct tb_ctl *ctl, u64 route, u8 sequence,
				 enum tb_xdp_error error)
{
	struct tb_xdp_error_response res;

	memset(&res, 0, sizeof(res));
	tb_xdp_fill_header(&res.hdr, route, sequence, ERROR_RESPONSE,
			   sizeof(res));
	res.error = error;

	return __tb_xdomain_response(ctl, &res, sizeof(res),
				     TB_CFG_PKG_XDOMAIN_RESP);
}

static int tb_xdp_properties_request(struct tb_ctl *ctl, u64 route,
	const uuid_t *src_uuid, const uuid_t *dst_uuid, int retry,
	u32 **block, u32 *generation)
{
	struct tb_xdp_properties_response *res;
	struct tb_xdp_properties req;
	u16 data_len, len;
	size_t total_size;
	u32 *data = NULL;
	int ret;

	total_size = sizeof(*res) + TB_XDP_PROPERTIES_MAX_DATA_LENGTH * 4;
	res = kzalloc(total_size, GFP_KERNEL);
	if (!res)
		return -ENOMEM;

	memset(&req, 0, sizeof(req));
	tb_xdp_fill_header(&req.hdr, route, retry % 4, PROPERTIES_REQUEST,
			   sizeof(req));
	memcpy(&req.src_uuid, src_uuid, sizeof(*src_uuid));
	memcpy(&req.dst_uuid, dst_uuid, sizeof(*dst_uuid));

	len = 0;
	data_len = 0;

	do {
		ret = __tb_xdomain_request(ctl, &req, sizeof(req),
					   TB_CFG_PKG_XDOMAIN_REQ, res,
					   total_size, TB_CFG_PKG_XDOMAIN_RESP,
					   XDOMAIN_DEFAULT_TIMEOUT);
		if (ret)
			goto err;

		ret = tb_xdp_handle_error(&res->hdr);
		if (ret)
			goto err;

		/*
		 * Package length includes the whole payload without the
		 * XDomain header. Validate first that the package is at
		 * least size of the response structure.
		 */
		len = res->hdr.xd_hdr.length_sn & TB_XDOMAIN_LENGTH_MASK;
		if (len < sizeof(*res) / 4) {
			ret = -EINVAL;
			goto err;
		}

		len += sizeof(res->hdr.xd_hdr) / 4;
		len -= sizeof(*res) / 4;

		if (res->offset != req.offset) {
			ret = -EINVAL;
			goto err;
		}

		/*
		 * First time allocate block that has enough space for
		 * the whole properties block.
		 */
		if (!data) {
			data_len = res->data_length;
			if (data_len > TB_XDP_PROPERTIES_MAX_LENGTH) {
				ret = -E2BIG;
				goto err;
			}

			data = kcalloc(data_len, sizeof(u32), GFP_KERNEL);
			if (!data) {
				ret = -ENOMEM;
				goto err;
			}
		}

		memcpy(data + req.offset, res->data, len * 4);
		req.offset += len;
	} while (!data_len || req.offset < data_len);

	*block = data;
	*generation = res->generation;

	kfree(res);

	return data_len;

err:
	kfree(data);
	kfree(res);

	return ret;
}

static int tb_xdp_properties_response(struct tb *tb, struct tb_ctl *ctl,
	u64 route, u8 sequence, const uuid_t *src_uuid,
	const struct tb_xdp_properties *req)
{
	struct tb_xdp_properties_response *res;
	size_t total_size;
	u16 len;
	int ret;

	/*
	 * Currently we expect all requests to be directed to us. The
	 * protocol supports forwarding, though which we might add
	 * support later on.
	 */
	if (!uuid_equal(src_uuid, &req->dst_uuid)) {
		tb_xdp_error_response(ctl, route, sequence,
				      ERROR_UNKNOWN_DOMAIN);
		return 0;
	}

	mutex_lock(&xdomain_lock);

	if (req->offset >= xdomain_property_block_len) {
		mutex_unlock(&xdomain_lock);
		return -EINVAL;
	}

	len = xdomain_property_block_len - req->offset;
	len = min_t(u16, len, TB_XDP_PROPERTIES_MAX_DATA_LENGTH);
	total_size = sizeof(*res) + len * 4;

	res = kzalloc(total_size, GFP_KERNEL);
	if (!res) {
		mutex_unlock(&xdomain_lock);
		return -ENOMEM;
	}

	tb_xdp_fill_header(&res->hdr, route, sequence, PROPERTIES_RESPONSE,
			   total_size);
	res->generation = xdomain_property_block_gen;
	res->data_length = xdomain_property_block_len;
	res->offset = req->offset;
	uuid_copy(&res->src_uuid, src_uuid);
	uuid_copy(&res->dst_uuid, &req->src_uuid);
	memcpy(res->data, &xdomain_property_block[req->offset], len * 4);

	mutex_unlock(&xdomain_lock);

	ret = __tb_xdomain_response(ctl, res, total_size,
				    TB_CFG_PKG_XDOMAIN_RESP);

	kfree(res);
	return ret;
}

static int tb_xdp_properties_changed_request(struct tb_ctl *ctl, u64 route,
					     int retry, const uuid_t *uuid)
{
	struct tb_xdp_properties_changed_response res;
	struct tb_xdp_properties_changed req;
	int ret;

	memset(&req, 0, sizeof(req));
	tb_xdp_fill_header(&req.hdr, route, retry % 4,
			   PROPERTIES_CHANGED_REQUEST, sizeof(req));
	uuid_copy(&req.src_uuid, uuid);

	memset(&res, 0, sizeof(res));
	ret = __tb_xdomain_request(ctl, &req, sizeof(req),
				   TB_CFG_PKG_XDOMAIN_REQ, &res, sizeof(res),
				   TB_CFG_PKG_XDOMAIN_RESP,
				   XDOMAIN_DEFAULT_TIMEOUT);
	if (ret)
		return ret;

	return tb_xdp_handle_error(&res.hdr);
}

static int
tb_xdp_properties_changed_response(struct tb_ctl *ctl, u64 route, u8 sequence)
{
	struct tb_xdp_properties_changed_response res;

	memset(&res, 0, sizeof(res));
	tb_xdp_fill_header(&res.hdr, route, sequence,
			   PROPERTIES_CHANGED_RESPONSE, sizeof(res));
	return __tb_xdomain_response(ctl, &res, sizeof(res),
				     TB_CFG_PKG_XDOMAIN_RESP);
}

/**
 * tb_register_protocol_handler() - Register protocol handler
 * @handler: Handler to register
 *
 * This allows XDomain service drivers to hook into incoming XDomain
 * messages. After this function is called the service driver needs to
 * be able to handle calls to callback whenever a package with the
 * registered protocol is received.
 */
int tb_register_protocol_handler(struct tb_protocol_handler *handler)
{
	if (!handler->uuid || !handler->callback)
		return -EINVAL;
	if (uuid_equal(handler->uuid, &tb_xdp_uuid))
		return -EINVAL;

	mutex_lock(&xdomain_lock);
	list_add_tail(&handler->list, &protocol_handlers);
	mutex_unlock(&xdomain_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(tb_register_protocol_handler);

/**
 * tb_unregister_protocol_handler() - Unregister protocol handler
 * @handler: Handler to unregister
 *
 * Removes the previously registered protocol handler.
 */
void tb_unregister_protocol_handler(struct tb_protocol_handler *handler)
{
	mutex_lock(&xdomain_lock);
	list_del_init(&handler->list);
	mutex_unlock(&xdomain_lock);
}
EXPORT_SYMBOL_GPL(tb_unregister_protocol_handler);

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;
	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;
	}

	switch (pkg->type) {
	case PROPERTIES_REQUEST:
		ret = tb_xdp_properties_response(tb, ctl, route, sequence, uuid,
			(const struct tb_xdp_properties *)pkg);
		break;

	case PROPERTIES_CHANGED_REQUEST: {
		const struct tb_xdp_properties_changed *xchg =
			(const struct tb_xdp_properties_changed *)pkg;
		struct tb_xdomain *xd;

		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.
		 */
		xd = tb_xdomain_find_by_uuid_locked(tb, &xchg->src_uuid);
		if (xd) {
			queue_delayed_work(tb->wq, &xd->get_properties_work,
					   msecs_to_jiffies(50));
			tb_xdomain_put(xd);
		}

		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;
	}

	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);
}

static bool
tb_xdp_schedule_request(struct tb *tb, const struct tb_xdp_header *hdr,
			size_t size)
{
	struct xdomain_request_work *xw;

	xw = kmalloc(sizeof(*xw), GFP_KERNEL);
	if (!xw)
		return false;

	INIT_WORK(&xw->work, tb_xdp_handle_request);
	xw->pkg = kmemdup(hdr, size, GFP_KERNEL);
	if (!xw->pkg) {
		kfree(xw);
		return false;
	}
	xw->tb = tb_domain_get(tb);

	schedule_work(&xw->work);
	return true;
}

/**
 * tb_register_service_driver() - Register XDomain service driver
 * @drv: Driver to register
 *
 * Registers new service driver from @drv to the bus.
 */
int tb_register_service_driver(struct tb_service_driver *drv)
{
	drv->driver.bus = &tb_bus_type;
	return driver_register(&drv->driver);
}
EXPORT_SYMBOL_GPL(tb_register_service_driver);

/**
 * tb_unregister_service_driver() - Unregister XDomain service driver
 * @xdrv: Driver to unregister
 *
 * Unregisters XDomain service driver from the bus.
 */
void tb_unregister_service_driver(struct tb_service_driver *drv)
{
	driver_unregister(&drv->driver);
}
EXPORT_SYMBOL_GPL(tb_unregister_service_driver);

static ssize_t key_show(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	/*
	 * It should be null terminated but anything else is pretty much
	 * allowed.
	 */
	return sprintf(buf, "%*pE\n", (int)strlen(svc->key), svc->key);
}
static DEVICE_ATTR_RO(key);

static int get_modalias(struct tb_service *svc, char *buf, size_t size)
{
	return snprintf(buf, size, "tbsvc:k%sp%08Xv%08Xr%08X", svc->key,
			svc->prtcid, svc->prtcvers, svc->prtcrevs);
}

static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	/* Full buffer size except new line and null termination */
	get_modalias(svc, buf, PAGE_SIZE - 2);
	return sprintf(buf, "%s\n", buf);
}
static DEVICE_ATTR_RO(modalias);

static ssize_t prtcid_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	return sprintf(buf, "%u\n", svc->prtcid);
}
static DEVICE_ATTR_RO(prtcid);

static ssize_t prtcvers_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	return sprintf(buf, "%u\n", svc->prtcvers);
}
static DEVICE_ATTR_RO(prtcvers);

static ssize_t prtcrevs_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	return sprintf(buf, "%u\n", svc->prtcrevs);
}
static DEVICE_ATTR_RO(prtcrevs);

static ssize_t prtcstns_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);

	return sprintf(buf, "0x%08x\n", svc->prtcstns);
}
static DEVICE_ATTR_RO(prtcstns);

static struct attribute *tb_service_attrs[] = {
	&dev_attr_key.attr,
	&dev_attr_modalias.attr,
	&dev_attr_prtcid.attr,
	&dev_attr_prtcvers.attr,
	&dev_attr_prtcrevs.attr,
	&dev_attr_prtcstns.attr,
	NULL,
};

static struct attribute_group tb_service_attr_group = {
	.attrs = tb_service_attrs,
};

static const struct attribute_group *tb_service_attr_groups[] = {
	&tb_service_attr_group,
	NULL,
};

static int tb_service_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);
	char modalias[64];

	get_modalias(svc, modalias, sizeof(modalias));
	return add_uevent_var(env, "MODALIAS=%s", modalias);
}

static void tb_service_release(struct device *dev)
{
	struct tb_service *svc = container_of(dev, struct tb_service, dev);
	struct tb_xdomain *xd = tb_service_parent(svc);

	ida_simple_remove(&xd->service_ids, svc->id);
	kfree(svc->key);
	kfree(svc);
}

struct device_type tb_service_type = {
	.name = "thunderbolt_service",
	.groups = tb_service_attr_groups,
	.uevent = tb_service_uevent,
	.release = tb_service_release,
};
EXPORT_SYMBOL_GPL(tb_service_type);

static int remove_missing_service(struct device *dev, void *data)
{
	struct tb_xdomain *xd = data;
	struct tb_service *svc;

	svc = tb_to_service(dev);
	if (!svc)
		return 0;

	if (!tb_property_find(xd->properties, svc->key,
			      TB_PROPERTY_TYPE_DIRECTORY))
		device_unregister(dev);

	return 0;
}

static int find_service(struct device *dev, void *data)
{
	const struct tb_property *p = data;
	struct tb_service *svc;

	svc = tb_to_service(dev);
	if (!svc)
		return 0;

	return !strcmp(svc->key, p->key);
}

static int populate_service(struct tb_service *svc,
			    struct tb_property *property)
{
	struct tb_property_dir *dir = property->value.dir;
	struct tb_property *p;

	/* Fill in standard properties */
	p = tb_property_find(dir, "prtcid", TB_PROPERTY_TYPE_VALUE);
	if (p)
		svc->prtcid = p->value.immediate;
	p = tb_property_find(dir, "prtcvers", TB_PROPERTY_TYPE_VALUE);
	if (p)
		svc->prtcvers = p->value.immediate;
	p = tb_property_find(dir, "prtcrevs", TB_PROPERTY_TYPE_VALUE);
	if (p)
		svc->prtcrevs = p->value.immediate;
	p = tb_property_find(dir, "prtcstns", TB_PROPERTY_TYPE_VALUE);
	if (p)
		svc->prtcstns = p->value.immediate;

	svc->key = kstrdup(property->key, GFP_KERNEL);
	if (!svc->key)
		return -ENOMEM;

	return 0;
}

static void enumerate_services(struct tb_xdomain *xd)
{
	struct tb_service *svc;
	struct tb_property *p;
	struct device *dev;
	int id;

	/*
	 * First remove all services that are not available anymore in
	 * the updated property block.
	 */
	device_for_each_child_reverse(&xd->dev, xd, remove_missing_service);

	/* Then re-enumerate properties creating new services as we go */
	tb_property_for_each(xd->properties, p) {
		if (p->type != TB_PROPERTY_TYPE_DIRECTORY)
			continue;

		/* If the service exists already we are fine */
		dev = device_find_child(&xd->dev, p, find_service);
		if (dev) {
			put_device(dev);
			continue;
		}

		svc = kzalloc(sizeof(*svc), GFP_KERNEL);
		if (!svc)
			break;

		if (populate_service(svc, p)) {
			kfree(svc);
			break;
		}

		id = ida_simple_get(&xd->service_ids, 0, 0, GFP_KERNEL);
		if (id < 0) {
			kfree(svc);
			break;
		}
		svc->id = id;
		svc->dev.bus = &tb_bus_type;
		svc->dev.type = &tb_service_type;
		svc->dev.parent = &xd->dev;
		dev_set_name(&svc->dev, "%s.%d", dev_name(&xd->dev), svc->id);

		if (device_register(&svc->dev)) {
			put_device(&svc->dev);
			break;
		}
	}
}

static int populate_properties(struct tb_xdomain *xd,
			       struct tb_property_dir *dir)
{
	const struct tb_property *p;

	/* Required properties */
	p = tb_property_find(dir, "deviceid", TB_PROPERTY_TYPE_VALUE);
	if (!p)
		return -EINVAL;
	xd->device = p->value.immediate;

	p = tb_property_find(dir, "vendorid", TB_PROPERTY_TYPE_VALUE);
	if (!p)
		return -EINVAL;
	xd->vendor = p->value.immediate;

	kfree(xd->device_name);
	xd->device_name = NULL;
	kfree(xd->vendor_name);
	xd->vendor_name = NULL;

	/* Optional properties */
	p = tb_property_find(dir, "deviceid", TB_PROPERTY_TYPE_TEXT);
	if (p)
		xd->device_name = kstrdup(p->value.text, GFP_KERNEL);
	p = tb_property_find(dir, "vendorid", TB_PROPERTY_TYPE_TEXT);
	if (p)
		xd->vendor_name = kstrdup(p->value.text, GFP_KERNEL);

	return 0;
}

/* Called with @xd->lock held */
static void tb_xdomain_restore_paths(struct tb_xdomain *xd)
{
	if (!xd->resume)
		return;

	xd->resume = false;
	if (xd->transmit_path) {
		dev_dbg(&xd->dev, "re-establishing DMA path\n");
		tb_domain_approve_xdomain_paths(xd->tb, xd);
	}
}

static void tb_xdomain_get_uuid(struct work_struct *work)
{
	struct tb_xdomain *xd = container_of(work, typeof(*xd),
					     get_uuid_work.work);
	struct tb *tb = xd->tb;
	uuid_t uuid;
	int ret;

	ret = tb_xdp_uuid_request(tb->ctl, xd->route, xd->uuid_retries, &uuid);
	if (ret < 0) {
		if (xd->uuid_retries-- > 0) {
			queue_delayed_work(xd->tb->wq, &xd->get_uuid_work,
					   msecs_to_jiffies(100));
		} else {
			dev_dbg(&xd->dev, "failed to read remote UUID\n");
		}
		return;
	}

	if (uuid_equal(&uuid, xd->local_uuid)) {
		dev_dbg(&xd->dev, "intra-domain loop detected\n");
		return;
	}

	/*
	 * If the UUID is different, there is another domain connected
	 * so mark this one unplugged and wait for the connection
	 * manager to replace it.
	 */
	if (xd->remote_uuid && !uuid_equal(&uuid, xd->remote_uuid)) {
		dev_dbg(&xd->dev, "remote UUID is different, unplugging\n");
		xd->is_unplugged = true;
		return;
	}

	/* First time fill in the missing UUID */
	if (!xd->remote_uuid) {
		xd->remote_uuid = kmemdup(&uuid, sizeof(uuid_t), GFP_KERNEL);
		if (!xd->remote_uuid)
			return;
	}

	/* Now we can start the normal properties exchange */
	queue_delayed_work(xd->tb->wq, &xd->properties_changed_work,
			   msecs_to_jiffies(100));
	queue_delayed_work(xd->tb->wq, &xd->get_properties_work,
			   msecs_to_jiffies(1000));
}

static void tb_xdomain_get_properties(struct work_struct *work)
{
	struct tb_xdomain *xd = container_of(work, typeof(*xd),
					     get_properties_work.work);
	struct tb_property_dir *dir;
	struct tb *tb = xd->tb;
	bool update = false;
	u32 *block = NULL;
	u32 gen = 0;
	int ret;

	ret = tb_xdp_properties_request(tb->ctl, xd->route, xd->local_uuid,
					xd->remote_uuid, xd->properties_retries,
					&block, &gen);
	if (ret < 0) {
		if (xd->properties_retries-- > 0) {
			queue_delayed_work(xd->tb->wq, &xd->get_properties_work,
					   msecs_to_jiffies(1000));
		} else {
			/* Give up now */
			dev_err(&xd->dev,
				"failed read XDomain properties from %pUb\n",
				xd->remote_uuid);
		}
		return;
	}

	xd->properties_retries = XDOMAIN_PROPERTIES_RETRIES;

	mutex_lock(&xd->lock);

	/* Only accept newer generation properties */
	if (xd->properties && gen <= xd->property_block_gen) {
		/*
		 * On resume it is likely that the properties block is
		 * not changed (unless the other end added or removed
		 * services). However, we need to make sure the existing
		 * DMA paths are restored properly.
		 */
		tb_xdomain_restore_paths(xd);
		goto err_free_block;
	}

	dir = tb_property_parse_dir(block, ret);
	if (!dir) {
		dev_err(&xd->dev, "failed to parse XDomain properties\n");
		goto err_free_block;
	}

	ret = populate_properties(xd, dir);
	if (ret) {
		dev_err(&xd->dev, "missing XDomain properties in response\n");
		goto err_free_dir;
	}

	/* Release the existing one */
	if (xd->properties) {
		tb_property_free_dir(xd->properties);
		update = true;
	}

	xd->properties = dir;
	xd->property_block_gen = gen;

	tb_xdomain_restore_paths(xd);

	mutex_unlock(&xd->lock);

	kfree(block);

	/*
	 * Now the device should be ready enough so we can add it to the
	 * bus and let userspace know about it. If the device is already
	 * registered, we notify the userspace that it has changed.
	 */
	if (!update) {
		if (device_add(&xd->dev)) {
			dev_err(&xd->dev, "failed to add XDomain device\n");
			return;
		}
	} else {
		kobject_uevent(&xd->dev.kobj, KOBJ_CHANGE);
	}

	enumerate_services(xd);
	return;

err_free_dir:
	tb_property_free_dir(dir);
err_free_block:
	kfree(block);
	mutex_unlock(&xd->lock);
}

static void tb_xdomain_properties_changed(struct work_struct *work)
{
	struct tb_xdomain *xd = container_of(work, typeof(*xd),
					     properties_changed_work.work);
	int ret;

	ret = tb_xdp_properties_changed_request(xd->tb->ctl, xd->route,
				xd->properties_changed_retries, xd->local_uuid);
	if (ret) {
		if (xd->properties_changed_retries-- > 0)
			queue_delayed_work(xd->tb->wq,
					   &xd->properties_changed_work,
					   msecs_to_jiffies(1000));
		return;
	}

	xd->properties_changed_retries = XDOMAIN_PROPERTIES_CHANGED_RETRIES;
}

static ssize_t device_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	return sprintf(buf, "%#x\n", xd->device);
}
static DEVICE_ATTR_RO(device);

static ssize_t
device_name_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);
	int ret;

	if (mutex_lock_interruptible(&xd->lock))
		return -ERESTARTSYS;
	ret = sprintf(buf, "%s\n", xd->device_name ? xd->device_name : "");
	mutex_unlock(&xd->lock);

	return ret;
}
static DEVICE_ATTR_RO(device_name);

static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	return sprintf(buf, "%#x\n", xd->vendor);
}
static DEVICE_ATTR_RO(vendor);

static ssize_t
vendor_name_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);
	int ret;

	if (mutex_lock_interruptible(&xd->lock))
		return -ERESTARTSYS;
	ret = sprintf(buf, "%s\n", xd->vendor_name ? xd->vendor_name : "");
	mutex_unlock(&xd->lock);

	return ret;
}
static DEVICE_ATTR_RO(vendor_name);

static ssize_t unique_id_show(struct device *dev, struct device_attribute *attr,
			      char *buf)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	return sprintf(buf, "%pUb\n", xd->remote_uuid);
}
static DEVICE_ATTR_RO(unique_id);

static struct attribute *xdomain_attrs[] = {
	&dev_attr_device.attr,
	&dev_attr_device_name.attr,
	&dev_attr_unique_id.attr,
	&dev_attr_vendor.attr,
	&dev_attr_vendor_name.attr,
	NULL,
};

static struct attribute_group xdomain_attr_group = {
	.attrs = xdomain_attrs,
};

static const struct attribute_group *xdomain_attr_groups[] = {
	&xdomain_attr_group,
	NULL,
};

static void tb_xdomain_release(struct device *dev)
{
	struct tb_xdomain *xd = container_of(dev, struct tb_xdomain, dev);

	put_device(xd->dev.parent);

	tb_property_free_dir(xd->properties);
	ida_destroy(&xd->service_ids);

	kfree(xd->local_uuid);
	kfree(xd->remote_uuid);
	kfree(xd->device_name);
	kfree(xd->vendor_name);
	kfree(xd);
}

static void start_handshake(struct tb_xdomain *xd)
{
	xd->uuid_retries = XDOMAIN_UUID_RETRIES;
	xd->properties_retries = XDOMAIN_PROPERTIES_RETRIES;
	xd->properties_changed_retries = XDOMAIN_PROPERTIES_CHANGED_RETRIES;

	if (xd->needs_uuid) {
		queue_delayed_work(xd->tb->wq, &xd->get_uuid_work,
				   msecs_to_jiffies(100));
	} else {
		/* Start exchanging properties with the other host */
		queue_delayed_work(xd->tb->wq, &xd->properties_changed_work,
				   msecs_to_jiffies(100));
		queue_delayed_work(xd->tb->wq, &xd->get_properties_work,
				   msecs_to_jiffies(1000));
	}
}

static void stop_handshake(struct tb_xdomain *xd)
{
	xd->uuid_retries = 0;
	xd->properties_retries = 0;
	xd->properties_changed_retries = 0;

	cancel_delayed_work_sync(&xd->get_uuid_work);
	cancel_delayed_work_sync(&xd->get_properties_work);
	cancel_delayed_work_sync(&xd->properties_changed_work);
}

static int __maybe_unused tb_xdomain_suspend(struct device *dev)
{
	stop_handshake(tb_to_xdomain(dev));
	return 0;
}

static int __maybe_unused tb_xdomain_resume(struct device *dev)
{
	struct tb_xdomain *xd = tb_to_xdomain(dev);

	/*
	 * Ask tb_xdomain_get_properties() restore any existing DMA
	 * paths after properties are re-read.
	 */
	xd->resume = true;
	start_handshake(xd);

	return 0;
}

static const struct dev_pm_ops tb_xdomain_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(tb_xdomain_suspend, tb_xdomain_resume)
};

struct device_type tb_xdomain_type = {
	.name = "thunderbolt_xdomain",
	.release = tb_xdomain_release,
	.pm = &tb_xdomain_pm_ops,
};
EXPORT_SYMBOL_GPL(tb_xdomain_type);

/**
 * tb_xdomain_alloc() - Allocate new XDomain object
 * @tb: Domain where the XDomain belongs
 * @parent: Parent device (the switch through the connection to the
 *	    other domain is reached).
 * @route: Route string used to reach the other domain
 * @local_uuid: Our local domain UUID
 * @remote_uuid: UUID of the other domain (optional)
 *
 * Allocates new XDomain structure and returns pointer to that. The
 * object must be released by calling tb_xdomain_put().
 */
struct tb_xdomain *tb_xdomain_alloc(struct tb *tb, struct device *parent,
				    u64 route, const uuid_t *local_uuid,
				    const uuid_t *remote_uuid)
{
	struct tb_switch *parent_sw = tb_to_switch(parent);
	struct tb_xdomain *xd;
	struct tb_port *down;

	/* Make sure the downstream domain is accessible */
	down = tb_port_at(route, parent_sw);
	tb_port_unlock(down);

	xd = kzalloc(sizeof(*xd), GFP_KERNEL);
	if (!xd)
		return NULL;

	xd->tb = tb;
	xd->route = route;
	ida_init(&xd->service_ids);
	mutex_init(&xd->lock);
	INIT_DELAYED_WORK(&xd->get_uuid_work, tb_xdomain_get_uuid);
	INIT_DELAYED_WORK(&xd->get_properties_work, tb_xdomain_get_properties);
	INIT_DELAYED_WORK(&xd->properties_changed_work,
			  tb_xdomain_properties_changed);

	xd->local_uuid = kmemdup(local_uuid, sizeof(uuid_t), GFP_KERNEL);
	if (!xd->local_uuid)
		goto err_free;

	if (remote_uuid) {
		xd->remote_uuid = kmemdup(remote_uuid, sizeof(uuid_t),
					  GFP_KERNEL);
		if (!xd->remote_uuid)
			goto err_free_local_uuid;
	} else {
		xd->needs_uuid = true;
	}

	device_initialize(&xd->dev);
	xd->dev.parent = get_device(parent);
	xd->dev.bus = &tb_bus_type;
	xd->dev.type = &tb_xdomain_type;
	xd->dev.groups = xdomain_attr_groups;
	dev_set_name(&xd->dev, "%u-%llx", tb->index, route);

	/*
	 * This keeps the DMA powered on as long as we have active
	 * connection to another host.
	 */
	pm_runtime_set_active(&xd->dev);
	pm_runtime_get_noresume(&xd->dev);
	pm_runtime_enable(&xd->dev);

	return xd;

err_free_local_uuid:
	kfree(xd->local_uuid);
err_free:
	kfree(xd);

	return NULL;
}

/**
 * tb_xdomain_add() - Add XDomain to the bus
 * @xd: XDomain to add
 *
 * This function starts XDomain discovery protocol handshake and
 * eventually adds the XDomain to the bus. After calling this function
 * the caller needs to call tb_xdomain_remove() in order to remove and
 * release the object regardless whether the handshake succeeded or not.
 */
void tb_xdomain_add(struct tb_xdomain *xd)
{
	/* Start exchanging properties with the other host */
	start_handshake(xd);
}

static int unregister_service(struct device *dev, void *data)
{
	device_unregister(dev);
	return 0;
}

/**
 * tb_xdomain_remove() - Remove XDomain from the bus
 * @xd: XDomain to remove
 *
 * This will stop all ongoing configuration work and remove the XDomain
 * along with any services from the bus. When the last reference to @xd
 * is released the object will be released as well.
 */
void tb_xdomain_remove(struct tb_xdomain *xd)
{
	stop_handshake(xd);

	device_for_each_child_reverse(&xd->dev, xd, unregister_service);

	/*
	 * Undo runtime PM here explicitly because it is possible that
	 * the XDomain was never added to the bus and thus device_del()
	 * is not called for it (device_del() would handle this otherwise).
	 */
	pm_runtime_disable(&xd->dev);
	pm_runtime_put_noidle(&xd->dev);
	pm_runtime_set_suspended(&xd->dev);

	if (!device_is_registered(&xd->dev))
		put_device(&xd->dev);
	else
		device_unregister(&xd->dev);
}

/**
 * tb_xdomain_enable_paths() - Enable DMA paths for XDomain connection
 * @xd: XDomain connection
 * @transmit_path: HopID of the transmit path the other end is using to
 *		   send packets
 * @transmit_ring: DMA ring used to receive packets from the other end
 * @receive_path: HopID of the receive path the other end is using to
 *		  receive packets
 * @receive_ring: DMA ring used to send packets to the other end
 *
 * The function enables DMA paths accordingly so that after successful
 * return the caller can send and receive packets using high-speed DMA
 * path.
 *
 * Return: %0 in case of success and negative errno in case of error
 */
int tb_xdomain_enable_paths(struct tb_xdomain *xd, u16 transmit_path,
			    u16 transmit_ring, u16 receive_path,
			    u16 receive_ring)
{
	int ret;

	mutex_lock(&xd->lock);

	if (xd->transmit_path) {
		ret = xd->transmit_path == transmit_path ? 0 : -EBUSY;
		goto exit_unlock;
	}

	xd->transmit_path = transmit_path;
	xd->transmit_ring = transmit_ring;
	xd->receive_path = receive_path;
	xd->receive_ring = receive_ring;

	ret = tb_domain_approve_xdomain_paths(xd->tb, xd);

exit_unlock:
	mutex_unlock(&xd->lock);

	return ret;
}
EXPORT_SYMBOL_GPL(tb_xdomain_enable_paths);

/**
 * tb_xdomain_disable_paths() - Disable DMA paths for XDomain connection
 * @xd: XDomain connection
 *
 * This does the opposite of tb_xdomain_enable_paths(). After call to
 * this the caller is not expected to use the rings anymore.
 *
 * Return: %0 in case of success and negative errno in case of error
 */
int tb_xdomain_disable_paths(struct tb_xdomain *xd)
{
	int ret = 0;

	mutex_lock(&xd->lock);
	if (xd->transmit_path) {
		xd->transmit_path = 0;
		xd->transmit_ring = 0;
		xd->receive_path = 0;
		xd->receive_ring = 0;

		ret = tb_domain_disconnect_xdomain_paths(xd->tb, xd);
	}
	mutex_unlock(&xd->lock);

	return ret;
}
EXPORT_SYMBOL_GPL(tb_xdomain_disable_paths);

struct tb_xdomain_lookup {
	const uuid_t *uuid;
	u8 link;
	u8 depth;
	u64 route;
};

static struct tb_xdomain *switch_find_xdomain(struct tb_switch *sw,
	const struct tb_xdomain_lookup *lookup)
{
	struct tb_port *port;

	tb_switch_for_each_port(sw, port) {
		struct tb_xdomain *xd;

		if (port->xdomain) {
			xd = port->xdomain;

			if (lookup->uuid) {
				if (xd->remote_uuid &&
				    uuid_equal(xd->remote_uuid, lookup->uuid))
					return xd;
			} else if (lookup->link &&
				   lookup->link == xd->link &&
				   lookup->depth == xd->depth) {
				return xd;
			} else if (lookup->route &&
				   lookup->route == xd->route) {
				return xd;
			}
		} else if (tb_port_has_remote(port)) {
			xd = switch_find_xdomain(port->remote->sw, lookup);
			if (xd)
				return xd;
		}
	}

	return NULL;
}

/**
 * tb_xdomain_find_by_uuid() - Find an XDomain by UUID
 * @tb: Domain where the XDomain belongs to
 * @uuid: UUID to look for
 *
 * Finds XDomain by walking through the Thunderbolt topology below @tb.
 * The returned XDomain will have its reference count increased so the
 * caller needs to call tb_xdomain_put() when it is done with the
 * object.
 *
 * This will find all XDomains including the ones that are not yet added
 * to the bus (handshake is still in progress).
 *
 * The caller needs to hold @tb->lock.
 */
struct tb_xdomain *tb_xdomain_find_by_uuid(struct tb *tb, const uuid_t *uuid)
{
	struct tb_xdomain_lookup lookup;
	struct tb_xdomain *xd;

	memset(&lookup, 0, sizeof(lookup));
	lookup.uuid = uuid;

	xd = switch_find_xdomain(tb->root_switch, &lookup);
	return tb_xdomain_get(xd);
}
EXPORT_SYMBOL_GPL(tb_xdomain_find_by_uuid);

/**
 * tb_xdomain_find_by_link_depth() - Find an XDomain by link and depth
 * @tb: Domain where the XDomain belongs to
 * @link: Root switch link number
 * @depth: Depth in the link
 *
 * Finds XDomain by walking through the Thunderbolt topology below @tb.
 * The returned XDomain will have its reference count increased so the
 * caller needs to call tb_xdomain_put() when it is done with the
 * object.
 *
 * This will find all XDomains including the ones that are not yet added
 * to the bus (handshake is still in progress).
 *
 * The caller needs to hold @tb->lock.
 */
struct tb_xdomain *tb_xdomain_find_by_link_depth(struct tb *tb, u8 link,
						 u8 depth)
{
	struct tb_xdomain_lookup lookup;
	struct tb_xdomain *xd;

	memset(&lookup, 0, sizeof(lookup));
	lookup.link = link;
	lookup.depth = depth;

	xd = switch_find_xdomain(tb->root_switch, &lookup);
	return tb_xdomain_get(xd);
}

/**
 * tb_xdomain_find_by_route() - Find an XDomain by route string
 * @tb: Domain where the XDomain belongs to
 * @route: XDomain route string
 *
 * Finds XDomain by walking through the Thunderbolt topology below @tb.
 * The returned XDomain will have its reference count increased so the
 * caller needs to call tb_xdomain_put() when it is done with the
 * object.
 *
 * This will find all XDomains including the ones that are not yet added
 * to the bus (handshake is still in progress).
 *
 * The caller needs to hold @tb->lock.
 */
struct tb_xdomain *tb_xdomain_find_by_route(struct tb *tb, u64 route)
{
	struct tb_xdomain_lookup lookup;
	struct tb_xdomain *xd;

	memset(&lookup, 0, sizeof(lookup));
	lookup.route = route;

	xd = switch_find_xdomain(tb->root_switch, &lookup);
	return tb_xdomain_get(xd);
}
EXPORT_SYMBOL_GPL(tb_xdomain_find_by_route);

bool tb_xdomain_handle_request(struct tb *tb, enum tb_cfg_pkg_type type,
			       const void *buf, size_t size)
{
	const struct tb_protocol_handler *handler, *tmp;
	const struct tb_xdp_header *hdr = buf;
	unsigned int length;
	int ret = 0;

	/* We expect the packet is at least size of the header */
	length = hdr->xd_hdr.length_sn & TB_XDOMAIN_LENGTH_MASK;
	if (length != size / 4 - sizeof(hdr->xd_hdr) / 4)
		return true;
	if (length < sizeof(*hdr) / 4 - sizeof(hdr->xd_hdr) / 4)
		return true;

	/*
	 * Handle XDomain discovery protocol packets directly here. For
	 * other protocols (based on their UUID) we call registered
	 * handlers in turn.
	 */
	if (uuid_equal(&hdr->uuid, &tb_xdp_uuid)) {
		if (type == TB_CFG_PKG_XDOMAIN_REQ)
			return tb_xdp_schedule_request(tb, hdr, size);
		return false;
	}

	mutex_lock(&xdomain_lock);
	list_for_each_entry_safe(handler, tmp, &protocol_handlers, list) {
		if (!uuid_equal(&hdr->uuid, handler->uuid))
			continue;

		mutex_unlock(&xdomain_lock);
		ret = handler->callback(buf, size, handler->data);
		mutex_lock(&xdomain_lock);

		if (ret)
			break;
	}
	mutex_unlock(&xdomain_lock);

	return ret > 0;
}

static int rebuild_property_block(void)
{
	u32 *block, len;
	int ret;

	ret = tb_property_format_dir(xdomain_property_dir, NULL, 0);
	if (ret < 0)
		return ret;

	len = ret;

	block = kcalloc(len, sizeof(u32), GFP_KERNEL);
	if (!block)
		return -ENOMEM;

	ret = tb_property_format_dir(xdomain_property_dir, block, len);
	if (ret) {
		kfree(block);
		return ret;
	}

	kfree(xdomain_property_block);
	xdomain_property_block = block;
	xdomain_property_block_len = len;
	xdomain_property_block_gen++;

	return 0;
}

static int update_xdomain(struct device *dev, void *data)
{
	struct tb_xdomain *xd;

	xd = tb_to_xdomain(dev);
	if (xd) {
		queue_delayed_work(xd->tb->wq, &xd->properties_changed_work,
				   msecs_to_jiffies(50));
	}

	return 0;
}

static void update_all_xdomains(void)
{
	bus_for_each_dev(&tb_bus_type, NULL, NULL, update_xdomain);
}

static bool remove_directory(const char *key, const struct tb_property_dir *dir)
{
	struct tb_property *p;

	p = tb_property_find(xdomain_property_dir, key,
			     TB_PROPERTY_TYPE_DIRECTORY);
	if (p && p->value.dir == dir) {
		tb_property_remove(p);
		return true;
	}
	return false;
}

/**
 * tb_register_property_dir() - Register property directory to the host
 * @key: Key (name) of the directory to add
 * @dir: Directory to add
 *
 * Service drivers can use this function to add new property directory
 * to the host available properties. The other connected hosts are
 * notified so they can re-read properties of this host if they are
 * interested.
 *
 * Return: %0 on success and negative errno on failure
 */
int tb_register_property_dir(const char *key, struct tb_property_dir *dir)
{
	int ret;

	if (WARN_ON(!xdomain_property_dir))
		return -EAGAIN;

	if (!key || strlen(key) > 8)
		return -EINVAL;

	mutex_lock(&xdomain_lock);
	if (tb_property_find(xdomain_property_dir, key,
			     TB_PROPERTY_TYPE_DIRECTORY)) {
		ret = -EEXIST;
		goto err_unlock;
	}

	ret = tb_property_add_dir(xdomain_property_dir, key, dir);
	if (ret)
		goto err_unlock;

	ret = rebuild_property_block();
	if (ret) {
		remove_directory(key, dir);
		goto err_unlock;
	}

	mutex_unlock(&xdomain_lock);
	update_all_xdomains();
	return 0;

err_unlock:
	mutex_unlock(&xdomain_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(tb_register_property_dir);

/**
 * tb_unregister_property_dir() - Removes property directory from host
 * @key: Key (name) of the directory
 * @dir: Directory to remove
 *
 * This will remove the existing directory from this host and notify the
 * connected hosts about the change.
 */
void tb_unregister_property_dir(const char *key, struct tb_property_dir *dir)
{
	int ret = 0;

	mutex_lock(&xdomain_lock);
	if (remove_directory(key, dir))
		ret = rebuild_property_block();
	mutex_unlock(&xdomain_lock);

	if (!ret)
		update_all_xdomains();
}
EXPORT_SYMBOL_GPL(tb_unregister_property_dir);

int tb_xdomain_init(void)
{
	int ret;

	xdomain_property_dir = tb_property_create_dir(NULL);
	if (!xdomain_property_dir)
		return -ENOMEM;

	/*
	 * Initialize standard set of properties without any service
	 * directories. Those will be added by service drivers
	 * themselves when they are loaded.
	 */
	tb_property_add_immediate(xdomain_property_dir, "vendorid",
				  PCI_VENDOR_ID_INTEL);
	tb_property_add_text(xdomain_property_dir, "vendorid", "Intel Corp.");
	tb_property_add_immediate(xdomain_property_dir, "deviceid", 0x1);
	tb_property_add_text(xdomain_property_dir, "deviceid",
			     utsname()->nodename);
	tb_property_add_immediate(xdomain_property_dir, "devicerv", 0x80000100);

	ret = rebuild_property_block();
	if (ret) {
		tb_property_free_dir(xdomain_property_dir);
		xdomain_property_dir = NULL;
	}

	return ret;
}

void tb_xdomain_exit(void)
{
	kfree(xdomain_property_block);
	tb_property_free_dir(xdomain_property_dir);
}
