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

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include "greybus.h"

/* Global list of registered protocols */
static DEFINE_SPINLOCK(gb_protocols_lock);
static LIST_HEAD(gb_protocols);

/* Caller must hold gb_protocols_lock */
static struct gb_protocol *gb_protocol_find(u8 id, u8 major, u8 minor)
{
	struct gb_protocol *protocol;

	list_for_each_entry(protocol, &gb_protocols, links) {
		if (protocol->id < id)
			continue;
		if (protocol->id > id)
			break;

		if (protocol->major > major)
			continue;
		if (protocol->major < major)
			break;

		if (protocol->minor > minor)
			continue;
		if (protocol->minor < minor)
			break;

		return protocol;
	}
	return NULL;
}

int __gb_protocol_register(struct gb_protocol *protocol, struct module *module)
{
	struct gb_protocol *existing;
	u8 id = protocol->id;
	u8 major = protocol->major;
	u8 minor = protocol->minor;

	protocol->owner = module;

	/*
	 * The protocols list is sorted first by protocol id (low to
	 * high), then by major version (high to low), and finally
	 * by minor version (high to low).  Searching only by
	 * protocol id will produce the newest implemented version
	 * of the protocol.
	 */
	spin_lock_irq(&gb_protocols_lock);

	list_for_each_entry(existing, &gb_protocols, links) {
		if (existing->id < id)
			continue;
		if (existing->id > id)
			break;

		if (existing->major > major)
			continue;
		if (existing->major < major)
			break;

		if (existing->minor > minor)
			continue;
		if (existing->minor < minor)
			break;

		/* A matching protocol has already been registered */
		spin_unlock_irq(&gb_protocols_lock);

		return -EEXIST;
	}

	/*
	 * We need to insert the protocol here, before the existing one
	 * (or before the head if we searched the whole list)
	 */
	list_add_tail(&protocol->links, &existing->links);
	spin_unlock_irq(&gb_protocols_lock);

	pr_info("Registered %s protocol.\n", protocol->name);

	/*
	 * Go try to bind any unbound connections, as we have a
	 * new protocol in the system
	 */
	gb_bundle_bind_protocols();

	return 0;
}
EXPORT_SYMBOL_GPL(__gb_protocol_register);

/*
 * De-register a previously registered protocol.
 *
 * XXX Currently this fails (and reports an error to the caller) if
 * XXX the protocol is currently in use.  We may want to forcefully
 * XXX kill off a protocol and all its active users at some point.
 * XXX But I think that's better handled by quiescing modules that
 * XXX have users and having those users drop their reference.
 *
 * Returns true if successful, false otherwise.
 */
int gb_protocol_deregister(struct gb_protocol *protocol)
{
	u8 protocol_count = 0;

	if (!protocol)
		return 0;

	spin_lock_irq(&gb_protocols_lock);
	protocol = gb_protocol_find(protocol->id, protocol->major,
				    protocol->minor);
	if (protocol) {
		protocol_count = protocol->count;
		if (!protocol_count)
			list_del(&protocol->links);
	}
	spin_unlock_irq(&gb_protocols_lock);

	if (protocol)
		pr_info("Deregistered %s protocol.\n", protocol->name);

	return protocol && !protocol_count;
}
EXPORT_SYMBOL_GPL(gb_protocol_deregister);

/* Returns the requested protocol if available, or a null pointer */
struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor)
{
	struct gb_protocol *protocol;
	u8 protocol_count;

	spin_lock_irq(&gb_protocols_lock);
	protocol = gb_protocol_find(id, major, minor);
	if (protocol) {
		if (!try_module_get(protocol->owner)) {
			protocol = NULL;
		} else {
			protocol_count = protocol->count;
			if (protocol_count != U8_MAX)
				protocol->count++;
		}
	}
	spin_unlock_irq(&gb_protocols_lock);

	if (protocol)
		WARN_ON(protocol_count == U8_MAX);
	else
		pr_err("protocol id %hhu version %hhu.%hhu not found\n",
			id, major, minor);

	return protocol;
}

int gb_protocol_get_version(struct gb_connection *connection, int type,
			    void *request, int request_size,
			    struct gb_protocol_version_response *response,
			    __u8 major)
{
	int retval;

	retval = gb_operation_sync(connection, type, request, request_size,
				   response, sizeof(*response));
	if (retval)
		return retval;

	if (response->major > major) {
		dev_err(&connection->dev,
			"unsupported major version (%hhu > %hhu)\n",
			response->major, major);
		return -ENOTSUPP;
	}

	dev_dbg(&connection->dev, "version_major = %u version_minor = %u\n",
		response->major, response->minor);

	return 0;
}
EXPORT_SYMBOL_GPL(gb_protocol_get_version);

void gb_protocol_put(struct gb_protocol *protocol)
{
	u8 id;
	u8 major;
	u8 minor;
	u8 protocol_count;

	if (!protocol)
		return;

	id = protocol->id;
	major = protocol->major;
	minor = protocol->minor;

	spin_lock_irq(&gb_protocols_lock);
	protocol = gb_protocol_find(id, major, minor);
	if (protocol) {
		protocol_count = protocol->count;
		if (protocol_count)
			protocol->count--;
		module_put(protocol->owner);
	}
	spin_unlock_irq(&gb_protocols_lock);
	if (protocol)
		WARN_ON(!protocol_count);
	else
		pr_err("protocol id %hhu version %hhu.%hhu not found\n",
			id, major, minor);
}
