diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2002-06-12 13:51:31 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2002-06-12 13:51:31 +0000 |
commit | 8169c8f5bdac59b12ecaf7537e1351a8a94e311e (patch) | |
tree | 51f12d09bad227c914277304a211440dad826add | |
parent | 558c9247f4597996da866aa3c2e129e2e11b560d (diff) | |
download | rockbox-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.c | 50 |
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 @@ | |||
59 | static struct mutex ata_mtx; | 63 | static struct mutex ata_mtx; |
60 | static char device; /* device 0 (master) or 1 (slave) */ | 64 | static char device; /* device 0 (master) or 1 (slave) */ |
61 | 65 | ||
66 | static volatile unsigned char* ata_control; | ||
67 | |||
62 | static int wait_for_bsy(void) | 68 | static 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 | ||
302 | static int master_slave(void) | 308 | static 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 | ||
329 | static 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 | |||
323 | int ata_init(void) | 364 | int 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 | ||