1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * 32bit -> 64bit ioctl wrapper for timer API
4 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
7 /* This file included from timer.c */
9 #include <linux/compat.h>
12 * ILP32/LP64 has different size for 'long' type. Additionally, the size
13 * of storage alignment differs depending on architectures. Here, '__packed'
14 * qualifier is used so that the size of this structure is multiple of 4 and
15 * it fits to any architectures with 32 bit storage alignment.
17 struct snd_timer_gparams32
{
18 struct snd_timer_id tid
;
21 unsigned char reserved
[32];
24 struct snd_timer_info32
{
28 unsigned char name
[80];
31 unsigned char reserved
[64];
34 static int snd_timer_user_gparams_compat(struct file
*file
,
35 struct snd_timer_gparams32 __user
*user
)
37 struct snd_timer_gparams gparams
;
39 if (copy_from_user(&gparams
.tid
, &user
->tid
, sizeof(gparams
.tid
)) ||
40 get_user(gparams
.period_num
, &user
->period_num
) ||
41 get_user(gparams
.period_den
, &user
->period_den
))
44 return timer_set_gparams(&gparams
);
47 static int snd_timer_user_info_compat(struct file
*file
,
48 struct snd_timer_info32 __user
*_info
)
50 struct snd_timer_user
*tu
;
51 struct snd_timer_info32 info
;
54 tu
= file
->private_data
;
57 t
= tu
->timeri
->timer
;
60 memset(&info
, 0, sizeof(info
));
61 info
.card
= t
->card
? t
->card
->number
: -1;
62 if (t
->hw
.flags
& SNDRV_TIMER_HW_SLAVE
)
63 info
.flags
|= SNDRV_TIMER_FLG_SLAVE
;
64 strlcpy(info
.id
, t
->id
, sizeof(info
.id
));
65 strlcpy(info
.name
, t
->name
, sizeof(info
.name
));
66 info
.resolution
= t
->hw
.resolution
;
67 if (copy_to_user(_info
, &info
, sizeof(*_info
)))
73 SNDRV_TIMER_IOCTL_GPARAMS32
= _IOW('T', 0x04, struct snd_timer_gparams32
),
74 SNDRV_TIMER_IOCTL_INFO32
= _IOR('T', 0x11, struct snd_timer_info32
),
75 SNDRV_TIMER_IOCTL_STATUS_COMPAT32
= _IOW('T', 0x14, struct snd_timer_status32
),
76 SNDRV_TIMER_IOCTL_STATUS_COMPAT64
= _IOW('T', 0x14, struct snd_timer_status64
),
79 static long __snd_timer_user_ioctl_compat(struct file
*file
, unsigned int cmd
,
82 void __user
*argp
= compat_ptr(arg
);
85 case SNDRV_TIMER_IOCTL_PVERSION
:
86 case SNDRV_TIMER_IOCTL_TREAD_OLD
:
87 case SNDRV_TIMER_IOCTL_TREAD64
:
88 case SNDRV_TIMER_IOCTL_GINFO
:
89 case SNDRV_TIMER_IOCTL_GSTATUS
:
90 case SNDRV_TIMER_IOCTL_SELECT
:
91 case SNDRV_TIMER_IOCTL_PARAMS
:
92 case SNDRV_TIMER_IOCTL_START
:
93 case SNDRV_TIMER_IOCTL_START_OLD
:
94 case SNDRV_TIMER_IOCTL_STOP
:
95 case SNDRV_TIMER_IOCTL_STOP_OLD
:
96 case SNDRV_TIMER_IOCTL_CONTINUE
:
97 case SNDRV_TIMER_IOCTL_CONTINUE_OLD
:
98 case SNDRV_TIMER_IOCTL_PAUSE
:
99 case SNDRV_TIMER_IOCTL_PAUSE_OLD
:
100 case SNDRV_TIMER_IOCTL_NEXT_DEVICE
:
101 return __snd_timer_user_ioctl(file
, cmd
, (unsigned long)argp
, true);
102 case SNDRV_TIMER_IOCTL_GPARAMS32
:
103 return snd_timer_user_gparams_compat(file
, argp
);
104 case SNDRV_TIMER_IOCTL_INFO32
:
105 return snd_timer_user_info_compat(file
, argp
);
106 case SNDRV_TIMER_IOCTL_STATUS_COMPAT32
:
107 return snd_timer_user_status32(file
, argp
);
108 case SNDRV_TIMER_IOCTL_STATUS_COMPAT64
:
109 return snd_timer_user_status64(file
, argp
);
114 static long snd_timer_user_ioctl_compat(struct file
*file
, unsigned int cmd
,
117 struct snd_timer_user
*tu
= file
->private_data
;
120 mutex_lock(&tu
->ioctl_lock
);
121 ret
= __snd_timer_user_ioctl_compat(file
, cmd
, arg
);
122 mutex_unlock(&tu
->ioctl_lock
);