Changes in uspace/srv/bd/rd/rd.c [52e4f526:47b7006] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/rd/rd.c
r52e4f526 r47b7006 32 32 /** @addtogroup rd 33 33 * @{ 34 */ 34 */ 35 35 36 36 /** 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 42 41 #include <ipc/services.h> 43 42 #include <ipc/ns.h> … … 51 50 #include <align.h> 52 51 #include <async.h> 53 #include <fibril_sync .h>52 #include <fibril_synch.h> 54 53 #include <stdio.h> 55 54 #include <devmap.h> 56 55 #include <ipc/bd.h> 56 #include <macros.h> 57 57 58 58 #define NAME "rd" 59 59 60 /** Pointer to the ramdisk's image .*/60 /** Pointer to the ramdisk's image */ 61 61 static void *rd_addr; 62 /** Size of the ramdisk. */ 62 63 /** Size of the ramdisk */ 63 64 static size_t rd_size; 64 65 65 /** 66 * This rwlock protects the ramdisk's data. 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 * 67 74 * 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 */ 71 79 fibril_rwlock_t rd_lock; 72 80 73 81 /** Handle one connection to ramdisk. 74 82 * 75 * @param iid 76 * @param icall 83 * @param iid Hash of the request that opened the connection. 84 * @param icall Call data of the request that opened the connection. 77 85 */ 78 86 static void rd_connection(ipc_callid_t iid, ipc_call_t *icall) … … 82 90 int retval; 83 91 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 88 96 /* 89 97 * Answer the first IPC_M_CONNECT_ME_TO call. 90 98 */ 91 ipc_answer_0(iid, EOK);92 99 async_answer_0(iid, EOK); 100 93 101 /* 94 102 * Now we wait for the client to send us its communication as_area. 95 103 */ 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); 99 107 if (fs_va) { 100 (void) ipc_share_out_finalize(callid, fs_va);108 (void) async_share_out_finalize(callid, fs_va); 101 109 } else { 102 ipc_answer_0(callid, EHANGUP);103 return; 110 async_answer_0(callid, EHANGUP); 111 return; 104 112 } 105 113 } else { … … 109 117 * Close the connection. 110 118 */ 111 ipc_answer_0(callid, EHANGUP);119 async_answer_0(callid, EHANGUP); 112 120 return; 113 121 } … … 115 123 while (true) { 116 124 callid = async_get_call(&call); 117 switch (IPC_GET_ METHOD(call)) {125 switch (IPC_GET_IMETHOD(call)) { 118 126 case IPC_M_PHONE_HUNGUP: 119 127 /* … … 121 129 * Answer the message and exit the fibril. 122 130 */ 123 ipc_answer_0(callid, EOK);131 async_answer_0(callid, EOK); 124 132 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) { 132 138 retval = ELIMIT; 133 139 break; 134 140 } 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) { 139 148 retval = ELIMIT; 140 149 break; 141 150 } 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); 146 152 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; 169 160 default: 170 161 /* … … 177 168 break; 178 169 } 179 ipc_answer_0(callid, retval); 180 } 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; 181 202 } 182 203 … … 184 205 static bool rd_init(void) 185 206 { 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); 191 217 return false; 192 218 } … … 195 221 196 222 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, 198 224 ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags); 199 225 200 226 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); 206 233 207 234 int rc = devmap_driver_register(NAME, rd_connection); 208 235 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); 217 243 return false; 218 244 } … … 225 251 int main(int argc, char **argv) 226 252 { 227 printf( NAME ": HelenOS RAM disk server\n");253 printf("%s: HelenOS RAM disk server\n", NAME); 228 254 229 255 if (!rd_init()) 230 256 return -1; 231 257 232 printf( NAME ": Accepting connections\n");258 printf("%s: Accepting connections\n", NAME); 233 259 async_manager(); 234 260
Note:
See TracChangeset
for help on using the changeset viewer.