source: mainline/uspace/srv/bd/rd/rd.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 * Copyright (c) 2007 Michal Konopa
3 * Copyright (c) 2007 Martin Jelen
4 * Copyright (c) 2007 Peter Majer
5 * Copyright (c) 2007 Jakub Jermar
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * - The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/** @addtogroup rd
33 * @{
34 */
35
36/**
37 * @file rd.c
38 * @brief Initial RAM disk for HelenOS.
39 */
40
41#include <ipc/services.h>
42#include <ipc/ns.h>
43#include <sysinfo.h>
44#include <as.h>
45#include <bd_srv.h>
46#include <ddi.h>
47#include <align.h>
48#include <stdbool.h>
49#include <errno.h>
50#include <str_error.h>
51#include <async.h>
52#include <fibril_synch.h>
53#include <stdio.h>
54#include <loc.h>
55#include <macros.h>
56#include <inttypes.h>
57
58#define NAME "rd"
59
60/** Pointer to the ramdisk's image */
61static void *rd_addr = AS_AREA_ANY;
62
63/** Size of the ramdisk */
64static size_t rd_size;
65
66/** Block size */
67static const size_t block_size = 512;
68
69static errno_t rd_open(bd_srvs_t *, bd_srv_t *);
70static errno_t rd_close(bd_srv_t *);
71static errno_t rd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
72static errno_t rd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
73static errno_t rd_get_block_size(bd_srv_t *, size_t *);
74static errno_t rd_get_num_blocks(bd_srv_t *, aoff64_t *);
75
76/** This rwlock protects the ramdisk's data.
77 *
78 * If we were to serve multiple requests (read + write or several writes)
79 * concurrently (i.e. from two or more threads), each read and write needs to
80 * be protected by this rwlock.
81 *
82 */
83static fibril_rwlock_t rd_lock;
84
85static bd_ops_t rd_bd_ops = {
86 .open = rd_open,
87 .close = rd_close,
88 .read_blocks = rd_read_blocks,
89 .write_blocks = rd_write_blocks,
90 .get_block_size = rd_get_block_size,
91 .get_num_blocks = rd_get_num_blocks
92};
93
94static bd_srvs_t bd_srvs;
95
96static void rd_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
97{
98 bd_conn(iid, icall, &bd_srvs);
99}
100
101/** Open device. */
102static errno_t rd_open(bd_srvs_t *bds, bd_srv_t *bd)
103{
104 return EOK;
105}
106
107/** Close device. */
108static errno_t rd_close(bd_srv_t *bd)
109{
110 return EOK;
111}
112
113/** Read blocks from the device. */
114static errno_t rd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
115 size_t size)
116{
117 if ((ba + cnt) * block_size > rd_size) {
118 /* Reading past the end of the device. */
119 return ELIMIT;
120 }
121
122 fibril_rwlock_read_lock(&rd_lock);
123 memcpy(buf, rd_addr + ba * block_size, min(block_size * cnt, size));
124 fibril_rwlock_read_unlock(&rd_lock);
125
126 return EOK;
127}
128
129/** Write blocks to the device. */
130static errno_t rd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
131 const void *buf, size_t size)
132{
133 if ((ba + cnt) * block_size > rd_size) {
134 /* Writing past the end of the device. */
135 return ELIMIT;
136 }
137
138 fibril_rwlock_write_lock(&rd_lock);
139 memcpy(rd_addr + ba * block_size, buf, min(block_size * cnt, size));
140 fibril_rwlock_write_unlock(&rd_lock);
141
142 return EOK;
143}
144
145/** Prepare the ramdisk image for operation. */
146static bool rd_init(void)
147{
148 sysarg_t size;
149 errno_t ret = sysinfo_get_value("rd.size", &size);
150 if ((ret != EOK) || (size == 0)) {
151 printf("%s: No RAM disk found\n", NAME);
152 return false;
153 }
154
155 sysarg_t addr_phys;
156 ret = sysinfo_get_value("rd.address.physical", &addr_phys);
157 if ((ret != EOK) || (addr_phys == 0)) {
158 printf("%s: Invalid RAM disk physical address\n", NAME);
159 return false;
160 }
161
162 rd_size = ALIGN_UP(size, block_size);
163 unsigned int flags =
164 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
165
166 ret = physmem_map(addr_phys,
167 ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags, &rd_addr);
168 if (ret != EOK) {
169 printf("%s: Error mapping RAM disk\n", NAME);
170 return false;
171 }
172
173 printf("%s: Found RAM disk at %p, %" PRIun " bytes\n", NAME,
174 (void *) addr_phys, size);
175
176 bd_srvs_init(&bd_srvs);
177 bd_srvs.ops = &rd_bd_ops;
178
179 async_set_fallback_port_handler(rd_client_conn, NULL);
180 ret = loc_server_register(NAME);
181 if (ret != EOK) {
182 printf("%s: Unable to register driver: %s\n", NAME, str_error(ret));
183 return false;
184 }
185
186 service_id_t service_id;
187 ret = loc_service_register("bd/initrd", &service_id);
188 if (ret != EOK) {
189 printf("%s: Unable to register device service\n", NAME);
190 return false;
191 }
192
193 fibril_rwlock_initialize(&rd_lock);
194
195 return true;
196}
197
198/** Get device block size. */
199static errno_t rd_get_block_size(bd_srv_t *bd, size_t *rsize)
200{
201 *rsize = block_size;
202 return EOK;
203}
204
205/** Get number of blocks on device. */
206static errno_t rd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
207{
208 *rnb = rd_size / block_size;
209 return EOK;
210}
211
212int main(int argc, char **argv)
213{
214 printf("%s: HelenOS RAM disk server\n", NAME);
215
216 if (!rd_init())
217 return -1;
218
219 printf("%s: Accepting connections\n", NAME);
220 async_manager();
221
222 /* Never reached */
223 return 0;
224}
225
226/**
227 * @}
228 */
Note: See TracBrowser for help on using the repository browser.