Changes in uspace/srv/bd/rd/rd.c [52e4f526:47b7006] in mainline


Ignore:
File:
1 edited

Legend:

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

    r52e4f526 r47b7006  
    3232/** @addtogroup rd
    3333 * @{
    34  */ 
     34 */
    3535
    3636/**
    37  * @file        rd.c
    38  * @brief       Initial RAM disk for HelenOS.
    39  */
    40 
    41 #include <ipc/ipc.h>
     37 * @file rd.c
     38 * @brief Initial RAM disk for HelenOS.
     39 */
     40
    4241#include <ipc/services.h>
    4342#include <ipc/ns.h>
     
    5150#include <align.h>
    5251#include <async.h>
    53 #include <fibril_sync.h>
     52#include <fibril_synch.h>
    5453#include <stdio.h>
    5554#include <devmap.h>
    5655#include <ipc/bd.h>
     56#include <macros.h>
    5757
    5858#define NAME "rd"
    5959
    60 /** Pointer to the ramdisk's image. */
     60/** Pointer to the ramdisk's image */
    6161static void *rd_addr;
    62 /** Size of the ramdisk. */
     62
     63/** Size of the ramdisk */
    6364static size_t rd_size;
    6465
    65 /**
    66  * This rwlock protects the ramdisk's data.
     66/** Block size */
     67static const size_t block_size = 512;
     68
     69static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf);
     70static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
     71
     72/** This rwlock protects the ramdisk's data.
     73 *
    6774 * If we were to serve multiple requests (read + write or several writes)
    68  * concurrently (i.e. from two or more threads), each read and write needs to be
    69  * protected by this rwlock.
    70  */
     75 * concurrently (i.e. from two or more threads), each read and write needs to
     76 * be protected by this rwlock.
     77 *
     78 */
    7179fibril_rwlock_t rd_lock;
    7280
    7381/** Handle one connection to ramdisk.
    7482 *
    75  * @param iid           Hash of the request that opened the connection.
    76  * @param icall         Call data of the request that opened the connection.
     83 * @param iid   Hash of the request that opened the connection.
     84 * @param icall Call data of the request that opened the connection.
    7785 */
    7886static void rd_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    8290        int retval;
    8391        void *fs_va = NULL;
    84         off_t offset;
    85         size_t block_size;
    86         size_t maxblock_size;
    87 
     92        uint64_t ba;
     93        size_t cnt;
     94        size_t comm_size;
     95       
    8896        /*
    8997         * Answer the first IPC_M_CONNECT_ME_TO call.
    9098         */
    91         ipc_answer_0(iid, EOK);
    92 
     99        async_answer_0(iid, EOK);
     100       
    93101        /*
    94102         * Now we wait for the client to send us its communication as_area.
    95103         */
    96         int flags;
    97         if (ipc_share_out_receive(&callid, &maxblock_size, &flags)) {
    98                 fs_va = as_get_mappable_page(maxblock_size);
     104        unsigned int flags;
     105        if (async_share_out_receive(&callid, &comm_size, &flags)) {
     106                fs_va = as_get_mappable_page(comm_size);
    99107                if (fs_va) {
    100                         (void) ipc_share_out_finalize(callid, fs_va);
     108                        (void) async_share_out_finalize(callid, fs_va);
    101109                } else {
    102                         ipc_answer_0(callid, EHANGUP);
    103                         return;         
     110                        async_answer_0(callid, EHANGUP);
     111                        return;
    104112                }
    105113        } else {
     
    109117                 * Close the connection.
    110118                 */
    111                 ipc_answer_0(callid, EHANGUP);
     119                async_answer_0(callid, EHANGUP);
    112120                return;
    113121        }
     
    115123        while (true) {
    116124                callid = async_get_call(&call);
    117                 switch (IPC_GET_METHOD(call)) {
     125                switch (IPC_GET_IMETHOD(call)) {
    118126                case IPC_M_PHONE_HUNGUP:
    119127                        /*
     
    121129                         * Answer the message and exit the fibril.
    122130                         */
    123                         ipc_answer_0(callid, EOK);
     131                        async_answer_0(callid, EOK);
    124132                        return;
    125                 case BD_READ_BLOCK:
    126                         offset = IPC_GET_ARG1(call);
    127                         block_size = IPC_GET_ARG2(call);
    128                         if (block_size > maxblock_size) {
    129                                 /*
    130                                  * Maximum block size exceeded.
    131                                  */
     133                case BD_READ_BLOCKS:
     134                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     135                            IPC_GET_ARG2(call));
     136                        cnt = IPC_GET_ARG3(call);
     137                        if (cnt * block_size > comm_size) {
    132138                                retval = ELIMIT;
    133139                                break;
    134140                        }
    135                         if (offset * block_size > rd_size - block_size) {
    136                                 /*
    137                                  * Reading past the end of the device.
    138                                  */
     141                        retval = rd_read_blocks(ba, cnt, fs_va);
     142                        break;
     143                case BD_WRITE_BLOCKS:
     144                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     145                            IPC_GET_ARG2(call));
     146                        cnt = IPC_GET_ARG3(call);
     147                        if (cnt * block_size > comm_size) {
    139148                                retval = ELIMIT;
    140149                                break;
    141150                        }
    142                         fibril_rwlock_read_lock(&rd_lock);
    143                         memcpy(fs_va, rd_addr + offset * block_size, block_size);
    144                         fibril_rwlock_read_unlock(&rd_lock);
    145                         retval = EOK;
     151                        retval = rd_write_blocks(ba, cnt, fs_va);
    146152                        break;
    147                 case BD_WRITE_BLOCK:
    148                         offset = IPC_GET_ARG1(call);
    149                         block_size = IPC_GET_ARG2(call);
    150                         if (block_size > maxblock_size) {
    151                                 /*
    152                                  * Maximum block size exceeded.
    153                                  */
    154                                 retval = ELIMIT;
    155                                 break;
    156                         }
    157                         if (offset * block_size > rd_size - block_size) {
    158                                 /*
    159                                  * Writing past the end of the device.
    160                                  */
    161                                 retval = ELIMIT;
    162                                 break;
    163                         }
    164                         fibril_rwlock_write_lock(&rd_lock);
    165                         memcpy(rd_addr + offset * block_size, fs_va, block_size);
    166                         fibril_rwlock_write_unlock(&rd_lock);
    167                         retval = EOK;
    168                         break;
     153                case BD_GET_BLOCK_SIZE:
     154                        async_answer_1(callid, EOK, block_size);
     155                        continue;
     156                case BD_GET_NUM_BLOCKS:
     157                        async_answer_2(callid, EOK, LOWER32(rd_size / block_size),
     158                            UPPER32(rd_size / block_size));
     159                        continue;
    169160                default:
    170161                        /*
     
    177168                        break;
    178169                }
    179                 ipc_answer_0(callid, retval);
    180         }
     170                async_answer_0(callid, retval);
     171        }
     172}
     173
     174/** Read blocks from the device. */
     175static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf)
     176{
     177        if ((ba + cnt) * block_size > rd_size) {
     178                /* Reading past the end of the device. */
     179                return ELIMIT;
     180        }
     181       
     182        fibril_rwlock_read_lock(&rd_lock);
     183        memcpy(buf, rd_addr + ba * block_size, block_size * cnt);
     184        fibril_rwlock_read_unlock(&rd_lock);
     185       
     186        return EOK;
     187}
     188
     189/** Write blocks to the device. */
     190static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
     191{
     192        if ((ba + cnt) * block_size > rd_size) {
     193                /* Writing past the end of the device. */
     194                return ELIMIT;
     195        }
     196       
     197        fibril_rwlock_write_lock(&rd_lock);
     198        memcpy(rd_addr + ba * block_size, buf, block_size * cnt);
     199        fibril_rwlock_write_unlock(&rd_lock);
     200       
     201        return EOK;
    181202}
    182203
     
    184205static bool rd_init(void)
    185206{
    186         rd_size = sysinfo_value("rd.size");
    187         void *rd_ph_addr = (void *) sysinfo_value("rd.address.physical");
    188        
    189         if (rd_size == 0) {
    190                 printf(NAME ": No RAM disk found\n");
     207        int ret = sysinfo_get_value("rd.size", &rd_size);
     208        if ((ret != EOK) || (rd_size == 0)) {
     209                printf("%s: No RAM disk found\n", NAME);
     210                return false;
     211        }
     212       
     213        sysarg_t rd_ph_addr;
     214        ret = sysinfo_get_value("rd.address.physical", &rd_ph_addr);
     215        if ((ret != EOK) || (rd_ph_addr == 0)) {
     216                printf("%s: Invalid RAM disk physical address\n", NAME);
    191217                return false;
    192218        }
     
    195221       
    196222        int flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
    197         int retval = physmem_map(rd_ph_addr, rd_addr,
     223        int retval = physmem_map((void *) rd_ph_addr, rd_addr,
    198224            ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
    199225       
    200226        if (retval < 0) {
    201                 printf(NAME ": Error mapping RAM disk\n");
    202                 return false;
    203         }
    204        
    205         printf(NAME ": Found RAM disk at %p, %d bytes\n", rd_ph_addr, rd_size);
     227                printf("%s: Error mapping RAM disk\n", NAME);
     228                return false;
     229        }
     230       
     231        printf("%s: Found RAM disk at %p, %zu bytes\n", NAME,
     232            (void *) rd_ph_addr, rd_size);
    206233       
    207234        int rc = devmap_driver_register(NAME, rd_connection);
    208235        if (rc < 0) {
    209                 printf(NAME ": Unable to register driver (%d)\n", rc);
    210                 return false;
    211         }
    212        
    213         dev_handle_t dev_handle;
    214         if (devmap_device_register("initrd", &dev_handle) != EOK) {
    215                 devmap_hangup_phone(DEVMAP_DRIVER);
    216                 printf(NAME ": Unable to register device\n");
     236                printf("%s: Unable to register driver (%d)\n", NAME, rc);
     237                return false;
     238        }
     239       
     240        devmap_handle_t devmap_handle;
     241        if (devmap_device_register("bd/initrd", &devmap_handle) != EOK) {
     242                printf("%s: Unable to register device\n", NAME);
    217243                return false;
    218244        }
     
    225251int main(int argc, char **argv)
    226252{
    227         printf(NAME ": HelenOS RAM disk server\n");
     253        printf("%s: HelenOS RAM disk server\n", NAME);
    228254       
    229255        if (!rd_init())
    230256                return -1;
    231257       
    232         printf(NAME ": Accepting connections\n");
     258        printf("%s: Accepting connections\n", NAME);
    233259        async_manager();
    234260
Note: See TracChangeset for help on using the changeset viewer.