Changeset 04803bf in mainline for uspace/srv/bd/gxe_bd/gxe_bd.c
- Timestamp:
- 2011-03-21T22:00:17Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 143932e
- Parents:
- b50b5af2 (diff), 7308e84 (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
rb50b5af2 r04803bf 39 39 #include <libarch/ddi.h> 40 40 #include <ddi.h> 41 #include <ipc/ipc.h>42 41 #include <ipc/bd.h> 43 42 #include <async.h> 44 43 #include <as.h> 45 #include <fibril_sync .h>44 #include <fibril_synch.h> 46 45 #include <devmap.h> 47 46 #include <sys/types.h> 48 47 #include <errno.h> 48 #include <macros.h> 49 49 #include <task.h> 50 50 51 #define NAME "gxe_bd" 51 #define NAME "gxe_bd" 52 #define NAMESPACE "bd" 52 53 53 54 enum { … … 91 92 static gxe_bd_t *dev; 92 93 93 static dev _handle_t dev_handle[MAX_DISKS];94 static devmap_handle_t devmap_handle[MAX_DISKS]; 94 95 95 96 static fibril_mutex_t dev_lock[MAX_DISKS]; … … 97 98 static int gxe_bd_init(void); 98 99 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall); 99 static int gx _bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,100 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt, 100 101 void *buf); 101 static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size, 102 void *buf); 103 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size, 102 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt, 104 103 const void *buf); 104 static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf); 105 static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf); 105 106 106 107 int main(int argc, char **argv) … … 140 141 141 142 for (i = 0; i < MAX_DISKS; i++) { 142 snprintf(name, 16, " disk%d", i);143 rc = devmap_device_register(name, &dev _handle[i]);143 snprintf(name, 16, "%s/disk%d", NAMESPACE, i); 144 rc = devmap_device_register(name, &devmap_handle[i]); 144 145 if (rc != EOK) { 145 devmap_hangup_phone(DEVMAP_DRIVER); 146 printf(NAME ": Unable to register device %s.\n", 147 name); 146 printf(NAME ": Unable to register device %s.\n", name); 148 147 return rc; 149 148 } … … 159 158 ipc_callid_t callid; 160 159 ipc_call_t call; 161 ipcarg_t method;162 dev _handle_t dh;163 int flags;160 sysarg_t method; 161 devmap_handle_t dh; 162 unsigned int flags; 164 163 int retval; 165 off_t idx;166 size_t size;164 uint64_t ba; 165 unsigned cnt; 167 166 int disk_id, i; 168 167 … … 173 172 disk_id = -1; 174 173 for (i = 0; i < MAX_DISKS; i++) 175 if (dev _handle[i] == dh)174 if (devmap_handle[i] == dh) 176 175 disk_id = i; 177 176 178 177 if (disk_id < 0) { 179 ipc_answer_0(iid, EINVAL);178 async_answer_0(iid, EINVAL); 180 179 return; 181 180 } 182 181 183 182 /* Answer the IPC_M_CONNECT_ME_TO call. */ 184 ipc_answer_0(iid, EOK); 185 186 if (!ipc_share_out_receive(&callid, &comm_size, &flags)) { 187 ipc_answer_0(callid, EHANGUP); 183 async_answer_0(iid, EOK); 184 185 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 186 async_answer_0(callid, EHANGUP); 187 return; 188 } 189 190 if (comm_size < block_size) { 191 async_answer_0(callid, EHANGUP); 188 192 return; 189 193 } … … 191 195 fs_va = as_get_mappable_page(comm_size); 192 196 if (fs_va == NULL) { 193 ipc_answer_0(callid, EHANGUP);197 async_answer_0(callid, EHANGUP); 194 198 return; 195 199 } 196 200 197 (void) ipc_share_out_finalize(callid, fs_va);201 (void) async_share_out_finalize(callid, fs_va); 198 202 199 203 while (1) { 200 204 callid = async_get_call(&call); 201 method = IPC_GET_ METHOD(call);205 method = IPC_GET_IMETHOD(call); 202 206 switch (method) { 203 207 case IPC_M_PHONE_HUNGUP: 204 208 /* The other side has hung up. */ 205 ipc_answer_0(callid, EOK);209 async_answer_0(callid, EOK); 206 210 return; 207 case BD_READ_BLOCK :208 case BD_WRITE_BLOCK:209 idx = IPC_GET_ARG1(call);210 size = IPC_GET_ARG2(call);211 if ( size > comm_size) {212 retval = E INVAL;211 case BD_READ_BLOCKS: 212 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 213 IPC_GET_ARG2(call)); 214 cnt = IPC_GET_ARG3(call); 215 if (cnt * block_size > comm_size) { 216 retval = ELIMIT; 213 217 break; 214 218 } 215 retval = gx_bd_rdwr(disk_id, method, idx * size, 216 size, fs_va); 219 retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va); 220 break; 221 case BD_WRITE_BLOCKS: 222 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 223 IPC_GET_ARG2(call)); 224 cnt = IPC_GET_ARG3(call); 225 if (cnt * block_size > comm_size) { 226 retval = ELIMIT; 227 break; 228 } 229 retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va); 230 break; 231 case BD_GET_BLOCK_SIZE: 232 async_answer_1(callid, EOK, block_size); 233 continue; 234 case BD_GET_NUM_BLOCKS: 235 retval = ENOTSUP; 217 236 break; 218 237 default: … … 220 239 break; 221 240 } 222 ipc_answer_0(callid, retval); 223 } 224 } 225 226 static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size, 227 void *buf) 228 { 241 async_answer_0(callid, retval); 242 } 243 } 244 245 /** Read multiple blocks from the device. */ 246 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt, 247 void *buf) { 248 229 249 int rc; 230 size_t now; 231 232 while (size > 0) { 233 now = size < block_size ? size : block_size; 234 235 if (method == BD_READ_BLOCK) 236 rc = gxe_bd_read_block(disk_id, offset, now, buf); 237 else 238 rc = gxe_bd_write_block(disk_id, offset, now, buf); 239 250 251 while (cnt > 0) { 252 rc = gxe_bd_read_block(disk_id, ba, buf); 240 253 if (rc != EOK) 241 254 return rc; 242 255 256 ++ba; 257 --cnt; 243 258 buf += block_size; 244 offset += block_size; 245 246 if (size > block_size) 247 size -= block_size; 248 else 249 size = 0; 250 } 251 252 return EOK; 253 } 254 255 static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size, 256 void *buf) 259 } 260 261 return EOK; 262 } 263 264 /** Write multiple blocks to the device. */ 265 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt, 266 const void *buf) { 267 268 int rc; 269 270 while (cnt > 0) { 271 rc = gxe_bd_write_block(disk_id, ba, buf); 272 if (rc != EOK) 273 return rc; 274 275 ++ba; 276 --cnt; 277 buf += block_size; 278 } 279 280 return EOK; 281 } 282 283 /** Read a block from the device. */ 284 static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf) 257 285 { 258 286 uint32_t status; 287 uint64_t byte_addr; 259 288 size_t i; 260 289 uint32_t w; 261 290 291 byte_addr = ba * block_size; 292 262 293 fibril_mutex_lock(&dev_lock[disk_id]); 263 pio_write_32(&dev->offset_lo, (uint32_t) offset);264 pio_write_32(&dev->offset_hi, offset>> 32);294 pio_write_32(&dev->offset_lo, (uint32_t) byte_addr); 295 pio_write_32(&dev->offset_hi, byte_addr >> 32); 265 296 pio_write_32(&dev->disk_id, disk_id); 266 297 pio_write_32(&dev->control, CTL_READ_START); … … 272 303 } 273 304 274 for (i = 0; i < size; i++) {305 for (i = 0; i < block_size; i++) { 275 306 ((uint8_t *) buf)[i] = w = pio_read_8(&dev->buffer[i]); 276 307 } … … 280 311 } 281 312 282 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size, 283 313 /** Write a block to the device. */ 314 static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf) 284 315 { 285 316 uint32_t status; 317 uint64_t byte_addr; 286 318 size_t i; 287 319 288 for (i = 0; i < size; i++) { 320 byte_addr = ba * block_size; 321 322 fibril_mutex_lock(&dev_lock[disk_id]); 323 324 for (i = 0; i < block_size; i++) { 289 325 pio_write_8(&dev->buffer[i], ((const uint8_t *) buf)[i]); 290 326 } 291 327 292 fibril_mutex_lock(&dev_lock[disk_id]); 293 pio_write_32(&dev->offset_lo, (uint32_t) offset); 294 pio_write_32(&dev->offset_hi, offset >> 32); 328 pio_write_32(&dev->offset_lo, (uint32_t) byte_addr); 329 pio_write_32(&dev->offset_hi, byte_addr >> 32); 295 330 pio_write_32(&dev->disk_id, disk_id); 296 331 pio_write_32(&dev->control, CTL_WRITE_START);
Note:
See TracChangeset
for help on using the changeset viewer.