Updated Swedish translation.
[kugel-rb.git] / firmware / drivers / ata.c
blob2c8033a533b2d37dafbf466e987cd91b8945ccc6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Alan Korr
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdbool.h>
20 #include "ata.h"
21 #include "kernel.h"
22 #include "thread.h"
23 #include "led.h"
24 #include "cpu.h"
25 #include "system.h"
26 #include "debug.h"
27 #include "panic.h"
28 #include "usb.h"
29 #include "power.h"
30 #include "string.h"
31 #include "ata_idle_notify.h"
32 #include "ata-target.h"
34 #define SECTOR_SIZE (512)
36 #define ATA_FEATURE ATA_ERROR
38 #define ATA_STATUS ATA_COMMAND
39 #define ATA_ALT_STATUS ATA_CONTROL
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_SET_MULTIPLE_MODE 0xC6
54 #define CMD_STANDBY_IMMEDIATE 0xE0
55 #define CMD_STANDBY 0xE2
56 #define CMD_IDENTIFY 0xEC
57 #define CMD_SLEEP 0xE6
58 #define CMD_SET_FEATURES 0xEF
59 #define CMD_SECURITY_FREEZE_LOCK 0xF5
61 #define Q_SLEEP 0
63 #define READ_TIMEOUT 5*HZ
65 #ifdef HAVE_ATA_POWER_OFF
66 #define ATA_POWER_OFF_TIMEOUT 2*HZ
67 #endif
69 static struct mutex ata_mtx;
70 int ata_device; /* device 0 (master) or 1 (slave) */
72 int ata_spinup_time = 0;
73 #if (CONFIG_LED == LED_REAL)
74 static bool ata_led_enabled = true;
75 static bool ata_led_on = false;
76 #endif
77 static bool spinup = false;
78 static bool sleeping = true;
79 static bool poweroff = false;
80 static long sleep_timeout = 5*HZ;
81 #ifdef HAVE_LBA48
82 static bool lba48 = false; /* set for 48 bit addressing */
83 #endif
84 static long ata_stack[(DEFAULT_STACK_SIZE*3)/sizeof(long)];
85 static const char ata_thread_name[] = "ata";
86 static struct event_queue ata_queue;
87 static bool initialized = false;
89 static long last_user_activity = -1;
90 long last_disk_activity = -1;
92 static int multisectors; /* number of supported multisectors */
93 static unsigned short identify_info[SECTOR_SIZE];
95 #ifdef MAX_PHYS_SECTOR_SIZE
96 struct sector_cache_entry {
97 bool inuse;
98 unsigned long sectornum; /* logical sector */
99 unsigned char data[MAX_PHYS_SECTOR_SIZE];
101 /* buffer for reading and writing large physical sectors */
102 #define NUMCACHES 2
103 static struct sector_cache_entry sector_cache;
104 static int phys_sector_mult = 1;
105 #endif
107 static int ata_power_on(void);
108 static int perform_soft_reset(void);
109 static int set_multiple_mode(int sectors);
110 static int set_features(void);
112 STATICIRAM int wait_for_bsy(void) ICODE_ATTR;
113 STATICIRAM int wait_for_bsy(void)
115 long timeout = current_tick + HZ*30;
116 while (TIME_BEFORE(current_tick, timeout) && (ATA_STATUS & STATUS_BSY)) {
117 last_disk_activity = current_tick;
118 priority_yield();
121 if (TIME_BEFORE(current_tick, timeout))
122 return 1;
123 else
124 return 0; /* timeout */
127 STATICIRAM int wait_for_rdy(void) ICODE_ATTR;
128 STATICIRAM int wait_for_rdy(void)
130 long timeout;
132 if (!wait_for_bsy())
133 return 0;
135 timeout = current_tick + HZ*10;
137 while (TIME_BEFORE(current_tick, timeout) &&
138 !(ATA_ALT_STATUS & STATUS_RDY)) {
139 last_disk_activity = current_tick;
140 priority_yield();
143 if (TIME_BEFORE(current_tick, timeout))
144 return STATUS_RDY;
145 else
146 return 0; /* timeout */
149 STATICIRAM int wait_for_start_of_transfer(void) ICODE_ATTR;
150 STATICIRAM int wait_for_start_of_transfer(void)
152 if (!wait_for_bsy())
153 return 0;
155 return (ATA_ALT_STATUS & (STATUS_BSY|STATUS_DRQ)) == STATUS_DRQ;
158 STATICIRAM int wait_for_end_of_transfer(void) ICODE_ATTR;
159 STATICIRAM int wait_for_end_of_transfer(void)
161 if (!wait_for_bsy())
162 return 0;
163 return (ATA_ALT_STATUS & (STATUS_RDY|STATUS_DRQ)) == STATUS_RDY;
166 #if (CONFIG_LED == LED_REAL)
167 /* Conditionally block LED access for the ATA driver, so the LED can be
168 * (mis)used for other purposes */
169 static void ata_led(bool on)
171 ata_led_on = on;
172 if (ata_led_enabled)
173 led(ata_led_on);
175 #else
176 #define ata_led(on) led(on)
177 #endif
179 #ifndef ATA_OPTIMIZED_READING
180 STATICIRAM void copy_read_sectors(unsigned char* buf, int wordcount) ICODE_ATTR;
181 STATICIRAM void copy_read_sectors(unsigned char* buf, int wordcount)
183 unsigned short tmp = 0;
185 if ( (unsigned long)buf & 1)
186 { /* not 16-bit aligned, copy byte by byte */
187 unsigned char* bufend = buf + wordcount*2;
190 tmp = ATA_DATA;
191 #if defined(SWAP_WORDS) || defined(ROCKBOX_LITTLE_ENDIAN)
192 *buf++ = tmp & 0xff; /* I assume big endian */
193 *buf++ = tmp >> 8; /* and don't use the SWAB16 macro */
194 #else
195 *buf++ = tmp >> 8;
196 *buf++ = tmp & 0xff;
197 #endif
198 } while (buf < bufend); /* tail loop is faster */
200 else
201 { /* 16-bit aligned, can do faster copy */
202 unsigned short* wbuf = (unsigned short*)buf;
203 unsigned short* wbufend = wbuf + wordcount;
206 #ifdef SWAP_WORDS
207 *wbuf = swap16(ATA_DATA);
208 #else
209 *wbuf = ATA_DATA;
210 #endif
211 } while (++wbuf < wbufend); /* tail loop is faster */
214 #endif /* !ATA_OPTIMIZED_READING */
216 #ifdef MAX_PHYS_SECTOR_SIZE
217 static int _read_sectors(unsigned long start,
218 int incount,
219 void* inbuf)
220 #else
221 int ata_read_sectors(IF_MV2(int drive,)
222 unsigned long start,
223 int incount,
224 void* inbuf)
225 #endif
227 int ret = 0;
228 long timeout;
229 int count;
230 void* buf;
231 long spinup_start;
233 #ifndef MAX_PHYS_SECTOR_SIZE
234 #ifdef HAVE_MULTIVOLUME
235 (void)drive; /* unused for now */
236 #endif
237 spinlock_lock(&ata_mtx);
238 #endif
240 last_disk_activity = current_tick;
241 spinup_start = current_tick;
243 ata_led(true);
245 if ( sleeping ) {
246 spinup = true;
247 if (poweroff) {
248 if (ata_power_on()) {
249 spinlock_unlock(&ata_mtx);
250 ata_led(false);
251 return -1;
254 else {
255 if (perform_soft_reset()) {
256 spinlock_unlock(&ata_mtx);
257 ata_led(false);
258 return -1;
263 timeout = current_tick + READ_TIMEOUT;
265 SET_REG(ATA_SELECT, ata_device);
266 if (!wait_for_rdy())
268 spinlock_unlock(&ata_mtx);
269 ata_led(false);
270 return -2;
273 retry:
274 buf = inbuf;
275 count = incount;
276 while (TIME_BEFORE(current_tick, timeout)) {
277 ret = 0;
278 last_disk_activity = current_tick;
280 #ifdef HAVE_LBA48
281 if (lba48)
283 SET_REG(ATA_NSECTOR, count >> 8);
284 SET_REG(ATA_NSECTOR, count & 0xff);
285 SET_REG(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */
286 SET_REG(ATA_SECTOR, start & 0xff); /* 7:0 */
287 SET_REG(ATA_LCYL, 0); /* 39:32 */
288 SET_REG(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */
289 SET_REG(ATA_HCYL, 0); /* 47:40 */
290 SET_REG(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */
291 SET_REG(ATA_SELECT, SELECT_LBA | ata_device);
292 SET_REG(ATA_COMMAND, CMD_READ_MULTIPLE_EXT);
294 else
295 #endif
297 SET_REG(ATA_NSECTOR, count & 0xff); /* 0 means 256 sectors */
298 SET_REG(ATA_SECTOR, start & 0xff);
299 SET_REG(ATA_LCYL, (start >> 8) & 0xff);
300 SET_REG(ATA_HCYL, (start >> 16) & 0xff);
301 SET_REG(ATA_SELECT, ((start >> 24) & 0xf) | SELECT_LBA | ata_device);
302 SET_REG(ATA_COMMAND, CMD_READ_MULTIPLE);
305 /* wait at least 400ns between writing command and reading status */
306 __asm__ volatile ("nop");
307 __asm__ volatile ("nop");
308 __asm__ volatile ("nop");
309 __asm__ volatile ("nop");
310 __asm__ volatile ("nop");
312 while (count) {
313 int sectors;
314 int wordcount;
315 int status;
317 if (!wait_for_start_of_transfer()) {
318 /* We have timed out waiting for RDY and/or DRQ, possibly
319 because the hard drive is shaking and has problems reading
320 the data. We have two options:
321 1) Wait some more
322 2) Perform a soft reset and try again.
324 We choose alternative 2.
326 perform_soft_reset();
327 ret = -4;
328 goto retry;
331 if (spinup) {
332 ata_spinup_time = current_tick - spinup_start;
333 spinup = false;
334 sleeping = false;
335 poweroff = false;
338 /* read the status register exactly once per loop */
339 status = ATA_STATUS;
341 if (count >= multisectors )
342 sectors = multisectors;
343 else
344 sectors = count;
346 wordcount = sectors * SECTOR_SIZE / 2;
348 copy_read_sectors(buf, wordcount);
351 "Device errors encountered during READ MULTIPLE commands are
352 posted at the beginning of the block or partial block transfer,
353 but the DRQ bit is still set to one and the data transfer shall
354 take place, including transfer of corrupted data, if any."
355 -- ATA specification
357 if ( status & (STATUS_BSY | STATUS_ERR | STATUS_DF) ) {
358 perform_soft_reset();
359 ret = -5;
360 goto retry;
363 buf += sectors * SECTOR_SIZE; /* Advance one chunk of sectors */
364 count -= sectors;
366 last_disk_activity = current_tick;
369 if(!ret && !wait_for_end_of_transfer()) {
370 perform_soft_reset();
371 ret = -3;
372 goto retry;
374 break;
376 ata_led(false);
378 #ifndef MAX_PHYS_SECTOR_SIZE
379 spinlock_unlock(&ata_mtx);
380 #endif
382 return ret;
385 #ifndef ATA_OPTIMIZED_WRITING
386 STATICIRAM void copy_write_sectors(const unsigned char* buf, int wordcount)
387 ICODE_ATTR;
388 STATICIRAM void copy_write_sectors(const unsigned char* buf, int wordcount)
390 if ( (unsigned long)buf & 1)
391 { /* not 16-bit aligned, copy byte by byte */
392 unsigned short tmp = 0;
393 const unsigned char* bufend = buf + wordcount*2;
396 #if defined(SWAP_WORDS) || defined(ROCKBOX_LITTLE_ENDIAN)
397 tmp = (unsigned short) *buf++;
398 tmp |= (unsigned short) *buf++ << 8;
399 SET_16BITREG(ATA_DATA, tmp);
400 #else
401 tmp = (unsigned short) *buf++ << 8;
402 tmp |= (unsigned short) *buf++;
403 SET_16BITREG(ATA_DATA, tmp);
404 #endif
405 } while (buf < bufend); /* tail loop is faster */
407 else
408 { /* 16-bit aligned, can do faster copy */
409 unsigned short* wbuf = (unsigned short*)buf;
410 unsigned short* wbufend = wbuf + wordcount;
413 #ifdef SWAP_WORDS
414 SET_16BITREG(ATA_DATA, swap16(*wbuf));
415 #else
416 SET_16BITREG(ATA_DATA, *wbuf);
417 #endif
418 } while (++wbuf < wbufend); /* tail loop is faster */
421 #endif /* !ATA_OPTIMIZED_WRITING */
423 #ifdef MAX_PHYS_SECTOR_SIZE
424 static int _write_sectors(unsigned long start,
425 int count,
426 const void* buf)
427 #else
428 int ata_write_sectors(IF_MV2(int drive,)
429 unsigned long start,
430 int count,
431 const void* buf)
432 #endif
434 int i;
435 int ret = 0;
436 long spinup_start;
438 if (start == 0)
439 panicf("Writing on sector 0\n");
441 #ifndef MAX_PHYS_SECTOR_SIZE
442 #ifdef HAVE_MULTIVOLUME
443 (void)drive; /* unused for now */
444 #endif
445 spinlock_lock(&ata_mtx);
446 #endif
448 last_disk_activity = current_tick;
449 spinup_start = current_tick;
451 ata_led(true);
453 if ( sleeping ) {
454 spinup = true;
455 if (poweroff) {
456 if (ata_power_on()) {
457 spinlock_unlock(&ata_mtx);
458 ata_led(false);
459 return -1;
462 else {
463 if (perform_soft_reset()) {
464 spinlock_unlock(&ata_mtx);
465 ata_led(false);
466 return -1;
471 SET_REG(ATA_SELECT, ata_device);
472 if (!wait_for_rdy())
474 spinlock_unlock(&ata_mtx);
475 ata_led(false);
476 return -2;
479 #ifdef HAVE_LBA48
480 if (lba48)
482 SET_REG(ATA_NSECTOR, count >> 8);
483 SET_REG(ATA_NSECTOR, count & 0xff);
484 SET_REG(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */
485 SET_REG(ATA_SECTOR, start & 0xff); /* 7:0 */
486 SET_REG(ATA_LCYL, 0); /* 39:32 */
487 SET_REG(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */
488 SET_REG(ATA_HCYL, 0); /* 47:40 */
489 SET_REG(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */
490 SET_REG(ATA_SELECT, SELECT_LBA | ata_device);
491 SET_REG(ATA_COMMAND, CMD_WRITE_SECTORS_EXT);
493 else
494 #endif
496 SET_REG(ATA_NSECTOR, count & 0xff); /* 0 means 256 sectors */
497 SET_REG(ATA_SECTOR, start & 0xff);
498 SET_REG(ATA_LCYL, (start >> 8) & 0xff);
499 SET_REG(ATA_HCYL, (start >> 16) & 0xff);
500 SET_REG(ATA_SELECT, ((start >> 24) & 0xf) | SELECT_LBA | ata_device);
501 SET_REG(ATA_COMMAND, CMD_WRITE_SECTORS);
504 for (i=0; i<count; i++) {
506 if (!wait_for_start_of_transfer()) {
507 ret = -3;
508 break;
511 if (spinup) {
512 ata_spinup_time = current_tick - spinup_start;
513 spinup = false;
514 sleeping = false;
515 poweroff = false;
518 copy_write_sectors(buf, SECTOR_SIZE/2);
520 #ifdef USE_INTERRUPT
521 /* reading the status register clears the interrupt */
522 j = ATA_STATUS;
523 #endif
524 buf += SECTOR_SIZE;
526 last_disk_activity = current_tick;
529 if(!ret && !wait_for_end_of_transfer()) {
530 DEBUGF("End on transfer failed. -- jyp");
531 ret = -4;
534 ata_led(false);
536 #ifndef MAX_PHYS_SECTOR_SIZE
537 spinlock_unlock(&ata_mtx);
538 #endif
540 return ret;
543 #ifdef MAX_PHYS_SECTOR_SIZE
544 static int cache_sector(unsigned long sector)
546 int rc;
548 sector &= ~(phys_sector_mult - 1);
549 /* round down to physical sector boundary */
551 /* check whether the sector is already cached */
552 if (sector_cache.inuse && (sector_cache.sectornum == sector))
553 return 0;
555 /* not found: read the sector */
556 sector_cache.inuse = false;
557 rc = _read_sectors(sector, phys_sector_mult, sector_cache.data);
558 if (!rc)
560 sector_cache.sectornum = sector;
561 sector_cache.inuse = true;
563 return rc;
566 static inline int flush_current_sector(void)
568 return _write_sectors(sector_cache.sectornum, phys_sector_mult,
569 sector_cache.data);
572 int ata_read_sectors(IF_MV2(int drive,)
573 unsigned long start,
574 int incount,
575 void* inbuf)
577 int rc = 0;
578 int offset;
580 #ifdef HAVE_MULTIVOLUME
581 (void)drive; /* unused for now */
582 #endif
583 spinlock_lock(&ata_mtx);
585 offset = start & (phys_sector_mult - 1);
587 if (offset) /* first partial sector */
589 int partcount = MIN(incount, phys_sector_mult - offset);
591 rc = cache_sector(start);
592 if (rc)
594 rc = rc * 10 - 1;
595 goto error;
597 memcpy(inbuf, sector_cache.data + offset * SECTOR_SIZE,
598 partcount * SECTOR_SIZE);
600 start += partcount;
601 inbuf += partcount * SECTOR_SIZE;
602 incount -= partcount;
604 if (incount)
606 offset = incount & (phys_sector_mult - 1);
607 incount -= offset;
609 if (incount)
611 rc = _read_sectors(start, incount, inbuf);
612 if (rc)
614 rc = rc * 10 - 2;
615 goto error;
617 start += incount;
618 inbuf += incount * SECTOR_SIZE;
620 if (offset)
622 rc = cache_sector(start);
623 if (rc)
625 rc = rc * 10 - 3;
626 goto error;
628 memcpy(inbuf, sector_cache.data, offset * SECTOR_SIZE);
632 error:
633 spinlock_unlock(&ata_mtx);
635 return rc;
638 int ata_write_sectors(IF_MV2(int drive,)
639 unsigned long start,
640 int count,
641 const void* buf)
643 int rc = 0;
644 int offset;
646 #ifdef HAVE_MULTIVOLUME
647 (void)drive; /* unused for now */
648 #endif
649 spinlock_lock(&ata_mtx);
651 offset = start & (phys_sector_mult - 1);
653 if (offset) /* first partial sector */
655 int partcount = MIN(count, phys_sector_mult - offset);
657 rc = cache_sector(start);
658 if (rc)
660 rc = rc * 10 - 1;
661 goto error;
663 memcpy(sector_cache.data + offset * SECTOR_SIZE, buf,
664 partcount * SECTOR_SIZE);
665 rc = flush_current_sector();
666 if (rc)
668 rc = rc * 10 - 2;
669 goto error;
671 start += partcount;
672 buf += partcount * SECTOR_SIZE;
673 count -= partcount;
675 if (count)
677 offset = count & (phys_sector_mult - 1);
678 count -= offset;
680 if (count)
682 rc = _write_sectors(start, count, buf);
683 if (rc)
685 rc = rc * 10 - 3;
686 goto error;
688 start += count;
689 buf += count * SECTOR_SIZE;
691 if (offset)
693 rc = cache_sector(start);
694 if (rc)
696 rc = rc * 10 - 4;
697 goto error;
699 memcpy(sector_cache.data, buf, offset * SECTOR_SIZE);
700 rc = flush_current_sector();
701 if (rc)
703 rc = rc * 10 - 5;
704 goto error;
709 error:
710 spinlock_unlock(&ata_mtx);
712 return rc;
714 #endif /* MAX_PHYS_SECTOR_SIZE */
716 static int check_registers(void)
718 int i;
719 if ( ATA_STATUS & STATUS_BSY )
720 return -1;
722 for (i = 0; i<64; i++) {
723 SET_REG(ATA_NSECTOR, WRITE_PATTERN1);
724 SET_REG(ATA_SECTOR, WRITE_PATTERN2);
725 SET_REG(ATA_LCYL, WRITE_PATTERN3);
726 SET_REG(ATA_HCYL, WRITE_PATTERN4);
728 if (((ATA_NSECTOR & READ_PATTERN1_MASK) == READ_PATTERN1) &&
729 ((ATA_SECTOR & READ_PATTERN2_MASK) == READ_PATTERN2) &&
730 ((ATA_LCYL & READ_PATTERN3_MASK) == READ_PATTERN3) &&
731 ((ATA_HCYL & READ_PATTERN4_MASK) == READ_PATTERN4))
732 return 0;
734 return -2;
737 static int freeze_lock(void)
739 /* does the disk support Security Mode feature set? */
740 if (identify_info[82] & 2)
742 SET_REG(ATA_SELECT, ata_device);
744 if (!wait_for_rdy())
745 return -1;
747 SET_REG(ATA_COMMAND, CMD_SECURITY_FREEZE_LOCK);
749 if (!wait_for_rdy())
750 return -2;
753 return 0;
756 void ata_spindown(int seconds)
758 sleep_timeout = seconds * HZ;
761 bool ata_disk_is_active(void)
763 return !sleeping;
766 static int ata_perform_sleep(void)
768 int ret = 0;
770 spinlock_lock(&ata_mtx);
772 SET_REG(ATA_SELECT, ata_device);
774 if(!wait_for_rdy()) {
775 DEBUGF("ata_perform_sleep() - not RDY\n");
776 spinlock_unlock(&ata_mtx);
777 return -1;
780 SET_REG(ATA_COMMAND, CMD_SLEEP);
782 if (!wait_for_rdy())
784 DEBUGF("ata_perform_sleep() - CMD failed\n");
785 ret = -2;
788 sleeping = true;
789 spinlock_unlock(&ata_mtx);
790 return ret;
793 void ata_sleep(void)
795 queue_post(&ata_queue, Q_SLEEP, 0);
798 void ata_sleepnow(void)
800 if (!spinup && !sleeping && !ata_mtx.locked && initialized)
802 call_ata_idle_notifys(false);
803 ata_perform_sleep();
807 void ata_spin(void)
809 last_user_activity = current_tick;
812 static void ata_thread(void)
814 static long last_sleep = 0;
815 struct event ev;
816 static long last_seen_mtx_unlock = 0;
818 while (1) {
819 while ( queue_empty( &ata_queue ) ) {
820 if (!spinup && !sleeping)
822 if (!ata_mtx.locked)
824 if (!last_seen_mtx_unlock)
825 last_seen_mtx_unlock = current_tick;
826 if (TIME_AFTER(current_tick, last_seen_mtx_unlock+(HZ*2)))
828 call_ata_idle_notifys(false);
829 last_seen_mtx_unlock = 0;
832 if ( sleep_timeout &&
833 TIME_AFTER( current_tick,
834 last_user_activity + sleep_timeout ) &&
835 TIME_AFTER( current_tick,
836 last_disk_activity + sleep_timeout ) )
838 call_ata_idle_notifys(true);
839 ata_perform_sleep();
840 last_sleep = current_tick;
843 #ifdef HAVE_ATA_POWER_OFF
844 if ( !spinup && sleeping && !poweroff &&
845 TIME_AFTER( current_tick, last_sleep + ATA_POWER_OFF_TIMEOUT ))
847 spinlock_lock(&ata_mtx);
848 ide_power_enable(false);
849 spinlock_unlock(&ata_mtx);
850 poweroff = true;
852 #endif
854 sleep(HZ/4);
856 queue_wait(&ata_queue, &ev);
857 switch ( ev.id ) {
858 #ifndef USB_NONE
859 case SYS_USB_CONNECTED:
860 if (poweroff) {
861 spinlock_lock(&ata_mtx);
862 ata_led(true);
863 ata_power_on();
864 ata_led(false);
865 spinlock_unlock(&ata_mtx);
868 /* Tell the USB thread that we are safe */
869 DEBUGF("ata_thread got SYS_USB_CONNECTED\n");
870 usb_acknowledge(SYS_USB_CONNECTED_ACK);
872 /* Wait until the USB cable is extracted again */
873 usb_wait_for_disconnect(&ata_queue);
874 break;
875 #endif
876 case Q_SLEEP:
877 call_ata_idle_notifys(false);
878 last_disk_activity = current_tick - sleep_timeout + (HZ/2);
879 break;
884 /* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
885 int ata_hard_reset(void)
887 int ret;
889 ata_reset();
891 /* state HRR2 */
892 SET_REG(ATA_SELECT, ata_device); /* select the right device */
893 ret = wait_for_bsy();
895 /* Massage the return code so it is 0 on success and -1 on failure */
896 ret = ret?0:-1;
898 return ret;
901 static int perform_soft_reset(void)
903 /* If this code is allowed to run on a Nano, the next reads from the flash will
904 * time out, so we disable it. It shouldn't be necessary anyway, since the
905 * ATA -> Flash interface automatically sleeps almost immediately after the
906 * last command.
908 #ifndef IPOD_NANO
909 int ret;
910 int retry_count;
912 SET_REG(ATA_SELECT, SELECT_LBA | ata_device );
913 SET_REG(ATA_CONTROL, CONTROL_nIEN|CONTROL_SRST );
914 sleep(1); /* >= 5us */
916 SET_REG(ATA_CONTROL, CONTROL_nIEN);
917 sleep(1); /* >2ms */
919 /* This little sucker can take up to 30 seconds */
920 retry_count = 8;
923 ret = wait_for_rdy();
924 } while(!ret && retry_count--);
926 /* Massage the return code so it is 0 on success and -1 on failure */
927 ret = ret?0:-1;
929 return ret;
930 #else
931 return 0; /* Always report success */
932 #endif
935 int ata_soft_reset(void)
937 int ret;
939 spinlock_lock(&ata_mtx);
941 ret = perform_soft_reset();
943 spinlock_unlock(&ata_mtx);
944 return ret;
947 static int ata_power_on(void)
949 int rc;
951 ide_power_enable(true);
952 if( ata_hard_reset() )
953 return -1;
955 rc = set_features();
956 if (rc)
957 return rc * 10 - 2;
959 if (set_multiple_mode(multisectors))
960 return -3;
962 if (freeze_lock())
963 return -4;
965 return 0;
968 static int master_slave_detect(void)
970 /* master? */
971 SET_REG(ATA_SELECT, 0);
972 if ( ATA_STATUS & (STATUS_RDY|STATUS_BSY) ) {
973 ata_device = 0;
974 DEBUGF("Found master harddisk\n");
976 else {
977 /* slave? */
978 SET_REG(ATA_SELECT, SELECT_DEVICE1);
979 if ( ATA_STATUS & (STATUS_RDY|STATUS_BSY) ) {
980 ata_device = SELECT_DEVICE1;
981 DEBUGF("Found slave harddisk\n");
983 else
984 return -1;
986 return 0;
989 static int identify(void)
991 int i;
993 SET_REG(ATA_SELECT, ata_device);
995 if(!wait_for_rdy()) {
996 DEBUGF("identify() - not RDY\n");
997 return -1;
999 SET_REG(ATA_COMMAND, CMD_IDENTIFY);
1001 if (!wait_for_start_of_transfer())
1003 DEBUGF("identify() - CMD failed\n");
1004 return -2;
1007 for (i=0; i<SECTOR_SIZE/2; i++) {
1008 /* the IDENTIFY words are already swapped, so we need to treat
1009 this info differently that normal sector data */
1010 #if defined(ROCKBOX_BIG_ENDIAN) && !defined(SWAP_WORDS)
1011 identify_info[i] = swap16(ATA_DATA);
1012 #else
1013 identify_info[i] = ATA_DATA;
1014 #endif
1017 return 0;
1020 static int set_multiple_mode(int sectors)
1022 SET_REG(ATA_SELECT, ata_device);
1024 if(!wait_for_rdy()) {
1025 DEBUGF("set_multiple_mode() - not RDY\n");
1026 return -1;
1029 SET_REG(ATA_NSECTOR, sectors);
1030 SET_REG(ATA_COMMAND, CMD_SET_MULTIPLE_MODE);
1032 if (!wait_for_rdy())
1034 DEBUGF("set_multiple_mode() - CMD failed\n");
1035 return -2;
1038 return 0;
1041 static int set_features(void)
1043 static struct {
1044 unsigned char id_word;
1045 unsigned char id_bit;
1046 unsigned char subcommand;
1047 unsigned char parameter;
1048 } features[] = {
1049 { 83, 3, 0x05, 0x80 }, /* power management: lowest power without standby */
1050 { 83, 9, 0x42, 0x80 }, /* acoustic management: lowest noise */
1051 { 82, 6, 0xaa, 0 }, /* enable read look-ahead */
1052 { 83, 14, 0x03, 0 }, /* force PIO mode */
1054 int i;
1055 int pio_mode = 2;
1057 /* Find out the highest supported PIO mode */
1058 if(identify_info[64] & 2)
1059 pio_mode = 4;
1060 else
1061 if(identify_info[64] & 1)
1062 pio_mode = 3;
1064 /* Update the table */
1065 features[3].parameter = 8 + pio_mode;
1067 SET_REG(ATA_SELECT, ata_device);
1069 if (!wait_for_rdy()) {
1070 DEBUGF("set_features() - not RDY\n");
1071 return -1;
1074 for (i=0; i < (int)(sizeof(features)/sizeof(features[0])); i++) {
1075 if (identify_info[features[i].id_word] & (1 << features[i].id_bit)) {
1076 SET_REG(ATA_FEATURE, features[i].subcommand);
1077 SET_REG(ATA_NSECTOR, features[i].parameter);
1078 SET_REG(ATA_COMMAND, CMD_SET_FEATURES);
1080 if (!wait_for_rdy()) {
1081 DEBUGF("set_features() - CMD failed\n");
1082 return -10 - i;
1085 if(ATA_ALT_STATUS & STATUS_ERR) {
1086 if(ATA_ERROR & ERROR_ABRT) {
1087 return -20 - i;
1093 return 0;
1096 unsigned short* ata_get_identify(void)
1098 return identify_info;
1101 static int init_and_check(bool hard_reset)
1103 int rc;
1105 if (hard_reset)
1107 /* This should reset both master and slave, we don't yet know what's in */
1108 ata_device = 0;
1109 if (ata_hard_reset())
1110 return -1;
1113 rc = master_slave_detect();
1114 if (rc)
1115 return -10 + rc;
1117 /* symptom fix: else check_registers() below may fail */
1118 if (hard_reset && !wait_for_bsy())
1119 return -20;
1121 rc = check_registers();
1122 if (rc)
1123 return -30 + rc;
1125 return 0;
1128 int ata_init(void)
1130 int rc;
1131 bool coldstart = ata_is_coldstart();
1132 /* must be called before ata_device_init() */
1134 spinlock_init(&ata_mtx);
1136 ata_led(false);
1137 ata_device_init();
1138 sleeping = false;
1139 ata_enable(true);
1140 #ifdef MAX_PHYS_SECTOR_SIZE
1141 memset(&sector_cache, 0, sizeof(sector_cache));
1142 #endif
1144 if ( !initialized ) {
1145 if (!ide_powered()) /* somebody has switched it off */
1147 ide_power_enable(true);
1148 sleep(HZ); /* allow voltage to build up */
1151 /* first try, hard reset at cold start only */
1152 rc = init_and_check(coldstart);
1154 if (rc)
1155 { /* failed? -> second try, always with hard reset */
1156 DEBUGF("ata: init failed, retrying...\n");
1157 rc = init_and_check(true);
1158 if (rc)
1159 return rc;
1162 rc = identify();
1164 if (rc)
1165 return -40 + rc;
1167 multisectors = identify_info[47] & 0xff;
1168 if (multisectors == 0) /* Invalid multisector info, try with 16 */
1169 multisectors = 16;
1171 DEBUGF("ata: %d sectors per ata request\n",multisectors);
1173 #ifdef MAX_PHYS_SECTOR_SIZE
1174 /* Find out the physical sector size */
1175 if((identify_info[106] & 0xe000) == 0x6000)
1176 phys_sector_mult = 1 << (identify_info[106] & 0x000f);
1177 else
1178 phys_sector_mult = 1;
1180 DEBUGF("ata: %d logical sectors per phys sector", phys_sector_mult);
1182 if (phys_sector_mult > (MAX_PHYS_SECTOR_SIZE/SECTOR_SIZE))
1183 panicf("Unsupported physical sector size: %d",
1184 phys_sector_mult * SECTOR_SIZE);
1185 #endif
1187 #ifdef HAVE_LBA48
1188 if (identify_info[83] & 0x0400 /* 48 bit address support */
1189 && identify_info[60] == 0xFFFF /* and disk size >= 128 GiB */
1190 && identify_info[61] == 0x0FFF) /* (needs BigLBA addressing) */
1192 lba48 = true; /* use BigLBA */
1194 #endif
1195 rc = freeze_lock();
1197 if (rc)
1198 return -50 + rc;
1200 rc = set_features();
1201 if (rc)
1202 return -60 + rc;
1204 queue_init(&ata_queue, true);
1206 last_disk_activity = current_tick;
1207 create_thread(ata_thread, ata_stack,
1208 sizeof(ata_stack), ata_thread_name
1209 IF_PRIO(, PRIORITY_SYSTEM)
1210 IF_COP(, CPU, false));
1211 initialized = true;
1214 rc = set_multiple_mode(multisectors);
1215 if (rc)
1216 return -70 + rc;
1218 return 0;
1221 #if (CONFIG_LED == LED_REAL)
1222 void ata_set_led_enabled(bool enabled)
1224 ata_led_enabled = enabled;
1225 if (ata_led_enabled)
1226 led(ata_led_on);
1227 else
1228 led(false);
1230 #endif