Changeset 88743b5 in mainline
- Timestamp:
- 2011-02-01T05:54:29Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0d247f5
- Parents:
- 7a56e33e
- Location:
- uspace/srv/bd/ata_bd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/ata_bd/ata_bd.c
r7a56e33e r88743b5 113 113 static int drive_identify(int drive_id, void *buf); 114 114 static int identify_pkt_dev(int dev_idx, void *buf); 115 static int ata_cmd_packet(int dev_idx, const void *cpkt, size_t cpkt_size, 116 void *obuf, size_t obuf_size); 117 static int ata_pcmd_inquiry(int dev_idx, void *obuf, size_t obuf_size); 115 118 static void disk_print_summary(disk_t *d); 116 119 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc); … … 360 363 identify_data_t idata; 361 364 uint8_t model[40]; 365 uint8_t inq_buf[36]; 362 366 uint16_t w; 363 367 uint8_t c; … … 367 371 368 372 d->present = false; 373 fibril_mutex_initialize(&d->lock); 369 374 370 375 /* Try identify command. */ … … 373 378 /* Success. It's a register (non-packet) device. */ 374 379 printf("ATA register-only device found.\n"); 375 d->present = true;376 380 d->dev_type = ata_reg_dev; 377 381 } else if (rc == EIO) { … … 383 387 if (rc == EOK) { 384 388 /* We have a packet device. */ 385 d->present = true;386 389 d->dev_type = ata_pkt_dev; 387 390 } else { 388 391 /* Nope. Something's there, but not recognized. */ 392 return EIO; 389 393 } 390 394 } else { 391 395 /* Operation timed out. That means there is no device there. */ 392 } 393 394 if (d->present == false) 395 return EIO; 396 return EIO; 397 } 396 398 397 399 printf("device caps: 0x%04x\n", idata.caps); … … 462 464 d->model[pos] = '\0'; 463 465 466 if (d->dev_type == ata_pkt_dev) { 467 /* Send inquiry. */ 468 rc = ata_pcmd_inquiry(0, inq_buf, 36); 469 if (rc != EOK) { 470 printf("Device inquiry failed.\n"); 471 d->present = false; 472 return EIO; 473 } 474 475 /* Check device type. */ 476 if ((inq_buf[0] & 0x1f) != 0x05) 477 printf("Warning: Peripheral device type is not CD-ROM.\n"); 478 } 479 464 480 d->present = true; 465 fibril_mutex_initialize(&d->lock);466 467 481 return EOK; 468 482 } … … 601 615 if ((status & SR_ERR) != 0) 602 616 return EIO; 617 618 return EOK; 619 } 620 621 /** Issue packet command (i. e. write a command packet to the device). 622 * 623 * Only data-in commands are supported (e.g. inquiry, read). 624 * 625 * @param dev_idx Device index (0 or 1) 626 * @param obuf Buffer for storing data read from device 627 * @param obuf_size Size of obuf in bytes 628 * 629 * @return EOK on success, EIO on error. 630 */ 631 static int ata_cmd_packet(int dev_idx, const void *cpkt, size_t cpkt_size, 632 void *obuf, size_t obuf_size) 633 { 634 size_t i; 635 uint8_t status; 636 uint8_t drv_head; 637 disk_t *d; 638 size_t data_size; 639 uint16_t val; 640 641 d = &disk[dev_idx]; 642 fibril_mutex_lock(&d->lock); 643 644 /* New value for Drive/Head register */ 645 drv_head = 646 ((dev_idx != 0) ? DHR_DRV : 0); 647 648 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) { 649 fibril_mutex_unlock(&d->lock); 650 return EIO; 651 } 652 653 pio_write_8(&cmd->drive_head, drv_head); 654 655 if (wait_status(0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) { 656 fibril_mutex_unlock(&d->lock); 657 return EIO; 658 } 659 660 /* Byte count <- max. number of bytes we can read in one transfer. */ 661 pio_write_8(&cmd->cylinder_low, 0xfe); 662 pio_write_8(&cmd->cylinder_high, 0xff); 663 664 pio_write_8(&cmd->command, CMD_PACKET); 665 666 if (wait_status(SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 667 fibril_mutex_unlock(&d->lock); 668 return EIO; 669 } 670 671 /* Write command packet. */ 672 for (i = 0; i < (cpkt_size + 1) / 2; i++) 673 pio_write_16(&cmd->data_port, ((uint16_t *) cpkt)[i]); 674 675 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 676 fibril_mutex_unlock(&d->lock); 677 return EIO; 678 } 679 680 if ((status & SR_DRQ) == 0) { 681 fibril_mutex_unlock(&d->lock); 682 return EIO; 683 } 684 685 /* Read byte count. */ 686 data_size = (uint16_t) pio_read_8(&cmd->cylinder_low) + 687 ((uint16_t) pio_read_8(&cmd->cylinder_high) << 8); 688 689 /* Check whether data fits into output buffer. */ 690 if (data_size > obuf_size) { 691 /* Output buffer is too small to store data. */ 692 fibril_mutex_unlock(&d->lock); 693 return EIO; 694 } 695 696 /* Read data from the device buffer. */ 697 for (i = 0; i < (data_size + 1) / 2; i++) { 698 val = pio_read_16(&cmd->data_port); 699 ((uint16_t *) obuf)[i] = val; 700 } 701 702 if (status & SR_ERR) { 703 fibril_mutex_unlock(&d->lock); 704 return EIO; 705 } 706 707 fibril_mutex_unlock(&d->lock); 708 709 return EOK; 710 } 711 712 /** Send ATAPI Inquiry. 713 * 714 * @param dev_idx Device index (0 or 1) 715 * @param obuf Buffer for storing inquiry data read from device 716 * @param obuf_size Size of obuf in bytes 717 * 718 * @return EOK on success, EIO on error. 719 */ 720 static int ata_pcmd_inquiry(int dev_idx, void *obuf, size_t obuf_size) 721 { 722 uint8_t cp[12]; 723 int rc; 724 725 memset(cp, 0, 12); 726 cp[0] = 0x12; /* Inquiry */ 727 cp[4] = min(obuf_size, 0xff); /* Allocation length */ 728 729 rc = ata_cmd_packet(0, cp, 12, obuf, obuf_size); 730 if (rc != EOK) 731 return rc; 603 732 604 733 return EOK; -
uspace/srv/bd/ata_bd/ata_hw.h
r7a56e33e r88743b5 134 134 CMD_WRITE_SECTORS = 0x30, 135 135 CMD_WRITE_SECTORS_EXT = 0x34, 136 CMD_PACKET = 0xA0, 136 137 CMD_IDENTIFY_PKT_DEV = 0xA1, 137 138 CMD_IDENTIFY_DRIVE = 0xEC
Note:
See TracChangeset
for help on using the changeset viewer.