Changeset 15d0046 in mainline for uspace/drv/block/ata_bd/ata_bd.c
- Timestamp:
- 2014-09-12T13:22:33Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9b20126
- Parents:
- 8db09e4 (diff), 105d8d6 (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/drv/block/ata_bd/ata_bd.c
r8db09e4 r15d0046 54 54 #include <bd_srv.h> 55 55 #include <fibril_synch.h> 56 #include <scsi/mmc.h> 57 #include <scsi/sbc.h> 58 #include <scsi/spc.h> 56 59 #include <stdint.h> 57 60 #include <str.h> … … 94 97 static int ata_bd_get_block_size(bd_srv_t *, size_t *); 95 98 static int ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 99 static int ata_bd_sync_cache(bd_srv_t *, aoff64_t, size_t); 96 100 97 101 static int ata_rcmd_read(disk_t *disk, uint64_t ba, size_t cnt, … … 99 103 static int ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt, 100 104 const void *buf); 105 static int ata_rcmd_flush_cache(disk_t *disk); 101 106 static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id); 102 107 static int ata_identify_dev(disk_t *disk, void *buf); 103 108 static int ata_identify_pkt_dev(disk_t *disk, void *buf); 104 109 static int ata_cmd_packet(disk_t *disk, const void *cpkt, size_t cpkt_size, 105 void *obuf, size_t obuf_size); 106 static int ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size); 110 void *obuf, size_t obuf_size, size_t *rcvd_size); 111 static int ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size, 112 size_t *rcvd_size); 107 113 static int ata_pcmd_read_12(disk_t *disk, uint64_t ba, size_t cnt, 108 114 void *obuf, size_t obuf_size); 115 static int ata_pcmd_read_capacity(disk_t *disk, uint64_t *nblocks, 116 size_t *block_size); 109 117 static int ata_pcmd_read_toc(disk_t *disk, uint8_t ses, 110 118 void *obuf, size_t obuf_size); … … 123 131 .write_blocks = ata_bd_write_blocks, 124 132 .get_block_size = ata_bd_get_block_size, 125 .get_num_blocks = ata_bd_get_num_blocks 133 .get_num_blocks = ata_bd_get_num_blocks, 134 .sync_cache = ata_bd_sync_cache 126 135 }; 127 136 … … 339 348 identify_data_t idata; 340 349 uint8_t model[40]; 341 ata_inquiry_data_t inq_data; 350 scsi_std_inquiry_data_t inq_data; 351 size_t isize; 342 352 uint16_t w; 343 353 uint8_t c; 344 354 uint16_t bc; 355 uint64_t nblocks; 356 size_t block_size; 345 357 size_t pos, len; 346 358 int rc; … … 457 469 if (d->dev_type == ata_pkt_dev) { 458 470 /* Send inquiry. */ 459 rc = ata_pcmd_inquiry(d, &inq_data, sizeof(inq_data) );460 if (rc != EOK ) {471 rc = ata_pcmd_inquiry(d, &inq_data, sizeof(inq_data), &isize); 472 if (rc != EOK || isize < sizeof(inq_data)) { 461 473 ddf_msg(LVL_ERROR, "Device inquiry failed."); 462 474 d->present = false; … … 465 477 466 478 /* Check device type. */ 467 if (INQUIRY_PDEV_TYPE(inq_data.p dev_type) != PDEV_TYPE_CDROM)479 if (INQUIRY_PDEV_TYPE(inq_data.pqual_devtype) != SCSI_DEV_CD_DVD) 468 480 ddf_msg(LVL_WARN, "Peripheral device type is not CD-ROM."); 469 481 470 /* Assume 2k block size for now. */ 471 d->block_size = 2048; 482 rc = ata_pcmd_read_capacity(d, &nblocks, &block_size); 483 if (rc != EOK) { 484 ddf_msg(LVL_ERROR, "Read capacity command failed."); 485 d->present = false; 486 return EIO; 487 } 488 489 d->blocks = nblocks; 490 d->block_size = block_size; 472 491 } else { 473 492 /* Assume register Read always uses 512-byte blocks. */ … … 570 589 } 571 590 591 /** Flush cache. */ 592 static int ata_bd_sync_cache(bd_srv_t *bd, uint64_t ba, size_t cnt) 593 { 594 disk_t *disk = bd_srv_disk(bd); 595 596 /* ATA cannot flush just some blocks, we just flush everything. */ 597 (void)ba; 598 (void)cnt; 599 600 return ata_rcmd_flush_cache(disk); 601 } 602 572 603 /** PIO data-in command protocol. */ 573 604 static int ata_pio_data_in(disk_t *disk, void *obuf, size_t obuf_size, … … 623 654 } 624 655 } 656 657 if (status & SR_ERR) 658 return EIO; 659 660 return EOK; 661 } 662 663 /** PIO non-data command protocol. */ 664 static int ata_pio_nondata(disk_t *disk) 665 { 666 ata_ctrl_t *ctrl = disk->ctrl; 667 uint8_t status; 668 669 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) 670 return EIO; 625 671 626 672 if (status & SR_ERR) … … 722 768 * @param obuf Buffer for storing data read from device 723 769 * @param obuf_size Size of obuf in bytes 770 * @param rcvd_size Place to store number of bytes read or @c NULL 724 771 * 725 772 * @return EOK on success, EIO on error. 726 773 */ 727 774 static int ata_cmd_packet(disk_t *disk, const void *cpkt, size_t cpkt_size, 728 void *obuf, size_t obuf_size )775 void *obuf, size_t obuf_size, size_t *rcvd_size) 729 776 { 730 777 ata_ctrl_t *ctrl = disk->ctrl; … … 800 847 return EIO; 801 848 849 if (rcvd_size != NULL) 850 *rcvd_size = data_size; 802 851 return EOK; 803 852 } … … 811 860 * @return EOK on success, EIO on error. 812 861 */ 813 static int ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size) 814 { 815 ata_pcmd_inquiry_t cp; 862 static int ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size, 863 size_t *rcvd_size) 864 { 865 uint8_t cpb[12]; 866 scsi_cdb_inquiry_t *cp = (scsi_cdb_inquiry_t *)cpb; 816 867 int rc; 817 868 818 memset(&cp, 0, sizeof(cp)); 819 820 cp.opcode = PCMD_INQUIRY; 821 cp.alloc_len = min(obuf_size, 0xff); /* Allocation length */ 822 823 rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size); 869 memset(cpb, 0, sizeof(cpb)); 870 871 /* 872 * For SFF 8020 compliance the inquiry must be padded to 12 bytes 873 * and allocation length must fit in one byte. 874 */ 875 cp->op_code = SCSI_CMD_INQUIRY; 876 877 /* Allocation length */ 878 cp->alloc_len = host2uint16_t_be(min(obuf_size, 0xff)); 879 880 rc = ata_cmd_packet(disk, cpb, sizeof(cpb), obuf, obuf_size, rcvd_size); 824 881 if (rc != EOK) 825 882 return rc; 883 884 return EOK; 885 } 886 887 /** Issue ATAPI read capacity(10) command. 888 * 889 * @param disk Disk 890 * @param nblocks Place to store number of blocks 891 * @param block_size Place to store block size 892 * 893 * @return EOK on success, EIO on error. 894 */ 895 static int ata_pcmd_read_capacity(disk_t *disk, uint64_t *nblocks, 896 size_t *block_size) 897 { 898 scsi_cdb_read_capacity_10_t cdb; 899 scsi_read_capacity_10_data_t data; 900 size_t rsize; 901 int rc; 902 903 memset(&cdb, 0, sizeof(cdb)); 904 cdb.op_code = SCSI_CMD_READ_CAPACITY_10; 905 906 rc = ata_cmd_packet(disk, &cdb, sizeof(cdb), &data, sizeof(data), &rsize); 907 if (rc != EOK) 908 return rc; 909 910 if (rsize != sizeof(data)) 911 return EIO; 912 913 *nblocks = uint32_t_be2host(data.last_lba) + 1; 914 *block_size = uint32_t_be2host(data.block_size); 826 915 827 916 return EOK; … … 844 933 void *obuf, size_t obuf_size) 845 934 { 846 ata_pcmd_read_12_t cp;935 scsi_cdb_read_12_t cp; 847 936 int rc; 848 937 … … 852 941 memset(&cp, 0, sizeof(cp)); 853 942 854 cp.op code = PCMD_READ_12;855 cp. ba = host2uint32_t_be(ba);856 cp. nblocks= host2uint32_t_be(cnt);857 858 rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size );943 cp.op_code = SCSI_CMD_READ_12; 944 cp.lba = host2uint32_t_be(ba); 945 cp.xfer_len = host2uint32_t_be(cnt); 946 947 rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size, NULL); 859 948 if (rc != EOK) 860 949 return rc; … … 883 972 size_t obuf_size) 884 973 { 885 ata_pcmd_read_toc_t cp; 974 uint8_t cpb[12]; 975 scsi_cdb_read_toc_t *cp = (scsi_cdb_read_toc_t *)cpb; 886 976 int rc; 887 977 888 memset( &cp, 0, sizeof(cp));889 890 cp .opcode = PCMD_READ_TOC;891 cp .msf = 0;892 cp .format = 0x01; /* 0x01 = multi-session mode */893 cp .start= session;894 cp .size= host2uint16_t_be(obuf_size);895 cp .oldformat= 0x40; /* 0x01 = multi-session mode (shifted to MSB) */896 897 rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size);978 memset(cpb, 0, sizeof(cpb)); 979 980 cp->op_code = SCSI_CMD_READ_TOC; 981 cp->msf = 0; 982 cp->format = 0x01; /* 0x01 = multi-session mode */ 983 cp->track_sess_no = session; 984 cp->alloc_len = host2uint16_t_be(obuf_size); 985 cp->control = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */ 986 987 rc = ata_cmd_packet(disk, cpb, sizeof(cpb), obuf, obuf_size, NULL); 898 988 if (rc != EOK) 899 989 return rc; 900 990 901 991 return EOK; 902 992 } … … 1016 1106 rc = ata_pio_data_out(disk, buf, cnt * disk->block_size, 1017 1107 disk->block_size, cnt); 1108 1109 fibril_mutex_unlock(&ctrl->lock); 1110 return rc; 1111 } 1112 1113 /** Flush cached data to nonvolatile storage. 1114 * 1115 * @param disk Disk 1116 * 1117 * @return EOK on success, EIO on error. 1118 */ 1119 static int ata_rcmd_flush_cache(disk_t *disk) 1120 { 1121 ata_ctrl_t *ctrl = disk->ctrl; 1122 uint8_t drv_head; 1123 int rc; 1124 1125 /* New value for Drive/Head register */ 1126 drv_head = 1127 (disk_dev_idx(disk) != 0) ? DHR_DRV : 0; 1128 1129 fibril_mutex_lock(&ctrl->lock); 1130 1131 /* Program a Flush Cache operation. */ 1132 1133 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 1134 fibril_mutex_unlock(&ctrl->lock); 1135 return EIO; 1136 } 1137 1138 pio_write_8(&ctrl->cmd->drive_head, drv_head); 1139 1140 if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 1141 fibril_mutex_unlock(&ctrl->lock); 1142 return EIO; 1143 } 1144 1145 pio_write_8(&ctrl->cmd->command, CMD_FLUSH_CACHE); 1146 1147 rc = ata_pio_nondata(disk); 1018 1148 1019 1149 fibril_mutex_unlock(&ctrl->lock);
Note:
See TracChangeset
for help on using the changeset viewer.