summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-11-10 04:50:57 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2010-11-10 04:50:57 (GMT)
commit7aec818907a1885a8ac63f84be5f7e2ac5af1f3c (patch)
tree618ac33afd5e844f45fc96fcfb39d4980cc92e3d
parentfc0a3c9c6ef4c92070ebf38c8a77c2d7df519acd (diff)
parent80d8616d5691798a7e7c2978b593ad28787ec49a (diff)
downloadabc8000-old-wf68k00.zip
abc8000-old-wf68k00.tar.gz
abc8000-old-wf68k00.tar.bz2
abc8000-old-wf68k00.tar.xz
Merge branch 'master' into wf68k00wf68k00
-rw-r--r--data/sysrom/sdcard.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/data/sysrom/sdcard.c b/data/sysrom/sdcard.c
index db0d472..c7ee6bc 100644
--- a/data/sysrom/sdcard.c
+++ b/data/sysrom/sdcard.c
@@ -121,7 +121,10 @@ static int sdcard_send_acmd(uint8_t opcode, uint32_t argument)
/*
* Read a data block of length len, with a timeout of (timeout)
- * byte-times. Note that the minimum length is 4 by spec.
+ * byte-times. Note that the minimum length is 4 by spec; under certain
+ * circumstances this function will have a lower minimum.
+ *
+ * The input buffer is allowed to be unaligned.
*/
static int sdcard_read_block(void *buf, int len, int timeout, const void *xcmd)
{
@@ -143,7 +146,7 @@ static int sdcard_read_block(void *buf, int len, int timeout, const void *xcmd)
}
/* Shift in the next data byte */
- if (len & 1) {
+ if ((unsigned long)pb & 1) {
*pb++ = readb(IO_SDC_RD_B(SDC_START|SDC_BYTE));
len--;
} else {
@@ -195,13 +198,19 @@ static int sdcard_read_block(void *buf, int len, int timeout, const void *xcmd)
if (len & 2)
*pw++ = readw(IO_SDC_RD_W(SDC_START));
+ pb = (uint8_t *)pw;
+ if (len & 1)
+ *pb++ = readb(IO_SDC_RD_BH(SDC_START|SDC_BYTE));
+
/*
* Now there are exactly 2 bytes left, and they are already
* latched... read the CRC at this time.
*/
ccrc = readw(IO_SDC_RD_CRC16(0));
- *pw++ = readw(IO_SDC_RD_W(SDC_START));
+ /* Do this with byte operations just in case the buffer is unaligned */
+ pb[0] = readb(IO_SDC_RD_BH(0));
+ pb[1] = readb(IO_SDC_RD_B(SDC_START));
xcrc = readw(IO_SDC_RD_W(SDC_BYTE|SDC_START));
return (ccrc == xcrc) ? 0 : -1;
@@ -257,6 +266,7 @@ static int sdcard_read_reg(uint8_t opcode, void *buf)
/*
* Write a number of sectors; returns the number of sectors written.
+ * XXX: handle unaligned buffer
*/
int sdcard_write_sectors(const void *buf, uint32_t lba, int count)
{