Ignore:
File:
1 edited

Legend:

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

    r4022513 r45059d6b  
    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};
     
    564548
    565549        fibril_mutex_lock(&driver->driver_mutex);
    566        
    567         async_exch_t *exch = async_exchange_begin(driver->sess);
    568         async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
    569             DRIVER_DEVMAN, 0, 0);
    570         async_exchange_end(exch);
    571 
    572         if (!sess) {
    573                 fibril_mutex_unlock(&driver->driver_mutex);
    574                 return;
    575         }
    576550
    577551        /*
     
    599573                fibril_mutex_unlock(&driver->driver_mutex);
    600574
    601                 add_device(sess, driver, dev, tree);
     575                add_device(driver, dev, tree);
    602576
    603577                /*
     
    619593                link = driver->devices.head.next;
    620594        }
    621 
    622         async_hangup(sess);
    623595
    624596        /*
     
    701673}
    702674
    703 /** Create devmap path and name for the function. */
    704 void devmap_register_tree_function(fun_node_t *fun, dev_tree_t *tree)
    705 {
    706         char *devmap_pathname = NULL;
    707         char *devmap_name = NULL;
    708        
    709         asprintf(&devmap_name, "%s", fun->pathname);
    710         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)
    711683                return;
    712684       
    713         replace_char(devmap_name, '/', DEVMAP_SEPARATOR);
    714        
    715         asprintf(&devmap_pathname, "%s/%s", DEVMAP_DEVICE_NAMESPACE,
    716             devmap_name);
    717         if (devmap_pathname == NULL) {
    718                 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);
    719691                return;
    720692        }
    721693       
    722         devmap_device_register_with_iface(devmap_pathname,
    723             &fun->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);
    724        
    725         tree_add_devmap_function(tree, fun);
    726        
    727         free(devmap_name);
    728         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);
    729701}
    730702
     
    734706 * @param node          The device's node in the device tree.
    735707 */
    736 void add_device(async_sess_t *sess, driver_t *drv, dev_node_t *dev,
    737     dev_tree_t *tree)
     708void add_device(driver_t *drv, dev_node_t *dev, dev_tree_t *tree)
    738709{
    739710        /*
     
    752723        }
    753724       
    754         async_exch_t *exch = async_exchange_begin(sess);
     725        async_exch_t *exch = async_exchange_begin(drv->sess);
    755726       
    756727        ipc_call_t answer;
     
    822793        fibril_mutex_unlock(&drv->driver_mutex);
    823794
    824         if (is_running) {
    825                 /* Notify the driver about the new device. */
    826                 async_exch_t *exch = async_exchange_begin(drv->sess);
    827                 async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
    828                     DRIVER_DEVMAN, 0, 0);
    829                 async_exchange_end(exch);
    830                
    831                 if (sess) {
    832                         add_device(sess, drv, dev, tree);
    833                         async_hangup(sess);
    834                 }
    835         }
     795        /* Notify the driver about the new device. */
     796        if (is_running)
     797                add_device(drv, dev, tree);
    836798       
    837799        return true;
     
    856818        hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1,
    857819            &devman_functions_ops);
    858         hash_table_create(&tree->devmap_functions, DEVICE_BUCKETS, 1,
    859             &devmap_devices_ops);
     820        hash_table_create(&tree->loc_functions, DEVICE_BUCKETS, 1,
     821            &loc_devices_ops);
    860822       
    861823        fibril_rwlock_initialize(&tree->rwlock);
     
    936898}
    937899
     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
    938931/* Function nodes */
    939932
     
    950943                link_initialize(&res->dev_functions);
    951944                list_initialize(&res->match_ids.ids);
    952                 list_initialize(&res->classes);
    953945                link_initialize(&res->devman_fun);
    954                 link_initialize(&res->devmap_fun);
     946                link_initialize(&res->loc_fun);
    955947        }
    956948       
     
    11151107       
    11161108        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);
    11171129}
    11181130
     
    11421154        char *rel_path = path;
    11431155        char *next_path_elem = NULL;
    1144         bool cont = true;
     1156        bool cont = (rel_path[1] != '\0');
    11451157       
    11461158        while (cont && fun != NULL) {
     
    11931205}
    11941206
    1195 /** Find function node by its class name and index. */
    1196 fun_node_t *find_fun_node_by_class(class_list_t *class_list,
    1197     const char *class_name, const char *dev_name)
    1198 {
    1199         assert(class_list != NULL);
    1200         assert(class_name != NULL);
    1201         assert(dev_name != NULL);
    1202 
    1203         fibril_rwlock_read_lock(&class_list->rwlock);
    1204 
    1205         dev_class_t *cl = find_dev_class_no_lock(class_list, class_name);
    1206         if (cl == NULL) {
    1207                 fibril_rwlock_read_unlock(&class_list->rwlock);
    1208                 return NULL;
    1209         }
    1210 
    1211         dev_class_info_t *dev = find_dev_in_class(cl, dev_name);
    1212         if (dev == NULL) {
    1213                 fibril_rwlock_read_unlock(&class_list->rwlock);
    1214                 return NULL;
    1215         }
    1216 
    1217         fun_node_t *fun = dev->fun;
    1218 
    1219         fibril_rwlock_read_unlock(&class_list->rwlock);
    1220 
    1221         return fun;
    1222 }
    1223 
    1224 
    12251207/** Find child function node with a specified name.
    12261208 *
     
    12361218}
    12371219
    1238 /* Device classes */
    1239 
    1240 /** Create device class.
    1241  *
    1242  * @return      Device class.
    1243  */
    1244 dev_class_t *create_dev_class(void)
    1245 {
    1246         dev_class_t *cl;
    1247        
    1248         cl = (dev_class_t *) malloc(sizeof(dev_class_t));
    1249         if (cl != NULL) {
    1250                 memset(cl, 0, sizeof(dev_class_t));
    1251                 list_initialize(&cl->devices);
    1252                 fibril_mutex_initialize(&cl->mutex);
    1253         }
    1254        
    1255         return cl;
    1256 }
    1257 
    1258 /** Create device class info.
    1259  *
    1260  * @return              Device class info.
    1261  */
    1262 dev_class_info_t *create_dev_class_info(void)
    1263 {
    1264         dev_class_info_t *info;
    1265        
    1266         info = (dev_class_info_t *) malloc(sizeof(dev_class_info_t));
    1267         if (info != NULL) {
    1268                 memset(info, 0, sizeof(dev_class_info_t));
    1269                 link_initialize(&info->dev_classes);
    1270                 link_initialize(&info->devmap_link);
    1271                 link_initialize(&info->link);
    1272         }
    1273        
    1274         return info;
    1275 }
    1276 
    1277 size_t get_new_class_dev_idx(dev_class_t *cl)
    1278 {
    1279         size_t dev_idx;
    1280        
    1281         fibril_mutex_lock(&cl->mutex);
    1282         dev_idx = ++cl->curr_dev_idx;
    1283         fibril_mutex_unlock(&cl->mutex);
    1284        
    1285         return dev_idx;
    1286 }
    1287 
    1288 
    1289 /** Create unique device name within the class.
    1290  *
    1291  * @param cl            The class.
    1292  * @param base_dev_name Contains the base name for the device if it was
    1293  *                      specified by the driver when it registered the device by
    1294  *                      the class; NULL if driver specified no base name.
    1295  * @return              The unique name for the device within the class.
    1296  */
    1297 char *create_dev_name_for_class(dev_class_t *cl, const char *base_dev_name)
    1298 {
    1299         char *dev_name;
    1300         const char *base_name;
    1301        
    1302         if (base_dev_name != NULL)
    1303                 base_name = base_dev_name;
    1304         else
    1305                 base_name = cl->base_dev_name;
    1306        
    1307         size_t idx = get_new_class_dev_idx(cl);
    1308         asprintf(&dev_name, "%s%zu", base_name, idx);
    1309        
    1310         return dev_name;
    1311 }
    1312 
    1313 /** Add the device function to the class.
    1314  *
    1315  * The device may be added to multiple classes and a class may contain multiple
    1316  * devices. The class and the device are associated with each other by the
    1317  * dev_class_info_t structure.
    1318  *
    1319  * @param dev           The device.
    1320  * @param class         The class.
    1321  * @param base_dev_name The base name of the device within the class if
    1322  *                      specified by the driver, NULL otherwise.
    1323  * @return              dev_class_info_t structure which associates the device
    1324  *                      with the class.
    1325  */
    1326 dev_class_info_t *add_function_to_class(fun_node_t *fun, dev_class_t *cl,
    1327     const char *base_dev_name)
    1328 {
    1329         dev_class_info_t *info;
    1330 
    1331         assert(fun != NULL);
    1332         assert(cl != NULL);
    1333 
    1334         info = create_dev_class_info();
    1335 
    1336        
    1337         if (info != NULL) {
    1338                 info->dev_class = cl;
    1339                 info->fun = fun;
    1340                
    1341                 /* Add the device to the class. */
    1342                 fibril_mutex_lock(&cl->mutex);
    1343                 list_append(&info->link, &cl->devices);
    1344                 fibril_mutex_unlock(&cl->mutex);
    1345                
    1346                 /* Add the class to the device. */
    1347                 list_append(&info->dev_classes, &fun->classes);
    1348                
    1349                 /* Create unique name for the device within the class. */
    1350                 info->dev_name = create_dev_name_for_class(cl, base_dev_name);
    1351         }
    1352        
    1353         return info;
    1354 }
    1355 
    1356 dev_class_t *get_dev_class(class_list_t *class_list, char *class_name)
    1357 {
    1358         dev_class_t *cl;
    1359        
    1360         fibril_rwlock_write_lock(&class_list->rwlock);
    1361         cl = find_dev_class_no_lock(class_list, class_name);
    1362         if (cl == NULL) {
    1363                 cl = create_dev_class();
    1364                 if (cl != NULL) {
    1365                         cl->name = class_name;
    1366                         cl->base_dev_name = "";
    1367                         add_dev_class_no_lock(class_list, cl);
    1368                 }
    1369         }
    1370 
    1371         fibril_rwlock_write_unlock(&class_list->rwlock);
    1372         return cl;
    1373 }
    1374 
    1375 dev_class_t *find_dev_class_no_lock(class_list_t *class_list,
    1376     const char *class_name)
    1377 {
    1378         dev_class_t *cl;
    1379        
    1380         list_foreach(class_list->classes, link) {
    1381                 cl = list_get_instance(link, dev_class_t, link);
    1382                 if (str_cmp(cl->name, class_name) == 0) {
    1383                         return cl;
    1384                 }
    1385         }
    1386        
    1387         return NULL;
    1388 }
    1389 
    1390 void add_dev_class_no_lock(class_list_t *class_list, dev_class_t *cl)
    1391 {
    1392         list_append(&cl->link, &class_list->classes);
    1393 }
    1394 
    1395 dev_class_info_t *find_dev_in_class(dev_class_t *dev_class, const char *dev_name)
    1396 {
    1397         assert(dev_class != NULL);
    1398         assert(dev_name != NULL);
    1399 
    1400         list_foreach(dev_class->devices, link) {
    1401                 dev_class_info_t *dev = list_get_instance(link,
    1402                     dev_class_info_t, link);
    1403 
    1404                 if (str_cmp(dev->dev_name, dev_name) == 0) {
    1405                         return dev;
    1406                 }
    1407         }
    1408 
    1409         return NULL;
    1410 }
    1411 
    1412 void init_class_list(class_list_t *class_list)
    1413 {
    1414         list_initialize(&class_list->classes);
    1415         fibril_rwlock_initialize(&class_list->rwlock);
    1416         hash_table_create(&class_list->devmap_functions, DEVICE_BUCKETS, 1,
    1417             &devmap_devices_class_ops);
    1418 }
    1419 
    1420 
    1421 /* Devmap devices */
    1422 
    1423 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)
    14241223{
    14251224        fun_node_t *fun = NULL;
    14261225        link_t *link;
    1427         unsigned long key = (unsigned long) devmap_handle;
     1226        unsigned long key = (unsigned long) service_id;
    14281227       
    14291228        fibril_rwlock_read_lock(&tree->rwlock);
    1430         link = hash_table_find(&tree->devmap_functions, &key);
     1229        link = hash_table_find(&tree->loc_functions, &key);
    14311230        if (link != NULL)
    1432                 fun = hash_table_get_instance(link, fun_node_t, devmap_fun);
     1231                fun = hash_table_get_instance(link, fun_node_t, loc_fun);
    14331232        fibril_rwlock_read_unlock(&tree->rwlock);
    14341233       
     
    14361235}
    14371236
    1438 fun_node_t *find_devmap_class_function(class_list_t *classes,
    1439     devmap_handle_t devmap_handle)
    1440 {
    1441         fun_node_t *fun = NULL;
    1442         dev_class_info_t *cli;
    1443         link_t *link;
    1444         unsigned long key = (unsigned long)devmap_handle;
    1445        
    1446         fibril_rwlock_read_lock(&classes->rwlock);
    1447         link = hash_table_find(&classes->devmap_functions, &key);
    1448         if (link != NULL) {
    1449                 cli = hash_table_get_instance(link, dev_class_info_t,
    1450                     devmap_link);
    1451                 fun = cli->fun;
    1452         }
    1453         fibril_rwlock_read_unlock(&classes->rwlock);
    1454        
    1455         return fun;
    1456 }
    1457 
    1458 void class_add_devmap_function(class_list_t *class_list, dev_class_info_t *cli)
    1459 {
    1460         unsigned long key = (unsigned long) cli->devmap_handle;
    1461        
    1462         fibril_rwlock_write_lock(&class_list->rwlock);
    1463         hash_table_insert(&class_list->devmap_functions, &key, &cli->devmap_link);
    1464         fibril_rwlock_write_unlock(&class_list->rwlock);
    1465 
    1466         assert(find_devmap_class_function(class_list, cli->devmap_handle) != NULL);
    1467 }
    1468 
    1469 void tree_add_devmap_function(dev_tree_t *tree, fun_node_t *fun)
    1470 {
    1471         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;
    14721240        fibril_rwlock_write_lock(&tree->rwlock);
    1473         hash_table_insert(&tree->devmap_functions, &key, &fun->devmap_fun);
     1241        hash_table_insert(&tree->loc_functions, &key, &fun->loc_fun);
    14741242        fibril_rwlock_write_unlock(&tree->rwlock);
    14751243}
Note: See TracChangeset for help on using the changeset viewer.