|
@@ -304,7 +304,7 @@ int sdcard_read_sectors(void *buf, sector_t lba, int count)
|
|
|
|
|
|
sdcard_led_on();
|
|
|
|
|
|
- dbg_printf("sdcard: reading %d sector%s at %u to %p\n",
|
|
|
+ con_printf("sdcard: reading %d sector%s at %u to %p\n",
|
|
|
count, (count != 1) ? "s" : "", lba, buf);
|
|
|
|
|
|
if (sdc.card_type == 1)
|
|
@@ -402,15 +402,16 @@ int sdcard_write_sectors(const void *buf, sector_t lba, int count)
|
|
|
uint16_t crc;
|
|
|
uint8_t resp;
|
|
|
xcptr_t p;
|
|
|
+ bool error = false;
|
|
|
|
|
|
if (!count || (sdc.status & STA_NOINIT))
|
|
|
return 0;
|
|
|
|
|
|
- p.b = buf;
|
|
|
+ p.v = buf;
|
|
|
|
|
|
sdcard_led_on();
|
|
|
|
|
|
- dbg_printf("sdcard: writing %d sectors at %u from %p\n", count, lba, buf);
|
|
|
+ con_printf("sdcard: writing %d sectors at %u from %p\n", count, lba, buf);
|
|
|
|
|
|
if (sdc.card_type == 1)
|
|
|
lba <<= SECTOR_SHIFT; /* Convert to a byte address */
|
|
@@ -431,7 +432,7 @@ int sdcard_write_sectors(const void *buf, sector_t lba, int count)
|
|
|
/* Start block token */
|
|
|
sd_writeb(0xfc, SD_GO8);
|
|
|
|
|
|
- /* Clear the CRC generator; dummy cycle */
|
|
|
+ /* Clear the CRC generator; no output */
|
|
|
sd_writeb(~0, SD_CLEARCRC);
|
|
|
|
|
|
if (podd & 1)
|
|
@@ -449,9 +450,13 @@ int sdcard_write_sectors(const void *buf, sector_t lba, int count)
|
|
|
if (podd & 1)
|
|
|
sd_writeb(*p.b++, SD_GO8);
|
|
|
|
|
|
- sd_writeh(sd_crc16_wr(), SD_GO16);
|
|
|
+ sd_writeh(sd_crc16_wr(), SD_GO16|SD_BE);
|
|
|
+
|
|
|
+ /* Discard byte shifted in during CRC transmission */
|
|
|
+ sd_readb(SD_GO8);
|
|
|
|
|
|
/* Wait for data response token */
|
|
|
+ /* XXX: Timeout */
|
|
|
do {
|
|
|
resp = sd_readb(SD_GO8);
|
|
|
} while ((resp & 0x11) != 0x01);
|
|
@@ -462,8 +467,10 @@ int sdcard_write_sectors(const void *buf, sector_t lba, int count)
|
|
|
* Things are confusing here... the spec says
|
|
|
* that on error we are supposed to issue a
|
|
|
* STOP_TRANSMISSION command, which isn't the normal
|
|
|
- * thing to do for a write... figure this out later.
|
|
|
+ * thing to do for a write; the error flag handles this.
|
|
|
*/
|
|
|
+ con_printf("sdcard: write error: %02x\n", resp);
|
|
|
+ error = true;
|
|
|
break; /* Error */
|
|
|
}
|
|
|
|
|
@@ -478,13 +485,28 @@ int sdcard_write_sectors(const void *buf, sector_t lba, int count)
|
|
|
/* Send stop transmission token */
|
|
|
sd_writeb(0xfd, SD_GO8);
|
|
|
|
|
|
- /* Wait for the card to go busy, then unbusy */
|
|
|
- do {
|
|
|
+ /*
|
|
|
+ * Wait for the card to go busy, then unbusy. The Sandisk
|
|
|
+ * documentation says the busy will happen no more than one byte
|
|
|
+ * after the stop token if it is going to happen at all; be a bit
|
|
|
+ * more cautious and give it up to 8.
|
|
|
+ */
|
|
|
+ for (int i = 0; i < 8; i++) {
|
|
|
resp = sd_readb(SD_GO8);
|
|
|
- } while (resp != 0x00);
|
|
|
- do {
|
|
|
+ if (resp == 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ /* XXX: Timeout */
|
|
|
+ while (resp == 0) {
|
|
|
resp = sd_readb(SD_GO8);
|
|
|
- } while (resp == 0x00);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we got an error, send STOP TRANSMISSION. Not sure why this
|
|
|
+ * is necessary after the stop token, but it apparently is.
|
|
|
+ */
|
|
|
+ if (error)
|
|
|
+ sdcard_send_cmd(CMD_STOP_TRANSMISSION, 0);
|
|
|
|
|
|
out:
|
|
|
sdcard_led_off();
|