Ignore:
File:
1 edited

Legend:

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

    r19f857a rcfd630af  
    3636 */
    3737
    38 #include <ipc/ipc.h>
    3938#include <macros.h>
    4039#include <bool.h>
     
    5453typedef struct {
    5554        devmap_handle_type_t type;
    56         dev_handle_t handle;
     55        devmap_handle_t handle;
    5756} devfs_node_t;
    5857
    5958/** Opened devices structure */
    6059typedef struct {
    61         dev_handle_t handle;
    62         int phone;
     60        devmap_handle_t handle;
     61        int phone;              /**< When < 0, the structure is incomplete. */
    6362        size_t refcount;
    6463        link_t link;
     64        fibril_condvar_t cv;    /**< Broadcast when completed. */
    6565} device_t;
    6666
     
    8484{
    8585        device_t *dev = hash_table_get_instance(item, device_t, link);
    86         return (dev->handle == (dev_handle_t) key[DEVICES_KEY_HANDLE]);
     86        return (dev->handle == (devmap_handle_t) key[DEVICES_KEY_HANDLE]);
    8787}
    8888
     
    9999
    100100static int devfs_node_get_internal(fs_node_t **rfn, devmap_handle_type_t type,
    101     dev_handle_t handle)
     101    devmap_handle_t handle)
    102102{
    103103        devfs_node_t *node = (devfs_node_t *) malloc(sizeof(devfs_node_t));
     
    122122}
    123123
    124 static int devfs_root_get(fs_node_t **rfn, dev_handle_t dev_handle)
     124static int devfs_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
    125125{
    126126        return devfs_node_get_internal(rfn, DEV_HANDLE_NONE, 0);
     
    130130{
    131131        devfs_node_t *node = (devfs_node_t *) pfn->data;
     132        int ret;
    132133       
    133134        if (node->handle == 0) {
     
    145146                               
    146147                                if (str_cmp(devs[pos].name, component) == 0) {
     148                                        ret = devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle);
    147149                                        free(devs);
    148                                         return devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle);
     150                                        return ret;
    149151                                }
    150152                        }
     
    154156               
    155157                /* Search root namespace */
    156                 dev_handle_t namespace;
     158                devmap_handle_t namespace;
    157159                if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {
    158160                        count = devmap_get_devices(namespace, &devs);
     
    162164                                for (pos = 0; pos < count; pos++) {
    163165                                        if (str_cmp(devs[pos].name, component) == 0) {
     166                                                ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
    164167                                                free(devs);
    165                                                 return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
     168                                                return ret;
    166169                                        }
    167170                                }
     
    184187                        for (pos = 0; pos < count; pos++) {
    185188                                if (str_cmp(devs[pos].name, component) == 0) {
     189                                        ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
    186190                                        free(devs);
    187                                         return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
     191                                        return ret;
    188192                                }
    189193                        }
     
    200204}
    201205
    202 static int devfs_node_get(fs_node_t **rfn, dev_handle_t dev_handle, fs_index_t index)
     206static int devfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)
    203207{
    204208        return devfs_node_get_internal(rfn, devmap_handle_probe(index), index);
     
    227231                        [DEVICES_KEY_HANDLE] = (unsigned long) node->handle
    228232                };
    229                
     233                link_t *lnk;
     234
    230235                fibril_mutex_lock(&devices_mutex);
    231                 link_t *lnk = hash_table_find(&devices, key);
     236restart:
     237                lnk = hash_table_find(&devices, key);
    232238                if (lnk == NULL) {
    233239                        device_t *dev = (device_t *) malloc(sizeof(device_t));
     
    237243                        }
    238244                       
     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
    239262                        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
    240272                        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);
    241278                                fibril_mutex_unlock(&devices_mutex);
    242                                 free(dev);
     279
    243280                                return ENOENT;
    244281                        }
    245282                       
    246                         dev->handle = node->handle;
     283                        /* Set the correct phone. */
    247284                        dev->phone = phone;
    248                         dev->refcount = 1;
    249                        
    250                         hash_table_insert(&devices, key, &dev->link);
    251285                } else {
    252286                        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
    253300                        dev->refcount++;
    254301                }
     
    269316}
    270317
    271 static int devfs_create_node(fs_node_t **rfn, dev_handle_t dev_handle, int lflag)
     318static int devfs_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int lflag)
    272319{
    273320        assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
     
    304351               
    305352                /* Root namespace */
    306                 dev_handle_t namespace;
     353                devmap_handle_t namespace;
    307354                if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {
    308355                        count = devmap_count_devices(namespace);
     
    372419}
    373420
    374 static dev_handle_t devfs_device_get(fs_node_t *fn)
     421static devmap_handle_t devfs_device_get(fs_node_t *fn)
    375422{
    376423        devfs_node_t *node = (devfs_node_t *) fn->data;
     
    409456                return false;
    410457       
    411         if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0)
    412                 return false;
    413        
    414458        return true;
    415459}
     
    420464       
    421465        /* Accept the mount options */
    422         ipcarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
     466        sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
    423467            0, NULL);
    424468        if (retval != EOK) {
    425                 ipc_answer_0(rid, retval);
     469                async_answer_0(rid, retval);
    426470                return;
    427471        }
    428472       
    429473        free(opts);
    430         ipc_answer_3(rid, EOK, 0, 0, 0);
     474        async_answer_3(rid, EOK, 0, 0, 0);
    431475}
    432476
     
    438482void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    439483{
    440         ipc_answer_0(rid, ENOTSUP);
     484        async_answer_0(rid, ENOTSUP);
    441485}
    442486
     
    471515                size_t size;
    472516                if (!async_data_read_receive(&callid, &size)) {
    473                         ipc_answer_0(callid, EINVAL);
    474                         ipc_answer_0(rid, EINVAL);
     517                        async_answer_0(callid, EINVAL);
     518                        async_answer_0(rid, EINVAL);
    475519                        return;
    476520                }
     
    493537                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    494538                        free(desc);
    495                         ipc_answer_1(rid, EOK, 1);
     539                        async_answer_1(rid, EOK, 1);
    496540                        return;
    497541                }
     
    501545               
    502546                /* Search root namespace */
    503                 dev_handle_t namespace;
     547                devmap_handle_t namespace;
    504548                if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {
    505549                        count = devmap_get_devices(namespace, &desc);
     
    508552                                async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    509553                                free(desc);
    510                                 ipc_answer_1(rid, EOK, 1);
     554                                async_answer_1(rid, EOK, 1);
    511555                                return;
    512556                        }
     
    515559                }
    516560               
    517                 ipc_answer_0(callid, ENOENT);
    518                 ipc_answer_1(rid, ENOENT, 0);
     561                async_answer_0(callid, ENOENT);
     562                async_answer_1(rid, ENOENT, 0);
    519563                return;
    520564        }
     
    527571                size_t size;
    528572                if (!async_data_read_receive(&callid, &size)) {
    529                         ipc_answer_0(callid, EINVAL);
    530                         ipc_answer_0(rid, EINVAL);
     573                        async_answer_0(callid, EINVAL);
     574                        async_answer_0(rid, EINVAL);
    531575                        return;
    532576                }
     
    538582                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    539583                        free(desc);
    540                         ipc_answer_1(rid, EOK, 1);
     584                        async_answer_1(rid, EOK, 1);
    541585                        return;
    542586                }
    543587               
    544588                free(desc);
    545                 ipc_answer_0(callid, ENOENT);
    546                 ipc_answer_1(rid, ENOENT, 0);
     589                async_answer_0(callid, ENOENT);
     590                async_answer_1(rid, ENOENT, 0);
    547591                return;
    548592        }
     
    559603                if (lnk == NULL) {
    560604                        fibril_mutex_unlock(&devices_mutex);
    561                         ipc_answer_0(rid, ENOENT);
     605                        async_answer_0(rid, ENOENT);
    562606                        return;
    563607                }
    564608               
    565609                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     610                assert(dev->phone >= 0);
    566611               
    567612                ipc_callid_t callid;
    568613                if (!async_data_read_receive(&callid, NULL)) {
    569614                        fibril_mutex_unlock(&devices_mutex);
    570                         ipc_answer_0(callid, EINVAL);
    571                         ipc_answer_0(rid, EINVAL);
     615                        async_answer_0(callid, EINVAL);
     616                        async_answer_0(rid, EINVAL);
    572617                        return;
    573618                }
     
    575620                /* Make a request at the driver */
    576621                ipc_call_t answer;
    577                 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),
    578623                    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    579624                    IPC_GET_ARG3(*request), &answer);
    580625               
    581626                /* Forward the IPC_M_DATA_READ request to the driver */
    582                 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);
    583628                fibril_mutex_unlock(&devices_mutex);
    584629               
    585630                /* Wait for reply from the driver. */
    586                 ipcarg_t rc;
     631                sysarg_t rc;
    587632                async_wait_for(msg, &rc);
    588633                size_t bytes = IPC_GET_ARG1(answer);
    589634               
    590635                /* Driver reply is the final result of the whole operation */
    591                 ipc_answer_1(rid, rc, bytes);
    592                 return;
    593         }
    594        
    595         ipc_answer_0(rid, ENOENT);
     636                async_answer_1(rid, rc, bytes);
     637                return;
     638        }
     639       
     640        async_answer_0(rid, ENOENT);
    596641}
    597642
     
    600645        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    601646        if (index == 0) {
    602                 ipc_answer_0(rid, ENOTSUP);
     647                async_answer_0(rid, ENOTSUP);
    603648                return;
    604649        }
     
    608653        if (type == DEV_HANDLE_NAMESPACE) {
    609654                /* Namespace directory */
    610                 ipc_answer_0(rid, ENOTSUP);
     655                async_answer_0(rid, ENOTSUP);
    611656                return;
    612657        }
     
    622667                if (lnk == NULL) {
    623668                        fibril_mutex_unlock(&devices_mutex);
    624                         ipc_answer_0(rid, ENOENT);
     669                        async_answer_0(rid, ENOENT);
    625670                        return;
    626671                }
    627672               
    628673                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     674                assert(dev->phone >= 0);
    629675               
    630676                ipc_callid_t callid;
    631677                if (!async_data_write_receive(&callid, NULL)) {
    632678                        fibril_mutex_unlock(&devices_mutex);
    633                         ipc_answer_0(callid, EINVAL);
    634                         ipc_answer_0(rid, EINVAL);
     679                        async_answer_0(callid, EINVAL);
     680                        async_answer_0(rid, EINVAL);
    635681                        return;
    636682                }
     
    638684                /* Make a request at the driver */
    639685                ipc_call_t answer;
    640                 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),
    641687                    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    642688                    IPC_GET_ARG3(*request), &answer);
    643689               
    644690                /* Forward the IPC_M_DATA_WRITE request to the driver */
    645                 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);
    646692               
    647693                fibril_mutex_unlock(&devices_mutex);
    648694               
    649695                /* Wait for reply from the driver. */
    650                 ipcarg_t rc;
     696                sysarg_t rc;
    651697                async_wait_for(msg, &rc);
    652698                size_t bytes = IPC_GET_ARG1(answer);
    653699               
    654700                /* Driver reply is the final result of the whole operation */
    655                 ipc_answer_1(rid, rc, bytes);
    656                 return;
    657         }
    658        
    659         ipc_answer_0(rid, ENOENT);
     701                async_answer_1(rid, rc, bytes);
     702                return;
     703        }
     704       
     705        async_answer_0(rid, ENOENT);
    660706}
    661707
    662708void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    663709{
    664         ipc_answer_0(rid, ENOTSUP);
     710        async_answer_0(rid, ENOTSUP);
    665711}
    666712
     
    670716       
    671717        if (index == 0) {
    672                 ipc_answer_0(rid, EOK);
     718                async_answer_0(rid, EOK);
    673719                return;
    674720        }
     
    678724        if (type == DEV_HANDLE_NAMESPACE) {
    679725                /* Namespace directory */
    680                 ipc_answer_0(rid, EOK);
     726                async_answer_0(rid, EOK);
    681727                return;
    682728        }
     
    691737                if (lnk == NULL) {
    692738                        fibril_mutex_unlock(&devices_mutex);
    693                         ipc_answer_0(rid, ENOENT);
     739                        async_answer_0(rid, ENOENT);
    694740                        return;
    695741                }
    696742               
    697743                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     744                assert(dev->phone >= 0);
    698745                dev->refcount--;
    699746               
    700747                if (dev->refcount == 0) {
    701                         ipc_hangup(dev->phone);
     748                        async_hangup(dev->phone);
    702749                        hash_table_remove(&devices, key, DEVICES_KEYS);
    703750                }
     
    705752                fibril_mutex_unlock(&devices_mutex);
    706753               
    707                 ipc_answer_0(rid, EOK);
    708                 return;
    709         }
    710        
    711         ipc_answer_0(rid, ENOENT);
     754                async_answer_0(rid, EOK);
     755                return;
     756        }
     757       
     758        async_answer_0(rid, ENOENT);
    712759}
    713760
     
    717764       
    718765        if (index == 0) {
    719                 ipc_answer_0(rid, EOK);
     766                async_answer_0(rid, EOK);
    720767                return;
    721768        }
     
    725772        if (type == DEV_HANDLE_NAMESPACE) {
    726773                /* Namespace directory */
    727                 ipc_answer_0(rid, EOK);
     774                async_answer_0(rid, EOK);
    728775                return;
    729776        }
     
    738785                if (lnk == NULL) {
    739786                        fibril_mutex_unlock(&devices_mutex);
    740                         ipc_answer_0(rid, ENOENT);
     787                        async_answer_0(rid, ENOENT);
    741788                        return;
    742789                }
    743790               
    744791                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     792                assert(dev->phone >= 0);
    745793               
    746794                /* Make a request at the driver */
    747795                ipc_call_t answer;
    748                 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),
    749797                    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);
    750798               
     
    752800               
    753801                /* Wait for reply from the driver */
    754                 ipcarg_t rc;
     802                sysarg_t rc;
    755803                async_wait_for(msg, &rc);
    756804               
    757805                /* Driver reply is the final result of the whole operation */
    758                 ipc_answer_0(rid, rc);
    759                 return;
    760         }
    761        
    762         ipc_answer_0(rid, ENOENT);
     806                async_answer_0(rid, rc);
     807                return;
     808        }
     809       
     810        async_answer_0(rid, ENOENT);
    763811}
    764812
    765813void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    766814{
    767         ipc_answer_0(rid, ENOTSUP);
     815        async_answer_0(rid, ENOTSUP);
    768816}
    769817
Note: See TracChangeset for help on using the changeset viewer.