summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
authorJonas Wielicki <j.wielicki@sotecware.net>2012-04-17 18:35:50 +0200
committerMarcin Bukat <marcin.bukat@gmail.com>2012-05-19 19:15:04 +0200
commit028c5e35eee43efc3c922ffc0db067fc61cf27cb (patch)
treeadfa75e0a26a5a5b898a72b08d0f4786e2aaf670 /firmware/drivers
parentf3fd2d41ccbd36226ed12e3977421f86cbcfad97 (diff)
downloadrockbox-028c5e35eee43efc3c922ffc0db067fc61cf27cb.zip
rockbox-028c5e35eee43efc3c922ffc0db067fc61cf27cb.tar.gz
rockbox-028c5e35eee43efc3c922ffc0db067fc61cf27cb.tar.bz2
rockbox-028c5e35eee43efc3c922ffc0db067fc61cf27cb.tar.xz
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/drivers')
-rw-r--r--firmware/drivers/ata.c62
1 files changed, 35 insertions, 27 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 8dfc8d9..ec04ac1 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -1016,6 +1016,35 @@ static int STORAGE_INIT_ATTR ata_hard_reset(void)
return ret;
}
+// not putting this into STORAGE_INIT_ATTR, as ATA spec recommends to
+// re-read identify_info after soft reset. So we'll do that.
+static int identify(void)
+{
+ int i;
+
+ ATA_OUT8(ATA_SELECT, ata_device);
+
+ if(!wait_for_rdy()) {
+ DEBUGF("identify() - not RDY\n");
+ return -1;
+ }
+ ATA_OUT8(ATA_COMMAND, CMD_IDENTIFY);
+
+ if (!wait_for_start_of_transfer())
+ {
+ DEBUGF("identify() - CMD failed\n");
+ return -2;
+ }
+
+ for (i=0; i<SECTOR_SIZE/2; i++) {
+ /* the IDENTIFY words are already swapped, so we need to treat
+ this info differently that normal sector data */
+ identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA));
+ }
+
+ return 0;
+}
+
static int perform_soft_reset(void)
{
/* 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)
if (!ret)
return -1;
+ if (identify())
+ return -5;
+
if (set_features())
return -2;
@@ -1090,6 +1122,9 @@ static int ata_power_on(void)
if( ata_hard_reset() )
return -1;
+ if (identify())
+ return -5;
+
rc = set_features();
if (rc)
return rc * 10 - 2;
@@ -1125,33 +1160,6 @@ static int STORAGE_INIT_ATTR master_slave_detect(void)
return 0;
}
-static int STORAGE_INIT_ATTR identify(void)
-{
- int i;
-
- ATA_OUT8(ATA_SELECT, ata_device);
-
- if(!wait_for_rdy()) {
- DEBUGF("identify() - not RDY\n");
- return -1;
- }
- ATA_OUT8(ATA_COMMAND, CMD_IDENTIFY);
-
- if (!wait_for_start_of_transfer())
- {
- DEBUGF("identify() - CMD failed\n");
- return -2;
- }
-
- for (i=0; i<SECTOR_SIZE/2; i++) {
- /* the IDENTIFY words are already swapped, so we need to treat
- this info differently that normal sector data */
- identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA));
- }
-
- return 0;
-}
-
static int set_multiple_mode(int sectors)
{
ATA_OUT8(ATA_SELECT, ata_device);