Changeset 85e48a9 in mainline for uspace/srv/devman/devman.c


Ignore:
Timestamp:
2010-02-11T21:05:00Z (14 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e2b9a993
Parents:
e4c4247
Message:

part of device manager

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devman/devman.c

    re4c4247 r85e48a9  
    4848#include <dirent.h>
    4949#include <fcntl.h>
     50#include <sys/stat.h>
    5051#include <ctype.h>
    5152//#include <ipc/devman.h>
     
    8990static inline node_t * create_dev_node();
    9091static node_t * create_root_node();
    91 static void init_device_tree(dev_tree_t *tree);
     92static bool init_device_tree(dev_tree_t *tree);
    9293static bool devman_init();
     94static int get_match_score(driver_t *drv, node_t *dev);
    9395
    9496
     
    144146        /** List of device ids for device-to-driver matching.*/
    145147        match_id_list_t match_ids;
     148        /** Pointer to the linked list of devices controlled by this driver */
     149        link_t devices;
    146150};
    147151
     
    154158        /** List of child device nodes. */
    155159        link_t children;
    156 
    157 
    158160        /** 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; 
    160167};
    161168
     
    175182        memset(drv, 0, sizeof(driver_t));       
    176183        list_initialize(&drv->match_ids.ids);
     184        list_initialize(&drv->devices);
    177185}
    178186
     
    408416        }       
    409417        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        }
    410430       
    411431        suc = true;
     
    462482static inline void init_dev_node(node_t *node, node_t *parent)
    463483{
    464         assert(node != NULL);
     484        assert(NULL != node);
    465485       
    466486        node->parent = parent;
    467         if (parent != NULL) {
     487        if (NULL != parent) {
    468488                list_append(&node->sibling, &parent->children);
    469489        }
     
    477497{
    478498        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
     509static 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
     561static 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
     579static void attach_driver(node_t *node, driver_t *drv)
     580{
     581        node->drv = drv;
     582        list_append(&node->driver_devices, &drv->devices);
     583}
     584
     585static 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
     602static 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
     614static 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
     636static bool init_device_tree(dev_tree_t *tree)
    483637{
    484638        // 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        }
    487642
    488643        // find suitable driver and start it
     644        return assign_driver(tree->root_node);
    489645}
    490646
     
    494650{
    495651        // 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        }
    497656
    498657        // 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        }
    500662
    501663        return true;
     664}
     665
     666
     667/** Function for handling connections to device manager.
     668 *
     669 */
     670static 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        }
    502682}
    503683
Note: See TracChangeset for help on using the changeset viewer.