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