Changeset cfa8738 in mainline for uspace/srv/bd/ata_bd/ata_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/ata_bd/ata_bd.c
rff62c6d rcfa8738 62 62 #include <bool.h> 63 63 #include <task.h> 64 #include <macros.h> 64 65 65 66 #include "ata_bd.h" … … 86 87 static int ata_bd_init(void); 87 88 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall); 88 static int ata_bd_r dwr(int disk_id, ipcarg_t method, off_t offset, size_t size,89 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt, 89 90 void *buf); 90 static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt, 91 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt, 92 const void *buf); 93 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t cnt, 91 94 void *buf); 92 static int ata_bd_write_block(int disk_id, uint64_t b lk_idx, size_t blk_cnt,95 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt, 93 96 const void *buf); 94 97 static int disk_init(disk_t *d, int disk_id); 95 98 static int drive_identify(int drive_id, void *buf); 96 99 static void disk_print_summary(disk_t *d); 97 static int coord_calc(disk_t *d, uint64_t b lk_idx, block_coord_t *bc);100 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc); 98 101 static void coord_sc_program(const block_coord_t *bc, uint16_t scnt); 99 102 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, … … 228 231 int flags; 229 232 int retval; 230 off_t idx;231 size_t size;233 uint64_t ba; 234 size_t cnt; 232 235 int disk_id, i; 233 236 … … 270 273 ipc_answer_0(callid, EOK); 271 274 return; 272 case BD_READ_BLOCK :273 case BD_WRITE_BLOCK:274 idx = IPC_GET_ARG1(call);275 size = IPC_GET_ARG2(call);276 if ( size > comm_size) {277 retval = E INVAL;275 case BD_READ_BLOCKS: 276 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 277 IPC_GET_ARG2(call)); 278 cnt = IPC_GET_ARG3(call); 279 if (cnt * block_size > comm_size) { 280 retval = ELIMIT; 278 281 break; 279 282 } 280 retval = ata_bd_rdwr(disk_id, method, idx, 281 size, fs_va); 283 retval = ata_bd_read_blocks(disk_id, ba, cnt, fs_va); 282 284 break; 285 case BD_WRITE_BLOCKS: 286 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 287 IPC_GET_ARG2(call)); 288 cnt = IPC_GET_ARG3(call); 289 if (cnt * block_size > comm_size) { 290 retval = ELIMIT; 291 break; 292 } 293 retval = ata_bd_write_blocks(disk_id, ba, cnt, fs_va); 294 break; 295 case BD_GET_BLOCK_SIZE: 296 ipc_answer_1(callid, EOK, block_size); 297 continue; 283 298 default: 284 299 retval = EINVAL; … … 373 388 } 374 389 375 /** Transfer a logical block from/to the device. 376 * 377 * @param disk_id Device index (0 or 1) 378 * @param method @c BD_READ_BLOCK or @c BD_WRITE_BLOCK 379 * @param blk_idx Index of the first block. 380 * @param size Size of the logical block. 381 * @param buf Data buffer. 382 * 383 * @return EOK on success, EIO on error. 384 */ 385 static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t blk_idx, size_t size, 386 void *buf) 387 { 390 /** Read multiple blocks from the device. */ 391 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt, 392 void *buf) { 393 388 394 int rc; 389 size_t now; 390 391 while (size > 0) { 392 now = size < block_size ? size : block_size; 393 if (now != block_size) 394 return EINVAL; 395 396 if (method == BD_READ_BLOCK) 397 rc = ata_bd_read_block(disk_id, blk_idx, 1, buf); 398 else 399 rc = ata_bd_write_block(disk_id, blk_idx, 1, buf); 400 395 396 while (cnt > 0) { 397 rc = ata_bd_read_block(disk_id, ba, 1, buf); 401 398 if (rc != EOK) 402 399 return rc; 403 400 401 ++ba; 402 --cnt; 404 403 buf += block_size; 405 blk_idx++; 406 407 if (size > block_size) 408 size -= block_size; 409 else 410 size = 0; 404 } 405 406 return EOK; 407 } 408 409 /** Write multiple blocks to the device. */ 410 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt, 411 const void *buf) { 412 413 int rc; 414 415 while (cnt > 0) { 416 rc = ata_bd_write_block(disk_id, ba, 1, buf); 417 if (rc != EOK) 418 return rc; 419 420 ++ba; 421 --cnt; 422 buf += block_size; 411 423 } 412 424 … … 466 478 * 467 479 * @param disk_id Device index (0 or 1) 468 * @param b lk_idx Index ofthe first block.469 * @param blk_cntNumber of blocks to transfer.480 * @param ba Address the first block. 481 * @param cnt Number of blocks to transfer. 470 482 * @param buf Buffer for holding the data. 471 483 * 472 484 * @return EOK on success, EIO on error. 473 485 */ 474 static int ata_bd_read_block(int disk_id, uint64_t b lk_idx, size_t blk_cnt,486 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt, 475 487 void *buf) 476 488 { … … 486 498 487 499 /* Compute block coordinates. */ 488 if (coord_calc(d, b lk_idx, &bc) != EOK)500 if (coord_calc(d, ba, &bc) != EOK) 489 501 return EINVAL; 490 502 … … 541 553 * 542 554 * @param disk_id Device index (0 or 1) 543 * @param b lk_idx Indexof the first block.544 * @param blk_cntNumber of blocks to transfer.555 * @param ba Address of the first block. 556 * @param cnt Number of blocks to transfer. 545 557 * @param buf Buffer holding the data to write. 546 558 * 547 559 * @return EOK on success, EIO on error. 548 560 */ 549 static int ata_bd_write_block(int disk_id, uint64_t b lk_idx, size_t blk_cnt,561 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt, 550 562 const void *buf) 551 563 { … … 560 572 561 573 /* Compute block coordinates. */ 562 if (coord_calc(d, b lk_idx, &bc) != EOK)574 if (coord_calc(d, ba, &bc) != EOK) 563 575 return EINVAL; 564 576 … … 620 632 * @return EOK on success or EINVAL if block index is past end of device. 621 633 */ 622 static int coord_calc(disk_t *d, uint64_t b lk_idx, block_coord_t *bc)634 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc) 623 635 { 624 636 uint64_t c; … … 626 638 627 639 /* Check device bounds. */ 628 if (b lk_idx>= d->blocks)640 if (ba >= d->blocks) 629 641 return EINVAL; 630 642 … … 634 646 case am_chs: 635 647 /* Compute CHS coordinates. */ 636 c = b lk_idx/ (d->geom.heads * d->geom.sectors);637 idx = b lk_idx% (d->geom.heads * d->geom.sectors);648 c = ba / (d->geom.heads * d->geom.sectors); 649 idx = ba % (d->geom.heads * d->geom.sectors); 638 650 639 651 bc->cyl_lo = c & 0xff; … … 645 657 case am_lba28: 646 658 /* Compute LBA-28 coordinates. */ 647 bc->c0 = b lk_idx& 0xff; /* bits 0-7 */648 bc->c1 = (b lk_idx >> 8) & 0xff;/* bits 8-15 */649 bc->c2 = (b lk_idx>> 16) & 0xff; /* bits 16-23 */650 bc->h = (b lk_idx>> 24) & 0x0f; /* bits 24-27 */659 bc->c0 = ba & 0xff; /* bits 0-7 */ 660 bc->c1 = (ba >> 8) & 0xff; /* bits 8-15 */ 661 bc->c2 = (ba >> 16) & 0xff; /* bits 16-23 */ 662 bc->h = (ba >> 24) & 0x0f; /* bits 24-27 */ 651 663 break; 652 664 653 665 case am_lba48: 654 666 /* Compute LBA-48 coordinates. */ 655 bc->c0 = b lk_idx& 0xff; /* bits 0-7 */656 bc->c1 = (b lk_idx >> 8) & 0xff;/* bits 8-15 */657 bc->c2 = (b lk_idx>> 16) & 0xff; /* bits 16-23 */658 bc->c3 = (b lk_idx>> 24) & 0xff; /* bits 24-31 */659 bc->c4 = (b lk_idx>> 32) & 0xff; /* bits 32-39 */660 bc->c5 = (b lk_idx>> 40) & 0xff; /* bits 40-47 */667 bc->c0 = ba & 0xff; /* bits 0-7 */ 668 bc->c1 = (ba >> 8) & 0xff; /* bits 8-15 */ 669 bc->c2 = (ba >> 16) & 0xff; /* bits 16-23 */ 670 bc->c3 = (ba >> 24) & 0xff; /* bits 24-31 */ 671 bc->c4 = (ba >> 32) & 0xff; /* bits 32-39 */ 672 bc->c5 = (ba >> 40) & 0xff; /* bits 40-47 */ 661 673 bc->h = 0; 662 674 break;
Note:
See TracChangeset
for help on using the changeset viewer.