Changeset 07b39338 in mainline for uspace/srv


Ignore:
Timestamp:
2011-08-20T18:21:49Z (15 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6ab014d
Parents:
0cf27ee (diff), f00af83 (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 libposix.

Location:
uspace/srv
Files:
17 edited

Legend:

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

    r0cf27ee r07b39338  
    7373}
    7474
    75 static int loc_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, loc_link);
    80         assert(class_info != NULL);
    81 
    82         return (class_info->service_id == (service_id_t) key[0]);
    83 }
    84 
    8575static void devices_remove_callback(link_t *item)
    8676{
     
    10292        .hash = devices_hash,
    10393        .compare = loc_functions_compare,
    104         .remove_callback = devices_remove_callback
    105 };
    106 
    107 static hash_table_operations_t loc_devices_class_ops = {
    108         .hash = devices_hash,
    109         .compare = loc_devices_class_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        /*
     
    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;
     
    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);
    954946                link_initialize(&res->loc_fun);
     
    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 *
     
    12351217        return find_fun_node_in_device(pfun->child, name);
    12361218}
    1237 
    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->loc_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->loc_functions, DEVICE_BUCKETS, 1,
    1417             &loc_devices_class_ops);
    1418 }
    1419 
    14201219
    14211220/* loc devices */
     
    14361235}
    14371236
    1438 fun_node_t *find_loc_class_function(class_list_t *classes,
    1439     service_id_t service_id)
    1440 {
    1441         fun_node_t *fun = NULL;
    1442         dev_class_info_t *cli;
    1443         link_t *link;
    1444         unsigned long key = (unsigned long)service_id;
    1445        
    1446         fibril_rwlock_read_lock(&classes->rwlock);
    1447         link = hash_table_find(&classes->loc_functions, &key);
    1448         if (link != NULL) {
    1449                 cli = hash_table_get_instance(link, dev_class_info_t,
    1450                     loc_link);
    1451                 fun = cli->fun;
    1452         }
    1453         fibril_rwlock_read_unlock(&classes->rwlock);
    1454        
    1455         return fun;
    1456 }
    1457 
    1458 void class_add_loc_function(class_list_t *class_list, dev_class_info_t *cli)
    1459 {
    1460         unsigned long key = (unsigned long) cli->service_id;
    1461        
    1462         fibril_rwlock_write_lock(&class_list->rwlock);
    1463         hash_table_insert(&class_list->loc_functions, &key, &cli->loc_link);
    1464         fibril_rwlock_write_unlock(&class_list->rwlock);
    1465 
    1466         assert(find_loc_class_function(class_list, cli->service_id) != NULL);
    1467 }
    1468 
    14691237void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun)
    14701238{
  • uspace/srv/devman/devman.h

    r0cf27ee r07b39338  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    5354#define DEVICE_BUCKETS 256
    5455
    55 #define LOC_CLASS_NAMESPACE "class"
    5656#define LOC_DEVICE_NAMESPACE "devices"
    5757#define LOC_SEPARATOR '\\'
     
    155155        /** Name of the function, assigned by the device driver */
    156156        char *name;
     157        /** Function type */
     158        fun_type_t ftype;
    157159       
    158160        /** Full path and name of the device in device hierarchy */
     
    170172        match_id_list_t match_ids;
    171173       
    172         /** List of device classes to which this device function belongs. */
    173         list_t classes;
    174174        /** Service ID if the device function is registered with loc. */
    175175        service_id_t service_id;
     
    214214} dev_tree_t;
    215215
    216 typedef struct dev_class {
    217         /** The name of the class. */
    218         const char *name;
    219        
    220         /**
    221          * Pointer to the previous and next class in the list of registered
    222          * classes.
    223          */
    224         link_t link;
    225        
    226         /**
    227          * List of dev_class_info structures - one for each device registered by
    228          * this class.
    229          */
    230         list_t devices;
    231        
    232         /**
    233          * Default base name for the device within the class, might be overrided
    234          * by the driver.
    235          */
    236         const char *base_dev_name;
    237        
    238         /** Unique numerical identifier of the newly added device. */
    239         size_t curr_dev_idx;
    240         /** Synchronize access to the list of devices in this class. */
    241         fibril_mutex_t mutex;
    242 } dev_class_t;
    243 
    244 /**
    245  * Provides n-to-m mapping between function nodes and classes - each function
    246  * can register in an arbitrary number of classes and each class can contain
    247  * an arbitrary number of device functions.
    248  */
    249 typedef struct dev_class_info {
    250         /** The class. */
    251         dev_class_t *dev_class;
    252         /** The device. */
    253         fun_node_t *fun;
    254        
    255         /**
    256          * Pointer to the previous and next class info in the list of devices
    257          * registered by the class.
    258          */
    259         link_t link;
    260        
    261         /**
    262          * Pointer to the previous and next class info in the list of classes
    263          * by which the device is registered.
    264          */
    265         link_t dev_classes;
    266        
    267         /** The name of the device function within the class. */
    268         char *dev_name;
    269         /** Service ID in the class namespace. */
    270         service_id_t service_id;
    271        
    272         /**
    273          * Link to hash table of services registered with location service using
    274          * their class names.
    275          */
    276         link_t loc_link;
    277 } dev_class_info_t;
    278 
    279 /** The list of device classes. */
    280 typedef struct class_list {
    281         /** List of classes. */
    282         list_t classes;
    283        
    284         /**
    285          * Hash table of services registered with location service using their
    286          * class name, indexed by service IDs.
    287          */
    288         hash_table_t loc_functions;
    289        
    290         /** Fibril mutex for list of classes. */
    291         fibril_rwlock_t rwlock;
    292 } class_list_t;
    293 
    294216/* Match ids and scores */
    295217
     
    313235extern void add_driver(driver_list_t *, driver_t *);
    314236extern void attach_driver(dev_node_t *, driver_t *);
    315 extern void add_device(async_sess_t *, driver_t *, dev_node_t *, dev_tree_t *);
     237extern void add_device(driver_t *, dev_node_t *, dev_tree_t *);
    316238extern bool start_driver(driver_t *);
    317239
     
    331253extern dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle);
    332254extern dev_node_t *find_dev_function(dev_node_t *, const char *);
     255extern int dev_get_functions(dev_tree_t *tree, dev_node_t *, devman_handle_t *,
     256    size_t, size_t *);
    333257
    334258extern fun_node_t *create_fun_node(void);
     
    339263extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *);
    340264extern fun_node_t *find_fun_node_in_device(dev_node_t *, const char *);
    341 extern fun_node_t *find_fun_node_by_class(class_list_t *, const char *, const char *);
    342265
    343266/* Device tree */
     
    347270extern bool insert_dev_node(dev_tree_t *, dev_node_t *, fun_node_t *);
    348271extern bool insert_fun_node(dev_tree_t *, fun_node_t *, char *, dev_node_t *);
    349 
    350 /* Device classes */
    351 
    352 extern dev_class_t *create_dev_class(void);
    353 extern dev_class_info_t *create_dev_class_info(void);
    354 extern size_t get_new_class_dev_idx(dev_class_t *);
    355 extern char *create_dev_name_for_class(dev_class_t *, const char *);
    356 extern dev_class_info_t *add_function_to_class(fun_node_t *, dev_class_t *,
    357     const char *);
    358 
    359 extern void init_class_list(class_list_t *);
    360 
    361 extern dev_class_t *get_dev_class(class_list_t *, char *);
    362 extern dev_class_t *find_dev_class_no_lock(class_list_t *, const char *);
    363 extern dev_class_info_t *find_dev_in_class(dev_class_t *, const char *);
    364 extern void add_dev_class_no_lock(class_list_t *, dev_class_t *);
     272extern void remove_fun_node(dev_tree_t *, fun_node_t *);
    365273
    366274/* Loc services */
     
    369277
    370278extern fun_node_t *find_loc_tree_function(dev_tree_t *, service_id_t);
    371 extern fun_node_t *find_loc_class_function(class_list_t *, service_id_t);
    372 
    373 extern void class_add_loc_function(class_list_t *, dev_class_info_t *);
     279
    374280extern void tree_add_loc_function(dev_tree_t *, fun_node_t *);
    375281
  • uspace/srv/devman/main.c

    r0cf27ee r07b39338  
    6464static driver_list_t drivers_list;
    6565static dev_tree_t device_tree;
    66 static class_list_t class_list;
    6766
    6867/** Register running driver. */
     
    279278                return;
    280279        }
    281 
     280       
    282281        fun_node_t *fun = create_fun_node();
     282        fun->ftype = ftype;
     283       
    283284        if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) {
    284285                fibril_rwlock_write_unlock(&tree->rwlock);
     
    333334}
    334335
    335 static void loc_register_class_dev(dev_class_info_t *cli)
    336 {
    337         /* Create loc path and name for the service. */
    338         char *loc_pathname = NULL;
    339 
    340         asprintf(&loc_pathname, "%s/%s%c%s", LOC_CLASS_NAMESPACE,
    341             cli->dev_class->name, LOC_SEPARATOR, cli->dev_name);
    342         if (loc_pathname == NULL)
    343                 return;
    344        
    345         /*
    346          * Register the device with location service and remember its
    347          * service ID.
    348          */
    349         loc_service_register_with_iface(loc_pathname,
    350             &cli->service_id, DEVMAN_CONNECT_FROM_LOC);
    351        
    352         /*
    353          * Add device to the hash map of class devices registered with
    354          * location service.
    355          */
    356         class_add_loc_function(&class_list, cli);
    357        
    358         free(loc_pathname);
    359 }
    360 
    361 static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call)
     336static void devman_add_function_to_cat(ipc_callid_t callid, ipc_call_t *call)
    362337{
    363338        devman_handle_t handle = IPC_GET_ARG1(*call);
     
    365340        int rc;
    366341       
    367         /* Get class name. */
    368         char *class_name;
    369         rc = async_data_write_accept((void **) &class_name, true,
     342        /* Get category name. */
     343        char *cat_name;
     344        rc = async_data_write_accept((void **) &cat_name, true,
    370345            0, 0, 0, 0);
    371346        if (rc != EOK) {
     
    380355        }
    381356       
    382         dev_class_t *cl = get_dev_class(&class_list, class_name);
    383         dev_class_info_t *class_info = add_function_to_class(fun, cl, NULL);
    384        
    385         /* Register the device's class alias with location service. */
    386         loc_register_class_dev(class_info);
    387        
    388         rc = loc_category_get_id(class_name, &cat_id, IPC_FLAG_BLOCKING);
     357        rc = loc_category_get_id(cat_name, &cat_id, IPC_FLAG_BLOCKING);
    389358        if (rc == EOK) {
    390359                loc_service_add_to_cat(fun->service_id, cat_id);
    391360        } else {
    392361                log_msg(LVL_ERROR, "Failed adding function `%s' to category "
    393                     "`%s'.", fun->pathname, class_name);
    394         }
    395        
    396         log_msg(LVL_NOTE, "Function `%s' added to class `%s' as `%s'.",
    397             fun->pathname, class_name, class_info->dev_name);
    398 
     362                    "`%s'.", fun->pathname, cat_name);
     363        }
     364       
     365        log_msg(LVL_NOTE, "Function `%s' added to category `%s'.",
     366            fun->pathname, cat_name);
     367
     368        async_answer_0(callid, EOK);
     369}
     370
     371/** Remove function. */
     372static void devman_remove_function(ipc_callid_t callid, ipc_call_t *call)
     373{
     374        devman_handle_t fun_handle = IPC_GET_ARG1(*call);
     375        dev_tree_t *tree = &device_tree;
     376        int rc;
     377       
     378        fibril_rwlock_write_lock(&tree->rwlock);
     379       
     380        fun_node_t *fun = find_fun_node_no_lock(&device_tree, fun_handle);
     381        if (fun == NULL) {
     382                fibril_rwlock_write_unlock(&tree->rwlock);
     383                async_answer_0(callid, ENOENT);
     384                return;
     385        }
     386       
     387        log_msg(LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname);
     388       
     389        if (fun->ftype == fun_inner) {
     390                /* Handle possible descendants */
     391                /* TODO */
     392                log_msg(LVL_WARN, "devman_remove_function(): not handling "
     393                    "descendants\n");
     394        } else {
     395                /* Unregister from location service */
     396                rc = loc_service_unregister(fun->service_id);
     397                if (rc != EOK) {
     398                        log_msg(LVL_ERROR, "Failed unregistering tree service.");
     399                        fibril_rwlock_write_unlock(&tree->rwlock);
     400                        async_answer_0(callid, EIO);
     401                        return;
     402                }
     403        }
     404       
     405        remove_fun_node(&device_tree, fun);
     406        fibril_rwlock_write_unlock(&tree->rwlock);
     407        delete_fun_node(fun);
     408       
     409        log_msg(LVL_DEBUG, "devman_remove_function() succeeded.");
    399410        async_answer_0(callid, EOK);
    400411}
     
    449460                        devman_add_function(callid, &call);
    450461                        break;
    451                 case DEVMAN_ADD_DEVICE_TO_CLASS:
    452                         devman_add_function_to_class(callid, &call);
     462                case DEVMAN_ADD_DEVICE_TO_CATEGORY:
     463                        devman_add_function_to_cat(callid, &call);
     464                        break;
     465                case DEVMAN_REMOVE_FUNCTION:
     466                        devman_remove_function(callid, &call);
    453467                        break;
    454468                default:
     
    483497}
    484498
    485 /** Find handle for the device instance identified by device class name. */
    486 static void devman_function_get_handle_by_class(ipc_callid_t iid,
    487     ipc_call_t *icall)
    488 {
    489         char *classname;
    490         char *devname;
    491 
    492         int rc = async_data_write_accept((void **) &classname, true, 0, 0, 0, 0);
    493         if (rc != EOK) {
    494                 async_answer_0(iid, rc);
    495                 return;
    496         }
    497         rc = async_data_write_accept((void **) &devname, true, 0, 0, 0, 0);
    498         if (rc != EOK) {
    499                 free(classname);
    500                 async_answer_0(iid, rc);
    501                 return;
    502         }
    503 
    504 
    505         fun_node_t *fun = find_fun_node_by_class(&class_list,
    506             classname, devname);
    507 
    508         free(classname);
    509         free(devname);
    510 
    511         if (fun == NULL) {
    512                 async_answer_0(iid, ENOENT);
    513                 return;
    514         }
    515 
    516         async_answer_1(iid, EOK, fun->handle);
    517 }
    518 
    519 /** Find device path by its handle. */
    520 static void devman_get_device_path_by_handle(ipc_callid_t iid,
    521     ipc_call_t *icall)
     499/** Get device name. */
     500static void devman_fun_get_name(ipc_callid_t iid, ipc_call_t *icall)
    522501{
    523502        devman_handle_t handle = IPC_GET_ARG1(*icall);
     
    543522        }
    544523
     524        size_t sent_length = str_size(fun->name);
     525        if (sent_length > data_len) {
     526                sent_length = data_len;
     527        }
     528
     529        async_data_read_finalize(data_callid, fun->name, sent_length);
     530        async_answer_0(iid, EOK);
     531
     532        free(buffer);
     533}
     534
     535
     536/** Get device path. */
     537static void devman_fun_get_path(ipc_callid_t iid, ipc_call_t *icall)
     538{
     539        devman_handle_t handle = IPC_GET_ARG1(*icall);
     540
     541        fun_node_t *fun = find_fun_node(&device_tree, handle);
     542        if (fun == NULL) {
     543                async_answer_0(iid, ENOMEM);
     544                return;
     545        }
     546
     547        ipc_callid_t data_callid;
     548        size_t data_len;
     549        if (!async_data_read_receive(&data_callid, &data_len)) {
     550                async_answer_0(iid, EINVAL);
     551                return;
     552        }
     553
     554        void *buffer = malloc(data_len);
     555        if (buffer == NULL) {
     556                async_answer_0(data_callid, ENOMEM);
     557                async_answer_0(iid, ENOMEM);
     558                return;
     559        }
     560
    545561        size_t sent_length = str_size(fun->pathname);
    546562        if (sent_length > data_len) {
     
    554570}
    555571
     572static void devman_dev_get_functions(ipc_callid_t iid, ipc_call_t *icall)
     573{
     574        ipc_callid_t callid;
     575        size_t size;
     576        size_t act_size;
     577        int rc;
     578       
     579        if (!async_data_read_receive(&callid, &size)) {
     580                async_answer_0(callid, EREFUSED);
     581                async_answer_0(iid, EREFUSED);
     582                return;
     583        }
     584       
     585        fibril_rwlock_read_lock(&device_tree.rwlock);
     586       
     587        dev_node_t *dev = find_dev_node_no_lock(&device_tree,
     588            IPC_GET_ARG1(*icall));
     589        if (dev == NULL) {
     590                fibril_rwlock_read_unlock(&device_tree.rwlock);
     591                async_answer_0(callid, ENOENT);
     592                async_answer_0(iid, ENOENT);
     593                return;
     594        }
     595       
     596        devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
     597        if (hdl_buf == NULL) {
     598                fibril_rwlock_read_unlock(&device_tree.rwlock);
     599                async_answer_0(callid, ENOMEM);
     600                async_answer_0(iid, ENOMEM);
     601                return;
     602        }
     603       
     604        rc = dev_get_functions(&device_tree, dev, hdl_buf, size, &act_size);
     605        if (rc != EOK) {
     606                fibril_rwlock_read_unlock(&device_tree.rwlock);
     607                async_answer_0(callid, rc);
     608                async_answer_0(iid, rc);
     609                return;
     610        }
     611       
     612        fibril_rwlock_read_unlock(&device_tree.rwlock);
     613       
     614        sysarg_t retval = async_data_read_finalize(callid, hdl_buf, size);
     615        free(hdl_buf);
     616       
     617        async_answer_1(iid, retval, act_size);
     618}
     619
     620
     621/** Get handle for child device of a function. */
     622static void devman_fun_get_child(ipc_callid_t iid, ipc_call_t *icall)
     623{
     624        fun_node_t *fun;
     625       
     626        fibril_rwlock_read_lock(&device_tree.rwlock);
     627       
     628        fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
     629        if (fun == NULL) {
     630                fibril_rwlock_read_unlock(&device_tree.rwlock);
     631                async_answer_0(iid, ENOENT);
     632                return;
     633        }
     634       
     635        if (fun->child == NULL) {
     636                fibril_rwlock_read_unlock(&device_tree.rwlock);
     637                async_answer_0(iid, ENOENT);
     638                return;
     639        }
     640       
     641        async_answer_1(iid, EOK, fun->child->handle);
     642       
     643        fibril_rwlock_read_unlock(&device_tree.rwlock);
     644}
     645
     646/** Find handle for the function instance identified by its service ID. */
     647static void devman_fun_sid_to_handle(ipc_callid_t iid, ipc_call_t *icall)
     648{
     649        fun_node_t *fun;
     650
     651        fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall));
     652       
     653        if (fun == NULL) {
     654                async_answer_0(iid, ENOENT);
     655                return;
     656        }
     657
     658        async_answer_1(iid, EOK, fun->handle);
     659}
    556660
    557661/** Function for handling connections from a client to the device manager. */
     
    572676                        devman_function_get_handle(callid, &call);
    573677                        break;
    574                 case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS:
    575                         devman_function_get_handle_by_class(callid, &call);
    576                         break;
    577                 case DEVMAN_DEVICE_GET_DEVICE_PATH:
    578                         devman_get_device_path_by_handle(callid, &call);
     678                case DEVMAN_DEV_GET_FUNCTIONS:
     679                        devman_dev_get_functions(callid, &call);
     680                        break;
     681                case DEVMAN_FUN_GET_CHILD:
     682                        devman_fun_get_child(callid, &call);
     683                        break;
     684                case DEVMAN_FUN_GET_NAME:
     685                        devman_fun_get_name(callid, &call);
     686                        break;
     687                case DEVMAN_FUN_GET_PATH:
     688                        devman_fun_get_path(callid, &call);
     689                        break;
     690                case DEVMAN_FUN_SID_TO_HANDLE:
     691                        devman_fun_sid_to_handle(callid, &call);
    579692                        break;
    580693                default:
     
    678791
    679792        fun = find_loc_tree_function(&device_tree, service_id);
    680         if (fun == NULL)
    681                 fun = find_loc_class_function(&class_list, service_id);
    682793       
    683794        if (fun == NULL || fun->dev->drv == NULL) {
     795                log_msg(LVL_WARN, "devman_connection_loc(): function "
     796                    "not found.\n");
    684797                async_answer_0(iid, ENOENT);
    685798                return;
     
    687800       
    688801        dev = fun->dev;
    689        
    690         if ((dev->state != DEVICE_USABLE) || (!dev->drv->sess)) {
    691                 async_answer_0(iid, EINVAL);
    692                 return;
    693         }
    694802       
    695803        async_exch_t *exch = async_exchange_begin(dev->drv->sess);
     
    753861        }
    754862
    755         init_class_list(&class_list);
    756        
    757863        /*
    758864         * !!! devman_connection ... as the device manager is not a real loc
  • uspace/srv/hid/input/generic/input.c

    r0cf27ee r07b39338  
    6666#include <abi/ipc/methods.h>
    6767
    68 /* In microseconds */
    69 #define DISCOVERY_POLL_INTERVAL  (10 * 1000 * 1000)
    70 
    7168#define NUM_LAYOUTS  3
    7269
     
    497494}
    498495
    499 /** Periodically check for new input devices.
    500  *
    501  * Looks under /loc/class/keyboard and /loc/class/mouse.
    502  *
    503  * @param arg Ignored
    504  *
    505  */
    506 static int dev_discovery_fibril(void *arg)
    507 {
    508         category_id_t keyboard_cat, mouse_cat;
     496static int dev_check_new_kbdevs(void)
     497{
     498        category_id_t keyboard_cat;
    509499        service_id_t *svcs;
    510500        size_t count, i;
     
    518508        }
    519509       
     510        /*
     511         * Check for new keyboard devices
     512         */
     513        rc = loc_category_get_svcs(keyboard_cat, &svcs, &count);
     514        if (rc != EOK) {
     515                printf("%s: Failed getting list of keyboard devices.\n",
     516                    NAME);
     517                return EIO;
     518        }
     519
     520        for (i = 0; i < count; i++) {
     521                already_known = false;
     522               
     523                /* Determine whether we already know this device. */
     524                list_foreach(kbd_devs, kdev_link) {
     525                        kbd_dev_t *kdev = list_get_instance(kdev_link,
     526                            kbd_dev_t, kbd_devs);
     527                        if (kdev->svc_id == svcs[i]) {
     528                                already_known = true;
     529                                break;
     530                        }
     531                }
     532               
     533                if (!already_known) {
     534                        kbd_dev_t *kdev;
     535                        if (kbd_add_kbdev(svcs[i], &kdev) == EOK) {
     536                                printf("%s: Connected keyboard device '%s'\n",
     537                                    NAME, kdev->svc_name);
     538                        }
     539                }
     540        }
     541       
     542        free(svcs);
     543       
     544        /* XXX Handle device removal */
     545       
     546        return EOK;
     547}
     548
     549static int dev_check_new_mousedevs(void)
     550{
     551        category_id_t mouse_cat;
     552        service_id_t *svcs;
     553        size_t count, i;
     554        bool already_known;
     555        int rc;
     556       
    520557        rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING);
    521558        if (rc != EOK) {
     
    524561        }
    525562       
    526         while (true) {
    527                 async_usleep(DISCOVERY_POLL_INTERVAL);
    528                
    529                 /*
    530                  * Check for new keyboard devices
    531                  */
    532                 rc = loc_category_get_svcs(keyboard_cat, &svcs, &count);
    533                 if (rc != EOK) {
    534                         printf("%s: Failed getting list of keyboard devices.\n",
    535                             NAME);
    536                         continue;
    537                 }
    538 
    539                 for (i = 0; i < count; i++) {
    540                         already_known = false;
    541                        
    542                         /* Determine whether we already know this device. */
    543                         list_foreach(kbd_devs, kdev_link) {
    544                                 kbd_dev_t *kdev = list_get_instance(kdev_link,
    545                                     kbd_dev_t, kbd_devs);
    546                                 if (kdev->svc_id == svcs[i]) {
    547                                         already_known = true;
    548                                         break;
    549                                 }
    550                         }
    551 
    552                         if (!already_known) {
    553                                 kbd_dev_t *kdev;
    554                                 if (kbd_add_kbdev(svcs[i], &kdev) == EOK) {
    555                                         printf("%s: Connected keyboard device '%s'\n",
    556                                             NAME, kdev->svc_name);
    557                                 }
     563        /*
     564         * Check for new mouse devices
     565         */
     566        rc = loc_category_get_svcs(mouse_cat, &svcs, &count);
     567        if (rc != EOK) {
     568                printf("%s: Failed getting list of mouse devices.\n",
     569                    NAME);
     570                return EIO;
     571        }
     572       
     573        for (i = 0; i < count; i++) {
     574                already_known = false;
     575               
     576                /* Determine whether we already know this device. */
     577                list_foreach(mouse_devs, mdev_link) {
     578                        mouse_dev_t *mdev = list_get_instance(mdev_link,
     579                            mouse_dev_t, mouse_devs);
     580                        if (mdev->svc_id == svcs[i]) {
     581                                already_known = true;
     582                                break;
    558583                        }
    559584                }
    560585               
    561                 /* XXX Handle device removal */
    562                
    563                 /*
    564                  * Check for new mouse devices
    565                  */
    566                 rc = loc_category_get_svcs(mouse_cat, &svcs, &count);
    567                 if (rc != EOK) {
    568                         printf("%s: Failed getting list of mouse devices.\n",
    569                             NAME);
    570                         continue;
    571                 }
    572 
    573                 for (i = 0; i < count; i++) {
    574                         already_known = false;
    575                        
    576                         /* Determine whether we already know this device. */
    577                         list_foreach(mouse_devs, mdev_link) {
    578                                 mouse_dev_t *mdev = list_get_instance(mdev_link,
    579                                     mouse_dev_t, mouse_devs);
    580                                 if (mdev->svc_id == svcs[i]) {
    581                                         already_known = true;
    582                                         break;
    583                                 }
    584                         }
    585 
    586                         if (!already_known) {
    587                                 mouse_dev_t *mdev;
    588                                 if (mouse_add_mousedev(svcs[i], &mdev) == EOK) {
    589                                         printf("%s: Connected mouse device '%s'\n",
    590                                             NAME, mdev->svc_name);
    591                                 }
     586                if (!already_known) {
     587                        mouse_dev_t *mdev;
     588                        if (mouse_add_mousedev(svcs[i], &mdev) == EOK) {
     589                                printf("%s: Connected mouse device '%s'\n",
     590                                    NAME, mdev->svc_name);
    592591                        }
    593592                }
    594                
    595                 /* XXX Handle device removal */
    596         }
     593        }
     594       
     595        free(svcs);
     596       
     597        /* XXX Handle device removal */
    597598       
    598599        return EOK;
    599600}
    600601
    601 /** Start a fibril for discovering new devices. */
    602 static void input_start_dev_discovery(void)
    603 {
    604         fid_t fid = fibril_create(dev_discovery_fibril, NULL);
    605         if (!fid) {
    606                 printf("%s: Failed to create device discovery fibril.\n",
    607                     NAME);
    608                 return;
    609         }
    610        
    611         fibril_add_ready(fid);
     602static int dev_check_new(void)
     603{
     604        int rc;
     605       
     606        rc = dev_check_new_kbdevs();
     607        if (rc != EOK)
     608                return rc;
     609       
     610        rc = dev_check_new_mousedevs();
     611        if (rc != EOK)
     612                return rc;
     613
     614        return EOK;
     615}
     616
     617static void cat_change_cb(void)
     618{
     619        dev_check_new();
     620}
     621
     622/** Start listening for new devices. */
     623static int input_start_dev_discovery(void)
     624{
     625        int rc;
     626
     627        rc = loc_register_cat_change_cb(cat_change_cb);
     628        if (rc != EOK) {
     629                printf("%s: Failed registering callback for device discovery. "
     630                    "(%d)\n", NAME, rc);
     631                return rc;
     632        }
     633
     634        return dev_check_new();
    612635}
    613636
  • uspace/srv/hid/input/port/adb_mouse.c

    r0cf27ee r07b39338  
    4242#include <errno.h>
    4343#include <loc.h>
     44#include <stdio.h>
    4445
    4546static mouse_dev_t *mouse_dev;
  • uspace/srv/hw/irc/apic/apic.c

    r0cf27ee r07b39338  
    4545#include <errno.h>
    4646#include <async.h>
     47#include <stdio.h>
    4748
    4849#define NAME  "apic"
  • uspace/srv/loader/main.c

    r0cf27ee r07b39338  
    6161#include <elf/elf.h>
    6262#include <elf/elf_load.h>
     63#include <vfs/vfs.h>
    6364
    6465#ifdef CONFIG_RTLD
     
    8990
    9091/** Number of preset files */
    91 static int filc = 0;
    92 /** Preset files vector */
    93 static fdi_node_t **filv = NULL;
    94 /** Buffer holding all preset files */
    95 static fdi_node_t *fil_buf = NULL;
     92static unsigned int filc = 0;
    9693
    9794static elf_info_t prog_info;
     
    239236static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
    240237{
    241         fdi_node_t *buf;
    242         size_t buf_size;
    243         int rc = async_data_write_accept((void **) &buf, false, 0, 0,
    244             sizeof(fdi_node_t), &buf_size);
    245        
    246         if (rc == EOK) {
    247                 int count = buf_size / sizeof(fdi_node_t);
    248                
    249                 /*
    250                  * Allocate new filv
    251                  */
    252                 fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *));
    253                 if (_filv == NULL) {
    254                         free(buf);
    255                         async_answer_0(rid, ENOMEM);
    256                         return;
     238        size_t count = IPC_GET_ARG1(*request);
     239
     240        async_exch_t *vfs_exch = vfs_exchange_begin();
     241
     242        for (filc = 0; filc < count; filc++) {
     243                ipc_callid_t callid;
     244                int fd;
     245
     246                if (!async_state_change_receive(&callid, NULL, NULL, NULL)) {
     247                        async_answer_0(callid, EINVAL);
     248                        break;
    257249                }
    258                
    259                 /*
    260                  * Fill the new filv with argument pointers
    261                  */
    262                 int i;
    263                 for (i = 0; i < count; i++)
    264                         _filv[i] = &buf[i];
    265                
    266                 _filv[count] = NULL;
    267                
    268                 /*
    269                  * Copy temporary data to global variables
    270                  */
    271                 if (fil_buf != NULL)
    272                         free(fil_buf);
    273                
    274                 if (filv != NULL)
    275                         free(filv);
    276                
    277                 filc = count;
    278                 fil_buf = buf;
    279                 filv = _filv;
    280         }
    281        
     250                async_state_change_finalize(callid, vfs_exch);
     251                fd = fd_wait();
     252                assert(fd == (int) filc);
     253        }
     254
     255        vfs_exchange_end(vfs_exch);
     256
    282257        async_answer_0(rid, EOK);
    283258}
     
    308283       
    309284        pcb.filc = filc;
    310         pcb.filv = filv;
    311285       
    312286        if (prog_info.interp == NULL) {
  • uspace/srv/loc/category.c

    r0cf27ee r07b39338  
    9393        cat->id = loc_create_id();
    9494        link_initialize(&cat->cat_list);
    95         list_initialize(&cat->services);
     95        list_initialize(&cat->svc_memb);
    9696}
    9797
     
    113113{
    114114        assert(fibril_mutex_is_locked(&cat->mutex));
     115        assert(fibril_mutex_is_locked(&services_list_mutex));
    115116
    116117        /* Verify that category does not contain this service yet. */
    117         list_foreach(cat->services, item) {
    118 
    119                 loc_service_t *csvc = list_get_instance(item, loc_service_t,
    120                     cat_services);
    121                 if (csvc == svc) {
     118        list_foreach(cat->svc_memb, item) {
     119                svc_categ_t *memb = list_get_instance(item, svc_categ_t,
     120                    cat_link);
     121                if (memb->svc == svc) {
    122122                        return EEXIST;
    123123                }
    124124        }
    125125
    126         list_append(&svc->cat_services, &cat->services);
     126        svc_categ_t *nmemb = malloc(sizeof(svc_categ_t));
     127        if (nmemb == NULL)
     128                return ENOMEM;
     129
     130        nmemb->svc = svc;
     131        nmemb->cat = cat;
     132
     133        list_append(&nmemb->cat_link, &cat->svc_memb);
     134        list_append(&nmemb->svc_link, &svc->cat_memb);
     135
    127136        return EOK;
     137}
     138
     139/** Remove service from category. */
     140void category_remove_service(svc_categ_t *memb)
     141{
     142        assert(fibril_mutex_is_locked(&memb->cat->mutex));
     143        assert(fibril_mutex_is_locked(&services_list_mutex));
     144
     145        list_remove(&memb->cat_link);
     146        list_remove(&memb->svc_link);
     147
     148        free(memb);
    128149}
    129150
     
    169190        buf_cnt = buf_size / sizeof(service_id_t);
    170191
    171         act_cnt = list_count(&cat->services);
     192        act_cnt = list_count(&cat->svc_memb);
    172193        *act_size = act_cnt * sizeof(service_id_t);
    173194
     
    176197
    177198        size_t pos = 0;
    178         list_foreach(cat->services, item) {
    179                 loc_service_t *svc =
    180                     list_get_instance(item, loc_service_t, cat_services);
     199        list_foreach(cat->svc_memb, item) {
     200                svc_categ_t *memb =
     201                    list_get_instance(item, svc_categ_t, cat_link);
    181202
    182203                if (pos < buf_cnt)
    183                         id_buf[pos] = svc->id;
     204                        id_buf[pos] = memb->svc->id;
    184205                pos++;
    185206        }
  • uspace/srv/loc/category.h

    r0cf27ee r07b39338  
    5555        link_t cat_list;
    5656
    57         /** List of services in this category (loc_service_t) */
    58         list_t services;
     57        /** List of service memberships in this category (svc_categ_t) */
     58        list_t svc_memb;
    5959} category_t;
    6060
     
    6767} categ_dir_t;
    6868
     69/** Service in category membership. */
     70typedef struct {
     71        /** Link to category_t.svc_memb list */
     72        link_t cat_link;
     73        /** Link to loc_service_t.cat_memb list */
     74        link_t svc_link;
     75       
     76        /** Category */
     77        category_t *cat;
     78        /** Service */
     79        loc_service_t *svc;
     80} svc_categ_t;
     81
    6982extern void categ_dir_init(categ_dir_t *);
    7083extern void categ_dir_add_cat(categ_dir_t *, category_t *);
     
    7386extern category_t *category_new(const char *);
    7487extern int category_add_service(category_t *, loc_service_t *);
     88extern void category_remove_service(svc_categ_t *);
    7589extern category_t *category_get(categ_dir_t *, catid_t);
    7690extern category_t *category_find_by_name(categ_dir_t *, const char *);
  • uspace/srv/loc/loc.c

    r0cf27ee r07b39338  
    6767 **/
    6868
    69 static FIBRIL_MUTEX_INITIALIZE(services_list_mutex);
     69FIBRIL_MUTEX_INITIALIZE(services_list_mutex);
    7070static FIBRIL_CONDVAR_INITIALIZE(services_list_cv);
    7171static FIBRIL_MUTEX_INITIALIZE(servers_list_mutex);
     
    8484/** Service directory ogranized by categories (yellow pages) */
    8585static categ_dir_t cdir;
     86
     87static FIBRIL_MUTEX_INITIALIZE(callback_sess_mutex);
     88static async_sess_t *callback_sess = NULL;
    8689
    8790service_id_t loc_create_id(void)
     
    308311{
    309312        assert(fibril_mutex_is_locked(&services_list_mutex));
    310 
     313        assert(fibril_mutex_is_locked(&cdir.mutex));
     314       
    311315        loc_namespace_delref(service->namespace);
    312316        list_remove(&(service->services));
    313317        list_remove(&(service->server_services));
     318       
     319        /* Remove service from all categories. */
     320        while (!list_empty(&service->cat_memb)) {
     321                link_t *link = list_first(&service->cat_memb);
     322                svc_categ_t *memb = list_get_instance(link, svc_categ_t,
     323                    svc_link);
     324                fibril_mutex_lock(&memb->cat->mutex);
     325                category_remove_service(memb);
     326                fibril_mutex_unlock(&memb->cat->mutex);
     327        }
    314328       
    315329        free(service->name);
     
    412426        fibril_mutex_lock(&services_list_mutex);
    413427        fibril_mutex_lock(&server->services_mutex);
     428        fibril_mutex_lock(&cdir.mutex);
    414429       
    415430        while (!list_empty(&server->services)) {
     
    420435        }
    421436       
     437        fibril_mutex_unlock(&cdir.mutex);
    422438        fibril_mutex_unlock(&server->services_mutex);
    423439        fibril_mutex_unlock(&services_list_mutex);
     
    489505        link_initialize(&service->services);
    490506        link_initialize(&service->server_services);
     507        list_initialize(&service->cat_memb);
    491508       
    492509        /* Check that service is not already registered */
     
    526543 *
    527544 */
    528 static int loc_service_unregister(ipc_callid_t iid, ipc_call_t *icall,
     545static void loc_service_unregister(ipc_callid_t iid, ipc_call_t *icall,
    529546    loc_server_t *server)
    530547{
    531         /* TODO */
    532         return EOK;
     548        loc_service_t *svc;
     549       
     550        fibril_mutex_lock(&services_list_mutex);
     551        svc = loc_service_find_id(IPC_GET_ARG1(*icall));
     552        if (svc == NULL) {
     553                fibril_mutex_unlock(&services_list_mutex);
     554                async_answer_0(iid, ENOENT);
     555                return;
     556        }
     557       
     558        fibril_mutex_lock(&cdir.mutex);
     559        loc_service_unregister_core(svc);
     560        fibril_mutex_unlock(&cdir.mutex);
     561        fibril_mutex_unlock(&services_list_mutex);
     562        async_answer_0(iid, EOK);
     563}
     564
     565static void loc_category_get_name(ipc_callid_t iid, ipc_call_t *icall)
     566{
     567        ipc_callid_t callid;
     568        size_t size;
     569        size_t act_size;
     570        category_t *cat;
     571       
     572        if (!async_data_read_receive(&callid, &size)) {
     573                async_answer_0(callid, EREFUSED);
     574                async_answer_0(iid, EREFUSED);
     575                return;
     576        }
     577       
     578        fibril_mutex_lock(&cdir.mutex);
     579       
     580        cat = category_get(&cdir, IPC_GET_ARG1(*icall));
     581        if (cat == NULL) {
     582                fibril_mutex_unlock(&cdir.mutex);
     583                async_answer_0(callid, ENOENT);
     584                async_answer_0(iid, ENOENT);
     585                return;
     586        }
     587       
     588        act_size = str_size(cat->name);
     589        if (act_size > size) {
     590                fibril_mutex_unlock(&cdir.mutex);
     591                async_answer_0(callid, EOVERFLOW);
     592                async_answer_0(iid, EOVERFLOW);
     593                return;
     594        }
     595       
     596        sysarg_t retval = async_data_read_finalize(callid, cat->name,
     597            min(size, act_size));
     598       
     599        fibril_mutex_unlock(&cdir.mutex);
     600       
     601        async_answer_0(iid, retval);
    533602}
    534603
     
    571640        async_answer_0(iid, retval);
    572641}
    573 
    574642
    575643/** Connect client to the service.
     
    728796 *
    729797 */
     798static void loc_callback_create(ipc_callid_t iid, ipc_call_t *icall)
     799{
     800        async_sess_t *cb_sess = async_callback_receive(EXCHANGE_SERIALIZE);
     801        if (cb_sess == NULL) {
     802                async_answer_0(iid, ENOMEM);
     803                return;
     804        }
     805       
     806        fibril_mutex_lock(&callback_sess_mutex);
     807        if (callback_sess != NULL) {
     808                fibril_mutex_unlock(&callback_sess_mutex);
     809                async_answer_0(iid, EEXIST);
     810                return;
     811        }
     812       
     813        callback_sess = cb_sess;
     814        fibril_mutex_unlock(&callback_sess_mutex);
     815       
     816        async_answer_0(iid, EOK);
     817}
     818
     819void loc_category_change_event(void)
     820{
     821        fibril_mutex_lock(&callback_sess_mutex);
     822
     823        if (callback_sess != NULL) {
     824                async_exch_t *exch = async_exchange_begin(callback_sess);
     825                async_msg_0(exch, LOC_EVENT_CAT_CHANGE);
     826                async_exchange_end(exch);
     827        }
     828
     829        fibril_mutex_unlock(&callback_sess_mutex);
     830}
     831
     832/** Find ID for category specified by name.
     833 *
     834 * On success, answer will contain EOK int retval and service ID in arg1.
     835 * On failure, error code will be sent in retval.
     836 *
     837 */
    730838static void loc_category_get_id(ipc_callid_t iid, ipc_call_t *icall)
    731839{
     
    10951203       
    10961204        fibril_mutex_lock(&services_list_mutex);
     1205        fibril_mutex_lock(&cdir.mutex);
    10971206        loc_service_unregister_core(null_services[i]);
     1207        fibril_mutex_unlock(&cdir.mutex);
    10981208        fibril_mutex_unlock(&services_list_mutex);
    10991209       
     
    11291239
    11301240        async_answer_0(iid, retval);
     1241
     1242        loc_category_change_event();
    11311243}
    11321244
     
    11561268
    11571269        cat = category_new("serial");
     1270        categ_dir_add_cat(&cdir, cat);
     1271
     1272        cat = category_new("usbhc");
     1273        categ_dir_add_cat(&cdir, cat);
     1274
     1275        cat = category_new("virtual");
    11581276        categ_dir_add_cat(&cdir, cat);
    11591277
     
    12441362                        loc_namespace_get_id(callid, &call);
    12451363                        break;
     1364                case LOC_CALLBACK_CREATE:
     1365                        loc_callback_create(callid, &call);
     1366                        break;
    12461367                case LOC_CATEGORY_GET_ID:
    12471368                        loc_category_get_id(callid, &call);
     1369                        break;
     1370                case LOC_CATEGORY_GET_NAME:
     1371                        loc_category_get_name(callid, &call);
    12481372                        break;
    12491373                case LOC_CATEGORY_GET_SVCS:
  • uspace/srv/loc/loc.h

    r0cf27ee r07b39338  
    3636#define LOC_H_
    3737
     38#include <ipc/loc.h>
    3839#include <async.h>
    3940#include <fibril_synch.h>
     
    8990        /** Link to list of services in category (category_t.services) */
    9091        link_t cat_services;
     92        /** List of category memberships (svc_categ_t) */
     93        list_t cat_memb;
    9194        /** Unique service identifier */
    9295        service_id_t id;
     
    101104} loc_service_t;
    102105
     106extern fibril_mutex_t services_list_mutex;
     107
    103108extern service_id_t loc_create_id(void);
     109extern void loc_category_change_event(void);
    104110
    105111#endif
  • uspace/srv/vfs/vfs.c

    r0cf27ee r07b39338  
    3636 */
    3737
     38#include <vfs/vfs.h>
    3839#include <ipc/services.h>
     40#include <abi/ipc/event.h>
     41#include <event.h>
    3942#include <ns.h>
    4043#include <async.h>
     
    4548#include <as.h>
    4649#include <atomic.h>
     50#include <macros.h>
    4751#include "vfs.h"
    4852
    4953#define NAME  "vfs"
     54
     55enum {
     56        VFS_TASK_STATE_CHANGE
     57};
    5058
    5159static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     
    8088                        vfs_open(callid, &call);
    8189                        break;
    82                 case VFS_IN_OPEN_NODE:
    83                         vfs_open_node(callid, &call);
    84                         break;
    8590                case VFS_IN_CLOSE:
    8691                        vfs_close(callid, &call);
     
    118123                case VFS_IN_DUP:
    119124                        vfs_dup(callid, &call);
     125                        break;
     126                case VFS_IN_WAIT_HANDLE:
     127                        vfs_wait_handle(callid, &call);
     128                        break;
    120129                default:
    121130                        async_answer_0(callid, ENOTSUP);
     
    128137         * connection fibril terminates.
    129138         */
     139}
     140
     141static void notification_received(ipc_callid_t callid, ipc_call_t *call)
     142{
     143        switch (IPC_GET_IMETHOD(*call)) {
     144        case VFS_TASK_STATE_CHANGE:
     145                if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
     146                        vfs_pass_handle(
     147                            (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
     148                            IPC_GET_ARG5(*call)), call->in_task_id,
     149                            (int) IPC_GET_ARG2(*call));
     150                break;
     151        default:
     152                break;
     153        }
    130154}
    131155
     
    170194
    171195        /*
     196         * Set notification handler and subscribe to notifications.
     197         */
     198        async_set_interrupt_received(notification_received);
     199        event_task_subscribe(EVENT_TASK_STATE_CHANGE, VFS_TASK_STATE_CHANGE);
     200
     201        /*
    172202         * Register at the naming service.
    173203         */
  • uspace/srv/vfs/vfs.h

    r0cf27ee r07b39338  
    4141#include <bool.h>
    4242#include <ipc/vfs.h>
     43#include <task.h>
    4344
    4445#ifndef dprintf
     
    175176extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *,
    176177    vfs_pair_t *, ...);
    177 extern int vfs_open_node_internal(vfs_lookup_res_t *);
    178178
    179179extern bool vfs_nodes_init(void);
     
    189189extern void vfs_client_data_destroy(void *);
    190190
     191extern void vfs_pass_handle(task_id_t, task_id_t, int);
     192extern int vfs_wait_handle_internal(void);
     193
    191194extern vfs_file_t *vfs_file_get(int);
    192195extern void vfs_file_put(vfs_file_t *);
     
    197200extern void vfs_node_addref(vfs_node_t *);
    198201extern void vfs_node_delref(vfs_node_t *);
     202extern int vfs_open_node_remote(vfs_node_t *);
    199203
    200204extern void vfs_register(ipc_callid_t, ipc_call_t *);
     
    202206extern void vfs_unmount(ipc_callid_t, ipc_call_t *);
    203207extern void vfs_open(ipc_callid_t, ipc_call_t *);
    204 extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
    205208extern void vfs_sync(ipc_callid_t, ipc_call_t *);
    206209extern void vfs_dup(ipc_callid_t, ipc_call_t *);
     
    215218extern void vfs_unlink(ipc_callid_t, ipc_call_t *);
    216219extern void vfs_rename(ipc_callid_t, ipc_call_t *);
     220extern void vfs_wait_handle(ipc_callid_t, ipc_call_t *);
    217221
    218222#endif
  • uspace/srv/vfs/vfs_file.c

    r0cf27ee r07b39338  
    4343#include <fibril.h>
    4444#include <fibril_synch.h>
     45#include <adt/list.h>
     46#include <task.h>
    4547#include "vfs.h"
    4648
     
    5052typedef struct {
    5153        fibril_mutex_t lock;
     54        fibril_condvar_t cv;
     55        list_t passed_handles;
    5256        vfs_file_t **files;
    5357} vfs_client_data_t;
    5458
     59typedef struct {
     60        link_t link;
     61        int handle;
     62} vfs_boxed_handle_t;
     63
     64static int _vfs_fd_free(vfs_client_data_t *, int);
     65
    5566/** Initialize the table of open files. */
    56 static bool vfs_files_init(void)
    57 {
    58         fibril_mutex_lock(&VFS_DATA->lock);
    59         if (!FILES) {
    60                 FILES = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
    61                 if (!FILES) {
    62                         fibril_mutex_unlock(&VFS_DATA->lock);
     67static bool vfs_files_init(vfs_client_data_t *vfs_data)
     68{
     69        fibril_mutex_lock(&vfs_data->lock);
     70        if (!vfs_data->files) {
     71                vfs_data->files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
     72                if (!vfs_data->files) {
     73                        fibril_mutex_unlock(&vfs_data->lock);
    6374                        return false;
    6475                }
    65                 memset(FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
    66         }
    67         fibril_mutex_unlock(&VFS_DATA->lock);
     76                memset(vfs_data->files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
     77        }
     78        fibril_mutex_unlock(&vfs_data->lock);
    6879        return true;
    6980}
    7081
    7182/** Cleanup the table of open files. */
    72 static void vfs_files_done(void)
     83static void vfs_files_done(vfs_client_data_t *vfs_data)
    7384{
    7485        int i;
    7586
    76         if (!FILES)
     87        if (!vfs_data->files)
    7788                return;
    7889
    7990        for (i = 0; i < MAX_OPEN_FILES; i++) {
    80                 if (FILES[i]) {
    81                         (void) vfs_fd_free(i);
    82                 }
    83         }
    84        
    85         free(FILES);
     91                if (vfs_data->files[i])
     92                        (void) _vfs_fd_free(vfs_data, i);
     93        }
     94       
     95        free(vfs_data->files);
     96
     97        while (!list_empty(&vfs_data->passed_handles)) {
     98                link_t *lnk;
     99                vfs_boxed_handle_t *bh;
     100               
     101                lnk = list_first(&vfs_data->passed_handles);
     102                list_remove(lnk);
     103
     104                bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
     105                free(bh);
     106        }
    86107}
    87108
     
    93114        if (vfs_data) {
    94115                fibril_mutex_initialize(&vfs_data->lock);
     116                fibril_condvar_initialize(&vfs_data->cv);
     117                list_initialize(&vfs_data->passed_handles);
    95118                vfs_data->files = NULL;
    96119        }
     
    103126        vfs_client_data_t *vfs_data = (vfs_client_data_t *) data;
    104127
    105         vfs_files_done();
     128        vfs_files_done(vfs_data);
    106129        free(vfs_data);
    107130}
     
    131154 *                      incremented.
    132155 */
    133 static void vfs_file_addref(vfs_file_t *file)
    134 {
    135         assert(fibril_mutex_is_locked(&VFS_DATA->lock));
     156static void vfs_file_addref(vfs_client_data_t *vfs_data, vfs_file_t *file)
     157{
     158        assert(fibril_mutex_is_locked(&vfs_data->lock));
    136159
    137160        file->refcnt++;
     
    143166 *                      decremented.
    144167 */
    145 static int vfs_file_delref(vfs_file_t *file)
     168static int vfs_file_delref(vfs_client_data_t *vfs_data, vfs_file_t *file)
    146169{
    147170        int rc = EOK;
    148171
    149         assert(fibril_mutex_is_locked(&VFS_DATA->lock));
     172        assert(fibril_mutex_is_locked(&vfs_data->lock));
    150173
    151174        if (file->refcnt-- == 1) {
     
    162185}
    163186
    164 
    165 /** Allocate a file descriptor.
    166  *
    167  * @param desc If true, look for an available file descriptor
    168  *             in a descending order.
    169  *
    170  * @return First available file descriptor or a negative error
    171  *         code.
    172  */
    173 int vfs_fd_alloc(bool desc)
    174 {
    175         if (!vfs_files_init())
     187static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc)
     188{
     189        if (!vfs_files_init(vfs_data))
    176190                return ENOMEM;
    177191       
     
    182196                i = 0;
    183197       
    184         fibril_mutex_lock(&VFS_DATA->lock);
     198        fibril_mutex_lock(&vfs_data->lock);
    185199        while (true) {
    186                 if (!FILES[i]) {
    187                         FILES[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
    188                         if (!FILES[i]) {
    189                                 fibril_mutex_unlock(&VFS_DATA->lock);
     200                if (!vfs_data->files[i]) {
     201                        vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
     202                        if (!vfs_data->files[i]) {
     203                                fibril_mutex_unlock(&vfs_data->lock);
    190204                                return ENOMEM;
    191205                        }
    192206                       
    193                         memset(FILES[i], 0, sizeof(vfs_file_t));
    194                         fibril_mutex_initialize(&FILES[i]->lock);
    195                         vfs_file_addref(FILES[i]);
    196                         fibril_mutex_unlock(&VFS_DATA->lock);
     207                        memset(vfs_data->files[i], 0, sizeof(vfs_file_t));
     208                        fibril_mutex_initialize(&vfs_data->files[i]->lock);
     209                        vfs_file_addref(vfs_data, vfs_data->files[i]);
     210                        fibril_mutex_unlock(&vfs_data->lock);
    197211                        return (int) i;
    198212                }
     
    210224                }
    211225        }
    212         fibril_mutex_unlock(&VFS_DATA->lock);
     226        fibril_mutex_unlock(&vfs_data->lock);
    213227       
    214228        return EMFILE;
     229}
     230
     231/** Allocate a file descriptor.
     232 *
     233 * @param desc If true, look for an available file descriptor
     234 *             in a descending order.
     235 *
     236 * @return First available file descriptor or a negative error
     237 *         code.
     238 */
     239int vfs_fd_alloc(bool desc)
     240{
     241        return _vfs_fd_alloc(VFS_DATA, desc);
     242}
     243
     244static int _vfs_fd_free(vfs_client_data_t *vfs_data, int fd)
     245{
     246        int rc;
     247
     248        if (!vfs_files_init(vfs_data))
     249                return ENOMEM;
     250
     251        fibril_mutex_lock(&vfs_data->lock);     
     252        if ((fd < 0) || (fd >= MAX_OPEN_FILES) || !vfs_data->files[fd]) {
     253                fibril_mutex_unlock(&vfs_data->lock);
     254                return EBADF;
     255        }
     256       
     257        rc = vfs_file_delref(vfs_data, vfs_data->files[fd]);
     258        vfs_data->files[fd] = NULL;
     259        fibril_mutex_unlock(&vfs_data->lock);
     260       
     261        return rc;
    215262}
    216263
     
    224271int vfs_fd_free(int fd)
    225272{
    226         int rc;
    227 
    228         if (!vfs_files_init())
    229                 return ENOMEM;
    230 
    231         fibril_mutex_lock(&VFS_DATA->lock);     
    232         if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] == NULL)) {
    233                 fibril_mutex_unlock(&VFS_DATA->lock);
    234                 return EBADF;
    235         }
    236        
    237         rc = vfs_file_delref(FILES[fd]);
    238         FILES[fd] = NULL;
    239         fibril_mutex_unlock(&VFS_DATA->lock);
    240        
    241         return rc;
     273        return _vfs_fd_free(VFS_DATA, fd);
    242274}
    243275
     
    253285int vfs_fd_assign(vfs_file_t *file, int fd)
    254286{
    255         if (!vfs_files_init())
     287        if (!vfs_files_init(VFS_DATA))
    256288                return ENOMEM;
    257289
     
    263295       
    264296        FILES[fd] = file;
    265         vfs_file_addref(FILES[fd]);
     297        vfs_file_addref(VFS_DATA, FILES[fd]);
    266298        fibril_mutex_unlock(&VFS_DATA->lock);
    267299       
     
    269301}
    270302
    271 /** Find VFS file structure for a given file descriptor.
    272  *
    273  * @param fd            File descriptor.
    274  *
    275  * @return              VFS file structure corresponding to fd.
    276  */
    277 vfs_file_t *vfs_file_get(int fd)
    278 {
    279         if (!vfs_files_init())
     303static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd)
     304{
     305        if (!vfs_files_init(vfs_data))
    280306                return NULL;
    281307       
    282         fibril_mutex_lock(&VFS_DATA->lock);
     308        fibril_mutex_lock(&vfs_data->lock);
    283309        if ((fd >= 0) && (fd < MAX_OPEN_FILES)) {
    284                 vfs_file_t *file = FILES[fd];
     310                vfs_file_t *file = vfs_data->files[fd];
    285311                if (file != NULL) {
    286                         vfs_file_addref(file);
    287                         fibril_mutex_unlock(&VFS_DATA->lock);
     312                        vfs_file_addref(vfs_data, file);
     313                        fibril_mutex_unlock(&vfs_data->lock);
    288314                        return file;
    289315                }
    290316        }
    291         fibril_mutex_unlock(&VFS_DATA->lock);
     317        fibril_mutex_unlock(&vfs_data->lock);
    292318       
    293319        return NULL;
    294320}
    295321
     322/** Find VFS file structure for a given file descriptor.
     323 *
     324 * @param fd            File descriptor.
     325 *
     326 * @return              VFS file structure corresponding to fd.
     327 */
     328vfs_file_t *vfs_file_get(int fd)
     329{
     330        return _vfs_file_get(VFS_DATA, fd);
     331}
     332
     333static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)
     334{
     335        fibril_mutex_lock(&vfs_data->lock);
     336        vfs_file_delref(vfs_data, file);
     337        fibril_mutex_unlock(&vfs_data->lock);
     338}
     339
    296340/** Stop using a file structure.
    297341 *
     
    300344void vfs_file_put(vfs_file_t *file)
    301345{
    302         fibril_mutex_lock(&VFS_DATA->lock);
    303         vfs_file_delref(file);
    304         fibril_mutex_unlock(&VFS_DATA->lock);
     346        _vfs_file_put(VFS_DATA, file);
     347}
     348
     349void vfs_pass_handle(task_id_t donor_id, task_id_t acceptor_id, int donor_fd)
     350{
     351        vfs_client_data_t *donor_data = NULL;
     352        vfs_client_data_t *acceptor_data = NULL;
     353        vfs_file_t *donor_file = NULL;
     354        vfs_file_t *acceptor_file = NULL;
     355        vfs_boxed_handle_t *bh;
     356        int acceptor_fd;
     357
     358        acceptor_data = async_get_client_data_by_id(acceptor_id);
     359        if (!acceptor_data)
     360                return;
     361
     362        bh = malloc(sizeof(vfs_boxed_handle_t));
     363        assert(bh);
     364
     365        link_initialize(&bh->link);
     366        bh->handle = -1;
     367
     368        donor_data = async_get_client_data_by_id(donor_id);
     369        if (!donor_data)
     370                goto out;
     371
     372        donor_file = _vfs_file_get(donor_data, donor_fd);
     373        if (!donor_file)
     374                goto out;
     375
     376        acceptor_fd = _vfs_fd_alloc(acceptor_data, false);
     377        if (acceptor_fd < 0)
     378                goto out;
     379
     380        bh->handle = acceptor_fd;
     381
     382        /*
     383         * Add a new reference to the underlying VFS node.
     384         */
     385        vfs_node_addref(donor_file->node);
     386        (void) vfs_open_node_remote(donor_file->node);
     387
     388        acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd);
     389        assert(acceptor_file);
     390
     391        /*
     392         * Inherit attributes from the donor.
     393         */
     394        acceptor_file->node = donor_file->node;
     395        acceptor_file->append = donor_file->append;
     396        acceptor_file->pos = donor_file->pos;
     397
     398out:
     399        fibril_mutex_lock(&acceptor_data->lock);
     400        list_append(&bh->link, &acceptor_data->passed_handles);
     401        fibril_condvar_broadcast(&acceptor_data->cv);
     402        fibril_mutex_unlock(&acceptor_data->lock);
     403
     404        if (donor_data)
     405                async_put_client_data_by_id(donor_id);
     406        if (acceptor_data)
     407                async_put_client_data_by_id(acceptor_id);
     408        if (donor_file)
     409                _vfs_file_put(donor_data, donor_file);
     410        if (acceptor_file)
     411                _vfs_file_put(acceptor_data, acceptor_file);
     412
     413}
     414
     415int vfs_wait_handle_internal(void)
     416{
     417        vfs_client_data_t *vfs_data = VFS_DATA;
     418        int fd;
     419       
     420        fibril_mutex_lock(&vfs_data->lock);
     421        while (list_empty(&vfs_data->passed_handles))
     422                fibril_condvar_wait(&vfs_data->cv, &vfs_data->lock);
     423        link_t *lnk = list_first(&vfs_data->passed_handles);
     424        list_remove(lnk);
     425        fibril_mutex_unlock(&vfs_data->lock);
     426
     427        vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
     428        fd = bh->handle;
     429        free(bh);
     430
     431        return fd;
    305432}
    306433
  • uspace/srv/vfs/vfs_lookup.c

    r0cf27ee r07b39338  
    201201}
    202202
    203 /** Perform a node open operation.
    204  *
    205  * @return EOK on success or an error code from errno.h.
    206  *
    207  */
    208 int vfs_open_node_internal(vfs_lookup_res_t *result)
    209 {
    210         async_exch_t *exch = vfs_exchange_grab(result->triplet.fs_handle);
    211        
    212         ipc_call_t answer;
    213         aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
    214             (sysarg_t) result->triplet.service_id,
    215             (sysarg_t) result->triplet.index, &answer);
    216        
    217         sysarg_t rc;
    218         async_wait_for(req, &rc);
    219         vfs_exchange_release(exch);
    220        
    221         if (rc == EOK) {
    222                 result->size =
    223                     MERGE_LOUP32(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer));
    224                 result->lnkcnt = (unsigned int) IPC_GET_ARG3(answer);
    225                 if (IPC_GET_ARG4(answer) & L_FILE)
    226                         result->type = VFS_NODE_FILE;
    227                 else if (IPC_GET_ARG4(answer) & L_DIRECTORY)
    228                         result->type = VFS_NODE_DIRECTORY;
    229                 else
    230                         result->type = VFS_NODE_UNKNOWN;
    231         }
    232        
    233         return rc;
    234 }
    235 
    236203/**
    237204 * @}
  • uspace/srv/vfs/vfs_node.c

    r0cf27ee r07b39338  
    293293}
    294294
     295
     296/** Perform a remote node open operation.
     297 *
     298 * @return EOK on success or an error code from errno.h.
     299 *
     300 */
     301int vfs_open_node_remote(vfs_node_t *node)
     302{
     303        async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
     304       
     305        ipc_call_t answer;
     306        aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
     307            (sysarg_t) node->service_id, (sysarg_t) node->index, &answer);
     308       
     309        vfs_exchange_release(exch);
     310
     311        sysarg_t rc;
     312        async_wait_for(req, &rc);
     313       
     314        return rc;
     315}
     316
    295317/**
    296318 * @}
  • uspace/srv/vfs/vfs_ops.c

    r0cf27ee r07b39338  
    618618}
    619619
    620 void vfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    621 {
    622         // FIXME: check for sanity of the supplied fs, dev and index
    623        
    624         /*
    625          * The interface is open_node(fs, dev, index, oflag).
    626          */
    627         vfs_lookup_res_t lr;
    628        
    629         lr.triplet.fs_handle = IPC_GET_ARG1(*request);
    630         lr.triplet.service_id = IPC_GET_ARG2(*request);
    631         lr.triplet.index = IPC_GET_ARG3(*request);
    632         int oflag = IPC_GET_ARG4(*request);
    633        
    634         fibril_rwlock_read_lock(&namespace_rwlock);
    635        
    636         int rc = vfs_open_node_internal(&lr);
    637         if (rc != EOK) {
    638                 fibril_rwlock_read_unlock(&namespace_rwlock);
    639                 async_answer_0(rid, rc);
    640                 return;
    641         }
    642        
    643         vfs_node_t *node = vfs_node_get(&lr);
    644         fibril_rwlock_read_unlock(&namespace_rwlock);
    645        
    646         /* Truncate the file if requested and if necessary. */
    647         if (oflag & O_TRUNC) {
    648                 fibril_rwlock_write_lock(&node->contents_rwlock);
    649                 if (node->size) {
    650                         rc = vfs_truncate_internal(node->fs_handle,
    651                             node->service_id, node->index, 0);
    652                         if (rc) {
    653                                 fibril_rwlock_write_unlock(&node->contents_rwlock);
    654                                 vfs_node_put(node);
    655                                 async_answer_0(rid, rc);
    656                                 return;
    657                         }
    658                         node->size = 0;
    659                 }
    660                 fibril_rwlock_write_unlock(&node->contents_rwlock);
    661         }
    662        
    663         /*
    664          * Get ourselves a file descriptor and the corresponding vfs_file_t
    665          * structure.
    666          */
    667         int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
    668         if (fd < 0) {
    669                 vfs_node_put(node);
    670                 async_answer_0(rid, fd);
    671                 return;
    672         }
    673         vfs_file_t *file = vfs_file_get(fd);
    674         file->node = node;
    675         if (oflag & O_APPEND)
    676                 file->append = true;
    677        
    678         /*
    679          * The following increase in reference count is for the fact that the
    680          * file is being opened and that a file structure is pointing to it.
    681          * It is necessary so that the file will not disappear when
    682          * vfs_node_put() is called. The reference will be dropped by the
    683          * respective VFS_IN_CLOSE.
    684          */
    685         vfs_node_addref(node);
    686         vfs_node_put(node);
    687         vfs_file_put(file);
    688        
    689         /* Success! Return the new file descriptor to the client. */
    690         async_answer_1(rid, EOK, fd);
    691 }
    692 
    693620void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
    694621{
     
    13491276}
    13501277
     1278void vfs_wait_handle(ipc_callid_t rid, ipc_call_t *request)
     1279{
     1280        int fd = vfs_wait_handle_internal();
     1281        async_answer_1(rid, EOK, fd);
     1282}
     1283
    13511284/**
    13521285 * @}
Note: See TracChangeset for help on using the changeset viewer.