/*
 * net/tipc/user_reg.c: TIPC user registry code
 * 
 * Copyright (c) 2003-2005, Ericsson Research Canada
 * Copyright (c) 2004-2005, Wind River Systems
 * Copyright (c) 2005-2006, Ericsson AB
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the names of the copyright holders nor the names of its 
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "core.h"
#include "user_reg.h"

/*
 * TIPC user registry keeps track of users of the tipc_port interface.
 *
 * The registry utilizes an array of "TIPC user" entries; 
 * a user's ID is the index of their associated array entry.
 * Array entry 0 is not used, so userid 0 is not valid;
 * TIPC sometimes uses this value to denote an anonymous user.
 * The list of free entries is initially chained from last entry to entry 1.
 */

/**
 * struct tipc_user - registered TIPC user info
 * @next: index of next free registry entry (or -1 for an allocated entry)
 * @callback: ptr to routine to call when TIPC mode changes (NULL if none)
 * @usr_handle: user-defined value passed to callback routine 
 * @ports: list of user ports owned by the user
 */

struct tipc_user {
	int next;
	tipc_mode_event callback;
	void *usr_handle;
	struct list_head ports;
};

#define MAX_USERID 64
#define USER_LIST_SIZE ((MAX_USERID + 1) * sizeof(struct tipc_user))

static struct tipc_user *users = 0;
static u32 next_free_user = MAX_USERID + 1;
static spinlock_t reg_lock = SPIN_LOCK_UNLOCKED;

/**
 * reg_init - create TIPC user registry (but don't activate it)
 * 
 * If registry has been pre-initialized it is left "as is".
 * NOTE: This routine may be called when TIPC is inactive.
 */

static int reg_init(void)
{
	u32 i;
	
	spin_lock_bh(&reg_lock);
	if (!users) {
		users = (struct tipc_user *)kmalloc(USER_LIST_SIZE, GFP_ATOMIC);
		if (users) {
			memset(users, 0, USER_LIST_SIZE);
			for (i = 1; i <= MAX_USERID; i++) {
				users[i].next = i - 1;
			}
			next_free_user = MAX_USERID;
		}
	}
	spin_unlock_bh(&reg_lock);
	return users ? TIPC_OK : -ENOMEM;
}

/**
 * reg_callback - inform TIPC user about current operating mode
 */

static void reg_callback(struct tipc_user *user_ptr)
{
	tipc_mode_event cb;
	void *arg;

	spin_lock_bh(&reg_lock);
	cb = user_ptr->callback;
	arg = user_ptr->usr_handle;
	spin_unlock_bh(&reg_lock);

	if (cb)
		cb(arg, tipc_mode, tipc_own_addr);
}

/**
 * reg_start - activate TIPC user registry
 */

int reg_start(void)
{
	u32 u;
	int res;

	if ((res = reg_init()))
		return res;

	for (u = 1; u <= MAX_USERID; u++) {
		if (users[u].callback)
			k_signal((Handler)reg_callback,
				 (unsigned long)&users[u]);
	}
	return TIPC_OK;
}

/**
 * reg_stop - shut down & delete TIPC user registry
 */

void reg_stop(void)
{               
	int id;

	if (!users)
		return;

	for (id = 1; id <= MAX_USERID; id++) {
		if (users[id].callback)
			reg_callback(&users[id]);
	}
	kfree(users);
	users = 0;
}

/**
 * tipc_attach - register a TIPC user
 *
 * NOTE: This routine may be called when TIPC is inactive.
 */

int tipc_attach(u32 *userid, tipc_mode_event cb, void *usr_handle)
{
	struct tipc_user *user_ptr;

	if ((tipc_mode == TIPC_NOT_RUNNING) && !cb)
		return -ENOPROTOOPT;
	if (!users)
		reg_init();

	spin_lock_bh(&reg_lock);
	if (!next_free_user) {
		spin_unlock_bh(&reg_lock);
		return -EBUSY;
	}
	user_ptr = &users[next_free_user];
	*userid = next_free_user;
	next_free_user = user_ptr->next;
	user_ptr->next = -1; 
	spin_unlock_bh(&reg_lock);

	user_ptr->callback = cb;
	user_ptr->usr_handle = usr_handle;
	INIT_LIST_HEAD(&user_ptr->ports);
	atomic_inc(&tipc_user_count);
	
	if (cb && (tipc_mode != TIPC_NOT_RUNNING))
		k_signal((Handler)reg_callback, (unsigned long)user_ptr);
	return TIPC_OK;
}

/**
 * tipc_detach - deregister a TIPC user
 */

void tipc_detach(u32 userid)
{
	struct tipc_user *user_ptr;
	struct list_head ports_temp;
	struct user_port *up_ptr, *temp_up_ptr;

	if ((userid == 0) || (userid > MAX_USERID))
		return;

	spin_lock_bh(&reg_lock);
	if ((!users) || (users[userid].next >= 0)) {
		spin_unlock_bh(&reg_lock);
		return;
	}

	user_ptr = &users[userid];
        user_ptr->callback = NULL;              
	INIT_LIST_HEAD(&ports_temp);
        list_splice(&user_ptr->ports, &ports_temp);
	user_ptr->next = next_free_user;
	next_free_user = userid;
	spin_unlock_bh(&reg_lock);

	atomic_dec(&tipc_user_count);

        list_for_each_entry_safe(up_ptr, temp_up_ptr, &ports_temp, uport_list) {
		tipc_deleteport(up_ptr->ref);
	}
}

/**
 * reg_add_port - register a user's driver port
 */

int reg_add_port(struct user_port *up_ptr)
{
	struct tipc_user *user_ptr;

	if (up_ptr->user_ref == 0)
		return TIPC_OK;
	if (up_ptr->user_ref > MAX_USERID)
		return -EINVAL;
	if ((tipc_mode == TIPC_NOT_RUNNING) || !users )
		return -ENOPROTOOPT;

	spin_lock_bh(&reg_lock);
	user_ptr = &users[up_ptr->user_ref];
	list_add(&up_ptr->uport_list, &user_ptr->ports);
	spin_unlock_bh(&reg_lock);
	return TIPC_OK;
}

/**
 * reg_remove_port - deregister a user's driver port
 */

int reg_remove_port(struct user_port *up_ptr)
{
	if (up_ptr->user_ref == 0)
		return TIPC_OK;
	if (up_ptr->user_ref > MAX_USERID)
		return -EINVAL;
	if (!users )
		return -ENOPROTOOPT;

	spin_lock_bh(&reg_lock);
	list_del_init(&up_ptr->uport_list);
	spin_unlock_bh(&reg_lock);
	return TIPC_OK;
}

