2 * Copyright (c) 2010 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Alex Hornung <ahornung@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <sys/types.h>
35 #include <sys/device.h>
37 #include <sys/socket.h>
38 #include <sys/ioctl.h>
40 #include <sys/queue.h>
43 #include <cpu/inttypes.h>
59 #include <libprop/proplib.h>
61 #define LIBDEVATTR_INTERNAL
65 struct udev *udev_ctx;
66 prop_dictionary_t dict;
72 udev_device_new_from_dictionary(struct udev *udev_ctx, prop_dictionary_t dict)
74 struct udev_device *udev_dev;
76 udev_dev = malloc(sizeof(struct udev_device));
81 udev_dev->ev_type = UDEV_EVENT_NONE;
84 prop_object_retain(dict);
86 udev_dev->dict = dict;
87 udev_dev->udev_ctx = udev_ref(udev_ctx);
93 udev_device_ref(struct udev_device *udev_device)
95 atomic_add_int(&udev_device->refs, 1);
101 udev_device_unref(struct udev_device *udev_device)
105 refcount = atomic_fetchadd_int(&udev_device->refs, -1);
108 atomic_subtract_int(&udev_device->refs, 0x400); /* in destruction */
109 if (udev_device->dict != NULL)
110 prop_object_release(udev_device->dict);
112 udev_unref(udev_device->udev_ctx);
118 udev_device_set_action(struct udev_device *udev_device, int action)
120 udev_device->ev_type = action;
124 udev_device_get_action(struct udev_device *udev_device)
128 switch (udev_device->ev_type) {
129 case UDEV_EVENT_ATTACH:
133 case UDEV_EVENT_DETACH:
146 udev_device_get_devnum(struct udev_device *udev_device)
151 if (udev_device->dict == NULL)
154 pn = prop_dictionary_get(udev_device->dict, "devnum");
158 devnum = prop_number_unsigned_integer_value(pn);
164 udev_device_get_kptr(struct udev_device *udev_device)
169 if (udev_device->dict == NULL)
172 pn = prop_dictionary_get(udev_device->dict, "kptr");
176 kptr = prop_number_unsigned_integer_value(pn);
182 udev_device_get_major(struct udev_device *udev_device)
187 if (udev_device->dict == NULL)
190 pn = prop_dictionary_get(udev_device->dict, "major");
194 major = (int32_t)prop_number_integer_value(pn);
200 udev_device_get_minor(struct udev_device *udev_device)
205 if (udev_device->dict == NULL)
208 pn = prop_dictionary_get(udev_device->dict, "minor");
212 minor = (int32_t)prop_number_integer_value(pn);
218 udev_device_get_devnode(struct udev_device *udev_device)
222 devnum = udev_device_get_devnum(udev_device);
226 return devname(devnum, S_IFCHR);
230 udev_device_get_property_value(struct udev_device *udev_device,
236 static char buf[128]; /* XXX: might cause trouble */
237 const char *str = NULL;
239 if (udev_device->dict == NULL)
242 if ((po = prop_dictionary_get(udev_device->dict, key)) == NULL)
245 if (prop_object_type(po) == PROP_TYPE_STRING) {
247 str = __DECONST(char *, prop_string_cstring_nocopy(ps));
248 } else if (prop_object_type(po) == PROP_TYPE_NUMBER) {
250 if (prop_number_unsigned(pn)) {
251 snprintf(buf, sizeof(buf), "%" PRIu64, prop_number_unsigned_integer_value(pn));
253 snprintf(buf, sizeof(buf), "%" PRIi64, prop_number_integer_value(pn));
261 udev_device_get_subsystem(struct udev_device *udev_device)
263 return udev_device_get_property_value(udev_device, "subsystem");
267 udev_device_get_driver(struct udev_device *udev_device)
269 return udev_device_get_property_value(udev_device, "driver");
273 udev_device_get_dictionary(struct udev_device *udev_device)
275 return udev_device->dict;
279 udev_device_get_udev(struct udev_device *udev_device)
281 return udev_device->udev_ctx;