Changeset bda60d9 in mainline


Ignore:
Timestamp:
2010-03-19T14:40:14Z (14 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d347b53
Parents:
7707954
Message:

adding child device - parts of code

Location:
uspace
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/generic/devman.c

    r7707954 rbda60d9  
    106106}
    107107
    108 int devman_child_device_register(const char *name, long parent_handle, long *handle)
     108int devman_child_device_register(
     109        const char *name, match_id_list_t *match_ids, device_handle_t parent_handle, device_handle_t *handle)
    109110{       
    110111        int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
     
    124125                return retval;
    125126        }
     127       
     128        // TODO match ids
    126129       
    127130        async_wait_for(req, &retval);
  • uspace/lib/libc/include/devman.h

    r7707954 rbda60d9  
    4646
    4747int devman_driver_register(const char *, async_client_conn_t);
    48 int devman_child_device_register(const char *name, long parent_handle, long *handle);
     48int devman_child_device_register(const char *, match_id_list_t *, device_handle_t, device_handle_t *);
    4949
    5050
  • uspace/lib/libc/include/ipc/devman.h

    r7707954 rbda60d9  
    3434#define LIBC_IPC_DEVMAN_H_
    3535
     36#include <adt/list.h>
    3637#include <ipc/ipc.h>
     38#include <stdlib.h>
     39#include <string.h>
    3740
    3841#define DEVMAN_NAME_MAXLEN 256
     42
     43typedef ipcarg_t device_handle_t;
     44
     45/** Ids of device models used for device-to-driver matching.
     46 */
     47typedef struct match_id {
     48        /** Pointers to next and previous ids.
     49         */
     50        link_t link;
     51        /** Id of device model.
     52         */
     53        const char *id;
     54        /** Relevancy of device-to-driver match.
     55         * The higher is the product of scores specified for the device by the bus driver and by the leaf driver,
     56         * the more suitable is the leaf driver for handling the device.
     57         */
     58        unsigned int score;
     59} match_id_t;
     60
     61/** List of ids for matching devices to drivers sorted
     62 * according to match scores in descending order.
     63 */
     64typedef struct match_id_list {
     65        link_t ids;
     66} match_id_list_t;
     67
     68
     69static inline match_id_t * create_match_id()
     70{
     71        match_id_t *id = malloc(sizeof(match_id_t));
     72        memset(id, 0, sizeof(match_id_t));
     73        return id;
     74}
     75
     76static inline void delete_match_id(match_id_t *id)
     77{
     78        if (id) {
     79                if (NULL != id->id) {
     80                        free(id->id);
     81                }
     82                free(id);
     83        }
     84}
     85
     86static inline void add_match_id(match_id_list_t *ids, match_id_t *id)
     87{
     88        match_id_t *mid = NULL;
     89        link_t *link = ids->ids.next;   
     90       
     91        while (link != &ids->ids) {
     92                mid = list_get_instance(link, match_id_t,link);
     93                if (mid->score < id->score) {
     94                        break;
     95                }       
     96                link = link->next;
     97        }
     98       
     99        list_insert_before(&id->link, link);   
     100}
     101
     102static inline void clean_match_ids(match_id_list_t *ids)
     103{
     104        link_t *link = NULL;
     105        match_id_t *id;
     106       
     107        while(!list_empty(&ids->ids)) {
     108                link = ids->ids.next;
     109                list_remove(link);             
     110                id = list_get_instance(link, match_id_t, link);
     111                delete_match_id(id);           
     112        }       
     113}
    39114
    40115typedef enum {
  • uspace/lib/libdrv/generic/driver.c

    r7707954 rbda60d9  
    7272        // result of the operation - device was added, device is not present etc.
    7373        ipcarg_t ret = 0;       
    74         ipcarg_t dev_handle =  IPC_GET_ARG1(*icall);
     74        device_handle_t dev_handle =  IPC_GET_ARG1(*icall);
    7575       
    7676        printf("%s: adding device with handle = %x \n", driver->name, dev_handle);
     
    109109                                ipc_answer_0(callid, ENOENT);
    110110                }
    111         }
    112        
     111        }       
    113112}
    114113
     
    150149}
    151150
    152 bool child_device_register(device_t *child, const char *child_name, device_t *parent)
     151bool child_device_register(device_t *child, device_t *parent)
    153152{
    154         if (devman_child_device_register(child_name, parent->handle, &child->handle)) {
     153        printf("%s: child_device_register\n", driver->name);
     154       
     155        assert(NULL != child->name);
     156       
     157        if (devman_child_device_register(child->name, &child->match_ids, parent->handle, &child->handle)) {
    155158                // TODO initialize child device
    156159                return true;
  • uspace/lib/libdrv/include/driver.h

    r7707954 rbda60d9  
    3737
    3838#include <adt/list.h>
     39#include <ipc/devman.h>
    3940
    4041typedef struct device {
    41         long handle;
     42        device_handle_t handle;
    4243        ipcarg_t parent_phone; 
     44        const char *name;
     45        match_id_list_t match_ids;
    4346       
    4447        // TODO add more items - parent bus type etc.
     
    6467        if (NULL != dev) {
    6568                memset(dev, 0, sizeof(device_t));
    66         }
    67        
     69        }       
     70        list_initialize(&dev->match_ids.ids);
    6871        return dev;
    6972}
    7073
    71 bool child_device_register(device_t *child, const char *child_name, device_t *parent);
     74static inline delete_device(device_t *dev) {
     75        clean_match_ids(&dev->match_ids);
     76        if (NULL != dev->name) {
     77                free(dev->name);
     78        }
     79        free(dev);
     80}
    7281
     82bool child_device_register(device_t *child, device_t *parent);
    7383
    7484
  • uspace/srv/devman/devman.c

    r7707954 rbda60d9  
    320320        node_t *node = create_dev_node();
    321321        if (node) {
    322                 insert_dev_node(tree, node, NULL);
     322                insert_dev_node(tree, node, "", NULL);
    323323                match_id_t *id = create_match_id();
    324324                id->id = "root";
     
    410410}
    411411
     412/** Find device driver in the list of device drivers.
     413 *
     414 * @param drv_list the list of device drivers.
     415 * @param drv_name the name of the device driver which is searched.
     416 * @return the device driver of the specified name, if it is in the list, NULL otherwise. 
     417 */
    412418driver_t * find_driver(driver_list_t *drv_list, const char *drv_name)
    413419{       
     
    432438}
    433439
     440/** Remember the driver's phone.
     441 * @param driver the driver.
     442 * @param phone the phone to the driver.
     443 */
    434444void set_driver_phone(driver_t *driver, ipcarg_t phone)
    435445{               
     
    467477}
    468478
    469 /** Finish the initialization of a driver after it has succesfully started and registered itself by the device manager.
     479/** Finish the initialization of a driver after it has succesfully started
     480 * and after it has registered itself by the device manager.
    470481 *
    471482 * Pass devices formerly matched to the driver to the driver and remember the driver is running and fully functional now.
     
    559570        printf(NAME ": init_device_tree.\n");
    560571       
     572        memset(tree->node_map, 0, MAX_DEV * sizeof(node_t *));
     573       
    561574        atomic_set(&tree->current_handle, 0);
    562575       
     
    570583}
    571584
     585/** Create and set device's full path in device tree.
     586 *
     587 * @param node the device's device node.
     588 * @param parent the parent device node.
     589 * @return true on success, false otherwise (insufficient resources etc.).
     590 */
     591static bool set_dev_path(node_t *node, node_t *parent)
     592{       
     593        assert(NULL != node->name);
     594       
     595        size_t pathsize = (str_size(node->name) + 1);   
     596        if (NULL != parent) {           
     597                pathsize += str_size(parent->name) + 1;         
     598        }
     599       
     600        if (NULL == (node->pathname = (char *)malloc(pathsize))) {
     601                printf(NAME ": failed to allocate device path.\n");
     602                return false;
     603        }
     604       
     605        if (NULL != parent) {
     606                str_cpy(node->pathname, pathsize, parent->pathname);
     607                str_append(node->pathname, pathsize, "/");
     608                str_append(node->pathname, pathsize, node->name);
     609        } else {
     610                str_cpy(node->pathname, pathsize, node->name);
     611        }
     612       
     613        return true;
     614}
     615
     616/** Insert new device into device tree.
     617 *
     618 * @param tree the device tree.
     619 * @param node the newly added device node.
     620 * @param dev_name the name of the newly added device.
     621 * @param parent the parent device node.
     622 * @return true on success, false otherwise (insufficient resources etc.).
     623 */
     624bool insert_dev_node(dev_tree_t *tree, node_t *node, const char *dev_name, node_t *parent)
     625{
     626        printf(NAME ": insert_dev_node\n");
     627       
     628        assert(NULL != node && NULL != tree && dev_name != NULL);
     629       
     630        node->name = dev_name;
     631        if (!set_dev_path(node, parent)) {
     632                return false;           
     633        }
     634       
     635        // add the node to the handle-to-node map
     636        node->handle = atomic_postinc(&tree->current_handle);
     637        if (node->handle >= MAX_DEV) {
     638                printf(NAME ": failed to add device to device tree, because maximum number of devices was reached.\n");
     639                free(node->pathname);
     640                node->pathname = NULL;
     641                atomic_postdec(&tree->current_handle);
     642                return false;
     643        }
     644        tree->node_map[node->handle] = node;
     645
     646        // add the node to the list of its parent's children
     647        node->parent = parent;
     648        if (NULL != parent) {
     649                fibril_mutex_lock(&parent->children_mutex);
     650                list_append(&node->sibling, &parent->children);
     651                fibril_mutex_unlock(&parent->children_mutex);
     652        }       
     653        return true;
     654}
     655
    572656/** @}
    573657 */
  • uspace/srv/devman/devman.h

    r7707954 rbda60d9  
    4040#include <adt/list.h>
    4141#include <ipc/ipc.h>
     42#include <ipc/devman.h>
    4243#include <fibril_synch.h>
    4344#include <atomic.h>
     
    4849
    4950#define MATCH_EXT ".ma"
     51#define MAX_DEV 256
    5052
    5153struct node;
    5254
    5355typedef struct node node_t;
    54 
    55 /** Ids of device models used for device-to-driver matching.
    56  */
    57 typedef struct match_id {
    58         /** Pointers to next and previous ids.
    59          */
    60         link_t link;
    61         /** Id of device model.
    62          */
    63         const char *id;
    64         /** Relevancy of device-to-driver match.
    65          * The higher is the product of scores specified for the device by the bus driver and by the leaf driver,
    66          * the more suitable is the leaf driver for handling the device.
    67          */
    68         unsigned int score;
    69 } match_id_t;
    70 
    71 /** List of ids for matching devices to drivers sorted
    72  * according to match scores in descending order.
    73  */
    74 typedef struct match_id_list {
    75         link_t ids;
    76 } match_id_list_t;
    7756
    7857typedef enum {
     
    11796struct node {
    11897        /** The global unique identifier of the device.*/
    119         long handle;
     98        device_handle_t handle;
     99        /** The name of the device specified by its parent. */
     100        char *name;
     101        /** Full path and name of the device in device hierarchi (i. e. in full path in device tree).*/
     102        char *pathname;
    120103        /** The node of the parent device. */
    121104        node_t *parent;
     
    140123        /** Root device node. */
    141124        node_t *root_node;
     125        /** The next available handle - handles are assigned in a sequential manner.*/
    142126        atomic_t current_handle;
     127        /** Handle-to-node mapping. */
     128        node_t * node_map[MAX_DEV];
    143129} dev_tree_t;
    144130
     
    152138bool read_match_ids(const char *conf_path, match_id_list_t *ids);
    153139char * read_id(const char **buf) ;
    154 void add_match_id(match_id_list_t *ids, match_id_t *id);
    155 
    156 void clean_match_ids(match_id_list_t *ids);
    157 
    158 
    159 static inline match_id_t * create_match_id()
    160 {
    161         match_id_t *id = malloc(sizeof(match_id_t));
    162         memset(id, 0, sizeof(match_id_t));
    163         return id;
    164 }
    165 
    166 static inline void delete_match_id(match_id_t *id)
    167 {
    168         if (id) {
    169                 free_not_null(id->id);
    170                 free(id);
    171         }
    172 }
    173 
    174 
    175 
    176 
    177140
    178141// Drivers
     
    248211}
    249212
    250 static inline void insert_dev_node(dev_tree_t *tree, node_t *node, node_t *parent)
    251 {
    252         assert(NULL != node && NULL != tree);
    253        
    254         node->handle = atomic_postinc(&tree->current_handle);
    255 
    256         node->parent = parent;
    257         if (NULL != parent) {
    258                 fibril_mutex_lock(&parent->children_mutex);
    259                 list_append(&node->sibling, &parent->children);
    260                 fibril_mutex_unlock(&parent->children_mutex);
     213static inline node_t * find_dev_node(dev_tree_t *tree, long handle)
     214{
     215        if (handle < MAX_DEV) {
     216                return tree->node_map[handle];
    261217        }
    262 }
    263 
     218        return NULL;
     219}
    264220
    265221// Device tree
     
    267223bool init_device_tree(dev_tree_t *tree, driver_list_t *drivers_list);
    268224bool create_root_node(dev_tree_t *tree);
    269 
     225bool insert_dev_node(dev_tree_t *tree, node_t *node, const char *dev_name, node_t *parent);
    270226
    271227#endif
  • uspace/srv/devman/main.c

    r7707954 rbda60d9  
    120120}
    121121
     122static void devman_add_child(ipc_callid_t callid, ipc_call_t *call, driver_t *driver)
     123{
     124        printf(NAME ": devman_add_child\n");
     125       
     126        // TODO
     127       
     128}
     129
    122130/** Function for handling connections to device manager.
    123131 *
     
    145153                        continue;
    146154                case DEVMAN_ADD_CHILD_DEVICE:
    147                         // TODO add new device node to the device tree
     155                        devman_add_child(callid, &call, driver);
    148156                        break;
    149157                default:
  • uspace/srv/devman/match.c

    r7707954 rbda60d9  
    8989}
    9090
    91 void add_match_id(match_id_list_t *ids, match_id_t *id)
    92 {
    93         match_id_t *mid = NULL;
    94         link_t *link = ids->ids.next;   
    95        
    96         while (link != &ids->ids) {
    97                 mid = list_get_instance(link, match_id_t,link);
    98                 if (mid->score < id->score) {
    99                         break;
    100                 }       
    101                 link = link->next;
    102         }
    103        
    104         list_insert_before(&id->link, link);   
    105 }
    10691
    107 void clean_match_ids(match_id_list_t *ids)
    108 {
    109         link_t *link = NULL;
    110         match_id_t *id;
    111        
    112         while(!list_empty(&ids->ids)) {
    113                 link = ids->ids.next;
    114                 list_remove(link);             
    115                 id = list_get_instance(link, match_id_t, link);
    116                 delete_match_id(id);           
    117         }       
    118 }
    11992
  • uspace/srv/drivers/root/root.c

    r7707954 rbda60d9  
    4444#include <string.h>
    4545#include <ctype.h>
     46#include <macros.h>
    4647
    4748#include <driver.h>
     
    6364};
    6465
     66static bool add_platform_child(device_t *parent) {
     67        printf(NAME ": adding new child for platform device.\n");
     68       
     69        device_t *platform = NULL;
     70        match_id_t *match_id = NULL;   
     71       
     72        // create new device
     73        if (NULL == (platform = create_device())) {
     74                goto failure;
     75        }
     76       
     77        // TODO - replace this with some better solution
     78        platform->name = STRING(UARCH);
     79        printf(NAME ": the new device's name is %s.\n", platform->name);
     80       
     81        // initialize match id list
     82        if (NULL == (match_id = create_match_id())) {
     83                goto failure;
     84        }
     85        match_id->id = platform->name;
     86        match_id->score = 100;
     87        add_match_id(&platform->match_ids, match_id);   
     88       
     89        // register child  device
     90        if (!child_device_register(platform, parent)) {
     91                goto failure;
     92        }
     93       
     94        return true;
     95       
     96failure:
     97        if (NULL != match_id) {
     98                match_id->id = NULL;
     99        }
     100       
     101        if (NULL != platform) {
     102                platform->name = NULL;
     103                delete_device(platform);               
     104        }
     105       
     106        return false;   
     107}
     108
    65109static bool root_add_device(device_t *dev)
    66110{
    67         printf(NAME ": root_add_device, device handle = %s", dev->handle);
    68         // TODO add root device and register its children
     111        printf(NAME ": root_add_device, device handle = %d\n", dev->handle);
     112       
     113        // register root device's children     
     114        if (!add_platform_child(dev)) {
     115                return false;
     116        }
     117       
    69118        return true;
    70119}
     
    90139 * @}
    91140 */
     141 
Note: See TracChangeset for help on using the changeset viewer.