source: mainline/uspace/srv/devman/devman.c@ e85920d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e85920d was e85920d, checked in by Lenka Trochtova <trochtova.lenka@…>, 15 years ago

parts of device manager

  • Property mode set to 100644
File size: 8.1 KB
RevLine 
[0358da0]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
[e2b9a993]29/** @addtogroup devman
[0358da0]30 * @{
31 */
32
33#include <errno.h>
[e4c4247]34#include <fcntl.h>
[85e48a9]35#include <sys/stat.h>
[0358da0]36
[e2b9a993]37#include "devman.h"
38#include "util.h"
[0358da0]39
40
[e2b9a993]41driver_t * create_driver()
[e4c4247]42{
[08d9c4e6]43 printf(NAME ": create_driver\n");
44
[e4c4247]45 driver_t *res = malloc(sizeof(driver_t));
46 if(res != NULL) {
[08d9c4e6]47 init_driver(res);
[e4c4247]48 }
49 return res;
50}
51
[e2b9a993]52char * read_id(const char **buf)
[e4c4247]53{
54 char *res = NULL;
[e2b9a993]55 size_t len = get_nonspace_len(*buf);
[e4c4247]56 if (len > 0) {
57 res = malloc(len + 1);
58 if (res != NULL) {
59 str_ncpy(res, len + 1, *buf, len);
60 *buf += len;
61 }
62 }
63 return res;
64}
65
[e2b9a993]66bool parse_match_ids(const char *buf, match_id_list_t *ids)
[e4c4247]67{
68 int score = 0;
69 char *id = NULL;
70 int ids_read = 0;
71
72 while (true) {
73 // skip spaces
74 if (!skip_spaces(&buf)) {
75 break;
76 }
77 // read score
78 score = strtoul(buf, &buf, 10);
79
80 // skip spaces
81 if (!skip_spaces(&buf)) {
82 break;
83 }
84
85 // read id
86 if (NULL == (id = read_id(&buf))) {
87 break;
88 }
89
90 // create new match_id structure
91 match_id_t *mid = create_match_id();
92 mid->id = id;
93 mid->score = score;
94
95 /// add it to the list
96 add_match_id(ids, mid);
97
98 ids_read++;
99 }
100
101 return ids_read > 0;
102}
103
[e2b9a993]104bool read_match_ids(const char *conf_path, match_id_list_t *ids)
[e4c4247]105{
[08d9c4e6]106 printf(NAME ": read_match_ids conf_path = %s.\n", conf_path);
107
[e4c4247]108 bool suc = false;
109 char *buf = NULL;
110 bool opened = false;
111 int fd;
112 off_t len = 0;
113
114 fd = open(conf_path, O_RDONLY);
115 if (fd < 0) {
116 printf(NAME ": unable to open %s\n", conf_path);
117 goto cleanup;
118 }
119 opened = true;
120
121 len = lseek(fd, 0, SEEK_END);
122 lseek(fd, 0, SEEK_SET);
123 if (len == 0) {
124 printf(NAME ": configuration file '%s' is empty.\n", conf_path);
125 goto cleanup;
126 }
127
128 buf = malloc(len + 1);
129 if (buf == NULL) {
130 printf(NAME ": memory allocation failed when parsing file '%s'.\n", conf_path);
131 goto cleanup;
132 }
133
134 if (0 >= read(fd, buf, len)) {
135 printf(NAME ": unable to read file '%s'.\n", conf_path);
136 goto cleanup;
137 }
138 buf[len] = 0;
139
140 suc = parse_match_ids(buf, ids);
141
142cleanup:
143
144 free(buf);
145
146 if(opened) {
147 close(fd);
148 }
149
150 return suc;
151}
152
153
[e2b9a993]154bool get_driver_info(const char *base_path, const char *name, driver_t *drv)
[e4c4247]155{
[08d9c4e6]156 printf(NAME ": get_driver_info base_path = %s, name = %s.\n", base_path, name);
157
[e4c4247]158 assert(base_path != NULL && name != NULL && drv != NULL);
159
160 bool suc = false;
161 char *match_path = NULL;
162 size_t name_size = 0;
163
164 // read the list of match ids from the driver's configuration file
165 if (NULL == (match_path = get_abs_path(base_path, name, MATCH_EXT))) {
166 goto cleanup;
167 }
168
[08d9c4e6]169 printf(NAME ": get_driver_info - path to match id list = %s.\n", match_path);
170
[e4c4247]171 if (!read_match_ids(match_path, &drv->match_ids)) {
172 goto cleanup;
173 }
174
175 // allocate and fill driver's name
176 name_size = str_size(name)+1;
177 drv->name = malloc(name_size);
178 if (!drv->name) {
179 goto cleanup;
180 }
181 str_cpy(drv->name, name_size, name);
182
[85e48a9]183 // initialize path with driver's binary
184 if (NULL == (drv->binary_path = get_abs_path(base_path, name, ""))) {
185 goto cleanup;
186 }
187
188 // check whether the driver's binary exists
189 struct stat s;
190 if (stat(drv->binary_path, &s) == ENOENT) {
191 printf(NAME ": driver not found at path %s.", drv->binary_path);
192 goto cleanup;
193 }
194
[e4c4247]195 suc = true;
196
197cleanup:
198
199 if (!suc) {
200 free(drv->binary_path);
201 free(drv->name);
202 // set the driver structure to the default state
203 init_driver(drv);
204 }
205
206 free(match_path);
207
208 return suc;
209}
210
211/** Lookup drivers in the directory.
212 *
[e2b9a993]213 * @param drivers_list the list of available drivers.
214 * @param dir_path the path to the directory where we search for drivers.
[e4c4247]215 */
[e2b9a993]216int lookup_available_drivers(link_t *drivers_list, const char *dir_path)
[e4c4247]217{
[08d9c4e6]218 printf(NAME ": lookup_available_drivers \n");
219
[e4c4247]220 int drv_cnt = 0;
221 DIR *dir = NULL;
222 struct dirent *diren;
223
224 dir = opendir(dir_path);
[08d9c4e6]225 printf(NAME ": lookup_available_drivers has opened directory %s for driver search.\n", dir_path);
226
[e4c4247]227 if (dir != NULL) {
228 driver_t *drv = create_driver();
[08d9c4e6]229 printf(NAME ": lookup_available_drivers has created driver structure.\n");
[e4c4247]230 while ((diren = readdir(dir))) {
231 if (get_driver_info(dir_path, diren->d_name, drv)) {
[e2b9a993]232 add_driver(drivers_list, drv);
[08d9c4e6]233 drv_cnt++;
[e4c4247]234 drv = create_driver();
235 }
236 }
237 delete_driver(drv);
238 closedir(dir);
239 }
240
241 return drv_cnt;
242}
243
[e2b9a993]244node_t * create_root_node()
[e4c4247]245{
[e85920d]246 printf(NAME ": create_root_node\n");
[e4c4247]247 node_t *node = create_dev_node();
[85e48a9]248 if (node) {
249 init_dev_node(node, NULL);
250 match_id_t *id = create_match_id();
251 id->id = "root";
252 id->score = 100;
253 add_match_id(&node->match_ids, id);
254 }
255 return node;
256}
257
[e2b9a993]258driver_t * find_best_match_driver(link_t *drivers_list, node_t *node)
[e4c4247]259{
[e85920d]260 printf(NAME ": find_best_match_driver\n");
[85e48a9]261 driver_t *best_drv = NULL, *drv = NULL;
262 int best_score = 0, score = 0;
[e2b9a993]263 link_t *link = drivers_list->next;
[85e48a9]264
[e2b9a993]265 while (link != drivers_list) {
[85e48a9]266 drv = list_get_instance(link, driver_t, drivers);
267 score = get_match_score(drv, node);
268 if (score > best_score) {
269 best_score = score;
270 best_drv = drv;
[e85920d]271 }
272 link = link->next;
[85e48a9]273 }
[e4c4247]274
[85e48a9]275 return best_drv;
276}
277
[e2b9a993]278void attach_driver(node_t *node, driver_t *drv)
[85e48a9]279{
280 node->drv = drv;
281 list_append(&node->driver_devices, &drv->devices);
282}
283
[e2b9a993]284bool start_driver(driver_t *drv)
[85e48a9]285{
[e85920d]286 printf(NAME ": start_driver\n");
287
[85e48a9]288 char *argv[2];
289
290 printf(NAME ": spawning driver %s\n", drv->name);
291
292 argv[0] = drv->name;
293 argv[1] = NULL;
294
295 if (!task_spawn(drv->binary_path, argv)) {
296 printf(NAME ": error spawning %s\n", drv->name);
297 return false;
298 }
299
[e85920d]300 drv->state = DRIVER_STARTING;
[85e48a9]301 return true;
302}
303
[e2b9a993]304bool add_device(driver_t *drv, node_t *node)
[85e48a9]305{
[e85920d]306 printf(NAME ": add_device\n");
307
[85e48a9]308 // TODO
309
310 // pass a new device to the running driver, which was previously assigned to it
311 // send the phone of the parent's driver and device's handle within the parent's driver to the driver
312 // let the driver to probe the device and specify whether the device is actually present
313 // if the device is present, remember its handle within the driver
314
315 return true;
316}
317
[e2b9a993]318bool assign_driver(node_t *node, link_t *drivers_list)
[85e48a9]319{
[e85920d]320 printf(NAME ": assign_driver\n");
321
[85e48a9]322 // find the driver which is the most suitable for handling this device
[e2b9a993]323 driver_t *drv = find_best_match_driver(drivers_list, node);
[85e48a9]324 if (NULL == drv) {
[e85920d]325 printf(NAME ": no driver found for device.\n");
[85e48a9]326 return false;
327 }
328
329 // attach the driver to the device
330 attach_driver(node, drv);
331
[e85920d]332 if (DRIVER_NOT_STARTED == drv->state) {
[85e48a9]333 // start driver
334 start_driver(drv);
[e85920d]335 }
336
337 if (DRIVER_RUNNING == drv->state) {
[85e48a9]338 // notify driver about new device
339 add_device(drv, node);
340 }
341
342 return true;
343}
344
[e2b9a993]345bool init_device_tree(dev_tree_t *tree, link_t *drivers_list)
[85e48a9]346{
[e85920d]347 printf(NAME ": init_device_tree.\n");
[85e48a9]348 // create root node and add it to the device tree
349 if (NULL == (tree->root_node = create_root_node())) {
350 return false;
351 }
[e4c4247]352
353 // find suitable driver and start it
[e2b9a993]354 return assign_driver(tree->root_node, drivers_list);
[e4c4247]355}
356
Note: See TracBrowser for help on using the repository browser.