Changeset 84947a4 in mainline
- Timestamp:
- 2007-06-20T20:52:23Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0eb58f1
- Parents:
- 9ec12fd
- Location:
- uspace/rd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/rd/rd.c
r9ec12fd r84947a4 3 3 * Copyright (c) 2007 Martin Jelen 4 4 * Copyright (c) 2007 Peter Majer 5 * Copyright (c) 2007 Jakub Jermar 5 6 * All rights reserved. 6 7 * … … 50 51 #include <align.h> 51 52 #include <async.h> 53 #include <futex.h> 52 54 #include "rd.h" 53 55 56 /** Pointer to the ramdisk's image. */ 54 57 static void *rd_addr; 55 static void *fs_addr; 56 58 59 /** 60 * This futex protects the ramdisk's data. 61 * If we were to serve multiple requests (read + write or several writes) 62 * concurrently (i.e. from two or more threads), each read and write needs to be 63 * protected by this futex. 64 */ 65 atomic_t rd_futex = FUTEX_INITIALIZER; 66 67 /** Handle one connection to ramdisk. 68 * 69 * @param iid Hash of the request that opened the connection. 70 * @param icall Call data of the request that opened the connection. 71 */ 57 72 static void rd_connection(ipc_callid_t iid, ipc_call_t *icall) 58 73 { … … 60 75 ipc_call_t call; 61 76 int retval; 62 63 ipc_answer_fast(iid, 0, 0, 0); 77 uintptr_t fs_va = NULL; 64 78 ipcarg_t offset; 65 79 80 /* 81 * We allocate VA for communication per connection. 82 * This allows us to potentionally have more clients and work 83 * concurrently. 84 */ 85 fs_va = as_get_mappable_page(ALIGN_UP(BLOCK_SIZE, PAGE_SIZE)); 86 if (!fs_va) { 87 /* 88 * Hang up the phone if we cannot proceed any further. 89 * This is the answer to the call that opened the connection. 90 */ 91 ipc_answer_fast(iid, EHANGUP, 0, 0); 92 return; 93 } else { 94 /* 95 * Answer the first IPC_M_CONNECT_ME_TO call. 96 * Return supported block size as ARG1. 97 */ 98 ipc_answer_fast(iid, EOK, BLOCK_SIZE, 0); 99 } 100 101 /* 102 * Now we wait for the client to send us its communication as_area. 103 */ 104 callid = async_get_call(&call); 105 if (IPC_GET_METHOD(call) == IPC_M_AS_AREA_SEND) { 106 if (IPC_GET_ARG1(call) >= (ipcarg_t) BLOCK_SIZE) { 107 /* 108 * The client sends an as_area that can absorb the whole 109 * block. 110 */ 111 ipc_answer_fast(callid, EOK, (uintptr_t) fs_va, 0); 112 } else { 113 /* 114 * The client offered as_area too small. 115 * Close the connection. 116 */ 117 ipc_answer_fast(callid, EHANGUP, 0, 0); 118 return; 119 } 120 } else { 121 /* 122 * The client doesn't speak the same protocol. 123 * At this point we can't handle protocol variations. 124 * Close the connection. 125 */ 126 ipc_answer_fast(callid, EHANGUP, 0, 0); 127 return; 128 } 129 66 130 while (1) { 67 131 callid = async_get_call(&call); 68 132 switch (IPC_GET_METHOD(call)) { 69 133 case IPC_M_PHONE_HUNGUP: 70 ipc_answer_fast(callid, 0, 0, 0); 134 /* 135 * The other side has hung up. 136 * Answer the message and exit the pseudo thread. 137 */ 138 ipc_answer_fast(callid, EOK, 0, 0); 71 139 return; 72 case IPC_M_AS_AREA_SEND: 73 ipc_answer_fast(callid, 0, (uintptr_t) fs_addr, 0); 74 continue; 75 case RD_READ_BLOCK: 140 case RD_READ_BLOCK: 76 141 offset = IPC_GET_ARG1(call); 77 memcpy((void *) fs_addr, rd_addr + offset, BLOCK_SIZE); 142 futex_down(&rd_futex); 143 memcpy((void *) fs_va, rd_addr + offset, BLOCK_SIZE); 144 futex_up(&rd_futex); 145 retval = EOK; 146 break; 147 case RD_WRITE_BLOCK: 148 offset = IPC_GET_ARG1(call); 149 futex_up(&rd_futex); 150 memcpy(rd_addr + offset, (void *) fs_va, BLOCK_SIZE); 151 futex_down(&rd_futex); 78 152 retval = EOK; 79 153 break; 80 154 default: 155 /* 156 * The client doesn't speak the same protocol. 157 * Instead of closing the connection, we just ignore 158 * the call. This can be useful if the client uses a 159 * newer version of the protocol. 160 */ 81 161 retval = EINVAL; 162 break; 82 163 } 83 164 ipc_answer_fast(callid, retval, 0, 0); … … 85 166 } 86 167 87 168 /** Prepare the ramdisk image for operation. */ 88 169 static bool rd_init(void) 89 170 { … … 104 185 if (retval < 0) 105 186 return false; 106 107 size_t fs_size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);108 fs_addr = as_get_mappable_page(fs_size);109 110 187 return true; 111 188 } -
uspace/rd/rd.h
r9ec12fd r84947a4 3 3 * Copyright (c) 2007 Martin Jelen 4 4 * Copyright (c) 2007 Peter Majer 5 * Copyright (c) 2007 Jakub Jermar 5 6 * All rights reserved. 6 7 * … … 40 41 /* Basic constants. */ 41 42 42 #ifndef _RD_H43 #define _RD_H43 #ifndef RD_RD_H_ 44 #define RD_RD_H_ 44 45 45 #define BLOCK_SIZE 1024 46 #define BLOCK_SIZE 1024 /**< Working block size */ 46 47 47 #define RD_OFFSET 100 /**< IPC Message offset */ 48 #define RD_BASE 1024 49 #define RD_READ_BLOCK (RD_BASE + 1) /**< Method for reading block. */ 50 #define RD_WRITE_BLOCK (RD_BASE + 2) /**< Method for writing block. */ 48 51 49 #define RD_BASE (FIRST_USER_METHOD + RD_OFFSET) /**< IPC Index of the first RD message */ 50 #define RD_READ_BLOCK (RD_BASE + 1) /**< IPC Index of the RD_READ_BLOCK message */ 51 52 #endif /* _RD_H */ 52 #endif
Note:
See TracChangeset
for help on using the changeset viewer.