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/drivers | |
| parent | f3fd2d41ccbd36226ed12e3977421f86cbcfad97 (diff) | |
| download | rockbox-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.c | 62 |
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); |