summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/ata-e200.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c
index 98d71c26ce..ef8608500a 100644
--- a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c
+++ b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c
@@ -16,10 +16,10 @@
16 * KIND, either express or implied. 16 * KIND, either express or implied.
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19/* TODO: Add ATA Callback support */
20#include "lcd.h" 19#include "lcd.h"
21#include "ata.h" 20#include "ata.h"
22#include "ata-target.h" 21#include "ata-target.h"
22#include "ata_idle_notify.h"
23#include "cpu.h" 23#include "cpu.h"
24#include "system.h" 24#include "system.h"
25#include <stdio.h> 25#include <stdio.h>
@@ -99,7 +99,7 @@
99static unsigned short identify_info[SECTOR_SIZE]; 99static unsigned short identify_info[SECTOR_SIZE];
100int ata_spinup_time = 0; 100int ata_spinup_time = 0;
101long last_disk_activity = -1; 101long last_disk_activity = -1;
102static bool delayed_write = false; 102static bool initialized = false;
103 103
104static unsigned char current_bank = 0; /* The bank that we are working with */ 104static unsigned char current_bank = 0; /* The bank that we are working with */
105 105
@@ -108,7 +108,13 @@ static tSDCardInfo card_info[2];
108/* For multi volume support */ 108/* For multi volume support */
109static int current_card = 0; 109static int current_card = 0;
110 110
111static struct mutex ata_mtx; 111static struct mutex sd_mtx;
112
113static long sd_stack [DEFAULT_STACK_SIZE/sizeof(long)];
114
115static const char sd_thread_name[] = "sd";
116static struct event_queue sd_queue;
117
112 118
113/* Private Functions */ 119/* Private Functions */
114 120
@@ -459,7 +465,7 @@ void sd_init_device(void)
459 dataptr += (FIFO_SIZE*2); /* Advance one chunk of 16 words */ 465 dataptr += (FIFO_SIZE*2); /* Advance one chunk of 16 words */
460 } 466 }
461 } 467 }
462 mutex_init(&ata_mtx); 468 mutex_init(&sd_mtx);
463} 469}
464 470
465/* API Functions */ 471/* API Functions */
@@ -469,12 +475,6 @@ void ata_led(bool onoff)
469 (void)onoff; 475 (void)onoff;
470} 476}
471 477
472/* write the delayed sector to volume 0 */
473extern void ata_flush(void)
474{
475
476}
477
478int ata_read_sectors(IF_MV2(int drive,) 478int ata_read_sectors(IF_MV2(int drive,)
479 unsigned long start, 479 unsigned long start,
480 int incount, 480 int incount,
@@ -495,7 +495,7 @@ int ata_read_sectors(IF_MV2(int drive,)
495#ifdef HAVE_MULTIVOLUME 495#ifdef HAVE_MULTIVOLUME
496 (void)drive; /* unused for now */ 496 (void)drive; /* unused for now */
497#endif 497#endif
498 mutex_lock(&ata_mtx); 498 mutex_lock(&sd_mtx);
499 499
500 last_disk_activity = current_tick; 500 last_disk_activity = current_tick;
501 spinup_start = current_tick; 501 spinup_start = current_tick;
@@ -551,11 +551,7 @@ int ata_read_sectors(IF_MV2(int drive,)
551 } 551 }
552 ata_led(false); 552 ata_led(false);
553 553
554 mutex_unlock(&ata_mtx); 554 mutex_unlock(&sd_mtx);
555
556 /* only flush if reading went ok */
557 if ( (ret == 0) && delayed_write )
558 ata_flush();
559 555
560 return ret; 556 return ret;
561} 557}
@@ -576,7 +572,7 @@ int ata_write_sectors(IF_MV2(int drive,)
576 long timeout; 572 long timeout;
577 tSDCardInfo *card = &card_info[current_card]; 573 tSDCardInfo *card = &card_info[current_card];
578 574
579 mutex_lock(&ata_mtx); 575 mutex_lock(&sd_mtx);
580 ata_led(true); 576 ata_led(true);
581 if(current_card == 0) 577 if(current_card == 0)
582 { 578 {
@@ -629,19 +625,39 @@ retry:
629 sd_read_response(&response, 1); 625 sd_read_response(&response, 1);
630 626
631 sd_wait_for_state(card, TRAN); 627 sd_wait_for_state(card, TRAN);
632 mutex_unlock(&ata_mtx); 628 mutex_unlock(&sd_mtx);
633 ata_led(false); 629 ata_led(false);
634 return ret; 630 return ret;
635} 631}
636 632
637/* schedule a single sector write, executed with the the next spinup 633static void sd_thread(void)
638 (volume 0 only, used for config sector) */
639extern void ata_delayed_write(unsigned long sector, const void* buf)
640{ 634{
641 (void)sector; 635 struct event ev;
642 (void)buf; 636 bool idle_notified = false;
637
638 while (1) {
639 queue_wait_w_tmo(&sd_queue, &ev, HZ);
640 switch ( ev.id )
641 {
642 default:
643 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
644 {
645 idle_notified = false;
646 }
647 else
648 {
649 if (!idle_notified)
650 {
651 call_ata_idle_notifys(false);
652 idle_notified = true;
653 }
654 }
655 break;
656 }
657 }
643} 658}
644 659
660
645void ata_spindown(int seconds) 661void ata_spindown(int seconds)
646{ 662{
647 (void)seconds; 663 (void)seconds;
@@ -684,5 +700,13 @@ unsigned short* ata_get_identify(void)
684int ata_init(void) 700int ata_init(void)
685{ 701{
686 sd_init_device(); 702 sd_init_device();
703 if ( !initialized )
704 {
705 queue_init(&sd_queue, true);
706 create_thread(sd_thread, sd_stack,
707 sizeof(sd_stack), sd_thread_name IF_PRIO(, PRIORITY_SYSTEM));
708 initialized = true;
709 }
710
687 return 0; 711 return 0;
688} 712}