summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2004-11-23 22:00:41 +0000
committerJens Arnold <amiconn@rockbox.org>2004-11-23 22:00:41 +0000
commitf05dec570289ef9ebd84deaba1e08d960eadabf9 (patch)
tree8708389529dfe077481c14192ef53fbf63110792 /firmware
parent8737b37ce7e59d34682bb6484b8f3cf7e86ced06 (diff)
downloadrockbox-f05dec570289ef9ebd84deaba1e08d960eadabf9.tar.gz
rockbox-f05dec570289ef9ebd84deaba1e08d960eadabf9.tar.bz2
rockbox-f05dec570289ef9ebd84deaba1e08d960eadabf9.zip
Retry initializing the harddisk with hard reset in case the first try fails. Fixes panic when starting flashed rockbox by leaving the archos charging screen with On.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5461 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/ata.c69
1 files changed, 40 insertions, 29 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 60b6a87488..9a0476f5cc 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -977,7 +977,7 @@ static int master_slave_detect(void)
}
#if CONFIG_CPU == SH7034 /* special archos quirk */
-static int io_address_detect(void)
+static void io_address_detect(void)
{ /* now, use the HW mask instead of probing */
if (read_hw_mask() & ATA_ADDRESS_200)
{
@@ -991,8 +991,6 @@ static int io_address_detect(void)
old_recorder = true;
ata_control = ATA_CONTROL2;
}
-
- return 0;
}
#endif
@@ -1117,10 +1115,37 @@ unsigned short* ata_get_identify(void)
return identify_info;
}
+static int init_and_check(bool hard_reset)
+{
+ int rc;
+
+ if (hard_reset)
+ {
+ /* This should reset both master and slave, we don't yet know what's in */
+ ata_device = 0;
+ if (ata_hard_reset())
+ return -1;
+ }
+
+ rc = master_slave_detect();
+ if (rc)
+ return -10 + rc;
+
+ /* symptom fix: else check_registers() below may fail */
+ if (hard_reset && !wait_for_bsy())
+ return -20;
+
+ rc = check_registers();
+ if (rc)
+ return -30 + rc;
+
+ return 0;
+}
+
int ata_init(void)
{
int rc;
- bool coldstart = (PACR2 & 0x4000) != 0;
+ bool coldstart = (PACR2 & 0x4000) != 0;
mutex_init(&ata_mtx);
@@ -1144,34 +1169,20 @@ int ata_init(void)
sleep(HZ); /* allow voltage to build up */
}
- if (coldstart)
- {
- /* This should reset both master and slave, we don't yet know what's in */
- ata_device = 0;
- if (ata_hard_reset())
- return -1;
- }
-
- rc = master_slave_detect();
- if (rc)
- return -10 + rc;
-
#if CONFIG_CPU == SH7034
- rc = io_address_detect();
- if (rc)
- return -20 + rc;
-#endif
-
- /* symptom fix: else check_registers() below may fail */
- if (coldstart && !wait_for_bsy())
- {
- return -29;
+ io_address_detect();
+#endif
+ /* first try, hard reset at cold start only */
+ rc = init_and_check(coldstart);
+
+ if (rc)
+ { /* failed? -> second try, always with hard reset */
+ DEBUGF("ata: init failed, retrying...\n");
+ rc = init_and_check(true);
+ if (rc)
+ return rc;
}
- rc = check_registers();
- if (rc)
- return -30 + rc;
-
rc = identify();
if (rc)
return -40 + rc;