Changeset affaf2e in mainline for uspace/srv/bd/gxe_bd/gxe_bd.c
- Timestamp:
- 2012-08-15T15:13:20Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b546231
- Parents:
- f66ca57f (diff), 135486d (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
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/gxe_bd/gxe_bd.c
rf66ca57f raffaf2e 39 39 #include <libarch/ddi.h> 40 40 #include <ddi.h> 41 #include <ipc/bd.h>42 41 #include <async.h> 43 42 #include <as.h> 43 #include <bd_srv.h> 44 44 #include <fibril_synch.h> 45 45 #include <loc.h> … … 65 65 }; 66 66 67 /** GXE disk hardware registers */ 67 68 typedef struct { 68 69 uint32_t offset_lo; … … 83 84 84 85 uint8_t buffer[512]; 86 } gxe_bd_hw_t; 87 88 /** GXE block device soft state */ 89 typedef struct { 90 /** Block device service structure */ 91 bd_srvs_t bds; 92 int disk_id; 85 93 } gxe_bd_t; 86 94 87 88 95 static const size_t block_size = 512; 89 static size_t comm_size;90 96 91 97 static uintptr_t dev_physical = 0x13000000; 92 static gxe_bd_ t *dev;98 static gxe_bd_hw_t *dev; 93 99 94 100 static service_id_t service_id[MAX_DISKS]; 95 101 96 102 static fibril_mutex_t dev_lock[MAX_DISKS]; 103 104 static gxe_bd_t gxe_bd[MAX_DISKS]; 97 105 98 106 static int gxe_bd_init(void); 99 107 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 108 static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf); 105 109 static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf); 110 111 static int gxe_bd_open(bd_srvs_t *, bd_srv_t *); 112 static int gxe_bd_close(bd_srv_t *); 113 static int gxe_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 114 static int gxe_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 115 static int gxe_bd_get_block_size(bd_srv_t *, size_t *); 116 static int gxe_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 117 118 static bd_ops_t gxe_bd_ops = { 119 .open = gxe_bd_open, 120 .close = gxe_bd_close, 121 .read_blocks = gxe_bd_read_blocks, 122 .write_blocks = gxe_bd_write_blocks, 123 .get_block_size = gxe_bd_get_block_size, 124 .get_num_blocks = gxe_bd_get_num_blocks 125 }; 126 127 static gxe_bd_t *bd_srv_gxe(bd_srv_t *bd) 128 { 129 return (gxe_bd_t *)bd->srvs->sarg; 130 } 106 131 107 132 int main(int argc, char **argv) … … 130 155 131 156 void *vaddr; 132 rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_ t), &vaddr);157 rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_hw_t), &vaddr); 133 158 if (rc != EOK) { 134 159 printf("%s: Could not initialize device I/O space.\n", NAME); … … 140 165 for (unsigned int i = 0; i < MAX_DISKS; i++) { 141 166 char name[16]; 167 168 bd_srvs_init(&gxe_bd[i].bds); 169 gxe_bd[i].bds.ops = &gxe_bd_ops; 170 gxe_bd[i].bds.sarg = (void *)&gxe_bd[i]; 142 171 143 172 snprintf(name, 16, "%s/disk%u", NAMESPACE, i); … … 157 186 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 158 187 { 159 void *fs_va = NULL;160 ipc_callid_t callid;161 ipc_call_t call;162 sysarg_t method;163 188 service_id_t dsid; 164 unsigned int flags;165 int retval;166 uint64_t ba;167 unsigned cnt;168 189 int disk_id, i; 169 190 … … 182 203 } 183 204 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 } 205 bd_conn(iid, icall, &gxe_bd[disk_id].bds); 206 } 207 208 /** Open device. */ 209 static int gxe_bd_open(bd_srvs_t *bds, bd_srv_t *bd) 210 { 211 return EOK; 212 } 213 214 /** Close device. */ 215 static int gxe_bd_close(bd_srv_t *bd) 216 { 217 return EOK; 246 218 } 247 219 248 220 /** 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 221 static int gxe_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 222 void *buf, size_t size) 223 { 224 int disk_id = bd_srv_gxe(bd)->disk_id; 252 225 int rc; 226 227 if (size < cnt * block_size) 228 return EINVAL; 253 229 254 230 while (cnt > 0) { … … 266 242 267 243 /** 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 244 static int gxe_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 245 const void *buf, size_t size) 246 { 247 int disk_id = bd_srv_gxe(bd)->disk_id; 271 248 int rc; 249 250 if (size < cnt * block_size) 251 return EINVAL; 272 252 273 253 while (cnt > 0) { … … 282 262 283 263 return EOK; 264 } 265 266 /** Get device block size. */ 267 static int gxe_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 268 { 269 *rsize = block_size; 270 return EOK; 271 } 272 273 /** Get number of blocks on device. */ 274 static int gxe_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 275 { 276 return ENOTSUP; 284 277 } 285 278
Note:
See TracChangeset
for help on using the changeset viewer.