Changeset 03362fbd in mainline for uspace/srv/bd/gxe_bd/gxe_bd.c
- Timestamp:
- 2013-02-09T23:14:45Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 22dfd38
- Parents:
- b5d2e57 (diff), 005b765 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 edited
-
uspace/srv/bd/gxe_bd/gxe_bd.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/gxe_bd/gxe_bd.c
rb5d2e57 r03362fbd 37 37 38 38 #include <stdio.h> 39 #include <libarch/ddi.h>40 39 #include <ddi.h> 41 #include <ipc/bd.h>42 40 #include <async.h> 43 41 #include <as.h> 42 #include <bd_srv.h> 44 43 #include <fibril_synch.h> 45 44 #include <loc.h> … … 65 64 }; 66 65 66 /** GXE disk hardware registers */ 67 67 typedef struct { 68 68 uint32_t offset_lo; … … 83 83 84 84 uint8_t buffer[512]; 85 } gxe_bd_hw_t; 86 87 /** GXE block device soft state */ 88 typedef struct { 89 /** Block device service structure */ 90 bd_srvs_t bds; 91 int disk_id; 85 92 } gxe_bd_t; 86 93 87 88 94 static const size_t block_size = 512; 89 static size_t comm_size;90 95 91 96 static uintptr_t dev_physical = 0x13000000; 92 static gxe_bd_ t *dev;97 static gxe_bd_hw_t *dev; 93 98 94 99 static service_id_t service_id[MAX_DISKS]; 95 100 96 101 static fibril_mutex_t dev_lock[MAX_DISKS]; 102 103 static gxe_bd_t gxe_bd[MAX_DISKS]; 97 104 98 105 static int gxe_bd_init(void); 99 106 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *); 100 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,101 void *buf);102 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,103 const void *buf);104 107 static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf); 105 108 static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf); 109 110 static int gxe_bd_open(bd_srvs_t *, bd_srv_t *); 111 static int gxe_bd_close(bd_srv_t *); 112 static int gxe_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 113 static int gxe_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 114 static int gxe_bd_get_block_size(bd_srv_t *, size_t *); 115 static int gxe_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 116 117 static bd_ops_t gxe_bd_ops = { 118 .open = gxe_bd_open, 119 .close = gxe_bd_close, 120 .read_blocks = gxe_bd_read_blocks, 121 .write_blocks = gxe_bd_write_blocks, 122 .get_block_size = gxe_bd_get_block_size, 123 .get_num_blocks = gxe_bd_get_num_blocks 124 }; 125 126 static gxe_bd_t *bd_srv_gxe(bd_srv_t *bd) 127 { 128 return (gxe_bd_t *) bd->srvs->sarg; 129 } 106 130 107 131 int main(int argc, char **argv) … … 130 154 131 155 void *vaddr; 132 rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_ t), &vaddr);156 rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_hw_t), &vaddr); 133 157 if (rc != EOK) { 134 158 printf("%s: Could not initialize device I/O space.\n", NAME); … … 140 164 for (unsigned int i = 0; i < MAX_DISKS; i++) { 141 165 char name[16]; 166 167 bd_srvs_init(&gxe_bd[i].bds); 168 gxe_bd[i].bds.ops = &gxe_bd_ops; 169 gxe_bd[i].bds.sarg = (void *)&gxe_bd[i]; 142 170 143 171 snprintf(name, 16, "%s/disk%u", NAMESPACE, i); … … 157 185 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 158 186 { 159 void *fs_va = NULL;160 ipc_callid_t callid;161 ipc_call_t call;162 sysarg_t method;163 187 service_id_t dsid; 164 unsigned int flags;165 int retval;166 uint64_t ba;167 unsigned cnt;168 188 int disk_id, i; 169 189 … … 182 202 } 183 203 184 /* Answer the IPC_M_CONNECT_ME_TO call. */ 185 async_answer_0(iid, EOK); 186 187 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 188 async_answer_0(callid, EHANGUP); 189 return; 190 } 191 192 if (comm_size < block_size) { 193 async_answer_0(callid, EHANGUP); 194 return; 195 } 196 197 (void) async_share_out_finalize(callid, &fs_va); 198 if (fs_va == AS_MAP_FAILED) { 199 async_answer_0(callid, EHANGUP); 200 return; 201 } 202 203 while (true) { 204 callid = async_get_call(&call); 205 method = IPC_GET_IMETHOD(call); 206 207 if (!method) { 208 /* The other side has hung up. */ 209 async_answer_0(callid, EOK); 210 return; 211 } 212 213 switch (method) { 214 case BD_READ_BLOCKS: 215 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 216 IPC_GET_ARG2(call)); 217 cnt = IPC_GET_ARG3(call); 218 if (cnt * block_size > comm_size) { 219 retval = ELIMIT; 220 break; 221 } 222 retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va); 223 break; 224 case BD_WRITE_BLOCKS: 225 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 226 IPC_GET_ARG2(call)); 227 cnt = IPC_GET_ARG3(call); 228 if (cnt * block_size > comm_size) { 229 retval = ELIMIT; 230 break; 231 } 232 retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va); 233 break; 234 case BD_GET_BLOCK_SIZE: 235 async_answer_1(callid, EOK, block_size); 236 continue; 237 case BD_GET_NUM_BLOCKS: 238 retval = ENOTSUP; 239 break; 240 default: 241 retval = EINVAL; 242 break; 243 } 244 async_answer_0(callid, retval); 245 } 204 bd_conn(iid, icall, &gxe_bd[disk_id].bds); 205 } 206 207 /** Open device. */ 208 static int gxe_bd_open(bd_srvs_t *bds, bd_srv_t *bd) 209 { 210 return EOK; 211 } 212 213 /** Close device. */ 214 static int gxe_bd_close(bd_srv_t *bd) 215 { 216 return EOK; 246 217 } 247 218 248 219 /** Read multiple blocks from the device. */ 249 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt, 250 void *buf) { 251 220 static int gxe_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 221 void *buf, size_t size) 222 { 223 int disk_id = bd_srv_gxe(bd)->disk_id; 252 224 int rc; 225 226 if (size < cnt * block_size) 227 return EINVAL; 253 228 254 229 while (cnt > 0) { … … 266 241 267 242 /** Write multiple blocks to the device. */ 268 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt, 269 const void *buf) { 270 243 static int gxe_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 244 const void *buf, size_t size) 245 { 246 int disk_id = bd_srv_gxe(bd)->disk_id; 271 247 int rc; 248 249 if (size < cnt * block_size) 250 return EINVAL; 272 251 273 252 while (cnt > 0) { … … 282 261 283 262 return EOK; 263 } 264 265 /** Get device block size. */ 266 static int gxe_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 267 { 268 *rsize = block_size; 269 return EOK; 270 } 271 272 /** Get number of blocks on device. */ 273 static int gxe_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 274 { 275 return ENOTSUP; 284 276 } 285 277
Note:
See TracChangeset
for help on using the changeset viewer.
