Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
97128577
Commit
97128577
authored
Feb 29, 2016
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-linus' into for-next
Back-merge of for-linus branch for further API/ABI cleanups.
parents
0bbf7e02
b24e7ad1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
320 additions
and
21 deletions
+320
-21
sound/core/control_compat.c
sound/core/control_compat.c
+74
-16
sound/core/pcm_compat.c
sound/core/pcm_compat.c
+176
-1
sound/core/rawmidi_compat.c
sound/core/rawmidi_compat.c
+54
-2
sound/core/timer_compat.c
sound/core/timer_compat.c
+16
-2
No files found.
sound/core/control_compat.c
View file @
97128577
...
@@ -170,6 +170,19 @@ struct snd_ctl_elem_value32 {
...
@@ -170,6 +170,19 @@ struct snd_ctl_elem_value32 {
unsigned
char
reserved
[
128
];
unsigned
char
reserved
[
128
];
};
};
#ifdef CONFIG_X86_X32
/* x32 has a different alignment for 64bit values from ia32 */
struct
snd_ctl_elem_value_x32
{
struct
snd_ctl_elem_id
id
;
unsigned
int
indirect
;
/* bit-field causes misalignment */
union
{
s32
integer
[
128
];
unsigned
char
data
[
512
];
s64
integer64
[
64
];
}
value
;
unsigned
char
reserved
[
128
];
};
#endif
/* CONFIG_X86_X32 */
/* get the value type and count of the control */
/* get the value type and count of the control */
static
int
get_ctl_type
(
struct
snd_card
*
card
,
struct
snd_ctl_elem_id
*
id
,
static
int
get_ctl_type
(
struct
snd_card
*
card
,
struct
snd_ctl_elem_id
*
id
,
...
@@ -219,9 +232,11 @@ static int get_elem_size(int type, int count)
...
@@ -219,9 +232,11 @@ static int get_elem_size(int type, int count)
static
int
copy_ctl_value_from_user
(
struct
snd_card
*
card
,
static
int
copy_ctl_value_from_user
(
struct
snd_card
*
card
,
struct
snd_ctl_elem_value
*
data
,
struct
snd_ctl_elem_value
*
data
,
struct
snd_ctl_elem_value32
__user
*
data32
,
void
__user
*
userdata
,
void
__user
*
valuep
,
int
*
typep
,
int
*
countp
)
int
*
typep
,
int
*
countp
)
{
{
struct
snd_ctl_elem_value32
__user
*
data32
=
userdata
;
int
i
,
type
,
size
;
int
i
,
type
,
size
;
int
uninitialized_var
(
count
);
int
uninitialized_var
(
count
);
unsigned
int
indirect
;
unsigned
int
indirect
;
...
@@ -239,8 +254,9 @@ static int copy_ctl_value_from_user(struct snd_card *card,
...
@@ -239,8 +254,9 @@ static int copy_ctl_value_from_user(struct snd_card *card,
if
(
type
==
SNDRV_CTL_ELEM_TYPE_BOOLEAN
||
if
(
type
==
SNDRV_CTL_ELEM_TYPE_BOOLEAN
||
type
==
SNDRV_CTL_ELEM_TYPE_INTEGER
)
{
type
==
SNDRV_CTL_ELEM_TYPE_INTEGER
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
{
s32
__user
*
intp
=
valuep
;
int
val
;
int
val
;
if
(
get_user
(
val
,
&
data32
->
value
.
integer
[
i
]))
if
(
get_user
(
val
,
&
intp
[
i
]))
return
-
EFAULT
;
return
-
EFAULT
;
data
->
value
.
integer
.
value
[
i
]
=
val
;
data
->
value
.
integer
.
value
[
i
]
=
val
;
}
}
...
@@ -250,8 +266,7 @@ static int copy_ctl_value_from_user(struct snd_card *card,
...
@@ -250,8 +266,7 @@ static int copy_ctl_value_from_user(struct snd_card *card,
dev_err
(
card
->
dev
,
"snd_ioctl32_ctl_elem_value: unknown type %d
\n
"
,
type
);
dev_err
(
card
->
dev
,
"snd_ioctl32_ctl_elem_value: unknown type %d
\n
"
,
type
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
(
copy_from_user
(
data
->
value
.
bytes
.
data
,
if
(
copy_from_user
(
data
->
value
.
bytes
.
data
,
valuep
,
size
))
data32
->
value
.
data
,
size
))
return
-
EFAULT
;
return
-
EFAULT
;
}
}
...
@@ -261,7 +276,8 @@ static int copy_ctl_value_from_user(struct snd_card *card,
...
@@ -261,7 +276,8 @@ static int copy_ctl_value_from_user(struct snd_card *card,
}
}
/* restore the value to 32bit */
/* restore the value to 32bit */
static
int
copy_ctl_value_to_user
(
struct
snd_ctl_elem_value32
__user
*
data32
,
static
int
copy_ctl_value_to_user
(
void
__user
*
userdata
,
void
__user
*
valuep
,
struct
snd_ctl_elem_value
*
data
,
struct
snd_ctl_elem_value
*
data
,
int
type
,
int
count
)
int
type
,
int
count
)
{
{
...
@@ -270,22 +286,22 @@ static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
...
@@ -270,22 +286,22 @@ static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
if
(
type
==
SNDRV_CTL_ELEM_TYPE_BOOLEAN
||
if
(
type
==
SNDRV_CTL_ELEM_TYPE_BOOLEAN
||
type
==
SNDRV_CTL_ELEM_TYPE_INTEGER
)
{
type
==
SNDRV_CTL_ELEM_TYPE_INTEGER
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
{
s32
__user
*
intp
=
valuep
;
int
val
;
int
val
;
val
=
data
->
value
.
integer
.
value
[
i
];
val
=
data
->
value
.
integer
.
value
[
i
];
if
(
put_user
(
val
,
&
data32
->
value
.
integer
[
i
]))
if
(
put_user
(
val
,
&
intp
[
i
]))
return
-
EFAULT
;
return
-
EFAULT
;
}
}
}
else
{
}
else
{
size
=
get_elem_size
(
type
,
count
);
size
=
get_elem_size
(
type
,
count
);
if
(
copy_to_user
(
data32
->
value
.
data
,
if
(
copy_to_user
(
valuep
,
data
->
value
.
bytes
.
data
,
size
))
data
->
value
.
bytes
.
data
,
size
))
return
-
EFAULT
;
return
-
EFAULT
;
}
}
return
0
;
return
0
;
}
}
static
int
snd_ctl_elem_read_user_compat
(
struct
snd_card
*
card
,
static
int
ctl_elem_read_user
(
struct
snd_card
*
card
,
struct
snd_ctl_elem_value32
__user
*
data32
)
void
__user
*
userdata
,
void
__user
*
valuep
)
{
{
struct
snd_ctl_elem_value
*
data
;
struct
snd_ctl_elem_value
*
data
;
int
err
,
type
,
count
;
int
err
,
type
,
count
;
...
@@ -294,7 +310,9 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
...
@@ -294,7 +310,9 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
if
(
data
==
NULL
)
if
(
data
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
if
((
err
=
copy_ctl_value_from_user
(
card
,
data
,
data32
,
&
type
,
&
count
))
<
0
)
err
=
copy_ctl_value_from_user
(
card
,
data
,
userdata
,
valuep
,
&
type
,
&
count
);
if
(
err
<
0
)
goto
error
;
goto
error
;
snd_power_lock
(
card
);
snd_power_lock
(
card
);
...
@@ -303,14 +321,15 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
...
@@ -303,14 +321,15 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
err
=
snd_ctl_elem_read
(
card
,
data
);
err
=
snd_ctl_elem_read
(
card
,
data
);
snd_power_unlock
(
card
);
snd_power_unlock
(
card
);
if
(
err
>=
0
)
if
(
err
>=
0
)
err
=
copy_ctl_value_to_user
(
data32
,
data
,
type
,
count
);
err
=
copy_ctl_value_to_user
(
userdata
,
valuep
,
data
,
type
,
count
);
error:
error:
kfree
(
data
);
kfree
(
data
);
return
err
;
return
err
;
}
}
static
int
snd_ctl_elem_write_user_compat
(
struct
snd_ctl_file
*
file
,
static
int
ctl_elem_write_user
(
struct
snd_ctl_file
*
file
,
struct
snd_ctl_elem_value32
__user
*
data32
)
void
__user
*
userdata
,
void
__user
*
valuep
)
{
{
struct
snd_ctl_elem_value
*
data
;
struct
snd_ctl_elem_value
*
data
;
struct
snd_card
*
card
=
file
->
card
;
struct
snd_card
*
card
=
file
->
card
;
...
@@ -320,7 +339,9 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
...
@@ -320,7 +339,9 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
if
(
data
==
NULL
)
if
(
data
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
if
((
err
=
copy_ctl_value_from_user
(
card
,
data
,
data32
,
&
type
,
&
count
))
<
0
)
err
=
copy_ctl_value_from_user
(
card
,
data
,
userdata
,
valuep
,
&
type
,
&
count
);
if
(
err
<
0
)
goto
error
;
goto
error
;
snd_power_lock
(
card
);
snd_power_lock
(
card
);
...
@@ -329,12 +350,39 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
...
@@ -329,12 +350,39 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
err
=
snd_ctl_elem_write
(
card
,
file
,
data
);
err
=
snd_ctl_elem_write
(
card
,
file
,
data
);
snd_power_unlock
(
card
);
snd_power_unlock
(
card
);
if
(
err
>=
0
)
if
(
err
>=
0
)
err
=
copy_ctl_value_to_user
(
data32
,
data
,
type
,
count
);
err
=
copy_ctl_value_to_user
(
userdata
,
valuep
,
data
,
type
,
count
);
error:
error:
kfree
(
data
);
kfree
(
data
);
return
err
;
return
err
;
}
}
static
int
snd_ctl_elem_read_user_compat
(
struct
snd_card
*
card
,
struct
snd_ctl_elem_value32
__user
*
data32
)
{
return
ctl_elem_read_user
(
card
,
data32
,
&
data32
->
value
);
}
static
int
snd_ctl_elem_write_user_compat
(
struct
snd_ctl_file
*
file
,
struct
snd_ctl_elem_value32
__user
*
data32
)
{
return
ctl_elem_write_user
(
file
,
data32
,
&
data32
->
value
);
}
#ifdef CONFIG_X86_X32
static
int
snd_ctl_elem_read_user_x32
(
struct
snd_card
*
card
,
struct
snd_ctl_elem_value_x32
__user
*
data32
)
{
return
ctl_elem_read_user
(
card
,
data32
,
&
data32
->
value
);
}
static
int
snd_ctl_elem_write_user_x32
(
struct
snd_ctl_file
*
file
,
struct
snd_ctl_elem_value_x32
__user
*
data32
)
{
return
ctl_elem_write_user
(
file
,
data32
,
&
data32
->
value
);
}
#endif
/* CONFIG_X86_X32 */
/* add or replace a user control */
/* add or replace a user control */
static
int
snd_ctl_elem_add_compat
(
struct
snd_ctl_file
*
file
,
static
int
snd_ctl_elem_add_compat
(
struct
snd_ctl_file
*
file
,
struct
snd_ctl_elem_info32
__user
*
data32
,
struct
snd_ctl_elem_info32
__user
*
data32
,
...
@@ -393,6 +441,10 @@ enum {
...
@@ -393,6 +441,10 @@ enum {
SNDRV_CTL_IOCTL_ELEM_WRITE32
=
_IOWR
(
'U'
,
0x13
,
struct
snd_ctl_elem_value32
),
SNDRV_CTL_IOCTL_ELEM_WRITE32
=
_IOWR
(
'U'
,
0x13
,
struct
snd_ctl_elem_value32
),
SNDRV_CTL_IOCTL_ELEM_ADD32
=
_IOWR
(
'U'
,
0x17
,
struct
snd_ctl_elem_info32
),
SNDRV_CTL_IOCTL_ELEM_ADD32
=
_IOWR
(
'U'
,
0x17
,
struct
snd_ctl_elem_info32
),
SNDRV_CTL_IOCTL_ELEM_REPLACE32
=
_IOWR
(
'U'
,
0x18
,
struct
snd_ctl_elem_info32
),
SNDRV_CTL_IOCTL_ELEM_REPLACE32
=
_IOWR
(
'U'
,
0x18
,
struct
snd_ctl_elem_info32
),
#ifdef CONFIG_X86_X32
SNDRV_CTL_IOCTL_ELEM_READ_X32
=
_IOWR
(
'U'
,
0x12
,
struct
snd_ctl_elem_value_x32
),
SNDRV_CTL_IOCTL_ELEM_WRITE_X32
=
_IOWR
(
'U'
,
0x13
,
struct
snd_ctl_elem_value_x32
),
#endif
/* CONFIG_X86_X32 */
};
};
static
inline
long
snd_ctl_ioctl_compat
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
static
inline
long
snd_ctl_ioctl_compat
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
...
@@ -431,6 +483,12 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
...
@@ -431,6 +483,12 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
return
snd_ctl_elem_add_compat
(
ctl
,
argp
,
0
);
return
snd_ctl_elem_add_compat
(
ctl
,
argp
,
0
);
case
SNDRV_CTL_IOCTL_ELEM_REPLACE32
:
case
SNDRV_CTL_IOCTL_ELEM_REPLACE32
:
return
snd_ctl_elem_add_compat
(
ctl
,
argp
,
1
);
return
snd_ctl_elem_add_compat
(
ctl
,
argp
,
1
);
#ifdef CONFIG_X86_X32
case
SNDRV_CTL_IOCTL_ELEM_READ_X32
:
return
snd_ctl_elem_read_user_x32
(
ctl
->
card
,
argp
);
case
SNDRV_CTL_IOCTL_ELEM_WRITE_X32
:
return
snd_ctl_elem_write_user_x32
(
ctl
,
argp
);
#endif
/* CONFIG_X86_X32 */
}
}
down_read
(
&
snd_ioctl_rwsem
);
down_read
(
&
snd_ioctl_rwsem
);
...
...
sound/core/pcm_compat.c
View file @
97128577
...
@@ -183,6 +183,14 @@ static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream
...
@@ -183,6 +183,14 @@ static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream
return
err
;
return
err
;
}
}
#ifdef CONFIG_X86_X32
/* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */
static
int
snd_pcm_channel_info_user
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_channel_info
__user
*
src
);
#define snd_pcm_ioctl_channel_info_x32(s, p) \
snd_pcm_channel_info_user(s, p)
#endif
/* CONFIG_X86_X32 */
struct
snd_pcm_status32
{
struct
snd_pcm_status32
{
s32
state
;
s32
state
;
struct
compat_timespec
trigger_tstamp
;
struct
compat_timespec
trigger_tstamp
;
...
@@ -243,6 +251,71 @@ static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
...
@@ -243,6 +251,71 @@ static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
return
err
;
return
err
;
}
}
#ifdef CONFIG_X86_X32
/* X32 ABI has 64bit timespec and 64bit alignment */
struct
snd_pcm_status_x32
{
s32
state
;
u32
rsvd
;
/* alignment */
struct
timespec
trigger_tstamp
;
struct
timespec
tstamp
;
u32
appl_ptr
;
u32
hw_ptr
;
s32
delay
;
u32
avail
;
u32
avail_max
;
u32
overrange
;
s32
suspended_state
;
u32
audio_tstamp_data
;
struct
timespec
audio_tstamp
;
struct
timespec
driver_tstamp
;
u32
audio_tstamp_accuracy
;
unsigned
char
reserved
[
52
-
2
*
sizeof
(
struct
timespec
)];
}
__packed
;
#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
static
int
snd_pcm_status_user_x32
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_status_x32
__user
*
src
,
bool
ext
)
{
struct
snd_pcm_status
status
;
int
err
;
memset
(
&
status
,
0
,
sizeof
(
status
));
/*
* with extension, parameters are read/write,
* get audio_tstamp_data from user,
* ignore rest of status structure
*/
if
(
ext
&&
get_user
(
status
.
audio_tstamp_data
,
(
u32
__user
*
)(
&
src
->
audio_tstamp_data
)))
return
-
EFAULT
;
err
=
snd_pcm_status
(
substream
,
&
status
);
if
(
err
<
0
)
return
err
;
if
(
clear_user
(
src
,
sizeof
(
*
src
)))
return
-
EFAULT
;
if
(
put_user
(
status
.
state
,
&
src
->
state
)
||
put_timespec
(
&
status
.
trigger_tstamp
,
&
src
->
trigger_tstamp
)
||
put_timespec
(
&
status
.
tstamp
,
&
src
->
tstamp
)
||
put_user
(
status
.
appl_ptr
,
&
src
->
appl_ptr
)
||
put_user
(
status
.
hw_ptr
,
&
src
->
hw_ptr
)
||
put_user
(
status
.
delay
,
&
src
->
delay
)
||
put_user
(
status
.
avail
,
&
src
->
avail
)
||
put_user
(
status
.
avail_max
,
&
src
->
avail_max
)
||
put_user
(
status
.
overrange
,
&
src
->
overrange
)
||
put_user
(
status
.
suspended_state
,
&
src
->
suspended_state
)
||
put_user
(
status
.
audio_tstamp_data
,
&
src
->
audio_tstamp_data
)
||
put_timespec
(
&
status
.
audio_tstamp
,
&
src
->
audio_tstamp
)
||
put_timespec
(
&
status
.
driver_tstamp
,
&
src
->
driver_tstamp
)
||
put_user
(
status
.
audio_tstamp_accuracy
,
&
src
->
audio_tstamp_accuracy
))
return
-
EFAULT
;
return
err
;
}
#endif
/* CONFIG_X86_X32 */
/* both for HW_PARAMS and HW_REFINE */
/* both for HW_PARAMS and HW_REFINE */
static
int
snd_pcm_ioctl_hw_params_compat
(
struct
snd_pcm_substream
*
substream
,
static
int
snd_pcm_ioctl_hw_params_compat
(
struct
snd_pcm_substream
*
substream
,
int
refine
,
int
refine
,
...
@@ -469,6 +542,93 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
...
@@ -469,6 +542,93 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
return
0
;
return
0
;
}
}
#ifdef CONFIG_X86_X32
/* X32 ABI has 64bit timespec and 64bit alignment */
struct
snd_pcm_mmap_status_x32
{
s32
state
;
s32
pad1
;
u32
hw_ptr
;
u32
pad2
;
/* alignment */
struct
timespec
tstamp
;
s32
suspended_state
;
struct
timespec
audio_tstamp
;
}
__packed
;
struct
snd_pcm_mmap_control_x32
{
u32
appl_ptr
;
u32
avail_min
;
};
struct
snd_pcm_sync_ptr_x32
{
u32
flags
;
u32
rsvd
;
/* alignment */
union
{
struct
snd_pcm_mmap_status_x32
status
;
unsigned
char
reserved
[
64
];
}
s
;
union
{
struct
snd_pcm_mmap_control_x32
control
;
unsigned
char
reserved
[
64
];
}
c
;
}
__packed
;
static
int
snd_pcm_ioctl_sync_ptr_x32
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_sync_ptr_x32
__user
*
src
)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
volatile
struct
snd_pcm_mmap_status
*
status
;
volatile
struct
snd_pcm_mmap_control
*
control
;
u32
sflags
;
struct
snd_pcm_mmap_control
scontrol
;
struct
snd_pcm_mmap_status
sstatus
;
snd_pcm_uframes_t
boundary
;
int
err
;
if
(
snd_BUG_ON
(
!
runtime
))
return
-
EINVAL
;
if
(
get_user
(
sflags
,
&
src
->
flags
)
||
get_user
(
scontrol
.
appl_ptr
,
&
src
->
c
.
control
.
appl_ptr
)
||
get_user
(
scontrol
.
avail_min
,
&
src
->
c
.
control
.
avail_min
))
return
-
EFAULT
;
if
(
sflags
&
SNDRV_PCM_SYNC_PTR_HWSYNC
)
{
err
=
snd_pcm_hwsync
(
substream
);
if
(
err
<
0
)
return
err
;
}
status
=
runtime
->
status
;
control
=
runtime
->
control
;
boundary
=
recalculate_boundary
(
runtime
);
if
(
!
boundary
)
boundary
=
0x7fffffff
;
snd_pcm_stream_lock_irq
(
substream
);
/* FIXME: we should consider the boundary for the sync from app */
if
(
!
(
sflags
&
SNDRV_PCM_SYNC_PTR_APPL
))
control
->
appl_ptr
=
scontrol
.
appl_ptr
;
else
scontrol
.
appl_ptr
=
control
->
appl_ptr
%
boundary
;
if
(
!
(
sflags
&
SNDRV_PCM_SYNC_PTR_AVAIL_MIN
))
control
->
avail_min
=
scontrol
.
avail_min
;
else
scontrol
.
avail_min
=
control
->
avail_min
;
sstatus
.
state
=
status
->
state
;
sstatus
.
hw_ptr
=
status
->
hw_ptr
%
boundary
;
sstatus
.
tstamp
=
status
->
tstamp
;
sstatus
.
suspended_state
=
status
->
suspended_state
;
sstatus
.
audio_tstamp
=
status
->
audio_tstamp
;
snd_pcm_stream_unlock_irq
(
substream
);
if
(
put_user
(
sstatus
.
state
,
&
src
->
s
.
status
.
state
)
||
put_user
(
sstatus
.
hw_ptr
,
&
src
->
s
.
status
.
hw_ptr
)
||
put_timespec
(
&
sstatus
.
tstamp
,
&
src
->
s
.
status
.
tstamp
)
||
put_user
(
sstatus
.
suspended_state
,
&
src
->
s
.
status
.
suspended_state
)
||
put_timespec
(
&
sstatus
.
audio_tstamp
,
&
src
->
s
.
status
.
audio_tstamp
)
||
put_user
(
scontrol
.
appl_ptr
,
&
src
->
c
.
control
.
appl_ptr
)
||
put_user
(
scontrol
.
avail_min
,
&
src
->
c
.
control
.
avail_min
))
return
-
EFAULT
;
return
0
;
}
#endif
/* CONFIG_X86_X32 */
/*
/*
*/
*/
...
@@ -487,7 +647,12 @@ enum {
...
@@ -487,7 +647,12 @@ enum {
SNDRV_PCM_IOCTL_WRITEN_FRAMES32
=
_IOW
(
'A'
,
0x52
,
struct
snd_xfern32
),
SNDRV_PCM_IOCTL_WRITEN_FRAMES32
=
_IOW
(
'A'
,
0x52
,
struct
snd_xfern32
),
SNDRV_PCM_IOCTL_READN_FRAMES32
=
_IOR
(
'A'
,
0x53
,
struct
snd_xfern32
),
SNDRV_PCM_IOCTL_READN_FRAMES32
=
_IOR
(
'A'
,
0x53
,
struct
snd_xfern32
),
SNDRV_PCM_IOCTL_SYNC_PTR32
=
_IOWR
(
'A'
,
0x23
,
struct
snd_pcm_sync_ptr32
),
SNDRV_PCM_IOCTL_SYNC_PTR32
=
_IOWR
(
'A'
,
0x23
,
struct
snd_pcm_sync_ptr32
),
#ifdef CONFIG_X86_X32
SNDRV_PCM_IOCTL_CHANNEL_INFO_X32
=
_IOR
(
'A'
,
0x32
,
struct
snd_pcm_channel_info
),
SNDRV_PCM_IOCTL_STATUS_X32
=
_IOR
(
'A'
,
0x20
,
struct
snd_pcm_status_x32
),
SNDRV_PCM_IOCTL_STATUS_EXT_X32
=
_IOWR
(
'A'
,
0x24
,
struct
snd_pcm_status_x32
),
SNDRV_PCM_IOCTL_SYNC_PTR_X32
=
_IOWR
(
'A'
,
0x23
,
struct
snd_pcm_sync_ptr_x32
),
#endif
/* CONFIG_X86_X32 */
};
};
static
long
snd_pcm_ioctl_compat
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
static
long
snd_pcm_ioctl_compat
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
...
@@ -559,6 +724,16 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
...
@@ -559,6 +724,16 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
return
snd_pcm_ioctl_rewind_compat
(
substream
,
argp
);
return
snd_pcm_ioctl_rewind_compat
(
substream
,
argp
);
case
SNDRV_PCM_IOCTL_FORWARD32
:
case
SNDRV_PCM_IOCTL_FORWARD32
:
return
snd_pcm_ioctl_forward_compat
(
substream
,
argp
);
return
snd_pcm_ioctl_forward_compat
(
substream
,
argp
);
#ifdef CONFIG_X86_X32
case
SNDRV_PCM_IOCTL_STATUS_X32
:
return
snd_pcm_status_user_x32
(
substream
,
argp
,
false
);
case
SNDRV_PCM_IOCTL_STATUS_EXT_X32
:
return
snd_pcm_status_user_x32
(
substream
,
argp
,
true
);
case
SNDRV_PCM_IOCTL_SYNC_PTR_X32
:
return
snd_pcm_ioctl_sync_ptr_x32
(
substream
,
argp
);
case
SNDRV_PCM_IOCTL_CHANNEL_INFO_X32
:
return
snd_pcm_ioctl_channel_info_x32
(
substream
,
argp
);
#endif
/* CONFIG_X86_X32 */
}
}
return
-
ENOIOCTLCMD
;
return
-
ENOIOCTLCMD
;
...
...
sound/core/rawmidi_compat.c
View file @
97128577
...
@@ -85,8 +85,7 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
...
@@ -85,8 +85,7 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
if
(
put_user
(
status
.
tstamp
.
tv_sec
,
&
src
->
tstamp
.
tv_sec
)
||
if
(
compat_put_timespec
(
&
status
.
tstamp
,
&
src
->
tstamp
)
||
put_user
(
status
.
tstamp
.
tv_nsec
,
&
src
->
tstamp
.
tv_nsec
)
||
put_user
(
status
.
avail
,
&
src
->
avail
)
||
put_user
(
status
.
avail
,
&
src
->
avail
)
||
put_user
(
status
.
xruns
,
&
src
->
xruns
))
put_user
(
status
.
xruns
,
&
src
->
xruns
))
return
-
EFAULT
;
return
-
EFAULT
;
...
@@ -94,9 +93,58 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
...
@@ -94,9 +93,58 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
return
0
;
return
0
;
}
}
#ifdef CONFIG_X86_X32
/* X32 ABI has 64bit timespec and 64bit alignment */
struct
snd_rawmidi_status_x32
{
s32
stream
;
u32
rsvd
;
/* alignment */
struct
timespec
tstamp
;
u32
avail
;
u32
xruns
;
unsigned
char
reserved
[
16
];
}
__attribute__
((
packed
));
#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
static
int
snd_rawmidi_ioctl_status_x32
(
struct
snd_rawmidi_file
*
rfile
,
struct
snd_rawmidi_status_x32
__user
*
src
)
{
int
err
;
struct
snd_rawmidi_status
status
;
if
(
rfile
->
output
==
NULL
)
return
-
EINVAL
;
if
(
get_user
(
status
.
stream
,
&
src
->
stream
))
return
-
EFAULT
;
switch
(
status
.
stream
)
{
case
SNDRV_RAWMIDI_STREAM_OUTPUT
:
err
=
snd_rawmidi_output_status
(
rfile
->
output
,
&
status
);
break
;
case
SNDRV_RAWMIDI_STREAM_INPUT
:
err
=
snd_rawmidi_input_status
(
rfile
->
input
,
&
status
);
break
;
default:
return
-
EINVAL
;
}
if
(
err
<
0
)
return
err
;
if
(
put_timespec
(
&
status
.
tstamp
,
&
src
->
tstamp
)
||
put_user
(
status
.
avail
,
&
src
->
avail
)
||
put_user
(
status
.
xruns
,
&
src
->
xruns
))
return
-
EFAULT
;
return
0
;
}
#endif
/* CONFIG_X86_X32 */
enum
{
enum
{
SNDRV_RAWMIDI_IOCTL_PARAMS32
=
_IOWR
(
'W'
,
0x10
,
struct
snd_rawmidi_params32
),
SNDRV_RAWMIDI_IOCTL_PARAMS32
=
_IOWR
(
'W'
,
0x10
,
struct
snd_rawmidi_params32
),
SNDRV_RAWMIDI_IOCTL_STATUS32
=
_IOWR
(
'W'
,
0x20
,
struct
snd_rawmidi_status32
),
SNDRV_RAWMIDI_IOCTL_STATUS32
=
_IOWR
(
'W'
,
0x20
,
struct
snd_rawmidi_status32
),
#ifdef CONFIG_X86_X32
SNDRV_RAWMIDI_IOCTL_STATUS_X32
=
_IOWR
(
'W'
,
0x20
,
struct
snd_rawmidi_status_x32
),
#endif
/* CONFIG_X86_X32 */
};
};
static
long
snd_rawmidi_ioctl_compat
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
static
long
snd_rawmidi_ioctl_compat
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
...
@@ -115,6 +163,10 @@ static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsign
...
@@ -115,6 +163,10 @@ static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsign
return
snd_rawmidi_ioctl_params_compat
(
rfile
,
argp
);
return
snd_rawmidi_ioctl_params_compat
(
rfile
,
argp
);
case
SNDRV_RAWMIDI_IOCTL_STATUS32
:
case
SNDRV_RAWMIDI_IOCTL_STATUS32
:
return
snd_rawmidi_ioctl_status_compat
(
rfile
,
argp
);
return
snd_rawmidi_ioctl_status_compat
(
rfile
,
argp
);
#ifdef CONFIG_X86_X32
case
SNDRV_RAWMIDI_IOCTL_STATUS_X32
:
return
snd_rawmidi_ioctl_status_x32
(
rfile
,
argp
);
#endif
/* CONFIG_X86_X32 */
}
}
return
-
ENOIOCTLCMD
;
return
-
ENOIOCTLCMD
;
}
}
sound/core/timer_compat.c
View file @
97128577
...
@@ -70,13 +70,14 @@ static int snd_timer_user_status_compat(struct file *file,
...
@@ -70,13 +70,14 @@ static int snd_timer_user_status_compat(struct file *file,
struct
snd_timer_status32
__user
*
_status
)
struct
snd_timer_status32
__user
*
_status
)
{
{
struct
snd_timer_user
*
tu
;
struct
snd_timer_user
*
tu
;
struct
snd_timer_status
status
;
struct
snd_timer_status
32
status
;
tu
=
file
->
private_data
;
tu
=
file
->
private_data
;
if
(
snd_BUG_ON
(
!
tu
->
timeri
))
if
(
snd_BUG_ON
(
!
tu
->
timeri
))
return
-
ENXIO
;
return
-
ENXIO
;
memset
(
&
status
,
0
,
sizeof
(
status
));
memset
(
&
status
,
0
,
sizeof
(
status
));
status
.
tstamp
=
tu
->
tstamp
;
status
.
tstamp
.
tv_sec
=
tu
->
tstamp
.
tv_sec
;
status
.
tstamp
.
tv_nsec
=
tu
->
tstamp
.
tv_nsec
;
status
.
resolution
=
snd_timer_resolution
(
tu
->
timeri
);
status
.
resolution
=
snd_timer_resolution
(
tu
->
timeri
);
status
.
lost
=
tu
->
timeri
->
lost
;
status
.
lost
=
tu
->
timeri
->
lost
;
status
.
overrun
=
tu
->
overrun
;
status
.
overrun
=
tu
->
overrun
;
...
@@ -88,12 +89,21 @@ static int snd_timer_user_status_compat(struct file *file,
...
@@ -88,12 +89,21 @@ static int snd_timer_user_status_compat(struct file *file,
return
0
;
return
0
;
}
}
#ifdef CONFIG_X86_X32
/* X32 ABI has the same struct as x86-64 */
#define snd_timer_user_status_x32(file, s) \
snd_timer_user_status(file, s)
#endif
/* CONFIG_X86_X32 */
/*
/*
*/
*/
enum
{
enum
{
SNDRV_TIMER_IOCTL_INFO32
=
_IOR
(
'T'
,
0x11
,
struct
snd_timer_info32
),
SNDRV_TIMER_IOCTL_INFO32
=
_IOR
(
'T'
,
0x11
,
struct
snd_timer_info32
),
SNDRV_TIMER_IOCTL_STATUS32
=
_IOW
(
'T'
,
0x14
,
struct
snd_timer_status32
),
SNDRV_TIMER_IOCTL_STATUS32
=
_IOW
(
'T'
,
0x14
,
struct
snd_timer_status32
),
#ifdef CONFIG_X86_X32
SNDRV_TIMER_IOCTL_STATUS_X32
=
_IOW
(
'T'
,
0x14
,
struct
snd_timer_status
),
#endif
/* CONFIG_X86_X32 */
};
};
static
long
snd_timer_user_ioctl_compat
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
static
long
snd_timer_user_ioctl_compat
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
...
@@ -122,6 +132,10 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns
...
@@ -122,6 +132,10 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns
return
snd_timer_user_info_compat
(
file
,
argp
);
return
snd_timer_user_info_compat
(
file
,
argp
);
case
SNDRV_TIMER_IOCTL_STATUS32
:
case
SNDRV_TIMER_IOCTL_STATUS32
:
return
snd_timer_user_status_compat
(
file
,
argp
);
return
snd_timer_user_status_compat
(
file
,
argp
);
#ifdef CONFIG_X86_X32
case
SNDRV_TIMER_IOCTL_STATUS_X32
:
return
snd_timer_user_status_x32
(
file
,
argp
);
#endif
/* CONFIG_X86_X32 */
}
}
return
-
ENOIOCTLCMD
;
return
-
ENOIOCTLCMD
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment