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);
> }
>
>