From 6c9e57810d6b07d4f05e4e7be14913b91083e2c3 Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Sat, 27 Apr 2002 14:19:00 +0000 Subject: Added ata_spindown() and use of ALT_STATUS instead of STATUS git-svn-id: svn://svn.rockbox.org/rockbox/trunk@259 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/ata.c | 42 +++++++++++++++++++++++++++++++++++++----- firmware/drivers/ata.h | 12 ++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) (limited to 'firmware/drivers') diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index cb4e1e6b90..24abecdb5c 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c @@ -31,6 +31,7 @@ #define ATA_COMMAND (*((volatile unsigned char*)0x06100107)) #define ATA_STATUS ATA_COMMAND #define ATA_CONTROL (*((volatile unsigned char*)0x06100306)) +#define ATA_ALT_STATUS ATA_CONTROL #define SELECT_LBA 0x40 @@ -52,7 +53,7 @@ static int wait_for_bsy(void) { char timeout = current_tick + HZ; - while (TIME_BEFORE(current_tick, timeout) && (ATA_STATUS & STATUS_BSY)) + while (TIME_BEFORE(current_tick, timeout) && (ATA_ALT_STATUS & STATUS_BSY)) yield(); if (TIME_BEFORE(current_tick, timeout)) @@ -65,21 +66,21 @@ static int wait_for_rdy(void) { if (!wait_for_bsy()) return 0; - return ATA_STATUS & STATUS_RDY; + return ATA_ALT_STATUS & STATUS_RDY; } static int wait_for_start_of_transfer(void) { if (!wait_for_bsy()) return 0; - return (ATA_STATUS & (STATUS_RDY|STATUS_DRQ)) == (STATUS_RDY|STATUS_DRQ); -} + return (ATA_ALT_STATUS & (STATUS_BSY|STATUS_DRQ)) == STATUS_DRQ; +} static int wait_for_end_of_transfer(void) { if (!wait_for_bsy()) return 0; - return (ATA_STATUS & (STATUS_RDY|STATUS_DRQ)) == STATUS_RDY; + return (ATA_ALT_STATUS & (STATUS_RDY|STATUS_DRQ)) == STATUS_RDY; } int ata_read_sectors(unsigned long start, @@ -107,6 +108,11 @@ int ata_read_sectors(unsigned long start, for (j=0; j<256; j++) ((unsigned short*)buf)[j] = SWAB16(ATA_DATA); + +#ifdef USE_INTERRUPT + /* reading the status register clears the interrupt */ + j = ATA_STATUS; +#endif } led_turn_off(); @@ -139,6 +145,11 @@ int ata_write_sectors(unsigned long start, for (j=0; j<256; j++) ATA_DATA = SWAB16(((unsigned short*)buf)[j]); + +#ifdef USE_INTERRUPT + /* reading the status register clears the interrupt */ + j = ATA_STATUS; +#endif } led_turn_off (); @@ -193,6 +204,27 @@ static int freeze_lock(void) return 0; } +int ata_spindown(int time) +{ + if (!wait_for_rdy()) + return -1; + + if ( time == -1 ) { + ATA_COMMAND = CMD_STANDBY_IMMEDIATE; + } + else { + if (time > 255) + return -1; + ATA_NSECTOR = time & 0xff; + ATA_COMMAND = CMD_STANDBY; + } + + if (!wait_for_rdy()) + return -1; + + return 0; +} + int ata_hard_reset(void) { clear_bit(1,PADR); diff --git a/firmware/drivers/ata.h b/firmware/drivers/ata.h index 50cd85d755..38e45d9e45 100644 --- a/firmware/drivers/ata.h +++ b/firmware/drivers/ata.h @@ -19,6 +19,18 @@ #ifndef __ATA_H__ #define __ATA_H__ +/* + ata_spindown() time values: + -1 Immediate spindown + 0 Timeout disabled + 1-240 (time * 5) seconds + 241-251((time - 240) * 30) minutes + 252 21 minutes + 253 Period between 8 and 12 hrs + 254 Reserved + 255 21 min 15 s +*/ +extern int ata_spindown(int time); extern int ata_hard_reset(void); extern int ata_soft_reset(void); extern int ata_init(void); -- cgit v1.2.3