Changeset e4c4247 in mainline


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

parts of device manager (unstable)

Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/Makefile

    r0358da0 re4c4247  
    4848        srv/clip \
    4949        srv/devmap \
     50        srv/devman \
    5051        srv/loader \
    5152        srv/ns \
  • uspace/srv/devman/devman.c

    r0358da0 re4c4247  
    3535/** @file
    3636 */
    37  
     37
     38#include <assert.h>
    3839#include <ipc/services.h>
    3940#include <ipc/ns.h>
     
    4546#include <stdlib.h>
    4647#include <string.h>
     48#include <dirent.h>
     49#include <fcntl.h>
     50#include <ctype.h>
    4751//#include <ipc/devman.h>
    4852
    4953#define NAME          "devman"
     54
     55#define DRIVER_DEFAULT_STORE  "/srv/drivers"
     56#define MATCH_EXT ".ma"
    5057
    5158#define MAX_ID_LEN 256
     
    6673
    6774
     75static driver_t * create_driver();
     76static inline void init_driver(driver_t *drv);
     77static inline void clean_driver(driver_t *drv);
     78static inline void delete_driver(driver_t *drv);
     79static inline void add_driver(driver_t *drv);
     80static char * get_abs_path(const char *base_path, const char *name, const char *ext);
     81static bool parse_match_ids(const char *buf, match_id_list_t *ids);
     82static bool read_match_ids(const char *conf_path, match_id_list_t *ids);
     83static void clean_match_ids(match_id_list_t *ids);
     84static inline match_id_t * create_match_id();
     85static inline void delete_match_id(match_id_t *id);
     86static void add_match_id(match_id_list_t *ids, match_id_t *id);
     87static bool get_driver_info(const char *base_path, const char *name, driver_t *drv);
     88static int lookup_available_drivers(const char *dir_path);
     89static inline node_t * create_dev_node();
     90static node_t * create_root_node();
     91static void init_device_tree(dev_tree_t *tree);
     92static bool devman_init();
     93
     94
    6895
    6996LIST_INITIALIZE(drivers_list);
     97
     98
    7099
    71100/** Represents device tree.
     
    73102struct dev_tree {
    74103        node_t *root_node;
    75 }
    76 
    77 
     104};
     105
     106static dev_tree_t device_tree;
    78107
    79108/** Ids of device models used for device-to-driver matching.
     
    82111        /** Pointers to next and previous ids.
    83112         */
    84         link_t ids;
     113        link_t link;
    85114        /** Id of device model.
    86115         */
    87         char 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.
    91120         */
    92121        unsigned int score;
    93122};
    94123
    95 /** List of ids for matching devices to drivers sorted 
     124/** List of ids for matching devices to drivers sorted
    96125 * according to match scores in descending order.
    97126 */
     
    102131/** Representation of device driver.
    103132 */
    104 struct driver { 
     133struct driver {
    105134        /** Pointers to previous and next drivers in a linked list */
    106135        link_t drivers;
     
    111140        /** Name of the device driver */
    112141        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;
    117144        /** List of device ids for device-to-driver matching.*/
    118145        match_id_list_t match_ids;
     
    124151        node_t *parent;
    125152        /** 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
    129158        /** List of device ids for device-to-driver matching.*/
    130159        match_id_list_t match_ids;
    131160};
    132161
     162static 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
     171static 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
     179static 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
     191static 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
     204static 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
     211static inline void delete_match_id(match_id_t *id)
     212{
     213        free(id->id);
     214        free(id);
     215}
     216
     217static 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
     233static inline void delete_driver(driver_t *drv)
     234{
     235        clean_driver(drv);
     236        free(drv);
     237}
     238
     239static 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
     245static 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
     268static inline bool skip_spaces(const char **buf)
     269{
     270        while (isspace(**buf)) {
     271                (*buf)++;               
     272        }
     273        return *buf != 0;       
     274}
     275
     276static 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
     286static 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
     300static 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
     338static 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       
     374cleanup:
     375       
     376        free(buf);
     377       
     378        if(opened) {
     379                close(fd);     
     380        }
     381       
     382        return suc;
     383}
     384
     385
     386static 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       
     413cleanup:
     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 */
     431static 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
     453static 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
     462static 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
     476static node_t * create_root_node()
     477{
     478        node_t *node = create_dev_node();
     479       
     480}
     481
     482static 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
    133491/** Initialize device manager internal structures.
    134492 */
    135 static bool devman_init()
    136 {
    137         // TODO:
     493static bool devman_init()
     494{
    138495        // 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
    140501        return true;
    141502}
     
    147508{
    148509        printf(NAME ": HelenOS Device Manager\n");
    149        
     510
    150511        if (!devman_init()) {
    151512                printf(NAME ": Error while initializing service\n");
    152513                return -1;
    153514        }
    154        
    155         /*// Set a handler of incomming connections
     515
     516        /*
     517        // Set a handler of incomming connections
    156518        async_set_client_connection(devman_connection);
    157        
    158         // Register device manager at naming service 
     519
     520        // Register device manager at naming service
    159521        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)
    161523                return -1;
    162        
     524
    163525        printf(NAME ": Accepting connections\n");
    164526        async_manager();*/
    165        
    166         // Never reached 
     527
     528        // Never reached
    167529        return 0;
    168530}
Note: See TracChangeset for help on using the changeset viewer.