Changes in uspace/srv/bd/rd/rd.c [faba839:4802dd7] in mainline


Ignore:
File:
1 edited

Legend:

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

    rfaba839 r4802dd7  
    4343#include <sysinfo.h>
    4444#include <as.h>
     45#include <bd_srv.h>
    4546#include <ddi.h>
    4647#include <align.h>
     
    5354#include <stdio.h>
    5455#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_read_blocks(uint64_t ba, size_t cnt, void *buf);
    71 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
     70static int rd_open(bd_srv_t *);
     71static int rd_close(bd_srv_t *);
     72static int rd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     73static int rd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     74static int rd_get_block_size(bd_srv_t *, size_t *);
     75static int rd_get_num_blocks(bd_srv_t *, aoff64_t *);
    7276
    7377/** This rwlock protects the ramdisk's data.
     
    7882 *
    7983 */
    80 fibril_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  */
    87 static 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         }
     84static fibril_rwlock_t rd_lock;
     85
     86static 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
     95static bd_srv_t bd_srv;
     96
     97static void rd_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     98{
     99        bd_conn(iid, icall, &bd_srv);
     100}
     101
     102/** Open device. */
     103static int rd_open(bd_srv_t *bd)
     104{
     105        return EOK;
     106}
     107
     108/** Close device. */
     109static int rd_close(bd_srv_t *bd)
     110{
     111        return EOK;
    174112}
    175113
    176114/** Read blocks from the device. */
    177 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf)
     115static int rd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
     116    size_t size)
    178117{
    179118        if ((ba + cnt) * block_size > rd_size) {
     
    183122       
    184123        fibril_rwlock_read_lock(&rd_lock);
    185         memcpy(buf, rd_addr + ba * block_size, block_size * cnt);
     124        memcpy(buf, rd_addr + ba * block_size, min(block_size * cnt, size));
    186125        fibril_rwlock_read_unlock(&rd_lock);
    187126       
     
    190129
    191130/** Write blocks to the device. */
    192 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
     131static int rd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     132    const void *buf, size_t size)
    193133{
    194134        if ((ba + cnt) * block_size > rd_size) {
     
    198138       
    199139        fibril_rwlock_write_lock(&rd_lock);
    200         memcpy(rd_addr + ba * block_size, buf, block_size * cnt);
     140        memcpy(rd_addr + ba * block_size, buf, min(block_size * cnt, size));
    201141        fibril_rwlock_write_unlock(&rd_lock);
    202142       
     
    235175            (void *) addr_phys, size);
    236176       
    237         async_set_client_connection(rd_connection);
     177        bd_srv_init(&bd_srv);
     178        bd_srv.ops = &rd_bd_ops;
     179       
     180        async_set_client_connection(rd_client_conn);
    238181        ret = loc_server_register(NAME);
    239182        if (ret != EOK) {
     
    254197}
    255198
     199/** Get device block size. */
     200static 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. */
     207static int rd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     208{
     209        *rnb = rd_size / block_size;
     210        return EOK;
     211}
     212
    256213int main(int argc, char **argv)
    257214{
Note: See TracChangeset for help on using the changeset viewer.