The new framing mode causes the user space regression, because the alsa-lib code does not initialize the reserved space in the params structure when the device is opened. This change adds SNDRV_RAWMIDI_IOCTL_USER_PVERSION like we do for the PCM interface for the protocol acknowledgment.
Unified · Split
| @@ -98,6 +98,7 @@ struct snd_rawmidi_file { · 97 unmodified lines | |||
| 98 | struct snd_rawmidi *rmidi; | 98 | struct snd_rawmidi *rmidi; |
| 99 | struct snd_rawmidi_substream *input; | 99 | struct snd_rawmidi_substream *input; |
| 100 | struct snd_rawmidi_substream *output; | 100 | struct snd_rawmidi_substream *output; |
| 101 | unsigned int user_pversion; /* supported protocol version */ | ||
| 101 | }; | 102 | }; |
| 102 | 103 | ||
| 103 | struct snd_rawmidi_str { | 104 | struct snd_rawmidi_str { |
| @@ -784,6 +784,7 @@ struct snd_rawmidi_status { · 783 unmodified lines | |||
| 784 | 784 | ||
| 785 | #define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) | 785 | #define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) |
| 786 | #define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info) | 786 | #define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info) |
| 787 | #define SNDRV_RAWMIDI_IOCTL_USER_PVERSION _IOW('W', 0x02, int) | ||
| 787 | #define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params) | 788 | #define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params) |
| 788 | #define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status) | 789 | #define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status) |
| 789 | #define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) | 790 | #define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) |
| @@ -873,12 +873,21 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long · 872 unmodified lines | |||
| 873 | return -EINVAL; | 873 | return -EINVAL; |
| 874 | } | 874 | } |
| 875 | } | 875 | } |
| 876 | case SNDRV_RAWMIDI_IOCTL_USER_PVERSION: | ||
| 877 | if (get_user(rfile->user_pversion, (unsigned int __user *)arg)) | ||
| 878 | return -EFAULT; | ||
| 879 | return 0; | ||
| 880 | |||
| 876 | case SNDRV_RAWMIDI_IOCTL_PARAMS: | 881 | case SNDRV_RAWMIDI_IOCTL_PARAMS: |
| 877 | { | 882 | { |
| 878 | struct snd_rawmidi_params params; | 883 | struct snd_rawmidi_params params; |
| 879 | 884 | ||
| 880 | if (copy_from_user(¶ms, argp, sizeof(struct snd_rawmidi_params))) | 885 | if (copy_from_user(¶ms, argp, sizeof(struct snd_rawmidi_params))) |
| 881 | return -EFAULT; | 886 | return -EFAULT; |
| 887 | if (rfile->user_pversion < SNDRV_PROTOCOL_VERSION(2, 0, 2)) { | ||
| 888 | params.mode = 0; | ||
| 889 | memset(params.reserved, 0, sizeof(params.reserved)); | ||
| 890 | } | ||
| 882 | switch (params.stream) { | 891 | switch (params.stream) { |
| 883 | case SNDRV_RAWMIDI_STREAM_OUTPUT: | 892 | case SNDRV_RAWMIDI_STREAM_OUTPUT: |
| 884 | if (rfile->output == NULL) | 893 | if (rfile->output == NULL) |