Changes in uspace/srv/bd/rd/rd.c [faba839:135486d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/rd/rd.c
rfaba839 r135486d 43 43 #include <sysinfo.h> 44 44 #include <as.h> 45 #include <bd_srv.h> 45 46 #include <ddi.h> 46 47 #include <align.h> … … 53 54 #include <stdio.h> 54 55 #include <loc.h> 55 #include <ipc/bd.h>56 56 #include <macros.h> 57 57 #include <inttypes.h> … … 68 68 static const size_t block_size = 512; 69 69 70 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf); 71 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf); 70 static int rd_open(bd_srvs_t *, bd_srv_t *); 71 static int rd_close(bd_srv_t *); 72 static int rd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 73 static int rd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 74 static int rd_get_block_size(bd_srv_t *, size_t *); 75 static int rd_get_num_blocks(bd_srv_t *, aoff64_t *); 72 76 73 77 /** This rwlock protects the ramdisk's data. … … 78 82 * 79 83 */ 80 fibril_rwlock_t rd_lock; 81 82 /** Handle one connection to ramdisk. 83 * 84 * @param iid Hash of the request that opened the connection. 85 * @param icall Call data of the request that opened the connection. 86 */ 87 static void rd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 88 { 89 ipc_callid_t callid; 90 ipc_call_t call; 91 int retval; 92 void *fs_va = NULL; 93 uint64_t ba; 94 size_t cnt; 95 size_t comm_size; 96 97 /* 98 * Answer the first IPC_M_CONNECT_ME_TO call. 99 */ 100 async_answer_0(iid, EOK); 101 102 /* 103 * Now we wait for the client to send us its communication as_area. 104 */ 105 unsigned int flags; 106 if (async_share_out_receive(&callid, &comm_size, &flags)) { 107 (void) async_share_out_finalize(callid, &fs_va); 108 if (fs_va == AS_MAP_FAILED) { 109 async_answer_0(callid, EHANGUP); 110 return; 111 } 112 } else { 113 /* 114 * The client doesn't speak the same protocol. 115 * At this point we can't handle protocol variations. 116 * Close the connection. 117 */ 118 async_answer_0(callid, EHANGUP); 119 return; 120 } 121 122 while (true) { 123 callid = async_get_call(&call); 124 125 if (!IPC_GET_IMETHOD(call)) { 126 /* 127 * The other side has hung up. 128 * Exit the fibril. 129 */ 130 async_answer_0(callid, EOK); 131 return; 132 } 133 134 switch (IPC_GET_IMETHOD(call)) { 135 case BD_READ_BLOCKS: 136 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 137 IPC_GET_ARG2(call)); 138 cnt = IPC_GET_ARG3(call); 139 if (cnt * block_size > comm_size) { 140 retval = ELIMIT; 141 break; 142 } 143 retval = rd_read_blocks(ba, cnt, fs_va); 144 break; 145 case BD_WRITE_BLOCKS: 146 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 147 IPC_GET_ARG2(call)); 148 cnt = IPC_GET_ARG3(call); 149 if (cnt * block_size > comm_size) { 150 retval = ELIMIT; 151 break; 152 } 153 retval = rd_write_blocks(ba, cnt, fs_va); 154 break; 155 case BD_GET_BLOCK_SIZE: 156 async_answer_1(callid, EOK, block_size); 157 continue; 158 case BD_GET_NUM_BLOCKS: 159 async_answer_2(callid, EOK, LOWER32(rd_size / block_size), 160 UPPER32(rd_size / block_size)); 161 continue; 162 default: 163 /* 164 * The client doesn't speak the same protocol. 165 * Instead of closing the connection, we just ignore 166 * the call. This can be useful if the client uses a 167 * newer version of the protocol. 168 */ 169 retval = EINVAL; 170 break; 171 } 172 async_answer_0(callid, retval); 173 } 84 static fibril_rwlock_t rd_lock; 85 86 static bd_ops_t rd_bd_ops = { 87 .open = rd_open, 88 .close = rd_close, 89 .read_blocks = rd_read_blocks, 90 .write_blocks = rd_write_blocks, 91 .get_block_size = rd_get_block_size, 92 .get_num_blocks = rd_get_num_blocks 93 }; 94 95 static bd_srvs_t bd_srvs; 96 97 static void rd_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 98 { 99 bd_conn(iid, icall, &bd_srvs); 100 } 101 102 /** Open device. */ 103 static int rd_open(bd_srvs_t *bds, bd_srv_t *bd) 104 { 105 return EOK; 106 } 107 108 /** Close device. */ 109 static int rd_close(bd_srv_t *bd) 110 { 111 return EOK; 174 112 } 175 113 176 114 /** Read blocks from the device. */ 177 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf) 115 static int rd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf, 116 size_t size) 178 117 { 179 118 if ((ba + cnt) * block_size > rd_size) { … … 183 122 184 123 fibril_rwlock_read_lock(&rd_lock); 185 memcpy(buf, rd_addr + ba * block_size, block_size * cnt);124 memcpy(buf, rd_addr + ba * block_size, min(block_size * cnt, size)); 186 125 fibril_rwlock_read_unlock(&rd_lock); 187 126 … … 190 129 191 130 /** Write blocks to the device. */ 192 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf) 131 static int rd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 132 const void *buf, size_t size) 193 133 { 194 134 if ((ba + cnt) * block_size > rd_size) { … … 198 138 199 139 fibril_rwlock_write_lock(&rd_lock); 200 memcpy(rd_addr + ba * block_size, buf, block_size * cnt);140 memcpy(rd_addr + ba * block_size, buf, min(block_size * cnt, size)); 201 141 fibril_rwlock_write_unlock(&rd_lock); 202 142 … … 235 175 (void *) addr_phys, size); 236 176 237 async_set_client_connection(rd_connection); 177 bd_srvs_init(&bd_srvs); 178 bd_srvs.ops = &rd_bd_ops; 179 180 async_set_client_connection(rd_client_conn); 238 181 ret = loc_server_register(NAME); 239 182 if (ret != EOK) { … … 254 197 } 255 198 199 /** Get device block size. */ 200 static int rd_get_block_size(bd_srv_t *bd, size_t *rsize) 201 { 202 *rsize = block_size; 203 return EOK; 204 } 205 206 /** Get number of blocks on device. */ 207 static int rd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 208 { 209 *rnb = rd_size / block_size; 210 return EOK; 211 } 212 256 213 int main(int argc, char **argv) 257 214 {
Note:
See TracChangeset
for help on using the changeset viewer.