/*
 * Greybus manifest parsing
 *
 * Copyright 2014-2015 Google Inc.
 * Copyright 2014-2015 Linaro Ltd.
 *
 * Released under the GPLv2 only.
 */

#include "greybus.h"

static const char *get_descriptor_type_string(u8 type)
{
	switch(type) {
	case GREYBUS_TYPE_INVALID:
		return "invalid";
	case GREYBUS_TYPE_STRING:
		return "string";
	case GREYBUS_TYPE_INTERFACE:
		return "interface";
	case GREYBUS_TYPE_CPORT:
		return "cport";
	case GREYBUS_TYPE_BUNDLE:
		return "bundle";
	default:
		WARN_ON(1);
		return "unknown";
	}
}

/*
 * We scan the manifest once to identify where all the descriptors
 * are.  The result is a list of these manifest_desc structures.  We
 * then pick through them for what we're looking for (starting with
 * the interface descriptor).  As each is processed we remove it from
 * the list.  When we're done the list should (probably) be empty.
 */
struct manifest_desc {
	struct list_head		links;

	size_t				size;
	void				*data;
	enum greybus_descriptor_type	type;
};

static void release_manifest_descriptor(struct manifest_desc *descriptor)
{
	list_del(&descriptor->links);
	kfree(descriptor);
}

static void release_manifest_descriptors(struct gb_interface *intf)
{
	struct manifest_desc *descriptor;
	struct manifest_desc *next;

	list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
		release_manifest_descriptor(descriptor);
}

static void release_cport_descriptors(struct list_head *head, u8 bundle_id)
{
	struct manifest_desc *desc, *tmp;
	struct greybus_descriptor_cport *desc_cport;

	list_for_each_entry_safe(desc, tmp, head, links) {
		desc_cport = desc->data;

		if (desc->type != GREYBUS_TYPE_CPORT)
			continue;

		if (desc_cport->bundle == bundle_id)
			release_manifest_descriptor(desc);
	}
}

static struct manifest_desc *get_next_bundle_desc(struct gb_interface *intf)
{
	struct manifest_desc *descriptor;
	struct manifest_desc *next;

	list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
		if (descriptor->type == GREYBUS_TYPE_BUNDLE)
			return descriptor;

	return NULL;
}

/*
 * Validate the given descriptor.  Its reported size must fit within
 * the number of bytes remaining, and it must have a recognized
 * type.  Check that the reported size is at least as big as what
 * we expect to see.  (It could be bigger, perhaps for a new version
 * of the format.)
 *
 * Returns the (non-zero) number of bytes consumed by the descriptor,
 * or a negative errno.
 */
static int identify_descriptor(struct gb_interface *intf,
			       struct greybus_descriptor *desc, size_t size)
{
	struct greybus_descriptor_header *desc_header = &desc->header;
	struct manifest_desc *descriptor;
	size_t desc_size;
	size_t expected_size;

	if (size < sizeof(*desc_header)) {
		dev_err(&intf->dev, "manifest too small (%zu < %zu)\n",
				size, sizeof(*desc_header));
		return -EINVAL;		/* Must at least have header */
	}

	desc_size = le16_to_cpu(desc_header->size);
	if (desc_size > size) {
		dev_err(&intf->dev, "descriptor too big (%zu > %zu)\n",
				desc_size, size);
		return -EINVAL;
	}

	/* Descriptor needs to at least have a header */
	expected_size = sizeof(*desc_header);

	switch (desc_header->type) {
	case GREYBUS_TYPE_STRING:
		expected_size += sizeof(struct greybus_descriptor_string);
		expected_size += desc->string.length;

		/* String descriptors are padded to 4 byte boundaries */
		expected_size = ALIGN(expected_size, 4);
		break;
	case GREYBUS_TYPE_INTERFACE:
		expected_size += sizeof(struct greybus_descriptor_interface);
		break;
	case GREYBUS_TYPE_BUNDLE:
		expected_size += sizeof(struct greybus_descriptor_bundle);
		break;
	case GREYBUS_TYPE_CPORT:
		expected_size += sizeof(struct greybus_descriptor_cport);
		break;
	case GREYBUS_TYPE_INVALID:
	default:
		dev_err(&intf->dev, "invalid descriptor type (%u)\n",
				desc_header->type);
		return -EINVAL;
	}

	if (desc_size < expected_size) {
		dev_err(&intf->dev, "%s descriptor too small (%zu < %zu)\n",
				get_descriptor_type_string(desc_header->type),
				desc_size, expected_size);
		return -EINVAL;
	}

	/* Descriptor bigger than what we expect */
	if (desc_size > expected_size) {
		dev_warn(&intf->dev, "%s descriptor size mismatch (want %zu got %zu)\n",
				get_descriptor_type_string(desc_header->type),
				expected_size, desc_size);
	}

	descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL);
	if (!descriptor)
		return -ENOMEM;

	descriptor->size = desc_size;
	descriptor->data = (char *)desc + sizeof(*desc_header);
	descriptor->type = desc_header->type;
	list_add_tail(&descriptor->links, &intf->manifest_descs);

	/* desc_size is positive and is known to fit in a signed int */

	return desc_size;
}

/*
 * Find the string descriptor having the given id, validate it, and
 * allocate a duplicate copy of it.  The duplicate has an extra byte
 * which guarantees the returned string is NUL-terminated.
 *
 * String index 0 is valid (it represents "no string"), and for
 * that a null pointer is returned.
 *
 * Otherwise returns a pointer to a newly-allocated copy of the
 * descriptor string, or an error-coded pointer on failure.
 */
static char *gb_string_get(struct gb_interface *intf, u8 string_id)
{
	struct greybus_descriptor_string *desc_string;
	struct manifest_desc *descriptor;
	bool found = false;
	char *string;

	/* A zero string id means no string (but no error) */
	if (!string_id)
		return NULL;

	list_for_each_entry(descriptor, &intf->manifest_descs, links) {
		if (descriptor->type != GREYBUS_TYPE_STRING)
			continue;

		desc_string = descriptor->data;
		if (desc_string->id == string_id) {
			found = true;
			break;
		}
	}
	if (!found)
		return ERR_PTR(-ENOENT);

	/* Allocate an extra byte so we can guarantee it's NUL-terminated */
	string = kmemdup(&desc_string->string, desc_string->length + 1,
				GFP_KERNEL);
	if (!string)
		return ERR_PTR(-ENOMEM);
	string[desc_string->length] = '\0';

	/* Ok we've used this string, so we're done with it */
	release_manifest_descriptor(descriptor);

	return string;
}

/*
 * Find cport descriptors in the manifest associated with the given
 * bundle, and set up data structures for the functions that use
 * them.  Returns the number of cports set up for the bundle, or 0
 * if there is an error.
 */
static u32 gb_manifest_parse_cports(struct gb_bundle *bundle)
{
	struct gb_interface *intf = bundle->intf;
	struct greybus_descriptor_cport *desc_cport;
	struct manifest_desc *desc, *next, *tmp;
	LIST_HEAD(list);
	u8 bundle_id = bundle->id;
	u16 cport_id;
	u32 count = 0;
	int i;

	/* Set up all cport descriptors associated with this bundle */
	list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) {
		if (desc->type != GREYBUS_TYPE_CPORT)
			continue;

		desc_cport = desc->data;
		if (desc_cport->bundle != bundle_id)
			continue;

		cport_id = le16_to_cpu(desc_cport->id);
		if (cport_id > CPORT_ID_MAX)
			goto exit;

		/*
		 * Found one, move it to our temporary list after checking for
		 * duplicates.
		 */
		list_for_each_entry(tmp, &list, links) {
			desc_cport = tmp->data;
			if (cport_id == le16_to_cpu(desc_cport->id)) {
				dev_err(&bundle->dev,
						"duplicate CPort %u found\n",
						cport_id);
				goto exit;
			}
		}
		list_move_tail(&desc->links, &list);
		count++;
	}

	if (!count)
		return 0;

	bundle->cport_desc = kcalloc(count, sizeof(*bundle->cport_desc),
					GFP_KERNEL);
	if (!bundle->cport_desc)
		goto exit;

	bundle->num_cports = count;

	i = 0;
	list_for_each_entry_safe(desc, next, &list, links) {
		desc_cport = desc->data;
		memcpy(&bundle->cport_desc[i++], desc_cport,
				sizeof(*desc_cport));

		/* Release the cport descriptor */
		release_manifest_descriptor(desc);
	}

	return count;
exit:
	release_cport_descriptors(&list, bundle_id);
	/*
	 * Free all cports for this bundle to avoid 'excess descriptors'
	 * warnings.
	 */
	release_cport_descriptors(&intf->manifest_descs, bundle_id);

	return 0;	/* Error; count should also be 0 */
}

/*
 * Find bundle descriptors in the manifest and set up their data
 * structures.  Returns the number of bundles set up for the
 * given interface.
 */
static u32 gb_manifest_parse_bundles(struct gb_interface *intf)
{
	struct manifest_desc *desc;
	struct gb_bundle *bundle;
	struct gb_bundle *bundle_next;
	u32 count = 0;
	u8 bundle_id;
	u8 class;

	while ((desc = get_next_bundle_desc(intf))) {
		struct greybus_descriptor_bundle *desc_bundle;

		/* Found one.  Set up its bundle structure*/
		desc_bundle = desc->data;
		bundle_id = desc_bundle->id;
		class = desc_bundle->class;

		/* Done with this bundle descriptor */
		release_manifest_descriptor(desc);

		/* Ignore any legacy control bundles */
		if (bundle_id == GB_CONTROL_BUNDLE_ID) {
			dev_dbg(&intf->dev, "%s - ignoring control bundle\n",
					__func__);
			release_cport_descriptors(&intf->manifest_descs,
								bundle_id);
			continue;
		}

		/* Nothing else should have its class set to control class */
		if (class == GREYBUS_CLASS_CONTROL) {
			dev_err(&intf->dev,
				"bundle %u cannot use control class\n",
				bundle_id);
			goto cleanup;
		}

		bundle = gb_bundle_create(intf, bundle_id, class);
		if (!bundle)
			goto cleanup;

		/*
		 * Now go set up this bundle's functions and cports.
		 *
		 * A 'bundle' represents a device in greybus. It may require
		 * multiple cports for its functioning. If we fail to setup any
		 * cport of a bundle, we better reject the complete bundle as
		 * the device may not be able to function properly then.
		 *
		 * But, failing to setup a cport of bundle X doesn't mean that
		 * the device corresponding to bundle Y will not work properly.
		 * Bundles should be treated as separate independent devices.
		 *
		 * While parsing manifest for an interface, treat bundles as
		 * separate entities and don't reject entire interface and its
		 * bundles on failing to initialize a cport. But make sure the
		 * bundle which needs the cport, gets destroyed properly.
		 */
		if (!gb_manifest_parse_cports(bundle)) {
			gb_bundle_destroy(bundle);
			continue;
		}

		count++;
	}

	return count;
cleanup:
	/* An error occurred; undo any changes we've made */
	list_for_each_entry_safe(bundle, bundle_next, &intf->bundles, links) {
		gb_bundle_destroy(bundle);
		count--;
	}
	return 0;	/* Error; count should also be 0 */
}

static bool gb_manifest_parse_interface(struct gb_interface *intf,
					struct manifest_desc *interface_desc)
{
	struct greybus_descriptor_interface *desc_intf = interface_desc->data;

	/* Handle the strings first--they can fail */
	intf->vendor_string = gb_string_get(intf, desc_intf->vendor_stringid);
	if (IS_ERR(intf->vendor_string))
		return false;

	intf->product_string = gb_string_get(intf, desc_intf->product_stringid);
	if (IS_ERR(intf->product_string))
		goto out_free_vendor_string;

	/* Release the interface descriptor, now that we're done with it */
	release_manifest_descriptor(interface_desc);

	/* An interface must have at least one bundle descriptor */
	if (!gb_manifest_parse_bundles(intf)) {
		dev_err(&intf->dev, "manifest bundle descriptors not valid\n");
		goto out_err;
	}

	return true;
out_err:
	kfree(intf->product_string);
	intf->product_string = NULL;
out_free_vendor_string:
	kfree(intf->vendor_string);
	intf->vendor_string = NULL;

	return false;
}

/*
 * Parse a buffer containing an interface manifest.
 *
 * If we find anything wrong with the content/format of the buffer
 * we reject it.
 *
 * The first requirement is that the manifest's version is
 * one we can parse.
 *
 * We make an initial pass through the buffer and identify all of
 * the descriptors it contains, keeping track for each its type
 * and the location size of its data in the buffer.
 *
 * Next we scan the descriptors, looking for an interface descriptor;
 * there must be exactly one of those.  When found, we record the
 * information it contains, and then remove that descriptor (and any
 * string descriptors it refers to) from further consideration.
 *
 * After that we look for the interface's bundles--there must be at
 * least one of those.
 *
 * Returns true if parsing was successful, false otherwise.
 */
bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size)
{
	struct greybus_manifest *manifest;
	struct greybus_manifest_header *header;
	struct greybus_descriptor *desc;
	struct manifest_desc *descriptor;
	struct manifest_desc *interface_desc = NULL;
	u16 manifest_size;
	u32 found = 0;
	bool result;

	/* Manifest descriptor list should be empty here */
	if (WARN_ON(!list_empty(&intf->manifest_descs)))
		return false;

	/* we have to have at _least_ the manifest header */
	if (size < sizeof(*header)) {
		dev_err(&intf->dev, "short manifest (%zu < %zu)\n",
				size, sizeof(*header));
		return false;
	}

	/* Make sure the size is right */
	manifest = data;
	header = &manifest->header;
	manifest_size = le16_to_cpu(header->size);
	if (manifest_size != size) {
		dev_err(&intf->dev, "manifest size mismatch (%zu != %u)\n",
				size, manifest_size);
		return false;
	}

	/* Validate major/minor number */
	if (header->version_major > GREYBUS_VERSION_MAJOR) {
		dev_err(&intf->dev, "manifest version too new (%u.%u > %u.%u)\n",
				header->version_major, header->version_minor,
				GREYBUS_VERSION_MAJOR, GREYBUS_VERSION_MINOR);
		return false;
	}

	/* OK, find all the descriptors */
	desc = manifest->descriptors;
	size -= sizeof(*header);
	while (size) {
		int desc_size;

		desc_size = identify_descriptor(intf, desc, size);
		if (desc_size < 0) {
			result = false;
			goto out;
		}
		desc = (struct greybus_descriptor *)((char *)desc + desc_size);
		size -= desc_size;
	}

	/* There must be a single interface descriptor */
	list_for_each_entry(descriptor, &intf->manifest_descs, links) {
		if (descriptor->type == GREYBUS_TYPE_INTERFACE)
			if (!found++)
				interface_desc = descriptor;
	}
	if (found != 1) {
		dev_err(&intf->dev, "manifest must have 1 interface descriptor (%u found)\n",
				found);
		result = false;
		goto out;
	}

	/* Parse the manifest, starting with the interface descriptor */
	result = gb_manifest_parse_interface(intf, interface_desc);

	/*
	 * We really should have no remaining descriptors, but we
	 * don't know what newer format manifests might leave.
	 */
	if (result && !list_empty(&intf->manifest_descs))
		dev_info(&intf->dev, "excess descriptors in interface manifest\n");
out:
	release_manifest_descriptors(intf);

	return result;
}
