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


Ignore:
File:
1 edited

Legend:

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

    r47b7006 r52e4f52  
    3232/** @addtogroup rd
    3333 * @{
    34  */
     34 */ 
    3535
    3636/**
    37  * @file rd.c
    38  * @brief Initial RAM disk for HelenOS.
    39  */
    40 
     37 * @file        rd.c
     38 * @brief       Initial RAM disk for HelenOS.
     39 */
     40
     41#include <ipc/ipc.h>
    4142#include <ipc/services.h>
    4243#include <ipc/ns.h>
     
    5051#include <align.h>
    5152#include <async.h>
    52 #include <fibril_synch.h>
     53#include <fibril_sync.h>
    5354#include <stdio.h>
    5455#include <devmap.h>
    5556#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 
    63 /** Size of the ramdisk */
     62/** Size of the ramdisk. */
    6463static size_t rd_size;
    6564
    66 /** Block size */
    67 static const size_t block_size = 512;
    68 
    69 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf);
    70 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
    71 
    72 /** This rwlock protects the ramdisk's data.
    73  *
     65/**
     66 * This rwlock protects the ramdisk's data.
    7467 * If we were to serve multiple requests (read + write or several writes)
    75  * concurrently (i.e. from two or more threads), each read and write needs to
    76  * be protected by this rwlock.
    77  *
    78  */
     68 * concurrently (i.e. from two or more threads), each read and write needs to be
     69 * protected by this rwlock.
     70 */
    7971fibril_rwlock_t rd_lock;
    8072
    8173/** Handle one connection to ramdisk.
    8274 *
    83  * @param iid   Hash of the request that opened the connection.
    84  * @param icall Call data of the request that opened the connection.
     75 * @param iid           Hash of the request that opened the connection.
     76 * @param icall         Call data of the request that opened the connection.
    8577 */
    8678static void rd_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    9082        int retval;
    9183        void *fs_va = NULL;
    92         uint64_t ba;
    93         size_t cnt;
    94         size_t comm_size;
    95        
     84        off_t offset;
     85        size_t block_size;
     86        size_t maxblock_size;
     87
    9688        /*
    9789         * Answer the first IPC_M_CONNECT_ME_TO call.
    9890         */
    99         async_answer_0(iid, EOK);
    100        
     91        ipc_answer_0(iid, EOK);
     92
    10193        /*
    10294         * Now we wait for the client to send us its communication as_area.
    10395         */
    104         unsigned int flags;
    105         if (async_share_out_receive(&callid, &comm_size, &flags)) {
    106                 fs_va = as_get_mappable_page(comm_size);
     96        int flags;
     97        if (ipc_share_out_receive(&callid, &maxblock_size, &flags)) {
     98                fs_va = as_get_mappable_page(maxblock_size);
    10799                if (fs_va) {
    108                         (void) async_share_out_finalize(callid, fs_va);
     100                        (void) ipc_share_out_finalize(callid, fs_va);
    109101                } else {
    110                         async_answer_0(callid, EHANGUP);
    111                         return;
     102                        ipc_answer_0(callid, EHANGUP);
     103                        return;         
    112104                }
    113105        } else {
     
    117109                 * Close the connection.
    118110                 */
    119                 async_answer_0(callid, EHANGUP);
     111                ipc_answer_0(callid, EHANGUP);
    120112                return;
    121113        }
     
    123115        while (true) {
    124116                callid = async_get_call(&call);
    125                 switch (IPC_GET_IMETHOD(call)) {
     117                switch (IPC_GET_METHOD(call)) {
    126118                case IPC_M_PHONE_HUNGUP:
    127119                        /*
     
    129121                         * Answer the message and exit the fibril.
    130122                         */
    131                         async_answer_0(callid, EOK);
     123                        ipc_answer_0(callid, EOK);
    132124                        return;
    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) {
    138                                 retval = ELIMIT;
    139                                 break;
    140                         }
    141                         retval = rd_read_blocks(ba, cnt, fs_va);
     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                                 */
     132                                retval = ELIMIT;
     133                                break;
     134                        }
     135                        if (offset * block_size > rd_size - block_size) {
     136                                /*
     137                                 * Reading past the end of the device.
     138                                 */
     139                                retval = ELIMIT;
     140                                break;
     141                        }
     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;
    142146                        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) {
    148                                 retval = ELIMIT;
    149                                 break;
    150                         }
    151                         retval = rd_write_blocks(ba, cnt, fs_va);
     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;
    152168                        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;
    160169                default:
    161170                        /*
     
    168177                        break;
    169178                }
    170                 async_answer_0(callid, retval);
    171         }
    172 }
    173 
    174 /** Read blocks from the device. */
    175 static 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. */
    190 static 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;
     179                ipc_answer_0(callid, retval);
     180        }
    202181}
    203182
     
    205184static bool rd_init(void)
    206185{
    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);
     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");
    217191                return false;
    218192        }
     
    221195       
    222196        int flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
    223         int retval = physmem_map((void *) rd_ph_addr, rd_addr,
     197        int retval = physmem_map(rd_ph_addr, rd_addr,
    224198            ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
    225199       
    226200        if (retval < 0) {
    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);
     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);
    233206       
    234207        int rc = devmap_driver_register(NAME, rd_connection);
    235208        if (rc < 0) {
    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);
     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");
    243217                return false;
    244218        }
     
    251225int main(int argc, char **argv)
    252226{
    253         printf("%s: HelenOS RAM disk server\n", NAME);
     227        printf(NAME ": HelenOS RAM disk server\n");
    254228       
    255229        if (!rd_init())
    256230                return -1;
    257231       
    258         printf("%s: Accepting connections\n", NAME);
     232        printf(NAME ": Accepting connections\n");
    259233        async_manager();
    260234
Note: See TracChangeset for help on using the changeset viewer.