Changes in uspace/srv/bd/rd/rd.c [135486d:faba839] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/rd/rd.c

    r135486d rfaba839  
    4343#include <sysinfo.h>
    4444#include <as.h>
    45 #include <bd_srv.h>
    4645#include <ddi.h>
    4746#include <align.h>
     
    5453#include <stdio.h>
    5554#include <loc.h>
     55#include <ipc/bd.h>
    5656#include <macros.h>
    5757#include <inttypes.h>
     
    6868static const size_t block_size = 512;
    6969
    70 static int rd_open(bd_srvs_t *, bd_srv_t *);
    71 static int rd_close(bd_srv_t *);
    72 static int rd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
    73 static int rd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
    74 static int rd_get_block_size(bd_srv_t *, size_t *);
    75 static int rd_get_num_blocks(bd_srv_t *, aoff64_t *);
     70static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf);
     71static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
    7672
    7773/** This rwlock protects the ramdisk's data.
     
    8278 *
    8379 */
    84 static fibril_rwlock_t rd_lock;
    85 
    86 static bd_ops_t rd_bd_ops = {
    87         .open = rd_open,
    88         .close = rd_close,
    89         .read_blocks = rd_read_blocks,
    90         .write_blocks = rd_write_blocks,
    91         .get_block_size = rd_get_block_size,
    92         .get_num_blocks = rd_get_num_blocks
    93 };
    94 
    95 static bd_srvs_t bd_srvs;
    96 
    97 static void rd_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    98 {
    99         bd_conn(iid, icall, &bd_srvs);
    100 }
    101 
    102 /** Open device. */
    103 static int rd_open(bd_srvs_t *bds, bd_srv_t *bd)
    104 {
    105         return EOK;
    106 }
    107 
    108 /** Close device. */
    109 static int rd_close(bd_srv_t *bd)
    110 {
    111         return EOK;
     80fibril_rwlock_t rd_lock;
     81
     82/** Handle one connection to ramdisk.
     83 *
     84 * @param iid   Hash of the request that opened the connection.
     85 * @param icall Call data of the request that opened the connection.
     86 */
     87static void rd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     88{
     89        ipc_callid_t callid;
     90        ipc_call_t call;
     91        int retval;
     92        void *fs_va = NULL;
     93        uint64_t ba;
     94        size_t cnt;
     95        size_t comm_size;
     96       
     97        /*
     98         * Answer the first IPC_M_CONNECT_ME_TO call.
     99         */
     100        async_answer_0(iid, EOK);
     101       
     102        /*
     103         * Now we wait for the client to send us its communication as_area.
     104         */
     105        unsigned int flags;
     106        if (async_share_out_receive(&callid, &comm_size, &flags)) {
     107                (void) async_share_out_finalize(callid, &fs_va);
     108                if (fs_va == AS_MAP_FAILED) {
     109                        async_answer_0(callid, EHANGUP);
     110                        return;
     111                }
     112        } else {
     113                /*
     114                 * The client doesn't speak the same protocol.
     115                 * At this point we can't handle protocol variations.
     116                 * Close the connection.
     117                 */
     118                async_answer_0(callid, EHANGUP);
     119                return;
     120        }
     121       
     122        while (true) {
     123                callid = async_get_call(&call);
     124               
     125                if (!IPC_GET_IMETHOD(call)) {
     126                        /*
     127                         * The other side has hung up.
     128                         * Exit the fibril.
     129                         */
     130                        async_answer_0(callid, EOK);
     131                        return;
     132                }
     133               
     134                switch (IPC_GET_IMETHOD(call)) {
     135                case BD_READ_BLOCKS:
     136                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     137                            IPC_GET_ARG2(call));
     138                        cnt = IPC_GET_ARG3(call);
     139                        if (cnt * block_size > comm_size) {
     140                                retval = ELIMIT;
     141                                break;
     142                        }
     143                        retval = rd_read_blocks(ba, cnt, fs_va);
     144                        break;
     145                case BD_WRITE_BLOCKS:
     146                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     147                            IPC_GET_ARG2(call));
     148                        cnt = IPC_GET_ARG3(call);
     149                        if (cnt * block_size > comm_size) {
     150                                retval = ELIMIT;
     151                                break;
     152                        }
     153                        retval = rd_write_blocks(ba, cnt, fs_va);
     154                        break;
     155                case BD_GET_BLOCK_SIZE:
     156                        async_answer_1(callid, EOK, block_size);
     157                        continue;
     158                case BD_GET_NUM_BLOCKS:
     159                        async_answer_2(callid, EOK, LOWER32(rd_size / block_size),
     160                            UPPER32(rd_size / block_size));
     161                        continue;
     162                default:
     163                        /*
     164                         * The client doesn't speak the same protocol.
     165                         * Instead of closing the connection, we just ignore
     166                         * the call. This can be useful if the client uses a
     167                         * newer version of the protocol.
     168                         */
     169                        retval = EINVAL;
     170                        break;
     171                }
     172                async_answer_0(callid, retval);
     173        }
    112174}
    113175
    114176/** Read blocks from the device. */
    115 static int rd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
    116     size_t size)
     177static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf)
    117178{
    118179        if ((ba + cnt) * block_size > rd_size) {
     
    122183       
    123184        fibril_rwlock_read_lock(&rd_lock);
    124         memcpy(buf, rd_addr + ba * block_size, min(block_size * cnt, size));
     185        memcpy(buf, rd_addr + ba * block_size, block_size * cnt);
    125186        fibril_rwlock_read_unlock(&rd_lock);
    126187       
     
    129190
    130191/** Write blocks to the device. */
    131 static int rd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
    132     const void *buf, size_t size)
     192static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
    133193{
    134194        if ((ba + cnt) * block_size > rd_size) {
     
    138198       
    139199        fibril_rwlock_write_lock(&rd_lock);
    140         memcpy(rd_addr + ba * block_size, buf, min(block_size * cnt, size));
     200        memcpy(rd_addr + ba * block_size, buf, block_size * cnt);
    141201        fibril_rwlock_write_unlock(&rd_lock);
    142202       
     
    175235            (void *) addr_phys, size);
    176236       
    177         bd_srvs_init(&bd_srvs);
    178         bd_srvs.ops = &rd_bd_ops;
    179        
    180         async_set_client_connection(rd_client_conn);
     237        async_set_client_connection(rd_connection);
    181238        ret = loc_server_register(NAME);
    182239        if (ret != EOK) {
     
    197254}
    198255
    199 /** Get device block size. */
    200 static int rd_get_block_size(bd_srv_t *bd, size_t *rsize)
    201 {
    202         *rsize = block_size;
    203         return EOK;
    204 }
    205 
    206 /** Get number of blocks on device. */
    207 static int rd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
    208 {
    209         *rnb = rd_size / block_size;
    210         return EOK;
    211 }
    212 
    213256int main(int argc, char **argv)
    214257{
Note: See TracChangeset for help on using the changeset viewer.