Ignore:
File:
1 edited

Legend:

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

    r45059d6b r8b1e15ac  
    3434#include <fcntl.h>
    3535#include <sys/stat.h>
    36 #include <io/log.h>
    3736#include <ipc/driver.h>
    3837#include <ipc/devman.h>
    39 #include <loc.h>
     38#include <devmap.h>
    4039#include <str_error.h>
    41 #include <stdio.h>
    4240
    4341#include "devman.h"
     
    6664}
    6765
    68 static int loc_functions_compare(unsigned long key[], hash_count_t keys,
     66static int devmap_functions_compare(unsigned long key[], hash_count_t keys,
    6967    link_t *item)
    7068{
    71         fun_node_t *fun = hash_table_get_instance(item, fun_node_t, loc_fun);
    72         return (fun->service_id == (service_id_t) key[0]);
     69        fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devmap_fun);
     70        return (fun->devmap_handle == (devmap_handle_t) key[0]);
     71}
     72
     73static int devmap_devices_class_compare(unsigned long key[], hash_count_t keys,
     74    link_t *item)
     75{
     76        dev_class_info_t *class_info
     77            = hash_table_get_instance(item, dev_class_info_t, devmap_link);
     78        assert(class_info != NULL);
     79
     80        return (class_info->devmap_handle == (devmap_handle_t) key[0]);
    7381}
    7482
     
    8997};
    9098
    91 static hash_table_operations_t loc_devices_ops = {
     99static hash_table_operations_t devmap_devices_ops = {
    92100        .hash = devices_hash,
    93         .compare = loc_functions_compare,
     101        .compare = devmap_functions_compare,
     102        .remove_callback = devices_remove_callback
     103};
     104
     105static hash_table_operations_t devmap_devices_class_ops = {
     106        .hash = devices_hash,
     107        .compare = devmap_devices_class_compare,
    94108        .remove_callback = devices_remove_callback
    95109};
     
    132146        fibril_mutex_unlock(&drivers_list->drivers_mutex);
    133147
    134         log_msg(LVL_NOTE, "Driver `%s' was added to the list of available "
    135             "drivers.", drv->name);
     148        printf(NAME": the '%s' driver was added to the list of available "
     149            "drivers.\n", drv->name);
    136150}
    137151
     
    223237bool read_match_ids(const char *conf_path, match_id_list_t *ids)
    224238{
    225         log_msg(LVL_DEBUG, "read_match_ids(conf_path=\"%s\")", conf_path);
     239        printf(NAME ": read_match_ids conf_path = %s.\n", conf_path);
    226240       
    227241        bool suc = false;
     
    233247        fd = open(conf_path, O_RDONLY);
    234248        if (fd < 0) {
    235                 log_msg(LVL_ERROR, "Unable to open `%s' for reading: %s.",
    236                     conf_path, str_error(fd));
     249                printf(NAME ": unable to open %s\n", conf_path);
    237250                goto cleanup;
    238251        }
     
    242255        lseek(fd, 0, SEEK_SET);
    243256        if (len == 0) {
    244                 log_msg(LVL_ERROR, "Configuration file '%s' is empty.",
    245                     conf_path);
     257                printf(NAME ": configuration file '%s' is empty.\n", conf_path);
    246258                goto cleanup;
    247259        }
     
    249261        buf = malloc(len + 1);
    250262        if (buf == NULL) {
    251                 log_msg(LVL_ERROR, "Memory allocation failed when parsing file "
    252                     "'%s'.", conf_path);
     263                printf(NAME ": memory allocation failed when parsing file "
     264                    "'%s'.\n", conf_path);
    253265                goto cleanup;
    254266        }
    255267       
    256         ssize_t read_bytes = read_all(fd, buf, len);
    257         if (read_bytes <= 0) {
    258                 log_msg(LVL_ERROR, "Unable to read file '%s' (%zd).", conf_path,
    259                     read_bytes);
     268        if (read(fd, buf, len) <= 0) {
     269                printf(NAME ": unable to read file '%s'.\n", conf_path);
    260270                goto cleanup;
    261271        }
    262         buf[read_bytes] = 0;
     272        buf[len] = 0;
    263273       
    264274        suc = parse_match_ids(buf, ids);
     
    295305bool get_driver_info(const char *base_path, const char *name, driver_t *drv)
    296306{
    297         log_msg(LVL_DEBUG, "get_driver_info(base_path=\"%s\", name=\"%s\")",
     307        printf(NAME ": get_driver_info base_path = %s, name = %s.\n",
    298308            base_path, name);
    299309       
     
    327337        struct stat s;
    328338        if (stat(drv->binary_path, &s) == ENOENT) { /* FIXME!! */
    329                 log_msg(LVL_ERROR, "Driver not found at path `%s'.",
    330                     drv->binary_path);
     339                printf(NAME ": driver not found at path %s.", drv->binary_path);
    331340                goto cleanup;
    332341        }
     
    355364int lookup_available_drivers(driver_list_t *drivers_list, const char *dir_path)
    356365{
    357         log_msg(LVL_DEBUG, "lookup_available_drivers(dir=\"%s\")", dir_path);
     366        printf(NAME ": lookup_available_drivers, dir = %s \n", dir_path);
    358367       
    359368        int drv_cnt = 0;
     
    389398        dev_node_t *dev;
    390399       
    391         log_msg(LVL_DEBUG, "create_root_nodes()");
     400        printf(NAME ": create_root_nodes\n");
    392401       
    393402        fibril_rwlock_write_lock(&tree->rwlock);
     
    406415        }
    407416       
    408         insert_fun_node(tree, fun, str_dup(""), NULL);
     417        insert_fun_node(tree, fun, clone_string(""), NULL);
    409418        match_id_t *id = create_match_id();
    410         id->id = str_dup("root");
     419        id->id = clone_string("root");
    411420        id->score = 100;
    412421        add_match_id(&fun->match_ids, id);
     
    451460        fibril_mutex_lock(&drivers_list->drivers_mutex);
    452461       
    453         list_foreach(drivers_list->drivers, link) {
     462        link_t *link = drivers_list->drivers.next;
     463        while (link != &drivers_list->drivers) {
    454464                drv = list_get_instance(link, driver_t, drivers);
    455465                score = get_match_score(drv, node);
     
    458468                        best_drv = drv;
    459469                }
     470                link = link->next;
    460471        }
    461472       
     
    472483void attach_driver(dev_node_t *dev, driver_t *drv)
    473484{
    474         log_msg(LVL_DEBUG, "attach_driver(dev=\"%s\",drv=\"%s\")",
    475             dev->pfun->pathname, drv->name);
     485        printf(NAME ": attach_driver %s to device %s\n",
     486            drv->name, dev->pfun->pathname);
    476487       
    477488        fibril_mutex_lock(&drv->driver_mutex);
     
    495506        assert(fibril_mutex_is_locked(&drv->driver_mutex));
    496507       
    497         log_msg(LVL_DEBUG, "start_driver(drv=\"%s\")", drv->name);
     508        printf(NAME ": start_driver '%s'\n", drv->name);
    498509       
    499510        rc = task_spawnl(NULL, drv->binary_path, drv->binary_path, NULL);
    500511        if (rc != EOK) {
    501                 log_msg(LVL_ERROR, "Spawning driver `%s' (%s) failed: %s.",
    502                     drv->name, drv->binary_path, str_error(rc));
     512                printf(NAME ": error spawning %s (%s)\n",
     513                    drv->name, str_error(rc));
    503514                return false;
    504515        }
     
    519530        driver_t *res = NULL;
    520531        driver_t *drv = NULL;
     532        link_t *link;
    521533       
    522534        fibril_mutex_lock(&drv_list->drivers_mutex);
    523535       
    524         list_foreach(drv_list->drivers, link) {
     536        link = drv_list->drivers.next;
     537        while (link != &drv_list->drivers) {
    525538                drv = list_get_instance(link, driver_t, drivers);
    526539                if (str_cmp(drv->name, drv_name) == 0) {
     
    528541                        break;
    529542                }
     543
     544                link = link->next;
    530545        }
    531546       
     
    533548       
    534549        return res;
     550}
     551
     552/** Remember the driver's phone.
     553 *
     554 * @param driver        The driver.
     555 * @param phone         The phone to the driver.
     556 */
     557void set_driver_phone(driver_t *driver, sysarg_t phone)
     558{
     559        fibril_mutex_lock(&driver->driver_mutex);
     560        assert(driver->state == DRIVER_STARTING);
     561        driver->phone = phone;
     562        fibril_mutex_unlock(&driver->driver_mutex);
    535563}
    536564
     
    543571        dev_node_t *dev;
    544572        link_t *link;
    545 
    546         log_msg(LVL_DEBUG, "pass_devices_to_driver(driver=\"%s\")",
    547             driver->name);
     573        int phone;
     574
     575        printf(NAME ": pass_devices_to_driver(`%s')\n", driver->name);
    548576
    549577        fibril_mutex_lock(&driver->driver_mutex);
     578
     579        phone = async_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
     580
     581        if (phone < 0) {
     582                fibril_mutex_unlock(&driver->driver_mutex);
     583                return;
     584        }
    550585
    551586        /*
     
    553588         * that has not been passed to the driver.
    554589         */
    555         link = driver->devices.head.next;
    556         while (link != &driver->devices.head) {
     590        link = driver->devices.next;
     591        while (link != &driver->devices) {
    557592                dev = list_get_instance(link, dev_node_t, driver_devices);
    558593                if (dev->passed_to_driver) {
     
    573608                fibril_mutex_unlock(&driver->driver_mutex);
    574609
    575                 add_device(driver, dev, tree);
     610                add_device(phone, driver, dev, tree);
    576611
    577612                /*
     
    591626                 * Restart the cycle to go through all devices again.
    592627                 */
    593                 link = driver->devices.head.next;
    594         }
     628                link = driver->devices.next;
     629        }
     630
     631        async_hangup(phone);
    595632
    596633        /*
     
    603640         * immediately and possibly started here as well.
    604641         */
    605         log_msg(LVL_DEBUG, "Driver `%s' enters running state.", driver->name);
     642        printf(NAME ": driver %s goes into running state.\n", driver->name);
    606643        driver->state = DRIVER_RUNNING;
    607644
     
    620657void initialize_running_driver(driver_t *driver, dev_tree_t *tree)
    621658{
    622         log_msg(LVL_DEBUG, "initialize_running_driver(driver=\"%s\")",
    623             driver->name);
     659        printf(NAME ": initialize_running_driver (`%s')\n", driver->name);
    624660       
    625661        /*
     
    642678        list_initialize(&drv->devices);
    643679        fibril_mutex_initialize(&drv->driver_mutex);
    644         drv->sess = NULL;
    645680}
    646681
     
    673708}
    674709
    675 /** Create loc path and name for the function. */
    676 void loc_register_tree_function(fun_node_t *fun, dev_tree_t *tree)
    677 {
    678         char *loc_pathname = NULL;
    679         char *loc_name = NULL;
    680        
    681         asprintf(&loc_name, "%s", fun->pathname);
    682         if (loc_name == NULL)
     710/** Create devmap path and name for the function. */
     711void devmap_register_tree_function(fun_node_t *fun, dev_tree_t *tree)
     712{
     713        char *devmap_pathname = NULL;
     714        char *devmap_name = NULL;
     715       
     716        asprintf(&devmap_name, "%s", fun->pathname);
     717        if (devmap_name == NULL)
    683718                return;
    684719       
    685         replace_char(loc_name, '/', LOC_SEPARATOR);
    686        
    687         asprintf(&loc_pathname, "%s/%s", LOC_DEVICE_NAMESPACE,
    688             loc_name);
    689         if (loc_pathname == NULL) {
    690                 free(loc_name);
     720        replace_char(devmap_name, '/', DEVMAP_SEPARATOR);
     721       
     722        asprintf(&devmap_pathname, "%s/%s", DEVMAP_DEVICE_NAMESPACE,
     723            devmap_name);
     724        if (devmap_pathname == NULL) {
     725                free(devmap_name);
    691726                return;
    692727        }
    693728       
    694         loc_service_register_with_iface(loc_pathname,
    695             &fun->service_id, DEVMAN_CONNECT_FROM_LOC);
    696        
    697         tree_add_loc_function(tree, fun);
    698        
    699         free(loc_name);
    700         free(loc_pathname);
     729        devmap_device_register_with_iface(devmap_pathname,
     730            &fun->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);
     731       
     732        tree_add_devmap_function(tree, fun);
     733       
     734        free(devmap_name);
     735        free(devmap_pathname);
    701736}
    702737
     
    706741 * @param node          The device's node in the device tree.
    707742 */
    708 void add_device(driver_t *drv, dev_node_t *dev, dev_tree_t *tree)
     743void add_device(int phone, driver_t *drv, dev_node_t *dev, dev_tree_t *tree)
    709744{
    710745        /*
     
    712747         * access any structures that would affect driver_t.
    713748         */
    714         log_msg(LVL_DEBUG, "add_device(drv=\"%s\", dev=\"%s\")",
    715             drv->name, dev->pfun->name);
     749        printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name,
     750            dev->pfun->name);
     751       
     752        sysarg_t rc;
     753        ipc_call_t answer;
    716754       
    717755        /* Send the device to the driver. */
     
    722760                parent_handle = 0;
    723761        }
    724        
    725         async_exch_t *exch = async_exchange_begin(drv->sess);
    726        
    727         ipc_call_t answer;
    728         aid_t req = async_send_2(exch, DRIVER_ADD_DEVICE, dev->handle,
     762
     763        aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, dev->handle,
    729764            parent_handle, &answer);
    730765       
    731         /* Send the device name to the driver. */
    732         sysarg_t rc = async_data_write_start(exch, dev->pfun->name,
     766        /* Send the device's name to the driver. */
     767        rc = async_data_write_start(phone, dev->pfun->name,
    733768            str_size(dev->pfun->name) + 1);
    734        
    735         async_exchange_end(exch);
    736        
    737769        if (rc != EOK) {
    738770                /* TODO handle error */
     
    777809        driver_t *drv = find_best_match_driver(drivers_list, dev);
    778810        if (drv == NULL) {
    779                 log_msg(LVL_ERROR, "No driver found for device `%s'.",
     811                printf(NAME ": no driver found for device '%s'.\n",
    780812                    dev->pfun->pathname);
    781813                return false;
     
    793825        fibril_mutex_unlock(&drv->driver_mutex);
    794826
    795         /* Notify the driver about the new device. */
    796         if (is_running)
    797                 add_device(drv, dev, tree);
     827        if (is_running) {
     828                /* Notify the driver about the new device. */
     829                int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
     830                if (phone >= 0) {
     831                        add_device(phone, drv, dev, tree);
     832                        async_hangup(phone);
     833                }
     834        }
    798835       
    799836        return true;
     
    810847bool init_device_tree(dev_tree_t *tree, driver_list_t *drivers_list)
    811848{
    812         log_msg(LVL_DEBUG, "init_device_tree()");
     849        printf(NAME ": init_device_tree.\n");
    813850       
    814851        tree->current_handle = 0;
     
    818855        hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1,
    819856            &devman_functions_ops);
    820         hash_table_create(&tree->loc_functions, DEVICE_BUCKETS, 1,
    821             &loc_devices_ops);
     857        hash_table_create(&tree->devmap_functions, DEVICE_BUCKETS, 1,
     858            &devmap_devices_ops);
    822859       
    823860        fibril_rwlock_initialize(&tree->rwlock);
     
    898935}
    899936
    900 /** Get list of device functions. */
    901 int dev_get_functions(dev_tree_t *tree, dev_node_t *dev,
    902     devman_handle_t *hdl_buf, size_t buf_size, size_t *act_size)
    903 {
    904         size_t act_cnt;
    905         size_t buf_cnt;
    906 
    907         assert(fibril_rwlock_is_locked(&tree->rwlock));
    908 
    909         buf_cnt = buf_size / sizeof(devman_handle_t);
    910 
    911         act_cnt = list_count(&dev->functions);
    912         *act_size = act_cnt * sizeof(devman_handle_t);
    913 
    914         if (buf_size % sizeof(devman_handle_t) != 0)
    915                 return EINVAL;
    916 
    917         size_t pos = 0;
    918         list_foreach(dev->functions, item) {
    919                 fun_node_t *fun =
    920                     list_get_instance(item, fun_node_t, dev_functions);
    921 
    922                 if (pos < buf_cnt)
    923                         hdl_buf[pos] = fun->handle;
    924                 pos++;
    925         }
    926 
    927         return EOK;
    928 }
    929 
    930 
    931937/* Function nodes */
    932938
     
    943949                link_initialize(&res->dev_functions);
    944950                list_initialize(&res->match_ids.ids);
     951                list_initialize(&res->classes);
    945952                link_initialize(&res->devman_fun);
    946                 link_initialize(&res->loc_fun);
     953                link_initialize(&res->devmap_fun);
    947954        }
    948955       
     
    10191026        fun->pathname = (char *) malloc(pathsize);
    10201027        if (fun->pathname == NULL) {
    1021                 log_msg(LVL_ERROR, "Failed to allocate device path.");
     1028                printf(NAME ": failed to allocate device path.\n");
    10221029                return false;
    10231030        }
     
    10501057        assert(fibril_rwlock_is_write_locked(&tree->rwlock));
    10511058       
    1052         log_msg(LVL_DEBUG, "insert_dev_node(dev=%p, pfun=%p [\"%s\"])",
    1053             dev, pfun, pfun->pathname);
    1054 
    10551059        /* Add the node to the handle-to-node map. */
    10561060        dev->handle = ++tree->current_handle;
     
    10591063
    10601064        /* Add the node to the list of its parent's children. */
     1065        printf("insert_dev_node: dev=%p, dev->pfun := %p\n", dev, pfun);
    10611066        dev->pfun = pfun;
    10621067        pfun->child = dev;
     
    11071112       
    11081113        return true;
    1109 }
    1110 
    1111 /** Remove function from device tree.
    1112  *
    1113  * @param tree          Device tree
    1114  * @param node          Function node to remove
    1115  */
    1116 void remove_fun_node(dev_tree_t *tree, fun_node_t *fun)
    1117 {
    1118         assert(tree != NULL);
    1119         assert(fun != NULL);
    1120         assert(fibril_rwlock_is_write_locked(&tree->rwlock));
    1121        
    1122         /* Remove the node from the handle-to-node map. */
    1123         unsigned long key = fun->handle;
    1124         hash_table_remove(&tree->devman_functions, &key, 1);
    1125        
    1126         /* Remove the node from the list of its parent's children. */
    1127         if (fun->dev != NULL)
    1128                 list_remove(&fun->dev_functions);
    11291114}
    11301115
     
    11381123fun_node_t *find_fun_node_by_path(dev_tree_t *tree, char *path)
    11391124{
    1140         assert(path != NULL);
    1141 
    1142         bool is_absolute = path[0] == '/';
    1143         if (!is_absolute) {
    1144                 return NULL;
    1145         }
    1146 
    11471125        fibril_rwlock_read_lock(&tree->rwlock);
    11481126       
     
    11541132        char *rel_path = path;
    11551133        char *next_path_elem = NULL;
    1156         bool cont = (rel_path[1] != '\0');
     1134        bool cont = (rel_path[0] == '/');
    11571135       
    11581136        while (cont && fun != NULL) {
     
    11791157}
    11801158
    1181 /** Find function with a specified name belonging to given device.
    1182  *
    1183  * Device tree rwlock should be held at least for reading.
    1184  *
    1185  * @param dev Device the function belongs to.
    1186  * @param name Function name (not path).
    1187  * @return Function node.
    1188  * @retval NULL No function with given name.
    1189  */
    1190 fun_node_t *find_fun_node_in_device(dev_node_t *dev, const char *name)
    1191 {
    1192         assert(dev != NULL);
    1193         assert(name != NULL);
    1194 
    1195         fun_node_t *fun;
    1196 
    1197         list_foreach(dev->functions, link) {
    1198                 fun = list_get_instance(link, fun_node_t, dev_functions);
    1199 
    1200                 if (str_cmp(name, fun->name) == 0)
    1201                         return fun;
    1202         }
    1203 
    1204         return NULL;
    1205 }
    1206 
    12071159/** Find child function node with a specified name.
    12081160 *
     
    12151167fun_node_t *find_node_child(fun_node_t *pfun, const char *name)
    12161168{
    1217         return find_fun_node_in_device(pfun->child, name);
    1218 }
    1219 
    1220 /* loc devices */
    1221 
    1222 fun_node_t *find_loc_tree_function(dev_tree_t *tree, service_id_t service_id)
     1169        fun_node_t *fun;
     1170        link_t *link;
     1171       
     1172        link = pfun->child->functions.next;
     1173       
     1174        while (link != &pfun->child->functions) {
     1175                fun = list_get_instance(link, fun_node_t, dev_functions);
     1176               
     1177                if (str_cmp(name, fun->name) == 0)
     1178                        return fun;
     1179               
     1180                link = link->next;
     1181        }
     1182       
     1183        return NULL;
     1184}
     1185
     1186/* Device classes */
     1187
     1188/** Create device class.
     1189 *
     1190 * @return      Device class.
     1191 */
     1192dev_class_t *create_dev_class(void)
     1193{
     1194        dev_class_t *cl;
     1195       
     1196        cl = (dev_class_t *) malloc(sizeof(dev_class_t));
     1197        if (cl != NULL) {
     1198                memset(cl, 0, sizeof(dev_class_t));
     1199                list_initialize(&cl->devices);
     1200                fibril_mutex_initialize(&cl->mutex);
     1201        }
     1202       
     1203        return cl;
     1204}
     1205
     1206/** Create device class info.
     1207 *
     1208 * @return              Device class info.
     1209 */
     1210dev_class_info_t *create_dev_class_info(void)
     1211{
     1212        dev_class_info_t *info;
     1213       
     1214        info = (dev_class_info_t *) malloc(sizeof(dev_class_info_t));
     1215        if (info != NULL) {
     1216                memset(info, 0, sizeof(dev_class_info_t));
     1217                list_initialize(&info->dev_classes);
     1218                list_initialize(&info->devmap_link);
     1219                list_initialize(&info->link);
     1220        }
     1221       
     1222        return info;
     1223}
     1224
     1225size_t get_new_class_dev_idx(dev_class_t *cl)
     1226{
     1227        size_t dev_idx;
     1228       
     1229        fibril_mutex_lock(&cl->mutex);
     1230        dev_idx = ++cl->curr_dev_idx;
     1231        fibril_mutex_unlock(&cl->mutex);
     1232       
     1233        return dev_idx;
     1234}
     1235
     1236
     1237/** Create unique device name within the class.
     1238 *
     1239 * @param cl            The class.
     1240 * @param base_dev_name Contains the base name for the device if it was
     1241 *                      specified by the driver when it registered the device by
     1242 *                      the class; NULL if driver specified no base name.
     1243 * @return              The unique name for the device within the class.
     1244 */
     1245char *create_dev_name_for_class(dev_class_t *cl, const char *base_dev_name)
     1246{
     1247        char *dev_name;
     1248        const char *base_name;
     1249       
     1250        if (base_dev_name != NULL)
     1251                base_name = base_dev_name;
     1252        else
     1253                base_name = cl->base_dev_name;
     1254       
     1255        size_t idx = get_new_class_dev_idx(cl);
     1256        asprintf(&dev_name, "%s%zu", base_name, idx);
     1257       
     1258        return dev_name;
     1259}
     1260
     1261/** Add the device function to the class.
     1262 *
     1263 * The device may be added to multiple classes and a class may contain multiple
     1264 * devices. The class and the device are associated with each other by the
     1265 * dev_class_info_t structure.
     1266 *
     1267 * @param dev           The device.
     1268 * @param class         The class.
     1269 * @param base_dev_name The base name of the device within the class if
     1270 *                      specified by the driver, NULL otherwise.
     1271 * @return              dev_class_info_t structure which associates the device
     1272 *                      with the class.
     1273 */
     1274dev_class_info_t *add_function_to_class(fun_node_t *fun, dev_class_t *cl,
     1275    const char *base_dev_name)
     1276{
     1277        dev_class_info_t *info;
     1278
     1279        assert(fun != NULL);
     1280        assert(cl != NULL);
     1281
     1282        info = create_dev_class_info();
     1283
     1284       
     1285        if (info != NULL) {
     1286                info->dev_class = cl;
     1287                info->fun = fun;
     1288               
     1289                /* Add the device to the class. */
     1290                fibril_mutex_lock(&cl->mutex);
     1291                list_append(&info->link, &cl->devices);
     1292                fibril_mutex_unlock(&cl->mutex);
     1293               
     1294                /* Add the class to the device. */
     1295                list_append(&info->dev_classes, &fun->classes);
     1296               
     1297                /* Create unique name for the device within the class. */
     1298                info->dev_name = create_dev_name_for_class(cl, base_dev_name);
     1299        }
     1300       
     1301        return info;
     1302}
     1303
     1304dev_class_t *get_dev_class(class_list_t *class_list, char *class_name)
     1305{
     1306        dev_class_t *cl;
     1307       
     1308        fibril_rwlock_write_lock(&class_list->rwlock);
     1309        cl = find_dev_class_no_lock(class_list, class_name);
     1310        if (cl == NULL) {
     1311                cl = create_dev_class();
     1312                if (cl != NULL) {
     1313                        cl->name = class_name;
     1314                        cl->base_dev_name = "";
     1315                        add_dev_class_no_lock(class_list, cl);
     1316                }
     1317        }
     1318
     1319        fibril_rwlock_write_unlock(&class_list->rwlock);
     1320        return cl;
     1321}
     1322
     1323dev_class_t *find_dev_class_no_lock(class_list_t *class_list,
     1324    const char *class_name)
     1325{
     1326        dev_class_t *cl;
     1327        link_t *link = class_list->classes.next;
     1328       
     1329        while (link != &class_list->classes) {
     1330                cl = list_get_instance(link, dev_class_t, link);
     1331                if (str_cmp(cl->name, class_name) == 0) {
     1332                        return cl;
     1333                }
     1334                link = link->next;
     1335        }
     1336       
     1337        return NULL;
     1338}
     1339
     1340void add_dev_class_no_lock(class_list_t *class_list, dev_class_t *cl)
     1341{
     1342        list_append(&cl->link, &class_list->classes);
     1343}
     1344
     1345void init_class_list(class_list_t *class_list)
     1346{
     1347        list_initialize(&class_list->classes);
     1348        fibril_rwlock_initialize(&class_list->rwlock);
     1349        hash_table_create(&class_list->devmap_functions, DEVICE_BUCKETS, 1,
     1350            &devmap_devices_class_ops);
     1351}
     1352
     1353
     1354/* Devmap devices */
     1355
     1356fun_node_t *find_devmap_tree_function(dev_tree_t *tree, devmap_handle_t devmap_handle)
    12231357{
    12241358        fun_node_t *fun = NULL;
    12251359        link_t *link;
    1226         unsigned long key = (unsigned long) service_id;
     1360        unsigned long key = (unsigned long) devmap_handle;
    12271361       
    12281362        fibril_rwlock_read_lock(&tree->rwlock);
    1229         link = hash_table_find(&tree->loc_functions, &key);
     1363        link = hash_table_find(&tree->devmap_functions, &key);
    12301364        if (link != NULL)
    1231                 fun = hash_table_get_instance(link, fun_node_t, loc_fun);
     1365                fun = hash_table_get_instance(link, fun_node_t, devmap_fun);
    12321366        fibril_rwlock_read_unlock(&tree->rwlock);
    12331367       
     
    12351369}
    12361370
    1237 void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun)
    1238 {
    1239         unsigned long key = (unsigned long) fun->service_id;
     1371fun_node_t *find_devmap_class_function(class_list_t *classes,
     1372    devmap_handle_t devmap_handle)
     1373{
     1374        fun_node_t *fun = NULL;
     1375        dev_class_info_t *cli;
     1376        link_t *link;
     1377        unsigned long key = (unsigned long)devmap_handle;
     1378       
     1379        fibril_rwlock_read_lock(&classes->rwlock);
     1380        link = hash_table_find(&classes->devmap_functions, &key);
     1381        if (link != NULL) {
     1382                cli = hash_table_get_instance(link, dev_class_info_t,
     1383                    devmap_link);
     1384                fun = cli->fun;
     1385        }
     1386        fibril_rwlock_read_unlock(&classes->rwlock);
     1387       
     1388        return fun;
     1389}
     1390
     1391void class_add_devmap_function(class_list_t *class_list, dev_class_info_t *cli)
     1392{
     1393        unsigned long key = (unsigned long) cli->devmap_handle;
     1394       
     1395        fibril_rwlock_write_lock(&class_list->rwlock);
     1396        hash_table_insert(&class_list->devmap_functions, &key, &cli->devmap_link);
     1397        fibril_rwlock_write_unlock(&class_list->rwlock);
     1398
     1399        assert(find_devmap_class_function(class_list, cli->devmap_handle) != NULL);
     1400}
     1401
     1402void tree_add_devmap_function(dev_tree_t *tree, fun_node_t *fun)
     1403{
     1404        unsigned long key = (unsigned long) fun->devmap_handle;
    12401405        fibril_rwlock_write_lock(&tree->rwlock);
    1241         hash_table_insert(&tree->loc_functions, &key, &fun->loc_fun);
     1406        hash_table_insert(&tree->devmap_functions, &key, &fun->devmap_fun);
    12421407        fibril_rwlock_write_unlock(&tree->rwlock);
    12431408}
Note: See TracChangeset for help on using the changeset viewer.