Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset e2b9a993 in mainline


Ignore:
Timestamp:
2010-02-12T15:08:16Z (12 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master
Children:
08d9c4e6
Parents:
85e48a9
Message:

device manager - parts of code

Location:
uspace
Files:
6 added
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/include/ipc/services.h

    r85e48a9 re2b9a993  
    4545        SERVICE_VFS,
    4646        SERVICE_DEVMAP,
     47        SERVICE_DEVMAN,
    4748        SERVICE_FHC,
    4849        SERVICE_OBIO,
  • uspace/srv/devman/Makefile

    r85e48a9 re2b9a993  
    3434
    3535SOURCES = \
    36         devman.c
     36        main.c \
     37        devman.c \
     38        match.c \
     39        util.c
    3740
    3841include ../Makefile.common
  • uspace/srv/devman/devman.c

    r85e48a9 re2b9a993  
    2727 */
    2828
    29 /**
    30  * @defgroup devman Device manager.
    31  * @brief HelenOS device manager.
     29/** @addtogroup devman
    3230 * @{
    3331 */
    3432
    35 /** @file
    36  */
    37 
    38 #include <assert.h>
    39 #include <ipc/services.h>
    40 #include <ipc/ns.h>
    41 #include <async.h>
    42 #include <stdio.h>
    4333#include <errno.h>
    44 #include <bool.h>
    45 #include <fibril_synch.h>
    46 #include <stdlib.h>
    47 #include <string.h>
    48 #include <dirent.h>
    4934#include <fcntl.h>
    5035#include <sys/stat.h>
    51 #include <ctype.h>
    52 //#include <ipc/devman.h>
    53 
    54 #define NAME          "devman"
    55 
    56 #define DRIVER_DEFAULT_STORE  "/srv/drivers"
    57 #define MATCH_EXT ".ma"
    58 
    59 #define MAX_ID_LEN 256
    60 
    61 
    62 struct driver;
    63 struct match_id;
    64 struct match_id_list;
    65 struct node;
    66 struct dev_tree;
    67 
    68 
    69 typedef struct driver driver_t;
    70 typedef struct match_id match_id_t;
    71 typedef struct match_id_list match_id_list_t;
    72 typedef struct node node_t;
    73 typedef struct dev_tree dev_tree_t;
    74 
    75 
    76 static driver_t * create_driver();
    77 static inline void init_driver(driver_t *drv);
    78 static inline void clean_driver(driver_t *drv);
    79 static inline void delete_driver(driver_t *drv);
    80 static inline void add_driver(driver_t *drv);
    81 static char * get_abs_path(const char *base_path, const char *name, const char *ext);
    82 static bool parse_match_ids(const char *buf, match_id_list_t *ids);
    83 static bool read_match_ids(const char *conf_path, match_id_list_t *ids);
    84 static void clean_match_ids(match_id_list_t *ids);
    85 static inline match_id_t * create_match_id();
    86 static inline void delete_match_id(match_id_t *id);
    87 static void add_match_id(match_id_list_t *ids, match_id_t *id);
    88 static bool get_driver_info(const char *base_path, const char *name, driver_t *drv);
    89 static int lookup_available_drivers(const char *dir_path);
    90 static inline node_t * create_dev_node();
    91 static node_t * create_root_node();
    92 static bool init_device_tree(dev_tree_t *tree);
    93 static bool devman_init();
    94 static int get_match_score(driver_t *drv, node_t *dev);
    95 
    96 
    97 
    98 LIST_INITIALIZE(drivers_list);
    99 
    100 
    101 
    102 /** Represents device tree.
    103  */
    104 struct dev_tree {
    105         node_t *root_node;
    106 };
    107 
    108 static dev_tree_t device_tree;
    109 
    110 /** Ids of device models used for device-to-driver matching.
    111  */
    112 struct match_id {
    113         /** Pointers to next and previous ids.
    114          */
    115         link_t link;
    116         /** Id of device model.
    117          */
    118         const char *id;
    119         /** Relevancy of device-to-driver match.
    120          * The higher is the product of scores specified for the device by the bus driver and by the leaf driver,
    121          * the more suitable is the leaf driver for handling the device.
    122          */
    123         unsigned int score;
    124 };
    125 
    126 /** List of ids for matching devices to drivers sorted
    127  * according to match scores in descending order.
    128  */
    129 struct match_id_list {
    130         link_t ids;
    131 };
    132 
    133 /** Representation of device driver.
    134  */
    135 struct driver {
    136         /** Pointers to previous and next drivers in a linked list */
    137         link_t drivers;
    138         /** Specifies whether the driver has been started.*/
    139         bool running;
    140         /** Phone asociated with this driver */
    141         ipcarg_t phone;
    142         /** Name of the device driver */
    143         char *name;
    144         /** Path to the driver's binary */
    145         const char *binary_path;
    146         /** List of device ids for device-to-driver matching.*/
    147         match_id_list_t match_ids;
    148         /** Pointer to the linked list of devices controlled by this driver */
    149         link_t devices;
    150 };
    151 
    152 /** Representation of a node in the device tree.*/
    153 struct node {
    154         /** The node of the parent device. */
    155         node_t *parent;
    156         /** Pointers to previous and next child devices in the linked list of parent device's node.*/
    157         link_t sibling;
    158         /** List of child device nodes. */
    159         link_t children;
    160         /** List of device ids for device-to-driver matching.*/
    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; 
    167 };
    168 
    169 static driver_t * create_driver()
     36
     37#include "devman.h"
     38#include "util.h"
     39
     40
     41driver_t * create_driver()
    17042{
    17143        driver_t *res = malloc(sizeof(driver_t));
     
    17648}
    17749
    178 static inline void init_driver(driver_t *drv)
    179 {
    180         assert(drv != NULL);   
    181        
    182         memset(drv, 0, sizeof(driver_t));       
    183         list_initialize(&drv->match_ids.ids);
    184         list_initialize(&drv->devices);
    185 }
    186 
    187 static inline void clean_driver(driver_t *drv)
    188 {
    189         assert(drv != NULL);
    190        
    191         free(drv->name);
    192         free(drv->binary_path);
    193        
    194         clean_match_ids(&drv->match_ids);
    195        
    196         init_driver(drv);       
    197 }
    198 
    199 static void clean_match_ids(match_id_list_t *ids)
    200 {
    201         link_t *link = NULL;
    202         match_id_t *id;
    203        
    204         while(!list_empty(&ids->ids)) {
    205                 link = ids->ids.next;
    206                 list_remove(link);             
    207                 id = list_get_instance(link, match_id_t, link);
    208                 delete_match_id(id);           
    209         }       
    210 }
    211 
    212 static inline match_id_t * create_match_id()
    213 {
    214         match_id_t *id = malloc(sizeof(match_id_t));
    215         memset(id, 0, sizeof(match_id_t));
    216         return id;     
    217 }
    218 
    219 static inline void delete_match_id(match_id_t *id)
    220 {
    221         free(id->id);
    222         free(id);
    223 }
    224 
    225 static void add_match_id(match_id_list_t *ids, match_id_t *id)
    226 {
    227         match_id_t *mid = NULL;
    228         link_t *link = ids->ids.next;   
    229        
    230         while (link != &ids->ids) {
    231                 mid = list_get_instance(link, match_id_t,link);
    232                 if (mid->score < id->score) {
    233                         break;
    234                 }       
    235                 link = link->next;
    236         }
    237        
    238         list_insert_before(&id->link, link);   
    239 }
    240 
    241 static inline void delete_driver(driver_t *drv)
    242 {
    243         clean_driver(drv);
    244         free(drv);
    245 }
    246 
    247 static inline void add_driver(driver_t *drv)
    248 {
    249         list_prepend(&drv->drivers, &drivers_list);
    250         printf(NAME": the '%s' driver was added to the list of available drivers.\n", drv->name);       
    251 }
    252 
    253 static char * get_abs_path(const char *base_path, const char *name, const char *ext)
    254 {
    255         char *res;
    256         int base_len = str_size(base_path);
    257         int size = base_len + str_size(name) + str_size(ext) + 3;       
    258        
    259         res = malloc(size);
    260        
    261         if (res) {
    262                 str_cpy(res, size, base_path);
    263                 if(base_path[base_len - 1] != '/') {
    264                         str_append(res, size, "/");                     
    265                 }
    266                 str_append(res, size, name);
    267                 if(ext[0] != '.') {
    268                         str_append(res, size, ".");
    269                 }
    270                 str_append(res, size, ext);             
    271         }
    272        
    273         return res;
    274 }
    275 
    276 static inline bool skip_spaces(const char **buf)
    277 {
    278         while (isspace(**buf)) {
    279                 (*buf)++;               
    280         }
    281         return *buf != 0;       
    282 }
    283 
    284 static inline size_t get_id_len(const char *str)
    285 {
    286         size_t len = 0;
    287         while(*str != 0 && !isspace(*str)) {
    288                 len++;
    289                 str++;
    290         }
    291         return len;
    292 }
    293 
    294 static char * read_id(const char **buf)
     50char * read_id(const char **buf)
    29551{
    29652        char *res = NULL;
    297         size_t len = get_id_len(*buf);
     53        size_t len = get_nonspace_len(*buf);
    29854        if (len > 0) {
    29955                res = malloc(len + 1);
     
    30662}
    30763
    308 static bool parse_match_ids(const char *buf, match_id_list_t *ids)
     64bool parse_match_ids(const char *buf, match_id_list_t *ids)
    30965{
    31066        int score = 0;
     
    344100}
    345101
    346 static bool read_match_ids(const char *conf_path, match_id_list_t *ids)
     102bool read_match_ids(const char *conf_path, match_id_list_t *ids)
    347103{       
    348104        bool suc = false;       
     
    392148
    393149
    394 static bool get_driver_info(const char *base_path, const char *name, driver_t *drv)
     150bool get_driver_info(const char *base_path, const char *name, driver_t *drv)
    395151{
    396152        assert(base_path != NULL && name != NULL && drv != NULL);
     
    447203/** Lookup drivers in the directory.
    448204 *
    449  * @param dir_path the path to the directory where we search for drivers. *
     205 * @param drivers_list the list of available drivers.
     206 * @param dir_path the path to the directory where we search for drivers.
    450207 */
    451 static int lookup_available_drivers(const char *dir_path)
     208int lookup_available_drivers(link_t *drivers_list, const char *dir_path)
    452209{
    453210        int drv_cnt = 0;
     
    460217                while ((diren = readdir(dir))) {                       
    461218                        if (get_driver_info(dir_path, diren->d_name, drv)) {
    462                                 add_driver(drv);
     219                                add_driver(drivers_list, drv);
    463220                                drv = create_driver();
    464221                        }       
     
    471228}
    472229
    473 static inline node_t * create_dev_node()
    474 {
    475         node_t *res = malloc(sizeof(node_t));
    476         if (res != NULL) {
    477                 memset(res, 0, sizeof(node_t));
    478         }
    479         return res;
    480 }
    481 
    482 static inline void init_dev_node(node_t *node, node_t *parent)
    483 {
    484         assert(NULL != node);
    485        
    486         node->parent = parent;
    487         if (NULL != parent) {
    488                 list_append(&node->sibling, &parent->children);
    489         }
    490        
    491         list_initialize(&node->children);
    492        
    493         list_initialize(&node->match_ids.ids); 
    494 }
    495 
    496 static node_t * create_root_node()
     230node_t * create_root_node()
    497231{
    498232        node_t *node = create_dev_node();
     
    507241}
    508242
    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)
     243driver_t * find_best_match_driver(link_t *drivers_list, node_t *node)
    562244{
    563245        driver_t *best_drv = NULL, *drv = NULL;
    564246        int best_score = 0, score = 0;
    565         link_t *link = drivers_list.next;       
    566        
    567         while (link != &drivers_list) {
     247        link_t *link = drivers_list->next;     
     248       
     249        while (link != drivers_list) {
    568250                drv = list_get_instance(link, driver_t, drivers);
    569251                score = get_match_score(drv, node);
     
    577259}
    578260
    579 static void attach_driver(node_t *node, driver_t *drv)
     261void attach_driver(node_t *node, driver_t *drv)
    580262{
    581263        node->drv = drv;
     
    583265}
    584266
    585 static bool start_driver(driver_t *drv)
     267bool start_driver(driver_t *drv)
    586268{
    587269        char *argv[2];
     
    600282}
    601283
    602 static bool add_device(driver_t *drv, node_t *node)
     284bool add_device(driver_t *drv, node_t *node)
    603285{
    604286        // TODO
     
    612294}
    613295
    614 static bool assign_driver(node_t *node)
     296bool assign_driver(node_t *node, link_t *drivers_list)
    615297{
    616298        // find the driver which is the most suitable for handling this device
    617         driver_t *drv = find_best_match_driver(node);
     299        driver_t *drv = find_best_match_driver(drivers_list, node);
    618300        if (NULL == drv) {
    619301                return false;           
     
    634316}
    635317
    636 static bool init_device_tree(dev_tree_t *tree)
     318bool init_device_tree(dev_tree_t *tree, link_t *drivers_list)
    637319{
    638320        // create root node and add it to the device tree
     
    642324
    643325        // find suitable driver and start it
    644         return assign_driver(tree->root_node);
    645 }
    646 
    647 /** Initialize device manager internal structures.
    648  */
    649 static bool devman_init()
    650 {
    651         // initialize list of available drivers
    652         if (0 == lookup_available_drivers(DRIVER_DEFAULT_STORE)) {
    653                 printf(NAME " no drivers found.");
    654                 return false;
    655         }
    656 
    657         // create root device node
    658         if (!init_device_tree(&device_tree)) {
    659                 printf(NAME " failed to initialize device tree.");
    660                 return false;           
    661         }
    662 
    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         }
    682 }
    683 
    684 /**
    685  *
    686  */
    687 int main(int argc, char *argv[])
    688 {
    689         printf(NAME ": HelenOS Device Manager\n");
    690 
    691         if (!devman_init()) {
    692                 printf(NAME ": Error while initializing service\n");
    693                 return -1;
    694         }
    695 
    696         /*
    697         // Set a handler of incomming connections
    698         async_set_client_connection(devman_connection);
    699 
    700         // Register device manager at naming service
    701         ipcarg_t phonead;
    702         if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0)
    703                 return -1;
    704 
    705         printf(NAME ": Accepting connections\n");
    706         async_manager();*/
    707 
    708         // Never reached
    709         return 0;
    710 }
     326        return assign_driver(tree->root_node, drivers_list);
     327}
     328
Note: See TracChangeset for help on using the changeset viewer.