irias_object.c revision 0da974f4f303a6842516b764507e3c0a03f41e5a
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
850da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC);
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj == NULL) {
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s(), Unable to allocate object!\n",
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->magic = IAS_OBJECT_MAGIC;
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->name = strndup(name, IAS_MAX_CLASSNAME);
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->id = id;
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Locking notes : the attrib spinlock has lower precendence
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * than the objects spinlock. Never grap the objects spinlock
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * while holding any attrib spinlock (risk of deadlock). Jean II */
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->attribs = hashbin_new(HB_LOCK);
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj->attribs == NULL) {
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s(), Unable to allocate attribs!\n",
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(obj);
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return obj;
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_new_object);
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_attrib (attrib)
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Delete given attribute and deallocate all its memory
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __irias_delete_attrib(struct ias_attrib *attrib)
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib != NULL, return;);
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
123a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl	kfree(attrib->name);
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_delete_value(attrib->value);
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = ~IAS_ATTRIB_MAGIC;
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(attrib);
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __irias_delete_object(struct ias_object *obj)
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
136a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl	kfree(obj->name);
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->magic = ~IAS_OBJECT_MAGIC;
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(obj);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_object (obj)
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Remove object from hashbin and deallocate all attributes associated with
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    with this object and the object itself
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint irias_delete_object(struct ias_object *obj)
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_object *node;
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return -1;);
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Remove from list */
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj);
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node)
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_DEBUG( 0, "%s(), object already removed!\n",
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    __FUNCTION__);
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Destroy */
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__irias_delete_object(obj);
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_delete_object);
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_attrib (obj)
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Remove attribute from hashbin and, if it was the last attribute of
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    the object, remove the object as well.
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib,
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int cleanobject)
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *node;
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return -1;);
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib != NULL, return -1;);
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Remove attribute from object */
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	node = hashbin_remove_this(obj->attribs, (irda_queue_t *) attrib);
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node)
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0; /* Already removed or non-existent */
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Deallocate attribute */
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__irias_delete_attrib(node);
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Check if object has still some attributes, destroy it if none.
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * At first glance, this look dangerous, as the kernel reference
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * various IAS objects. However, we only use this function on
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * user attributes, not kernel attributes, so there is no risk
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * of deleting a kernel object this way. Jean II */
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	node = (struct ias_attrib *) hashbin_get_first(obj->attribs);
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cleanobject && !node)
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		irias_delete_object(obj);
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_insert_object (obj)
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Insert an object into the LM-IAS database
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_insert_object(struct ias_object *obj)
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hashbin_insert(irias_objects, (irda_queue_t *) obj, 0, obj->name);
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_insert_object);
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_find_object (name)
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Find object with given name
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_object *irias_find_object(char *name)
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return NULL;);
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Unsafe (locking), object might change */
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return hashbin_lock_find(irias_objects, 0, name);
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_find_object);
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_find_attrib (obj, name)
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Find named attribute in object
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name)
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return NULL;);
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return NULL;);
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return NULL;);
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib = hashbin_lock_find(obj->attribs, 0, name);
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL)
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Unsafe (locking), attrib might change */
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return attrib;
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_add_attribute (obj, attrib)
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add attribute to object
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void irias_add_attrib(struct ias_object *obj, struct ias_attrib *attrib,
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int owner)
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib != NULL, return;);
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Set if attrib is owned by kernel or user space */
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value->owner = owner;
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hashbin_insert(obj->attribs, (irda_queue_t *) attrib, 0, attrib->name);
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_object_change_attribute (obj_name, attrib_name, new_value)
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Change the value of an objects attribute.
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint irias_object_change_attribute(char *obj_name, char *attrib_name,
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  struct ias_value *new_value)
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_object *obj;
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Find object */
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj = hashbin_lock_find(irias_objects, 0, obj_name);
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj == NULL) {
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to find object: %s\n", __FUNCTION__,
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     obj_name);
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Slightly unsafe (obj might get removed under us) */
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave(&obj->attribs->hb_spinlock, flags);
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Find attribute */
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib = hashbin_find(obj->attribs, 0, attrib_name);
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to find attribute: %s\n",
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__, attrib_name);
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( attrib->value->type != new_value->type) {
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_DEBUG( 0, "%s(), changing value type not allowed!\n",
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    __FUNCTION__);
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Delete old value */
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_delete_value(attrib->value);
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Insert new value */
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = new_value;
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Success */
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_object_change_attribute);
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_object_add_integer_attrib (obj, name, value)
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add an integer attribute to an LM-IAS object
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      int owner)
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return;);
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3480da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to allocate attribute!\n",
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = IAS_ATTRIB_MAGIC;
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Insert value */
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = irias_new_integer_value(value);
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_add_attrib(obj, attrib, owner);
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_add_integer_attrib);
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /*
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_add_octseq_attrib (obj, name, octet_seq, len)
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add a octet sequence attribute to an LM-IAS object
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int len, int owner)
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return;);
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(octets != NULL, return;);
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3830da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to allocate attribute!\n",
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = IAS_ATTRIB_MAGIC;
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = irias_new_octseq_value( octets, len);
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_add_attrib(obj, attrib, owner);
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_add_octseq_attrib);
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_object_add_string_attrib (obj, string)
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add a string attribute to an LM-IAS object
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int owner)
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return;);
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(value != NULL, return;);
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4160da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	attrib = kzalloc(sizeof( struct ias_attrib), GFP_ATOMIC);
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to allocate attribute!\n",
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     __FUNCTION__);
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = IAS_ATTRIB_MAGIC;
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = irias_new_string_value(value);
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_add_attrib(obj, attrib, owner);
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_add_string_attrib);
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_new_integer_value (integer)
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create new IAS integer value
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_integer_value(int integer)
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4420da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_INTEGER;
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = 4;
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->t.integer = integer;
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_new_integer_value);
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_new_string_value (string)
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create new IAS string value
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Per IrLMP 1.1, 4.3.3.2, strings are up to 256 chars - Jean II
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_string_value(char *string)
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4670da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_STRING;
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->charset = CS_ASCII;
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->t.string = strndup(string, IAS_MAX_STRING);
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = strlen(value->t.string);
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_new_octseq_value (octets, len)
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create new IAS octet-sequence value
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Per IrLMP 1.1, 4.3.3.2, octet-sequence are up to 1024 bytes - Jean II
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4920da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_OCT_SEQ;
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Check length */
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(len > IAS_MAX_OCTET_STRING)
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		len = IAS_MAX_OCTET_STRING;
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = len;
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->t.oct_seq = kmalloc(len, GFP_ATOMIC);
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value->t.oct_seq == NULL){
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(value);
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memcpy(value->t.oct_seq, octseq , len);
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_missing_value(void)
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5180da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_MISSING;
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = 0;
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_value (value)
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Delete IAS value
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_delete_value(struct ias_value *value)
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(value != NULL, return;);
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (value->type) {
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_INTEGER: /* Fallthrough */
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_MISSING:
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* No need to deallocate */
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_STRING:
548a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl		/* Deallocate string */
549a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl		kfree(value->t.string);
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_OCT_SEQ:
552a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl		/* Deallocate byte stream */
553a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl		 kfree(value->t.oct_seq);
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 break;
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__);
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(value);
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_delete_value);
562