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