diff options
author | Jens Arnold <amiconn@rockbox.org> | 2004-10-04 22:29:06 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2004-10-04 22:29:06 +0000 |
commit | a15386bb9d676833f2743dcc6624ab22899c8198 (patch) | |
tree | 323055c2b5456c6dbb2903fa5a27d46399243172 /firmware/drivers | |
parent | 36813086e6fa4bfe75484db20bedbf564b5a2420 (diff) | |
download | rockbox-a15386bb9d676833f2743dcc6624ab22899c8198.tar.gz rockbox-a15386bb9d676833f2743dcc6624ab22899c8198.zip |
(Re-)added the delayed write feature to avoid wearing the flash unnecessarily
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5162 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/ata_mmc.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c index b4006c6aff..7a9a67839d 100644 --- a/firmware/drivers/ata_mmc.c +++ b/firmware/drivers/ata_mmc.c | |||
@@ -99,6 +99,10 @@ static char mmc_stack[DEFAULT_STACK_SIZE]; | |||
99 | static const char mmc_thread_name[] = "mmc"; | 99 | static const char mmc_thread_name[] = "mmc"; |
100 | static struct event_queue mmc_queue; | 100 | static struct event_queue mmc_queue; |
101 | static bool initialized = false; | 101 | static bool initialized = false; |
102 | static bool delayed_write = false; | ||
103 | static unsigned char delayed_sector[SECTOR_SIZE]; | ||
104 | static int delayed_sector_num; | ||
105 | |||
102 | static int current_card = 0; | 106 | static int current_card = 0; |
103 | 107 | ||
104 | static const unsigned char dummy[] = { | 108 | static const unsigned char dummy[] = { |
@@ -264,7 +268,7 @@ static unsigned char poll_busy(int timeout) | |||
264 | /* get data response */ | 268 | /* get data response */ |
265 | SSR1 = 0; /* start receiving */ | 269 | SSR1 = 0; /* start receiving */ |
266 | while (!(SSR1 & SCI_RDRF)); /* wait for data */ | 270 | while (!(SSR1 & SCI_RDRF)); /* wait for data */ |
267 | data = RDR1; /* read byte */ | 271 | data = fliptable[(signed char)(RDR1)]; /* read byte */ |
268 | 272 | ||
269 | /* wait until the card is ready again */ | 273 | /* wait until the card is ready again */ |
270 | i = 0; | 274 | i = 0; |
@@ -274,7 +278,7 @@ static unsigned char poll_busy(int timeout) | |||
274 | dummy = RDR1; /* read byte */ | 278 | dummy = RDR1; /* read byte */ |
275 | } while ((dummy != 0xFF) && (++i < timeout)); | 279 | } while ((dummy != 0xFF) && (++i < timeout)); |
276 | 280 | ||
277 | return fliptable[(signed char)data]; | 281 | return data; |
278 | } | 282 | } |
279 | 283 | ||
280 | static int send_cmd(int cmd, unsigned long parameter, unsigned char *response) | 284 | static int send_cmd(int cmd, unsigned long parameter, unsigned char *response) |
@@ -498,6 +502,10 @@ int ata_read_sectors(unsigned long start, | |||
498 | deselect_card(); | 502 | deselect_card(); |
499 | mutex_unlock(&mmc_mutex); | 503 | mutex_unlock(&mmc_mutex); |
500 | 504 | ||
505 | /* only flush if reading went ok */ | ||
506 | if ( (ret == 0) && delayed_write ) | ||
507 | ata_flush(); | ||
508 | |||
501 | return ret; | 509 | return ret; |
502 | } | 510 | } |
503 | 511 | ||
@@ -552,17 +560,29 @@ int ata_write_sectors(unsigned long start, | |||
552 | deselect_card(); | 560 | deselect_card(); |
553 | mutex_unlock(&mmc_mutex); | 561 | mutex_unlock(&mmc_mutex); |
554 | 562 | ||
563 | /* only flush if writing went ok */ | ||
564 | if ( (ret == 0) && delayed_write ) | ||
565 | ata_flush(); | ||
566 | |||
555 | return ret; | 567 | return ret; |
556 | } | 568 | } |
557 | 569 | ||
558 | /* no need to delay with flash memory. There is no spinup :) */ | 570 | /* While there is no spinup, the delayed write is still here to avoid |
571 | wearing the flash unnecessarily */ | ||
559 | extern void ata_delayed_write(unsigned long sector, const void* buf) | 572 | extern void ata_delayed_write(unsigned long sector, const void* buf) |
560 | { | 573 | { |
561 | ata_write_sectors(sector, 1, buf); | 574 | memcpy(delayed_sector, buf, SECTOR_SIZE); |
575 | delayed_sector_num = sector; | ||
576 | delayed_write = true; | ||
562 | } | 577 | } |
563 | 578 | ||
564 | extern void ata_flush(void) | 579 | extern void ata_flush(void) |
565 | { | 580 | { |
581 | if ( delayed_write ) { | ||
582 | DEBUGF("ata_flush()\n"); | ||
583 | delayed_write = false; | ||
584 | ata_write_sectors(delayed_sector_num, 1, delayed_sector); | ||
585 | } | ||
566 | } | 586 | } |
567 | 587 | ||
568 | void ata_spindown(int seconds) | 588 | void ata_spindown(int seconds) |