summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-04-28 01:11:21 +0000
committerJens Arnold <amiconn@rockbox.org>2005-04-28 01:11:21 +0000
commita7f7781dca4db172a507e7e6f73bee03fc7deb2f (patch)
treebccca466c70e36229ab37f32b479f7271ddc6453
parent7e3f91d3d8bb0a672bd9803b84c2f08b76c92b60 (diff)
downloadrockbox-a7f7781dca4db172a507e7e6f73bee03fc7deb2f.tar.gz
rockbox-a7f7781dca4db172a507e7e6f73bee03fc7deb2f.zip
MMC driver does now handle block sizes != 512 bytes, which is necessary to support cards > 1 GB. Changed error handling to use the same method as other parts of rockbox, allowing to trace the call chain. Long policy, code cleanup.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6366 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/debug_menu.c4
-rw-r--r--firmware/drivers/ata_mmc.c510
-rw-r--r--firmware/export/ata_mmc.h13
3 files changed, 359 insertions, 168 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index f1402950a9..92fe0be63c 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -1678,8 +1678,10 @@ bool dbg_mmc_info(void)
1678 (int) mmc_extract_bits(card->cid, 0, 8), 1678 (int) mmc_extract_bits(card->cid, 0, 8),
1679 (int) mmc_extract_bits(card->cid, 8, 16)); 1679 (int) mmc_extract_bits(card->cid, 8, 16));
1680 lcd_puts(0, 4, pbuf); 1680 lcd_puts(0, 4, pbuf);
1681 snprintf(pbuf, sizeof(pbuf), "Sectors: %08x", card->numsectors); 1681 snprintf(pbuf, sizeof(pbuf), "Blocks: %08lx", card->numblocks);
1682 lcd_puts(0, 5, pbuf); 1682 lcd_puts(0, 5, pbuf);
1683 snprintf(pbuf, sizeof(pbuf), "Blocksize: %d", card->blocksize);
1684 lcd_puts(0, 6, pbuf);
1683 } 1685 }
1684 else /* Technical details */ 1686 else /* Technical details */
1685 { 1687 {
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c
index 7204a7eff5..3c242878e4 100644
--- a/firmware/drivers/ata_mmc.c
+++ b/firmware/drivers/ata_mmc.c
@@ -35,6 +35,7 @@
35#include "disk.h" /* for mount/unmount */ 35#include "disk.h" /* for mount/unmount */
36 36
37#define SECTOR_SIZE 512 37#define SECTOR_SIZE 512
38#define MAX_BLOCK_SIZE 2048
38 39
39/* Command definitions */ 40/* Command definitions */
40#define CMD_GO_IDLE_STATE 0x40 /* R1 */ 41#define CMD_GO_IDLE_STATE 0x40 /* R1 */
@@ -43,6 +44,7 @@
43#define CMD_SEND_CID 0x4a /* R1 */ 44#define CMD_SEND_CID 0x4a /* R1 */
44#define CMD_STOP_TRANSMISSION 0x4c /* R1 */ 45#define CMD_STOP_TRANSMISSION 0x4c /* R1 */
45#define CMD_SEND_STATUS 0x4d /* R2 */ 46#define CMD_SEND_STATUS 0x4d /* R2 */
47#define CMD_SET_BLOCKLEN 0x50 /* R1 */
46#define CMD_READ_SINGLE_BLOCK 0x51 /* R1 */ 48#define CMD_READ_SINGLE_BLOCK 0x51 /* R1 */
47#define CMD_READ_MULTIPLE_BLOCK 0x52 /* R1 */ 49#define CMD_READ_MULTIPLE_BLOCK 0x52 /* R1 */
48#define CMD_WRITE_BLOCK 0x58 /* R1b */ 50#define CMD_WRITE_BLOCK 0x58 /* R1b */
@@ -75,15 +77,13 @@
75 77
76/* Data start tokens */ 78/* Data start tokens */
77 79
78#define DT_START_BLOCK 0xfe 80#define DT_START_BLOCK 0xfe
79#define DT_START_WRITE_MULTIPLE 0xfc 81#define DT_START_WRITE_MULTIPLE 0xfc
80#define DT_STOP_TRAN 0xfd 82#define DT_STOP_TRAN 0xfd
81 83
82/* for compatibility */ 84/* for compatibility */
83bool old_recorder = false; /* FIXME: get rid of this cross-dependency */ 85bool old_recorder = false; /* FIXME: get rid of this cross-dependency */
84int ata_spinup_time = 0; 86int ata_spinup_time = 0;
85char ata_device = 0; /* device 0 (master) or 1 (slave) */
86int ata_io_address = 0; /* 0x300 or 0x200, only valid on recorder */
87long last_disk_activity = -1; 87long last_disk_activity = -1;
88 88
89/* private variables */ 89/* private variables */
@@ -91,7 +91,7 @@ long last_disk_activity = -1;
91static struct mutex mmc_mutex; 91static struct mutex mmc_mutex;
92 92
93#ifdef HAVE_HOTSWAP 93#ifdef HAVE_HOTSWAP
94static long mmc_stack[DEFAULT_STACK_SIZE/sizeof(long)]; 94static long mmc_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
95static const char mmc_thread_name[] = "mmc"; 95static const char mmc_thread_name[] = "mmc";
96static struct event_queue mmc_queue; 96static struct event_queue mmc_queue;
97#endif 97#endif
@@ -111,10 +111,22 @@ static const unsigned char dummy[] = {
111 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 111 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
112}; 112};
113 113
114/* 2 buffers for writing, include start token and dummy crc and an extra 114struct block_cache_entry {
115 * byte to keep word alignment */ 115 bool inuse;
116static unsigned char sector_buffer[2][(SECTOR_SIZE+4)]; 116#ifdef HAVE_MULTIVOLUME
117static int current_buffer = 0; 117 int drive;
118#endif
119 unsigned long blocknum;
120 unsigned char data[MAX_BLOCK_SIZE+4];
121 /* include start token, dummy crc, and an extra byte at the start
122 * to keep the data word aligned. */
123};
124
125/* 2 buffers used alternatively for writing, and also for reading
126 * and sub-block writing if block size > sector size */
127#define NUMCACHES 2
128static struct block_cache_entry block_cache[NUMCACHES];
129static int current_cache = 0;
118 130
119static tCardInfo card_info[2]; 131static tCardInfo card_info[2];
120#ifndef HAVE_MULTIVOLUME 132#ifndef HAVE_MULTIVOLUME
@@ -135,17 +147,19 @@ static void write_transfer(const unsigned char *buf, int len)
135 __attribute__ ((section(".icode"))); 147 __attribute__ ((section(".icode")));
136static void read_transfer(unsigned char *buf, int len) 148static void read_transfer(unsigned char *buf, int len)
137 __attribute__ ((section(".icode"))); 149 __attribute__ ((section(".icode")));
138static unsigned char poll_byte(int timeout); 150static unsigned char poll_byte(long timeout);
139static unsigned char poll_busy(int timeout); 151static unsigned char poll_busy(long timeout);
140static int send_cmd(int cmd, unsigned long parameter, unsigned char *response); 152static int send_cmd(int cmd, unsigned long parameter, unsigned char *response);
141static int receive_cxd(unsigned char *buf); 153static int receive_cxd(unsigned char *buf);
142static int initialize_card(int card_no); 154static int initialize_card(int card_no);
143static int receive_sector(unsigned char *inbuf, unsigned char *swapbuf, 155static void swapcopy(void *dst, const void *src, unsigned long size);
144 int timeout); 156static int receive_block(unsigned char *inbuf, unsigned char *swapbuf,
145static void swapcopy_sector(const unsigned char *buf); 157 int size, long timeout);
146static int send_sector(const unsigned char *nextbuf, int timeout); 158static void swapcopy_block(const unsigned char *buf, int size);
147static int send_single_sector(const unsigned char *buf, int timeout); 159static int send_block(const unsigned char *nextbuf, int size,
148 160 unsigned char start_token, long timeout);
161static int cache_block(IF_MV2(int drive,) unsigned long blocknum,
162 int size, long timeout);
149static void mmc_tick(void); 163static void mmc_tick(void);
150 164
151/* implementation */ 165/* implementation */
@@ -227,9 +241,9 @@ static void write_transfer(const unsigned char *buf, int len)
227 if (serial_mode != SER_POLL_WRITE) 241 if (serial_mode != SER_POLL_WRITE)
228 { 242 {
229 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ 243 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
230 SCR1 = 0; /* disable transmitter & receiver */ 244 SCR1 = 0; /* disable transmitter & receiver */
231 SSR1 = 0; /* clear all flags */ 245 SSR1 = 0; /* clear all flags */
232 SCR1 = SCI_TE; /* enable transmitter only */ 246 SCR1 = SCI_TE; /* enable transmitter only */
233 serial_mode = SER_POLL_WRITE; 247 serial_mode = SER_POLL_WRITE;
234 } 248 }
235 249
@@ -264,9 +278,9 @@ static void read_transfer(unsigned char *buf, int len)
264} 278}
265 279
266/* returns 0xFF on timeout, timeout is in bytes */ 280/* returns 0xFF on timeout, timeout is in bytes */
267static unsigned char poll_byte(int timeout) 281static unsigned char poll_byte(long timeout)
268{ 282{
269 int i; 283 long i;
270 unsigned char data = 0; /* stop the compiler complaining */ 284 unsigned char data = 0; /* stop the compiler complaining */
271 285
272 if (serial_mode != SER_POLL_READ) 286 if (serial_mode != SER_POLL_READ)
@@ -283,9 +297,9 @@ static unsigned char poll_byte(int timeout)
283} 297}
284 298
285/* returns 0 on timeout, timeout is in bytes */ 299/* returns 0 on timeout, timeout is in bytes */
286static unsigned char poll_busy(int timeout) 300static unsigned char poll_busy(long timeout)
287{ 301{
288 int i; 302 long i;
289 unsigned char data, dummy; 303 unsigned char data, dummy;
290 304
291 if (serial_mode != SER_POLL_READ) 305 if (serial_mode != SER_POLL_READ)
@@ -329,7 +343,7 @@ static int send_cmd(int cmd, unsigned long parameter, unsigned char *response)
329 if (response[0] != 0x00) 343 if (response[0] != 0x00)
330 { 344 {
331 write_transfer(dummy, 1); 345 write_transfer(dummy, 1);
332 return -10; 346 return -1;
333 } 347 }
334 348
335 switch (cmd) 349 switch (cmd)
@@ -364,7 +378,7 @@ static int receive_cxd(unsigned char *buf)
364 if (poll_byte(20) != DT_START_BLOCK) 378 if (poll_byte(20) != DT_START_BLOCK)
365 { 379 {
366 write_transfer(dummy, 1); 380 write_transfer(dummy, 1);
367 return -11; /* not start of data */ 381 return -1; /* not start of data */
368 } 382 }
369 383
370 read_transfer(buf, 16); 384 read_transfer(buf, 16);
@@ -408,7 +422,7 @@ unsigned long mmc_extract_bits(
408 422
409static int initialize_card(int card_no) 423static int initialize_card(int card_no)
410{ 424{
411 int i, temp; 425 int rc, i, temp;
412 unsigned char response[5]; 426 unsigned char response[5];
413 tCardInfo *card = &card_info[card_no]; 427 tCardInfo *card = &card_info[card_no];
414 428
@@ -437,24 +451,39 @@ static int initialize_card(int card_no)
437 return -2; /* not ready */ 451 return -2; /* not ready */
438 452
439 /* get OCR register */ 453 /* get OCR register */
440 if (send_cmd(CMD_READ_OCR, 0, response)) 454 rc = send_cmd(CMD_READ_OCR, 0, response);
441 return -3; 455 if (rc)
442 card->ocr = (response[1] << 24) + (response[2] << 16) 456 return rc * 10 - 3;
443 + (response[3] << 8) + response[4]; 457 card->ocr = (response[1] << 24) | (response[2] << 16)
458 | (response[3] << 8) | response[4];
444 459
445 /* check voltage */ 460 /* check voltage */
446 if (!(card->ocr & 0x00100000)) /* 3.2 .. 3.3 V */ 461 if (!(card->ocr & 0x00100000)) /* 3.2 .. 3.3 V */
447 return -4; 462 return -4;
448 463
449 /* get CSD register */ 464 /* get CSD register */
450 if (send_cmd(CMD_SEND_CSD, 0, response)) 465 rc = send_cmd(CMD_SEND_CSD, 0, response);
451 return -5; 466 if (rc)
452 if (receive_cxd((unsigned char*)card->csd)) 467 return rc * 10 - 5;
453 return -6; 468 rc = receive_cxd((unsigned char*)card->csd);
454 469 if (rc)
455 /* check block size */ 470 return rc * 10 - 6;
456 if ((1 << mmc_extract_bits(card->csd, 44, 4)) != SECTOR_SIZE) 471
472 /* check block sizes */
473 card->block_exp = mmc_extract_bits(card->csd, 44, 4);
474 card->blocksize = 1 << card->block_exp;
475 if ((mmc_extract_bits(card->csd, 102, 4) != card->block_exp)
476 || card->blocksize > MAX_BLOCK_SIZE)
477 {
457 return -7; 478 return -7;
479 }
480
481 if (card->blocksize != SECTOR_SIZE)
482 {
483 rc = send_cmd(CMD_SET_BLOCKLEN, card->blocksize, response);
484 if (rc)
485 return rc * 10 - 8;
486 }
458 487
459 /* max transmission speed, clock divider */ 488 /* max transmission speed, clock divider */
460 temp = mmc_extract_bits(card->csd, 29, 3); 489 temp = mmc_extract_bits(card->csd, 29, 3);
@@ -474,23 +503,30 @@ static int initialize_card(int card_no)
474 card->tsac = card->tsac * exponent[temp] / 10; 503 card->tsac = card->tsac * exponent[temp] / 10;
475 504
476 /* r2w_factor, write timeout */ 505 /* r2w_factor, write timeout */
477 temp = mmc_extract_bits(card->csd, 99, 3); 506 card->r2w_factor = 1 << mmc_extract_bits(card->csd, 99, 3);
478 temp = (temp > 5) ? 5 : temp; 507 if (card->r2w_factor > 32) /* dirty MMC spec violation */
479 card->r2w_factor = 1 << temp; 508 {
480 card->write_timeout = card->read_timeout * card->r2w_factor; 509 card->read_timeout *= 4; /* add safety factor */
510 card->write_timeout = card->read_timeout * 8;
511 }
512 else
513 card->write_timeout = card->read_timeout * card->r2w_factor;
481 514
482 /* card size */ 515 /* card size */
483 card->numsectors = (mmc_extract_bits(card->csd, 54, 12) + 1) 516 card->numblocks = (mmc_extract_bits(card->csd, 54, 12) + 1)
484 * (1 << (mmc_extract_bits(card->csd, 78, 3)+2)); 517 * (1 << (mmc_extract_bits(card->csd, 78, 3) + 2));
518 card->size = card->numblocks * card->blocksize;
485 519
486 /* switch to full speed */ 520 /* switch to full speed */
487 setup_sci1(card->bitrate_register); 521 setup_sci1(card->bitrate_register);
488 522
489 /* get CID register */ 523 /* get CID register */
490 if (send_cmd(CMD_SEND_CID, 0, response)) 524 rc = send_cmd(CMD_SEND_CID, 0, response);
491 return -8; 525 if (rc)
492 if (receive_cxd((unsigned char*)card->cid)) 526 return rc * 10 - 9;
493 return -9; 527 rc = receive_cxd((unsigned char*)card->cid);
528 if (rc)
529 return rc * 10 - 9;
494 530
495 card->initialized = true; 531 card->initialized = true;
496 return 0; 532 return 0;
@@ -510,17 +546,23 @@ tCardInfo *mmc_card_info(int card_no)
510 return card; 546 return card;
511} 547}
512 548
513/* Receive one sector with dma, possibly swapping the previously received 549static void swapcopy(void *dst, const void *src, unsigned long size)
514 * sector in the background */ 550{
515static int receive_sector(unsigned char *inbuf, unsigned char *swapbuf, 551 memcpy(dst, src, size);
516 int timeout) 552 bitswap(dst, size);
553}
554
555/* Receive one block with dma, possibly swapping the previously received
556 * block in the background */
557static int receive_block(unsigned char *inbuf, unsigned char *swapbuf,
558 int size, long timeout)
517{ 559{
518 if (poll_byte(timeout) != DT_START_BLOCK) 560 if (poll_byte(timeout) != DT_START_BLOCK)
519 { 561 {
520 write_transfer(dummy, 1); 562 write_transfer(dummy, 1);
521 return -12; /* not start of data */ 563 return -1; /* not start of data */
522 } 564 }
523 565
524 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ 566 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
525 567
526 SCR1 = 0; /* disable serial */ 568 SCR1 = 0; /* disable serial */
@@ -530,7 +572,7 @@ static int receive_sector(unsigned char *inbuf, unsigned char *swapbuf,
530 CHCR2 = 0; /* disable */ 572 CHCR2 = 0; /* disable */
531 SAR2 = RDR1_ADDR; 573 SAR2 = RDR1_ADDR;
532 DAR2 = (unsigned long) inbuf; 574 DAR2 = (unsigned long) inbuf;
533 DTCR2 = SECTOR_SIZE; 575 DTCR2 = size;
534 CHCR2 = 0x4601; /* fixed source address, RXI1, enable */ 576 CHCR2 = 0x4601; /* fixed source address, RXI1, enable */
535 DMAOR = 0x0001; 577 DMAOR = 0x0001;
536 SCR1 = (SCI_RE|SCI_RIE); /* kick off DMA */ 578 SCR1 = (SCI_RE|SCI_RIE); /* kick off DMA */
@@ -540,8 +582,8 @@ static int receive_sector(unsigned char *inbuf, unsigned char *swapbuf,
540 * the second one is lost because of the SCI overrun. However, this 582 * the second one is lost because of the SCI overrun. However, this
541 * behaviour conveniently discards the crc. */ 583 * behaviour conveniently discards the crc. */
542 584
543 if (swapbuf != NULL) /* bitswap previous sector */ 585 if (swapbuf != NULL) /* bitswap previous block */
544 bitswap(swapbuf, SECTOR_SIZE); 586 bitswap(swapbuf, size);
545 yield(); /* be nice */ 587 yield(); /* be nice */
546 588
547 while (!(CHCR2 & 0x0002)); /* wait for end of DMA */ 589 while (!(CHCR2 & 0x0002)); /* wait for end of DMA */
@@ -553,26 +595,25 @@ static int receive_sector(unsigned char *inbuf, unsigned char *swapbuf,
553 return 0; 595 return 0;
554} 596}
555 597
556/* copies one sector into the next-current write buffer, then bitswaps */ 598/* copies one block into the next-current block cache, then bitswaps */
557static void swapcopy_sector(const unsigned char *buf) 599static void swapcopy_block(const unsigned char *buf, int size)
558{ 600{
559 unsigned char *curbuf; 601 current_cache = (current_cache + 1) % NUMCACHES; /* next cache */
560 602
561 current_buffer ^= 1; /* toggles between 0 and 1 */ 603 block_cache[current_cache].inuse = false;
562 604 swapcopy(block_cache[current_cache].data + 2, buf, size);
563 curbuf = sector_buffer[current_buffer];
564 curbuf[1] = DT_START_WRITE_MULTIPLE;
565 curbuf[(SECTOR_SIZE+2)] = curbuf[(SECTOR_SIZE+3)] = 0xFF; /* dummy crc */
566 memcpy(curbuf + 2, buf, SECTOR_SIZE);
567 bitswap(curbuf + 1, (SECTOR_SIZE+1));
568} 605}
569 606
570/* Send one sector with dma from the current sector buffer, possibly preparing 607/* Send one block with dma from the current block cache, possibly preparing
571 * the next sector within the other sector buffer in the background. Use 608 * the next block within the next block cache in the background. */
572 * for multisector transfer only */ 609static int send_block(const unsigned char *nextbuf, int size,
573static int send_sector(const unsigned char *nextbuf, int timeout) 610 unsigned char start_token, long timeout)
574{ 611{
575 int ret = 0; 612 int rc = 0;
613 unsigned char *curbuf = block_cache[current_cache].data;
614
615 curbuf[1] = fliptable[(signed char)start_token];
616 *(unsigned short *)(curbuf + size + 2) = 0xFFFF;
576 617
577 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ 618 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
578 619
@@ -581,15 +622,15 @@ static int send_sector(const unsigned char *nextbuf, int timeout)
581 622
582 /* setup DMA channel 2 */ 623 /* setup DMA channel 2 */
583 CHCR2 = 0; /* disable */ 624 CHCR2 = 0; /* disable */
584 SAR2 = (unsigned long)(sector_buffer[current_buffer] + 1); 625 SAR2 = (unsigned long)(curbuf + 1);
585 DAR2 = TDR1_ADDR; 626 DAR2 = TDR1_ADDR;
586 DTCR2 = (SECTOR_SIZE+3); 627 DTCR2 = size + 3; /* start token + block + dummy crc */
587 CHCR2 = 0x1701; /* fixed dest. address, TXI1, enable */ 628 CHCR2 = 0x1701; /* fixed dest. address, TXI1, enable */
588 DMAOR = 0x0001; 629 DMAOR = 0x0001;
589 SCR1 = (SCI_TE|SCI_TIE); /* kick off DMA */ 630 SCR1 = (SCI_TE|SCI_TIE); /* kick off DMA */
590 631
591 if (nextbuf != NULL) /* prepare next sector */ 632 if (nextbuf != NULL) /* prepare next sector */
592 swapcopy_sector(nextbuf); 633 swapcopy_block(nextbuf, size);
593 yield(); /* be nice */ 634 yield(); /* be nice */
594 635
595 while (!(CHCR2 & 0x0002)); /* wait for end of DMA */ 636 while (!(CHCR2 & 0x0002)); /* wait for end of DMA */
@@ -598,29 +639,52 @@ static int send_sector(const unsigned char *nextbuf, int timeout)
598 serial_mode = SER_DISABLED; 639 serial_mode = SER_DISABLED;
599 640
600 if ((poll_busy(timeout) & 0x1F) != 0x05) /* something went wrong */ 641 if ((poll_busy(timeout) & 0x1F) != 0x05) /* something went wrong */
601 ret = -13; 642 rc = -1;
602 643
603 write_transfer(dummy, 1); 644 write_transfer(dummy, 1);
604 645
605 return ret; 646 return rc;
606} 647}
607 648
608/* Send one sector with polled i/o. Use for single sector transfers only. */ 649static int cache_block(IF_MV2(int drive,) unsigned long blocknum,
609static int send_single_sector(const unsigned char *buf, int timeout) 650 int size, long timeout)
610{ 651{
611 int ret = 0; 652 int rc, i;
612 unsigned char start_token = DT_START_BLOCK; 653 unsigned char response;
613 654
614 write_transfer(&start_token, 1); 655 /* check whether the block is already cached */
615 write_transfer(buf, SECTOR_SIZE); 656 for (i = 0; i < NUMCACHES; i++)
616 write_transfer(dummy, 2); /* crc - dontcare */ 657 {
617 658 if (block_cache[i].inuse && (block_cache[i].blocknum == blocknum)
618 if ((poll_busy(timeout) & 0x1F) != 0x05) /* something went wrong */ 659#ifdef HAVE_MULTIVOLUME
619 ret = -14; 660 && (block_cache[i].drive == drive)
661#endif
662 )
663 {
664 current_cache = i;
665 return 0;
666 }
667 }
668 /* not found: read the block */
669 current_cache = (current_cache + 1) % NUMCACHES;
670 rc = send_cmd(CMD_READ_SINGLE_BLOCK, blocknum * size, &response);
671 if (rc)
672 return rc * 10 - 1;
673
674 block_cache[current_cache].inuse = false;
675 rc = receive_block(block_cache[current_cache].data + 2, NULL,
676 size, timeout);
677 if (rc)
678 return rc * 10 - 2;
620 679
621 write_transfer(dummy, 1); 680#ifdef HAVE_MULTIVOLUME
681 block_cache[current_cache].drive = drive;
682#endif
683 block_cache[current_cache].blocknum = blocknum;
684 block_cache[current_cache].inuse = true;
685 last_disk_activity = current_tick;
622 686
623 return ret; 687 return 0;
624} 688}
625 689
626int ata_read_sectors(IF_MV2(int drive,) 690int ata_read_sectors(IF_MV2(int drive,)
@@ -628,75 +692,120 @@ int ata_read_sectors(IF_MV2(int drive,)
628 int incount, 692 int incount,
629 void* inbuf) 693 void* inbuf)
630{ 694{
631 int ret = 0; 695 int rc = 0;
632 int last_sector; 696 unsigned int blocksize, offset;
633 unsigned long addr; 697 unsigned long c_addr, c_end_addr;
698 unsigned long c_block, c_end_block;
634 unsigned char response; 699 unsigned char response;
635 void *inbuf_prev = NULL; 700 void *inbuf_prev = NULL;
636 tCardInfo *card; 701 tCardInfo *card;
637 702
638 addr = start * SECTOR_SIZE; 703 c_addr = start * SECTOR_SIZE;
639 704 c_end_addr = c_addr + incount * SECTOR_SIZE;
705
640 mutex_lock(&mmc_mutex); 706 mutex_lock(&mmc_mutex);
641 led(true); 707 led(true);
642#ifdef HAVE_MULTIVOLUME 708#ifdef HAVE_MULTIVOLUME
643 card = &card_info[drive]; 709 card = &card_info[drive];
644 ret = select_card(drive); 710 rc = select_card(drive);
645#else 711#else
646 card = &card_info[current_card]; 712 card = &card_info[current_card];
647 ret = select_card(current_card); 713 rc = select_card(current_card);
648#endif 714#endif
649 if (start + incount > card->numsectors) 715 if (rc)
716 {
717 rc = rc * 10 - 1;
718 goto error;
719 }
720 if (c_end_addr > card->size)
650 { 721 {
651 ret = -15; 722 rc = -2;
652 /* panicf("Reading %d@%d, past end of card %d\n", 723 goto error;
653 incount, start, card->numsectors); */
654 } 724 }
655 725
726 blocksize = card->blocksize;
727 offset = c_addr & (blocksize - 1);
728 c_block = c_addr >> card->block_exp;
729 c_end_block = c_end_addr >> card->block_exp;
730
731 if (offset) /* first partial block */
732 {
733 unsigned long len = MIN(c_end_addr - c_addr, blocksize - offset);
734
735 rc = cache_block(IF_MV2(drive,) c_block, blocksize,
736 card->read_timeout);
737 if (rc)
738 {
739 rc = rc * 10 - 3;
740 goto error;
741 }
742 swapcopy(inbuf, block_cache[current_cache].data + 2 + offset, len);
743 inbuf += len;
744 c_addr += len;
745 c_block++;
746 }
656 /* some cards don't like reading the very last sector with 747 /* some cards don't like reading the very last sector with
657 * CMD_READ_MULTIPLE_BLOCK, so make sure this sector is always 748 * CMD_READ_MULTIPLE_BLOCK, so make sure this sector is always
658 * read with CMD_READ_SINGLE_BLOCK. */ 749 * read with CMD_READ_SINGLE_BLOCK. This is caught by the 'last
659 last_sector = (start + incount == card->numsectors) ? 1 : 0; 750 * partial block' read. */
751 if (c_end_block == card->numblocks)
752 c_end_block--;
660 753
661 if (ret == 0) 754 if (c_block < c_end_block)
662 { 755 {
663 if (incount > 1) 756 rc = send_cmd(CMD_READ_MULTIPLE_BLOCK, c_addr, &response);
757 if (rc)
664 { 758 {
665 ret = send_cmd(CMD_READ_MULTIPLE_BLOCK, addr, &response); 759 rc = rc * 10 - 4;
666 for (; (incount > last_sector) && (ret == 0); incount--) 760 goto error;
667 {
668 ret = receive_sector(inbuf, inbuf_prev, card->read_timeout);
669 inbuf_prev = inbuf;
670 inbuf += SECTOR_SIZE;
671 last_disk_activity = current_tick;
672 }
673 if (ret == 0)
674 ret = send_cmd(CMD_STOP_TRANSMISSION, 0, &response);
675 } 761 }
676 if (incount && (ret == 0)) 762 while (c_block < c_end_block)
677 { 763 {
678 ret = send_cmd(CMD_READ_SINGLE_BLOCK, addr, &response); 764 rc = receive_block(inbuf, inbuf_prev, blocksize,
679 if (ret == 0) 765 card->read_timeout);
766 if (rc)
680 { 767 {
681 ret = receive_sector(inbuf, inbuf_prev, card->read_timeout); 768 rc = rc * 10 - 5;
682 inbuf_prev = inbuf; 769 goto error;
683 last_disk_activity = current_tick;
684 } 770 }
771 last_disk_activity = current_tick;
772 inbuf_prev = inbuf;
773 inbuf += blocksize;
774 c_addr += blocksize;
775 c_block++;
685 } 776 }
686 777 rc = send_cmd(CMD_STOP_TRANSMISSION, 0, &response);
687 if (ret == 0) 778 if (rc)
688 bitswap(inbuf_prev, SECTOR_SIZE); 779 {
780 rc = rc * 10 - 6;
781 goto error;
782 }
783 bitswap(inbuf_prev, blocksize);
784 }
785 if (c_addr < c_end_addr) /* last partial block */
786 {
787 rc = cache_block(IF_MV2(drive,) c_block, blocksize,
788 card->read_timeout);
789 if (rc)
790 {
791 rc = rc * 10 - 7;
792 goto error;
793 }
794 swapcopy(inbuf, block_cache[current_cache].data + 2,
795 c_end_addr - c_addr);
689 } 796 }
690 797
798 error:
799
691 deselect_card(); 800 deselect_card();
692 led(false); 801 led(false);
693 mutex_unlock(&mmc_mutex); 802 mutex_unlock(&mmc_mutex);
694 803
695 /* only flush if reading went ok */ 804 /* only flush if reading went ok */
696 if ( (ret == 0) && delayed_write ) 805 if ( (rc == 0) && delayed_write )
697 ata_flush(); 806 ata_flush();
698 807
699 return ret; 808 return rc;
700} 809}
701 810
702int ata_write_sectors(IF_MV2(int drive,) 811int ata_write_sectors(IF_MV2(int drive,)
@@ -704,70 +813,145 @@ int ata_write_sectors(IF_MV2(int drive,)
704 int count, 813 int count,
705 const void* buf) 814 const void* buf)
706{ 815{
707 int ret = 0; 816 int rc = 0;
708 unsigned long addr; 817 unsigned int blocksize, offset;
818 unsigned long c_addr, c_end_addr;
819 unsigned long c_block, c_end_block;
709 unsigned char response; 820 unsigned char response;
710 tCardInfo *card; 821 tCardInfo *card;
711 822
712 if (start == 0) 823 if (start == 0)
713 panicf("Writing on sector 0\n"); 824 panicf("Writing on sector 0\n");
714 825
715 addr = start * SECTOR_SIZE; 826 c_addr = start * SECTOR_SIZE;
716 827 c_end_addr = c_addr + count * SECTOR_SIZE;
828
717 mutex_lock(&mmc_mutex); 829 mutex_lock(&mmc_mutex);
718 led(true); 830 led(true);
719#ifdef HAVE_MULTIVOLUME 831#ifdef HAVE_MULTIVOLUME
720 card = &card_info[drive]; 832 card = &card_info[drive];
721 ret = select_card(drive); 833 rc = select_card(drive);
722#else 834#else
723 card = &card_info[current_card]; 835 card = &card_info[current_card];
724 ret = select_card(current_card); 836 rc = select_card(current_card);
725#endif 837#endif
726 if (start + count > card->numsectors) 838 if (rc)
839 {
840 rc = rc * 10 - 1;
841 goto error;
842 }
843
844 if (c_end_addr > card->size)
727 panicf("Writing past end of card\n"); 845 panicf("Writing past end of card\n");
728 846
729 if (ret == 0) 847 blocksize = card->blocksize;
848 offset = c_addr & (blocksize - 1);
849 c_block = c_addr >> card->block_exp;
850 c_end_block = c_end_addr >> card->block_exp;
851
852 if (offset) /* first partial block */
730 { 853 {
731 if (count == 1) 854 unsigned long len = MIN(c_end_addr - c_addr, blocksize - offset);
855
856 rc = cache_block(IF_MV2(drive,) c_block, blocksize,
857 card->read_timeout);
858 if (rc)
732 { 859 {
733 ret = send_cmd(CMD_WRITE_BLOCK, addr, &response); 860 rc = rc * 10 - 2;
734 if (ret == 0) 861 goto error;
735 ret = send_single_sector(buf, card->write_timeout);
736 last_disk_activity = current_tick;
737 } 862 }
738 else 863 swapcopy(block_cache[current_cache].data + 2 + offset, buf, len);
864 rc = send_cmd(CMD_WRITE_BLOCK, c_addr - offset, &response);
865 if (rc)
739 { 866 {
740 swapcopy_sector(buf); /* prepare first sector */ 867 rc = rc * 10 - 3;
741 ret = send_cmd(CMD_WRITE_MULTIPLE_BLOCK, addr, &response); 868 goto error;
742 for (; (count > 1) && (ret == 0); count--) 869 }
743 { 870 buf += len;
744 buf += SECTOR_SIZE; 871 rc = send_block(NULL, blocksize, DT_START_BLOCK, card->write_timeout);
745 ret = send_sector(buf, card->write_timeout); 872 if (rc)
746 last_disk_activity = current_tick; 873 {
747 } 874 rc = rc * 10 - 4;
748 if (ret == 0) 875 goto error;
876 }
877 c_addr += len;
878 c_block++;
879 }
880 if (c_block < c_end_block)
881 {
882 swapcopy_block(buf, blocksize);
883 rc = send_cmd(CMD_WRITE_MULTIPLE_BLOCK, c_addr, &response);
884 if (rc)
885 {
886 rc = rc * 10 - 5;
887 goto error;
888 }
889 while (c_block < c_end_block - 1)
890 {
891 buf += blocksize;
892 rc = send_block(buf, blocksize, DT_START_WRITE_MULTIPLE,
893 card->write_timeout);
894 if (rc)
749 { 895 {
750 ret = send_sector(NULL, card->write_timeout); 896 rc = rc * 10 - 6;
751 if (ret == 0) 897 goto error;
752 {
753 response = DT_STOP_TRAN;
754 write_transfer(&response, 1);
755 poll_busy(card->write_timeout);
756 }
757 last_disk_activity = current_tick;
758 } 898 }
899 last_disk_activity = current_tick;
900 c_addr += blocksize;
901 c_block++;
902 }
903 buf += blocksize;
904 rc = send_block(NULL, blocksize, DT_START_WRITE_MULTIPLE,
905 card->write_timeout);
906 if (rc)
907 {
908 rc = rc * 10 - 7;
909 goto error;
910 }
911 last_disk_activity = current_tick;
912 c_addr += blocksize;
913 c_block++;
914
915 response = DT_STOP_TRAN;
916 write_transfer(&response, 1);
917 poll_busy(card->write_timeout);
918 }
919 if (c_addr < c_end_addr) /* last partial block */
920 {
921 rc = cache_block(IF_MV2(drive,) c_block, blocksize,
922 card->read_timeout);
923 if (rc)
924 {
925 rc = rc * 10 - 8;
926 goto error;
927 }
928 swapcopy(block_cache[current_cache].data + 2, buf,
929 c_end_addr - c_addr);
930 rc = send_cmd(CMD_WRITE_BLOCK, c_addr, &response);
931 if (rc)
932 {
933 rc = rc * 10 - 9;
934 goto error;
935 }
936 rc = send_block(NULL, blocksize, DT_START_BLOCK, card->write_timeout);
937 if (rc)
938 {
939 rc = rc * 10 - 9;
940 goto error;
759 } 941 }
760 } 942 }
761 943
944 error:
945
762 deselect_card(); 946 deselect_card();
763 led(false); 947 led(false);
764 mutex_unlock(&mmc_mutex); 948 mutex_unlock(&mmc_mutex);
765 949
766 /* only flush if writing went ok */ 950 /* only flush if writing went ok */
767 if ( (ret == 0) && delayed_write ) 951 if ( (rc == 0) && delayed_write )
768 ata_flush(); 952 ata_flush();
769 953
770 return ret; 954 return rc;
771} 955}
772 956
773/* While there is no spinup, the delayed write is still here to avoid 957/* While there is no spinup, the delayed write is still here to avoid
@@ -782,7 +966,8 @@ extern void ata_delayed_write(unsigned long sector, const void* buf)
782/* write the delayed sector to volume 0 */ 966/* write the delayed sector to volume 0 */
783extern void ata_flush(void) 967extern void ata_flush(void)
784{ 968{
785 if ( delayed_write ) { 969 if ( delayed_write )
970 {
786 DEBUGF("ata_flush()\n"); 971 DEBUGF("ata_flush()\n");
787 delayed_write = false; 972 delayed_write = false;
788 ata_write_sectors(IF_MV2(0,) delayed_sector_num, 1, delayed_sector); 973 ata_write_sectors(IF_MV2(0,) delayed_sector_num, 1, delayed_sector);
@@ -823,7 +1008,8 @@ static void mmc_thread(void)
823 1008
824 while (1) { 1009 while (1) {
825 queue_wait(&mmc_queue, &ev); 1010 queue_wait(&mmc_queue, &ev);
826 switch ( ev.id ) { 1011 switch ( ev.id )
1012 {
827 case SYS_USB_CONNECTED: 1013 case SYS_USB_CONNECTED:
828 usb_acknowledge(SYS_USB_CONNECTED_ACK); 1014 usb_acknowledge(SYS_USB_CONNECTED_ACK);
829 /* Wait until the USB cable is extracted again */ 1015 /* Wait until the USB cable is extracted again */
diff --git a/firmware/export/ata_mmc.h b/firmware/export/ata_mmc.h
index 6c5141dd05..8b5056bbd8 100644
--- a/firmware/export/ata_mmc.h
+++ b/firmware/export/ata_mmc.h
@@ -23,17 +23,20 @@ typedef struct
23{ 23{
24 bool initialized; 24 bool initialized;
25 unsigned char bitrate_register; 25 unsigned char bitrate_register;
26 unsigned int read_timeout; /* n * 8 clock cycles */ 26 unsigned long read_timeout; /* n * 8 clock cycles */
27 unsigned int write_timeout; /* n * 8 clock cycles */ 27 unsigned long write_timeout; /* n * 8 clock cycles */
28 28
29 unsigned long ocr; /* OCR register */ 29 unsigned long ocr; /* OCR register */
30 unsigned long csd[4]; /* CSD register, 16 bytes */ 30 unsigned long csd[4]; /* CSD register, 16 bytes */
31 unsigned long cid[4]; /* CID register, 16 bytes */ 31 unsigned long cid[4]; /* CID register, 16 bytes */
32 unsigned int speed; /* bit/s */ 32 unsigned long speed; /* bit/s */
33 unsigned int nsac; /* clock cycles */ 33 unsigned int nsac; /* clock cycles */
34 unsigned int tsac; /* n * 0.1 ns */ 34 unsigned long tsac; /* n * 0.1 ns */
35 unsigned int r2w_factor; 35 unsigned int r2w_factor;
36 unsigned int numsectors; /* size in sectors */ 36 unsigned long size; /* size in bytes */
37 unsigned long numblocks; /* size in flash blocks */
38 unsigned int blocksize; /* block size in bytes */
39 unsigned int block_exp; /* block size exponent */
37} tCardInfo; 40} tCardInfo;
38 41
39void mmc_select_clock(int card_no); 42void mmc_select_clock(int card_no);