Changeset 21989e5 in mainline
- Timestamp:
- 2024-05-01T07:46:48Z (8 months ago)
- Branches:
- master
- Children:
- 64cf7a3
- Parents:
- 926d9d9b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/block/ata_bd/ata_bd.c
r926d9d9b r21989e5 115 115 void *obuf, size_t obuf_size); 116 116 static void disk_print_summary(disk_t *d); 117 static size_t ata_disk_maxnb(disk_t *d); 117 118 static errno_t coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc); 118 119 static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc, … … 514 515 { 515 516 disk_t *disk = bd_srv_disk(bd); 517 size_t maxnb; 518 size_t nb; 516 519 errno_t rc; 517 520 … … 519 522 return EINVAL; 520 523 524 /* Maximum number of blocks to transfer at the same time */ 525 maxnb = ata_disk_maxnb(disk); 521 526 while (cnt > 0) { 527 nb = min(maxnb, cnt); 522 528 if (disk->dev_type == ata_reg_dev) { 523 rc = ata_rcmd_read(disk, ba, 1, buf);529 rc = ata_rcmd_read(disk, ba, nb, buf); 524 530 } else { 525 rc = ata_pcmd_read_12(disk, ba, 1, buf,531 rc = ata_pcmd_read_12(disk, ba, nb, buf, 526 532 disk->block_size); 527 533 } … … 530 536 return rc; 531 537 532 ++ba;533 --cnt;534 buf += disk->block_size ;538 ba += nb; 539 cnt -= nb; 540 buf += disk->block_size * nb; 535 541 } 536 542 … … 551 557 { 552 558 disk_t *disk = bd_srv_disk(bd); 559 size_t maxnb; 560 size_t nb; 553 561 errno_t rc; 554 562 … … 559 567 return EINVAL; 560 568 569 /* Maximum number of blocks to transfer at the same time */ 570 maxnb = ata_disk_maxnb(disk); 561 571 while (cnt > 0) { 562 rc = ata_rcmd_write(disk, ba, 1, buf); 572 nb = min(maxnb, cnt); 573 rc = ata_rcmd_write(disk, ba, nb, buf); 563 574 if (rc != EOK) 564 575 return rc; 565 576 566 ++ba;567 --cnt;568 buf += disk->block_size ;577 ba += nb; 578 cnt -= nb; 579 buf += disk->block_size * nb; 569 580 } 570 581 … … 609 620 uint16_t data; 610 621 size_t i; 622 size_t bidx; 611 623 uint8_t status; 612 624 613 /* XXX Support multiple blocks */ 614 assert(nblocks == 1); 625 assert(nblocks > 0); 615 626 assert(blk_size % 2 == 0); 616 627 617 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) 618 return EIO; 619 620 if ((status & SR_DRQ) != 0) { 628 bidx = 0; 629 while (nblocks > 0) { 630 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) 631 return EIO; 632 633 if ((status & SR_DRQ) == 0) { 634 break; 635 } 636 621 637 /* Read data from the device buffer. */ 622 623 638 for (i = 0; i < blk_size / 2; i++) { 624 639 data = pio_read_16(&ctrl->cmd->data_port); 625 ((uint16_t *) obuf)[i] = data; 626 } 640 ((uint16_t *) obuf)[bidx++] = data; 641 } 642 643 --nblocks; 627 644 } 628 645 629 646 if ((status & SR_ERR) != 0) 647 return EIO; 648 if (nblocks > 0) 630 649 return EIO; 631 650 … … 639 658 ata_ctrl_t *ctrl = disk->ctrl; 640 659 size_t i; 660 size_t bidx; 641 661 uint8_t status; 642 662 643 /* XXX Support multiple blocks */ 644 assert(nblocks == 1); 663 assert(nblocks > 0); 645 664 assert(blk_size % 2 == 0); 646 665 647 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) 648 return EIO; 649 650 if ((status & SR_DRQ) != 0) { 666 bidx = 0; 667 while (nblocks > 0) { 668 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) 669 return EIO; 670 671 if ((status & SR_DRQ) == 0) 672 break; 673 651 674 /* Write data to the device buffer. */ 652 653 675 for (i = 0; i < blk_size / 2; i++) { 654 pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) buf)[i]); 655 } 676 pio_write_16(&ctrl->cmd->data_port, 677 ((uint16_t *) buf)[bidx++]); 678 } 679 680 --nblocks; 656 681 } 657 682 658 683 if (status & SR_ERR) 684 return EIO; 685 if (nblocks > 0) 659 686 return EIO; 660 687 … … 781 808 uint8_t drv_head; 782 809 size_t data_size; 810 size_t remain; 811 size_t bidx; 783 812 uint16_t val; 784 813 … … 816 845 pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) cpkt)[i]); 817 846 818 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 819 fibril_mutex_unlock(&ctrl->lock); 820 return EIO; 821 } 822 823 if ((status & SR_DRQ) == 0) { 824 fibril_mutex_unlock(&ctrl->lock); 825 return EIO; 826 } 827 828 /* Read byte count. */ 829 data_size = (uint16_t) pio_read_8(&ctrl->cmd->cylinder_low) + 830 ((uint16_t) pio_read_8(&ctrl->cmd->cylinder_high) << 8); 831 832 /* Check whether data fits into output buffer. */ 833 if (data_size > obuf_size) { 834 /* Output buffer is too small to store data. */ 835 fibril_mutex_unlock(&ctrl->lock); 836 return EIO; 837 } 838 839 /* Read data from the device buffer. */ 840 for (i = 0; i < (data_size + 1) / 2; i++) { 841 val = pio_read_16(&ctrl->cmd->data_port); 842 ((uint16_t *) obuf)[i] = val; 847 bidx = 0; 848 remain = obuf_size; 849 while (remain > 0) { 850 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 851 fibril_mutex_unlock(&ctrl->lock); 852 return EIO; 853 } 854 855 if ((status & SR_DRQ) == 0) 856 break; 857 858 /* Read byte count. */ 859 data_size = (uint16_t) pio_read_8(&ctrl->cmd->cylinder_low) + 860 ((uint16_t) pio_read_8(&ctrl->cmd->cylinder_high) << 8); 861 862 /* Check whether data fits into output buffer. */ 863 if (data_size > obuf_size) { 864 /* Output buffer is too small to store data. */ 865 fibril_mutex_unlock(&ctrl->lock); 866 return EIO; 867 } 868 869 /* Read data from the device buffer. */ 870 for (i = 0; i < (data_size + 1) / 2; i++) { 871 val = pio_read_16(&ctrl->cmd->data_port); 872 ((uint16_t *) obuf)[bidx++] = val; 873 } 874 875 remain -= data_size; 843 876 } 844 877 … … 849 882 850 883 if (rcvd_size != NULL) 851 *rcvd_size = data_size;884 *rcvd_size = obuf_size - remain; 852 885 return EOK; 853 886 } … … 1040 1073 1041 1074 /* Program block coordinates into the device. */ 1042 coord_sc_program(ctrl, &bc, 1);1075 coord_sc_program(ctrl, &bc, blk_cnt); 1043 1076 1044 1077 pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ? … … 1100 1133 1101 1134 /* Program block coordinates into the device. */ 1102 coord_sc_program(ctrl, &bc, 1);1135 coord_sc_program(ctrl, &bc, cnt); 1103 1136 1104 1137 pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ? … … 1150 1183 fibril_mutex_unlock(&ctrl->lock); 1151 1184 return rc; 1185 } 1186 1187 /** Get the maximum number of blocks to be transferred in one I/O 1188 * 1189 * @param d Disk 1190 * @return Maximum number of blocks 1191 */ 1192 static size_t ata_disk_maxnb(disk_t *d) 1193 { 1194 size_t maxnb; 1195 1196 maxnb = 0; 1197 1198 if (d->dev_type == ata_pkt_dev) { 1199 /* Could be more depending on SCSI command support */ 1200 maxnb = 0x100; 1201 } else { 1202 switch (d->amode) { 1203 case am_chs: 1204 case am_lba28: 1205 maxnb = 0x100; 1206 break; 1207 case am_lba48: 1208 maxnb = 0x10000; 1209 break; 1210 } 1211 } 1212 1213 /* 1214 * If using DMA, this needs to be further restricted not to 1215 * exceed DMA buffer size. 1216 */ 1217 return maxnb; 1152 1218 } 1153 1219
Note:
See TracChangeset
for help on using the changeset viewer.