diff options
author | Jonas Wielicki <j.wielicki@sotecware.net> | 2012-04-17 18:35:50 +0200 |
---|---|---|
committer | Marcin Bukat <marcin.bukat@gmail.com> | 2012-05-19 19:15:04 +0200 |
commit | 028c5e35eee43efc3c922ffc0db067fc61cf27cb (patch) | |
tree | adfa75e0a26a5a5b898a72b08d0f4786e2aaf670 /firmware | |
parent | f3fd2d41ccbd36226ed12e3977421f86cbcfad97 (diff) | |
download | rockbox-028c5e35eee43efc3c922ffc0db067fc61cf27cb.tar.gz rockbox-028c5e35eee43efc3c922ffc0db067fc61cf27cb.zip |
Add identify() call to reset procedures
This change is motivated by the ATA specs, section 9.2 Software reset protocol
(quote):
A host should issue an IDENTIFY DEVICE and/or IDENTIFY PACKET DEVICE
command after the software reset protocol has completed to determine the
current status of features implemented by the device(s).
This indeed fixes a local issue with an SSD in an iriver h320. No other tests
were carried out.
Change-Id: I191444aec3e55f6890020f601c715d0022d09fb6
Reviewed-on: http://gerrit.rockbox.org/218
Reviewed-by: Bertrik Sikken <bertrik@sikken.nl>
Reviewed-by: Linus Nielsen Feltzing <linus@haxx.se>
Reviewed-by: Peter D'Hoye <peter.dhoye@gmail.com>
Tested-by: Peter D'Hoye <peter.dhoye@gmail.com>
Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/ata.c | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 8dfc8d965d..ec04ac1426 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -1016,6 +1016,35 @@ static int STORAGE_INIT_ATTR ata_hard_reset(void) | |||
1016 | return ret; | 1016 | return ret; |
1017 | } | 1017 | } |
1018 | 1018 | ||
1019 | // not putting this into STORAGE_INIT_ATTR, as ATA spec recommends to | ||
1020 | // re-read identify_info after soft reset. So we'll do that. | ||
1021 | static int identify(void) | ||
1022 | { | ||
1023 | int i; | ||
1024 | |||
1025 | ATA_OUT8(ATA_SELECT, ata_device); | ||
1026 | |||
1027 | if(!wait_for_rdy()) { | ||
1028 | DEBUGF("identify() - not RDY\n"); | ||
1029 | return -1; | ||
1030 | } | ||
1031 | ATA_OUT8(ATA_COMMAND, CMD_IDENTIFY); | ||
1032 | |||
1033 | if (!wait_for_start_of_transfer()) | ||
1034 | { | ||
1035 | DEBUGF("identify() - CMD failed\n"); | ||
1036 | return -2; | ||
1037 | } | ||
1038 | |||
1039 | for (i=0; i<SECTOR_SIZE/2; i++) { | ||
1040 | /* the IDENTIFY words are already swapped, so we need to treat | ||
1041 | this info differently that normal sector data */ | ||
1042 | identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA)); | ||
1043 | } | ||
1044 | |||
1045 | return 0; | ||
1046 | } | ||
1047 | |||
1019 | static int perform_soft_reset(void) | 1048 | static int perform_soft_reset(void) |
1020 | { | 1049 | { |
1021 | /* If this code is allowed to run on a Nano, the next reads from the flash will | 1050 | /* If this code is allowed to run on a Nano, the next reads from the flash will |
@@ -1048,6 +1077,9 @@ static int perform_soft_reset(void) | |||
1048 | if (!ret) | 1077 | if (!ret) |
1049 | return -1; | 1078 | return -1; |
1050 | 1079 | ||
1080 | if (identify()) | ||
1081 | return -5; | ||
1082 | |||
1051 | if (set_features()) | 1083 | if (set_features()) |
1052 | return -2; | 1084 | return -2; |
1053 | 1085 | ||
@@ -1090,6 +1122,9 @@ static int ata_power_on(void) | |||
1090 | if( ata_hard_reset() ) | 1122 | if( ata_hard_reset() ) |
1091 | return -1; | 1123 | return -1; |
1092 | 1124 | ||
1125 | if (identify()) | ||
1126 | return -5; | ||
1127 | |||
1093 | rc = set_features(); | 1128 | rc = set_features(); |
1094 | if (rc) | 1129 | if (rc) |
1095 | return rc * 10 - 2; | 1130 | return rc * 10 - 2; |
@@ -1125,33 +1160,6 @@ static int STORAGE_INIT_ATTR master_slave_detect(void) | |||
1125 | return 0; | 1160 | return 0; |
1126 | } | 1161 | } |
1127 | 1162 | ||
1128 | static int STORAGE_INIT_ATTR identify(void) | ||
1129 | { | ||
1130 | int i; | ||
1131 | |||
1132 | ATA_OUT8(ATA_SELECT, ata_device); | ||
1133 | |||
1134 | if(!wait_for_rdy()) { | ||
1135 | DEBUGF("identify() - not RDY\n"); | ||
1136 | return -1; | ||
1137 | } | ||
1138 | ATA_OUT8(ATA_COMMAND, CMD_IDENTIFY); | ||
1139 | |||
1140 | if (!wait_for_start_of_transfer()) | ||
1141 | { | ||
1142 | DEBUGF("identify() - CMD failed\n"); | ||
1143 | return -2; | ||
1144 | } | ||
1145 | |||
1146 | for (i=0; i<SECTOR_SIZE/2; i++) { | ||
1147 | /* the IDENTIFY words are already swapped, so we need to treat | ||
1148 | this info differently that normal sector data */ | ||
1149 | identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA)); | ||
1150 | } | ||
1151 | |||
1152 | return 0; | ||
1153 | } | ||
1154 | |||
1155 | static int set_multiple_mode(int sectors) | 1163 | static int set_multiple_mode(int sectors) |
1156 | { | 1164 | { |
1157 | ATA_OUT8(ATA_SELECT, ata_device); | 1165 | ATA_OUT8(ATA_SELECT, ata_device); |