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
,
252 prop_number_unsigned_integer_value(pn
));
254 snprintf(buf
, sizeof(buf
), "%" PRIi64
,
255 prop_number_integer_value(pn
));
263 udev_device_get_subsystem(struct udev_device
*udev_device
)
265 return udev_device_get_property_value(udev_device
, "subsystem");
269 udev_device_get_driver(struct udev_device
*udev_device
)
271 return udev_device_get_property_value(udev_device
, "driver");
275 udev_device_get_dictionary(struct udev_device
*udev_device
)
277 return udev_device
->dict
;
281 udev_device_get_udev(struct udev_device
*udev_device
)
283 return udev_device
->udev_ctx
;