Changeset bd5f3b7 in mainline for uspace/srv/devman/devman.c


Ignore:
Timestamp:
2011-08-21T13:07:35Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
00aece0, f1a9e87
Parents:
86a34d3e (diff), a6480d5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    r86a34d3e rbd5f3b7  
    3737#include <ipc/driver.h>
    3838#include <ipc/devman.h>
    39 #include <devmap.h>
     39#include <loc.h>
    4040#include <str_error.h>
    4141#include <stdio.h>
     
    6666}
    6767
    68 static int devmap_functions_compare(unsigned long key[], hash_count_t keys,
     68static int loc_functions_compare(unsigned long key[], hash_count_t keys,
    6969    link_t *item)
    7070{
    71         fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devmap_fun);
    72         return (fun->devmap_handle == (devmap_handle_t) key[0]);
    73 }
    74 
    75 static int devmap_devices_class_compare(unsigned long key[], hash_count_t keys,
    76     link_t *item)
    77 {
    78         dev_class_info_t *class_info
    79             = hash_table_get_instance(item, dev_class_info_t, devmap_link);
    80         assert(class_info != NULL);
    81 
    82         return (class_info->devmap_handle == (devmap_handle_t) key[0]);
     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]);
    8373}
    8474
     
    9989};
    10090
    101 static hash_table_operations_t devmap_devices_ops = {
     91static hash_table_operations_t loc_devices_ops = {
    10292        .hash = devices_hash,
    103         .compare = devmap_functions_compare,
    104         .remove_callback = devices_remove_callback
    105 };
    106 
    107 static hash_table_operations_t devmap_devices_class_ops = {
    108         .hash = devices_hash,
    109         .compare = devmap_devices_class_compare,
     93        .compare = loc_functions_compare,
    11094        .remove_callback = devices_remove_callback
    11195};
     
    270254        }
    271255       
    272         ssize_t read_bytes = safe_read(fd, buf, len);
     256        ssize_t read_bytes = read_all(fd, buf, len);
    273257        if (read_bytes <= 0) {
    274                 log_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path);
     258                log_msg(LVL_ERROR, "Unable to read file '%s' (%zd).", conf_path,
     259                    read_bytes);
    275260                goto cleanup;
    276261        }
     
    421406        }
    422407       
    423         insert_fun_node(tree, fun, clone_string(""), NULL);
     408        insert_fun_node(tree, fun, str_dup(""), NULL);
    424409        match_id_t *id = create_match_id();
    425         id->id = clone_string("root");
     410        id->id = str_dup("root");
    426411        id->score = 100;
    427412        add_match_id(&fun->match_ids, id);
     
    563548
    564549        fibril_mutex_lock(&driver->driver_mutex);
    565        
    566         async_exch_t *exch = async_exchange_begin(driver->sess);
    567         async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
    568             DRIVER_DEVMAN, 0, 0);
    569         async_exchange_end(exch);
    570 
    571         if (!sess) {
    572                 fibril_mutex_unlock(&driver->driver_mutex);
    573                 return;
    574         }
    575550
    576551        /*
     
    598573                fibril_mutex_unlock(&driver->driver_mutex);
    599574
    600                 add_device(sess, driver, dev, tree);
     575                add_device(driver, dev, tree);
    601576
    602577                /*
     
    618593                link = driver->devices.head.next;
    619594        }
    620 
    621         async_hangup(sess);
    622595
    623596        /*
     
    700673}
    701674
    702 /** Create devmap path and name for the function. */
    703 void devmap_register_tree_function(fun_node_t *fun, dev_tree_t *tree)
    704 {
    705         char *devmap_pathname = NULL;
    706         char *devmap_name = NULL;
    707        
    708         asprintf(&devmap_name, "%s", fun->pathname);
    709         if (devmap_name == NULL)
     675/** Create loc path and name for the function. */
     676void 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)
    710683                return;
    711684       
    712         replace_char(devmap_name, '/', DEVMAP_SEPARATOR);
    713        
    714         asprintf(&devmap_pathname, "%s/%s", DEVMAP_DEVICE_NAMESPACE,
    715             devmap_name);
    716         if (devmap_pathname == NULL) {
    717                 free(devmap_name);
     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);
    718691                return;
    719692        }
    720693       
    721         devmap_device_register_with_iface(devmap_pathname,
    722             &fun->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);
    723        
    724         tree_add_devmap_function(tree, fun);
    725        
    726         free(devmap_name);
    727         free(devmap_pathname);
     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);
    728701}
    729702
     
    733706 * @param node          The device's node in the device tree.
    734707 */
    735 void add_device(async_sess_t *sess, driver_t *drv, dev_node_t *dev,
    736     dev_tree_t *tree)
     708void add_device(driver_t *drv, dev_node_t *dev, dev_tree_t *tree)
    737709{
    738710        /*
     
    751723        }
    752724       
    753         async_exch_t *exch = async_exchange_begin(sess);
     725        async_exch_t *exch = async_exchange_begin(drv->sess);
    754726       
    755727        ipc_call_t answer;
     
    821793        fibril_mutex_unlock(&drv->driver_mutex);
    822794
    823         if (is_running) {
    824                 /* Notify the driver about the new device. */
    825                 async_exch_t *exch = async_exchange_begin(drv->sess);
    826                 async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
    827                     DRIVER_DEVMAN, 0, 0);
    828                 async_exchange_end(exch);
    829                
    830                 if (sess) {
    831                         add_device(sess, drv, dev, tree);
    832                         async_hangup(sess);
    833                 }
    834         }
     795        /* Notify the driver about the new device. */
     796        if (is_running)
     797                add_device(drv, dev, tree);
    835798       
    836799        return true;
     
    855818        hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1,
    856819            &devman_functions_ops);
    857         hash_table_create(&tree->devmap_functions, DEVICE_BUCKETS, 1,
    858             &devmap_devices_ops);
     820        hash_table_create(&tree->loc_functions, DEVICE_BUCKETS, 1,
     821            &loc_devices_ops);
    859822       
    860823        fibril_rwlock_initialize(&tree->rwlock);
     
    935898}
    936899
     900/** Get list of device functions. */
     901int 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
    937931/* Function nodes */
    938932
     
    949943                link_initialize(&res->dev_functions);
    950944                list_initialize(&res->match_ids.ids);
    951                 list_initialize(&res->classes);
    952945                link_initialize(&res->devman_fun);
    953                 link_initialize(&res->devmap_fun);
     946                link_initialize(&res->loc_fun);
    954947        }
    955948       
     
    11141107       
    11151108        return true;
     1109}
     1110
     1111/** Remove function from device tree.
     1112 *
     1113 * @param tree          Device tree
     1114 * @param node          Function node to remove
     1115 */
     1116void 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);
    11161129}
    11171130
     
    11411154        char *rel_path = path;
    11421155        char *next_path_elem = NULL;
    1143         bool cont = true;
     1156        bool cont = (rel_path[1] != '\0');
    11441157       
    11451158        while (cont && fun != NULL) {
     
    11921205}
    11931206
    1194 /** Find function node by its class name and index. */
    1195 fun_node_t *find_fun_node_by_class(class_list_t *class_list,
    1196     const char *class_name, const char *dev_name)
    1197 {
    1198         assert(class_list != NULL);
    1199         assert(class_name != NULL);
    1200         assert(dev_name != NULL);
    1201 
    1202         fibril_rwlock_read_lock(&class_list->rwlock);
    1203 
    1204         dev_class_t *cl = find_dev_class_no_lock(class_list, class_name);
    1205         if (cl == NULL) {
    1206                 fibril_rwlock_read_unlock(&class_list->rwlock);
    1207                 return NULL;
    1208         }
    1209 
    1210         dev_class_info_t *dev = find_dev_in_class(cl, dev_name);
    1211         if (dev == NULL) {
    1212                 fibril_rwlock_read_unlock(&class_list->rwlock);
    1213                 return NULL;
    1214         }
    1215 
    1216         fun_node_t *fun = dev->fun;
    1217 
    1218         fibril_rwlock_read_unlock(&class_list->rwlock);
    1219 
    1220         return fun;
    1221 }
    1222 
    1223 
    12241207/** Find child function node with a specified name.
    12251208 *
     
    12351218}
    12361219
    1237 /* Device classes */
    1238 
    1239 /** Create device class.
    1240  *
    1241  * @return      Device class.
    1242  */
    1243 dev_class_t *create_dev_class(void)
    1244 {
    1245         dev_class_t *cl;
    1246        
    1247         cl = (dev_class_t *) malloc(sizeof(dev_class_t));
    1248         if (cl != NULL) {
    1249                 memset(cl, 0, sizeof(dev_class_t));
    1250                 list_initialize(&cl->devices);
    1251                 fibril_mutex_initialize(&cl->mutex);
    1252         }
    1253        
    1254         return cl;
    1255 }
    1256 
    1257 /** Create device class info.
    1258  *
    1259  * @return              Device class info.
    1260  */
    1261 dev_class_info_t *create_dev_class_info(void)
    1262 {
    1263         dev_class_info_t *info;
    1264        
    1265         info = (dev_class_info_t *) malloc(sizeof(dev_class_info_t));
    1266         if (info != NULL) {
    1267                 memset(info, 0, sizeof(dev_class_info_t));
    1268                 link_initialize(&info->dev_classes);
    1269                 link_initialize(&info->devmap_link);
    1270                 link_initialize(&info->link);
    1271         }
    1272        
    1273         return info;
    1274 }
    1275 
    1276 size_t get_new_class_dev_idx(dev_class_t *cl)
    1277 {
    1278         size_t dev_idx;
    1279        
    1280         fibril_mutex_lock(&cl->mutex);
    1281         dev_idx = ++cl->curr_dev_idx;
    1282         fibril_mutex_unlock(&cl->mutex);
    1283        
    1284         return dev_idx;
    1285 }
    1286 
    1287 
    1288 /** Create unique device name within the class.
    1289  *
    1290  * @param cl            The class.
    1291  * @param base_dev_name Contains the base name for the device if it was
    1292  *                      specified by the driver when it registered the device by
    1293  *                      the class; NULL if driver specified no base name.
    1294  * @return              The unique name for the device within the class.
    1295  */
    1296 char *create_dev_name_for_class(dev_class_t *cl, const char *base_dev_name)
    1297 {
    1298         char *dev_name;
    1299         const char *base_name;
    1300        
    1301         if (base_dev_name != NULL)
    1302                 base_name = base_dev_name;
    1303         else
    1304                 base_name = cl->base_dev_name;
    1305        
    1306         size_t idx = get_new_class_dev_idx(cl);
    1307         asprintf(&dev_name, "%s%zu", base_name, idx);
    1308        
    1309         return dev_name;
    1310 }
    1311 
    1312 /** Add the device function to the class.
    1313  *
    1314  * The device may be added to multiple classes and a class may contain multiple
    1315  * devices. The class and the device are associated with each other by the
    1316  * dev_class_info_t structure.
    1317  *
    1318  * @param dev           The device.
    1319  * @param class         The class.
    1320  * @param base_dev_name The base name of the device within the class if
    1321  *                      specified by the driver, NULL otherwise.
    1322  * @return              dev_class_info_t structure which associates the device
    1323  *                      with the class.
    1324  */
    1325 dev_class_info_t *add_function_to_class(fun_node_t *fun, dev_class_t *cl,
    1326     const char *base_dev_name)
    1327 {
    1328         dev_class_info_t *info;
    1329 
    1330         assert(fun != NULL);
    1331         assert(cl != NULL);
    1332 
    1333         info = create_dev_class_info();
    1334 
    1335        
    1336         if (info != NULL) {
    1337                 info->dev_class = cl;
    1338                 info->fun = fun;
    1339                
    1340                 /* Add the device to the class. */
    1341                 fibril_mutex_lock(&cl->mutex);
    1342                 list_append(&info->link, &cl->devices);
    1343                 fibril_mutex_unlock(&cl->mutex);
    1344                
    1345                 /* Add the class to the device. */
    1346                 list_append(&info->dev_classes, &fun->classes);
    1347                
    1348                 /* Create unique name for the device within the class. */
    1349                 info->dev_name = create_dev_name_for_class(cl, base_dev_name);
    1350         }
    1351        
    1352         return info;
    1353 }
    1354 
    1355 dev_class_t *get_dev_class(class_list_t *class_list, char *class_name)
    1356 {
    1357         dev_class_t *cl;
    1358        
    1359         fibril_rwlock_write_lock(&class_list->rwlock);
    1360         cl = find_dev_class_no_lock(class_list, class_name);
    1361         if (cl == NULL) {
    1362                 cl = create_dev_class();
    1363                 if (cl != NULL) {
    1364                         cl->name = class_name;
    1365                         cl->base_dev_name = "";
    1366                         add_dev_class_no_lock(class_list, cl);
    1367                 }
    1368         }
    1369 
    1370         fibril_rwlock_write_unlock(&class_list->rwlock);
    1371         return cl;
    1372 }
    1373 
    1374 dev_class_t *find_dev_class_no_lock(class_list_t *class_list,
    1375     const char *class_name)
    1376 {
    1377         dev_class_t *cl;
    1378        
    1379         list_foreach(class_list->classes, link) {
    1380                 cl = list_get_instance(link, dev_class_t, link);
    1381                 if (str_cmp(cl->name, class_name) == 0) {
    1382                         return cl;
    1383                 }
    1384         }
    1385        
    1386         return NULL;
    1387 }
    1388 
    1389 void add_dev_class_no_lock(class_list_t *class_list, dev_class_t *cl)
    1390 {
    1391         list_append(&cl->link, &class_list->classes);
    1392 }
    1393 
    1394 dev_class_info_t *find_dev_in_class(dev_class_t *dev_class, const char *dev_name)
    1395 {
    1396         assert(dev_class != NULL);
    1397         assert(dev_name != NULL);
    1398 
    1399         list_foreach(dev_class->devices, link) {
    1400                 dev_class_info_t *dev = list_get_instance(link,
    1401                     dev_class_info_t, link);
    1402 
    1403                 if (str_cmp(dev->dev_name, dev_name) == 0) {
    1404                         return dev;
    1405                 }
    1406         }
    1407 
    1408         return NULL;
    1409 }
    1410 
    1411 void init_class_list(class_list_t *class_list)
    1412 {
    1413         list_initialize(&class_list->classes);
    1414         fibril_rwlock_initialize(&class_list->rwlock);
    1415         hash_table_create(&class_list->devmap_functions, DEVICE_BUCKETS, 1,
    1416             &devmap_devices_class_ops);
    1417 }
    1418 
    1419 
    1420 /* Devmap devices */
    1421 
    1422 fun_node_t *find_devmap_tree_function(dev_tree_t *tree, devmap_handle_t devmap_handle)
     1220/* loc devices */
     1221
     1222fun_node_t *find_loc_tree_function(dev_tree_t *tree, service_id_t service_id)
    14231223{
    14241224        fun_node_t *fun = NULL;
    14251225        link_t *link;
    1426         unsigned long key = (unsigned long) devmap_handle;
     1226        unsigned long key = (unsigned long) service_id;
    14271227       
    14281228        fibril_rwlock_read_lock(&tree->rwlock);
    1429         link = hash_table_find(&tree->devmap_functions, &key);
     1229        link = hash_table_find(&tree->loc_functions, &key);
    14301230        if (link != NULL)
    1431                 fun = hash_table_get_instance(link, fun_node_t, devmap_fun);
     1231                fun = hash_table_get_instance(link, fun_node_t, loc_fun);
    14321232        fibril_rwlock_read_unlock(&tree->rwlock);
    14331233       
     
    14351235}
    14361236
    1437 fun_node_t *find_devmap_class_function(class_list_t *classes,
    1438     devmap_handle_t devmap_handle)
    1439 {
    1440         fun_node_t *fun = NULL;
    1441         dev_class_info_t *cli;
    1442         link_t *link;
    1443         unsigned long key = (unsigned long)devmap_handle;
    1444        
    1445         fibril_rwlock_read_lock(&classes->rwlock);
    1446         link = hash_table_find(&classes->devmap_functions, &key);
    1447         if (link != NULL) {
    1448                 cli = hash_table_get_instance(link, dev_class_info_t,
    1449                     devmap_link);
    1450                 fun = cli->fun;
    1451         }
    1452         fibril_rwlock_read_unlock(&classes->rwlock);
    1453        
    1454         return fun;
    1455 }
    1456 
    1457 void class_add_devmap_function(class_list_t *class_list, dev_class_info_t *cli)
    1458 {
    1459         unsigned long key = (unsigned long) cli->devmap_handle;
    1460        
    1461         fibril_rwlock_write_lock(&class_list->rwlock);
    1462         hash_table_insert(&class_list->devmap_functions, &key, &cli->devmap_link);
    1463         fibril_rwlock_write_unlock(&class_list->rwlock);
    1464 
    1465         assert(find_devmap_class_function(class_list, cli->devmap_handle) != NULL);
    1466 }
    1467 
    1468 void tree_add_devmap_function(dev_tree_t *tree, fun_node_t *fun)
    1469 {
    1470         unsigned long key = (unsigned long) fun->devmap_handle;
     1237void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun)
     1238{
     1239        unsigned long key = (unsigned long) fun->service_id;
    14711240        fibril_rwlock_write_lock(&tree->rwlock);
    1472         hash_table_insert(&tree->devmap_functions, &key, &fun->devmap_fun);
     1241        hash_table_insert(&tree->loc_functions, &key, &fun->loc_fun);
    14731242        fibril_rwlock_write_unlock(&tree->rwlock);
    14741243}
Note: See TracChangeset for help on using the changeset viewer.