Changeset 96cbd18 in mainline
- Timestamp:
- 2013-06-21T18:54:29Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 89ac5513, ccf282f
- Parents:
- 7901ac8
- Location:
- uspace/srv/bd/ata_bd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/ata_bd/ata_bd.c
r7901ac8 r96cbd18 1 1 /* 2 * Copyright (c) 20 09Jiri Svoboda2 * Copyright (c) 2013 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 35 35 * @brief ATA disk driver 36 36 * 37 * This driver supports CHS, 28-bit and 48-bit LBA addressing . It only uses38 * P IO transfers. There is no support DMA, the PACKET feature set or any other39 * fancy features such as S.M.A.R.T, removable devices, etc.37 * This driver supports CHS, 28-bit and 48-bit LBA addressing, as well as 38 * PACKET devices. It only uses PIO transfers. There is no support DMA 39 * or any other fancy features such as S.M.A.R.T, removable devices, etc. 40 40 * 41 41 * This driver is based on the ATA-1, ATA-2, ATA-3 and ATA/ATAPI-4 through 7 … … 80 80 static const size_t identify_data_size = 512; 81 81 82 /** I/O base address of the command registers. */83 static uintptr_t cmd_physical;84 /** I/O base address of the control registers. */85 static uintptr_t ctl_physical;86 87 82 /** I/O base addresses for legacy (ISA-compatible) controllers. */ 88 83 static ata_base_t legacy_base[LEGACY_CTLS] = { … … 93 88 }; 94 89 95 static ata_cmd_t *cmd; 96 static ata_ctl_t *ctl; 97 98 /** Per-disk state. */ 99 static disk_t ata_disk[MAX_DISKS]; 90 /** Controller */ 91 static ata_ctrl_t ata_ctrl; 100 92 101 93 static void print_syntax(void); 102 static int ata_bd_init( void);94 static int ata_bd_init(ata_ctrl_t *ctrl); 103 95 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *); 104 96 … … 117 109 static int ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt, 118 110 const void *buf); 119 static int disk_init( disk_t *d, int disk_id);111 static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id); 120 112 static int drive_identify(disk_t *disk, void *buf); 121 113 static int identify_pkt_dev(disk_t *disk, void *buf); … … 129 121 static void disk_print_summary(disk_t *d); 130 122 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc); 131 static void coord_sc_program(const block_coord_t *bc, uint16_t scnt); 132 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, 133 unsigned timeout); 123 static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc, 124 uint16_t scnt); 125 static int wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset, 126 uint8_t *pstatus, unsigned timeout); 134 127 135 128 static bd_ops_t ata_bd_ops = { … … 160 153 unsigned ctl_num; 161 154 char *eptr; 155 ata_ctrl_t *ctrl = &ata_ctrl; 162 156 163 157 printf(NAME ": ATA disk driver\n"); … … 174 168 } 175 169 176 c md_physical = legacy_base[ctl_num - 1].cmd;177 ct l_physical = legacy_base[ctl_num - 1].ctl;178 179 printf("I/O address %p/%p\n", (void *) c md_physical,180 (void *) ct l_physical);181 182 if (ata_bd_init( ) != EOK)170 ctrl->cmd_physical = legacy_base[ctl_num - 1].cmd; 171 ctrl->ctl_physical = legacy_base[ctl_num - 1].ctl; 172 173 printf("I/O address %p/%p\n", (void *) ctrl->cmd_physical, 174 (void *) ctrl->ctl_physical); 175 176 if (ata_bd_init(ctrl) != EOK) 183 177 return -1; 184 178 … … 187 181 fflush(stdout); 188 182 189 rc = disk_init( &ata_disk[i], i);183 rc = disk_init(ctrl, &ctrl->disk[i], i); 190 184 191 185 if (rc == EOK) { 192 disk_print_summary(& ata_disk[i]);186 disk_print_summary(&ctrl->disk[i]); 193 187 } else { 194 188 printf("Not found.\n"); … … 200 194 for (i = 0; i < MAX_DISKS; i++) { 201 195 /* Skip unattached drives. */ 202 if ( ata_disk[i].present == false)196 if (ctrl->disk[i].present == false) 203 197 continue; 204 198 205 199 snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i); 206 rc = loc_service_register(name, & ata_disk[i].service_id);200 rc = loc_service_register(name, &ctrl->disk[i].service_id); 207 201 if (rc != EOK) { 208 202 printf(NAME ": Unable to register device %s.\n", name); … … 267 261 268 262 /** Register driver and enable device I/O. */ 269 static int ata_bd_init( void)263 static int ata_bd_init(ata_ctrl_t *ctrl) 270 264 { 271 265 async_set_client_connection(ata_bd_connection); … … 277 271 278 272 void *vaddr; 279 rc = pio_enable((void *) c md_physical, sizeof(ata_cmd_t), &vaddr);273 rc = pio_enable((void *) ctrl->cmd_physical, sizeof(ata_cmd_t), &vaddr); 280 274 if (rc != EOK) { 281 275 printf("%s: Could not initialize device I/O space.\n", NAME); … … 283 277 } 284 278 285 c md = vaddr;279 ctrl->cmd = vaddr; 286 280 287 rc = pio_enable((void *) ct l_physical, sizeof(ata_ctl_t), &vaddr);281 rc = pio_enable((void *) ctrl->ctl_physical, sizeof(ata_ctl_t), &vaddr); 288 282 if (rc != EOK) { 289 283 printf("%s: Could not initialize device I/O space.\n", NAME); … … 291 285 } 292 286 293 ct l = vaddr;287 ctrl->ctl = vaddr; 294 288 295 289 return EOK; … … 309 303 disk = NULL; 310 304 for (i = 0; i < MAX_DISKS; i++) 311 if (ata_ disk[i].service_id == dsid)312 disk = &ata_ disk[i];305 if (ata_ctrl.disk[i].service_id == dsid) 306 disk = &ata_ctrl.disk[i]; 313 307 314 308 if (disk == NULL || disk->present == false) { … … 325 319 * the disk structure. 326 320 */ 327 static int disk_init( disk_t *d, int disk_id)321 static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id) 328 322 { 329 323 identify_data_t idata; … … 337 331 unsigned i; 338 332 333 d->ctrl = ctrl; 339 334 d->disk_id = disk_id; 340 335 d->present = false; … … 362 357 * the byte count registers. So, only check these. 363 358 */ 364 bc = ((uint16_t)pio_read_8(&c md->cylinder_high) << 8) |365 pio_read_8(&c md->cylinder_low);359 bc = ((uint16_t)pio_read_8(&ctrl->cmd->cylinder_high) << 8) | 360 pio_read_8(&ctrl->cmd->cylinder_low); 366 361 367 362 if (bc == PDEV_SIGNATURE_BC) { … … 576 571 static int drive_identify(disk_t *disk, void *buf) 577 572 { 573 ata_ctrl_t *ctrl = disk->ctrl; 578 574 uint16_t data; 579 575 uint8_t status; … … 583 579 drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0); 584 580 585 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)581 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 586 582 return ETIMEOUT; 587 583 588 pio_write_8(&c md->drive_head, drv_head);584 pio_write_8(&ctrl->cmd->drive_head, drv_head); 589 585 590 586 /* … … 593 589 * set after issuing the command. 594 590 */ 595 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)591 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 596 592 return ETIMEOUT; 597 593 598 pio_write_8(&c md->command, CMD_IDENTIFY_DRIVE);599 600 if (wait_status( 0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)594 pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_DRIVE); 595 596 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) 601 597 return ETIMEOUT; 602 598 … … 609 605 } 610 606 611 if (wait_status( SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)607 if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) 612 608 return ETIMEOUT; 613 609 … … 615 611 616 612 for (i = 0; i < identify_data_size / 2; i++) { 617 data = pio_read_16(&c md->data_port);613 data = pio_read_16(&ctrl->cmd->data_port); 618 614 ((uint16_t *) buf)[i] = data; 619 615 } … … 632 628 static int identify_pkt_dev(disk_t *disk, void *buf) 633 629 { 630 ata_ctrl_t *ctrl = disk->ctrl; 634 631 uint16_t data; 635 632 uint8_t status; … … 639 636 drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0); 640 637 641 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)642 return EIO; 643 644 pio_write_8(&c md->drive_head, drv_head);638 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 639 return EIO; 640 641 pio_write_8(&ctrl->cmd->drive_head, drv_head); 645 642 646 643 /* For ATAPI commands we do not need to wait for DRDY. */ 647 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)648 return EIO; 649 650 pio_write_8(&c md->command, CMD_IDENTIFY_PKT_DEV);651 652 if (wait_status( 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)644 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 645 return EIO; 646 647 pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_PKT_DEV); 648 649 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) 653 650 return EIO; 654 651 … … 657 654 if ((status & SR_DRQ) != 0) { 658 655 for (i = 0; i < identify_data_size / 2; i++) { 659 data = pio_read_16(&c md->data_port);656 data = pio_read_16(&ctrl->cmd->data_port); 660 657 ((uint16_t *) buf)[i] = data; 661 658 } … … 681 678 void *obuf, size_t obuf_size) 682 679 { 680 ata_ctrl_t *ctrl = disk->ctrl; 683 681 size_t i; 684 682 uint8_t status; … … 693 691 ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0); 694 692 695 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {696 fibril_mutex_unlock(&disk->lock); 697 return EIO; 698 } 699 700 pio_write_8(&c md->drive_head, drv_head);701 702 if (wait_status( 0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {693 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) { 694 fibril_mutex_unlock(&disk->lock); 695 return EIO; 696 } 697 698 pio_write_8(&ctrl->cmd->drive_head, drv_head); 699 700 if (wait_status(ctrl, 0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) { 703 701 fibril_mutex_unlock(&disk->lock); 704 702 return EIO; … … 706 704 707 705 /* Byte count <- max. number of bytes we can read in one transfer. */ 708 pio_write_8(&c md->cylinder_low, 0xfe);709 pio_write_8(&c md->cylinder_high, 0xff);710 711 pio_write_8(&c md->command, CMD_PACKET);712 713 if (wait_status( SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {706 pio_write_8(&ctrl->cmd->cylinder_low, 0xfe); 707 pio_write_8(&ctrl->cmd->cylinder_high, 0xff); 708 709 pio_write_8(&ctrl->cmd->command, CMD_PACKET); 710 711 if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 714 712 fibril_mutex_unlock(&disk->lock); 715 713 return EIO; … … 718 716 /* Write command packet. */ 719 717 for (i = 0; i < (cpkt_size + 1) / 2; i++) 720 pio_write_16(&c md->data_port, ((uint16_t *) cpkt)[i]);721 722 if (wait_status( 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {718 pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) cpkt)[i]); 719 720 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 723 721 fibril_mutex_unlock(&disk->lock); 724 722 return EIO; … … 731 729 732 730 /* Read byte count. */ 733 data_size = (uint16_t) pio_read_8(&c md->cylinder_low) +734 ((uint16_t) pio_read_8(&c md->cylinder_high) << 8);731 data_size = (uint16_t) pio_read_8(&ctrl->cmd->cylinder_low) + 732 ((uint16_t) pio_read_8(&ctrl->cmd->cylinder_high) << 8); 735 733 736 734 /* Check whether data fits into output buffer. */ … … 743 741 /* Read data from the device buffer. */ 744 742 for (i = 0; i < (data_size + 1) / 2; i++) { 745 val = pio_read_16(&c md->data_port);743 val = pio_read_16(&ctrl->cmd->data_port); 746 744 ((uint16_t *) obuf)[i] = val; 747 745 } … … 868 866 void *buf) 869 867 { 868 ata_ctrl_t *ctrl = disk->ctrl; 870 869 size_t i; 871 870 uint16_t data; … … 891 890 /* Program a Read Sectors operation. */ 892 891 893 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {894 fibril_mutex_unlock(&disk->lock); 895 return EIO; 896 } 897 898 pio_write_8(&c md->drive_head, drv_head);899 900 if (wait_status( SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {892 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 893 fibril_mutex_unlock(&disk->lock); 894 return EIO; 895 } 896 897 pio_write_8(&ctrl->cmd->drive_head, drv_head); 898 899 if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 901 900 fibril_mutex_unlock(&disk->lock); 902 901 return EIO; … … 904 903 905 904 /* Program block coordinates into the device. */ 906 coord_sc_program( &bc, 1);907 908 pio_write_8(&c md->command, disk->amode == am_lba48 ?905 coord_sc_program(ctrl, &bc, 1); 906 907 pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ? 909 908 CMD_READ_SECTORS_EXT : CMD_READ_SECTORS); 910 909 911 if (wait_status( 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {910 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 912 911 fibril_mutex_unlock(&disk->lock); 913 912 return EIO; … … 918 917 919 918 for (i = 0; i < disk->block_size / 2; i++) { 920 data = pio_read_16(&c md->data_port);919 data = pio_read_16(&ctrl->cmd->data_port); 921 920 ((uint16_t *) buf)[i] = data; 922 921 } … … 942 941 const void *buf) 943 942 { 943 ata_ctrl_t *ctrl = disk->ctrl; 944 944 size_t i; 945 945 uint8_t status; … … 964 964 /* Program a Write Sectors operation. */ 965 965 966 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {967 fibril_mutex_unlock(&disk->lock); 968 return EIO; 969 } 970 971 pio_write_8(&c md->drive_head, drv_head);972 973 if (wait_status( SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {966 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 967 fibril_mutex_unlock(&disk->lock); 968 return EIO; 969 } 970 971 pio_write_8(&ctrl->cmd->drive_head, drv_head); 972 973 if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 974 974 fibril_mutex_unlock(&disk->lock); 975 975 return EIO; … … 977 977 978 978 /* Program block coordinates into the device. */ 979 coord_sc_program( &bc, 1);980 981 pio_write_8(&c md->command, disk->amode == am_lba48 ?979 coord_sc_program(ctrl, &bc, 1); 980 981 pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ? 982 982 CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS); 983 983 984 if (wait_status( 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {984 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 985 985 fibril_mutex_unlock(&disk->lock); 986 986 return EIO; … … 991 991 992 992 for (i = 0; i < disk->block_size / 2; i++) { 993 pio_write_16(&c md->data_port, ((uint16_t *) buf)[i]);993 pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) buf)[i]); 994 994 } 995 995 } … … 1060 1060 * 1061 1061 * Note that bc->h must be programmed separately into the device/head register. 1062 */ 1063 static void coord_sc_program(const block_coord_t *bc, uint16_t scnt) 1064 { 1062 * 1063 * @param ctrl Controller 1064 * @param bc Block coordinates 1065 * @param scnt Sector count 1066 */ 1067 static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc, 1068 uint16_t scnt) 1069 { 1070 ata_cmd_t *cmd = ctrl->cmd; 1071 1065 1072 if (bc->amode == am_lba48) { 1066 1073 /* Write high-order bits. */ … … 1080 1087 /** Wait until some status bits are set and some are reset. 1081 1088 * 1082 * Example: wait_status( SR_DRDY, ~SR_BSY) waits for SR_DRDY to become1089 * Example: wait_status(ctrl, SR_DRDY, ~SR_BSY, ...) waits for SR_DRDY to become 1083 1090 * set and SR_BSY to become reset. 1084 1091 * 1092 * @param ctrl Controller 1085 1093 * @param set Combination if bits which must be all set. 1086 1094 * @param n_reset Negated combination of bits which must be all reset. … … 1090 1098 * @return EOK on success, EIO on timeout. 1091 1099 */ 1092 static int wait_status( unsigned set, unsigned n_reset, uint8_t *pstatus,1093 u nsigned timeout)1100 static int wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset, 1101 uint8_t *pstatus, unsigned timeout) 1094 1102 { 1095 1103 uint8_t status; 1096 1104 int cnt; 1097 1105 1098 status = pio_read_8(&c md->status);1106 status = pio_read_8(&ctrl->cmd->status); 1099 1107 1100 1108 /* … … 1110 1118 if (cnt <= 0) break; 1111 1119 1112 status = pio_read_8(&c md->status);1120 status = pio_read_8(&ctrl->cmd->status); 1113 1121 } 1114 1122 … … 1119 1127 if (cnt <= 0) break; 1120 1128 1121 status = pio_read_8(&c md->status);1129 status = pio_read_8(&ctrl->cmd->status); 1122 1130 } 1123 1131 -
uspace/srv/bd/ata_bd/ata_bd.h
r7901ac8 r96cbd18 95 95 typedef struct { 96 96 bool present; 97 struct ata_ctrl *ctrl; 97 98 98 99 /** Device type */ … … 122 123 } disk_t; 123 124 125 /** ATA controller */ 126 typedef struct ata_ctrl { 127 /** I/O base address of the command registers */ 128 uintptr_t cmd_physical; 129 /** I/O base address of the control registers */ 130 uintptr_t ctl_physical; 131 132 /** Command registers */ 133 ata_cmd_t *cmd; 134 /** Control registers */ 135 ata_ctl_t *ctl; 136 137 /** Per-disk state. */ 138 disk_t disk[MAX_DISKS]; 139 } ata_ctrl_t; 140 124 141 #endif 125 142
Note:
See TracChangeset
for help on using the changeset viewer.