On Thu, Jan 8, 2009 at 9:51 AM, Jonathan Gray <j...@goblin.cx> wrote:
> On Thu, Jan 08, 2009 at 09:32:47AM -0500, Dan Colish wrote: > > > > The latest patch works great for me. I was not able to write disklabels > with > > the prior patch, probably due to the block write code missing. As soon as > I > > get the card up, I'll post some i/o benchmarks. > > Well it's an SD card, don't expect miracles. > > Here is a bonus revised revised patch that lets you use SD cards > after SDHC cards by storing the flag state in a better card specific > state structure. > > I'd appreciate it if people testing this stuff could test on > a range of SDHC and normal cards and tell me what size cards/ > which controllers they are testing against. > > Thanks > > Index: sdmmc.c > =================================================================== > RCS file: /cvs/src/sys/dev/sdmmc/sdmmc.c,v > retrieving revision 1.16 > diff -u -p -r1.16 sdmmc.c > --- sdmmc.c 2 Dec 2008 23:49:54 -0000 1.16 > +++ sdmmc.c 8 Jan 2009 12:49:43 -0000 > @@ -569,6 +569,32 @@ sdmmc_go_idle_state(struct sdmmc_softc * > } > > /* > + * Send the "SEND_IF_COND" command, to check operating condition > + */ > +int > +sdmmc_send_if_cond(struct sdmmc_softc *sc, uint32_t card_ocr) > +{ > + struct sdmmc_command cmd; > + uint8_t pat = 0x23; > + uint8_t res; > + > + bzero(&cmd, sizeof cmd); > + > + cmd.c_opcode = SD_SEND_IF_COND; > + cmd.c_arg = ((card_ocr & SD_OCR_VOL_MASK) != 0) << 8 | pat; > + cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R7; > + > + if (sdmmc_mmc_command(sc, &cmd) != 0) > + return 1; > + > + res = cmd.c_resp[0]; > + if (res != pat) > + return 1; > + else > + return 0; > +} > + > +/* > * Retrieve (SD) or set (MMC) the relative card address (RCA). > */ > int > Index: sdmmc_mem.c > =================================================================== > RCS file: /cvs/src/sys/dev/sdmmc/sdmmc_mem.c,v > retrieving revision 1.9 > diff -u -p -r1.9 sdmmc_mem.c > --- sdmmc_mem.c 2 Dec 2008 23:49:54 -0000 1.9 > +++ sdmmc_mem.c 8 Jan 2009 12:49:43 -0000 > @@ -93,6 +93,9 @@ sdmmc_mem_enable(struct sdmmc_softc *sc) > /* Tell the card(s) to enter the idle state (again). */ > sdmmc_go_idle_state(sc); > > + if (sdmmc_send_if_cond(sc, card_ocr) == 0) > + host_ocr |= SD_OCR_SDHC_CAP; > + > /* Send the new OCR value until all cards are ready. */ > if (sdmmc_mem_send_op_cond(sc, host_ocr, NULL) != 0) { > DPRINTF(("%s: can't send memory OCR\n", SDMMCDEVNAME(sc))); > @@ -224,14 +227,23 @@ sdmmc_decode_csd(struct sdmmc_softc *sc, > * specification version 1.0 - 1.10. (SanDisk, 3.5.3) > */ > csd->csdver = SD_CSD_CSDVER(resp); > - if (csd->csdver != SD_CSD_CSDVER_1_0) { > + switch (csd->csdver) { > + case SD_CSD_CSDVER_2_0: > + sf->flags |= SFF_SDHC; > + csd->capacity = SD_CSD_V2_CAPACITY(resp); > + csd->read_bl_len = SD_CSD_V2_BL_LEN; > + break; > + case SD_CSD_CSDVER_1_0: > + csd->capacity = SD_CSD_CAPACITY(resp); > + csd->read_bl_len = SD_CSD_READ_BL_LEN(resp); > + break; > + default: > printf("%s: unknown SD CSD structure version > 0x%x\n", > SDMMCDEVNAME(sc), csd->csdver); > return 1; > + break; > } > > - csd->capacity = SD_CSD_CAPACITY(resp); > - csd->read_bl_len = SD_CSD_READ_BL_LEN(resp); > } else { > csd->csdver = MMC_CSD_CSDVER(resp); > if (csd->csdver != MMC_CSD_CSDVER_1_0 && > @@ -403,7 +415,10 @@ sdmmc_mem_read_block(struct sdmmc_functi > cmd.c_blklen = sf->csd.sector_size; > cmd.c_opcode = (datalen / cmd.c_blklen) > 1 ? > MMC_READ_BLOCK_MULTIPLE : MMC_READ_BLOCK_SINGLE; > - cmd.c_arg = blkno << 9; > + if (sf->flags & SFF_SDHC) > + cmd.c_arg = blkno; > + else > + cmd.c_arg = blkno << 9; > cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1; > > error = sdmmc_mmc_command(sc, &cmd); > @@ -458,7 +473,10 @@ sdmmc_mem_write_block(struct sdmmc_funct > cmd.c_blklen = sf->csd.sector_size; > cmd.c_opcode = (datalen / cmd.c_blklen) > 1 ? > MMC_WRITE_BLOCK_MULTIPLE : MMC_WRITE_BLOCK_SINGLE; > - cmd.c_arg = blkno << 9; > + if (sf->flags & SFF_SDHC) > + cmd.c_arg = blkno; > + else > + cmd.c_arg = blkno << 9; > cmd.c_flags = SCF_CMD_ADTC | SCF_RSP_R1; > > error = sdmmc_mmc_command(sc, &cmd); > Index: sdmmcreg.h > =================================================================== > RCS file: /cvs/src/sys/dev/sdmmc/sdmmcreg.h,v > retrieving revision 1.3 > diff -u -p -r1.3 sdmmcreg.h > --- sdmmcreg.h 18 Mar 2007 22:21:21 -0000 1.3 > +++ sdmmcreg.h 8 Jan 2009 12:49:44 -0000 > @@ -38,6 +38,7 @@ > > /* SD commands */ /* response type */ > #define SD_SEND_RELATIVE_ADDR 3 /* R6 */ > +#define SD_SEND_IF_COND 8 /* R7 */ > > /* SD application commands */ /* response type */ > #define SD_APP_SET_BUS_WIDTH 6 /* R1 */ > @@ -66,6 +67,9 @@ > #define MMC_OCR_1_7V_1_8V (1<<5) > #define MMC_OCR_1_6V_1_7V (1<<4) > > +#define SD_OCR_SDHC_CAP (1<<30) > +#define SD_OCR_VOL_MASK 0xFF8000 /* bits 23:15 */ > + > /* R1 response type bits */ > #define MMC_R1_READY_FOR_DATA (1<<8) /* ready for next transfer > */ > #define MMC_R1_APP_CMD (1<<5) /* app. commands supported > */ > @@ -134,6 +138,7 @@ > /* SD R2 response (CSD) */ > #define SD_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2) > #define SD_CSD_CSDVER_1_0 0 > +#define SD_CSD_CSDVER_2_0 1 > #define SD_CSD_TAAC(resp) MMC_RSP_BITS((resp), 112, 8) > #define SD_CSD_TAAC_1_5_MSEC 0x26 > #define SD_CSD_NSAC(resp) MMC_RSP_BITS((resp), 104, 8) > @@ -150,6 +155,9 @@ > #define SD_CSD_C_SIZE(resp) MMC_RSP_BITS((resp), 62, 12) > #define SD_CSD_CAPACITY(resp) ((SD_CSD_C_SIZE((resp))+1) << \ > (SD_CSD_C_SIZE_MULT((resp))+2)) > +#define SD_CSD_V2_C_SIZE(resp) MMC_RSP_BITS((resp), 48, 22) > +#define SD_CSD_V2_CAPACITY(resp) ((SD_CSD_V2_C_SIZE((resp))+1) << > 10) > +#define SD_CSD_V2_BL_LEN 0x9 /* 512 */ > #define SD_CSD_VDD_R_CURR_MIN(resp) MMC_RSP_BITS((resp), 59, 3) > #define SD_CSD_VDD_R_CURR_MAX(resp) MMC_RSP_BITS((resp), 56, 3) > #define SD_CSD_VDD_W_CURR_MIN(resp) MMC_RSP_BITS((resp), 53, 3) > Index: sdmmcvar.h > =================================================================== > RCS file: /cvs/src/sys/dev/sdmmc/sdmmcvar.h,v > retrieving revision 1.12 > diff -u -p -r1.12 sdmmcvar.h > --- sdmmcvar.h 2 Dec 2008 23:49:54 -0000 1.12 > +++ sdmmcvar.h 8 Jan 2009 12:49:44 -0000 > @@ -98,6 +98,7 @@ struct sdmmc_command { > #define SCF_RSP_R5 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) > #define SCF_RSP_R5B > (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY) > #define SCF_RSP_R6 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) > +#define SCF_RSP_R7 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) > int c_error; /* errno value on completion */ > > /* Host controller owned fields for data xfer in progress */ > @@ -135,6 +136,7 @@ struct sdmmc_function { > u_int16_t rca; /* relative card address */ > int flags; > #define SFF_ERROR 0x0001 /* function is poo; ignore it */ > +#define SFF_SDHC 0x0002 /* SD High Capacity card */ > SIMPLEQ_ENTRY(sdmmc_function) sf_list; > /* SD card I/O function members */ > int number; /* I/O function number or -1 */ > @@ -200,6 +202,7 @@ void sdmmc_go_idle_state(struct sdmmc_so > int sdmmc_select_card(struct sdmmc_softc *, struct sdmmc_function *); > int sdmmc_set_relative_addr(struct sdmmc_softc *, > struct sdmmc_function *); > +int sdmmc_send_if_cond(struct sdmmc_softc *, uint32_t); > > void sdmmc_intr_enable(struct sdmmc_function *); > void sdmmc_intr_disable(struct sdmmc_function *); > When I attempted to copy files to the sdhc card, I got an out of inodes error. uid 0 on /tmp/home: out of inodes I created the filesystem using newfs. I then unmounted and tried to remount to now luck. Just pulling the card produced this error. Data modified on freelist: word 7 of object 0xd21fd400 size 0x32c previous type UVM amap (0xefffeecf != 0xefffeecc) I'm also having some trouble with unmounting/mounting. The device unmounts but when I try to remount I get device is busy. I