Changeset e4c4247 in mainline
- Timestamp:
- 2010-02-10T21:05:49Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 85e48a9
- Parents:
- 0358da0
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/Makefile
r0358da0 re4c4247 48 48 srv/clip \ 49 49 srv/devmap \ 50 srv/devman \ 50 51 srv/loader \ 51 52 srv/ns \ -
uspace/srv/devman/devman.c
r0358da0 re4c4247 35 35 /** @file 36 36 */ 37 37 38 #include <assert.h> 38 39 #include <ipc/services.h> 39 40 #include <ipc/ns.h> … … 45 46 #include <stdlib.h> 46 47 #include <string.h> 48 #include <dirent.h> 49 #include <fcntl.h> 50 #include <ctype.h> 47 51 //#include <ipc/devman.h> 48 52 49 53 #define NAME "devman" 54 55 #define DRIVER_DEFAULT_STORE "/srv/drivers" 56 #define MATCH_EXT ".ma" 50 57 51 58 #define MAX_ID_LEN 256 … … 66 73 67 74 75 static driver_t * create_driver(); 76 static inline void init_driver(driver_t *drv); 77 static inline void clean_driver(driver_t *drv); 78 static inline void delete_driver(driver_t *drv); 79 static inline void add_driver(driver_t *drv); 80 static char * get_abs_path(const char *base_path, const char *name, const char *ext); 81 static bool parse_match_ids(const char *buf, match_id_list_t *ids); 82 static bool read_match_ids(const char *conf_path, match_id_list_t *ids); 83 static void clean_match_ids(match_id_list_t *ids); 84 static inline match_id_t * create_match_id(); 85 static inline void delete_match_id(match_id_t *id); 86 static void add_match_id(match_id_list_t *ids, match_id_t *id); 87 static bool get_driver_info(const char *base_path, const char *name, driver_t *drv); 88 static int lookup_available_drivers(const char *dir_path); 89 static inline node_t * create_dev_node(); 90 static node_t * create_root_node(); 91 static void init_device_tree(dev_tree_t *tree); 92 static bool devman_init(); 93 94 68 95 69 96 LIST_INITIALIZE(drivers_list); 97 98 70 99 71 100 /** Represents device tree. … … 73 102 struct dev_tree { 74 103 node_t *root_node; 75 } 76 77 104 }; 105 106 static dev_tree_t device_tree; 78 107 79 108 /** Ids of device models used for device-to-driver matching. … … 82 111 /** Pointers to next and previous ids. 83 112 */ 84 link_t ids;113 link_t link; 85 114 /** Id of device model. 86 115 */ 87 c har id[MAX_ID_LEN];88 /** Relevancy of device-to-driver match. 89 * The higher is the product of scores specified for the device by the bus driver and by the leaf driver, 90 * the more suitable is the leaf driver for handling the device. 116 const char *id; 117 /** Relevancy of device-to-driver match. 118 * The higher is the product of scores specified for the device by the bus driver and by the leaf driver, 119 * the more suitable is the leaf driver for handling the device. 91 120 */ 92 121 unsigned int score; 93 122 }; 94 123 95 /** List of ids for matching devices to drivers sorted 124 /** List of ids for matching devices to drivers sorted 96 125 * according to match scores in descending order. 97 126 */ … … 102 131 /** Representation of device driver. 103 132 */ 104 struct driver { 133 struct driver { 105 134 /** Pointers to previous and next drivers in a linked list */ 106 135 link_t drivers; … … 111 140 /** Name of the device driver */ 112 141 char *name; 113 /** Path to the driver's binary */ 114 const char *path; 115 /** Fibril mutex for list of devices owned by this driver */ 116 fibril_mutex_t devices_mutex; 142 /** Path to the driver's binary */ 143 const char *binary_path; 117 144 /** List of device ids for device-to-driver matching.*/ 118 145 match_id_list_t match_ids; … … 124 151 node_t *parent; 125 152 /** Pointers to previous and next child devices in the linked list of parent device's node.*/ 126 link_t sibling; 127 128 153 link_t sibling; 154 /** List of child device nodes. */ 155 link_t children; 156 157 129 158 /** List of device ids for device-to-driver matching.*/ 130 159 match_id_list_t match_ids; 131 160 }; 132 161 162 static driver_t * create_driver() 163 { 164 driver_t *res = malloc(sizeof(driver_t)); 165 if(res != NULL) { 166 clean_driver(res); 167 } 168 return res; 169 } 170 171 static inline void init_driver(driver_t *drv) 172 { 173 assert(drv != NULL); 174 175 memset(drv, 0, sizeof(driver_t)); 176 list_initialize(&drv->match_ids.ids); 177 } 178 179 static inline void clean_driver(driver_t *drv) 180 { 181 assert(drv != NULL); 182 183 free(drv->name); 184 free(drv->binary_path); 185 186 clean_match_ids(&drv->match_ids); 187 188 init_driver(drv); 189 } 190 191 static void clean_match_ids(match_id_list_t *ids) 192 { 193 link_t *link = NULL; 194 match_id_t *id; 195 196 while(!list_empty(&ids->ids)) { 197 link = ids->ids.next; 198 list_remove(link); 199 id = list_get_instance(link, match_id_t, link); 200 delete_match_id(id); 201 } 202 } 203 204 static inline match_id_t * create_match_id() 205 { 206 match_id_t *id = malloc(sizeof(match_id_t)); 207 memset(id, 0, sizeof(match_id_t)); 208 return id; 209 } 210 211 static inline void delete_match_id(match_id_t *id) 212 { 213 free(id->id); 214 free(id); 215 } 216 217 static void add_match_id(match_id_list_t *ids, match_id_t *id) 218 { 219 match_id_t *mid = NULL; 220 link_t *link = ids->ids.next; 221 222 while (link != &ids->ids) { 223 mid = list_get_instance(link, match_id_t,link); 224 if (mid->score < id->score) { 225 break; 226 } 227 link = link->next; 228 } 229 230 list_insert_before(&id->link, link); 231 } 232 233 static inline void delete_driver(driver_t *drv) 234 { 235 clean_driver(drv); 236 free(drv); 237 } 238 239 static inline void add_driver(driver_t *drv) 240 { 241 list_prepend(&drv->drivers, &drivers_list); 242 printf(NAME": the '%s' driver was added to the list of available drivers.\n", drv->name); 243 } 244 245 static char * get_abs_path(const char *base_path, const char *name, const char *ext) 246 { 247 char *res; 248 int base_len = str_size(base_path); 249 int size = base_len + str_size(name) + str_size(ext) + 3; 250 251 res = malloc(size); 252 253 if (res) { 254 str_cpy(res, size, base_path); 255 if(base_path[base_len - 1] != '/') { 256 str_append(res, size, "/"); 257 } 258 str_append(res, size, name); 259 if(ext[0] != '.') { 260 str_append(res, size, "."); 261 } 262 str_append(res, size, ext); 263 } 264 265 return res; 266 } 267 268 static inline bool skip_spaces(const char **buf) 269 { 270 while (isspace(**buf)) { 271 (*buf)++; 272 } 273 return *buf != 0; 274 } 275 276 static inline size_t get_id_len(const char *str) 277 { 278 size_t len = 0; 279 while(*str != 0 && !isspace(*str)) { 280 len++; 281 str++; 282 } 283 return len; 284 } 285 286 static char * read_id(const char **buf) 287 { 288 char *res = NULL; 289 size_t len = get_id_len(*buf); 290 if (len > 0) { 291 res = malloc(len + 1); 292 if (res != NULL) { 293 str_ncpy(res, len + 1, *buf, len); 294 *buf += len; 295 } 296 } 297 return res; 298 } 299 300 static bool parse_match_ids(const char *buf, match_id_list_t *ids) 301 { 302 int score = 0; 303 char *id = NULL; 304 int ids_read = 0; 305 306 while (true) { 307 // skip spaces 308 if (!skip_spaces(&buf)) { 309 break; 310 } 311 // read score 312 score = strtoul(buf, &buf, 10); 313 314 // skip spaces 315 if (!skip_spaces(&buf)) { 316 break; 317 } 318 319 // read id 320 if (NULL == (id = read_id(&buf))) { 321 break; 322 } 323 324 // create new match_id structure 325 match_id_t *mid = create_match_id(); 326 mid->id = id; 327 mid->score = score; 328 329 /// add it to the list 330 add_match_id(ids, mid); 331 332 ids_read++; 333 } 334 335 return ids_read > 0; 336 } 337 338 static bool read_match_ids(const char *conf_path, match_id_list_t *ids) 339 { 340 bool suc = false; 341 char *buf = NULL; 342 bool opened = false; 343 int fd; 344 off_t len = 0; 345 346 fd = open(conf_path, O_RDONLY); 347 if (fd < 0) { 348 printf(NAME ": unable to open %s\n", conf_path); 349 goto cleanup; 350 } 351 opened = true; 352 353 len = lseek(fd, 0, SEEK_END); 354 lseek(fd, 0, SEEK_SET); 355 if (len == 0) { 356 printf(NAME ": configuration file '%s' is empty.\n", conf_path); 357 goto cleanup; 358 } 359 360 buf = malloc(len + 1); 361 if (buf == NULL) { 362 printf(NAME ": memory allocation failed when parsing file '%s'.\n", conf_path); 363 goto cleanup; 364 } 365 366 if (0 >= read(fd, buf, len)) { 367 printf(NAME ": unable to read file '%s'.\n", conf_path); 368 goto cleanup; 369 } 370 buf[len] = 0; 371 372 suc = parse_match_ids(buf, ids); 373 374 cleanup: 375 376 free(buf); 377 378 if(opened) { 379 close(fd); 380 } 381 382 return suc; 383 } 384 385 386 static bool get_driver_info(const char *base_path, const char *name, driver_t *drv) 387 { 388 assert(base_path != NULL && name != NULL && drv != NULL); 389 390 bool suc = false; 391 char *match_path = NULL; 392 size_t name_size = 0; 393 394 // read the list of match ids from the driver's configuration file 395 if (NULL == (match_path = get_abs_path(base_path, name, MATCH_EXT))) { 396 goto cleanup; 397 } 398 399 if (!read_match_ids(match_path, &drv->match_ids)) { 400 goto cleanup; 401 } 402 403 // allocate and fill driver's name 404 name_size = str_size(name)+1; 405 drv->name = malloc(name_size); 406 if (!drv->name) { 407 goto cleanup; 408 } 409 str_cpy(drv->name, name_size, name); 410 411 suc = true; 412 413 cleanup: 414 415 if (!suc) { 416 free(drv->binary_path); 417 free(drv->name); 418 // set the driver structure to the default state 419 init_driver(drv); 420 } 421 422 free(match_path); 423 424 return suc; 425 } 426 427 /** Lookup drivers in the directory. 428 * 429 * @param dir_path the path to the directory where we search for drivers. * 430 */ 431 static int lookup_available_drivers(const char *dir_path) 432 { 433 int drv_cnt = 0; 434 DIR *dir = NULL; 435 struct dirent *diren; 436 437 dir = opendir(dir_path); 438 if (dir != NULL) { 439 driver_t *drv = create_driver(); 440 while ((diren = readdir(dir))) { 441 if (get_driver_info(dir_path, diren->d_name, drv)) { 442 add_driver(drv); 443 drv = create_driver(); 444 } 445 } 446 delete_driver(drv); 447 closedir(dir); 448 } 449 450 return drv_cnt; 451 } 452 453 static inline node_t * create_dev_node() 454 { 455 node_t *res = malloc(sizeof(node_t)); 456 if (res != NULL) { 457 memset(res, 0, sizeof(node_t)); 458 } 459 return res; 460 } 461 462 static inline void init_dev_node(node_t *node, node_t *parent) 463 { 464 assert(node != NULL); 465 466 node->parent = parent; 467 if (parent != NULL) { 468 list_append(&node->sibling, &parent->children); 469 } 470 471 list_initialize(&node->children); 472 473 list_initialize(&node->match_ids.ids); 474 } 475 476 static node_t * create_root_node() 477 { 478 node_t *node = create_dev_node(); 479 480 } 481 482 static void init_device_tree(dev_tree_t *tree) 483 { 484 // create root node and add it to the device tree 485 tree->root_node = create_root_node(); 486 487 488 // find suitable driver and start it 489 } 490 133 491 /** Initialize device manager internal structures. 134 492 */ 135 static bool devman_init() 136 { 137 // TODO: 493 static bool devman_init() 494 { 138 495 // initialize list of available drivers 139 496 lookup_available_drivers(DRIVER_DEFAULT_STORE); 497 498 // create root device node 499 init_device_tree(&device_tree); 500 140 501 return true; 141 502 } … … 147 508 { 148 509 printf(NAME ": HelenOS Device Manager\n"); 149 510 150 511 if (!devman_init()) { 151 512 printf(NAME ": Error while initializing service\n"); 152 513 return -1; 153 514 } 154 155 /*// Set a handler of incomming connections 515 516 /* 517 // Set a handler of incomming connections 156 518 async_set_client_connection(devman_connection); 157 158 // Register device manager at naming service 519 520 // Register device manager at naming service 159 521 ipcarg_t phonead; 160 if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0) 522 if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0) 161 523 return -1; 162 524 163 525 printf(NAME ": Accepting connections\n"); 164 526 async_manager();*/ 165 166 // Never reached 527 528 // Never reached 167 529 return 0; 168 530 }
Note:
See TracChangeset
for help on using the changeset viewer.