Remove sector 0 write protection from the ATA and MMC drivers. The one in the ATA...
[Rockbox.git] / firmware / drivers / ata.c
blob549a7bf920dd85978e3e3f9ed5936ba5d11cea9d
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 NOCACHEBSS_ATTR;
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/2];
95 #ifdef MAX_PHYS_SECTOR_SIZE
97 /** This is temporary **/
98 /* Define the mutex functions to use the special hack object */
99 #define mutex_init ata_spin_init
100 #define mutex_lock ata_spin_lock
101 #define mutex_unlock ata_spin_unlock
103 void ata_spin_init(struct mutex *m)
105 m->thread = NULL;
106 m->locked = 0;
107 m->count = 0;
108 #if CONFIG_CORELOCK == SW_CORELOCK
109 corelock_init(&m->cl);
110 #endif
113 void ata_spin_lock(struct mutex *m)
115 struct thread_entry *current = thread_get_current();
117 if (current == m->thread)
119 m->count++;
120 return;
123 while (test_and_set(&m->locked, 1, &m->cl))
124 yield();
126 m->thread = current;
129 void ata_spin_unlock(struct mutex *m)
131 if (m->count > 0)
133 m->count--;
134 return;
137 m->thread = NULL;
138 test_and_set(&m->locked, 0, &m->cl);
141 /****/
143 struct sector_cache_entry {
144 bool inuse;
145 unsigned long sectornum; /* logical sector */
146 unsigned char data[MAX_PHYS_SECTOR_SIZE];
148 /* buffer for reading and writing large physical sectors */
149 #define NUMCACHES 2
150 static struct sector_cache_entry sector_cache;
151 static int phys_sector_mult = 1;
152 #endif
154 static int ata_power_on(void);
155 static int perform_soft_reset(void);
156 static int set_multiple_mode(int sectors);
157 static int set_features(void);
159 STATICIRAM int wait_for_bsy(void) ICODE_ATTR;
160 STATICIRAM int wait_for_bsy(void)
162 long timeout = current_tick + HZ*30;
163 while (TIME_BEFORE(current_tick, timeout) && (ATA_STATUS & STATUS_BSY)) {
164 last_disk_activity = current_tick;
165 priority_yield();
168 if (TIME_BEFORE(current_tick, timeout))
169 return 1;
170 else
171 return 0; /* timeout */
174 STATICIRAM int wait_for_rdy(void) ICODE_ATTR;
175 STATICIRAM int wait_for_rdy(void)
177 long timeout;
179 if (!wait_for_bsy())
180 return 0;
182 timeout = current_tick + HZ*10;
184 while (TIME_BEFORE(current_tick, timeout) &&
185 !(ATA_ALT_STATUS & STATUS_RDY)) {
186 last_disk_activity = current_tick;
187 priority_yield();
190 if (TIME_BEFORE(current_tick, timeout))
191 return STATUS_RDY;
192 else
193 return 0; /* timeout */
196 STATICIRAM int wait_for_start_of_transfer(void) ICODE_ATTR;
197 STATICIRAM int wait_for_start_of_transfer(void)
199 if (!wait_for_bsy())
200 return 0;
202 return (ATA_ALT_STATUS & (STATUS_BSY|STATUS_DRQ)) == STATUS_DRQ;
205 STATICIRAM int wait_for_end_of_transfer(void) ICODE_ATTR;
206 STATICIRAM int wait_for_end_of_transfer(void)
208 if (!wait_for_bsy())
209 return 0;
210 return (ATA_ALT_STATUS & (STATUS_RDY|STATUS_DRQ)) == STATUS_RDY;
213 #if (CONFIG_LED == LED_REAL)
214 /* Conditionally block LED access for the ATA driver, so the LED can be
215 * (mis)used for other purposes */
216 static void ata_led(bool on)
218 ata_led_on = on;
219 if (ata_led_enabled)
220 led(ata_led_on);
222 #else
223 #define ata_led(on) led(on)
224 #endif
226 #ifndef ATA_OPTIMIZED_READING
227 STATICIRAM void copy_read_sectors(unsigned char* buf, int wordcount) ICODE_ATTR;
228 STATICIRAM void copy_read_sectors(unsigned char* buf, int wordcount)
230 unsigned short tmp = 0;
232 if ( (unsigned long)buf & 1)
233 { /* not 16-bit aligned, copy byte by byte */
234 unsigned char* bufend = buf + wordcount*2;
237 tmp = ATA_DATA;
238 #if defined(SWAP_WORDS) || defined(ROCKBOX_LITTLE_ENDIAN)
239 *buf++ = tmp & 0xff; /* I assume big endian */
240 *buf++ = tmp >> 8; /* and don't use the SWAB16 macro */
241 #else
242 *buf++ = tmp >> 8;
243 *buf++ = tmp & 0xff;
244 #endif
245 } while (buf < bufend); /* tail loop is faster */
247 else
248 { /* 16-bit aligned, can do faster copy */
249 unsigned short* wbuf = (unsigned short*)buf;
250 unsigned short* wbufend = wbuf + wordcount;
253 #ifdef SWAP_WORDS
254 *wbuf = swap16(ATA_DATA);
255 #else
256 *wbuf = ATA_DATA;
257 #endif
258 } while (++wbuf < wbufend); /* tail loop is faster */
261 #endif /* !ATA_OPTIMIZED_READING */
263 #ifdef MAX_PHYS_SECTOR_SIZE
264 static int _read_sectors(unsigned long start,
265 int incount,
266 void* inbuf)
267 #else
268 int ata_read_sectors(IF_MV2(int drive,)
269 unsigned long start,
270 int incount,
271 void* inbuf)
272 #endif
274 int ret = 0;
275 long timeout;
276 int count;
277 void* buf;
278 long spinup_start;
280 #ifndef MAX_PHYS_SECTOR_SIZE
281 #ifdef HAVE_MULTIVOLUME
282 (void)drive; /* unused for now */
283 #endif
284 mutex_lock(&ata_mtx);
285 #endif
287 last_disk_activity = current_tick;
288 spinup_start = current_tick;
290 ata_led(true);
292 if ( sleeping ) {
293 spinup = true;
294 if (poweroff) {
295 if (ata_power_on()) {
296 mutex_unlock(&ata_mtx);
297 ata_led(false);
298 return -1;
301 else {
302 if (perform_soft_reset()) {
303 mutex_unlock(&ata_mtx);
304 ata_led(false);
305 return -1;
310 timeout = current_tick + READ_TIMEOUT;
312 SET_REG(ATA_SELECT, ata_device);
313 if (!wait_for_rdy())
315 mutex_unlock(&ata_mtx);
316 ata_led(false);
317 return -2;
320 retry:
321 buf = inbuf;
322 count = incount;
323 while (TIME_BEFORE(current_tick, timeout)) {
324 ret = 0;
325 last_disk_activity = current_tick;
327 #ifdef HAVE_LBA48
328 if (lba48)
330 SET_REG(ATA_NSECTOR, count >> 8);
331 SET_REG(ATA_NSECTOR, count & 0xff);
332 SET_REG(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */
333 SET_REG(ATA_SECTOR, start & 0xff); /* 7:0 */
334 SET_REG(ATA_LCYL, 0); /* 39:32 */
335 SET_REG(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */
336 SET_REG(ATA_HCYL, 0); /* 47:40 */
337 SET_REG(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */
338 SET_REG(ATA_SELECT, SELECT_LBA | ata_device);
339 SET_REG(ATA_COMMAND, CMD_READ_MULTIPLE_EXT);
341 else
342 #endif
344 SET_REG(ATA_NSECTOR, count & 0xff); /* 0 means 256 sectors */
345 SET_REG(ATA_SECTOR, start & 0xff);
346 SET_REG(ATA_LCYL, (start >> 8) & 0xff);
347 SET_REG(ATA_HCYL, (start >> 16) & 0xff);
348 SET_REG(ATA_SELECT, ((start >> 24) & 0xf) | SELECT_LBA | ata_device);
349 SET_REG(ATA_COMMAND, CMD_READ_MULTIPLE);
352 /* wait at least 400ns between writing command and reading status */
353 __asm__ volatile ("nop");
354 __asm__ volatile ("nop");
355 __asm__ volatile ("nop");
356 __asm__ volatile ("nop");
357 __asm__ volatile ("nop");
359 while (count) {
360 int sectors;
361 int wordcount;
362 int status;
364 if (!wait_for_start_of_transfer()) {
365 /* We have timed out waiting for RDY and/or DRQ, possibly
366 because the hard drive is shaking and has problems reading
367 the data. We have two options:
368 1) Wait some more
369 2) Perform a soft reset and try again.
371 We choose alternative 2.
373 perform_soft_reset();
374 ret = -4;
375 goto retry;
378 if (spinup) {
379 ata_spinup_time = current_tick - spinup_start;
380 spinup = false;
381 sleeping = false;
382 poweroff = false;
385 /* read the status register exactly once per loop */
386 status = ATA_STATUS;
388 if (count >= multisectors )
389 sectors = multisectors;
390 else
391 sectors = count;
393 wordcount = sectors * SECTOR_SIZE / 2;
395 copy_read_sectors(buf, wordcount);
398 "Device errors encountered during READ MULTIPLE commands are
399 posted at the beginning of the block or partial block transfer,
400 but the DRQ bit is still set to one and the data transfer shall
401 take place, including transfer of corrupted data, if any."
402 -- ATA specification
404 if ( status & (STATUS_BSY | STATUS_ERR | STATUS_DF) ) {
405 perform_soft_reset();
406 ret = -5;
407 goto retry;
410 buf += sectors * SECTOR_SIZE; /* Advance one chunk of sectors */
411 count -= sectors;
413 last_disk_activity = current_tick;
416 if(!ret && !wait_for_end_of_transfer()) {
417 perform_soft_reset();
418 ret = -3;
419 goto retry;
421 break;
423 ata_led(false);
425 #ifndef MAX_PHYS_SECTOR_SIZE
426 mutex_unlock(&ata_mtx);
427 #endif
429 return ret;
432 #ifndef ATA_OPTIMIZED_WRITING
433 STATICIRAM void copy_write_sectors(const unsigned char* buf, int wordcount)
434 ICODE_ATTR;
435 STATICIRAM void copy_write_sectors(const unsigned char* buf, int wordcount)
437 if ( (unsigned long)buf & 1)
438 { /* not 16-bit aligned, copy byte by byte */
439 unsigned short tmp = 0;
440 const unsigned char* bufend = buf + wordcount*2;
443 #if defined(SWAP_WORDS) || defined(ROCKBOX_LITTLE_ENDIAN)
444 tmp = (unsigned short) *buf++;
445 tmp |= (unsigned short) *buf++ << 8;
446 SET_16BITREG(ATA_DATA, tmp);
447 #else
448 tmp = (unsigned short) *buf++ << 8;
449 tmp |= (unsigned short) *buf++;
450 SET_16BITREG(ATA_DATA, tmp);
451 #endif
452 } while (buf < bufend); /* tail loop is faster */
454 else
455 { /* 16-bit aligned, can do faster copy */
456 unsigned short* wbuf = (unsigned short*)buf;
457 unsigned short* wbufend = wbuf + wordcount;
460 #ifdef SWAP_WORDS
461 SET_16BITREG(ATA_DATA, swap16(*wbuf));
462 #else
463 SET_16BITREG(ATA_DATA, *wbuf);
464 #endif
465 } while (++wbuf < wbufend); /* tail loop is faster */
468 #endif /* !ATA_OPTIMIZED_WRITING */
470 #ifdef MAX_PHYS_SECTOR_SIZE
471 static int _write_sectors(unsigned long start,
472 int count,
473 const void* buf)
474 #else
475 int ata_write_sectors(IF_MV2(int drive,)
476 unsigned long start,
477 int count,
478 const void* buf)
479 #endif
481 int i;
482 int ret = 0;
483 long spinup_start;
485 #ifndef MAX_PHYS_SECTOR_SIZE
486 #ifdef HAVE_MULTIVOLUME
487 (void)drive; /* unused for now */
488 #endif
489 mutex_lock(&ata_mtx);
490 #endif
492 last_disk_activity = current_tick;
493 spinup_start = current_tick;
495 ata_led(true);
497 if ( sleeping ) {
498 spinup = true;
499 if (poweroff) {
500 if (ata_power_on()) {
501 mutex_unlock(&ata_mtx);
502 ata_led(false);
503 return -1;
506 else {
507 if (perform_soft_reset()) {
508 mutex_unlock(&ata_mtx);
509 ata_led(false);
510 return -1;
515 SET_REG(ATA_SELECT, ata_device);
516 if (!wait_for_rdy())
518 mutex_unlock(&ata_mtx);
519 ata_led(false);
520 return -2;
523 #ifdef HAVE_LBA48
524 if (lba48)
526 SET_REG(ATA_NSECTOR, count >> 8);
527 SET_REG(ATA_NSECTOR, count & 0xff);
528 SET_REG(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */
529 SET_REG(ATA_SECTOR, start & 0xff); /* 7:0 */
530 SET_REG(ATA_LCYL, 0); /* 39:32 */
531 SET_REG(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */
532 SET_REG(ATA_HCYL, 0); /* 47:40 */
533 SET_REG(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */
534 SET_REG(ATA_SELECT, SELECT_LBA | ata_device);
535 SET_REG(ATA_COMMAND, CMD_WRITE_SECTORS_EXT);
537 else
538 #endif
540 SET_REG(ATA_NSECTOR, count & 0xff); /* 0 means 256 sectors */
541 SET_REG(ATA_SECTOR, start & 0xff);
542 SET_REG(ATA_LCYL, (start >> 8) & 0xff);
543 SET_REG(ATA_HCYL, (start >> 16) & 0xff);
544 SET_REG(ATA_SELECT, ((start >> 24) & 0xf) | SELECT_LBA | ata_device);
545 SET_REG(ATA_COMMAND, CMD_WRITE_SECTORS);
548 for (i=0; i<count; i++) {
550 if (!wait_for_start_of_transfer()) {
551 ret = -3;
552 break;
555 if (spinup) {
556 ata_spinup_time = current_tick - spinup_start;
557 spinup = false;
558 sleeping = false;
559 poweroff = false;
562 copy_write_sectors(buf, SECTOR_SIZE/2);
564 #ifdef USE_INTERRUPT
565 /* reading the status register clears the interrupt */
566 j = ATA_STATUS;
567 #endif
568 buf += SECTOR_SIZE;
570 last_disk_activity = current_tick;
573 if(!ret && !wait_for_end_of_transfer()) {
574 DEBUGF("End on transfer failed. -- jyp");
575 ret = -4;
578 ata_led(false);
580 #ifndef MAX_PHYS_SECTOR_SIZE
581 mutex_unlock(&ata_mtx);
582 #endif
584 return ret;
587 #ifdef MAX_PHYS_SECTOR_SIZE
588 static int cache_sector(unsigned long sector)
590 int rc;
592 sector &= ~(phys_sector_mult - 1);
593 /* round down to physical sector boundary */
595 /* check whether the sector is already cached */
596 if (sector_cache.inuse && (sector_cache.sectornum == sector))
597 return 0;
599 /* not found: read the sector */
600 sector_cache.inuse = false;
601 rc = _read_sectors(sector, phys_sector_mult, sector_cache.data);
602 if (!rc)
604 sector_cache.sectornum = sector;
605 sector_cache.inuse = true;
607 return rc;
610 static inline int flush_current_sector(void)
612 return _write_sectors(sector_cache.sectornum, phys_sector_mult,
613 sector_cache.data);
616 int ata_read_sectors(IF_MV2(int drive,)
617 unsigned long start,
618 int incount,
619 void* inbuf)
621 int rc = 0;
622 int offset;
624 #ifdef HAVE_MULTIVOLUME
625 (void)drive; /* unused for now */
626 #endif
627 mutex_lock(&ata_mtx);
629 offset = start & (phys_sector_mult - 1);
631 if (offset) /* first partial sector */
633 int partcount = MIN(incount, phys_sector_mult - offset);
635 rc = cache_sector(start);
636 if (rc)
638 rc = rc * 10 - 1;
639 goto error;
641 memcpy(inbuf, sector_cache.data + offset * SECTOR_SIZE,
642 partcount * SECTOR_SIZE);
644 start += partcount;
645 inbuf += partcount * SECTOR_SIZE;
646 incount -= partcount;
648 if (incount)
650 offset = incount & (phys_sector_mult - 1);
651 incount -= offset;
653 if (incount)
655 rc = _read_sectors(start, incount, inbuf);
656 if (rc)
658 rc = rc * 10 - 2;
659 goto error;
661 start += incount;
662 inbuf += incount * SECTOR_SIZE;
664 if (offset)
666 rc = cache_sector(start);
667 if (rc)
669 rc = rc * 10 - 3;
670 goto error;
672 memcpy(inbuf, sector_cache.data, offset * SECTOR_SIZE);
676 error:
677 mutex_unlock(&ata_mtx);
679 return rc;
682 int ata_write_sectors(IF_MV2(int drive,)
683 unsigned long start,
684 int count,
685 const void* buf)
687 int rc = 0;
688 int offset;
690 #ifdef HAVE_MULTIVOLUME
691 (void)drive; /* unused for now */
692 #endif
693 mutex_lock(&ata_mtx);
695 offset = start & (phys_sector_mult - 1);
697 if (offset) /* first partial sector */
699 int partcount = MIN(count, phys_sector_mult - offset);
701 rc = cache_sector(start);
702 if (rc)
704 rc = rc * 10 - 1;
705 goto error;
707 memcpy(sector_cache.data + offset * SECTOR_SIZE, buf,
708 partcount * SECTOR_SIZE);
709 rc = flush_current_sector();
710 if (rc)
712 rc = rc * 10 - 2;
713 goto error;
715 start += partcount;
716 buf += partcount * SECTOR_SIZE;
717 count -= partcount;
719 if (count)
721 offset = count & (phys_sector_mult - 1);
722 count -= offset;
724 if (count)
726 rc = _write_sectors(start, count, buf);
727 if (rc)
729 rc = rc * 10 - 3;
730 goto error;
732 start += count;
733 buf += count * SECTOR_SIZE;
735 if (offset)
737 rc = cache_sector(start);
738 if (rc)
740 rc = rc * 10 - 4;
741 goto error;
743 memcpy(sector_cache.data, buf, offset * SECTOR_SIZE);
744 rc = flush_current_sector();
745 if (rc)
747 rc = rc * 10 - 5;
748 goto error;
753 error:
754 mutex_unlock(&ata_mtx);
756 return rc;
758 #endif /* MAX_PHYS_SECTOR_SIZE */
760 static int check_registers(void)
762 int i;
763 if ( ATA_STATUS & STATUS_BSY )
764 return -1;
766 for (i = 0; i<64; i++) {
767 SET_REG(ATA_NSECTOR, WRITE_PATTERN1);
768 SET_REG(ATA_SECTOR, WRITE_PATTERN2);
769 SET_REG(ATA_LCYL, WRITE_PATTERN3);
770 SET_REG(ATA_HCYL, WRITE_PATTERN4);
772 if (((ATA_NSECTOR & READ_PATTERN1_MASK) == READ_PATTERN1) &&
773 ((ATA_SECTOR & READ_PATTERN2_MASK) == READ_PATTERN2) &&
774 ((ATA_LCYL & READ_PATTERN3_MASK) == READ_PATTERN3) &&
775 ((ATA_HCYL & READ_PATTERN4_MASK) == READ_PATTERN4))
776 return 0;
778 return -2;
781 static int freeze_lock(void)
783 /* does the disk support Security Mode feature set? */
784 if (identify_info[82] & 2)
786 SET_REG(ATA_SELECT, ata_device);
788 if (!wait_for_rdy())
789 return -1;
791 SET_REG(ATA_COMMAND, CMD_SECURITY_FREEZE_LOCK);
793 if (!wait_for_rdy())
794 return -2;
797 return 0;
800 void ata_spindown(int seconds)
802 sleep_timeout = seconds * HZ;
805 bool ata_disk_is_active(void)
807 return !sleeping;
810 static int ata_perform_sleep(void)
812 int ret = 0;
814 mutex_lock(&ata_mtx);
816 SET_REG(ATA_SELECT, ata_device);
818 if(!wait_for_rdy()) {
819 DEBUGF("ata_perform_sleep() - not RDY\n");
820 mutex_unlock(&ata_mtx);
821 return -1;
824 SET_REG(ATA_COMMAND, CMD_SLEEP);
826 if (!wait_for_rdy())
828 DEBUGF("ata_perform_sleep() - CMD failed\n");
829 ret = -2;
832 sleeping = true;
833 mutex_unlock(&ata_mtx);
834 return ret;
837 void ata_sleep(void)
839 queue_post(&ata_queue, Q_SLEEP, 0);
842 void ata_sleepnow(void)
844 if (!spinup && !sleeping && !ata_mtx.locked && initialized)
846 call_ata_idle_notifys(false);
847 ata_perform_sleep();
851 void ata_spin(void)
853 last_user_activity = current_tick;
856 static void ata_thread(void)
858 static long last_sleep = 0;
859 struct queue_event ev;
860 static long last_seen_mtx_unlock = 0;
862 while (1) {
863 queue_wait_w_tmo(&ata_queue, &ev, HZ/2);
865 switch ( ev.id ) {
866 case SYS_TIMEOUT:
867 if (!spinup && !sleeping)
869 if (!ata_mtx.locked)
871 if (!last_seen_mtx_unlock)
872 last_seen_mtx_unlock = current_tick;
873 if (TIME_AFTER(current_tick, last_seen_mtx_unlock+(HZ*2)))
875 call_ata_idle_notifys(false);
876 last_seen_mtx_unlock = 0;
879 if ( sleep_timeout &&
880 TIME_AFTER( current_tick,
881 last_user_activity + sleep_timeout ) &&
882 TIME_AFTER( current_tick,
883 last_disk_activity + sleep_timeout ) )
885 call_ata_idle_notifys(true);
886 ata_perform_sleep();
887 last_sleep = current_tick;
891 #ifdef HAVE_ATA_POWER_OFF
892 if ( !spinup && sleeping && !poweroff &&
893 TIME_AFTER( current_tick, last_sleep + ATA_POWER_OFF_TIMEOUT ))
895 mutex_lock(&ata_mtx);
896 ide_power_enable(false);
897 mutex_unlock(&ata_mtx);
898 poweroff = true;
900 #endif
901 break;
903 #ifndef USB_NONE
904 case SYS_USB_CONNECTED:
905 if (poweroff) {
906 mutex_lock(&ata_mtx);
907 ata_led(true);
908 ata_power_on();
909 ata_led(false);
910 mutex_unlock(&ata_mtx);
913 /* Tell the USB thread that we are safe */
914 DEBUGF("ata_thread got SYS_USB_CONNECTED\n");
915 usb_acknowledge(SYS_USB_CONNECTED_ACK);
917 /* Wait until the USB cable is extracted again */
918 usb_wait_for_disconnect(&ata_queue);
919 break;
920 #endif
921 case Q_SLEEP:
922 call_ata_idle_notifys(false);
923 last_disk_activity = current_tick - sleep_timeout + (HZ/2);
924 break;
929 /* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
930 int ata_hard_reset(void)
932 int ret;
934 ata_reset();
936 /* state HRR2 */
937 SET_REG(ATA_SELECT, ata_device); /* select the right device */
938 ret = wait_for_bsy();
940 /* Massage the return code so it is 0 on success and -1 on failure */
941 ret = ret?0:-1;
943 return ret;
946 static int perform_soft_reset(void)
948 /* If this code is allowed to run on a Nano, the next reads from the flash will
949 * time out, so we disable it. It shouldn't be necessary anyway, since the
950 * ATA -> Flash interface automatically sleeps almost immediately after the
951 * last command.
953 #ifndef IPOD_NANO
954 int ret;
955 int retry_count;
957 SET_REG(ATA_SELECT, SELECT_LBA | ata_device );
958 SET_REG(ATA_CONTROL, CONTROL_nIEN|CONTROL_SRST );
959 sleep(1); /* >= 5us */
961 SET_REG(ATA_CONTROL, CONTROL_nIEN);
962 sleep(1); /* >2ms */
964 /* This little sucker can take up to 30 seconds */
965 retry_count = 8;
968 ret = wait_for_rdy();
969 } while(!ret && retry_count--);
971 /* Massage the return code so it is 0 on success and -1 on failure */
972 ret = ret?0:-1;
974 return ret;
975 #else
976 return 0; /* Always report success */
977 #endif
980 int ata_soft_reset(void)
982 int ret;
984 mutex_lock(&ata_mtx);
986 ret = perform_soft_reset();
988 mutex_unlock(&ata_mtx);
989 return ret;
992 static int ata_power_on(void)
994 int rc;
996 ide_power_enable(true);
997 sleep(HZ/50); /* allow voltage to build up */
998 if( ata_hard_reset() )
999 return -1;
1001 rc = set_features();
1002 if (rc)
1003 return rc * 10 - 2;
1005 if (set_multiple_mode(multisectors))
1006 return -3;
1008 if (freeze_lock())
1009 return -4;
1011 return 0;
1014 static int master_slave_detect(void)
1016 /* master? */
1017 SET_REG(ATA_SELECT, 0);
1018 if ( ATA_STATUS & (STATUS_RDY|STATUS_BSY) ) {
1019 ata_device = 0;
1020 DEBUGF("Found master harddisk\n");
1022 else {
1023 /* slave? */
1024 SET_REG(ATA_SELECT, SELECT_DEVICE1);
1025 if ( ATA_STATUS & (STATUS_RDY|STATUS_BSY) ) {
1026 ata_device = SELECT_DEVICE1;
1027 DEBUGF("Found slave harddisk\n");
1029 else
1030 return -1;
1032 return 0;
1035 static int identify(void)
1037 int i;
1039 SET_REG(ATA_SELECT, ata_device);
1041 if(!wait_for_rdy()) {
1042 DEBUGF("identify() - not RDY\n");
1043 return -1;
1045 SET_REG(ATA_COMMAND, CMD_IDENTIFY);
1047 if (!wait_for_start_of_transfer())
1049 DEBUGF("identify() - CMD failed\n");
1050 return -2;
1053 for (i=0; i<SECTOR_SIZE/2; i++) {
1054 /* the IDENTIFY words are already swapped, so we need to treat
1055 this info differently that normal sector data */
1056 #if defined(ROCKBOX_BIG_ENDIAN) && !defined(SWAP_WORDS)
1057 identify_info[i] = swap16(ATA_DATA);
1058 #else
1059 identify_info[i] = ATA_DATA;
1060 #endif
1063 return 0;
1066 static int set_multiple_mode(int sectors)
1068 SET_REG(ATA_SELECT, ata_device);
1070 if(!wait_for_rdy()) {
1071 DEBUGF("set_multiple_mode() - not RDY\n");
1072 return -1;
1075 SET_REG(ATA_NSECTOR, sectors);
1076 SET_REG(ATA_COMMAND, CMD_SET_MULTIPLE_MODE);
1078 if (!wait_for_rdy())
1080 DEBUGF("set_multiple_mode() - CMD failed\n");
1081 return -2;
1084 return 0;
1087 static int set_features(void)
1089 static struct {
1090 unsigned char id_word;
1091 unsigned char id_bit;
1092 unsigned char subcommand;
1093 unsigned char parameter;
1094 } features[] = {
1095 { 83, 3, 0x05, 0x80 }, /* power management: lowest power without standby */
1096 { 83, 9, 0x42, 0x80 }, /* acoustic management: lowest noise */
1097 { 82, 6, 0xaa, 0 }, /* enable read look-ahead */
1098 { 83, 14, 0x03, 0 }, /* force PIO mode */
1100 int i;
1101 int pio_mode = 2;
1103 /* Find out the highest supported PIO mode */
1104 if(identify_info[64] & 2)
1105 pio_mode = 4;
1106 else
1107 if(identify_info[64] & 1)
1108 pio_mode = 3;
1110 /* Update the table */
1111 features[3].parameter = 8 + pio_mode;
1113 SET_REG(ATA_SELECT, ata_device);
1115 if (!wait_for_rdy()) {
1116 DEBUGF("set_features() - not RDY\n");
1117 return -1;
1120 for (i=0; i < (int)(sizeof(features)/sizeof(features[0])); i++) {
1121 if (identify_info[features[i].id_word] & (1 << features[i].id_bit)) {
1122 SET_REG(ATA_FEATURE, features[i].subcommand);
1123 SET_REG(ATA_NSECTOR, features[i].parameter);
1124 SET_REG(ATA_COMMAND, CMD_SET_FEATURES);
1126 if (!wait_for_rdy()) {
1127 DEBUGF("set_features() - CMD failed\n");
1128 return -10 - i;
1131 if(ATA_ALT_STATUS & STATUS_ERR) {
1132 if(ATA_ERROR & ERROR_ABRT) {
1133 return -20 - i;
1139 return 0;
1142 unsigned short* ata_get_identify(void)
1144 return identify_info;
1147 static int init_and_check(bool hard_reset)
1149 int rc;
1151 if (hard_reset)
1153 /* This should reset both master and slave, we don't yet know what's in */
1154 ata_device = 0;
1155 if (ata_hard_reset())
1156 return -1;
1159 rc = master_slave_detect();
1160 if (rc)
1161 return -10 + rc;
1163 /* symptom fix: else check_registers() below may fail */
1164 if (hard_reset && !wait_for_bsy())
1165 return -20;
1167 rc = check_registers();
1168 if (rc)
1169 return -30 + rc;
1171 return 0;
1174 int ata_init(void)
1176 int rc = 0;
1177 bool coldstart;
1179 if ( !initialized ) {
1180 mutex_init(&ata_mtx);
1181 queue_init(&ata_queue, true);
1184 mutex_lock(&ata_mtx);
1186 /* must be called before ata_device_init() */
1187 coldstart = ata_is_coldstart();
1188 ata_led(false);
1189 ata_device_init();
1190 sleeping = false;
1191 ata_enable(true);
1192 #ifdef MAX_PHYS_SECTOR_SIZE
1193 memset(&sector_cache, 0, sizeof(sector_cache));
1194 #endif
1196 if ( !initialized ) {
1197 /* First call won't have multiple thread contention - this
1198 * may return at any point without having to unlock */
1199 mutex_unlock(&ata_mtx);
1201 if (!ide_powered()) /* somebody has switched it off */
1203 ide_power_enable(true);
1204 sleep(HZ/50); /* allow voltage to build up */
1207 /* first try, hard reset at cold start only */
1208 rc = init_and_check(coldstart);
1210 if (rc)
1211 { /* failed? -> second try, always with hard reset */
1212 DEBUGF("ata: init failed, retrying...\n");
1213 rc = init_and_check(true);
1214 if (rc)
1215 return rc;
1218 rc = identify();
1220 if (rc)
1221 return -40 + rc;
1223 multisectors = identify_info[47] & 0xff;
1224 if (multisectors == 0) /* Invalid multisector info, try with 16 */
1225 multisectors = 16;
1227 DEBUGF("ata: %d sectors per ata request\n",multisectors);
1229 #ifdef MAX_PHYS_SECTOR_SIZE
1230 /* Find out the physical sector size */
1231 if((identify_info[106] & 0xe000) == 0x6000)
1232 phys_sector_mult = 1 << (identify_info[106] & 0x000f);
1233 else
1234 phys_sector_mult = 1;
1236 DEBUGF("ata: %d logical sectors per phys sector", phys_sector_mult);
1238 if (phys_sector_mult > (MAX_PHYS_SECTOR_SIZE/SECTOR_SIZE))
1239 panicf("Unsupported physical sector size: %d",
1240 phys_sector_mult * SECTOR_SIZE);
1241 #endif
1243 #ifdef HAVE_LBA48
1244 if (identify_info[83] & 0x0400 /* 48 bit address support */
1245 && identify_info[60] == 0xFFFF /* and disk size >= 128 GiB */
1246 && identify_info[61] == 0x0FFF) /* (needs BigLBA addressing) */
1248 lba48 = true; /* use BigLBA */
1250 #endif
1251 rc = freeze_lock();
1253 if (rc)
1254 return -50 + rc;
1256 rc = set_features();
1257 if (rc)
1258 return -60 + rc;
1260 mutex_lock(&ata_mtx); /* Balance unlock below */
1262 last_disk_activity = current_tick;
1263 create_thread(ata_thread, ata_stack,
1264 sizeof(ata_stack), 0, ata_thread_name
1265 IF_PRIO(, PRIORITY_USER_INTERFACE)
1266 IF_COP(, CPU));
1267 initialized = true;
1270 rc = set_multiple_mode(multisectors);
1271 if (rc)
1272 rc = -70 + rc;
1274 mutex_unlock(&ata_mtx);
1275 return rc;
1278 #if (CONFIG_LED == LED_REAL)
1279 void ata_set_led_enabled(bool enabled)
1281 ata_led_enabled = enabled;
1282 if (ata_led_enabled)
1283 led(ata_led_on);
1284 else
1285 led(false);
1287 #endif