Changeset cfa8738 in mainline for uspace/srv/bd/gxe_bd/gxe_bd.c
- Timestamp:
- 2009-08-30T22:30:42Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d061efe
- Parents:
- ff62c6d (diff), a830611 (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
rff62c6d rcfa8738 47 47 #include <sys/types.h> 48 48 #include <errno.h> 49 #include <macros.h> 49 50 #include <task.h> 50 51 … … 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) … … 163 164 int flags; 164 165 int retval; 165 off_t idx;166 size_t size;166 uint64_t ba; 167 unsigned cnt; 167 168 int disk_id, i; 168 169 … … 185 186 186 187 if (!ipc_share_out_receive(&callid, &comm_size, &flags)) { 188 ipc_answer_0(callid, EHANGUP); 189 return; 190 } 191 192 if (comm_size < block_size) { 187 193 ipc_answer_0(callid, EHANGUP); 188 194 return; … … 205 211 ipc_answer_0(callid, EOK); 206 212 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;213 case BD_READ_BLOCKS: 214 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 215 IPC_GET_ARG2(call)); 216 cnt = IPC_GET_ARG3(call); 217 if (cnt * block_size > comm_size) { 218 retval = ELIMIT; 213 219 break; 214 220 } 215 retval = gx_bd_rdwr(disk_id, method, idx * size, 216 size, fs_va); 221 retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va); 217 222 break; 223 case BD_WRITE_BLOCKS: 224 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 225 IPC_GET_ARG2(call)); 226 cnt = IPC_GET_ARG3(call); 227 if (cnt * block_size > comm_size) { 228 retval = ELIMIT; 229 break; 230 } 231 retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va); 232 break; 233 case BD_GET_BLOCK_SIZE: 234 ipc_answer_1(callid, EOK, block_size); 235 continue; 218 236 default: 219 237 retval = EINVAL; … … 224 242 } 225 243 226 static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size, 227 void *buf) 228 { 244 /** Read multiple blocks from the device. */ 245 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt, 246 void *buf) { 247 229 248 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 249 250 while (cnt > 0) { 251 rc = gxe_bd_read_block(disk_id, ba, buf); 240 252 if (rc != EOK) 241 253 return rc; 242 254 255 ++ba; 256 --cnt; 243 257 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) 258 } 259 260 return EOK; 261 } 262 263 /** Write multiple blocks to the device. */ 264 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt, 265 const void *buf) { 266 267 int rc; 268 269 while (cnt > 0) { 270 rc = gxe_bd_write_block(disk_id, ba, buf); 271 if (rc != EOK) 272 return rc; 273 274 ++ba; 275 --cnt; 276 buf += block_size; 277 } 278 279 return EOK; 280 } 281 282 /** Read a block from the device. */ 283 static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf) 257 284 { 258 285 uint32_t status; 286 uint64_t byte_addr; 259 287 size_t i; 260 288 uint32_t w; 261 289 290 byte_addr = ba * block_size; 291 262 292 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);293 pio_write_32(&dev->offset_lo, (uint32_t) byte_addr); 294 pio_write_32(&dev->offset_hi, byte_addr >> 32); 265 295 pio_write_32(&dev->disk_id, disk_id); 266 296 pio_write_32(&dev->control, CTL_READ_START); … … 272 302 } 273 303 274 for (i = 0; i < size; i++) {304 for (i = 0; i < block_size; i++) { 275 305 ((uint8_t *) buf)[i] = w = pio_read_8(&dev->buffer[i]); 276 306 } … … 280 310 } 281 311 282 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size, 283 312 /** Write a block to the device. */ 313 static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf) 284 314 { 285 315 uint32_t status; 316 uint64_t byte_addr; 286 317 size_t i; 287 318 288 for (i = 0; i < size; i++) { 319 byte_addr = ba * block_size; 320 321 fibril_mutex_lock(&dev_lock[disk_id]); 322 323 for (i = 0; i < block_size; i++) { 289 324 pio_write_8(&dev->buffer[i], ((const uint8_t *) buf)[i]); 290 325 } 291 326 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); 327 pio_write_32(&dev->offset_lo, (uint32_t) byte_addr); 328 pio_write_32(&dev->offset_hi, byte_addr >> 32); 295 329 pio_write_32(&dev->disk_id, disk_id); 296 330 pio_write_32(&dev->control, CTL_WRITE_START);
Note:
See TracChangeset
for help on using the changeset viewer.