On Sun, Feb 15, 2015 at 08:53:08PM +0000, Miod Vallat wrote:
> This ought to fix this problem:

This looks reasonable but needs a tweak if you want to keep the existing
behavior.  In the existing code, it has this section above the copyout():

                rw_enter_write(&sc->sc_lock);
                if (request == SDIOCEXECMMC)
                        error = sdmmc_mmc_command(sc, &cmd);
                else
                        error = sdmmc_app_command(sc, &cmd);
                rw_exit(&sc->sc_lock);
                if (error && !cmd.c_error)
                        cmd.c_error = error;

and returns 0 even if error is non-zero.  With this diff, it will either
return the result of those functions or the result of copyout depending
on whether ucmd->c_data is non-zero.  Using the result of copyout is
intentional, but not the result from sdmmc_{mmc,app}_command().

Could you set error=0 after the above chunk or use a new variable?
Also, one of the new lines has space indents rather than a tab.

> Index: sdmmc.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/sdmmc/sdmmc.c,v
> retrieving revision 1.36
> diff -u -p -r1.36 sdmmc.c
> --- sdmmc.c   1 Nov 2014 16:32:06 -0000       1.36
> +++ sdmmc.c   15 Feb 2015 20:52:08 -0000
> @@ -749,7 +749,7 @@ sdmmc_ioctl(struct device *self, u_long 
>       struct sdmmc_command *ucmd;
>       struct sdmmc_command cmd;
>       void *data;
> -     int error;
> +     int error = 0;
>  
>       switch (request) {
>  #ifdef SDMMC_DEBUG
> @@ -784,8 +784,9 @@ sdmmc_ioctl(struct device *self, u_long 
>                           M_WAITOK | M_CANFAIL);
>                       if (data == NULL)
>                               return ENOMEM;
> -                     if (copyin(ucmd->c_data, data, ucmd->c_datalen))
> -                             return EFAULT;
> +                     error = copyin(ucmd->c_data, data, ucmd->c_datalen);
> +                     if (error != 0)
> +                             goto exec_done;
>  
>                       cmd.c_data = data;
>                       cmd.c_datalen = ucmd->c_datalen;
> @@ -804,10 +805,10 @@ sdmmc_ioctl(struct device *self, u_long 
>               ucmd->c_flags = cmd.c_flags;
>               ucmd->c_error = cmd.c_error;
>  
> -             if (ucmd->c_data && copyout(data, ucmd->c_data,
> -                 ucmd->c_datalen))
> -                     return EFAULT;
> +             if (ucmd->c_data)
> +                    error = copyout(data, ucmd->c_data, ucmd->c_datalen);
>  
> +exec_done:
>               if (ucmd->c_data)
>                       free(data, M_TEMP, 0);
>               break;
> @@ -815,7 +816,7 @@ sdmmc_ioctl(struct device *self, u_long 
>       default:
>               return ENOTTY;
>       }
> -     return 0;
> +     return error;
>  }
>  #endif
>  
> 

Reply via email to