| Index: emcore/trunk/target/ipodclassic/storage_ata.c | 
| — | — | @@ -68,9 +68,10 @@ | 
| 69 | 69 | uint32_t ata_last_offset; | 
| 70 | 70 | uint64_t ata_last_phys; | 
| 71 | 71 |  | 
|  | 72 | +static uint16_t ata_read_cbr(uint32_t volatile* reg); | 
| 72 | 73 | int ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer) | 
| 73 | 74 | { | 
| 74 |  | -    if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_soft_reset(); | 
|  | 75 | +    if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_reset(); | 
| 75 | 76 | int rc = ata_rw_sectors_internal(sector, count, buffer, false); | 
| 76 | 77 | if (rc) rc = ata_rw_sectors_internal(sector, count, buffer, false); | 
| 77 | 78 | ata_last_phys = sector + count - 1; | 
| — | — | @@ -89,7 +90,7 @@ | 
| 90 | 91 | #ifdef ATA_HAVE_BBT | 
| 91 | 92 | .bbt_translate = ata_bbt_translate, | 
| 92 | 93 | .bbt_reload = ata_bbt_reload, | 
| 93 |  | -    .bbt_disable = ata_bbt_disable | 
|  | 94 | +    .bbt_disable = ata_bbt_disable, | 
| 94 | 95 | #endif | 
| 95 | 96 | }; | 
| 96 | 97 |  | 
| — | — | @@ -107,7 +108,7 @@ | 
| 108 | 109 | static uint16_t ata_read_cbr(uint32_t volatile* reg) | 
| 109 | 110 | { | 
| 110 | 111 | while (!(ATA_PIO_READY & 2)) yield(); | 
| 111 |  | -    volatile uint32_t dummy = *reg; | 
|  | 112 | +    uint32_t dummy = *reg; | 
| 112 | 113 | while (!(ATA_PIO_READY & 1)) yield(); | 
| 113 | 114 | return ATA_PIO_RDATA; | 
| 114 | 115 | } | 
| — | — | @@ -492,20 +493,20 @@ | 
| 493 | 494 | | SDCI_CMD_CMD_TYPE_ADTC | cmdtype | responsetype | 
| 494 | 495 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, | 
| 495 | 496 | direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count), | 
| 496 |  | -                             NULL, CEATA_COMMAND_TIMEOUT), 4, 0); | 
|  | 497 | +                             NULL, CEATA_COMMAND_TIMEOUT), 3, 0); | 
| 497 | 498 | if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; | 
| 498 | 499 | if (wakeup_wait(&mmc_wakeup, timeout) == THREAD_TIMEOUT) | 
| 499 | 500 | { | 
| 500 |  | -        PASS_RC(ceata_cancel_command(), 4, 1); | 
|  | 501 | +        PASS_RC(ceata_cancel_command(), 3, 1); | 
| 501 | 502 | RET_ERR(2); | 
| 502 | 503 | } | 
| 503 |  | -    PASS_RC(mmc_dsta_check_data_success(), 4, 3); | 
|  | 504 | +    PASS_RC(mmc_dsta_check_data_success(), 3, 3); | 
| 504 | 505 | if (wakeup_wait(&mmc_comp_wakeup, timeout) == THREAD_TIMEOUT) | 
| 505 | 506 | { | 
| 506 |  | -        PASS_RC(ceata_cancel_command(), 4, 4); | 
| 507 |  | -        RET_ERR(4); | 
|  | 507 | +        PASS_RC(ceata_cancel_command(), 3, 4); | 
|  | 508 | +        RET_ERR(5); | 
| 508 | 509 | } | 
| 509 |  | -    PASS_RC(ceata_check_error(), 4, 5); | 
|  | 510 | +    PASS_RC(ceata_check_error(), 3, 6); | 
| 510 | 511 | return 0; | 
| 511 | 512 | } | 
| 512 | 513 |  | 
| — | — | @@ -543,12 +544,25 @@ | 
| 544 | 545 |  | 
| 545 | 546 | int ata_set_feature(uint32_t feature, uint32_t param) | 
| 546 | 547 | { | 
| 547 |  | -    PASS_RC(ata_wait_for_rdy(500000), 1, 0); | 
| 548 |  | -    ata_write_cbr(&ATA_PIO_DVR, 0); | 
| 549 |  | -    ata_write_cbr(&ATA_PIO_FED, 3); | 
| 550 |  | -    ata_write_cbr(&ATA_PIO_SCR, param); | 
| 551 |  | -    ata_write_cbr(&ATA_PIO_CSD, feature); | 
| 552 |  | -    PASS_RC(ata_wait_for_rdy(500000), 1, 1); | 
|  | 548 | +    if (ceata) | 
|  | 549 | +    { | 
|  | 550 | +        memset(ceata_taskfile, 0, 16); | 
|  | 551 | +        ceata_taskfile[0x1] = feature; | 
|  | 552 | +        ceata_taskfile[0x2] = param; | 
|  | 553 | +        ceata_taskfile[0xf] = 0xef; | 
|  | 554 | +        PASS_RC(ceata_wait_idle(), 2, 0); | 
|  | 555 | +        PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); | 
|  | 556 | +        PASS_RC(ceata_wait_idle(), 2, 2); | 
|  | 557 | +    } | 
|  | 558 | +    else | 
|  | 559 | +    { | 
|  | 560 | +        PASS_RC(ata_wait_for_rdy(2000000), 2, 0); | 
|  | 561 | +        ata_write_cbr(&ATA_PIO_DVR, 0); | 
|  | 562 | +        ata_write_cbr(&ATA_PIO_FED, feature); | 
|  | 563 | +        ata_write_cbr(&ATA_PIO_SCR, param); | 
|  | 564 | +        ata_write_cbr(&ATA_PIO_CSD, 0xef); | 
|  | 565 | +        PASS_RC(ata_wait_for_rdy(2000000), 2, 1); | 
|  | 566 | +    } | 
| 553 | 567 | return 0; | 
| 554 | 568 | } | 
| 555 | 569 |  | 
| — | — | @@ -555,10 +569,16 @@ | 
| 556 | 570 | int ata_power_up() | 
| 557 | 571 | { | 
| 558 | 572 | ata_set_active(); | 
| 559 |  | -    if (ata_powered) return 0; | 
| 560 | 573 | i2c_sendbyte(0, 0xe6, 0x1b, 1); | 
| 561 | 574 | if (ceata) | 
| 562 | 575 | { | 
|  | 576 | +        ata_lba48 = true; | 
|  | 577 | +        ata_dma = true; | 
|  | 578 | +        PCON(8) = 0x33333333; | 
|  | 579 | +        PCON(9) = 0x00000033; | 
|  | 580 | +        PCON(11) |= 0xf; | 
|  | 581 | +        *((uint32_t volatile*)0x38a00000) = 0; | 
|  | 582 | +        *((uint32_t volatile*)0x38700000) = 0; | 
| 563 | 583 | clockgate_enable(9, true); | 
| 564 | 584 | SDCI_RESET = 0xa5; | 
| 565 | 585 | sleep(1000); | 
| — | — | @@ -569,18 +589,21 @@ | 
| 570 | 590 | SDCI_CDIV = SDCI_CDIV_CLKDIV(260); | 
| 571 | 591 | *((uint32_t volatile*)0x3cf00200) = 0xb000f; | 
| 572 | 592 | SDCI_IRQ_MASK = SDCI_IRQ_MASK_MASK_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT; | 
| 573 |  | -        PASS_RC(mmc_init(), 2, 0); | 
|  | 593 | +        PASS_RC(mmc_init(), 3, 0); | 
| 574 | 594 | SDCI_CDIV = SDCI_CDIV_CLKDIV(4); | 
| 575 | 595 | sleep(10000); | 
| 576 |  | -        PASS_RC(ceata_init(8), 2, 1); | 
| 577 |  | -        PASS_RC(ata_identify(ata_identify_data), 2, 2); | 
|  | 596 | +        PASS_RC(ceata_init(8), 3, 1); | 
|  | 597 | +        PASS_RC(ata_identify(ata_identify_data), 3, 2); | 
| 578 | 598 | } | 
| 579 | 599 | else | 
| 580 | 600 | { | 
| 581 |  | -        sleep(1000); | 
|  | 601 | +        PCON(7) = 0x44444444; | 
|  | 602 | +        PCON(8) = 0x44444444; | 
|  | 603 | +        PCON(9) = 0x44444444; | 
|  | 604 | +        PCON(10) = (PCON(10) & ~0xffff) | 0x4444; | 
| 582 | 605 | clockgate_enable(5, true); | 
| 583 | 606 | ATA_CFG = BIT(0); | 
| 584 |  | -        sleep(1000); | 
|  | 607 | +        sleep(10000); | 
| 585 | 608 | ATA_CFG = 0; | 
| 586 | 609 | sleep(6000); | 
| 587 | 610 | ATA_SWRST = BIT(0); | 
| — | — | @@ -593,7 +616,7 @@ | 
| 594 | 617 | ATA_PIO_LHR = 0; | 
| 595 | 618 | ATA_CFG = BIT(6); | 
| 596 | 619 | while (!(ATA_PIO_READY & BIT(1))) sleep(100); | 
| 597 |  | -        PASS_RC(ata_identify(ata_identify_data), 2, 0); | 
|  | 620 | +        PASS_RC(ata_identify(ata_identify_data), 3, 3); | 
| 598 | 621 | uint32_t piotime = 0x11f3; | 
| 599 | 622 | uint32_t mdmatime = 0x1c175; | 
| 600 | 623 | uint32_t udmatime = 0x5071152; | 
| — | — | @@ -649,13 +672,14 @@ | 
| 650 | 673 | } | 
| 651 | 674 | } | 
| 652 | 675 | ata_dma = param ? true : false; | 
| 653 |  | -        PASS_RC(ata_set_feature(0xef, param), 2, 1); | 
| 654 |  | -        if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2); | 
| 655 |  | -        if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3); | 
|  | 676 | +        PASS_RC(ata_set_feature(0x03, param), 3, 4); | 
| 656 | 677 | ATA_PIO_TIME = piotime; | 
| 657 | 678 | ATA_MDMA_TIME = mdmatime; | 
| 658 | 679 | ATA_UDMA_TIME = udmatime; | 
| 659 | 680 | } | 
|  | 681 | +    if (ata_identify_data[82] & BIT(5)) | 
|  | 682 | +        PASS_RC(ata_set_feature(ata_bbt ? 0x82 : 0x02, 0), 3, 5); | 
|  | 683 | +    if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0xaa, 0), 3, 6); | 
| 660 | 684 | if (ata_lba48) | 
| 661 | 685 | ata_total_sectors = ata_identify_data[100] | 
| 662 | 686 | | (((uint64_t)ata_identify_data[101]) << 16) | 
| — | — | @@ -678,7 +702,8 @@ | 
| 679 | 703 | ceata_taskfile[0xf] = 0xe0; | 
| 680 | 704 | ceata_wait_idle(); | 
| 681 | 705 | ceata_write_multiple_register(0, ceata_taskfile, 16); | 
| 682 |  | -        sleep(1000000); | 
|  | 706 | +        ceata_wait_idle(); | 
|  | 707 | +        sleep(100000); | 
| 683 | 708 | clockgate_enable(9, false); | 
| 684 | 709 | } | 
| 685 | 710 | else | 
| — | — | @@ -692,6 +717,11 @@ | 
| 693 | 718 | while (!(ATA_CONTROL & BIT(1))) yield(); | 
| 694 | 719 | clockgate_enable(5, false); | 
| 695 | 720 | } | 
|  | 721 | +    PCON(7) = 0; | 
|  | 722 | +    PCON(8) = 0; | 
|  | 723 | +    PCON(9) = 0; | 
|  | 724 | +    PCON(10) &= ~0xffff; | 
|  | 725 | +    PCON(11) &= ~0xf; | 
| 696 | 726 | i2c_sendbyte(0, 0xe6, 0x1b, 0); | 
| 697 | 727 | } | 
| 698 | 728 |  | 
| — | — | @@ -863,7 +893,7 @@ | 
| 864 | 894 | uint32_t cnt; | 
| 865 | 895 | PASS_RC(ata_bbt_translate(sector, count, &phys, &cnt), 0, 0); | 
| 866 | 896 | uint32_t offset = phys - sector; | 
| 867 |  | -            if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset(); | 
|  | 897 | +            if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_reset(); | 
| 868 | 898 | ata_last_offset = offset; | 
| 869 | 899 | ata_last_phys = phys + cnt; | 
| 870 | 900 | PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0); | 
| — | — | @@ -889,7 +919,7 @@ | 
| 890 | 920 | uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count); | 
| 891 | 921 | int rc = -1; | 
| 892 | 922 | rc = ata_rw_chunk(sector, cnt, buffer, write); | 
| 893 |  | -        if (rc && ata_error_srst) ata_soft_reset(); | 
|  | 923 | +        if (rc && ata_error_srst) ata_reset(); | 
| 894 | 924 | if (rc && ata_retries) | 
| 895 | 925 | { | 
| 896 | 926 | void* buf = buffer; | 
| — | — | @@ -901,7 +931,7 @@ | 
| 902 | 932 | while (tries-- && rc) | 
| 903 | 933 | { | 
| 904 | 934 | rc = ata_rw_chunk(sect, 1, buf, write); | 
| 905 |  | -                    if (rc && ata_error_srst) ata_soft_reset(); | 
|  | 935 | +                    if (rc && ata_error_srst) ata_reset(); | 
| 906 | 936 | } | 
| 907 | 937 | if (rc) break; | 
| 908 | 938 | buf += SECTOR_SIZE; | 
| — | — | @@ -941,17 +971,46 @@ | 
| 942 | 972 | ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2)); | 
| 943 | 973 | sleep(10); | 
| 944 | 974 | ata_write_cbr(&ATA_PIO_DAD, 0); | 
| 945 |  | -        rc = ata_wait_for_rdy(20000000); | 
|  | 975 | +        rc = ata_wait_for_rdy(3000000); | 
| 946 | 976 | } | 
|  | 977 | +    ata_set_active(); | 
|  | 978 | +    mutex_unlock(&ata_mutex); | 
|  | 979 | +    PASS_RC(rc, 1, 1); | 
|  | 980 | +    return 0; | 
|  | 981 | +} | 
|  | 982 | + | 
|  | 983 | +int ata_hard_reset() | 
|  | 984 | +{ | 
|  | 985 | +    mutex_lock(&ata_mutex, TIMEOUT_BLOCK); | 
|  | 986 | +    PASS_RC(ata_power_up(), 0, 0); | 
|  | 987 | +    ata_set_active(); | 
|  | 988 | +    mutex_unlock(&ata_mutex); | 
|  | 989 | +    return 0; | 
|  | 990 | +} | 
|  | 991 | + | 
|  | 992 | +int ata_reset() | 
|  | 993 | +{ | 
|  | 994 | +    int rc; | 
|  | 995 | +    mutex_lock(&ata_mutex, TIMEOUT_BLOCK); | 
|  | 996 | +    if (!ata_powered) PASS_RC(ata_power_up(), 2, 0); | 
|  | 997 | +    ata_set_active(); | 
|  | 998 | +    rc = ata_soft_reset(); | 
| 947 | 999 | if (IS_ERR(rc)) | 
| 948 | 1000 | { | 
| 949 |  | -        ata_power_down(); | 
| 950 |  | -        sleep(3000000); | 
| 951 |  | -        ata_power_up(); | 
|  | 1001 | +        rc = ata_hard_reset(); | 
|  | 1002 | +        if (IS_ERR(rc)) | 
|  | 1003 | +        { | 
|  | 1004 | +            rc = ERR_RC((rc << 2) | 1); | 
|  | 1005 | +            ata_power_down(); | 
|  | 1006 | +            sleep(3000000); | 
|  | 1007 | +            int rc2 = ata_power_up(); | 
|  | 1008 | +            if (IS_ERR(rc2)) rc = ERR_RC((rc << 2) | 2); | 
|  | 1009 | +        } | 
|  | 1010 | +        else rc = 1; | 
| 952 | 1011 | } | 
| 953 | 1012 | ata_set_active(); | 
| 954 | 1013 | mutex_unlock(&ata_mutex); | 
| 955 |  | -    PASS_RC(rc, 1, 1); | 
|  | 1014 | +    return rc; | 
| 956 | 1015 | } | 
| 957 | 1016 |  | 
| 958 | 1017 | int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount, | 
| — | — | @@ -1032,7 +1091,7 @@ | 
| 1033 | 1092 | { | 
| 1034 | 1093 | mutex_lock(&ata_mutex, TIMEOUT_BLOCK); | 
| 1035 | 1094 | ata_bbt_disable(); | 
| 1036 |  | -    PASS_RC(ata_power_up(), 0, 0); | 
|  | 1095 | +    PASS_RC(ata_power_up(), 1, 0); | 
| 1037 | 1096 | uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000); | 
| 1038 | 1097 | if (buf) | 
| 1039 | 1098 | { | 
| — | — | @@ -1040,6 +1099,7 @@ | 
| 1041 | 1100 | ata_virtual_sectors = ata_total_sectors; | 
| 1042 | 1101 | else if (!memcmp(buf, "emBIbbth", 8)) | 
| 1043 | 1102 | { | 
|  | 1103 | +            if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 1, 1); | 
| 1044 | 1104 | ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc]; | 
| 1045 | 1105 | uint32_t count = buf[0x1ff]; | 
| 1046 | 1106 | ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count); | 
| — | — | @@ -1074,6 +1134,7 @@ | 
| 1075 | 1135 | } | 
| 1076 | 1136 | else ata_virtual_sectors = ata_total_sectors; | 
| 1077 | 1137 | mutex_unlock(&ata_mutex); | 
|  | 1138 | +    return 0; | 
| 1078 | 1139 | } | 
| 1079 | 1140 | #endif | 
| 1080 | 1141 |  | 
| — | — | @@ -1084,23 +1145,6 @@ | 
| 1085 | 1146 | wakeup_init(&mmc_wakeup); | 
| 1086 | 1147 | wakeup_init(&mmc_comp_wakeup); | 
| 1087 | 1148 | ceata = PDAT(11) & BIT(1); | 
| 1088 |  | -    if (ceata) | 
| 1089 |  | -    { | 
| 1090 |  | -        ata_lba48 = true; | 
| 1091 |  | -        ata_dma = true; | 
| 1092 |  | -        PCON(8) = 0x33333333; | 
| 1093 |  | -        PCON(9) = (PCON(9) & ~0xff) | 0x33; | 
| 1094 |  | -        PCON(11) |= 0xf; | 
| 1095 |  | -        *((uint32_t volatile*)0x38a00000) = 0; | 
| 1096 |  | -        *((uint32_t volatile*)0x38700000) = 0; | 
| 1097 |  | -    } | 
| 1098 |  | -    else | 
| 1099 |  | -    { | 
| 1100 |  | -        PCON(7) = 0x44444444; | 
| 1101 |  | -        PCON(8) = 0x44444444; | 
| 1102 |  | -        PCON(9) = 0x44444444; | 
| 1103 |  | -        PCON(10) = (PCON(10) & ~0xffff) | 0x4444; | 
| 1104 |  | -    } | 
| 1105 | 1149 | ata_powered = false; | 
| 1106 | 1150 | ata_total_sectors = 0; | 
| 1107 | 1151 | #ifdef ATA_HAVE_BBT | 
| Index: emcore/trunk/storage.c | 
| — | — | @@ -334,7 +334,7 @@ | 
| 335 | 335 | int rc=0; | 
| 336 | 336 |  | 
| 337 | 337 | #if (CONFIG_STORAGE & STORAGE_ATA) | 
| 338 |  | -    if ((rc=ata_soft_reset())) return rc; | 
|  | 338 | +    if ((rc=ata_reset())) return rc; | 
| 339 | 339 | #endif | 
| 340 | 340 |  | 
| 341 | 341 | #if (CONFIG_STORAGE & STORAGE_MMC) |