Ignore:
File:
1 edited

Legend:

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

    rcfd630af refcebe1  
    5959typedef struct {
    6060        devmap_handle_t handle;
    61         int phone;              /**< When < 0, the structure is incomplete. */
     61        async_sess_t *sess;       /**< If NULL, the structure is incomplete. */
    6262        size_t refcount;
    6363        link_t link;
    64         fibril_condvar_t cv;    /**< Broadcast when completed. */
     64        fibril_condvar_t cv;      /**< Broadcast when completed. */
    6565} device_t;
    6666
     
    232232                };
    233233                link_t *lnk;
    234 
     234               
    235235                fibril_mutex_lock(&devices_mutex);
    236236restart:
     
    244244                       
    245245                        dev->handle = node->handle;
    246                         dev->phone = -1;        /* mark as incomplete */
     246                       
     247                        /* Mark as incomplete */
     248                        dev->sess = NULL;
    247249                        dev->refcount = 1;
    248250                        fibril_condvar_initialize(&dev->cv);
    249 
     251                       
    250252                        /*
    251253                         * Insert the incomplete device structure so that other
     
    254256                         */
    255257                        hash_table_insert(&devices, key, &dev->link);
    256 
     258                       
    257259                        /*
    258260                         * Drop the mutex to allow recursive devfs requests.
    259261                         */
    260262                        fibril_mutex_unlock(&devices_mutex);
    261 
    262                         int phone = devmap_device_connect(node->handle, 0);
    263 
     263                       
     264                        async_sess_t *sess = devmap_device_connect(EXCHANGE_SERIALIZE,
     265                            node->handle, 0);
     266                       
    264267                        fibril_mutex_lock(&devices_mutex);
    265 
     268                       
    266269                        /*
    267270                         * Notify possible waiters about this device structure
     
    269272                         */
    270273                        fibril_condvar_broadcast(&dev->cv);
    271 
    272                         if (phone < 0) {
     274                       
     275                        if (!sess) {
    273276                                /*
    274277                                 * Connecting failed, need to remove the
     
    277280                                hash_table_remove(&devices, key, DEVICES_KEYS);
    278281                                fibril_mutex_unlock(&devices_mutex);
    279 
     282                               
    280283                                return ENOENT;
    281284                        }
    282285                       
    283                         /* Set the correct phone. */
    284                         dev->phone = phone;
     286                        /* Set the correct session. */
     287                        dev->sess = sess;
    285288                } else {
    286289                        device_t *dev = hash_table_get_instance(lnk, device_t, link);
    287 
    288                         if (dev->phone < 0) {
     290                       
     291                        if (!dev->sess) {
    289292                                /*
    290293                                 * Wait until the device structure is completed
     
    398401       
    399402        return 1;
    400 }
    401 
    402 static char devfs_plb_get_char(unsigned pos)
    403 {
    404         return devfs_reg.plb_ro[pos % PLB_SIZE];
    405403}
    406404
     
    444442        .size_get = devfs_size_get,
    445443        .lnkcnt_get = devfs_lnkcnt_get,
    446         .plb_get_char = devfs_plb_get_char,
    447444        .is_directory = devfs_is_directory,
    448445        .is_file = devfs_is_file,
     
    459456}
    460457
    461 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    462 {
    463         char *opts;
    464        
    465         /* Accept the mount options */
    466         sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
    467             0, NULL);
    468         if (retval != EOK) {
    469                 async_answer_0(rid, retval);
    470                 return;
    471         }
    472        
    473         free(opts);
    474         async_answer_3(rid, EOK, 0, 0, 0);
    475 }
    476 
    477 void devfs_mount(ipc_callid_t rid, ipc_call_t *request)
    478 {
    479         libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    480 }
    481 
    482 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    483 {
    484         async_answer_0(rid, ENOTSUP);
    485 }
    486 
    487 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
    488 {
    489         libfs_unmount(&devfs_libfs_ops, rid, request);
    490 }
    491 
    492 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    493 {
    494         libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    495 }
    496 
    497 void 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 
    502 void 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 
    507 void 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        
     458static int devfs_mounted(devmap_handle_t devmap_handle, const char *opts,
     459    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     460{
     461        *index = 0;
     462        *size = 0;
     463        *lnkcnt = 0;
     464        return EOK;
     465}
     466
     467static int devfs_unmounted(devmap_handle_t devmap_handle)
     468{
     469        return ENOTSUP;
     470}
     471
     472static int
     473devfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     474    size_t *rbytes)
     475{
    513476        if (index == 0) {
    514477                ipc_callid_t callid;
     
    516479                if (!async_data_read_receive(&callid, &size)) {
    517480                        async_answer_0(callid, EINVAL);
    518                         async_answer_0(rid, EINVAL);
    519                         return;
     481                        return EINVAL;
    520482                }
    521483               
     
    537499                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    538500                        free(desc);
    539                         async_answer_1(rid, EOK, 1);
    540                         return;
     501                        *rbytes = 1;
     502                        return EOK;
    541503                }
    542504               
     
    552514                                async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    553515                                free(desc);
    554                                 async_answer_1(rid, EOK, 1);
    555                                 return;
     516                                *rbytes = 1;
     517                                return EOK;
    556518                        }
    557519                       
     
    560522               
    561523                async_answer_0(callid, ENOENT);
    562                 async_answer_1(rid, ENOENT, 0);
    563                 return;
     524                return ENOENT;
    564525        }
    565526       
     
    572533                if (!async_data_read_receive(&callid, &size)) {
    573534                        async_answer_0(callid, EINVAL);
    574                         async_answer_0(rid, EINVAL);
    575                         return;
     535                        return EINVAL;
    576536                }
    577537               
     
    582542                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    583543                        free(desc);
    584                         async_answer_1(rid, EOK, 1);
    585                         return;
     544                        *rbytes = 1;
     545                        return EOK;
    586546                }
    587547               
    588548                free(desc);
    589549                async_answer_0(callid, ENOENT);
    590                 async_answer_1(rid, ENOENT, 0);
    591                 return;
     550                return ENOENT;
    592551        }
    593552       
     
    603562                if (lnk == NULL) {
    604563                        fibril_mutex_unlock(&devices_mutex);
    605                         async_answer_0(rid, ENOENT);
    606                         return;
     564                        return ENOENT;
    607565                }
    608566               
    609567                device_t *dev = hash_table_get_instance(lnk, device_t, link);
    610                 assert(dev->phone >= 0);
     568                assert(dev->sess);
    611569               
    612570                ipc_callid_t callid;
     
    614572                        fibril_mutex_unlock(&devices_mutex);
    615573                        async_answer_0(callid, EINVAL);
    616                         async_answer_0(rid, EINVAL);
    617                         return;
     574                        return EINVAL;
    618575                }
    619576               
    620577                /* Make a request at the driver */
     578                async_exch_t *exch = async_exchange_begin(dev->sess);
     579               
    621580                ipc_call_t answer;
    622                 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
    623                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    624                     IPC_GET_ARG3(*request), &answer);
     581                aid_t msg = async_send_4(exch, VFS_OUT_READ, devmap_handle,
     582                    index, LOWER32(pos), UPPER32(pos), &answer);
    625583               
    626584                /* Forward the IPC_M_DATA_READ request to the driver */
    627                 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     585                async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     586               
     587                async_exchange_end(exch);
     588               
    628589                fibril_mutex_unlock(&devices_mutex);
    629590               
     
    631592                sysarg_t rc;
    632593                async_wait_for(msg, &rc);
    633                 size_t bytes = IPC_GET_ARG1(answer);
    634                
    635                 /* Driver reply is the final result of the whole operation */
    636                 async_answer_1(rid, rc, bytes);
    637                 return;
    638         }
    639        
    640         async_answer_0(rid, ENOENT);
    641 }
    642 
    643 void devfs_write(ipc_callid_t rid, ipc_call_t *request)
    644 {
    645         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    646         if (index == 0) {
    647                 async_answer_0(rid, ENOTSUP);
    648                 return;
    649         }
     594               
     595                *rbytes = IPC_GET_ARG1(answer);
     596                return rc;
     597        }
     598       
     599        return ENOENT;
     600}
     601
     602static int
     603devfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     604    size_t *wbytes, aoff64_t *nsize)
     605{
     606        if (index == 0)
     607                return ENOTSUP;
    650608       
    651609        devmap_handle_type_t type = devmap_handle_probe(index);
     
    653611        if (type == DEV_HANDLE_NAMESPACE) {
    654612                /* Namespace directory */
    655                 async_answer_0(rid, ENOTSUP);
    656                 return;
     613                return ENOTSUP;
    657614        }
    658615       
     
    667624                if (lnk == NULL) {
    668625                        fibril_mutex_unlock(&devices_mutex);
    669                         async_answer_0(rid, ENOENT);
    670                         return;
     626                        return ENOENT;
    671627                }
    672628               
    673629                device_t *dev = hash_table_get_instance(lnk, device_t, link);
    674                 assert(dev->phone >= 0);
     630                assert(dev->sess);
    675631               
    676632                ipc_callid_t callid;
     
    678634                        fibril_mutex_unlock(&devices_mutex);
    679635                        async_answer_0(callid, EINVAL);
    680                         async_answer_0(rid, EINVAL);
    681                         return;
     636                        return EINVAL;
    682637                }
    683638               
    684639                /* Make a request at the driver */
     640                async_exch_t *exch = async_exchange_begin(dev->sess);
     641               
    685642                ipc_call_t answer;
    686                 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
    687                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    688                     IPC_GET_ARG3(*request), &answer);
     643                aid_t msg = async_send_4(exch, VFS_OUT_WRITE, devmap_handle,
     644                    index, LOWER32(pos), UPPER32(pos), &answer);
    689645               
    690646                /* Forward the IPC_M_DATA_WRITE request to the driver */
    691                 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     647                async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     648               
     649                async_exchange_end(exch);
    692650               
    693651                fibril_mutex_unlock(&devices_mutex);
     
    696654                sysarg_t rc;
    697655                async_wait_for(msg, &rc);
    698                 size_t bytes = IPC_GET_ARG1(answer);
    699                
    700                 /* Driver reply is the final result of the whole operation */
    701                 async_answer_1(rid, rc, bytes);
    702                 return;
    703         }
    704        
    705         async_answer_0(rid, ENOENT);
    706 }
    707 
    708 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    709 {
    710         async_answer_0(rid, ENOTSUP);
    711 }
    712 
    713 void devfs_close(ipc_callid_t rid, ipc_call_t *request)
    714 {
    715         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    716        
    717         if (index == 0) {
    718                 async_answer_0(rid, EOK);
    719                 return;
    720         }
     656               
     657                *wbytes = IPC_GET_ARG1(answer);
     658                *nsize = 0;
     659                return rc;
     660        }
     661       
     662        return ENOENT;
     663}
     664
     665static int
     666devfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     667{
     668        return ENOTSUP;
     669}
     670
     671static int devfs_close(devmap_handle_t devmap_handle, fs_index_t index)
     672{
     673        if (index == 0)
     674                return EOK;
    721675       
    722676        devmap_handle_type_t type = devmap_handle_probe(index);
     
    724678        if (type == DEV_HANDLE_NAMESPACE) {
    725679                /* Namespace directory */
    726                 async_answer_0(rid, EOK);
    727                 return;
     680                return EOK;
    728681        }
    729682       
     
    737690                if (lnk == NULL) {
    738691                        fibril_mutex_unlock(&devices_mutex);
    739                         async_answer_0(rid, ENOENT);
    740                         return;
     692                        return ENOENT;
    741693                }
    742694               
    743695                device_t *dev = hash_table_get_instance(lnk, device_t, link);
    744                 assert(dev->phone >= 0);
     696                assert(dev->sess);
    745697                dev->refcount--;
    746698               
    747699                if (dev->refcount == 0) {
    748                         async_hangup(dev->phone);
     700                        async_hangup(dev->sess);
    749701                        hash_table_remove(&devices, key, DEVICES_KEYS);
    750702                }
     
    752704                fibril_mutex_unlock(&devices_mutex);
    753705               
    754                 async_answer_0(rid, EOK);
    755                 return;
    756         }
    757        
    758         async_answer_0(rid, ENOENT);
    759 }
    760 
    761 void devfs_sync(ipc_callid_t rid, ipc_call_t *request)
    762 {
    763         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    764        
    765         if (index == 0) {
    766                 async_answer_0(rid, EOK);
    767                 return;
    768         }
     706                return EOK;
     707        }
     708       
     709        return ENOENT;
     710}
     711
     712static int devfs_sync(devmap_handle_t devmap_handle, fs_index_t index)
     713{
     714        if (index == 0)
     715                return EOK;
    769716       
    770717        devmap_handle_type_t type = devmap_handle_probe(index);
     
    772719        if (type == DEV_HANDLE_NAMESPACE) {
    773720                /* Namespace directory */
    774                 async_answer_0(rid, EOK);
    775                 return;
     721                return EOK;
    776722        }
    777723       
     
    785731                if (lnk == NULL) {
    786732                        fibril_mutex_unlock(&devices_mutex);
    787                         async_answer_0(rid, ENOENT);
    788                         return;
     733                        return ENOENT;
    789734                }
    790735               
    791736                device_t *dev = hash_table_get_instance(lnk, device_t, link);
    792                 assert(dev->phone >= 0);
     737                assert(dev->sess);
    793738               
    794739                /* Make a request at the driver */
     740                async_exch_t *exch = async_exchange_begin(dev->sess);
     741               
    795742                ipc_call_t answer;
    796                 aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request),
    797                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);
     743                aid_t msg = async_send_2(exch, VFS_OUT_SYNC, devmap_handle,
     744                    index, &answer);
     745               
     746                async_exchange_end(exch);
    798747               
    799748                fibril_mutex_unlock(&devices_mutex);
     
    803752                async_wait_for(msg, &rc);
    804753               
    805                 /* Driver reply is the final result of the whole operation */
    806                 async_answer_0(rid, rc);
    807                 return;
    808         }
    809        
    810         async_answer_0(rid, ENOENT);
    811 }
    812 
    813 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    814 {
    815         async_answer_0(rid, ENOTSUP);
    816 }
     754                return rc;
     755        }
     756       
     757        return  ENOENT;
     758}
     759
     760static int devfs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     761{
     762        return ENOTSUP;
     763}
     764
     765vfs_out_ops_t devfs_ops = {
     766        .mounted = devfs_mounted,
     767        .unmounted = devfs_unmounted,
     768        .read = devfs_read,
     769        .write = devfs_write,
     770        .truncate = devfs_truncate,
     771        .close = devfs_close,
     772        .destroy = devfs_destroy,
     773        .sync = devfs_sync,
     774};
    817775
    818776/**
Note: See TracChangeset for help on using the changeset viewer.