1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Alan Korr
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
34 #include "ata_idle_notify.h"
35 #include "ata-target.h"
36 #include "ata-defines.h"
39 #define SECTOR_SIZE 512
41 #define SELECT_DEVICE1 0x10
42 #define SELECT_LBA 0x40
44 #define CONTROL_nIEN 0x02
45 #define CONTROL_SRST 0x04
47 #define CMD_READ_SECTORS 0x20
48 #define CMD_WRITE_SECTORS 0x30
49 #define CMD_WRITE_SECTORS_EXT 0x34
50 #define CMD_READ_MULTIPLE 0xC4
51 #define CMD_READ_MULTIPLE_EXT 0x29
52 #define CMD_WRITE_MULTIPLE 0xC5
53 #define CMD_WRITE_MULTIPLE_EXT 0x39
54 #define CMD_SET_MULTIPLE_MODE 0xC6
55 #define CMD_STANDBY_IMMEDIATE 0xE0
56 #define CMD_STANDBY 0xE2
57 #define CMD_IDENTIFY 0xEC
58 #define CMD_SLEEP 0xE6
59 #define CMD_SET_FEATURES 0xEF
60 #define CMD_SECURITY_FREEZE_LOCK 0xF5
62 #define CMD_READ_DMA 0xC8
63 #define CMD_READ_DMA_EXT 0x25
64 #define CMD_WRITE_DMA 0xCA
65 #define CMD_WRITE_DMA_EXT 0x35
68 /* Should all be < 0x100 (which are reserved for control messages) */
72 #define READWRITE_TIMEOUT 5*HZ
74 #ifdef HAVE_ATA_POWER_OFF
75 #define ATA_POWER_OFF_TIMEOUT 2*HZ
78 #ifdef ATA_DRIVER_CLOSE
79 static unsigned int ata_thread_id
= 0;
82 #if defined(MAX_PHYS_SECTOR_SIZE) && MEM == 64
83 /* Hack - what's the deal with 5g? */
86 struct thread_entry
*thread
;
88 volatile unsigned char locked
;
89 IF_COP( struct corelock cl
; )
92 static void ata_lock_init(struct ata_lock
*l
)
94 corelock_init(&l
->cl
);
100 static void ata_lock_lock(struct ata_lock
*l
)
102 struct thread_entry
* const current
=
103 thread_id_entry(THREAD_ID_CURRENT
);
105 if (current
== l
->thread
)
111 corelock_lock(&l
->cl
);
113 IF_PRIO( current
->skip_count
= -1; )
115 while (l
->locked
!= 0)
117 corelock_unlock(&l
->cl
);
119 corelock_lock(&l
->cl
);
124 corelock_unlock(&l
->cl
);
127 static void ata_lock_unlock(struct ata_lock
*l
)
135 corelock_lock(&l
->cl
);
137 IF_PRIO( l
->thread
->skip_count
= 0; )
142 corelock_unlock(&l
->cl
);
145 #define mutex ata_lock
146 #define mutex_init ata_lock_init
147 #define mutex_lock ata_lock_lock
148 #define mutex_unlock ata_lock_unlock
149 #endif /* MAX_PHYS_SECTOR_SIZE */
151 #if defined(HAVE_USBSTACK) && defined(USE_ROCKBOX_USB)
152 #define ALLOW_USB_SPINDOWN
155 static struct mutex ata_mtx SHAREDBSS_ATTR
;
156 static int ata_device
; /* device 0 (master) or 1 (slave) */
158 static int spinup_time
= 0;
159 #if (CONFIG_LED == LED_REAL)
160 static bool ata_led_enabled
= true;
161 static bool ata_led_on
= false;
163 static bool spinup
= false;
164 static bool sleeping
= true;
165 static bool poweroff
= false;
166 static long sleep_timeout
= 5*HZ
;
168 static bool lba48
= false; /* set for 48 bit addressing */
170 static long ata_stack
[(DEFAULT_STACK_SIZE
*3)/sizeof(long)];
171 static const char ata_thread_name
[] = "ata";
172 static struct event_queue ata_queue SHAREDBSS_ATTR
;
173 static bool initialized
= false;
175 static long last_user_activity
= -1;
176 static long last_disk_activity
= -1;
178 static unsigned long total_sectors
;
179 static int multisectors
; /* number of supported multisectors */
180 static unsigned short identify_info
[SECTOR_SIZE
/2];
182 #ifdef MAX_PHYS_SECTOR_SIZE
184 struct sector_cache_entry
{
186 unsigned long sectornum
; /* logical sector */
187 unsigned char data
[MAX_PHYS_SECTOR_SIZE
];
189 /* buffer for reading and writing large physical sectors */
191 static struct sector_cache_entry sector_cache
;
192 static int phys_sector_mult
= 1;
196 static int dma_mode
= 0;
199 static int ata_power_on(void);
200 static int perform_soft_reset(void);
201 static int set_multiple_mode(int sectors
);
202 static int set_features(void);
204 STATICIRAM ICODE_ATTR
int wait_for_bsy(void)
206 long timeout
= current_tick
+ HZ
*30;
210 if (!(ATA_IN8(ATA_STATUS
) & STATUS_BSY
))
212 last_disk_activity
= current_tick
;
214 } while (TIME_BEFORE(current_tick
, timeout
));
216 return 0; /* timeout */
219 STATICIRAM ICODE_ATTR
int wait_for_rdy(void)
226 timeout
= current_tick
+ HZ
*10;
230 if (ATA_IN8(ATA_ALT_STATUS
) & STATUS_RDY
)
232 last_disk_activity
= current_tick
;
234 } while (TIME_BEFORE(current_tick
, timeout
));
236 return 0; /* timeout */
239 STATICIRAM ICODE_ATTR
int wait_for_start_of_transfer(void)
244 return (ATA_IN8(ATA_ALT_STATUS
) & (STATUS_BSY
|STATUS_DRQ
)) == STATUS_DRQ
;
247 STATICIRAM ICODE_ATTR
int wait_for_end_of_transfer(void)
251 return (ATA_IN8(ATA_ALT_STATUS
) &
252 (STATUS_BSY
|STATUS_RDY
|STATUS_DF
|STATUS_DRQ
|STATUS_ERR
))
256 #if (CONFIG_LED == LED_REAL)
257 /* Conditionally block LED access for the ATA driver, so the LED can be
258 * (mis)used for other purposes */
259 static void ata_led(bool on
)
266 #define ata_led(on) led(on)
269 #ifndef ATA_OPTIMIZED_READING
270 STATICIRAM ICODE_ATTR
void copy_read_sectors(unsigned char* buf
, int wordcount
)
272 unsigned short tmp
= 0;
274 if ( (unsigned long)buf
& 1)
275 { /* not 16-bit aligned, copy byte by byte */
276 unsigned char* bufend
= buf
+ wordcount
*2;
279 tmp
= ATA_IN16(ATA_DATA
);
280 #if defined(ROCKBOX_LITTLE_ENDIAN)
281 *buf
++ = tmp
& 0xff; /* I assume big endian */
282 *buf
++ = tmp
>> 8; /* and don't use the SWAB16 macro */
287 } while (buf
< bufend
); /* tail loop is faster */
290 { /* 16-bit aligned, can do faster copy */
291 unsigned short* wbuf
= (unsigned short*)buf
;
292 unsigned short* wbufend
= wbuf
+ wordcount
;
295 *wbuf
= ATA_IN16(ATA_DATA
);
296 } while (++wbuf
< wbufend
); /* tail loop is faster */
299 #endif /* !ATA_OPTIMIZED_READING */
301 #ifndef ATA_OPTIMIZED_WRITING
302 STATICIRAM ICODE_ATTR
void copy_write_sectors(const unsigned char* buf
,
305 if ( (unsigned long)buf
& 1)
306 { /* not 16-bit aligned, copy byte by byte */
307 unsigned short tmp
= 0;
308 const unsigned char* bufend
= buf
+ wordcount
*2;
311 #if defined(ROCKBOX_LITTLE_ENDIAN)
312 tmp
= (unsigned short) *buf
++;
313 tmp
|= (unsigned short) *buf
++ << 8;
315 tmp
= (unsigned short) *buf
++ << 8;
316 tmp
|= (unsigned short) *buf
++;
318 ATA_OUT16(ATA_DATA
, tmp
);
319 } while (buf
< bufend
); /* tail loop is faster */
322 { /* 16-bit aligned, can do faster copy */
323 unsigned short* wbuf
= (unsigned short*)buf
;
324 unsigned short* wbufend
= wbuf
+ wordcount
;
327 ATA_OUT16(ATA_DATA
, *wbuf
);
328 } while (++wbuf
< wbufend
); /* tail loop is faster */
331 #endif /* !ATA_OPTIMIZED_WRITING */
333 static int ata_transfer_sectors(unsigned long start
,
347 #ifndef MAX_PHYS_SECTOR_SIZE
348 mutex_lock(&ata_mtx
);
351 if (start
+ incount
> total_sectors
) {
356 last_disk_activity
= current_tick
;
357 spinup_start
= current_tick
;
362 sleeping
= false; /* set this now since it'll be on */
365 if (ata_power_on()) {
371 if (perform_soft_reset()) {
378 timeout
= current_tick
+ READWRITE_TIMEOUT
;
380 ATA_OUT8(ATA_SELECT
, ata_device
);
390 while (TIME_BEFORE(current_tick
, timeout
)) {
392 last_disk_activity
= current_tick
;
395 /* If DMA is supported and parameters are ok for DMA, use it */
396 if (dma_mode
&& ata_dma_setup(inbuf
, incount
* SECTOR_SIZE
, write
))
403 ATA_OUT8(ATA_NSECTOR
, count
>> 8);
404 ATA_OUT8(ATA_NSECTOR
, count
& 0xff);
405 ATA_OUT8(ATA_SECTOR
, (start
>> 24) & 0xff); /* 31:24 */
406 ATA_OUT8(ATA_SECTOR
, start
& 0xff); /* 7:0 */
407 ATA_OUT8(ATA_LCYL
, 0); /* 39:32 */
408 ATA_OUT8(ATA_LCYL
, (start
>> 8) & 0xff); /* 15:8 */
409 ATA_OUT8(ATA_HCYL
, 0); /* 47:40 */
410 ATA_OUT8(ATA_HCYL
, (start
>> 16) & 0xff); /* 23:16 */
411 ATA_OUT8(ATA_SELECT
, SELECT_LBA
| ata_device
);
414 ATA_OUT8(ATA_COMMAND
, usedma
? CMD_WRITE_DMA_EXT
: CMD_WRITE_MULTIPLE_EXT
);
416 ATA_OUT8(ATA_COMMAND
, usedma
? CMD_READ_DMA_EXT
: CMD_READ_MULTIPLE_EXT
);
418 ATA_OUT8(ATA_COMMAND
, write
? CMD_WRITE_MULTIPLE_EXT
: CMD_READ_MULTIPLE_EXT
);
424 ATA_OUT8(ATA_NSECTOR
, count
& 0xff); /* 0 means 256 sectors */
425 ATA_OUT8(ATA_SECTOR
, start
& 0xff);
426 ATA_OUT8(ATA_LCYL
, (start
>> 8) & 0xff);
427 ATA_OUT8(ATA_HCYL
, (start
>> 16) & 0xff);
428 ATA_OUT8(ATA_SELECT
, ((start
>> 24) & 0xf) | SELECT_LBA
| ata_device
);
431 ATA_OUT8(ATA_COMMAND
, usedma
? CMD_WRITE_DMA
: CMD_WRITE_MULTIPLE
);
433 ATA_OUT8(ATA_COMMAND
, usedma
? CMD_READ_DMA
: CMD_READ_MULTIPLE
);
435 ATA_OUT8(ATA_COMMAND
, write
? CMD_WRITE_MULTIPLE
: CMD_READ_MULTIPLE
);
439 /* wait at least 400ns between writing command and reading status */
440 __asm__
volatile ("nop");
441 __asm__
volatile ("nop");
442 __asm__
volatile ("nop");
443 __asm__
volatile ("nop");
444 __asm__
volatile ("nop");
448 if (!ata_dma_finish())
452 perform_soft_reset();
457 spinup_time
= current_tick
- spinup_start
;
463 #endif /* HAVE_ATA_DMA */
471 if (!wait_for_start_of_transfer()) {
472 /* We have timed out waiting for RDY and/or DRQ, possibly
473 because the hard drive is shaking and has problems
474 reading the data. We have two options:
476 2) Perform a soft reset and try again.
478 We choose alternative 2.
480 perform_soft_reset();
486 spinup_time
= current_tick
- spinup_start
;
491 /* read the status register exactly once per loop */
492 status
= ATA_IN8(ATA_STATUS
);
493 error
= ATA_IN8(ATA_ERROR
);
495 if (count
>= multisectors
)
496 sectors
= multisectors
;
500 wordcount
= sectors
* SECTOR_SIZE
/ 2;
503 copy_write_sectors(buf
, wordcount
);
505 copy_read_sectors(buf
, wordcount
);
508 "Device errors encountered during READ MULTIPLE commands
509 are posted at the beginning of the block or partial block
510 transfer, but the DRQ bit is still set to one and the data
511 transfer shall take place, including transfer of corrupted
515 if ( status
& (STATUS_BSY
| STATUS_ERR
| STATUS_DF
) ) {
516 perform_soft_reset();
518 /* no point retrying IDNF, sector no. was invalid */
519 if (error
& ERROR_IDNF
)
524 buf
+= sectors
* SECTOR_SIZE
; /* Advance one chunk of sectors */
527 last_disk_activity
= current_tick
;
531 if(!ret
&& !wait_for_end_of_transfer()) {
534 error
= ATA_IN8(ATA_ERROR
);
535 perform_soft_reset();
537 /* no point retrying IDNF, sector no. was invalid */
538 if (error
& ERROR_IDNF
)
547 #ifndef MAX_PHYS_SECTOR_SIZE
548 mutex_unlock(&ata_mtx
);
554 #ifndef MAX_PHYS_SECTOR_SIZE
555 int ata_read_sectors(IF_MD2(int drive
,)
560 #ifdef HAVE_MULTIDRIVE
561 (void)drive
; /* unused for now */
564 return ata_transfer_sectors(start
, incount
, inbuf
, false);
568 #ifndef MAX_PHYS_SECTOR_SIZE
569 int ata_write_sectors(IF_MD2(int drive
,)
574 #ifdef HAVE_MULTIDRIVE
575 (void)drive
; /* unused for now */
578 return ata_transfer_sectors(start
, count
, (void*)buf
, true);
582 #ifdef MAX_PHYS_SECTOR_SIZE
583 static int cache_sector(unsigned long sector
)
587 sector
&= ~(phys_sector_mult
- 1);
588 /* round down to physical sector boundary */
590 /* check whether the sector is already cached */
591 if (sector_cache
.inuse
&& (sector_cache
.sectornum
== sector
))
594 /* not found: read the sector */
595 sector_cache
.inuse
= false;
596 rc
= ata_transfer_sectors(sector
, phys_sector_mult
, sector_cache
.data
, false);
599 sector_cache
.sectornum
= sector
;
600 sector_cache
.inuse
= true;
605 static inline int flush_current_sector(void)
607 return ata_transfer_sectors(sector_cache
.sectornum
, phys_sector_mult
,
608 sector_cache
.data
, true);
611 int ata_read_sectors(IF_MD2(int drive
,)
619 #ifdef HAVE_MULTIDRIVE
620 (void)drive
; /* unused for now */
622 mutex_lock(&ata_mtx
);
624 offset
= start
& (phys_sector_mult
- 1);
626 if (offset
) /* first partial sector */
628 int partcount
= MIN(incount
, phys_sector_mult
- offset
);
630 rc
= cache_sector(start
);
636 memcpy(inbuf
, sector_cache
.data
+ offset
* SECTOR_SIZE
,
637 partcount
* SECTOR_SIZE
);
640 inbuf
+= partcount
* SECTOR_SIZE
;
641 incount
-= partcount
;
645 offset
= incount
& (phys_sector_mult
- 1);
650 rc
= ata_transfer_sectors(start
, incount
, inbuf
, false);
657 inbuf
+= incount
* SECTOR_SIZE
;
661 rc
= cache_sector(start
);
667 memcpy(inbuf
, sector_cache
.data
, offset
* SECTOR_SIZE
);
672 mutex_unlock(&ata_mtx
);
677 int ata_write_sectors(IF_MD2(int drive
,)
685 #ifdef HAVE_MULTIDRIVE
686 (void)drive
; /* unused for now */
688 mutex_lock(&ata_mtx
);
690 offset
= start
& (phys_sector_mult
- 1);
692 if (offset
) /* first partial sector */
694 int partcount
= MIN(count
, phys_sector_mult
- offset
);
696 rc
= cache_sector(start
);
702 memcpy(sector_cache
.data
+ offset
* SECTOR_SIZE
, buf
,
703 partcount
* SECTOR_SIZE
);
704 rc
= flush_current_sector();
711 buf
+= partcount
* SECTOR_SIZE
;
716 offset
= count
& (phys_sector_mult
- 1);
721 rc
= ata_transfer_sectors(start
, count
, (void*)buf
, true);
728 buf
+= count
* SECTOR_SIZE
;
732 rc
= cache_sector(start
);
738 memcpy(sector_cache
.data
, buf
, offset
* SECTOR_SIZE
);
739 rc
= flush_current_sector();
749 mutex_unlock(&ata_mtx
);
753 #endif /* MAX_PHYS_SECTOR_SIZE */
755 static int check_registers(void)
759 if (ATA_IN8(ATA_STATUS
) & STATUS_BSY
)
762 for (i
= 0; i
<64; i
++) {
763 ATA_OUT8(ATA_NSECTOR
, TEST_PATTERN1
);
764 ATA_OUT8(ATA_SECTOR
, TEST_PATTERN2
);
765 ATA_OUT8(ATA_LCYL
, TEST_PATTERN3
);
766 ATA_OUT8(ATA_HCYL
, TEST_PATTERN4
);
768 if (((ATA_IN8(ATA_NSECTOR
) & 0xff) == TEST_PATTERN1
) &&
769 ((ATA_IN8(ATA_SECTOR
) & 0xff) == TEST_PATTERN2
) &&
770 ((ATA_IN8(ATA_LCYL
) & 0xff) == TEST_PATTERN3
) &&
771 ((ATA_IN8(ATA_HCYL
) & 0xff) == TEST_PATTERN4
))
779 static int freeze_lock(void)
781 /* does the disk support Security Mode feature set? */
782 if (identify_info
[82] & 2)
784 ATA_OUT8(ATA_SELECT
, ata_device
);
789 ATA_OUT8(ATA_COMMAND
, CMD_SECURITY_FREEZE_LOCK
);
798 void ata_spindown(int seconds
)
800 sleep_timeout
= seconds
* HZ
;
803 bool ata_disk_is_active(void)
808 static int ata_perform_sleep(void)
810 /* guard against calls made with checks of these variables outside
811 the mutex that may not be on the ata thread; status may have changed. */
812 if (spinup
|| sleeping
) {
816 ATA_OUT8(ATA_SELECT
, ata_device
);
818 if(!wait_for_rdy()) {
819 DEBUGF("ata_perform_sleep() - not RDY\n");
823 ATA_OUT8(ATA_COMMAND
, CMD_SLEEP
);
827 DEBUGF("ata_perform_sleep() - CMD failed\n");
837 queue_post(&ata_queue
, Q_SLEEP
, 0);
840 void ata_sleepnow(void)
842 if (!spinup
&& !sleeping
&& initialized
)
844 call_storage_idle_notifys(false);
845 mutex_lock(&ata_mtx
);
847 mutex_unlock(&ata_mtx
);
853 last_user_activity
= current_tick
;
856 static void ata_thread(void)
858 static long last_sleep
= 0;
859 struct queue_event ev
;
860 #ifdef ALLOW_USB_SPINDOWN
861 static bool usb_mode
= false;
865 queue_wait_w_tmo(&ata_queue
, &ev
, HZ
/2);
869 if (!spinup
&& !sleeping
)
871 if (TIME_AFTER( current_tick
,
872 last_disk_activity
+ (HZ
*2) ) )
874 #ifdef ALLOW_USB_SPINDOWN
878 call_storage_idle_notifys(false);
882 if ( sleep_timeout
&&
883 TIME_AFTER( current_tick
,
884 last_user_activity
+ sleep_timeout
) &&
885 TIME_AFTER( current_tick
,
886 last_disk_activity
+ sleep_timeout
) )
888 #ifdef ALLOW_USB_SPINDOWN
892 call_storage_idle_notifys(true);
894 mutex_lock(&ata_mtx
);
896 last_sleep
= current_tick
;
897 mutex_unlock(&ata_mtx
);
901 #ifdef HAVE_ATA_POWER_OFF
902 if ( !spinup
&& sleeping
&& !poweroff
&&
903 TIME_AFTER( current_tick
, last_sleep
+ ATA_POWER_OFF_TIMEOUT
))
905 mutex_lock(&ata_mtx
);
906 ide_power_enable(false);
908 mutex_unlock(&ata_mtx
);
914 case SYS_USB_CONNECTED
:
915 /* Tell the USB thread that we are safe */
916 DEBUGF("ata_thread got SYS_USB_CONNECTED\n");
917 #ifdef ALLOW_USB_SPINDOWN
919 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
920 /* There is no need to force ATA power on */
922 mutex_lock(&ata_mtx
);
925 sleeping
= false; /* set this now since it'll be on */
932 perform_soft_reset();
937 mutex_unlock(&ata_mtx
);
939 /* Wait until the USB cable is extracted again */
940 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
941 usb_wait_for_disconnect(&ata_queue
);
945 #ifdef ALLOW_USB_SPINDOWN
946 case SYS_USB_DISCONNECTED
:
947 /* Tell the USB thread that we are ready again */
948 DEBUGF("ata_thread got SYS_USB_DISCONNECTED\n");
952 #endif /* USB_NONE */
955 #ifdef ALLOW_USB_SPINDOWN
959 call_storage_idle_notifys(false);
961 last_disk_activity
= current_tick
- sleep_timeout
+ (HZ
/2);
964 #ifdef ATA_DRIVER_CLOSE
972 /* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
973 static int ata_hard_reset(void)
977 mutex_lock(&ata_mtx
);
982 ATA_OUT8(ATA_SELECT
, ata_device
); /* select the right device */
983 ret
= wait_for_bsy();
985 /* Massage the return code so it is 0 on success and -1 on failure */
988 mutex_unlock(&ata_mtx
);
993 static int perform_soft_reset(void)
995 /* If this code is allowed to run on a Nano, the next reads from the flash will
996 * time out, so we disable it. It shouldn't be necessary anyway, since the
997 * ATA -> Flash interface automatically sleeps almost immediately after the
1003 ATA_OUT8(ATA_SELECT
, SELECT_LBA
| ata_device
);
1004 ATA_OUT8(ATA_CONTROL
, CONTROL_nIEN
|CONTROL_SRST
);
1005 sleep(1); /* >= 5us */
1008 /* DMA requires INTRQ be enabled */
1009 ATA_OUT8(ATA_CONTROL
, 0);
1011 ATA_OUT8(ATA_CONTROL
, CONTROL_nIEN
);
1013 sleep(1); /* >2ms */
1015 /* This little sucker can take up to 30 seconds */
1019 ret
= wait_for_rdy();
1020 } while(!ret
&& retry_count
--);
1028 if (set_multiple_mode(multisectors
))
1037 int ata_soft_reset(void)
1041 mutex_lock(&ata_mtx
);
1043 ret
= perform_soft_reset();
1045 mutex_unlock(&ata_mtx
);
1049 static int ata_power_on(void)
1053 ide_power_enable(true);
1054 sleep(HZ
/4); /* allow voltage to build up */
1056 /* Accessing the PP IDE controller too early after powering up the disk
1057 * makes the core hang for a short time, causing an audio dropout. This
1058 * also depends on the disk; iPod Mini G2 needs at least HZ/5 to get rid
1059 * of the dropout. Since this time isn't additive (the wait_for_bsy() in
1060 * ata_hard_reset() will shortened by the same amount), it's a good idea
1061 * to do this on all HDD based targets. */
1063 if( ata_hard_reset() )
1066 rc
= set_features();
1070 if (set_multiple_mode(multisectors
))
1079 static int master_slave_detect(void)
1082 ATA_OUT8(ATA_SELECT
, 0);
1083 if (ATA_IN8(ATA_STATUS
) & (STATUS_RDY
|STATUS_BSY
)) {
1085 DEBUGF("Found master harddisk\n");
1089 ATA_OUT8(ATA_SELECT
, SELECT_DEVICE1
);
1090 if (ATA_IN8(ATA_STATUS
) & (STATUS_RDY
|STATUS_BSY
)) {
1091 ata_device
= SELECT_DEVICE1
;
1092 DEBUGF("Found slave harddisk\n");
1100 static int identify(void)
1104 ATA_OUT8(ATA_SELECT
, ata_device
);
1106 if(!wait_for_rdy()) {
1107 DEBUGF("identify() - not RDY\n");
1110 ATA_OUT8(ATA_COMMAND
, CMD_IDENTIFY
);
1112 if (!wait_for_start_of_transfer())
1114 DEBUGF("identify() - CMD failed\n");
1118 for (i
=0; i
<SECTOR_SIZE
/2; i
++) {
1119 /* the IDENTIFY words are already swapped, so we need to treat
1120 this info differently that normal sector data */
1121 identify_info
[i
] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA
));
1127 static int set_multiple_mode(int sectors
)
1129 ATA_OUT8(ATA_SELECT
, ata_device
);
1131 if(!wait_for_rdy()) {
1132 DEBUGF("set_multiple_mode() - not RDY\n");
1136 ATA_OUT8(ATA_NSECTOR
, sectors
);
1137 ATA_OUT8(ATA_COMMAND
, CMD_SET_MULTIPLE_MODE
);
1139 if (!wait_for_rdy())
1141 DEBUGF("set_multiple_mode() - CMD failed\n");
1149 static int get_best_mode(unsigned short identword
, int max
, int modetype
)
1151 unsigned short testbit
= BIT_N(max
);
1154 if (identword
& testbit
)
1155 return max
| modetype
;
1164 static int set_features(void)
1167 unsigned char id_word
;
1168 unsigned char id_bit
;
1169 unsigned char subcommand
;
1170 unsigned char parameter
;
1172 { 83, 14, 0x03, 0 }, /* force PIO mode */
1173 { 83, 3, 0x05, 0x80 }, /* adv. power management: lowest w/o standby */
1174 { 83, 9, 0x42, 0x80 }, /* acoustic management: lowest noise */
1175 { 82, 6, 0xaa, 0 }, /* enable read look-ahead */
1177 { 0, 0, 0x03, 0 }, /* DMA mode */
1183 /* Find out the highest supported PIO mode */
1184 if(identify_info
[64] & 2)
1187 if(identify_info
[64] & 1)
1190 /* Update the table: set highest supported pio mode that we also support */
1191 features
[0].parameter
= 8 + pio_mode
;
1194 if (identify_info
[53] & (1<<2))
1195 /* Ultra DMA mode info present, find a mode */
1196 dma_mode
= get_best_mode(identify_info
[88], ATA_MAX_UDMA
, 0x40);
1199 /* No UDMA mode found, try to find a multi-word DMA mode */
1200 dma_mode
= get_best_mode(identify_info
[63], ATA_MAX_MWDMA
, 0x20);
1201 features
[4].id_word
= 63;
1204 features
[4].id_word
= 88;
1206 features
[4].id_bit
= dma_mode
& 7;
1207 features
[4].parameter
= dma_mode
;
1208 #endif /* HAVE_ATA_DMA */
1210 ATA_OUT8(ATA_SELECT
, ata_device
);
1212 if (!wait_for_rdy()) {
1213 DEBUGF("set_features() - not RDY\n");
1217 for (i
=0; i
< (int)(sizeof(features
)/sizeof(features
[0])); i
++) {
1218 if (identify_info
[features
[i
].id_word
] & BIT_N(features
[i
].id_bit
)) {
1219 ATA_OUT8(ATA_FEATURE
, features
[i
].subcommand
);
1220 ATA_OUT8(ATA_NSECTOR
, features
[i
].parameter
);
1221 ATA_OUT8(ATA_COMMAND
, CMD_SET_FEATURES
);
1223 if (!wait_for_rdy()) {
1224 DEBUGF("set_features() - CMD failed\n");
1228 if((ATA_IN8(ATA_ALT_STATUS
) & STATUS_ERR
) && (i
!= 1)) {
1229 /* some CF cards don't like advanced powermanagement
1230 even if they mark it as supported - go figure... */
1231 if(ATA_IN8(ATA_ERROR
) & ERROR_ABRT
) {
1238 #ifdef ATA_SET_DEVICE_FEATURES
1239 ata_set_pio_timings(pio_mode
);
1243 ata_dma_set_mode(dma_mode
);
1249 unsigned short* ata_get_identify(void)
1251 return identify_info
;
1254 static int init_and_check(bool hard_reset
)
1260 /* This should reset both master and slave, we don't yet know what's in */
1262 if (ata_hard_reset())
1266 rc
= master_slave_detect();
1270 /* symptom fix: else check_registers() below may fail */
1271 if (hard_reset
&& !wait_for_bsy())
1274 rc
= check_registers();
1286 if ( !initialized
) {
1287 mutex_init(&ata_mtx
);
1288 queue_init(&ata_queue
, true);
1291 mutex_lock(&ata_mtx
);
1293 /* must be called before ata_device_init() */
1294 coldstart
= ata_is_coldstart();
1299 #ifdef MAX_PHYS_SECTOR_SIZE
1300 memset(§or_cache
, 0, sizeof(sector_cache
));
1303 if ( !initialized
) {
1304 /* First call won't have multiple thread contention - this
1305 * may return at any point without having to unlock */
1306 mutex_unlock(&ata_mtx
);
1308 if (!ide_powered()) /* somebody has switched it off */
1310 ide_power_enable(true);
1311 sleep(HZ
/4); /* allow voltage to build up */
1315 /* DMA requires INTRQ be enabled */
1316 ATA_OUT8(ATA_CONTROL
, 0);
1319 /* first try, hard reset at cold start only */
1320 rc
= init_and_check(coldstart
);
1323 { /* failed? -> second try, always with hard reset */
1324 DEBUGF("ata: init failed, retrying...\n");
1325 rc
= init_and_check(true);
1335 multisectors
= identify_info
[47] & 0xff;
1336 if (multisectors
== 0) /* Invalid multisector info, try with 16 */
1339 DEBUGF("ata: %d sectors per ata request\n",multisectors
);
1341 total_sectors
= identify_info
[60] | (identify_info
[61] << 16);
1344 if (identify_info
[83] & 0x0400 /* 48 bit address support */
1345 && total_sectors
== 0x0FFFFFFF) /* and disk size >= 128 GiB */
1346 { /* (needs BigLBA addressing) */
1347 if (identify_info
[102] || identify_info
[103])
1348 panicf("Unsupported disk size: >= 2^32 sectors");
1350 total_sectors
= identify_info
[100] | (identify_info
[101] << 16);
1351 lba48
= true; /* use BigLBA */
1359 rc
= set_features();
1363 #ifdef MAX_PHYS_SECTOR_SIZE
1364 /* Find out the physical sector size */
1365 if((identify_info
[106] & 0xe000) == 0x6000)
1366 phys_sector_mult
= BIT_N(identify_info
[106] & 0x000f);
1368 phys_sector_mult
= 1;
1370 DEBUGF("ata: %d logical sectors per phys sector", phys_sector_mult
);
1372 if (phys_sector_mult
> 1)
1374 /* Check if drive really needs emulation - if we can access
1375 * sector 1 then assume the drive will handle it better than
1376 * us, and ignore the large physical sectors.
1378 char throwaway
[SECTOR_SIZE
];
1379 rc
= ata_transfer_sectors(1, 1, &throwaway
, false);
1381 phys_sector_mult
= 1;
1384 if (phys_sector_mult
> (MAX_PHYS_SECTOR_SIZE
/SECTOR_SIZE
))
1385 panicf("Unsupported physical sector size: %d",
1386 phys_sector_mult
* SECTOR_SIZE
);
1389 mutex_lock(&ata_mtx
); /* Balance unlock below */
1391 last_disk_activity
= current_tick
;
1392 #ifdef ATA_DRIVER_CLOSE
1395 create_thread(ata_thread
, ata_stack
,
1396 sizeof(ata_stack
), 0, ata_thread_name
1397 IF_PRIO(, PRIORITY_USER_INTERFACE
)
1402 rc
= set_multiple_mode(multisectors
);
1406 mutex_unlock(&ata_mtx
);
1410 #ifdef ATA_DRIVER_CLOSE
1411 void ata_close(void)
1413 unsigned int thread_id
= ata_thread_id
;
1420 queue_post(&ata_queue
, Q_CLOSE
, 0);
1421 thread_wait(thread_id
);
1423 #endif /* ATA_DRIVER_CLOSE */
1425 #if (CONFIG_LED == LED_REAL)
1426 void ata_set_led_enabled(bool enabled
)
1428 ata_led_enabled
= enabled
;
1429 if (ata_led_enabled
)
1436 long ata_last_disk_activity(void)
1438 return last_disk_activity
;
1441 int ata_spinup_time(void)
1446 #ifdef STORAGE_GET_INFO
1447 void ata_get_info(IF_MD2(int drive
,)struct storage_info
*info
)
1449 unsigned short *src
,*dest
;
1450 static char vendor
[8];
1451 static char product
[16];
1452 static char revision
[4];
1453 #ifdef HAVE_MULTIDRIVE
1454 (void)drive
; /* unused for now */
1457 info
->sector_size
= SECTOR_SIZE
;
1458 info
->num_sectors
= total_sectors
;
1460 src
= (unsigned short*)&identify_info
[27];
1461 dest
= (unsigned short*)vendor
;
1463 dest
[i
] = htobe16(src
[i
]);
1464 info
->vendor
=vendor
;
1466 src
= (unsigned short*)&identify_info
[31];
1467 dest
= (unsigned short*)product
;
1469 dest
[i
] = htobe16(src
[i
]);
1470 info
->product
=product
;
1472 src
= (unsigned short*)&identify_info
[23];
1473 dest
= (unsigned short*)revision
;
1475 dest
[i
] = htobe16(src
[i
]);
1476 info
->revision
=revision
;
1481 /* Returns last DMA mode as set by set_features() */
1482 int ata_get_dma_mode(void)
1487 /* Needed to allow updating while waiting for DMA to complete */
1488 void ata_keep_active(void)
1490 last_disk_activity
= current_tick
;
1494 #ifdef CONFIG_STORAGE_MULTI
1495 int ata_num_drives(int first_drive
)
1497 /* We don't care which logical drive number(s) we have been assigned */