Ignore:
File:
1 edited

Legend:

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

    r991f645 rb366a1bc  
    3636 */
    3737
    38 #include <ipc/ipc.h>
    3938#include <macros.h>
    4039#include <bool.h>
     
    6059typedef struct {
    6160        devmap_handle_t handle;
    62         int phone;
     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
     
    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                        }
     
    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                        }
     
    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);
     279
    242280                                free(dev);
    243281                                return ENOENT;
    244282                        }
    245283                       
    246                         dev->handle = node->handle;
     284                        /* Set the correct phone. */
    247285                        dev->phone = phone;
    248                         dev->refcount = 1;
    249                        
    250                         hash_table_insert(&devices, key, &dev->link);
    251286                } else {
    252287                        device_t *dev = hash_table_get_instance(lnk, device_t, link);
     288
     289                        if (dev->phone < 0) {
     290                                /*
     291                                 * Wait until the device structure is completed
     292                                 * and start from the beginning as the device
     293                                 * structure might have entirely disappeared
     294                                 * while we were not holding the mutex in
     295                                 * fibril_condvar_wait().
     296                                 */
     297                                fibril_condvar_wait(&dev->cv, &devices_mutex);
     298                                goto restart;
     299                        }
     300
    253301                        dev->refcount++;
    254302                }
     
    409457                return false;
    410458       
    411         if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0)
    412                 return false;
    413        
    414459        return true;
    415460}
     
    420465       
    421466        /* Accept the mount options */
    422         ipcarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
     467        sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
    423468            0, NULL);
    424469        if (retval != EOK) {
    425                 ipc_answer_0(rid, retval);
     470                async_answer_0(rid, retval);
    426471                return;
    427472        }
    428473       
    429474        free(opts);
    430         ipc_answer_3(rid, EOK, 0, 0, 0);
     475        async_answer_3(rid, EOK, 0, 0, 0);
    431476}
    432477
     
    438483void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    439484{
    440         ipc_answer_0(rid, ENOTSUP);
     485        async_answer_0(rid, ENOTSUP);
    441486}
    442487
     
    471516                size_t size;
    472517                if (!async_data_read_receive(&callid, &size)) {
    473                         ipc_answer_0(callid, EINVAL);
    474                         ipc_answer_0(rid, EINVAL);
     518                        async_answer_0(callid, EINVAL);
     519                        async_answer_0(rid, EINVAL);
    475520                        return;
    476521                }
     
    493538                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    494539                        free(desc);
    495                         ipc_answer_1(rid, EOK, 1);
     540                        async_answer_1(rid, EOK, 1);
    496541                        return;
    497542                }
     
    508553                                async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    509554                                free(desc);
    510                                 ipc_answer_1(rid, EOK, 1);
     555                                async_answer_1(rid, EOK, 1);
    511556                                return;
    512557                        }
     
    515560                }
    516561               
    517                 ipc_answer_0(callid, ENOENT);
    518                 ipc_answer_1(rid, ENOENT, 0);
     562                async_answer_0(callid, ENOENT);
     563                async_answer_1(rid, ENOENT, 0);
    519564                return;
    520565        }
     
    527572                size_t size;
    528573                if (!async_data_read_receive(&callid, &size)) {
    529                         ipc_answer_0(callid, EINVAL);
    530                         ipc_answer_0(rid, EINVAL);
     574                        async_answer_0(callid, EINVAL);
     575                        async_answer_0(rid, EINVAL);
    531576                        return;
    532577                }
     
    538583                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    539584                        free(desc);
    540                         ipc_answer_1(rid, EOK, 1);
     585                        async_answer_1(rid, EOK, 1);
    541586                        return;
    542587                }
    543588               
    544589                free(desc);
    545                 ipc_answer_0(callid, ENOENT);
    546                 ipc_answer_1(rid, ENOENT, 0);
     590                async_answer_0(callid, ENOENT);
     591                async_answer_1(rid, ENOENT, 0);
    547592                return;
    548593        }
     
    559604                if (lnk == NULL) {
    560605                        fibril_mutex_unlock(&devices_mutex);
    561                         ipc_answer_0(rid, ENOENT);
     606                        async_answer_0(rid, ENOENT);
    562607                        return;
    563608                }
    564609               
    565610                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     611                assert(dev->phone >= 0);
    566612               
    567613                ipc_callid_t callid;
    568614                if (!async_data_read_receive(&callid, NULL)) {
    569615                        fibril_mutex_unlock(&devices_mutex);
    570                         ipc_answer_0(callid, EINVAL);
    571                         ipc_answer_0(rid, EINVAL);
     616                        async_answer_0(callid, EINVAL);
     617                        async_answer_0(rid, EINVAL);
    572618                        return;
    573619                }
     
    575621                /* Make a request at the driver */
    576622                ipc_call_t answer;
    577                 aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request),
     623                aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
    578624                    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    579625                    IPC_GET_ARG3(*request), &answer);
    580626               
    581627                /* 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);
     628                async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    583629                fibril_mutex_unlock(&devices_mutex);
    584630               
    585631                /* Wait for reply from the driver. */
    586                 ipcarg_t rc;
     632                sysarg_t rc;
    587633                async_wait_for(msg, &rc);
    588634                size_t bytes = IPC_GET_ARG1(answer);
    589635               
    590636                /* 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);
     637                async_answer_1(rid, rc, bytes);
     638                return;
     639        }
     640       
     641        async_answer_0(rid, ENOENT);
    596642}
    597643
     
    600646        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    601647        if (index == 0) {
    602                 ipc_answer_0(rid, ENOTSUP);
     648                async_answer_0(rid, ENOTSUP);
    603649                return;
    604650        }
     
    608654        if (type == DEV_HANDLE_NAMESPACE) {
    609655                /* Namespace directory */
    610                 ipc_answer_0(rid, ENOTSUP);
     656                async_answer_0(rid, ENOTSUP);
    611657                return;
    612658        }
     
    622668                if (lnk == NULL) {
    623669                        fibril_mutex_unlock(&devices_mutex);
    624                         ipc_answer_0(rid, ENOENT);
     670                        async_answer_0(rid, ENOENT);
    625671                        return;
    626672                }
    627673               
    628674                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     675                assert(dev->phone >= 0);
    629676               
    630677                ipc_callid_t callid;
    631678                if (!async_data_write_receive(&callid, NULL)) {
    632679                        fibril_mutex_unlock(&devices_mutex);
    633                         ipc_answer_0(callid, EINVAL);
    634                         ipc_answer_0(rid, EINVAL);
     680                        async_answer_0(callid, EINVAL);
     681                        async_answer_0(rid, EINVAL);
    635682                        return;
    636683                }
     
    638685                /* Make a request at the driver */
    639686                ipc_call_t answer;
    640                 aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request),
     687                aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
    641688                    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    642689                    IPC_GET_ARG3(*request), &answer);
    643690               
    644691                /* 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);
     692                async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    646693               
    647694                fibril_mutex_unlock(&devices_mutex);
    648695               
    649696                /* Wait for reply from the driver. */
    650                 ipcarg_t rc;
     697                sysarg_t rc;
    651698                async_wait_for(msg, &rc);
    652699                size_t bytes = IPC_GET_ARG1(answer);
    653700               
    654701                /* 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);
     702                async_answer_1(rid, rc, bytes);
     703                return;
     704        }
     705       
     706        async_answer_0(rid, ENOENT);
    660707}
    661708
    662709void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    663710{
    664         ipc_answer_0(rid, ENOTSUP);
     711        async_answer_0(rid, ENOTSUP);
    665712}
    666713
     
    670717       
    671718        if (index == 0) {
    672                 ipc_answer_0(rid, EOK);
     719                async_answer_0(rid, EOK);
    673720                return;
    674721        }
     
    678725        if (type == DEV_HANDLE_NAMESPACE) {
    679726                /* Namespace directory */
    680                 ipc_answer_0(rid, EOK);
     727                async_answer_0(rid, EOK);
    681728                return;
    682729        }
     
    691738                if (lnk == NULL) {
    692739                        fibril_mutex_unlock(&devices_mutex);
    693                         ipc_answer_0(rid, ENOENT);
     740                        async_answer_0(rid, ENOENT);
    694741                        return;
    695742                }
    696743               
    697744                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     745                assert(dev->phone >= 0);
    698746                dev->refcount--;
    699747               
    700748                if (dev->refcount == 0) {
    701                         ipc_hangup(dev->phone);
     749                        async_hangup(dev->phone);
    702750                        hash_table_remove(&devices, key, DEVICES_KEYS);
    703751                }
     
    705753                fibril_mutex_unlock(&devices_mutex);
    706754               
    707                 ipc_answer_0(rid, EOK);
    708                 return;
    709         }
    710        
    711         ipc_answer_0(rid, ENOENT);
     755                async_answer_0(rid, EOK);
     756                return;
     757        }
     758       
     759        async_answer_0(rid, ENOENT);
    712760}
    713761
     
    717765       
    718766        if (index == 0) {
    719                 ipc_answer_0(rid, EOK);
     767                async_answer_0(rid, EOK);
    720768                return;
    721769        }
     
    725773        if (type == DEV_HANDLE_NAMESPACE) {
    726774                /* Namespace directory */
    727                 ipc_answer_0(rid, EOK);
     775                async_answer_0(rid, EOK);
    728776                return;
    729777        }
     
    738786                if (lnk == NULL) {
    739787                        fibril_mutex_unlock(&devices_mutex);
    740                         ipc_answer_0(rid, ENOENT);
     788                        async_answer_0(rid, ENOENT);
    741789                        return;
    742790                }
    743791               
    744792                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     793                assert(dev->phone >= 0);
    745794               
    746795                /* Make a request at the driver */
    747796                ipc_call_t answer;
    748                 aid_t msg = async_send_2(dev->phone, IPC_GET_METHOD(*request),
     797                aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request),
    749798                    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);
    750799               
     
    752801               
    753802                /* Wait for reply from the driver */
    754                 ipcarg_t rc;
     803                sysarg_t rc;
    755804                async_wait_for(msg, &rc);
    756805               
    757806                /* 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);
     807                async_answer_0(rid, rc);
     808                return;
     809        }
     810       
     811        async_answer_0(rid, ENOENT);
    763812}
    764813
    765814void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    766815{
    767         ipc_answer_0(rid, ENOTSUP);
     816        async_answer_0(rid, ENOTSUP);
    768817}
    769818
Note: See TracChangeset for help on using the changeset viewer.