summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-06-12 13:51:31 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-06-12 13:51:31 +0000
commit8169c8f5bdac59b12ecaf7537e1351a8a94e311e (patch)
tree51f12d09bad227c914277304a211440dad826add
parent558c9247f4597996da866aa3c2e129e2e11b560d (diff)
downloadrockbox-8169c8f5bdac59b12ecaf7537e1351a8a94e311e.tar.gz
rockbox-8169c8f5bdac59b12ecaf7537e1351a8a94e311e.zip
Added I/O address detection for CONTROL/ALT_STATUS
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@976 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/ata.c50
1 files 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 @@
35#define ATA_SELECT (*((volatile unsigned char*)0x06100106)) 35#define ATA_SELECT (*((volatile unsigned char*)0x06100106))
36#define ATA_COMMAND (*((volatile unsigned char*)0x06100107)) 36#define ATA_COMMAND (*((volatile unsigned char*)0x06100107))
37#define ATA_STATUS (*((volatile unsigned char*)0x06100107)) 37#define ATA_STATUS (*((volatile unsigned char*)0x06100107))
38#define ATA_CONTROL (*((volatile unsigned char*)0x06200206)) 38
39#define ATA_CONTROL1 ((volatile unsigned char*)0x06200206)
40#define ATA_CONTROL2 ((volatile unsigned char*)0x06200306)
41
42#define ATA_CONTROL (*ata_control)
39#define ATA_ALT_STATUS ATA_CONTROL 43#define ATA_ALT_STATUS ATA_CONTROL
40 44
41#define SELECT_DEVICE1 0x10 45#define SELECT_DEVICE1 0x10
@@ -59,6 +63,8 @@
59static struct mutex ata_mtx; 63static struct mutex ata_mtx;
60static char device; /* device 0 (master) or 1 (slave) */ 64static char device; /* device 0 (master) or 1 (slave) */
61 65
66static volatile unsigned char* ata_control;
67
62static int wait_for_bsy(void) 68static int wait_for_bsy(void)
63{ 69{
64 int timeout = current_tick + HZ*4; 70 int timeout = current_tick + HZ*4;
@@ -299,7 +305,7 @@ int ata_soft_reset(void)
299 return ret; 305 return ret;
300} 306}
301 307
302static int master_slave(void) 308static int master_slave_detect(void)
303{ 309{
304 /* master? */ 310 /* master? */
305 ATA_SELECT = 0; 311 ATA_SELECT = 0;
@@ -320,6 +326,41 @@ static int master_slave(void)
320 return 0; 326 return 0;
321} 327}
322 328
329static int io_address_detect(void)
330{
331 unsigned char tmp = ATA_STATUS;
332 unsigned char dummy;
333
334 /* We compare the STATUS register with the ALT_STATUS register, which
335 is located at the same address as CONTROL. If they are the same, we
336 assume that we have the correct address.
337
338 We can't read the ATA_STATUS directly, since the read data will stay
339 on the data bus if the following read does not assert the Chip Select
340 to the ATA controller. We read a register that we know exists to make
341 sure that the data on the bus isn't identical to the STATUS register
342 contents. */
343 dummy = ATA_SECTOR;
344 if(tmp == *ATA_CONTROL2)
345 {
346 DEBUGF("CONTROL is at 0x306\n");
347 ata_control = ATA_CONTROL2;
348 }
349 else
350 {
351 DEBUGF("CONTROL is at 0x206\n");
352 ata_control = ATA_CONTROL1;
353 }
354
355 /* Let's check again, to be sure */
356 if(tmp != ATA_CONTROL)
357 {
358 DEBUGF("ATA I/O address detection failed\n");
359 return -1;
360 }
361 return 0;
362}
363
323int ata_init(void) 364int ata_init(void)
324{ 365{
325 mutex_init(&ata_mtx); 366 mutex_init(&ata_mtx);
@@ -329,9 +370,12 @@ int ata_init(void)
329 PADR |= 0x800; /* disable USB */ 370 PADR |= 0x800; /* disable USB */
330 PADR &= ~0x80; /* activate ATA */ 371 PADR &= ~0x80; /* activate ATA */
331 372
332 if (master_slave()) 373 if (master_slave_detect())
333 return -1; 374 return -1;
334 375
376 if (io_address_detect())
377 return -2;
378
335 if (check_registers()) 379 if (check_registers())
336 return -3; 380 return -3;
337 381