Revision: dc2c51cb07
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 09:36:55 2010
Log: make non-sdhc sd cards work....
http://code.google.com/p/inferno-kirkwood/source/detail?r=dc2c51cb07
Revision: 22e2014feb
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 09:53:29 2010
Log: don't just check for "dma ready". always check for errors first....
http://code.google.com/p/inferno-kirkwood/source/detail?r=22e2014feb
Revision: 39d3266e38
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 10:29:28 2010
Log: make non-high capacity cards work....
http://code.google.com/p/inferno-kirkwood/source/detail?r=39d3266e38
Revision: a2c9879dc3
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 13:58:10 2010
Log: erase command, erase before writing.
http://code.google.com/p/inferno-kirkwood/source/detail?r=a2c9879dc3
Revision: 2f012a0fc6
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 14:41:56 2010
Log: do not lose interrupts for completion.
http://code.google.com/p/inferno-kirkwood/source/detail?r=2f012a0fc6
Revision: 74e02f46ac
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 15:22:01 2010
Log: little cleanup: shorter names in csd reg struct.
http://code.google.com/p/inferno-kirkwood/source/detail?r=74e02f46ac
==============================================================================
Revision: dc2c51cb07
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 09:36:55 2010
Log: make non-sdhc sd cards work.
i was setting block length to what the device reported. but that
should be ignored and a blocksize of 512 bytes should be used.
http://code.google.com/p/inferno-kirkwood/source/detail?r=dc2c51cb07
Modified:
/devsdio.c
=======================================
--- /devsdio.c Sun Mar 28 07:18:45 2010
+++ /devsdio.c Sun Mar 28 09:36:55 2010
@@ -333,7 +333,7 @@
ulong need;
uvlong w;
- print("sdcmd, cmd %ld, arg %ld, fl %#lux\n", cmd, arg, fl);
+ print("sdcmd, cmd %lud, arg %lud, fl %#lux\n", cmd, arg, fl);
i = 0;
for(;;) {
@@ -611,9 +611,9 @@
if(s < 0)
errorsd("setting buswidth to 4-bit", s);
- s = sdcmd(&card, 16, card.bs, R1, 0);
+ s = sdcmd(&card, 16, 512, R1, 0);
if(s < 0)
- errorsd("setting block length", s);
+ errorsd("setting 512 byte blocksize", s);
sdiotab[Qdata].length = card.size;
card.valid = 1;
@@ -634,9 +634,9 @@
if((ulong)a % 4 != 0)
error("bad buffer alignment...");
- if(offset % card.bs != 0)
+ if(offset & (512-1))
error("not sector aligned");
- if(n % card.bs != 0)
+ if(n & (512-1))
error("not multiple of sector size");
cmd = CMDReadmulti;
@@ -649,13 +649,13 @@
h = 0;
for(;;) {
if(card.sdhc)
- arg = (offset+h)/card.bs;
+ arg = (offset+h)/512;
else
arg = offset+h;
nn = n;
if(nn > 512*1024)
nn = 512*1024;
- s = sdcmddma(&card, cmd, arg, a+h, card.bs, nn/card.bs, R1, fl|Fmulti);
+ s = sdcmddma(&card, cmd, arg, a+h, 512, nn/512, R1, fl|Fmulti);
if(s < 0)
errorsd("io", s);
h += nn;
==============================================================================
Revision: 22e2014feb
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 09:53:29 2010
Log: don't just check for "dma ready". always check for errors first.
also another failed attempt to read the scr register...
http://code.google.com/p/inferno-kirkwood/source/detail?r=22e2014feb
Modified:
/devsdio.c
/sdcard.c
=======================================
--- /devsdio.c Sun Mar 28 09:36:55 2010
+++ /devsdio.c Sun Mar 28 09:53:29 2010
@@ -405,7 +405,7 @@
if(s == SDInterrupted)
return s;
- if((r->st & need) == 0) {
+ if(r->st & (Sunexpresp|Serror) || (r->st & need) == 0) {
card.status = r->est;
return SDError;
}
@@ -600,10 +600,22 @@
errorsd("selecting card", s);
if(0){
- uchar *p = malloc(512);
- s = sdcmddma(&card, 51, 1<<0, p, 512, 1, R1, Fappdata|Fdmad2h);
+ uchar *p = malloc(64);
+ Scr scr;
+
+ s = sdcmd(&card, 16, 64, R1, 0);
+ if(s < 0)
+ errorsd("setting 64 byte blocksize", s);
+
+ s = sdcmddma(&card, 51, 1<<0, p, 64, 1, R1, Fapp|Fdmad2h);
if(s < 0)
errorsd("read scr", s);
+
+ if(parsescr(&scr, card.resp) < 0)
+ error("bad scr register");
+
+ print("scr: vers %ud, spec %ud, dataerased %ud, sec %ud, buswidth %ud\n",
+ (uint)scr.vers, (uint)scr.spec, (uint)scr.dataerased, (uint)scr.sec,
(uint)scr.buswidth);
}
/* xxx have to check if this is supported by card. in scr register */
=======================================
--- /sdcard.c Thu Mar 18 06:11:29 2010
+++ /sdcard.c Sun Mar 28 09:53:29 2010
@@ -16,8 +16,9 @@
return b;
}
+/* return bits h(igh) to l(ow) (inclusive) from big endian r[3] */
static ulong
-bits(uvlong *r, int h, int l)
+bits(uvlong r[3], int h, int l)
{
uvlong v;
int o;
@@ -220,17 +221,11 @@
int
parsescr(Scr *s, uvlong *r)
{
-/* xxx */
- USED(s);
- USED(r);
-/*
-63-60 scr
-59-56 spec
-55-55 data status after erase
-54-52 security
-51-48 bus width
-47-32 reserved
-31-0 reserved for manufacturer
-*/
- return -1; /* not yet */
-}
+ s->vers = bits(r, 63, 60);
+ s->spec = bits(r, 59, 56);
+ s->dataerased = bits(r, 55, 55);
+ s->sec = bits(r, 54, 52);
+ s->buswidth = bits(r, 51, 48);
+
+ return 0;
+}
==============================================================================
Revision: 39d3266e38
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 10:29:28 2010
Log: make non-high capacity cards work.
just tested against some old cards i found. sizes: 64mb, 128mb, 256mb, 2gb.
http://code.google.com/p/inferno-kirkwood/source/detail?r=39d3266e38
Modified:
/devsdio.c
=======================================
--- /devsdio.c Sun Mar 28 09:53:29 2010
+++ /devsdio.c Sun Mar 28 10:29:28 2010
@@ -2,9 +2,9 @@
* only memory cards are supported (not sdio). only sd cards for now, mmc
cards seem obsolete anyway.
*
* todo:
+ * - interrupts are sometimes lost?
* - don't crash when proc doing read/write is killed.
* - hook into devsd.c?
- * - test with non-high capacity sd cards. i think it does need different
code.
* - see if we can detect device inserts/ejects? yes, by sd_cd gpio pin
(on mpp47).
* - ctl commands for erasing?
* - erase before writing big buffer?
@@ -501,16 +501,26 @@
card.sdhc = 0;
card.rca = 0;
s = sdcmd(&card, 8, CMD8voltage|CMD8pattern, R7, 0);
- if(s == SDOk) {
+ switch(s) {
+ case SDOk:
card.sd2 = 1;
v = card.resp[2]>>8;
if((v & CMD8patternmask) != CMD8pattern)
error("check pattern mismatch");
- if((v & CMD8voltagemask) != CMD8voltage) {
+ if((v & CMD8voltagemask) != CMD8voltage)
error("voltage not supported");
- }
- } else if(s != SDTimeout)
- error("voltage exchange failed");
+ break;
+
+ case SDTimeout:
+ case SDError: /* "no response" from spec can result in error too
apparently */
+ /* sd 1.x or not an sd memory card */
+ s = sdcmd(&card, 0, 0, R0, 0);
+ if(s < 0)
+ errorsd("reset failed", s);
+ break;
+ default:
+ errorsd("voltage exchange failed", s);
+ }
/*
* "send host capacity support information".
@@ -520,7 +530,9 @@
*/
i = 0;
for(;;) {
- v = ACMD41sdhcsupported|ACMD41voltagewindow;
+ v = ACMD41voltagewindow;
+ if(card.sd2)
+ v |= ACMD41sdhcsupported;
s = sdcmd(&card, 41, v, R3, Fapp);
if(s < 0) {
if(s == SDTimeout && !card.sd2)
@@ -535,9 +547,9 @@
break;
}
- if(i >= 100)
+ if(i++ >= 100)
error("sd card failed to power up");
- tsleep(&up->sleep, return0, nil, 5);
+ tsleep(&up->sleep, return0, nil, 10);
}
dprint("acmd41 done, mmc %d, sd2 %d, sdhc %d\n", card.mmc, card.sd2,
card.sdhc);
if(card.mmc)
==============================================================================
Revision: a2c9879dc3
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 13:58:10 2010
Log: erase command, erase before writing.
http://code.google.com/p/inferno-kirkwood/source/detail?r=a2c9879dc3
Modified:
/devsdio.c
=======================================
--- /devsdio.c Sun Mar 28 10:29:28 2010
+++ /devsdio.c Sun Mar 28 13:58:10 2010
@@ -5,6 +5,8 @@
* - interrupts are sometimes lost?
* - don't crash when proc doing read/write is killed.
* - hook into devsd.c?
+ * - wait reading dat[0] in hoststate for r1b responses?
+ * - read scr register and use it to determine if card supports 4bit data
bus
* - see if we can detect device inserts/ejects? yes, by sd_cd gpio pin
(on mpp47).
* - ctl commands for erasing?
* - erase before writing big buffer?
@@ -74,6 +76,7 @@
/* hoststate */
HScmdinhibit = 1<<0,
HScardbusy = 1<<1,
+ HSdatshift = 3,
HStxactive = 1<<8,
HSrxactive = 1<<9,
HSfifofull = 1<<12,
@@ -405,10 +408,12 @@
if(s == SDInterrupted)
return s;
- if(r->st & (Sunexpresp|Serror) || (r->st & need) == 0) {
+ if(r->st & (Sunexpresp|Serror)) {
card.status = r->est;
return SDError;
}
+ if((r->st & need) == 0)
+ return SDTimeout;
printstatus("success", r->st, r->est, r->acmd12st);
@@ -463,11 +468,11 @@
dcwbinv(a, blsz*nbl);
r->dmaaddrlo = (ulong)a & MASK(16);
- r->dmaaddrhi = ((ulong)a>>16) & MASK(16);
+ r->dmaaddrhi = (ulong)a>>16 & MASK(16);
r->blksize = blsz;
r->blkcount = nbl;
dprint("sdcmddma, a %#lux, dmaddrlo %#lux dmaadrhi %#lux blksize %d
blkcount %d cmdarg %#lux\n",
- a, (ulong)a & MASK(16), ((ulong)a>>16) & MASK(16), blsz, nbl, arg);
+ a, (ulong)a & MASK(16), (ulong)a>>16 & MASK(16), blsz, nbl, arg);
return sdcmd(c, cmd, arg, resp, fl);
}
@@ -475,6 +480,7 @@
sdclock(ulong v)
{
SDIOREG->clockdiv = ((100*1000*1000)/v)-1;
+ delay(1);
}
static void
@@ -566,8 +572,8 @@
s = sdcmd(&card, 3, 0, R6, 0);
if(s < 0)
errorsd("getting relative address", s);
- card.rca = (card.resp[2]>>24) & MASK(16);
- v = (card.resp[2]>>8) & MASK(16);
+ card.rca = card.resp[2]>>24 & MASK(16);
+ v = card.resp[2]>>8 & MASK(16);
dprint("have card rca %ux, status %lux\n", card.rca, v);
USED(v);
if(card.rca != 0)
@@ -611,26 +617,7 @@
if(s < 0)
errorsd("selecting card", s);
-if(0){
- uchar *p = malloc(64);
- Scr scr;
-
- s = sdcmd(&card, 16, 64, R1, 0);
- if(s < 0)
- errorsd("setting 64 byte blocksize", s);
-
- s = sdcmddma(&card, 51, 1<<0, p, 64, 1, R1, Fapp|Fdmad2h);
- if(s < 0)
- errorsd("read scr", s);
-
- if(parsescr(&scr, card.resp) < 0)
- error("bad scr register");
-
- print("scr: vers %ud, spec %ud, dataerased %ud, sec %ud, buswidth %ud\n",
- (uint)scr.vers, (uint)scr.spec, (uint)scr.dataerased, (uint)scr.sec,
(uint)scr.buswidth);
-}
-
- /* xxx have to check if this is supported by card. in scr register */
+ /* xxx have to check with scr register if 4bit buswidth is supported by
card. have not been able to read it though... */
s = sdcmd(&card, 6, 1<<1, R1, Fapp);
if(s < 0)
errorsd("setting buswidth to 4-bit", s);
@@ -644,6 +631,27 @@
print("%s", cardstr(&card, up->genbuf, sizeof (up->genbuf)));
}
+static int
+erase(vlong offset, long n)
+{
+ vlong e;
+ int s;
+
+ e = offset+n;
+ if(card.sdhc) {
+ e -= 512;
+ offset /= 512;
+ e /= 512;
+ } else
+ e -= 1;
+
+ s = sdcmd(&card, 32, offset, R1, 0); /* first addr to erase */
+ if(s >= 0)
+ s = sdcmd(&card, 33, e, R1, 0); /* last addr to erase (inclusive) */
+ if(s >= 0)
+ s = sdcmd(&card, 38, 0, R1b, 0); /* start erasing */
+ return s;
+}
static long
sdio(uchar *a, long n, vlong offset, int iswrite)
@@ -679,6 +687,11 @@
nn = n;
if(nn > 512*1024)
nn = 512*1024;
+ if(iswrite) {
+ s = sdcmd(&card, 23, nn/512, R1, Fapp);
+ if(s < 0)
+ errorsd("erase before write", s);
+ }
s = sdcmddma(&card, cmd, arg, a+h, 512, nn/512, R1, fl|Fmulti);
if(s < 0)
errorsd("io", s);
@@ -857,13 +870,14 @@
}
enum {
- CMreset, CMinit, CMclean,
+ CMreset, CMinit, CMclean, CMerase,
};
static Cmdtab sdioctl[] =
{
CMreset, "reset", 1,
CMinit, "init", 1,
CMclean, "clean", 1,
+ CMerase, "erase", 3,
};
static long
@@ -872,6 +886,9 @@
Cmdbuf *cb;
Cmdtab *ct;
SdioReg *r = SDIOREG;
+ vlong eoff;
+ long en;
+ int s;
qlock(&sdl);
if(waserror()) {
@@ -902,6 +919,13 @@
r->est = ~0;
r->acmd12st = ~0;
break;
+ case CMerase:
+ eoff = strtoll(cb->f[1], nil, 0);
+ en = strtol(cb->f[2], nil, 0);
+ s = erase(eoff, en);
+ if(s < 0)
+ errorsd("erase", s);
+ break;
}
poperror();
free(cb);
==============================================================================
Revision: 2f012a0fc6
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 14:41:56 2010
Log: do not lose interrupts for completion.
http://code.google.com/p/inferno-kirkwood/source/detail?r=2f012a0fc6
Modified:
/devsdio.c
=======================================
--- /devsdio.c Sun Mar 28 13:58:10 2010
+++ /devsdio.c Sun Mar 28 14:41:56 2010
@@ -2,7 +2,6 @@
* only memory cards are supported (not sdio). only sd cards for now, mmc
cards seem obsolete anyway.
*
* todo:
- * - interrupts are sometimes lost?
* - don't crash when proc doing read/write is killed.
* - hook into devsd.c?
* - wait reading dat[0] in hoststate for r1b responses?
@@ -21,7 +20,7 @@
#include "io.h"
#include "sdcard.h"
-#define DEBUG 1
+#define DEBUG 0
#define dprint if(DEBUG)print
char Enocard[] = "no card";
@@ -311,11 +310,12 @@
}
static int
-isdone(void *)
+sdiodone(void *p)
{
SdioReg *r = SDIOREG;
-
- if(r->st & r->stirq) {
+ ulong v = *(ulong *)p;
+
+ if(r->st & v) {
r->stirq = 0;
return 1;
}
@@ -333,7 +333,7 @@
int i, s;
ulong acmd;
ulong cmdopts, mode;
- ulong need;
+ ulong need, v;
uvlong w;
print("sdcmd, cmd %lud, arg %lud, fl %#lux\n", cmd, arg, fl);
@@ -344,7 +344,7 @@
break;
if(i++ >= 50)
return SDCardbusy;
- tsleep(&up->sleep, return0, nil, 10);
+ tsleep(&up->sleep, return0, nil, i);
}
if(fl & (Fapp|Fappdata)) {
@@ -365,9 +365,6 @@
// xxx remove?
printstatus("before cmd: ", r->st, r->est, r->acmd12st);
- // xxx?
- microdelay(1000);
-
/* prepare args & execute command */
r->arglo = arg>>0 & MASK(16);
r->arghi = arg>>16 & MASK(16);
@@ -401,13 +398,15 @@
need = Sdmaintr;
r->stirq = need|Sunexpresp|Serror;
r->estirq = ~0;
+
while(waserror())
s = SDInterrupted;
- tsleep(&cmdr, isdone, nil, 5000);
+ v = r->stirq;
+ tsleep(&cmdr, sdiodone, &v, 5000);
poperror();
-
if(s == SDInterrupted)
return s;
+
if(r->st & (Sunexpresp|Serror)) {
card.status = r->est;
return SDError;
==============================================================================
Revision: 74e02f46ac
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Sun Mar 28 15:22:01 2010
Log: little cleanup: shorter names in csd reg struct.
http://code.google.com/p/inferno-kirkwood/source/detail?r=74e02f46ac
Modified:
/devsdio.c
/sdcard.c
/sdcard.h
=======================================
--- /devsdio.c Sun Mar 28 14:41:56 2010
+++ /devsdio.c Sun Mar 28 15:22:01 2010
@@ -587,16 +587,16 @@
if(parsecsd(&card.csd, card.resp) < 0)
error("bad csd register");
- if(card.csd.version == 0) {
- card.bs = 1<<card.csd.readblocklength;
+ if(card.csd.vers == 0) {
+ card.bs = 1<<card.csd.rbl;
card.size = card.csd.size+1;
card.size *= 1<<(card.csd.v0.sizemult+2);
- card.size *= 1<<card.csd.readblocklength;
+ card.size *= 1<<card.csd.rbl;
print("csd0, block length read/write %d/%d, size %lld bytes,
eraseblock %d\n",
- 1<<card.csd.readblocklength,
- 1<<card.csd.writeblocklength,
+ 1<<card.csd.rbl,
+ 1<<card.csd.wbl,
card.size,
- (1<<card.csd.writeblocklength)*(card.csd.erasesectorsize+1));
+ (1<<card.csd.wbl)*(card.csd.erasesecsz+1));
} else {
card.bs = 512;
card.size = (vlong)(card.csd.size+1)*card.bs*1024;
@@ -629,6 +629,12 @@
card.valid = 1;
print("%s", cardstr(&card, up->genbuf, sizeof (up->genbuf)));
}
+
+static int
+sdstatus(uchar *p)
+{
+ return sdcmddma(&card, 13, 0, p, 64, 1, R1, Fapp|Fdmad2h);
+}
static int
erase(vlong offset, long n)
=======================================
--- /sdcard.c Sun Mar 28 09:53:29 2010
+++ /sdcard.c Sun Mar 28 15:22:01 2010
@@ -79,20 +79,20 @@
int
parsecsd(Csd *c, uvlong *r)
{
- c->version = bits(r, 127, 126);
- if(c->version != 0 && c->version != 1)
+ c->vers = bits(r, 127, 126);
+ if(c->vers != 0 && c->vers != 1)
return -1;
c->taac = bits(r, 119, 112);
c->nsac = bits(r, 111, 104);
- c->xferspeed = bits(r, 103, 96);
- c->cmdclasses = bits(r, 95, 84);
- c->readblocklength = bits(r, 83, 80);
- c->readblockpartial = bits(r, 79, 79);
- c->writeblockmisalign = bits(r, 78, 78);
- c->readblockmisalign = bits(r, 77, 77);
+ c->speed = bits(r, 103, 96);
+ c->ccc = bits(r, 95, 84);
+ c->rbl = bits(r, 83, 80);
+ c->rbpart = bits(r, 79, 79);
+ c->wbmalign = bits(r, 78, 78);
+ c->rbmalign = bits(r, 77, 77);
c->dsr = bits(r, 76, 76);
- if(c->version == 0) {
+ if(c->vers == 0) {
c->size = bits(r, 75, 62);
c->v0.vddrmin = bits(r, 61, 59);
c->v0.vddrmax = bits(r, 58, 56);
@@ -102,18 +102,18 @@
} else {
c->size = bits(r, 69, 48);
}
- c->eraseblockenable = bits(r, 46, 46);
- c->erasesectorsize = bits(r, 45, 39);
- c->wpgroupsize = bits(r, 38, 32);
- c->wpgroupenable = bits(r, 31, 31);
- c->writespeedfactor = bits(r, 28, 26);
- c->writeblocklength = bits(r, 25, 22);
- c->writeblockpartial = bits(r, 21, 21);
- c->fileformatgroup = bits(r, 15, 15);
+ c->eraseblk = bits(r, 46, 46);
+ c->erasesecsz = bits(r, 45, 39);
+ c->wpgrpsize = bits(r, 38, 32);
+ c->wpgrp = bits(r, 31, 31);
+ c->speedfactor = bits(r, 28, 26);
+ c->wbl = bits(r, 25, 22);
+ c->wbpart = bits(r, 21, 21);
+ c->ffgrp = bits(r, 15, 15);
c->copy = bits(r, 14, 14);
- c->permwriteprotect = bits(r, 13, 13);
- c->tmpwriteprotect = bits(r, 12, 12);
- c->fileformat = bits(r, 11, 10);
+ c->permwp = bits(r, 13, 13);
+ c->tmpwp = bits(r, 12, 12);
+ c->ff = bits(r, 11, 10);
return 0;
}
@@ -124,7 +124,7 @@
char versbuf[128];
versbuf[0] = '\0';
- if(c->version == 0)
+ if(c->vers == 0)
snprint(versbuf, sizeof versbuf,
"vddrmin %x\n"
"vddrmax %x\n"
@@ -137,54 +137,54 @@
c->v0.vddwmax,
c->v0.sizemult);
return seprint(p, e,
- "version %x\n"
- "taac %x\n"
- "nsac %x\n"
- "xferspeed %x\n"
- "cmdclasses %x\n"
- "readblocklength %x\n"
- "readblockpartial %x\n"
- "writeblockmisalign %x\n"
- "readblockmisalign %x\n"
- "dsr %x\n"
- "devsize %x\n"
+ "version %ux\n"
+ "taac %ux\n"
+ "nsac %ux\n"
+ "transferspeed %ux\n"
+ "card command classes %ux\n"
+ "readblocklength %ux\n"
+ "readblockpartial %ux\n"
+ "writeblockmisalign %ux\n"
+ "readblockmisalign %ux\n"
+ "dsr %ux\n"
+ "devsize %ux\n"
"%s"
- "eraseblockenable %x\n"
- "erasesectorsize %x\n"
- "wpgroupsize %x\n"
- "wpgroupenable %x\n"
- "writespeedfactor %x\n"
- "writeblocklength %x\n"
- "writeblockpartial %x\n"
- "fileformatgroup %x\n"
- "copy %x\n"
- "permwriteprotect %x\n"
- "tmpwriteprotect %x\n"
- "fileformat %x\n",
- c->version,
- c->taac,
- c->nsac,
- c->xferspeed,
- c->cmdclasses,
- c->readblocklength,
- c->readblockpartial,
- c->writeblockmisalign,
- c->readblockmisalign,
- c->dsr,
- c->size,
+ "eraseblockenable %ux\n"
+ "erasesectorsize %ux\n"
+ "wpgroupsize %ux\n"
+ "wpgroupenable %ux\n"
+ "writespeedfactor %ux\n"
+ "writeblocklength %ux\n"
+ "writeblockpartial %ux\n"
+ "fileformatgroup %ux\n"
+ "copy %ux\n"
+ "permwriteprotect %ux\n"
+ "tmpwriteprotect %ux\n"
+ "fileformat %ux\n",
+ (uint)c->vers,
+ (uint)c->taac,
+ (uint)c->nsac,
+ (uint)c->speed,
+ (uint)c->ccc,
+ (uint)c->rbl,
+ (uint)c->rbpart,
+ (uint)c->wbmalign,
+ (uint)c->rbmalign,
+ (uint)c->dsr,
+ (uint)c->size,
versbuf,
- c->eraseblockenable,
- c->erasesectorsize,
- c->wpgroupsize,
- c->wpgroupenable,
- c->writespeedfactor,
- c->writeblocklength,
- c->writeblockpartial,
- c->fileformatgroup,
- c->copy,
- c->permwriteprotect,
- c->tmpwriteprotect,
- c->fileformat);
+ (uint)c->eraseblk,
+ (uint)c->erasesecsz,
+ (uint)c->wpgrpsize,
+ (uint)c->wpgrp,
+ (uint)c->speedfactor,
+ (uint)c->wbl,
+ (uint)c->wbpart,
+ (uint)c->ffgrp,
+ (uint)c->copy,
+ (uint)c->permwp,
+ (uint)c->tmpwp,
+ (uint)c->ff);
}
char*
=======================================
--- /sdcard.h Sun Mar 28 07:18:45 2010
+++ /sdcard.h Sun Mar 28 15:22:01 2010
@@ -14,31 +14,40 @@
int mon;
};
-/* xxx make shorter but still readable names */
struct Csd
{
- int version;
- int taac, nsac;
- int xferspeed;
- int cmdclasses;
- int readblocklength, readblockpartial;
- int writeblockmisalign, readblockmisalign;
- int dsr;
- int size;
+ uchar vers; /* version */
+ uchar taac; /* data read access time */
+ uchar nsac; /* idem */
+ uchar speed; /* transfer speed */
+ ushort ccc; /* card command classes */
+ uchar rbl; /* read block length, log 2 */
+ uchar rbpart; /* partial block reads allowed */
+ uchar wbmalign; /* writes on misaligned blocks allowed */
+ uchar rbmalign; /* idem for reads */
+ uchar dsr; /* whether dsr is implemented */
+ uint size; /* for calculating size */
union {
struct {
- int vddrmin, vddrmax, vddwmin, vddwmax;
- int sizemult;
+ uchar vddrmin;
+ uchar vddrmax;
+ uchar vddwmin;
+ uchar vddwmax;
+ uchar sizemult; /* available bytes: (size+1)*2**(sizemult+2) */
} v0;
};
- int eraseblockenable, erasesectorsize;
- int wpgroupsize, wpgroupenable;
- int writespeedfactor;
- int writeblocklength, writeblockpartial;
- int fileformatgroup;
- int copy;
- int permwriteprotect, tmpwriteprotect;
- int fileformat;
+ uchar eraseblk; /* if areas smaller than sector can be erased */
+ uchar erasesecsz; /* (erasesecsz+1) is number of wbl blocks that are
erased, for eraseblk */
+ uchar wpgrpsize; /* write protected group size */
+ uchar wpgrp; /* idem, enabled */
+ uchar speedfactor; /* read/write speed factor */
+ uchar wbl; /* write block length, log 2 */
+ uchar wbpart; /* partial block writes allowed */
+ uchar ffgrp; /* file format group */
+ uchar copy; /* is this a copy? */
+ uchar permwp; /* permanently write protected */
+ uchar tmpwp; /* temporarily write protected */
+ uchar ff; /* file format */
};
enum {