source: mainline/uspace/srv/devman/dev.c@ d1bafbf

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d1bafbf was d1bafbf, checked in by Jiri Svoboda <jiri@…>, 12 years ago

Move dev-node related devman functionality to a separate module.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (c) 2010 Lenka Trochtova
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup devman
30 * @{
31 */
32
33#include <errno.h>
34#include <fcntl.h>
35#include <sys/stat.h>
36#include <io/log.h>
37#include <ipc/driver.h>
38#include <ipc/devman.h>
39#include <loc.h>
40#include <str_error.h>
41#include <stdio.h>
42
43#include "dev.h"
44#include "devman.h"
45
46/** Create a new device node.
47 *
48 * @return A device node structure.
49 */
50dev_node_t *create_dev_node(void)
51{
52 dev_node_t *dev;
53
54 dev = calloc(1, sizeof(dev_node_t));
55 if (dev == NULL)
56 return NULL;
57
58 atomic_set(&dev->refcnt, 0);
59 list_initialize(&dev->functions);
60 link_initialize(&dev->driver_devices);
61
62 return dev;
63}
64
65/** Delete a device node.
66 *
67 * @param node The device node structure.
68 */
69void delete_dev_node(dev_node_t *dev)
70{
71 assert(list_empty(&dev->functions));
72 assert(dev->pfun == NULL);
73 assert(dev->drv == NULL);
74
75 free(dev);
76}
77
78/** Increase device node reference count.
79 *
80 * @param dev Device node
81 */
82void dev_add_ref(dev_node_t *dev)
83{
84 atomic_inc(&dev->refcnt);
85}
86
87/** Decrease device node reference count.
88 *
89 * When the count drops to zero the device node is freed.
90 *
91 * @param dev Device node
92 */
93void dev_del_ref(dev_node_t *dev)
94{
95 if (atomic_predec(&dev->refcnt) == 0)
96 delete_dev_node(dev);
97}
98
99/** Find the device node structure of the device witch has the specified handle.
100 *
101 * @param tree The device tree where we look for the device node.
102 * @param handle The handle of the device.
103 * @return The device node.
104 */
105dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, devman_handle_t handle)
106{
107 assert(fibril_rwlock_is_locked(&tree->rwlock));
108
109 ht_link_t *link = hash_table_find(&tree->devman_devices, &handle);
110 if (link == NULL)
111 return NULL;
112
113 return hash_table_get_inst(link, dev_node_t, devman_dev);
114}
115
116/** Find the device node structure of the device witch has the specified handle.
117 *
118 * @param tree The device tree where we look for the device node.
119 * @param handle The handle of the device.
120 * @return The device node.
121 */
122dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle)
123{
124 dev_node_t *dev = NULL;
125
126 fibril_rwlock_read_lock(&tree->rwlock);
127 dev = find_dev_node_no_lock(tree, handle);
128 if (dev != NULL)
129 dev_add_ref(dev);
130
131 fibril_rwlock_read_unlock(&tree->rwlock);
132
133 return dev;
134}
135
136/** Get list of device functions. */
137int dev_get_functions(dev_tree_t *tree, dev_node_t *dev,
138 devman_handle_t *hdl_buf, size_t buf_size, size_t *act_size)
139{
140 size_t act_cnt;
141 size_t buf_cnt;
142
143 assert(fibril_rwlock_is_locked(&tree->rwlock));
144
145 buf_cnt = buf_size / sizeof(devman_handle_t);
146
147 act_cnt = list_count(&dev->functions);
148 *act_size = act_cnt * sizeof(devman_handle_t);
149
150 if (buf_size % sizeof(devman_handle_t) != 0)
151 return EINVAL;
152
153 size_t pos = 0;
154 list_foreach(dev->functions, item) {
155 fun_node_t *fun =
156 list_get_instance(item, fun_node_t, dev_functions);
157
158 if (pos < buf_cnt) {
159 hdl_buf[pos] = fun->handle;
160 }
161
162 pos++;
163 }
164
165 return EOK;
166}
167
168/** @}
169 */
Note: See TracBrowser for help on using the repository browser.