@@ -2931,155 +2931,106 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
2931
2931
}
2932
2932
2933
2933
/* Copy 32-bit cmd structure to native cmd structure. */
2934
- static int get_compat_cmd (struct comedi_cmd __user * cmd ,
2934
+ static int get_compat_cmd (struct comedi_cmd * cmd ,
2935
2935
struct comedi32_cmd_struct __user * cmd32 )
2936
2936
{
2937
- int err ;
2938
- union {
2939
- unsigned int uint ;
2940
- compat_uptr_t uptr ;
2941
- } temp ;
2942
-
2943
- /* Copy cmd structure. */
2944
- if (!access_ok (cmd32 , sizeof (* cmd32 )) ||
2945
- !access_ok (cmd , sizeof (* cmd )))
2937
+ struct comedi32_cmd_struct v32 ;
2938
+
2939
+ if (copy_from_user (& v32 , cmd32 , sizeof (v32 )))
2946
2940
return - EFAULT ;
2947
2941
2948
- err = 0 ;
2949
- err |= __get_user (temp .uint , & cmd32 -> subdev );
2950
- err |= __put_user (temp .uint , & cmd -> subdev );
2951
- err |= __get_user (temp .uint , & cmd32 -> flags );
2952
- err |= __put_user (temp .uint , & cmd -> flags );
2953
- err |= __get_user (temp .uint , & cmd32 -> start_src );
2954
- err |= __put_user (temp .uint , & cmd -> start_src );
2955
- err |= __get_user (temp .uint , & cmd32 -> start_arg );
2956
- err |= __put_user (temp .uint , & cmd -> start_arg );
2957
- err |= __get_user (temp .uint , & cmd32 -> scan_begin_src );
2958
- err |= __put_user (temp .uint , & cmd -> scan_begin_src );
2959
- err |= __get_user (temp .uint , & cmd32 -> scan_begin_arg );
2960
- err |= __put_user (temp .uint , & cmd -> scan_begin_arg );
2961
- err |= __get_user (temp .uint , & cmd32 -> convert_src );
2962
- err |= __put_user (temp .uint , & cmd -> convert_src );
2963
- err |= __get_user (temp .uint , & cmd32 -> convert_arg );
2964
- err |= __put_user (temp .uint , & cmd -> convert_arg );
2965
- err |= __get_user (temp .uint , & cmd32 -> scan_end_src );
2966
- err |= __put_user (temp .uint , & cmd -> scan_end_src );
2967
- err |= __get_user (temp .uint , & cmd32 -> scan_end_arg );
2968
- err |= __put_user (temp .uint , & cmd -> scan_end_arg );
2969
- err |= __get_user (temp .uint , & cmd32 -> stop_src );
2970
- err |= __put_user (temp .uint , & cmd -> stop_src );
2971
- err |= __get_user (temp .uint , & cmd32 -> stop_arg );
2972
- err |= __put_user (temp .uint , & cmd -> stop_arg );
2973
- err |= __get_user (temp .uptr , & cmd32 -> chanlist );
2974
- err |= __put_user ((unsigned int __force * )compat_ptr (temp .uptr ),
2975
- & cmd -> chanlist );
2976
- err |= __get_user (temp .uint , & cmd32 -> chanlist_len );
2977
- err |= __put_user (temp .uint , & cmd -> chanlist_len );
2978
- err |= __get_user (temp .uptr , & cmd32 -> data );
2979
- err |= __put_user (compat_ptr (temp .uptr ), & cmd -> data );
2980
- err |= __get_user (temp .uint , & cmd32 -> data_len );
2981
- err |= __put_user (temp .uint , & cmd -> data_len );
2982
- return err ? - EFAULT : 0 ;
2942
+ cmd -> subdev = v32 .subdev ;
2943
+ cmd -> flags = v32 .flags ;
2944
+ cmd -> start_src = v32 .start_src ;
2945
+ cmd -> start_arg = v32 .start_arg ;
2946
+ cmd -> scan_begin_src = v32 .scan_begin_src ;
2947
+ cmd -> scan_begin_arg = v32 .scan_begin_arg ;
2948
+ cmd -> convert_src = v32 .convert_src ;
2949
+ cmd -> convert_arg = v32 .convert_arg ;
2950
+ cmd -> scan_end_src = v32 .scan_end_src ;
2951
+ cmd -> scan_end_arg = v32 .scan_end_arg ;
2952
+ cmd -> stop_src = v32 .stop_src ;
2953
+ cmd -> stop_arg = v32 .stop_arg ;
2954
+ cmd -> chanlist = compat_ptr (v32 .chanlist );
2955
+ cmd -> chanlist_len = v32 .chanlist_len ;
2956
+ cmd -> data = compat_ptr (v32 .data );
2957
+ cmd -> data_len = v32 .data_len ;
2958
+ return 0 ;
2983
2959
}
2984
2960
2985
2961
/* Copy native cmd structure to 32-bit cmd structure. */
2986
2962
static int put_compat_cmd (struct comedi32_cmd_struct __user * cmd32 ,
2987
- struct comedi_cmd __user * cmd )
2988
- {
2989
- int err ;
2990
- unsigned int temp ;
2991
-
2992
- /*
2993
- * Copy back most of cmd structure.
2994
- *
2995
- * Assume the pointer values are already valid.
2996
- * (Could use ptr_to_compat() to set them.)
2997
- */
2998
- if (!access_ok (cmd , sizeof (* cmd )) ||
2999
- !access_ok (cmd32 , sizeof (* cmd32 )))
3000
- return - EFAULT ;
3001
-
3002
- err = 0 ;
3003
- err |= __get_user (temp , & cmd -> subdev );
3004
- err |= __put_user (temp , & cmd32 -> subdev );
3005
- err |= __get_user (temp , & cmd -> flags );
3006
- err |= __put_user (temp , & cmd32 -> flags );
3007
- err |= __get_user (temp , & cmd -> start_src );
3008
- err |= __put_user (temp , & cmd32 -> start_src );
3009
- err |= __get_user (temp , & cmd -> start_arg );
3010
- err |= __put_user (temp , & cmd32 -> start_arg );
3011
- err |= __get_user (temp , & cmd -> scan_begin_src );
3012
- err |= __put_user (temp , & cmd32 -> scan_begin_src );
3013
- err |= __get_user (temp , & cmd -> scan_begin_arg );
3014
- err |= __put_user (temp , & cmd32 -> scan_begin_arg );
3015
- err |= __get_user (temp , & cmd -> convert_src );
3016
- err |= __put_user (temp , & cmd32 -> convert_src );
3017
- err |= __get_user (temp , & cmd -> convert_arg );
3018
- err |= __put_user (temp , & cmd32 -> convert_arg );
3019
- err |= __get_user (temp , & cmd -> scan_end_src );
3020
- err |= __put_user (temp , & cmd32 -> scan_end_src );
3021
- err |= __get_user (temp , & cmd -> scan_end_arg );
3022
- err |= __put_user (temp , & cmd32 -> scan_end_arg );
3023
- err |= __get_user (temp , & cmd -> stop_src );
3024
- err |= __put_user (temp , & cmd32 -> stop_src );
3025
- err |= __get_user (temp , & cmd -> stop_arg );
3026
- err |= __put_user (temp , & cmd32 -> stop_arg );
2963
+ struct comedi_cmd * cmd )
2964
+ {
2965
+ struct comedi32_cmd_struct v32 ;
2966
+
2967
+ memset (& v32 , 0 , sizeof (v32 ));
2968
+ v32 .subdev = cmd -> subdev ;
2969
+ v32 .flags = cmd -> flags ;
2970
+ v32 .start_src = cmd -> start_src ;
2971
+ v32 .start_arg = cmd -> start_arg ;
2972
+ v32 .scan_begin_src = cmd -> scan_begin_src ;
2973
+ v32 .scan_begin_arg = cmd -> scan_begin_arg ;
2974
+ v32 .convert_src = cmd -> convert_src ;
2975
+ v32 .convert_arg = cmd -> convert_arg ;
2976
+ v32 .scan_end_src = cmd -> scan_end_src ;
2977
+ v32 .scan_end_arg = cmd -> scan_end_arg ;
2978
+ v32 .stop_src = cmd -> stop_src ;
2979
+ v32 .stop_arg = cmd -> stop_arg ;
3027
2980
/* Assume chanlist pointer is unchanged. */
3028
- err |= __get_user (temp , & cmd -> chanlist_len );
3029
- err |= __put_user (temp , & cmd32 -> chanlist_len );
3030
- /* Assume data pointer is unchanged. */
3031
- err |= __get_user (temp , & cmd -> data_len );
3032
- err |= __put_user (temp , & cmd32 -> data_len );
3033
- return err ? - EFAULT : 0 ;
2981
+ v32 .chanlist = ptr_to_compat (cmd -> chanlist );
2982
+ v32 .chanlist_len = cmd -> chanlist_len ;
2983
+ v32 .data = ptr_to_compat (cmd -> data );
2984
+ v32 .data_len = cmd -> data_len ;
2985
+ return copy_to_user (cmd32 , & v32 , sizeof (v32 ));
3034
2986
}
3035
2987
3036
2988
/* Handle 32-bit COMEDI_CMD ioctl. */
3037
2989
static int compat_cmd (struct file * file , unsigned long arg )
3038
2990
{
3039
- struct comedi_cmd __user * cmd ;
3040
- struct comedi32_cmd_struct __user * cmd32 ;
2991
+ struct comedi_file * cfp = file -> private_data ;
2992
+ struct comedi_device * dev = cfp -> dev ;
2993
+ struct comedi_cmd cmd ;
2994
+ bool copy = false;
3041
2995
int rc , err ;
3042
2996
3043
- cmd32 = compat_ptr (arg );
3044
- cmd = compat_alloc_user_space (sizeof (* cmd ));
3045
-
3046
- rc = get_compat_cmd (cmd , cmd32 );
2997
+ rc = get_compat_cmd (& cmd , compat_ptr (arg ));
3047
2998
if (rc )
3048
2999
return rc ;
3049
3000
3050
- rc = comedi_unlocked_ioctl (file , COMEDI_CMD , (unsigned long )cmd );
3051
- if (rc == - EAGAIN ) {
3001
+ mutex_lock (& dev -> mutex );
3002
+ rc = do_cmd_ioctl (dev , & cmd , & copy , file );
3003
+ mutex_unlock (& dev -> mutex );
3004
+ if (copy ) {
3052
3005
/* Special case: copy cmd back to user. */
3053
- err = put_compat_cmd (cmd32 , cmd );
3006
+ err = put_compat_cmd (compat_ptr ( arg ), & cmd );
3054
3007
if (err )
3055
3008
rc = err ;
3056
3009
}
3057
-
3058
3010
return rc ;
3059
3011
}
3060
3012
3061
3013
/* Handle 32-bit COMEDI_CMDTEST ioctl. */
3062
3014
static int compat_cmdtest (struct file * file , unsigned long arg )
3063
3015
{
3064
- struct comedi_cmd __user * cmd ;
3065
- struct comedi32_cmd_struct __user * cmd32 ;
3016
+ struct comedi_file * cfp = file -> private_data ;
3017
+ struct comedi_device * dev = cfp -> dev ;
3018
+ struct comedi_cmd cmd ;
3019
+ bool copy = false;
3066
3020
int rc , err ;
3067
3021
3068
- cmd32 = compat_ptr (arg );
3069
- cmd = compat_alloc_user_space (sizeof (* cmd ));
3070
-
3071
- rc = get_compat_cmd (cmd , cmd32 );
3022
+ rc = get_compat_cmd (& cmd , compat_ptr (arg ));
3072
3023
if (rc )
3073
3024
return rc ;
3074
3025
3075
- rc = comedi_unlocked_ioctl ( file , COMEDI_CMDTEST , ( unsigned long ) cmd );
3076
- if ( rc < 0 )
3077
- return rc ;
3078
-
3079
- err = put_compat_cmd (cmd32 , cmd );
3080
- if (err )
3081
- rc = err ;
3082
-
3026
+ mutex_lock ( & dev -> mutex );
3027
+ rc = do_cmdtest_ioctl ( dev , & cmd , & copy , file );
3028
+ mutex_unlock ( & dev -> mutex ) ;
3029
+ if ( copy ) {
3030
+ err = put_compat_cmd (compat_ptr ( arg ), & cmd );
3031
+ if (err )
3032
+ rc = err ;
3033
+ }
3083
3034
return rc ;
3084
3035
}
3085
3036
0 commit comments