On Fri, October 18, 2013 9:54 am, Sylvestre Gallon wrote: > Hi tech@ > > Here is a diff to allow the sdmmc SMC_CAPS_SINGLE_ONLY caps to do > something. The bits I take are from NetBSD and it works well with > ommmc(4) on my Beagle Bone Black. > > This capability force the sdmmc stack to only issue single blocks > transfers. It is usefull for debug purpose and/or for broken sdmmmc > controller. > > Any OK/Comments ?
This looks good to me. I have tested it with ommmc(4), if needed I can test with pxammc(4) next week. > > Cheers, > > Index: sdmmc_mem.c > =================================================================== > RCS file: /cvs/src/sys/dev/sdmmc/sdmmc_mem.c,v > retrieving revision 1.17 > diff -u -p -u -p -r1.17 sdmmc_mem.c > --- sdmmc_mem.c 12 Sep 2013 11:54:04 -0000 1.17 > +++ sdmmc_mem.c 18 Oct 2013 09:31:15 -0000 > @@ -42,6 +42,14 @@ int sdmmc_mem_mmc_switch(struct sdmmc_fu > > int sdmmc_mem_sd_init(struct sdmmc_softc *, struct sdmmc_function *); > int sdmmc_mem_mmc_init(struct sdmmc_softc *, struct sdmmc_function *); > +int sdmmc_mem_single_read_block(struct sdmmc_function *, int, u_char *, > + size_t); > +int sdmmc_mem_read_block_subr(struct sdmmc_function *, int, u_char *, > + size_t); > +int sdmmc_mem_single_write_block(struct sdmmc_function *, int, u_char *, > + size_t); > +int sdmmc_mem_write_block_subr(struct sdmmc_function *, int, u_char *, > + size_t); > > #ifdef SDMMC_DEBUG > #define DPRINTF(s) printf s > @@ -551,14 +559,13 @@ sdmmc_mem_set_blocklen(struct sdmmc_soft > } > > int > -sdmmc_mem_read_block(struct sdmmc_function *sf, int blkno, u_char *data, > +sdmmc_mem_read_block_subr(struct sdmmc_function *sf, int blkno, u_char *data, > size_t datalen) > { > struct sdmmc_softc *sc = sf->sc; > struct sdmmc_command cmd; > int error; > > - rw_enter_write(&sc->sc_lock); > > if ((error = sdmmc_select_card(sc, sf)) != 0) > goto err; > @@ -602,20 +609,53 @@ sdmmc_mem_read_block(struct sdmmc_functi > } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)); > > err: > - rw_exit(&sc->sc_lock); > - return error; > + return (error); > } > > int > -sdmmc_mem_write_block(struct sdmmc_function *sf, int blkno, u_char *data, > +sdmmc_mem_single_read_block(struct sdmmc_function *sf, int blkno, u_char > *data, > + size_t datalen) > +{ > + int error; > + int i; > + > + for (i = 0; i < datalen / sf->csd.sector_size; i++) { > + error = sdmmc_mem_read_block_subr(sf, blkno + i, data + i * > + sf->csd.sector_size, sf->csd.sector_size); > + if (error) > + break; > + } > + > + return (error); > +} > + > +int > +sdmmc_mem_read_block(struct sdmmc_function *sf, int blkno, u_char *data, > size_t datalen) > { > struct sdmmc_softc *sc = sf->sc; > - struct sdmmc_command cmd; > int error; > > rw_enter_write(&sc->sc_lock); > > + if (ISSET(sc->sc_caps, SMC_CAPS_SINGLE_ONLY)) { > + error = sdmmc_mem_single_read_block(sf, blkno, data, datalen); > + } else { > + error = sdmmc_mem_read_block_subr(sf, blkno, data, datalen); > + } > + > + rw_exit(&sc->sc_lock); > + return (error); > +} > + > +int > +sdmmc_mem_write_block_subr(struct sdmmc_function *sf, int blkno, u_char > *data, > + size_t datalen) > +{ > + struct sdmmc_softc *sc = sf->sc; > + struct sdmmc_command cmd; > + int error; > + > if ((error = sdmmc_select_card(sc, sf)) != 0) > goto err; > > @@ -657,6 +697,41 @@ sdmmc_mem_write_block(struct sdmmc_funct > } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)); > > err: > + return (error); > +} > + > +int > +sdmmc_mem_single_write_block(struct sdmmc_function *sf, int blkno, u_char > *data, > + size_t datalen) > +{ > + int error; > + int i; > + > + for (i = 0; i < datalen / sf->csd.sector_size; i++) { > + error = sdmmc_mem_write_block_subr(sf, blkno + i, data + i * > + sf->csd.sector_size, sf->csd.sector_size); > + if (error) > + break; > + } > + > + return (error); > +} > + > +int > +sdmmc_mem_write_block(struct sdmmc_function *sf, int blkno, u_char *data, > + size_t datalen) > +{ > + struct sdmmc_softc *sc = sf->sc; > + int error; > + > + rw_enter_write(&sc->sc_lock); > + > + if (ISSET(sc->sc_caps, SMC_CAPS_SINGLE_ONLY)) { > + error = sdmmc_mem_single_write_block(sf, blkno, data, datalen); > + } else { > + error = sdmmc_mem_write_block_subr(sf, blkno, data, datalen); > + } > + > rw_exit(&sc->sc_lock); > - return error; > + return (error); > } > >