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


Reply via email to