Ignore:
File:
1 edited

Legend:

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

    rd0dd7b5 r4022513  
    3737#include <ipc/driver.h>
    3838#include <ipc/devman.h>
    39 #include <loc.h>
     39#include <devmap.h>
    4040#include <str_error.h>
    4141#include <stdio.h>
     
    6666}
    6767
    68 static int loc_functions_compare(unsigned long key[], hash_count_t keys,
     68static int devmap_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, loc_fun);
    72         return (fun->service_id == (service_id_t) key[0]);
     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
     75static 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]);
    7383}
    7484
     
    8999};
    90100
    91 static hash_table_operations_t loc_devices_ops = {
     101static hash_table_operations_t devmap_devices_ops = {
    92102        .hash = devices_hash,
    93         .compare = loc_functions_compare,
     103        .compare = devmap_functions_compare,
     104        .remove_callback = devices_remove_callback
     105};
     106
     107static hash_table_operations_t devmap_devices_class_ops = {
     108        .hash = devices_hash,
     109        .compare = devmap_devices_class_compare,
    94110        .remove_callback = devices_remove_callback
    95111};
     
    685701}
    686702
    687 /** Create loc path and name for the function. */
    688 void loc_register_tree_function(fun_node_t *fun, dev_tree_t *tree)
    689 {
    690         char *loc_pathname = NULL;
    691         char *loc_name = NULL;
    692        
    693         asprintf(&loc_name, "%s", fun->pathname);
    694         if (loc_name == NULL)
     703/** Create devmap path and name for the function. */
     704void 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)
    695711                return;
    696712       
    697         replace_char(loc_name, '/', LOC_SEPARATOR);
    698        
    699         asprintf(&loc_pathname, "%s/%s", LOC_DEVICE_NAMESPACE,
    700             loc_name);
    701         if (loc_pathname == NULL) {
    702                 free(loc_name);
     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);
    703719                return;
    704720        }
    705721       
    706         loc_service_register_with_iface(loc_pathname,
    707             &fun->service_id, DEVMAN_CONNECT_FROM_LOC);
    708        
    709         tree_add_loc_function(tree, fun);
    710        
    711         free(loc_name);
    712         free(loc_pathname);
     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);
    713729}
    714730
     
    840856        hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1,
    841857            &devman_functions_ops);
    842         hash_table_create(&tree->loc_functions, DEVICE_BUCKETS, 1,
    843             &loc_devices_ops);
     858        hash_table_create(&tree->devmap_functions, DEVICE_BUCKETS, 1,
     859            &devmap_devices_ops);
    844860       
    845861        fibril_rwlock_initialize(&tree->rwlock);
     
    934950                link_initialize(&res->dev_functions);
    935951                list_initialize(&res->match_ids.ids);
     952                list_initialize(&res->classes);
    936953                link_initialize(&res->devman_fun);
    937                 link_initialize(&res->loc_fun);
     954                link_initialize(&res->devmap_fun);
    938955        }
    939956       
     
    10981115       
    10991116        return true;
    1100 }
    1101 
    1102 /** Remove function from device tree.
    1103  *
    1104  * @param tree          Device tree
    1105  * @param node          Function node to remove
    1106  */
    1107 void remove_fun_node(dev_tree_t *tree, fun_node_t *fun)
    1108 {
    1109         assert(tree != NULL);
    1110         assert(fun != NULL);
    1111         assert(fibril_rwlock_is_write_locked(&tree->rwlock));
    1112        
    1113         /* Remove the node from the handle-to-node map. */
    1114         unsigned long key = fun->handle;
    1115         hash_table_remove(&tree->devman_functions, &key, 1);
    1116        
    1117         /* Remove the node from the list of its parent's children. */
    1118         if (fun->dev != NULL)
    1119                 list_remove(&fun->dev_functions);
    11201117}
    11211118
     
    11961193}
    11971194
     1195/** Find function node by its class name and index. */
     1196fun_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
    11981225/** Find child function node with a specified name.
    11991226 *
     
    12091236}
    12101237
    1211 /* loc devices */
    1212 
    1213 fun_node_t *find_loc_tree_function(dev_tree_t *tree, service_id_t service_id)
     1238/* Device classes */
     1239
     1240/** Create device class.
     1241 *
     1242 * @return      Device class.
     1243 */
     1244dev_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 */
     1262dev_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
     1277size_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 */
     1297char *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 */
     1326dev_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
     1356dev_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
     1375dev_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
     1390void 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
     1395dev_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
     1412void 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
     1423fun_node_t *find_devmap_tree_function(dev_tree_t *tree, devmap_handle_t devmap_handle)
    12141424{
    12151425        fun_node_t *fun = NULL;
    12161426        link_t *link;
    1217         unsigned long key = (unsigned long) service_id;
     1427        unsigned long key = (unsigned long) devmap_handle;
    12181428       
    12191429        fibril_rwlock_read_lock(&tree->rwlock);
    1220         link = hash_table_find(&tree->loc_functions, &key);
     1430        link = hash_table_find(&tree->devmap_functions, &key);
    12211431        if (link != NULL)
    1222                 fun = hash_table_get_instance(link, fun_node_t, loc_fun);
     1432                fun = hash_table_get_instance(link, fun_node_t, devmap_fun);
    12231433        fibril_rwlock_read_unlock(&tree->rwlock);
    12241434       
     
    12261436}
    12271437
    1228 void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun)
    1229 {
    1230         unsigned long key = (unsigned long) fun->service_id;
     1438fun_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
     1458void 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
     1469void tree_add_devmap_function(dev_tree_t *tree, fun_node_t *fun)
     1470{
     1471        unsigned long key = (unsigned long) fun->devmap_handle;
    12311472        fibril_rwlock_write_lock(&tree->rwlock);
    1232         hash_table_insert(&tree->loc_functions, &key, &fun->loc_fun);
     1473        hash_table_insert(&tree->devmap_functions, &key, &fun->devmap_fun);
    12331474        fibril_rwlock_write_unlock(&tree->rwlock);
    12341475}
Note: See TracChangeset for help on using the changeset viewer.