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 *
1996de0e252cedffad61b3cb5e05662c591898e69aJan Engelhardt *     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
255a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/socket.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irda.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irias_object.h>
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshashbin_t *irias_objects;
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Used when a missing value needs to be returned
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value irias_missing = { IAS_MISSING, 0, 0, 0, {0}};
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function ias_new_object (name, id)
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create a new IAS object
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_object *irias_new_object( char *name, int id)
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
496819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki	struct ias_object *obj;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
510dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison	IRDA_DEBUG( 4, "%s()\n", __func__);
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
530da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC);
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj == NULL) {
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s(), Unable to allocate object!\n",
560dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__);
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->magic = IAS_OBJECT_MAGIC;
611e66df3ee301209f4a38df097d7cc5cb9b367a3fJeremy Fitzhardinge	obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC);
62bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	if (!obj->name) {
63bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		IRDA_WARNING("%s(), Unable to allocate name!\n",
640dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__);
65bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		kfree(obj);
66bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		return NULL;
67bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	}
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->id = id;
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Locking notes : the attrib spinlock has lower precendence
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * than the objects spinlock. Never grap the objects spinlock
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * while holding any attrib spinlock (risk of deadlock). Jean II */
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->attribs = hashbin_new(HB_LOCK);
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj->attribs == NULL) {
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s(), Unable to allocate attribs!\n",
770dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__);
78bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		kfree(obj->name);
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(obj);
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return obj;
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_new_object);
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_attrib (attrib)
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Delete given attribute and deallocate all its memory
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __irias_delete_attrib(struct ias_attrib *attrib)
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib != NULL, return;);
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
98a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl	kfree(attrib->name);
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_delete_value(attrib->value);
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = ~IAS_ATTRIB_MAGIC;
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(attrib);
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __irias_delete_object(struct ias_object *obj)
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl	kfree(obj->name);
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj->magic = ~IAS_OBJECT_MAGIC;
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(obj);
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_object (obj)
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Remove object from hashbin and deallocate all attributes associated with
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    with this object and the object itself
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint irias_delete_object(struct ias_object *obj)
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_object *node;
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return -1;);
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Remove from list */
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj);
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node)
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_DEBUG( 0, "%s(), object already removed!\n",
1380dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			    __func__);
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Destroy */
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__irias_delete_object(obj);
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_delete_object);
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_attrib (obj)
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Remove attribute from hashbin and, if it was the last attribute of
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    the object, remove the object as well.
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib,
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int cleanobject)
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *node;
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return -1;);
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib != NULL, return -1;);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Remove attribute from object */
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	node = hashbin_remove_this(obj->attribs, (irda_queue_t *) attrib);
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node)
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0; /* Already removed or non-existent */
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Deallocate attribute */
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__irias_delete_attrib(node);
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Check if object has still some attributes, destroy it if none.
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * At first glance, this look dangerous, as the kernel reference
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * various IAS objects. However, we only use this function on
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * user attributes, not kernel attributes, so there is no risk
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * of deleting a kernel object this way. Jean II */
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	node = (struct ias_attrib *) hashbin_get_first(obj->attribs);
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cleanobject && !node)
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		irias_delete_object(obj);
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_insert_object (obj)
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Insert an object into the LM-IAS database
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_insert_object(struct ias_object *obj)
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hashbin_insert(irias_objects, (irda_queue_t *) obj, 0, obj->name);
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_insert_object);
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_find_object (name)
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Find object with given name
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_object *irias_find_object(char *name)
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return NULL;);
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Unsafe (locking), object might change */
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return hashbin_lock_find(irias_objects, 0, name);
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_find_object);
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_find_attrib (obj, name)
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Find named attribute in object
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name)
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return NULL;);
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return NULL;);
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return NULL;);
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib = hashbin_lock_find(obj->attribs, 0, name);
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL)
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Unsafe (locking), attrib might change */
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return attrib;
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_add_attribute (obj, attrib)
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add attribute to object
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void irias_add_attrib(struct ias_object *obj, struct ias_attrib *attrib,
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int owner)
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib != NULL, return;);
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Set if attrib is owned by kernel or user space */
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value->owner = owner;
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hashbin_insert(obj->attribs, (irda_queue_t *) attrib, 0, attrib->name);
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_object_change_attribute (obj_name, attrib_name, new_value)
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Change the value of an objects attribute.
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint irias_object_change_attribute(char *obj_name, char *attrib_name,
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  struct ias_value *new_value)
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_object *obj;
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Find object */
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	obj = hashbin_lock_find(irias_objects, 0, obj_name);
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (obj == NULL) {
2720dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison		IRDA_WARNING("%s: Unable to find object: %s\n", __func__,
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     obj_name);
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Slightly unsafe (obj might get removed under us) */
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave(&obj->attribs->hb_spinlock, flags);
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Find attribute */
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib = hashbin_find(obj->attribs, 0, attrib_name);
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to find attribute: %s\n",
2840dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__, attrib_name);
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( attrib->value->type != new_value->type) {
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_DEBUG( 0, "%s(), changing value type not allowed!\n",
2910dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			    __func__);
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Delete old value */
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_delete_value(attrib->value);
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Insert new value */
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = new_value;
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Success */
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_object_change_attribute);
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_object_add_integer_attrib (obj, name, value)
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add an integer attribute to an LM-IAS object
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      int owner)
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return;);
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3230da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to allocate attribute!\n",
3260dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__);
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = IAS_ATTRIB_MAGIC;
3311e66df3ee301209f4a38df097d7cc5cb9b367a3fJeremy Fitzhardinge	attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Insert value */
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = irias_new_integer_value(value);
335bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	if (!attrib->name || !attrib->value) {
336bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		IRDA_WARNING("%s: Unable to allocate attribute!\n",
3370dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__);
338bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		if (attrib->value)
339bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita			irias_delete_value(attrib->value);
340bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		kfree(attrib->name);
341bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		kfree(attrib);
342bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		return;
343bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	}
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_add_attrib(obj, attrib, owner);
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_add_integer_attrib);
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /*
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_add_octseq_attrib (obj, name, octet_seq, len)
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add a octet sequence attribute to an LM-IAS object
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int len, int owner)
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return;);
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(octets != NULL, return;);
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3670da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to allocate attribute!\n",
3700dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__);
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = IAS_ATTRIB_MAGIC;
3751e66df3ee301209f4a38df097d7cc5cb9b367a3fJeremy Fitzhardinge	attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = irias_new_octseq_value( octets, len);
378bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	if (!attrib->name || !attrib->value) {
379bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		IRDA_WARNING("%s: Unable to allocate attribute!\n",
3800dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__);
381bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		if (attrib->value)
382bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita			irias_delete_value(attrib->value);
383bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		kfree(attrib->name);
384bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		kfree(attrib);
385bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		return;
386bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	}
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_add_attrib(obj, attrib, owner);
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_add_octseq_attrib);
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_object_add_string_attrib (obj, string)
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Add a string attribute to an LM-IAS object
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int owner)
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_attrib *attrib;
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj != NULL, return;);
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(name != NULL, return;);
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(value != NULL, return;);
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4090da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	attrib = kzalloc(sizeof( struct ias_attrib), GFP_ATOMIC);
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (attrib == NULL) {
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IRDA_WARNING("%s: Unable to allocate attribute!\n",
4120dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__);
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->magic = IAS_ATTRIB_MAGIC;
4171e66df3ee301209f4a38df097d7cc5cb9b367a3fJeremy Fitzhardinge	attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	attrib->value = irias_new_string_value(value);
420bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	if (!attrib->name || !attrib->value) {
421bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		IRDA_WARNING("%s: Unable to allocate attribute!\n",
4220dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison			     __func__);
423bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		if (attrib->value)
424bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita			irias_delete_value(attrib->value);
425bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		kfree(attrib->name);
426bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		kfree(attrib);
427bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		return;
428bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	}
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	irias_add_attrib(obj, attrib, owner);
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_add_string_attrib);
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_new_integer_value (integer)
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create new IAS integer value
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_integer_value(int integer)
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4440da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
4460dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison		IRDA_WARNING("%s: Unable to kmalloc!\n", __func__);
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_INTEGER;
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = 4;
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->t.integer = integer;
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_new_integer_value);
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_new_string_value (string)
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create new IAS string value
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Per IrLMP 1.1, 4.3.3.2, strings are up to 256 chars - Jean II
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_string_value(char *string)
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4690da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
4710dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison		IRDA_WARNING("%s: Unable to kmalloc!\n", __func__);
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_STRING;
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->charset = CS_ASCII;
4771e66df3ee301209f4a38df097d7cc5cb9b367a3fJeremy Fitzhardinge	value->t.string = kstrndup(string, IAS_MAX_STRING, GFP_ATOMIC);
478bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	if (!value->t.string) {
4790dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison		IRDA_WARNING("%s: Unable to kmalloc!\n", __func__);
480bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		kfree(value);
481bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita		return NULL;
482bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita	}
483bb5aa42734e72b3f02fc0b3cdd6105083f9880f1Akinobu Mita
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = strlen(value->t.string);
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_new_octseq_value (octets, len)
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Create new IAS octet-sequence value
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Per IrLMP 1.1, 4.3.3.2, octet-sequence are up to 1024 bytes - Jean II
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5000da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
5020dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison		IRDA_WARNING("%s: Unable to kmalloc!\n", __func__);
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_OCT_SEQ;
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Check length */
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(len > IAS_MAX_OCTET_STRING)
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		len = IAS_MAX_OCTET_STRING;
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->len = len;
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
512b3ab09f9e1681916df349d54232fbb3f8a79bfa5Arnaldo Carvalho de Melo	value->t.oct_seq = kmemdup(octseq, len, GFP_ATOMIC);
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value->t.oct_seq == NULL){
5140dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison		IRDA_WARNING("%s: Unable to kmalloc!\n", __func__);
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(value);
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ias_value *irias_new_missing_value(void)
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ias_value *value;
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5250da974f4f303a6842516b764507e3c0a03f41e5aPanagiotis Issaris	value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (value == NULL) {
5270dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison		IRDA_WARNING("%s: Unable to kmalloc!\n", __func__);
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	value->type = IAS_MISSING;
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return value;
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function irias_delete_value (value)
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Delete IAS value
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid irias_delete_value(struct ias_value *value)
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5440dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison	IRDA_DEBUG(4, "%s()\n", __func__);
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IRDA_ASSERT(value != NULL, return;);
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (value->type) {
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_INTEGER: /* Fallthrough */
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_MISSING:
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* No need to deallocate */
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_STRING:
554a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl		/* Deallocate string */
555a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl		kfree(value->t.string);
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IAS_OCT_SEQ:
558a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl		/* Deallocate byte stream */
559a51482bde22f99c63fbbb57d5d46cc666384e379Jesper Juhl		 kfree(value->t.oct_seq);
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 break;
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
5620dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison		IRDA_DEBUG(0, "%s(), Unknown value type!\n", __func__);
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(value);
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(irias_delete_value);
568