Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: pcm: Add an ioctl to specify the supported protocol version

We have an ioctl to inform the PCM protocol version the running kernel
supports, but there is no way to know which protocol version the
user-space can understand. This lack of information caused headaches
in the past when we tried to extend the ABI. For example, because we
couldn't guarantee the validity of the reserved bytes, we had to
introduce a new ioctl SNDRV_PCM_IOCTL_STATUS_EXT for assigning a few
new fields in the formerly reserved bits. If we could know that it's
a new alsa-lib, we could assume the availability of the new fields,
thus we could have reused the existing SNDRV_PCM_IOCTL_STATUS.

In order to improve the ABI extensibility, this patch adds a new ioctl
for user-space to inform its supporting protocol version to the
kernel. By reporting the supported protocol from user-space, the
kernel can judge which feature should be provided and which not.

With the addition of the new ioctl, the PCM protocol version is bumped
to 2.0.14, too. User-space checks the kernel protocol version via
SNDRV_PCM_INFO_PVERSION, then it sets the supported version back via
SNDRV_PCM_INFO_USER_PVERSION.

Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+11 -1
+1
include/sound/pcm.h
··· 218 218 struct snd_pcm_file { 219 219 struct snd_pcm_substream *substream; 220 220 int no_compat_mmap; 221 + unsigned int user_pversion; /* supported protocol version */ 221 222 }; 222 223 223 224 struct snd_pcm_hw_rule;
+2 -1
include/uapi/sound/asound.h
··· 152 152 * * 153 153 *****************************************************************************/ 154 154 155 - #define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 13) 155 + #define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 14) 156 156 157 157 typedef unsigned long snd_pcm_uframes_t; 158 158 typedef signed long snd_pcm_sframes_t; ··· 564 564 #define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info) 565 565 #define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int) 566 566 #define SNDRV_PCM_IOCTL_TTSTAMP _IOW('A', 0x03, int) 567 + #define SNDRV_PCM_IOCTL_USER_PVERSION _IOW('A', 0x04, int) 567 568 #define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct snd_pcm_hw_params) 568 569 #define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct snd_pcm_hw_params) 569 570 #define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12)
+1
sound/core/pcm_compat.c
··· 676 676 case SNDRV_PCM_IOCTL_INFO: 677 677 case SNDRV_PCM_IOCTL_TSTAMP: 678 678 case SNDRV_PCM_IOCTL_TTSTAMP: 679 + case SNDRV_PCM_IOCTL_USER_PVERSION: 679 680 case SNDRV_PCM_IOCTL_HWSYNC: 680 681 case SNDRV_PCM_IOCTL_PREPARE: 681 682 case SNDRV_PCM_IOCTL_RESET:
+7
sound/core/pcm_native.c
··· 2770 2770 struct snd_pcm_substream *substream, 2771 2771 unsigned int cmd, void __user *arg) 2772 2772 { 2773 + struct snd_pcm_file *pcm_file = file->private_data; 2774 + 2773 2775 switch (cmd) { 2774 2776 case SNDRV_PCM_IOCTL_PVERSION: 2775 2777 return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; ··· 2781 2779 return 0; 2782 2780 case SNDRV_PCM_IOCTL_TTSTAMP: 2783 2781 return snd_pcm_tstamp(substream, arg); 2782 + case SNDRV_PCM_IOCTL_USER_PVERSION: 2783 + if (get_user(pcm_file->user_pversion, 2784 + (unsigned int __user *)arg)) 2785 + return -EFAULT; 2786 + return 0; 2784 2787 case SNDRV_PCM_IOCTL_HW_REFINE: 2785 2788 return snd_pcm_hw_refine_user(substream, arg); 2786 2789 case SNDRV_PCM_IOCTL_HW_PARAMS: