@@ -40,8 +40,8 @@ static uint8_t (*spi_rw_byte)(uint8_t data) = NULL;
4040static void (* spi_set_cs )(bool enabled ) = NULL ;
4141static int (* spi_init )(bool fast ) = NULL ;
4242static void (* spi_shutdown )(void ) = NULL ;
43- static void (* spi_read_data )(uint8_t * data , size_t len ) = NULL ;
44- static void (* spi_write_data )(const uint8_t * data , size_t len ) = NULL ;
43+ static int (* spi_read_data )(uint8_t * data , size_t len ) = NULL ;
44+ static int (* spi_write_data )(const uint8_t * data , size_t len ) = NULL ;
4545static uint8_t (* spi_read_byte )(void ) = NULL ;
4646static void (* spi_write_byte )(uint8_t data ) = NULL ;
4747
@@ -117,10 +117,16 @@ static uint8_t scif_rw_byte_wrapper(uint8_t data) {
117117 return scif_spi_slow_rw_byte (data );
118118}
119119
120- static void scif_write_data_wrapper (const uint8_t * data , size_t len ) {
120+ static int scif_read_data_wrapper (uint8_t * data , size_t len ) {
121+ scif_spi_read_data (data , len );
122+ return 0 ;
123+ }
124+
125+ static int scif_write_data_wrapper (const uint8_t * data , size_t len ) {
121126 while (len -- ) {
122127 scif_spi_write_byte (* data ++ );
123128 }
129+ return 0 ;
124130}
125131
126132static uint8_t sci_read_byte_wrapper (void ) {
@@ -133,18 +139,18 @@ static void sci_write_byte_wrapper(uint8_t data) {
133139 sci_spi_write_byte (data );
134140}
135141
136- static void sci_read_data_wrapper (uint8_t * data , size_t len ) {
142+ static int sci_read_data_wrapper (uint8_t * data , size_t len ) {
137143 if (len & 31 )
138- sci_spi_read_data (data , len );
144+ return sci_spi_read_data (data , len );
139145 else
140- sci_spi_dma_read_data (data , len , NULL , NULL );
146+ return sci_spi_dma_read_data (data , len , NULL , NULL );
141147}
142148
143- static void sci_write_data_wrapper (const uint8_t * data , size_t len ) {
149+ static int sci_write_data_wrapper (const uint8_t * data , size_t len ) {
144150 if (len & 31 )
145- sci_spi_write_data (data , len );
151+ return sci_spi_write_data (data , len );
146152 else
147- sci_spi_dma_write_data (data , len , NULL , NULL );
153+ return sci_spi_dma_write_data (data , len , NULL , NULL );
148154}
149155
150156static void scif_shutdown_wrapper (void ) {
@@ -269,6 +275,21 @@ int sd_init(void) {
269275 return sd_init_ex (& params );
270276}
271277
278+ static int sd_reinit (void ) {
279+ sd_init_params_t params = {
280+ .interface = current_interface ,
281+ .check_crc = check_crc
282+ };
283+
284+ spi_set_cs (false);
285+ spi_rw_byte (0xFF );
286+
287+ spi_shutdown ();
288+
289+ initted = false;
290+ return sd_init_ex (& params );
291+ }
292+
272293int sd_init_ex (const sd_init_params_t * params ) {
273294 int i ;
274295 uint8 buf [4 ];
@@ -290,7 +311,7 @@ int sd_init_ex(const sd_init_params_t *params) {
290311 spi_set_cs = & scif_set_cs_wrapper ;
291312 spi_init = & scif_init_wrapper ;
292313 spi_shutdown = & scif_shutdown_wrapper ;
293- spi_read_data = & scif_spi_read_data ;
314+ spi_read_data = & scif_read_data_wrapper ;
294315 spi_write_data = & scif_write_data_wrapper ;
295316 spi_read_byte = & scif_spi_read_byte ;
296317 spi_write_byte = & scif_spi_write_byte ;
@@ -440,7 +461,9 @@ static int read_data(size_t bytes, uint8 *buf) {
440461 return -1 ;
441462
442463 /* Read in the data */
443- spi_read_data (buf , bytes );
464+ if (spi_read_data (buf , bytes )) {
465+ return -1 ;
466+ }
444467
445468 /* Read in the trailing CRC */
446469 if (check_crc ) {
@@ -455,7 +478,10 @@ static int read_data(size_t bytes, uint8 *buf) {
455478}
456479
457480int sd_read_blocks (uint32 block , size_t count , uint8 * buf ) {
458- int rv = 0 ;
481+ int rv ;
482+ size_t read_count ;
483+ uint8_t * read_buf ;
484+ bool retried = false;
459485
460486 if (!initted ) {
461487 errno = ENXIO ;
@@ -466,9 +492,13 @@ int sd_read_blocks(uint32 block, size_t count, uint8 *buf) {
466492 if (byte_mode )
467493 block <<= 9 ;
468494
495+ read_blocks :
496+ read_count = count ;
497+ read_buf = buf ;
498+ rv = 0 ;
469499 spi_set_cs (true);
470500
471- if (count == 1 ) {
501+ if (read_count == 1 ) {
472502 /* Ask the card for the block */
473503 if (sd_send_cmd (CMD (17 ), block )) {
474504 rv = -1 ;
@@ -477,7 +507,7 @@ int sd_read_blocks(uint32 block, size_t count, uint8 *buf) {
477507 }
478508
479509 /* Read the block back */
480- if (read_data (512 , buf )) {
510+ if (read_data (512 , read_buf )) {
481511 rv = -1 ;
482512 errno = EIO ;
483513 goto out ;
@@ -491,14 +521,14 @@ int sd_read_blocks(uint32 block, size_t count, uint8 *buf) {
491521 goto out ;
492522 }
493523
494- while (count -- ) {
495- if (read_data (512 , buf )) {
524+ while (read_count -- ) {
525+ if (read_data (512 , read_buf )) {
496526 rv = -1 ;
497527 errno = EIO ;
498528 goto out ;
499529 }
500530
501- buf += 512 ;
531+ read_buf += 512 ;
502532 }
503533
504534 /* Stop the data transfer */
@@ -507,6 +537,12 @@ int sd_read_blocks(uint32 block, size_t count, uint8 *buf) {
507537
508538out :
509539 spi_set_cs (false);
540+ if (rv && !retried ) {
541+ retried = true;
542+ if (!sd_reinit ()) {
543+ goto read_blocks ;
544+ }
545+ }
510546 spi_rw_byte (0xFF );
511547
512548 return rv ;
@@ -516,7 +552,6 @@ static int write_data(uint8 tag, size_t bytes, const uint8 *buf) {
516552 uint8 rv ;
517553 int i = 0 ;
518554 uint16 crc ;
519- const uint8 * ptr = buf ;
520555
521556 /* Wait for the card to be ready for our data */
522557 spi_rw_byte (0xFF );
@@ -532,8 +567,8 @@ static int write_data(uint8 tag, size_t bytes, const uint8 *buf) {
532567
533568 /* Send the data. */
534569 crc = net_crc16ccitt (buf , bytes , 0 );
535- while ( bytes -- ) {
536- spi_write_byte ( * ptr ++ ) ;
570+ if ( spi_write_data ( buf , bytes ) ) {
571+ return -1 ;
537572 }
538573
539574 /* Write out the block's crc */
@@ -549,8 +584,11 @@ static int write_data(uint8 tag, size_t bytes, const uint8 *buf) {
549584}
550585
551586int sd_write_blocks (uint32 block , size_t count , const uint8 * buf ) {
552- int rv = 0 , i = 0 ;
553- uint8 byte ;
587+ int rv , i = 0 ;
588+ uint8_t byte ;
589+ size_t write_count ;
590+ uint8_t * write_buf ;
591+ bool retried = false;
554592
555593 if (!initted ) {
556594 errno = ENXIO ;
@@ -561,18 +599,22 @@ int sd_write_blocks(uint32 block, size_t count, const uint8 *buf) {
561599 if (byte_mode )
562600 block <<= 9 ;
563601
602+ write_blocks :
603+ write_count = count ;
604+ write_buf = buf ;
605+ rv = 0 ;
564606 spi_set_cs (true);
565607
566- if (count == 1 ) {
608+ if (write_count == 1 ) {
567609 /* Prepare the card for the block */
568610 if (sd_send_cmd (CMD (24 ), block )) {
569611 rv = -1 ;
570612 errno = EIO ;
571613 goto out ;
572614 }
573615
574- /* Read the block back */
575- if (write_data (0xFE , 512 , buf )) {
616+ /* Write the block */
617+ if (write_data (0xFE , 512 , write_buf )) {
576618 rv = -1 ;
577619 errno = EIO ;
578620 goto out ;
@@ -583,7 +625,7 @@ int sd_write_blocks(uint32 block, size_t count, const uint8 *buf) {
583625 we intend to write. */
584626 if (!is_mmc ) {
585627 sd_send_cmd (CMD (55 ), 0 );
586- sd_send_cmd (CMD (23 ), count );
628+ sd_send_cmd (CMD (23 ), write_count );
587629 }
588630
589631 /* Set up the multi-block write */
@@ -593,15 +635,15 @@ int sd_write_blocks(uint32 block, size_t count, const uint8 *buf) {
593635 goto out ;
594636 }
595637
596- while (count -- ) {
597- if (write_data (0xFC , 512 , buf )) {
638+ while (write_count -- ) {
639+ if (write_data (0xFC , 512 , write_buf )) {
598640 /* Make sure we at least try to stop the transfer... */
599641 rv = -1 ;
600642 errno = EIO ;
601643 break ;
602644 }
603645
604- buf += 512 ;
646+ write_buf += 512 ;
605647 }
606648
607649 /* Write the end data token. */
@@ -622,6 +664,12 @@ int sd_write_blocks(uint32 block, size_t count, const uint8 *buf) {
622664
623665out :
624666 spi_set_cs (false);
667+ if (rv && !retried ) {
668+ retried = true;
669+ if (!sd_reinit ()) {
670+ goto write_blocks ;
671+ }
672+ }
625673 spi_rw_byte (0xFF );
626674
627675 return rv ;
0 commit comments