Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / net / irda / irias_object.c
1 /*********************************************************************
2  *
3  * Filename:      irias_object.c
4  * Version:       0.3
5  * Description:   IAS object database and functions
6  * Status:        Experimental.
7  * Author:        Dag Brattli <dagb@cs.uit.no>
8  * Created at:    Thu Oct  1 22:50:04 1998
9  * Modified at:   Wed Dec 15 11:23:16 1999
10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
11  *
12  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
13  *
14  *     This program is free software; you can redistribute it and/or
15  *     modify it under the terms of the GNU General Public License as
16  *     published by the Free Software Foundation; either version 2 of
17  *     the License, or (at your option) any later version.
18  *
19  *     Neither Dag Brattli nor University of Tromsø admit liability nor
20  *     provide warranty for any of this software. This material is
21  *     provided "AS-IS" and at no charge.
22  *
23  ********************************************************************/
24
25 #include <linux/slab.h>
26 #include <linux/string.h>
27 #include <linux/socket.h>
28 #include <linux/module.h>
29
30 #include <net/irda/irda.h>
31 #include <net/irda/irias_object.h>
32
33 hashbin_t *irias_objects;
34
35 /*
36  *  Used when a missing value needs to be returned
37  */
38 struct ias_value irias_missing = { IAS_MISSING, 0, 0, 0, {0}};
39
40
41 /*
42  * Function ias_new_object (name, id)
43  *
44  *    Create a new IAS object
45  *
46  */
47 struct ias_object *irias_new_object( char *name, int id)
48 {
49         struct ias_object *obj;
50
51         obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC);
52         if (obj == NULL) {
53                 net_warn_ratelimited("%s(), Unable to allocate object!\n",
54                                      __func__);
55                 return NULL;
56         }
57
58         obj->magic = IAS_OBJECT_MAGIC;
59         obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC);
60         if (!obj->name) {
61                 net_warn_ratelimited("%s(), Unable to allocate name!\n",
62                                      __func__);
63                 kfree(obj);
64                 return NULL;
65         }
66         obj->id = id;
67
68         /* Locking notes : the attrib spinlock has lower precendence
69          * than the objects spinlock. Never grap the objects spinlock
70          * while holding any attrib spinlock (risk of deadlock). Jean II */
71         obj->attribs = hashbin_new(HB_LOCK);
72
73         if (obj->attribs == NULL) {
74                 net_warn_ratelimited("%s(), Unable to allocate attribs!\n",
75                                      __func__);
76                 kfree(obj->name);
77                 kfree(obj);
78                 return NULL;
79         }
80
81         return obj;
82 }
83 EXPORT_SYMBOL(irias_new_object);
84
85 /*
86  * Function irias_delete_attrib (attrib)
87  *
88  *    Delete given attribute and deallocate all its memory
89  *
90  */
91 static void __irias_delete_attrib(struct ias_attrib *attrib)
92 {
93         IRDA_ASSERT(attrib != NULL, return;);
94         IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
95
96         kfree(attrib->name);
97
98         irias_delete_value(attrib->value);
99         attrib->magic = ~IAS_ATTRIB_MAGIC;
100
101         kfree(attrib);
102 }
103
104 void __irias_delete_object(struct ias_object *obj)
105 {
106         IRDA_ASSERT(obj != NULL, return;);
107         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
108
109         kfree(obj->name);
110
111         hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
112
113         obj->magic = ~IAS_OBJECT_MAGIC;
114
115         kfree(obj);
116 }
117
118 /*
119  * Function irias_delete_object (obj)
120  *
121  *    Remove object from hashbin and deallocate all attributes associated with
122  *    with this object and the object itself
123  *
124  */
125 int irias_delete_object(struct ias_object *obj)
126 {
127         struct ias_object *node;
128
129         IRDA_ASSERT(obj != NULL, return -1;);
130         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
131
132         /* Remove from list */
133         node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj);
134         if (!node)
135                 pr_debug("%s(), object already removed!\n",
136                          __func__);
137
138         /* Destroy */
139         __irias_delete_object(obj);
140
141         return 0;
142 }
143 EXPORT_SYMBOL(irias_delete_object);
144
145 /*
146  * Function irias_delete_attrib (obj)
147  *
148  *    Remove attribute from hashbin and, if it was the last attribute of
149  *    the object, remove the object as well.
150  *
151  */
152 int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib,
153                         int cleanobject)
154 {
155         struct ias_attrib *node;
156
157         IRDA_ASSERT(obj != NULL, return -1;);
158         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
159         IRDA_ASSERT(attrib != NULL, return -1;);
160
161         /* Remove attribute from object */
162         node = hashbin_remove_this(obj->attribs, (irda_queue_t *) attrib);
163         if (!node)
164                 return 0; /* Already removed or non-existent */
165
166         /* Deallocate attribute */
167         __irias_delete_attrib(node);
168
169         /* Check if object has still some attributes, destroy it if none.
170          * At first glance, this look dangerous, as the kernel reference
171          * various IAS objects. However, we only use this function on
172          * user attributes, not kernel attributes, so there is no risk
173          * of deleting a kernel object this way. Jean II */
174         node = (struct ias_attrib *) hashbin_get_first(obj->attribs);
175         if (cleanobject && !node)
176                 irias_delete_object(obj);
177
178         return 0;
179 }
180
181 /*
182  * Function irias_insert_object (obj)
183  *
184  *    Insert an object into the LM-IAS database
185  *
186  */
187 void irias_insert_object(struct ias_object *obj)
188 {
189         IRDA_ASSERT(obj != NULL, return;);
190         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
191
192         hashbin_insert(irias_objects, (irda_queue_t *) obj, 0, obj->name);
193 }
194 EXPORT_SYMBOL(irias_insert_object);
195
196 /*
197  * Function irias_find_object (name)
198  *
199  *    Find object with given name
200  *
201  */
202 struct ias_object *irias_find_object(char *name)
203 {
204         IRDA_ASSERT(name != NULL, return NULL;);
205
206         /* Unsafe (locking), object might change */
207         return hashbin_lock_find(irias_objects, 0, name);
208 }
209 EXPORT_SYMBOL(irias_find_object);
210
211 /*
212  * Function irias_find_attrib (obj, name)
213  *
214  *    Find named attribute in object
215  *
216  */
217 struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name)
218 {
219         struct ias_attrib *attrib;
220
221         IRDA_ASSERT(obj != NULL, return NULL;);
222         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return NULL;);
223         IRDA_ASSERT(name != NULL, return NULL;);
224
225         attrib = hashbin_lock_find(obj->attribs, 0, name);
226         if (attrib == NULL)
227                 return NULL;
228
229         /* Unsafe (locking), attrib might change */
230         return attrib;
231 }
232
233 /*
234  * Function irias_add_attribute (obj, attrib)
235  *
236  *    Add attribute to object
237  *
238  */
239 static void irias_add_attrib(struct ias_object *obj, struct ias_attrib *attrib,
240                              int owner)
241 {
242         IRDA_ASSERT(obj != NULL, return;);
243         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
244
245         IRDA_ASSERT(attrib != NULL, return;);
246         IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
247
248         /* Set if attrib is owned by kernel or user space */
249         attrib->value->owner = owner;
250
251         hashbin_insert(obj->attribs, (irda_queue_t *) attrib, 0, attrib->name);
252 }
253
254 /*
255  * Function irias_object_change_attribute (obj_name, attrib_name, new_value)
256  *
257  *    Change the value of an objects attribute.
258  *
259  */
260 int irias_object_change_attribute(char *obj_name, char *attrib_name,
261                                   struct ias_value *new_value)
262 {
263         struct ias_object *obj;
264         struct ias_attrib *attrib;
265         unsigned long flags;
266
267         /* Find object */
268         obj = hashbin_lock_find(irias_objects, 0, obj_name);
269         if (obj == NULL) {
270                 net_warn_ratelimited("%s: Unable to find object: %s\n",
271                                      __func__, obj_name);
272                 return -1;
273         }
274
275         /* Slightly unsafe (obj might get removed under us) */
276         spin_lock_irqsave(&obj->attribs->hb_spinlock, flags);
277
278         /* Find attribute */
279         attrib = hashbin_find(obj->attribs, 0, attrib_name);
280         if (attrib == NULL) {
281                 net_warn_ratelimited("%s: Unable to find attribute: %s\n",
282                                      __func__, attrib_name);
283                 spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
284                 return -1;
285         }
286
287         if ( attrib->value->type != new_value->type) {
288                 pr_debug("%s(), changing value type not allowed!\n",
289                          __func__);
290                 spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
291                 return -1;
292         }
293
294         /* Delete old value */
295         irias_delete_value(attrib->value);
296
297         /* Insert new value */
298         attrib->value = new_value;
299
300         /* Success */
301         spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
302         return 0;
303 }
304 EXPORT_SYMBOL(irias_object_change_attribute);
305
306 /*
307  * Function irias_object_add_integer_attrib (obj, name, value)
308  *
309  *    Add an integer attribute to an LM-IAS object
310  *
311  */
312 void irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
313                               int owner)
314 {
315         struct ias_attrib *attrib;
316
317         IRDA_ASSERT(obj != NULL, return;);
318         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
319         IRDA_ASSERT(name != NULL, return;);
320
321         attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
322         if (attrib == NULL) {
323                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
324                                      __func__);
325                 return;
326         }
327
328         attrib->magic = IAS_ATTRIB_MAGIC;
329         attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
330
331         /* Insert value */
332         attrib->value = irias_new_integer_value(value);
333         if (!attrib->name || !attrib->value) {
334                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
335                                      __func__);
336                 if (attrib->value)
337                         irias_delete_value(attrib->value);
338                 kfree(attrib->name);
339                 kfree(attrib);
340                 return;
341         }
342
343         irias_add_attrib(obj, attrib, owner);
344 }
345 EXPORT_SYMBOL(irias_add_integer_attrib);
346
347  /*
348  * Function irias_add_octseq_attrib (obj, name, octet_seq, len)
349  *
350  *    Add a octet sequence attribute to an LM-IAS object
351  *
352  */
353
354 void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
355                              int len, int owner)
356 {
357         struct ias_attrib *attrib;
358
359         IRDA_ASSERT(obj != NULL, return;);
360         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
361
362         IRDA_ASSERT(name != NULL, return;);
363         IRDA_ASSERT(octets != NULL, return;);
364
365         attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
366         if (attrib == NULL) {
367                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
368                                      __func__);
369                 return;
370         }
371
372         attrib->magic = IAS_ATTRIB_MAGIC;
373         attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
374
375         attrib->value = irias_new_octseq_value( octets, len);
376         if (!attrib->name || !attrib->value) {
377                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
378                                      __func__);
379                 if (attrib->value)
380                         irias_delete_value(attrib->value);
381                 kfree(attrib->name);
382                 kfree(attrib);
383                 return;
384         }
385
386         irias_add_attrib(obj, attrib, owner);
387 }
388 EXPORT_SYMBOL(irias_add_octseq_attrib);
389
390 /*
391  * Function irias_object_add_string_attrib (obj, string)
392  *
393  *    Add a string attribute to an LM-IAS object
394  *
395  */
396 void irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
397                              int owner)
398 {
399         struct ias_attrib *attrib;
400
401         IRDA_ASSERT(obj != NULL, return;);
402         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
403
404         IRDA_ASSERT(name != NULL, return;);
405         IRDA_ASSERT(value != NULL, return;);
406
407         attrib = kzalloc(sizeof( struct ias_attrib), GFP_ATOMIC);
408         if (attrib == NULL) {
409                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
410                                      __func__);
411                 return;
412         }
413
414         attrib->magic = IAS_ATTRIB_MAGIC;
415         attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
416
417         attrib->value = irias_new_string_value(value);
418         if (!attrib->name || !attrib->value) {
419                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
420                                      __func__);
421                 if (attrib->value)
422                         irias_delete_value(attrib->value);
423                 kfree(attrib->name);
424                 kfree(attrib);
425                 return;
426         }
427
428         irias_add_attrib(obj, attrib, owner);
429 }
430 EXPORT_SYMBOL(irias_add_string_attrib);
431
432 /*
433  * Function irias_new_integer_value (integer)
434  *
435  *    Create new IAS integer value
436  *
437  */
438 struct ias_value *irias_new_integer_value(int integer)
439 {
440         struct ias_value *value;
441
442         value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
443         if (value == NULL)
444                 return NULL;
445
446         value->type = IAS_INTEGER;
447         value->len = 4;
448         value->t.integer = integer;
449
450         return value;
451 }
452 EXPORT_SYMBOL(irias_new_integer_value);
453
454 /*
455  * Function irias_new_string_value (string)
456  *
457  *    Create new IAS string value
458  *
459  * Per IrLMP 1.1, 4.3.3.2, strings are up to 256 chars - Jean II
460  */
461 struct ias_value *irias_new_string_value(char *string)
462 {
463         struct ias_value *value;
464
465         value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
466         if (value == NULL)
467                 return NULL;
468
469         value->type = IAS_STRING;
470         value->charset = CS_ASCII;
471         value->t.string = kstrndup(string, IAS_MAX_STRING, GFP_ATOMIC);
472         if (!value->t.string) {
473                 net_warn_ratelimited("%s: Unable to kmalloc!\n", __func__);
474                 kfree(value);
475                 return NULL;
476         }
477
478         value->len = strlen(value->t.string);
479
480         return value;
481 }
482
483 /*
484  * Function irias_new_octseq_value (octets, len)
485  *
486  *    Create new IAS octet-sequence value
487  *
488  * Per IrLMP 1.1, 4.3.3.2, octet-sequence are up to 1024 bytes - Jean II
489  */
490 struct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
491 {
492         struct ias_value *value;
493
494         value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
495         if (value == NULL)
496                 return NULL;
497
498         value->type = IAS_OCT_SEQ;
499         /* Check length */
500         if(len > IAS_MAX_OCTET_STRING)
501                 len = IAS_MAX_OCTET_STRING;
502         value->len = len;
503
504         value->t.oct_seq = kmemdup(octseq, len, GFP_ATOMIC);
505         if (value->t.oct_seq == NULL){
506                 net_warn_ratelimited("%s: Unable to kmalloc!\n", __func__);
507                 kfree(value);
508                 return NULL;
509         }
510         return value;
511 }
512
513 struct ias_value *irias_new_missing_value(void)
514 {
515         struct ias_value *value;
516
517         value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
518         if (value == NULL)
519                 return NULL;
520
521         value->type = IAS_MISSING;
522
523         return value;
524 }
525
526 /*
527  * Function irias_delete_value (value)
528  *
529  *    Delete IAS value
530  *
531  */
532 void irias_delete_value(struct ias_value *value)
533 {
534         IRDA_ASSERT(value != NULL, return;);
535
536         switch (value->type) {
537         case IAS_INTEGER: /* Fallthrough */
538         case IAS_MISSING:
539                 /* No need to deallocate */
540                 break;
541         case IAS_STRING:
542                 /* Deallocate string */
543                 kfree(value->t.string);
544                 break;
545         case IAS_OCT_SEQ:
546                 /* Deallocate byte stream */
547                  kfree(value->t.oct_seq);
548                  break;
549         default:
550                 pr_debug("%s(), Unknown value type!\n", __func__);
551                 break;
552         }
553         kfree(value);
554 }
555 EXPORT_SYMBOL(irias_delete_value);