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

ALSA: compress_offload: Add SNDRV_COMPRESS_AVAIL64 ioctl

The previous patch introduced a 64-bit timestamp ioctl
(SNDRV_COMPRESS_TSTAMP64). To provide a consistent API, this patch
adds a corresponding 64-bit version of the SNDRV_COMPRESS_AVAIL ioctl.

A new struct snd_compr_avail64 is added to the UAPI, which includes
the 64-bit timestamp. The existing ioctl implementation is refactored
to handle both the 32-bit and 64-bit variants.

Reviewed-by: Miller Liang <millerliang@google.com>
Tested-by: Joris Verhaegen <verhaegen@google.com>
Signed-off-by: Joris Verhaegen <verhaegen@google.com>
Acked-by: Vinod Koul <vkoul@kernel.org>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20250905091301.2711705-4-verhaegen@google.com

authored by

Joris Verhaegen and committed by
Takashi Iwai
86eec88c f20a5397

+39 -15
+11
include/uapi/sound/compress_offload.h
··· 84 84 struct snd_compr_tstamp tstamp; 85 85 } __attribute__((packed, aligned(4))); 86 86 87 + /** 88 + * struct snd_compr_avail64 - avail descriptor with tstamp in 64 bit format 89 + * @avail: Number of bytes available in ring buffer for writing/reading 90 + * @tstamp: timestamp information 91 + */ 92 + struct snd_compr_avail64 { 93 + __u64 avail; 94 + struct snd_compr_tstamp64 tstamp; 95 + } __attribute__((packed, aligned(4))); 96 + 87 97 enum snd_compr_direction { 88 98 SND_COMPRESS_PLAYBACK = 0, 89 99 SND_COMPRESS_CAPTURE, ··· 241 231 #define SNDRV_COMPRESS_TSTAMP _IOR('C', 0x20, struct snd_compr_tstamp) 242 232 #define SNDRV_COMPRESS_AVAIL _IOR('C', 0x21, struct snd_compr_avail) 243 233 #define SNDRV_COMPRESS_TSTAMP64 _IOR('C', 0x22, struct snd_compr_tstamp64) 234 + #define SNDRV_COMPRESS_AVAIL64 _IOR('C', 0x23, struct snd_compr_avail64) 244 235 #define SNDRV_COMPRESS_PAUSE _IO('C', 0x30) 245 236 #define SNDRV_COMPRESS_RESUME _IO('C', 0x31) 246 237 #define SNDRV_COMPRESS_START _IO('C', 0x32)
+28 -15
sound/core/compress_offload.c
··· 203 203 } 204 204 205 205 static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, 206 - struct snd_compr_avail *avail) 206 + struct snd_compr_avail64 *avail) 207 207 { 208 - struct snd_compr_tstamp64 tstamp64 = { 0 }; 209 - 210 208 memset(avail, 0, sizeof(*avail)); 211 - snd_compr_update_tstamp(stream, &tstamp64); 212 - snd_compr_tstamp32_from_64(&avail->tstamp, &tstamp64); 209 + snd_compr_update_tstamp(stream, &avail->tstamp); 213 210 /* Still need to return avail even if tstamp can't be filled in */ 214 211 215 212 if (stream->runtime->total_bytes_available == 0 && ··· 234 237 if (stream->direction == SND_COMPRESS_PLAYBACK) 235 238 avail->avail = stream->runtime->buffer_size - avail->avail; 236 239 237 - pr_debug("ret avail as %llu\n", avail->avail); 240 + pr_debug("ret avail as %zu\n", (size_t)avail->avail); 238 241 return avail->avail; 239 242 } 240 243 241 244 static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream) 242 245 { 243 - struct snd_compr_avail avail; 246 + struct snd_compr_avail64 avail; 244 247 245 248 return snd_compr_calc_avail(stream, &avail); 246 249 } 247 250 248 - static int 249 - snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg) 251 + static void snd_compr_avail32_from_64(struct snd_compr_avail *avail32, 252 + const struct snd_compr_avail64 *avail64) 250 253 { 251 - struct snd_compr_avail ioctl_avail; 254 + avail32->avail = avail64->avail; 255 + snd_compr_tstamp32_from_64(&avail32->tstamp, &avail64->tstamp); 256 + } 257 + 258 + static int snd_compr_ioctl_avail(struct snd_compr_stream *stream, 259 + unsigned long arg, bool is_32bit) 260 + { 261 + struct snd_compr_avail64 ioctl_avail64; 262 + struct snd_compr_avail ioctl_avail32; 252 263 size_t avail; 264 + const void *copy_from = &ioctl_avail64; 265 + size_t copy_size = sizeof(ioctl_avail64); 253 266 254 267 if (stream->direction == SND_COMPRESS_ACCEL) 255 268 return -EBADFD; 256 269 257 - avail = snd_compr_calc_avail(stream, &ioctl_avail); 258 - ioctl_avail.avail = avail; 270 + avail = snd_compr_calc_avail(stream, &ioctl_avail64); 271 + ioctl_avail64.avail = avail; 272 + if (is_32bit) { 273 + snd_compr_avail32_from_64(&ioctl_avail32, &ioctl_avail64); 274 + copy_from = &ioctl_avail32; 275 + copy_size = sizeof(ioctl_avail32); 276 + } 259 277 260 278 switch (stream->runtime->state) { 261 279 case SNDRV_PCM_STATE_OPEN: ··· 281 269 break; 282 270 } 283 271 284 - if (copy_to_user((__u64 __user *)arg, 285 - &ioctl_avail, sizeof(ioctl_avail))) 272 + if (copy_to_user((__u64 __user *)arg, copy_from, copy_size)) 286 273 return -EFAULT; 287 274 return 0; 288 275 } ··· 1347 1336 case SNDRV_COMPRESS_TSTAMP64: 1348 1337 return snd_compr_tstamp(stream, arg, false); 1349 1338 case SNDRV_COMPRESS_AVAIL: 1350 - return snd_compr_ioctl_avail(stream, arg); 1339 + return snd_compr_ioctl_avail(stream, arg, true); 1340 + case SNDRV_COMPRESS_AVAIL64: 1341 + return snd_compr_ioctl_avail(stream, arg, false); 1351 1342 case SNDRV_COMPRESS_PAUSE: 1352 1343 return snd_compr_pause(stream); 1353 1344 case SNDRV_COMPRESS_RESUME: