Changeset 31de325 in mainline
- Timestamp:
- 2009-08-08T15:21:01Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 330965c
- Parents:
- 54d0ddc
- Location:
- uspace/srv/bd/ata_bd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/ata_bd/ata_bd.c
r54d0ddc r31de325 86 86 const void *buf); 87 87 static int drive_identify(int drive_id, disk_t *d); 88 static uint8_t wait_status(unsigned set, unsigned n_reset); 88 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, 89 unsigned timeout); 89 90 90 91 int main(int argc, char **argv) … … 101 102 return -1; 102 103 103 (void) drive_identify(0, &disk[0]); 104 (void) drive_identify(1, &disk[1]); 104 for (i = 0; i < MAX_DISKS; i++) { 105 printf("Identify drive %d... ", i); 106 fflush(stdout); 107 108 rc = drive_identify(i, &disk[i]); 109 110 if (rc == EOK) { 111 printf("%u cylinders, %u heads, %u sectors\n", 112 disk[i].cylinders, disk[i].heads, disk[i].sectors); 113 } else { 114 printf("Not found.\n"); 115 } 116 } 105 117 106 118 n_disks = 0; … … 295 307 size_t i; 296 308 297 printf("Identify drive %d... ", disk_id);298 fflush(stdout);299 300 309 drv_head = ((disk_id != 0) ? DHR_DRV : 0); 301 310 d->present = false; 302 311 303 wait_status(0, ~SR_BSY); 312 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 313 return EIO; 314 304 315 pio_write_8(&cmd->drive_head, drv_head); 305 316 306 317 /* 307 * Detect if drive is present. This is only temorary.308 * We should really try for some time before giving up.318 * This is where we would most likely expect a non-existing device to 319 * show up by not setting SR_DRDY. 309 320 */ 310 status = wait_status(0, ~SR_BSY); 311 312 if ((status & SR_DRDY) == 0) { 313 printf("None attached.\n"); 314 return ENOENT; 315 } 316 /***/ 317 318 wait_status(SR_DRDY, ~SR_BSY); 321 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 322 return EIO; 323 319 324 pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE); 320 325 321 status = wait_status(0, ~SR_BSY); 326 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) 327 return EIO; 322 328 323 329 /* Read data from the disk buffer. */ … … 344 350 345 351 d->blocks = d->cylinders * d->heads * d->sectors; 346 347 printf("Geometry: %u cylinders, %u heads, %u sectors\n",348 d->cylinders, d->heads, d->sectors);349 352 350 353 d->present = true; … … 396 399 /* Program a Read Sectors operation. */ 397 400 398 wait_status(0, ~SR_BSY); 401 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 402 fibril_mutex_unlock(&d->lock); 403 return EIO; 404 } 405 399 406 pio_write_8(&cmd->drive_head, drv_head); 400 407 401 wait_status(SR_DRDY, ~SR_BSY); 408 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 409 fibril_mutex_unlock(&d->lock); 410 return EIO; 411 } 412 402 413 pio_write_8(&cmd->sector_count, 1); 403 414 pio_write_8(&cmd->sector_number, s); … … 407 418 pio_write_8(&cmd->command, CMD_READ_SECTORS); 408 419 409 status = wait_status(0, ~SR_BSY); 410 411 /* Read data from the disk buffer. */ 420 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 421 fibril_mutex_unlock(&d->lock); 422 return EIO; 423 } 412 424 413 425 if ((status & SR_DRQ) != 0) { 426 /* Read data from the device buffer. */ 427 414 428 for (i = 0; i < block_size / 2; i++) { 415 429 data = pio_read_16(&cmd->data_port); … … 464 478 fibril_mutex_lock(&d->lock); 465 479 466 /* Program a Read Sectors operation. */ 467 468 wait_status(0, ~SR_BSY); 480 /* Program a Write Sectors operation. */ 481 482 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 483 fibril_mutex_unlock(&d->lock); 484 return EIO; 485 } 486 469 487 pio_write_8(&cmd->drive_head, drv_head); 470 488 471 wait_status(SR_DRDY, ~SR_BSY); 489 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 490 fibril_mutex_unlock(&d->lock); 491 return EIO; 492 } 493 472 494 pio_write_8(&cmd->sector_count, 1); 473 495 pio_write_8(&cmd->sector_number, s); … … 477 499 pio_write_8(&cmd->command, CMD_WRITE_SECTORS); 478 500 479 status = wait_status(0, ~SR_BSY); 480 481 /* Write data to the disk buffer. */ 501 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 502 fibril_mutex_unlock(&d->lock); 503 return EIO; 504 } 482 505 483 506 if ((status & SR_DRQ) != 0) { 507 /* Write data to the device buffer. */ 508 484 509 for (i = 0; i < block_size / 2; i++) { 485 510 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]); … … 495 520 } 496 521 497 /** Wait until some status bits are set and some reset.522 /** Wait until some status bits are set and some are reset. 498 523 * 499 524 * Example: wait_status(SR_DRDY, ~SR_BSY) waits for SR_DRDY to become … … 502 527 * @param set Combination if bits which must be all set. 503 528 * @param n_reset Negated combination of bits which must be all reset. 504 * @return The last value of status register that was read. 505 */ 506 static uint8_t wait_status(unsigned set, unsigned n_reset) 529 * @param pstatus Pointer where to store last read status or NULL. 530 * @param timeout Timeout in 10ms units. 531 * 532 * @return EOK on success, EIO on timeout. 533 */ 534 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, 535 unsigned timeout) 507 536 { 508 537 uint8_t status; 509 510 do { 538 int cnt; 539 540 status = pio_read_8(&cmd->status); 541 542 /* 543 * This is crude, yet simple. First try with 1us delays 544 * (most likely the device will respond very fast). If not, 545 * start trying every 10 ms. 546 */ 547 548 cnt = 100; 549 while ((status & ~n_reset) != 0 || (status & set) != set) { 550 async_usleep(1); 551 --cnt; 552 if (cnt <= 0) break; 553 511 554 status = pio_read_8(&cmd->status); 512 } while ((status & ~n_reset) != 0 || (status & set) != set); 513 514 return status; 555 } 556 557 cnt = timeout; 558 while ((status & ~n_reset) != 0 || (status & set) != set) { 559 async_usleep(10000); 560 --cnt; 561 if (cnt <= 0) break; 562 563 status = pio_read_8(&cmd->status); 564 } 565 566 if (pstatus) 567 *pstatus = status; 568 569 if (cnt == 0) 570 return EIO; 571 572 return EOK; 515 573 } 516 574 -
uspace/srv/bd/ata_bd/ata_bd.h
r54d0ddc r31de325 135 135 }; 136 136 137 /** Timeout definitions. Unit is 10 ms. */ 138 enum ata_timeout { 139 TIMEOUT_PROBE = 100, /* 1 s */ 140 TIMEOUT_BSY = 100, /* 1 s */ 141 TIMEOUT_DRDY = 1000 /* 10 s */ 142 }; 143 137 144 typedef struct { 138 145 bool present;
Note:
See TracChangeset
for help on using the changeset viewer.