irias_object.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Filename:      irias_object.c
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Version:       0.3
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description:   IAS object database and functions
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Status:        Experimental.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author:        Dag Brattli <dagb@cs.uit.no>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Created at:    Thu Oct  1 22:50:04 1998
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified at:   Wed Dec 15 11:23:16 1999
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified by:   Dag Brattli <dagb@cs.uit.no>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     This program is free software; you can redistribute it and/or
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     modify it under the terms of the GNU General Public License as
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     published by the Free Software Foundation; either version 2 of
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     the License, or (at your option) any later version.
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Neither Dag Brattli nor University of Troms� admit liability nor
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     provide warranty for any of this software. This material is
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     provided "AS-IS" and at no charge.
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ********************************************************************/
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/socket.h>
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irda.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irias_object.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshashbin_t *irias_objects;
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Used when a missing value needs to be returned
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value irias_missing = { IAS_MISSING, 0, 0, 0, {0}};
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function strndup (str, max)
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    My own kernel version of strndup!
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Faster, check boundary... Jean II
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *strndup(char *str, int max)
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *new_str;
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int len;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Check string */
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (str == NULL)
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Check length, truncate */
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	len = strlen(str);
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(len > max)
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		len = max;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Allocate new string */
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        new_str = kmalloc(len + 1, GFP_ATOMIC);
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        if (new_str == NULL) {
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Copy and truncate */
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memcpy(new_str, str, len);
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	new_str[len] = '\0';
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return new_str;
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function ias_new_object (name, id)
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create a new IAS object
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_object *irias_new_object( char *name, int id)
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        struct ias_object *obj;
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj = (struct ias_object *) kmalloc(sizeof(struct ias_object),
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    GFP_ATOMIC);
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj == NULL) {
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s(), Unable to allocate object!\n",
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(obj, 0, sizeof( struct ias_object));
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->magic = IAS_OBJECT_MAGIC;
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->name = strndup(name, IAS_MAX_CLASSNAME);
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->id = id;
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Locking notes : the attrib spinlock has lower precendence
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * than the objects spinlock. Never grap the objects spinlock
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * while holding any attrib spinlock (risk of deadlock). Jean II */
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->attribs = hashbin_new(HB_LOCK);
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj->attribs == NULL) {
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s(), Unable to allocate attribs!\n",
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(obj);
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return obj;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_new_object);
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_attrib (attrib)
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Delete given attribute and deallocate all its memory
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __irias_delete_attrib(struct ias_attrib *attrib)
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib != NULL, return;);
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib->name)
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(attrib->name);
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_delete_value(attrib->value);
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = ~IAS_ATTRIB_MAGIC;
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(attrib);
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __irias_delete_object(struct ias_object *obj)
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj->name)
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(obj->name);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->magic = ~IAS_OBJECT_MAGIC;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(obj);
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_object (obj)
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Remove object from hashbin and deallocate all attributes associated with
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    with this object and the object itself
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint irias_delete_object(struct ias_object *obj)
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_object *node;
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return -1;);
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Remove from list */
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj);
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node)
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_DEBUG( 0, "%s(), object already removed!\n",
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    __FUNCTION__);
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Destroy */
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__irias_delete_object(obj);
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_delete_object);
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_attrib (obj)
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Remove attribute from hashbin and, if it was the last attribute of
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    the object, remove the object as well.
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib,
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int cleanobject)
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *node;
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return -1;);
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib != NULL, return -1;);
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Remove attribute from object */
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	node = hashbin_remove_this(obj->attribs, (irda_queue_t *) attrib);
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node)
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0; /* Already removed or non-existent */
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Deallocate attribute */
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__irias_delete_attrib(node);
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Check if object has still some attributes, destroy it if none.
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * At first glance, this look dangerous, as the kernel reference
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * various IAS objects. However, we only use this function on
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * user attributes, not kernel attributes, so there is no risk
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * of deleting a kernel object this way. Jean II */
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	node = (struct ias_attrib *) hashbin_get_first(obj->attribs);
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cleanobject && !node)
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		irias_delete_object(obj);
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_insert_object (obj)
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Insert an object into the LM-IAS database
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_insert_object(struct ias_object *obj)
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hashbin_insert(irias_objects, (irda_queue_t *) obj, 0, obj->name);
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_insert_object);
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_find_object (name)
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Find object with given name
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_object *irias_find_object(char *name)
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return NULL;);
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Unsafe (locking), object might change */
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return hashbin_lock_find(irias_objects, 0, name);
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_find_object);
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_find_attrib (obj, name)
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Find named attribute in object
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name)
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return NULL;);
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return NULL;);
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return NULL;);
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib = hashbin_lock_find(obj->attribs, 0, name);
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL)
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Unsafe (locking), attrib might change */
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return attrib;
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_find_attrib);
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_add_attribute (obj, attrib)
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add attribute to object
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void irias_add_attrib(struct ias_object *obj, struct ias_attrib *attrib,
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int owner)
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib != NULL, return;);
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Set if attrib is owned by kernel or user space */
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value->owner = owner;
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hashbin_insert(obj->attribs, (irda_queue_t *) attrib, 0, attrib->name);
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_object_change_attribute (obj_name, attrib_name, new_value)
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Change the value of an objects attribute.
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint irias_object_change_attribute(char *obj_name, char *attrib_name,
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  struct ias_value *new_value)
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_object *obj;
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Find object */
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj = hashbin_lock_find(irias_objects, 0, obj_name);
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj == NULL) {
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to find object: %s\n", __FUNCTION__,
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     obj_name);
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Slightly unsafe (obj might get removed under us) */
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave(&obj->attribs->hb_spinlock, flags);
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Find attribute */
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib = hashbin_find(obj->attribs, 0, attrib_name);
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to find attribute: %s\n",
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__, attrib_name);
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( attrib->value->type != new_value->type) {
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_DEBUG( 0, "%s(), changing value type not allowed!\n",
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    __FUNCTION__);
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Delete old value */
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_delete_value(attrib->value);
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Insert new value */
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = new_value;
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Success */
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_object_change_attribute);
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_object_add_integer_attrib (obj, name, value)
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add an integer attribute to an LM-IAS object
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      int owner)
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return;);
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib),
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					       GFP_ATOMIC);
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to allocate attribute!\n",
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(attrib, 0, sizeof( struct ias_attrib));
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = IAS_ATTRIB_MAGIC;
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Insert value */
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = irias_new_integer_value(value);
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_add_attrib(obj, attrib, owner);
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_add_integer_attrib);
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /*
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_add_octseq_attrib (obj, name, octet_seq, len)
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add a octet sequence attribute to an LM-IAS object
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int len, int owner)
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return;);
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(octets != NULL, return;);
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib),
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					       GFP_ATOMIC);
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to allocate attribute!\n",
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(attrib, 0, sizeof( struct ias_attrib));
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = IAS_ATTRIB_MAGIC;
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = irias_new_octseq_value( octets, len);
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_add_attrib(obj, attrib, owner);
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_add_octseq_attrib);
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_object_add_string_attrib (obj, string)
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add a string attribute to an LM-IAS object
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int owner)
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return;);
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(value != NULL, return;);
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib = (struct ias_attrib *) kmalloc(sizeof( struct ias_attrib),
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					       GFP_ATOMIC);
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to allocate attribute!\n",
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(attrib, 0, sizeof( struct ias_attrib));
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = IAS_ATTRIB_MAGIC;
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = irias_new_string_value(value);
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_add_attrib(obj, attrib, owner);
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_add_string_attrib);
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_new_integer_value (integer)
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create new IAS integer value
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_integer_value(int integer)
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(value, 0, sizeof(struct ias_value));
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_INTEGER;
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = 4;
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->t.integer = integer;
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_new_integer_value);
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_new_string_value (string)
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create new IAS string value
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Per IrLMP 1.1, 4.3.3.2, strings are up to 256 chars - Jean II
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_string_value(char *string)
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset( value, 0, sizeof( struct ias_value));
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_STRING;
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->charset = CS_ASCII;
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->t.string = strndup(string, IAS_MAX_STRING);
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = strlen(value->t.string);
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_new_string_value);
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_new_octseq_value (octets, len)
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create new IAS octet-sequence value
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Per IrLMP 1.1, 4.3.3.2, octet-sequence are up to 1024 bytes - Jean II
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(value, 0, sizeof(struct ias_value));
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_OCT_SEQ;
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Check length */
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(len > IAS_MAX_OCTET_STRING)
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		len = IAS_MAX_OCTET_STRING;
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = len;
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->t.oct_seq = kmalloc(len, GFP_ATOMIC);
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value->t.oct_seq == NULL){
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(value);
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memcpy(value->t.oct_seq, octseq , len);
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_new_octseq_value);
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_missing_value(void)
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(value, 0, sizeof(struct ias_value));
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_MISSING;
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = 0;
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_value (value)
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Delete IAS value
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_delete_value(struct ias_value *value)
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(value != NULL, return;);
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (value->type) {
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_INTEGER: /* Fallthrough */
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_MISSING:
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* No need to deallocate */
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_STRING:
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* If string, deallocate string */
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (value->t.string != NULL)
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			kfree(value->t.string);
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_OCT_SEQ:
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* If byte stream, deallocate byte stream */
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 if (value->t.oct_seq != NULL)
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 kfree(value->t.oct_seq);
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 break;
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__);
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(value);
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_delete_value);
581