Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/devfs/devfs_ops.c

    r0143f72 rcfd630af  
    3636 */
    3737
    38 #include <ipc/ipc.h>
     38#include <macros.h>
    3939#include <bool.h>
    4040#include <errno.h>
    4141#include <malloc.h>
    42 #include <string.h>
     42#include <str.h>
    4343#include <libfs.h>
    44 #include <fibril_sync.h>
     44#include <fibril_synch.h>
    4545#include <adt/hash_table.h>
     46#include <ipc/devmap.h>
    4647#include <sys/stat.h>
     48#include <libfs.h>
     49#include <assert.h>
    4750#include "devfs.h"
    4851#include "devfs_ops.h"
    4952
    50 #define PLB_GET_CHAR(pos)  (devfs_reg.plb_ro[pos % PLB_SIZE])
     53typedef struct {
     54        devmap_handle_type_t type;
     55        devmap_handle_t handle;
     56} devfs_node_t;
    5157
    5258/** Opened devices structure */
    5359typedef struct {
    54         dev_handle_t handle;
    55         int phone;
     60        devmap_handle_t handle;
     61        int phone;              /**< When < 0, the structure is incomplete. */
    5662        size_t refcount;
    5763        link_t link;
     64        fibril_condvar_t cv;    /**< Broadcast when completed. */
    5865} device_t;
    5966
     
    7784{
    7885        device_t *dev = hash_table_get_instance(item, device_t, link);
    79         return (dev->handle == (dev_handle_t) key[DEVICES_KEY_HANDLE]);
     86        return (dev->handle == (devmap_handle_t) key[DEVICES_KEY_HANDLE]);
    8087}
    8188
     
    9198};
    9299
     100static int devfs_node_get_internal(fs_node_t **rfn, devmap_handle_type_t type,
     101    devmap_handle_t handle)
     102{
     103        devfs_node_t *node = (devfs_node_t *) malloc(sizeof(devfs_node_t));
     104        if (node == NULL) {
     105                *rfn = NULL;
     106                return ENOMEM;
     107        }
     108       
     109        *rfn = (fs_node_t *) malloc(sizeof(fs_node_t));
     110        if (*rfn == NULL) {
     111                free(node);
     112                *rfn = NULL;
     113                return ENOMEM;
     114        }
     115       
     116        fs_node_initialize(*rfn);
     117        node->type = type;
     118        node->handle = handle;
     119       
     120        (*rfn)->data = node;
     121        return EOK;
     122}
     123
     124static int devfs_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
     125{
     126        return devfs_node_get_internal(rfn, DEV_HANDLE_NONE, 0);
     127}
     128
     129static int devfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
     130{
     131        devfs_node_t *node = (devfs_node_t *) pfn->data;
     132        int ret;
     133       
     134        if (node->handle == 0) {
     135                /* Root directory */
     136               
     137                dev_desc_t *devs;
     138                size_t count = devmap_get_namespaces(&devs);
     139               
     140                if (count > 0) {
     141                        size_t pos;
     142                        for (pos = 0; pos < count; pos++) {
     143                                /* Ignore root namespace */
     144                                if (str_cmp(devs[pos].name, "") == 0)
     145                                        continue;
     146                               
     147                                if (str_cmp(devs[pos].name, component) == 0) {
     148                                        ret = devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle);
     149                                        free(devs);
     150                                        return ret;
     151                                }
     152                        }
     153                       
     154                        free(devs);
     155                }
     156               
     157                /* Search root namespace */
     158                devmap_handle_t namespace;
     159                if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {
     160                        count = devmap_get_devices(namespace, &devs);
     161                       
     162                        if (count > 0) {
     163                                size_t pos;
     164                                for (pos = 0; pos < count; pos++) {
     165                                        if (str_cmp(devs[pos].name, component) == 0) {
     166                                                ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
     167                                                free(devs);
     168                                                return ret;
     169                                        }
     170                                }
     171                               
     172                                free(devs);
     173                        }
     174                }
     175               
     176                *rfn = NULL;
     177                return EOK;
     178        }
     179       
     180        if (node->type == DEV_HANDLE_NAMESPACE) {
     181                /* Namespace directory */
     182               
     183                dev_desc_t *devs;
     184                size_t count = devmap_get_devices(node->handle, &devs);
     185                if (count > 0) {
     186                        size_t pos;
     187                        for (pos = 0; pos < count; pos++) {
     188                                if (str_cmp(devs[pos].name, component) == 0) {
     189                                        ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
     190                                        free(devs);
     191                                        return ret;
     192                                }
     193                        }
     194                       
     195                        free(devs);
     196                }
     197               
     198                *rfn = NULL;
     199                return EOK;
     200        }
     201       
     202        *rfn = NULL;
     203        return EOK;
     204}
     205
     206static int devfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)
     207{
     208        return devfs_node_get_internal(rfn, devmap_handle_probe(index), index);
     209}
     210
     211static int devfs_node_open(fs_node_t *fn)
     212{
     213        devfs_node_t *node = (devfs_node_t *) fn->data;
     214       
     215        if (node->handle == 0) {
     216                /* Root directory */
     217                return EOK;
     218        }
     219       
     220        devmap_handle_type_t type = devmap_handle_probe(node->handle);
     221       
     222        if (type == DEV_HANDLE_NAMESPACE) {
     223                /* Namespace directory */
     224                return EOK;
     225        }
     226       
     227        if (type == DEV_HANDLE_DEVICE) {
     228                /* Device node */
     229               
     230                unsigned long key[] = {
     231                        [DEVICES_KEY_HANDLE] = (unsigned long) node->handle
     232                };
     233                link_t *lnk;
     234
     235                fibril_mutex_lock(&devices_mutex);
     236restart:
     237                lnk = hash_table_find(&devices, key);
     238                if (lnk == NULL) {
     239                        device_t *dev = (device_t *) malloc(sizeof(device_t));
     240                        if (dev == NULL) {
     241                                fibril_mutex_unlock(&devices_mutex);
     242                                return ENOMEM;
     243                        }
     244                       
     245                        dev->handle = node->handle;
     246                        dev->phone = -1;        /* mark as incomplete */
     247                        dev->refcount = 1;
     248                        fibril_condvar_initialize(&dev->cv);
     249
     250                        /*
     251                         * Insert the incomplete device structure so that other
     252                         * fibrils will not race with us when we drop the mutex
     253                         * below.
     254                         */
     255                        hash_table_insert(&devices, key, &dev->link);
     256
     257                        /*
     258                         * Drop the mutex to allow recursive devfs requests.
     259                         */
     260                        fibril_mutex_unlock(&devices_mutex);
     261
     262                        int phone = devmap_device_connect(node->handle, 0);
     263
     264                        fibril_mutex_lock(&devices_mutex);
     265
     266                        /*
     267                         * Notify possible waiters about this device structure
     268                         * being completed (or destroyed).
     269                         */
     270                        fibril_condvar_broadcast(&dev->cv);
     271
     272                        if (phone < 0) {
     273                                /*
     274                                 * Connecting failed, need to remove the
     275                                 * entry and free the device structure.
     276                                 */
     277                                hash_table_remove(&devices, key, DEVICES_KEYS);
     278                                fibril_mutex_unlock(&devices_mutex);
     279
     280                                return ENOENT;
     281                        }
     282                       
     283                        /* Set the correct phone. */
     284                        dev->phone = phone;
     285                } else {
     286                        device_t *dev = hash_table_get_instance(lnk, device_t, link);
     287
     288                        if (dev->phone < 0) {
     289                                /*
     290                                 * Wait until the device structure is completed
     291                                 * and start from the beginning as the device
     292                                 * structure might have entirely disappeared
     293                                 * while we were not holding the mutex in
     294                                 * fibril_condvar_wait().
     295                                 */
     296                                fibril_condvar_wait(&dev->cv, &devices_mutex);
     297                                goto restart;
     298                        }
     299
     300                        dev->refcount++;
     301                }
     302               
     303                fibril_mutex_unlock(&devices_mutex);
     304               
     305                return EOK;
     306        }
     307       
     308        return ENOENT;
     309}
     310
     311static int devfs_node_put(fs_node_t *fn)
     312{
     313        free(fn->data);
     314        free(fn);
     315        return EOK;
     316}
     317
     318static int devfs_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int lflag)
     319{
     320        assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
     321       
     322        *rfn = NULL;
     323        return ENOTSUP;
     324}
     325
     326static int devfs_destroy_node(fs_node_t *fn)
     327{
     328        return ENOTSUP;
     329}
     330
     331static int devfs_link_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
     332{
     333        return ENOTSUP;
     334}
     335
     336static int devfs_unlink_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
     337{
     338        return ENOTSUP;
     339}
     340
     341static int devfs_has_children(bool *has_children, fs_node_t *fn)
     342{
     343        devfs_node_t *node = (devfs_node_t *) fn->data;
     344       
     345        if (node->handle == 0) {
     346                size_t count = devmap_count_namespaces();
     347                if (count > 0) {
     348                        *has_children = true;
     349                        return EOK;
     350                }
     351               
     352                /* Root namespace */
     353                devmap_handle_t namespace;
     354                if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {
     355                        count = devmap_count_devices(namespace);
     356                        if (count > 0) {
     357                                *has_children = true;
     358                                return EOK;
     359                        }
     360                }
     361               
     362                *has_children = false;
     363                return EOK;
     364        }
     365       
     366        if (node->type == DEV_HANDLE_NAMESPACE) {
     367                size_t count = devmap_count_devices(node->handle);
     368                if (count > 0) {
     369                        *has_children = true;
     370                        return EOK;
     371                }
     372               
     373                *has_children = false;
     374                return EOK;
     375        }
     376       
     377        *has_children = false;
     378        return EOK;
     379}
     380
     381static fs_index_t devfs_index_get(fs_node_t *fn)
     382{
     383        devfs_node_t *node = (devfs_node_t *) fn->data;
     384        return node->handle;
     385}
     386
     387static aoff64_t devfs_size_get(fs_node_t *fn)
     388{
     389        return 0;
     390}
     391
     392static unsigned int devfs_lnkcnt_get(fs_node_t *fn)
     393{
     394        devfs_node_t *node = (devfs_node_t *) fn->data;
     395       
     396        if (node->handle == 0)
     397                return 0;
     398       
     399        return 1;
     400}
     401
     402static char devfs_plb_get_char(unsigned pos)
     403{
     404        return devfs_reg.plb_ro[pos % PLB_SIZE];
     405}
     406
     407static bool devfs_is_directory(fs_node_t *fn)
     408{
     409        devfs_node_t *node = (devfs_node_t *) fn->data;
     410       
     411        return ((node->type == DEV_HANDLE_NONE) || (node->type == DEV_HANDLE_NAMESPACE));
     412}
     413
     414static bool devfs_is_file(fs_node_t *fn)
     415{
     416        devfs_node_t *node = (devfs_node_t *) fn->data;
     417       
     418        return (node->type == DEV_HANDLE_DEVICE);
     419}
     420
     421static devmap_handle_t devfs_device_get(fs_node_t *fn)
     422{
     423        devfs_node_t *node = (devfs_node_t *) fn->data;
     424       
     425        if (node->type == DEV_HANDLE_DEVICE)
     426                return node->handle;
     427       
     428        return 0;
     429}
     430
     431/** libfs operations */
     432libfs_ops_t devfs_libfs_ops = {
     433        .root_get = devfs_root_get,
     434        .match = devfs_match,
     435        .node_get = devfs_node_get,
     436        .node_open = devfs_node_open,
     437        .node_put = devfs_node_put,
     438        .create = devfs_create_node,
     439        .destroy = devfs_destroy_node,
     440        .link = devfs_link_node,
     441        .unlink = devfs_unlink_node,
     442        .has_children = devfs_has_children,
     443        .index_get = devfs_index_get,
     444        .size_get = devfs_size_get,
     445        .lnkcnt_get = devfs_lnkcnt_get,
     446        .plb_get_char = devfs_plb_get_char,
     447        .is_directory = devfs_is_directory,
     448        .is_file = devfs_is_file,
     449        .device_get = devfs_device_get
     450};
     451
    93452bool devfs_init(void)
    94453{
     
    97456                return false;
    98457       
    99         if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0)
    100                 return false;
    101        
    102458        return true;
    103459}
     
    105461void devfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    106462{
     463        char *opts;
     464       
    107465        /* Accept the mount options */
    108         ipc_callid_t callid;
    109         size_t size;
    110         if (!ipc_data_write_receive(&callid, &size)) {
    111                 ipc_answer_0(callid, EINVAL);
    112                 ipc_answer_0(rid, EINVAL);
    113                 return;
    114         }
    115        
    116         char *opts = malloc(size + 1);
    117         if (!opts) {
    118                 ipc_answer_0(callid, ENOMEM);
    119                 ipc_answer_0(rid, ENOMEM);
    120                 return;
    121         }
    122        
    123         ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
     466        sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
     467            0, NULL);
    124468        if (retval != EOK) {
    125                 ipc_answer_0(rid, retval);
    126                 free(opts);
     469                async_answer_0(rid, retval);
    127470                return;
    128471        }
    129472       
    130473        free(opts);
    131        
    132         ipc_answer_3(rid, EOK, 0, 0, 0);
     474        async_answer_3(rid, EOK, 0, 0, 0);
    133475}
    134476
    135477void devfs_mount(ipc_callid_t rid, ipc_call_t *request)
    136478{
    137         ipc_answer_0(rid, ENOTSUP);
     479        libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
     480}
     481
     482void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
     483{
     484        async_answer_0(rid, ENOTSUP);
     485}
     486
     487void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     488{
     489        libfs_unmount(&devfs_libfs_ops, rid, request);
    138490}
    139491
    140492void devfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    141493{
    142         ipcarg_t first = IPC_GET_ARG1(*request);
    143         ipcarg_t last = IPC_GET_ARG2(*request);
    144         dev_handle_t dev_handle = IPC_GET_ARG3(*request);
    145         ipcarg_t lflag = IPC_GET_ARG4(*request);
    146         fs_index_t index = IPC_GET_ARG5(*request);
    147        
    148         /* Hierarchy is flat, no altroot is supported */
    149         if (index != 0) {
    150                 ipc_answer_0(rid, ENOENT);
    151                 return;
    152         }
    153        
    154         if ((lflag & L_LINK) || (lflag & L_UNLINK)) {
    155                 ipc_answer_0(rid, ENOTSUP);
    156                 return;
    157         }
    158        
    159         /* Eat slash */
    160         if (PLB_GET_CHAR(first) == '/') {
    161                 first++;
    162                 first %= PLB_SIZE;
    163         }
    164        
    165         if (first >= last) {
    166                 /* Root entry */
    167                 if (!(lflag & L_FILE))
    168                         ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, 0, 0, 0);
    169                 else
    170                         ipc_answer_0(rid, ENOENT);
    171         } else {
    172                 if (!(lflag & L_DIRECTORY)) {
    173                         size_t len;
    174                         if (last >= first)
    175                                 len = last - first + 1;
    176                         else
    177                                 len = first + PLB_SIZE - last + 1;
     494        libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
     495}
     496
     497void devfs_open_node(ipc_callid_t rid, ipc_call_t *request)
     498{
     499        libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
     500}
     501
     502void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
     503{
     504        libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
     505}
     506
     507void devfs_read(ipc_callid_t rid, ipc_call_t *request)
     508{
     509        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     510        aoff64_t pos =
     511            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     512       
     513        if (index == 0) {
     514                ipc_callid_t callid;
     515                size_t size;
     516                if (!async_data_read_receive(&callid, &size)) {
     517                        async_answer_0(callid, EINVAL);
     518                        async_answer_0(rid, EINVAL);
     519                        return;
     520                }
     521               
     522                dev_desc_t *desc;
     523                size_t count = devmap_get_namespaces(&desc);
     524               
     525                /* Get rid of root namespace */
     526                size_t i;
     527                for (i = 0; i < count; i++) {
     528                        if (str_cmp(desc[i].name, "") == 0) {
     529                                if (pos >= i)
     530                                        pos++;
     531                               
     532                                break;
     533                        }
     534                }
     535               
     536                if (pos < count) {
     537                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
     538                        free(desc);
     539                        async_answer_1(rid, EOK, 1);
     540                        return;
     541                }
     542               
     543                free(desc);
     544                pos -= count;
     545               
     546                /* Search root namespace */
     547                devmap_handle_t namespace;
     548                if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {
     549                        count = devmap_get_devices(namespace, &desc);
    178550                       
    179                         char *name = (char *) malloc(len + 1);
    180                         if (name == NULL) {
    181                                 ipc_answer_0(rid, ENOMEM);
     551                        if (pos < count) {
     552                                async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
     553                                free(desc);
     554                                async_answer_1(rid, EOK, 1);
    182555                                return;
    183556                        }
    184557                       
    185                         size_t i;
    186                         for (i = 0; i < len; i++)
    187                                 name[i] = PLB_GET_CHAR(first + i);
    188                        
    189                         name[len] = 0;
    190                        
    191                         dev_handle_t handle;
    192                         if (devmap_device_get_handle(name, &handle, 0) != EOK) {
    193                                 free(name);
    194                                 ipc_answer_0(rid, ENOENT);
    195                                 return;
    196                         }
    197                        
    198                         if (lflag & L_OPEN) {
    199                                 unsigned long key[] = {
    200                                         [DEVICES_KEY_HANDLE] = (unsigned long) handle
    201                                 };
    202                                
    203                                 fibril_mutex_lock(&devices_mutex);
    204                                 link_t *lnk = hash_table_find(&devices, key);
    205                                 if (lnk == NULL) {
    206                                         int phone = devmap_device_connect(handle, 0);
    207                                         if (phone < 0) {
    208                                                 fibril_mutex_unlock(&devices_mutex);
    209                                                 free(name);
    210                                                 ipc_answer_0(rid, ENOENT);
    211                                                 return;
    212                                         }
    213                                        
    214                                         device_t *dev = (device_t *) malloc(sizeof(device_t));
    215                                         if (dev == NULL) {
    216                                                 fibril_mutex_unlock(&devices_mutex);
    217                                                 free(name);
    218                                                 ipc_answer_0(rid, ENOMEM);
    219                                                 return;
    220                                         }
    221                                        
    222                                         dev->handle = handle;
    223                                         dev->phone = phone;
    224                                         dev->refcount = 1;
    225                                        
    226                                         hash_table_insert(&devices, key, &dev->link);
    227                                 } else {
    228                                         device_t *dev = hash_table_get_instance(lnk, device_t, link);
    229                                         dev->refcount++;
    230                                 }
    231                                 fibril_mutex_unlock(&devices_mutex);
    232                         }
    233                        
    234                         free(name);
    235                        
    236                         ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, handle, 0, 1);
    237                 } else
    238                         ipc_answer_0(rid, ENOENT);
    239         }
    240 }
    241 
    242 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    243 {
    244         dev_handle_t handle = IPC_GET_ARG2(*request);
    245        
    246         unsigned long key[] = {
    247                 [DEVICES_KEY_HANDLE] = (unsigned long) handle
    248         };
    249        
    250         fibril_mutex_lock(&devices_mutex);
    251         link_t *lnk = hash_table_find(&devices, key);
    252         if (lnk == NULL) {
    253                 int phone = devmap_device_connect(handle, 0);
    254                 if (phone < 0) {
    255                         fibril_mutex_unlock(&devices_mutex);
    256                         ipc_answer_0(rid, ENOENT);
    257                         return;
    258                 }
    259                
    260                 device_t *dev = (device_t *) malloc(sizeof(device_t));
    261                 if (dev == NULL) {
    262                         fibril_mutex_unlock(&devices_mutex);
    263                         ipc_answer_0(rid, ENOMEM);
    264                         return;
    265                 }
    266                
    267                 dev->handle = handle;
    268                 dev->phone = phone;
    269                 dev->refcount = 1;
    270                
    271                 hash_table_insert(&devices, key, &dev->link);
    272         } else {
    273                 device_t *dev = hash_table_get_instance(lnk, device_t, link);
    274                 dev->refcount++;
    275         }
    276         fibril_mutex_unlock(&devices_mutex);
    277        
    278         ipc_answer_3(rid, EOK, 0, 1, L_FILE);
    279 }
    280 
    281 void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
    282 {
    283         dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    284         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    285        
    286         ipc_callid_t callid;
    287         size_t size;
    288         if (!ipc_data_read_receive(&callid, &size) ||
    289             size != sizeof(struct stat)) {
    290                 ipc_answer_0(callid, EINVAL);
    291                 ipc_answer_0(rid, EINVAL);
    292                 return;
    293         }
    294 
    295         struct stat stat;
    296         memset(&stat, 0, sizeof(struct stat));
    297 
    298         stat.fs_handle = devfs_reg.fs_handle;
    299         stat.dev_handle = dev_handle;
    300         stat.index = index;
    301         stat.lnkcnt = 1;
    302         stat.is_file = (index != 0);
    303         stat.size = 0;
    304        
    305         if (index != 0) {
    306                 unsigned long key[] = {
    307                         [DEVICES_KEY_HANDLE] = (unsigned long) index
    308                 };
    309                
    310                 fibril_mutex_lock(&devices_mutex);
    311                 link_t *lnk = hash_table_find(&devices, key);
    312                 if (lnk != NULL)
    313                         stat.devfs_stat.device = (dev_handle_t)index;
    314                 fibril_mutex_unlock(&devices_mutex);
    315         }
    316 
    317         ipc_data_read_finalize(callid, &stat, sizeof(struct stat));
    318         ipc_answer_0(rid, EOK);
    319 }
    320 
    321 void devfs_read(ipc_callid_t rid, ipc_call_t *request)
    322 {
    323         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    324         off_t pos = (off_t) IPC_GET_ARG3(*request);
    325        
    326         if (index != 0) {
     558                        free(desc);
     559                }
     560               
     561                async_answer_0(callid, ENOENT);
     562                async_answer_1(rid, ENOENT, 0);
     563                return;
     564        }
     565       
     566        devmap_handle_type_t type = devmap_handle_probe(index);
     567       
     568        if (type == DEV_HANDLE_NAMESPACE) {
     569                /* Namespace directory */
     570                ipc_callid_t callid;
     571                size_t size;
     572                if (!async_data_read_receive(&callid, &size)) {
     573                        async_answer_0(callid, EINVAL);
     574                        async_answer_0(rid, EINVAL);
     575                        return;
     576                }
     577               
     578                dev_desc_t *desc;
     579                size_t count = devmap_get_devices(index, &desc);
     580               
     581                if (pos < count) {
     582                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
     583                        free(desc);
     584                        async_answer_1(rid, EOK, 1);
     585                        return;
     586                }
     587               
     588                free(desc);
     589                async_answer_0(callid, ENOENT);
     590                async_answer_1(rid, ENOENT, 0);
     591                return;
     592        }
     593       
     594        if (type == DEV_HANDLE_DEVICE) {
     595                /* Device node */
     596               
    327597                unsigned long key[] = {
    328598                        [DEVICES_KEY_HANDLE] = (unsigned long) index
     
    333603                if (lnk == NULL) {
    334604                        fibril_mutex_unlock(&devices_mutex);
    335                         ipc_answer_0(rid, ENOENT);
     605                        async_answer_0(rid, ENOENT);
    336606                        return;
    337607                }
    338608               
    339609                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     610                assert(dev->phone >= 0);
    340611               
    341612                ipc_callid_t callid;
    342                 if (!ipc_data_read_receive(&callid, NULL)) {
     613                if (!async_data_read_receive(&callid, NULL)) {
    343614                        fibril_mutex_unlock(&devices_mutex);
    344                         ipc_answer_0(callid, EINVAL);
    345                         ipc_answer_0(rid, EINVAL);
     615                        async_answer_0(callid, EINVAL);
     616                        async_answer_0(rid, EINVAL);
    346617                        return;
    347618                }
     
    349620                /* Make a request at the driver */
    350621                ipc_call_t answer;
    351                 aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request),
     622                aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
    352623                    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    353624                    IPC_GET_ARG3(*request), &answer);
    354625               
    355626                /* Forward the IPC_M_DATA_READ request to the driver */
    356                 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     627                async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    357628                fibril_mutex_unlock(&devices_mutex);
    358629               
    359630                /* Wait for reply from the driver. */
    360                 ipcarg_t rc;
     631                sysarg_t rc;
    361632                async_wait_for(msg, &rc);
    362633                size_t bytes = IPC_GET_ARG1(answer);
    363634               
    364635                /* Driver reply is the final result of the whole operation */
    365                 ipc_answer_1(rid, rc, bytes);
    366         } else {
    367                 ipc_callid_t callid;
    368                 size_t size;
    369                 if (!ipc_data_read_receive(&callid, &size)) {
    370                         ipc_answer_0(callid, EINVAL);
    371                         ipc_answer_0(rid, EINVAL);
    372                         return;
    373                 }
    374                
    375                 size_t count = devmap_device_get_count();
    376                 dev_desc_t *desc = malloc(count * sizeof(dev_desc_t));
    377                 if (desc == NULL) {
    378                         ipc_answer_0(callid, ENOMEM);
    379                         ipc_answer_1(rid, ENOMEM, 0);
    380                         return;
    381                 }
    382                
    383                 size_t max = devmap_device_get_devices(count, desc);
    384                
    385                 if (pos < max) {
    386                         ipc_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    387                 } else {
    388                         ipc_answer_0(callid, ENOENT);
    389                         ipc_answer_1(rid, ENOENT, 0);
    390                         return;
    391                 }
    392                
    393                 free(desc);
    394                
    395                 ipc_answer_1(rid, EOK, 1);
    396         }
     636                async_answer_1(rid, rc, bytes);
     637                return;
     638        }
     639       
     640        async_answer_0(rid, ENOENT);
    397641}
    398642
     
    400644{
    401645        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    402         off_t pos = (off_t) IPC_GET_ARG3(*request);
    403        
    404         if (index != 0) {
     646        if (index == 0) {
     647                async_answer_0(rid, ENOTSUP);
     648                return;
     649        }
     650       
     651        devmap_handle_type_t type = devmap_handle_probe(index);
     652       
     653        if (type == DEV_HANDLE_NAMESPACE) {
     654                /* Namespace directory */
     655                async_answer_0(rid, ENOTSUP);
     656                return;
     657        }
     658       
     659        if (type == DEV_HANDLE_DEVICE) {
     660                /* Device node */
    405661                unsigned long key[] = {
    406662                        [DEVICES_KEY_HANDLE] = (unsigned long) index
     
    411667                if (lnk == NULL) {
    412668                        fibril_mutex_unlock(&devices_mutex);
    413                         ipc_answer_0(rid, ENOENT);
     669                        async_answer_0(rid, ENOENT);
    414670                        return;
    415671                }
    416672               
    417673                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     674                assert(dev->phone >= 0);
    418675               
    419676                ipc_callid_t callid;
    420                 if (!ipc_data_write_receive(&callid, NULL)) {
     677                if (!async_data_write_receive(&callid, NULL)) {
    421678                        fibril_mutex_unlock(&devices_mutex);
    422                         ipc_answer_0(callid, EINVAL);
    423                         ipc_answer_0(rid, EINVAL);
     679                        async_answer_0(callid, EINVAL);
     680                        async_answer_0(rid, EINVAL);
    424681                        return;
    425682                }
     
    427684                /* Make a request at the driver */
    428685                ipc_call_t answer;
    429                 aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request),
     686                aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
    430687                    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    431688                    IPC_GET_ARG3(*request), &answer);
    432689               
    433690                /* Forward the IPC_M_DATA_WRITE request to the driver */
    434                 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     691                async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    435692               
    436693                fibril_mutex_unlock(&devices_mutex);
    437694               
    438695                /* Wait for reply from the driver. */
    439                 ipcarg_t rc;
     696                sysarg_t rc;
    440697                async_wait_for(msg, &rc);
    441698                size_t bytes = IPC_GET_ARG1(answer);
    442699               
    443700                /* Driver reply is the final result of the whole operation */
    444                 ipc_answer_1(rid, rc, bytes);
    445         } else {
    446                 /* Read-only filesystem */
    447                 ipc_answer_0(rid, ENOTSUP);
    448         }
     701                async_answer_1(rid, rc, bytes);
     702                return;
     703        }
     704       
     705        async_answer_0(rid, ENOENT);
    449706}
    450707
    451708void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    452709{
    453         ipc_answer_0(rid, ENOTSUP);
     710        async_answer_0(rid, ENOTSUP);
    454711}
    455712
     
    458715        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    459716       
    460         if (index != 0) {
     717        if (index == 0) {
     718                async_answer_0(rid, EOK);
     719                return;
     720        }
     721       
     722        devmap_handle_type_t type = devmap_handle_probe(index);
     723       
     724        if (type == DEV_HANDLE_NAMESPACE) {
     725                /* Namespace directory */
     726                async_answer_0(rid, EOK);
     727                return;
     728        }
     729       
     730        if (type == DEV_HANDLE_DEVICE) {
    461731                unsigned long key[] = {
    462732                        [DEVICES_KEY_HANDLE] = (unsigned long) index
     
    467737                if (lnk == NULL) {
    468738                        fibril_mutex_unlock(&devices_mutex);
    469                         ipc_answer_0(rid, ENOENT);
     739                        async_answer_0(rid, ENOENT);
    470740                        return;
    471741                }
    472742               
    473743                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     744                assert(dev->phone >= 0);
    474745                dev->refcount--;
    475746               
    476747                if (dev->refcount == 0) {
    477                         ipc_hangup(dev->phone);
     748                        async_hangup(dev->phone);
    478749                        hash_table_remove(&devices, key, DEVICES_KEYS);
    479750                }
     
    481752                fibril_mutex_unlock(&devices_mutex);
    482753               
    483                 ipc_answer_0(rid, EOK);
    484         } else
    485                 ipc_answer_0(rid, ENOTSUP);
     754                async_answer_0(rid, EOK);
     755                return;
     756        }
     757       
     758        async_answer_0(rid, ENOENT);
    486759}
    487760
     
    490763        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    491764       
    492         if (index != 0) {
     765        if (index == 0) {
     766                async_answer_0(rid, EOK);
     767                return;
     768        }
     769       
     770        devmap_handle_type_t type = devmap_handle_probe(index);
     771       
     772        if (type == DEV_HANDLE_NAMESPACE) {
     773                /* Namespace directory */
     774                async_answer_0(rid, EOK);
     775                return;
     776        }
     777       
     778        if (type == DEV_HANDLE_DEVICE) {
    493779                unsigned long key[] = {
    494780                        [DEVICES_KEY_HANDLE] = (unsigned long) index
     
    499785                if (lnk == NULL) {
    500786                        fibril_mutex_unlock(&devices_mutex);
    501                         ipc_answer_0(rid, ENOENT);
     787                        async_answer_0(rid, ENOENT);
    502788                        return;
    503789                }
    504790               
    505791                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     792                assert(dev->phone >= 0);
    506793               
    507794                /* Make a request at the driver */
    508795                ipc_call_t answer;
    509                 aid_t msg = async_send_2(dev->phone, IPC_GET_METHOD(*request),
     796                aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request),
    510797                    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);
    511798               
     
    513800               
    514801                /* Wait for reply from the driver */
    515                 ipcarg_t rc;
     802                sysarg_t rc;
    516803                async_wait_for(msg, &rc);
    517804               
    518805                /* Driver reply is the final result of the whole operation */
    519                 ipc_answer_0(rid, rc);
    520         } else
    521                 ipc_answer_0(rid, ENOTSUP);
     806                async_answer_0(rid, rc);
     807                return;
     808        }
     809       
     810        async_answer_0(rid, ENOENT);
    522811}
    523812
    524813void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    525814{
    526         ipc_answer_0(rid, ENOTSUP);
     815        async_answer_0(rid, ENOTSUP);
    527816}
    528817
Note: See TracChangeset for help on using the changeset viewer.