From 8169c8f5bdac59b12ecaf7537e1351a8a94e311e Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Wed, 12 Jun 2002 13:51:31 +0000 Subject: Added I/O address detection for CONTROL/ALT_STATUS git-svn-id: svn://svn.rockbox.org/rockbox/trunk@976 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/ata.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 7f4cb270f8..477369bea1 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c @@ -35,7 +35,11 @@ #define ATA_SELECT (*((volatile unsigned char*)0x06100106)) #define ATA_COMMAND (*((volatile unsigned char*)0x06100107)) #define ATA_STATUS (*((volatile unsigned char*)0x06100107)) -#define ATA_CONTROL (*((volatile unsigned char*)0x06200206)) + +#define ATA_CONTROL1 ((volatile unsigned char*)0x06200206) +#define ATA_CONTROL2 ((volatile unsigned char*)0x06200306) + +#define ATA_CONTROL (*ata_control) #define ATA_ALT_STATUS ATA_CONTROL #define SELECT_DEVICE1 0x10 @@ -59,6 +63,8 @@ static struct mutex ata_mtx; static char device; /* device 0 (master) or 1 (slave) */ +static volatile unsigned char* ata_control; + static int wait_for_bsy(void) { int timeout = current_tick + HZ*4; @@ -299,7 +305,7 @@ int ata_soft_reset(void) return ret; } -static int master_slave(void) +static int master_slave_detect(void) { /* master? */ ATA_SELECT = 0; @@ -320,6 +326,41 @@ static int master_slave(void) return 0; } +static int io_address_detect(void) +{ + unsigned char tmp = ATA_STATUS; + unsigned char dummy; + + /* We compare the STATUS register with the ALT_STATUS register, which + is located at the same address as CONTROL. If they are the same, we + assume that we have the correct address. + + We can't read the ATA_STATUS directly, since the read data will stay + on the data bus if the following read does not assert the Chip Select + to the ATA controller. We read a register that we know exists to make + sure that the data on the bus isn't identical to the STATUS register + contents. */ + dummy = ATA_SECTOR; + if(tmp == *ATA_CONTROL2) + { + DEBUGF("CONTROL is at 0x306\n"); + ata_control = ATA_CONTROL2; + } + else + { + DEBUGF("CONTROL is at 0x206\n"); + ata_control = ATA_CONTROL1; + } + + /* Let's check again, to be sure */ + if(tmp != ATA_CONTROL) + { + DEBUGF("ATA I/O address detection failed\n"); + return -1; + } + return 0; +} + int ata_init(void) { mutex_init(&ata_mtx); @@ -329,9 +370,12 @@ int ata_init(void) PADR |= 0x800; /* disable USB */ PADR &= ~0x80; /* activate ATA */ - if (master_slave()) + if (master_slave_detect()) return -1; + if (io_address_detect()) + return -2; + if (check_registers()) return -3; -- cgit v1.2.3