Changeset 85e48a9 in mainline
- Timestamp:
- 2010-02-11T21:05:00Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e2b9a993
- Parents:
- e4c4247
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
re4c4247 r85e48a9 48 48 #include <dirent.h> 49 49 #include <fcntl.h> 50 #include <sys/stat.h> 50 51 #include <ctype.h> 51 52 //#include <ipc/devman.h> … … 89 90 static inline node_t * create_dev_node(); 90 91 static node_t * create_root_node(); 91 static voidinit_device_tree(dev_tree_t *tree);92 static bool init_device_tree(dev_tree_t *tree); 92 93 static bool devman_init(); 94 static int get_match_score(driver_t *drv, node_t *dev); 93 95 94 96 … … 144 146 /** List of device ids for device-to-driver matching.*/ 145 147 match_id_list_t match_ids; 148 /** Pointer to the linked list of devices controlled by this driver */ 149 link_t devices; 146 150 }; 147 151 … … 154 158 /** List of child device nodes. */ 155 159 link_t children; 156 157 158 160 /** List of device ids for device-to-driver matching.*/ 159 match_id_list_t match_ids; 161 match_id_list_t match_ids; 162 /** Driver of this device.*/ 163 driver_t *drv; 164 /** Pointer to the previous and next device in the list of devices 165 owned by one driver */ 166 link_t driver_devices; 160 167 }; 161 168 … … 175 182 memset(drv, 0, sizeof(driver_t)); 176 183 list_initialize(&drv->match_ids.ids); 184 list_initialize(&drv->devices); 177 185 } 178 186 … … 408 416 } 409 417 str_cpy(drv->name, name_size, name); 418 419 // initialize path with driver's binary 420 if (NULL == (drv->binary_path = get_abs_path(base_path, name, ""))) { 421 goto cleanup; 422 } 423 424 // check whether the driver's binary exists 425 struct stat s; 426 if (stat(drv->binary_path, &s) == ENOENT) { 427 printf(NAME ": driver not found at path %s.", drv->binary_path); 428 goto cleanup; 429 } 410 430 411 431 suc = true; … … 462 482 static inline void init_dev_node(node_t *node, node_t *parent) 463 483 { 464 assert( node != NULL);484 assert(NULL != node); 465 485 466 486 node->parent = parent; 467 if ( parent != NULL) {487 if (NULL != parent) { 468 488 list_append(&node->sibling, &parent->children); 469 489 } … … 477 497 { 478 498 node_t *node = create_dev_node(); 479 480 } 481 482 static void init_device_tree(dev_tree_t *tree) 499 if (node) { 500 init_dev_node(node, NULL); 501 match_id_t *id = create_match_id(); 502 id->id = "root"; 503 id->score = 100; 504 add_match_id(&node->match_ids, id); 505 } 506 return node; 507 } 508 509 static int get_match_score(driver_t *drv, node_t *dev) 510 { 511 link_t* drv_head = &drv->match_ids.ids; 512 link_t* dev_head = &dev->match_ids.ids; 513 514 if (list_empty(drv_head) || list_empty(dev_head)) { 515 return 0; 516 } 517 518 link_t* drv_link = drv->match_ids.ids.next; 519 link_t* dev_link = dev->match_ids.ids.next; 520 521 match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link); 522 match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link); 523 524 int score_next_drv = 0; 525 int score_next_dev = 0; 526 527 do { 528 if (0 == str_cmp(drv_id->id, dev_id->id)) { // we found a match 529 // return the score of the match 530 return drv_id->score * dev_id->score; 531 } 532 533 // compute the next score we get, if we advance in the driver's list of match ids 534 if (drv_head != drv_link->next) { 535 score_next_drv = dev_id->score * list_get_instance(drv_link->next, match_id_t, link)->score; 536 } else { 537 score_next_drv = 0; 538 } 539 540 // compute the next score we get, if we advance in the device's list of match ids 541 if (dev_head != dev_link->next) { 542 score_next_dev = drv_id->score * list_get_instance(dev_link->next, match_id_t, link)->score; 543 } else { 544 score_next_dev = 0; 545 } 546 547 // advance in one of the two lists, so we get the next highest score 548 if (score_next_drv > score_next_dev) { 549 drv_link = drv_link->next; 550 drv_id = list_get_instance(drv_link, match_id_t, link); 551 } else { 552 dev_link = dev_link->next; 553 dev_id = list_get_instance(dev_link, match_id_t, link); 554 } 555 556 } while (drv_head != drv_link->next && dev_head != dev_link->next); 557 558 return 0; 559 } 560 561 static driver_t * find_best_match_driver(node_t *node) 562 { 563 driver_t *best_drv = NULL, *drv = NULL; 564 int best_score = 0, score = 0; 565 link_t *link = drivers_list.next; 566 567 while (link != &drivers_list) { 568 drv = list_get_instance(link, driver_t, drivers); 569 score = get_match_score(drv, node); 570 if (score > best_score) { 571 best_score = score; 572 best_drv = drv; 573 } 574 } 575 576 return best_drv; 577 } 578 579 static void attach_driver(node_t *node, driver_t *drv) 580 { 581 node->drv = drv; 582 list_append(&node->driver_devices, &drv->devices); 583 } 584 585 static bool start_driver(driver_t *drv) 586 { 587 char *argv[2]; 588 589 printf(NAME ": spawning driver %s\n", drv->name); 590 591 argv[0] = drv->name; 592 argv[1] = NULL; 593 594 if (!task_spawn(drv->binary_path, argv)) { 595 printf(NAME ": error spawning %s\n", drv->name); 596 return false; 597 } 598 599 return true; 600 } 601 602 static bool add_device(driver_t *drv, node_t *node) 603 { 604 // TODO 605 606 // pass a new device to the running driver, which was previously assigned to it 607 // send the phone of the parent's driver and device's handle within the parent's driver to the driver 608 // let the driver to probe the device and specify whether the device is actually present 609 // if the device is present, remember its handle within the driver 610 611 return true; 612 } 613 614 static bool assign_driver(node_t *node) 615 { 616 // find the driver which is the most suitable for handling this device 617 driver_t *drv = find_best_match_driver(node); 618 if (NULL == drv) { 619 return false; 620 } 621 622 // attach the driver to the device 623 attach_driver(node, drv); 624 625 if (!drv->running) { 626 // start driver 627 start_driver(drv); 628 } else { 629 // notify driver about new device 630 add_device(drv, node); 631 } 632 633 return true; 634 } 635 636 static bool init_device_tree(dev_tree_t *tree) 483 637 { 484 638 // create root node and add it to the device tree 485 tree->root_node = create_root_node(); 486 639 if (NULL == (tree->root_node = create_root_node())) { 640 return false; 641 } 487 642 488 643 // find suitable driver and start it 644 return assign_driver(tree->root_node); 489 645 } 490 646 … … 494 650 { 495 651 // initialize list of available drivers 496 lookup_available_drivers(DRIVER_DEFAULT_STORE); 652 if (0 == lookup_available_drivers(DRIVER_DEFAULT_STORE)) { 653 printf(NAME " no drivers found."); 654 return false; 655 } 497 656 498 657 // create root device node 499 init_device_tree(&device_tree); 658 if (!init_device_tree(&device_tree)) { 659 printf(NAME " failed to initialize device tree."); 660 return false; 661 } 500 662 501 663 return true; 664 } 665 666 667 /** Function for handling connections to device manager. 668 * 669 */ 670 static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall) 671 { 672 /* Select interface */ 673 switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) { 674 /*case DEVMAN_DRIVER: 675 devmap_connection_driver(iid, icall); 676 break;*/ 677 678 default: 679 /* No such interface */ 680 ipc_answer_0(iid, ENOENT); 681 } 502 682 } 503 683
Note:
See TracChangeset
for help on using the changeset viewer.