1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * compress_core.c - compress offload core
4 *
5 * Copyright (C) 2011 Intel Corporation
6 * Authors: Vinod Koul <vinod.koul@linux.intel.com>
7 * Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 */
12 #define FORMAT(fmt) "%s: %d: " fmt, __func__, __LINE__
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " FORMAT(fmt)
14
15 #include <linux/file.h>
16 #include <linux/fs.h>
17 #include <linux/list.h>
18 #include <linux/math64.h>
19 #include <linux/mm.h>
20 #include <linux/mutex.h>
21 #include <linux/poll.h>
22 #include <linux/slab.h>
23 #include <linux/sched.h>
24 #include <linux/types.h>
25 #include <linux/uio.h>
26 #include <linux/uaccess.h>
27 #include <linux/dma-buf.h>
28 #include <linux/module.h>
29 #include <linux/compat.h>
30 #include <sound/core.h>
31 #include <sound/initval.h>
32 #include <sound/info.h>
33 #include <sound/compress_params.h>
34 #include <sound/compress_offload.h>
35 #include <sound/compress_driver.h>
36
37 /* struct snd_compr_codec_caps overflows the ioctl bit size for some
38 * architectures, so we need to disable the relevant ioctls.
39 */
40 #if _IOC_SIZEBITS < 14
41 #define COMPR_CODEC_CAPS_OVERFLOW
42 #endif
43
44 /* TODO:
45 * - add substream support for multiple devices in case of
46 * SND_DYNAMIC_MINORS is not used
47 * - Multiple node representation
48 * driver should be able to register multiple nodes
49 */
50
51 struct snd_compr_file {
52 unsigned long caps;
53 struct snd_compr_stream stream;
54 };
55
56 static void error_delayed_work(struct work_struct *work);
57
58 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)
59 static void snd_compr_task_free_all(struct snd_compr_stream *stream);
60 #else
snd_compr_task_free_all(struct snd_compr_stream * stream)61 static inline void snd_compr_task_free_all(struct snd_compr_stream *stream) { }
62 #endif
63
64 /*
65 * a note on stream states used:
66 * we use following states in the compressed core
67 * SNDRV_PCM_STATE_OPEN: When stream has been opened.
68 * SNDRV_PCM_STATE_SETUP: When stream has been initialized. This is done by
69 * calling SNDRV_COMPRESS_SET_PARAMS. Running streams will come to this
70 * state at stop by calling SNDRV_COMPRESS_STOP, or at end of drain.
71 * SNDRV_PCM_STATE_PREPARED: When a stream has been written to (for
72 * playback only). User after setting up stream writes the data buffer
73 * before starting the stream.
74 * SNDRV_PCM_STATE_RUNNING: When stream has been started and is
75 * decoding/encoding and rendering/capturing data.
76 * SNDRV_PCM_STATE_DRAINING: When stream is draining current data. This is done
77 * by calling SNDRV_COMPRESS_DRAIN.
78 * SNDRV_PCM_STATE_PAUSED: When stream is paused. This is done by calling
79 * SNDRV_COMPRESS_PAUSE. It can be stopped or resumed by calling
80 * SNDRV_COMPRESS_STOP or SNDRV_COMPRESS_RESUME respectively.
81 */
snd_compr_open(struct inode * inode,struct file * f)82 static int snd_compr_open(struct inode *inode, struct file *f)
83 {
84 struct snd_compr *compr;
85 struct snd_compr_file *data;
86 struct snd_compr_runtime *runtime;
87 enum snd_compr_direction dirn;
88 int maj = imajor(inode);
89 int ret;
90
91 if ((f->f_flags & O_ACCMODE) == O_WRONLY)
92 dirn = SND_COMPRESS_PLAYBACK;
93 else if ((f->f_flags & O_ACCMODE) == O_RDONLY)
94 dirn = SND_COMPRESS_CAPTURE;
95 else if ((f->f_flags & O_ACCMODE) == O_RDWR)
96 dirn = SND_COMPRESS_ACCEL;
97 else
98 return -EINVAL;
99
100 if (maj == snd_major)
101 compr = snd_lookup_minor_data(iminor(inode),
102 SNDRV_DEVICE_TYPE_COMPRESS);
103 else
104 return -EBADFD;
105
106 if (compr == NULL) {
107 pr_err("no device data!!!\n");
108 return -ENODEV;
109 }
110
111 if (dirn != compr->direction) {
112 pr_err("this device doesn't support this direction\n");
113 snd_card_unref(compr->card);
114 return -EINVAL;
115 }
116
117 data = kzalloc(sizeof(*data), GFP_KERNEL);
118 if (!data) {
119 snd_card_unref(compr->card);
120 return -ENOMEM;
121 }
122
123 INIT_DELAYED_WORK(&data->stream.error_work, error_delayed_work);
124
125 data->stream.ops = compr->ops;
126 data->stream.direction = dirn;
127 data->stream.private_data = compr->private_data;
128 data->stream.device = compr;
129 runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
130 if (!runtime) {
131 kfree(data);
132 snd_card_unref(compr->card);
133 return -ENOMEM;
134 }
135 runtime->state = SNDRV_PCM_STATE_OPEN;
136 init_waitqueue_head(&runtime->sleep);
137 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)
138 INIT_LIST_HEAD(&runtime->tasks);
139 #endif
140 data->stream.runtime = runtime;
141 f->private_data = (void *)data;
142 scoped_guard(mutex, &compr->lock)
143 ret = compr->ops->open(&data->stream);
144 if (ret) {
145 kfree(runtime);
146 kfree(data);
147 }
148 snd_card_unref(compr->card);
149 return ret;
150 }
151
snd_compr_free(struct inode * inode,struct file * f)152 static int snd_compr_free(struct inode *inode, struct file *f)
153 {
154 struct snd_compr_file *data = f->private_data;
155 struct snd_compr_runtime *runtime = data->stream.runtime;
156
157 cancel_delayed_work_sync(&data->stream.error_work);
158
159 switch (runtime->state) {
160 case SNDRV_PCM_STATE_RUNNING:
161 case SNDRV_PCM_STATE_DRAINING:
162 case SNDRV_PCM_STATE_PAUSED:
163 data->stream.ops->trigger(&data->stream, SNDRV_PCM_TRIGGER_STOP);
164 break;
165 default:
166 break;
167 }
168
169 snd_compr_task_free_all(&data->stream);
170
171 data->stream.ops->free(&data->stream);
172 if (!data->stream.runtime->dma_buffer_p)
173 kfree(data->stream.runtime->buffer);
174 kfree(data->stream.runtime);
175 kfree(data);
176 return 0;
177 }
178
179 static void
snd_compr_tstamp32_from_64(struct snd_compr_tstamp * tstamp32,const struct snd_compr_tstamp64 * tstamp64)180 snd_compr_tstamp32_from_64(struct snd_compr_tstamp *tstamp32,
181 const struct snd_compr_tstamp64 *tstamp64)
182 {
183 tstamp32->byte_offset = tstamp64->byte_offset;
184 tstamp32->copied_total = (u32)tstamp64->copied_total;
185 tstamp32->pcm_frames = (u32)tstamp64->pcm_frames;
186 tstamp32->pcm_io_frames = (u32)tstamp64->pcm_io_frames;
187 tstamp32->sampling_rate = tstamp64->sampling_rate;
188 }
189
snd_compr_update_tstamp(struct snd_compr_stream * stream,struct snd_compr_tstamp64 * tstamp)190 static int snd_compr_update_tstamp(struct snd_compr_stream *stream,
191 struct snd_compr_tstamp64 *tstamp)
192 {
193 if (!stream->ops->pointer)
194 return -ENOTSUPP;
195 stream->ops->pointer(stream, tstamp);
196 pr_debug("dsp consumed till %u total %llu bytes\n", tstamp->byte_offset,
197 tstamp->copied_total);
198 if (stream->direction == SND_COMPRESS_PLAYBACK)
199 stream->runtime->total_bytes_transferred = tstamp->copied_total;
200 else
201 stream->runtime->total_bytes_available = tstamp->copied_total;
202 return 0;
203 }
204
snd_compr_calc_avail(struct snd_compr_stream * stream,struct snd_compr_avail64 * avail)205 static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
206 struct snd_compr_avail64 *avail)
207 {
208 memset(avail, 0, sizeof(*avail));
209 snd_compr_update_tstamp(stream, &avail->tstamp);
210 /* Still need to return avail even if tstamp can't be filled in */
211
212 if (stream->runtime->total_bytes_available == 0 &&
213 stream->runtime->state == SNDRV_PCM_STATE_SETUP &&
214 stream->direction == SND_COMPRESS_PLAYBACK) {
215 pr_debug("detected init and someone forgot to do a write\n");
216 return stream->runtime->buffer_size;
217 }
218 pr_debug("app wrote %llu, DSP consumed %llu\n",
219 stream->runtime->total_bytes_available,
220 stream->runtime->total_bytes_transferred);
221 if (stream->runtime->total_bytes_available ==
222 stream->runtime->total_bytes_transferred) {
223 if (stream->direction == SND_COMPRESS_PLAYBACK) {
224 pr_debug("both pointers are same, returning full avail\n");
225 return stream->runtime->buffer_size;
226 } else {
227 pr_debug("both pointers are same, returning no avail\n");
228 return 0;
229 }
230 }
231
232 avail->avail = stream->runtime->total_bytes_available -
233 stream->runtime->total_bytes_transferred;
234 if (stream->direction == SND_COMPRESS_PLAYBACK)
235 avail->avail = stream->runtime->buffer_size - avail->avail;
236
237 pr_debug("ret avail as %zu\n", (size_t)avail->avail);
238 return avail->avail;
239 }
240
snd_compr_get_avail(struct snd_compr_stream * stream)241 static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream)
242 {
243 struct snd_compr_avail64 avail;
244
245 return snd_compr_calc_avail(stream, &avail);
246 }
247
snd_compr_avail32_from_64(struct snd_compr_avail * avail32,const struct snd_compr_avail64 * avail64)248 static void snd_compr_avail32_from_64(struct snd_compr_avail *avail32,
249 const struct snd_compr_avail64 *avail64)
250 {
251 avail32->avail = avail64->avail;
252 snd_compr_tstamp32_from_64(&avail32->tstamp, &avail64->tstamp);
253 }
254
snd_compr_ioctl_avail(struct snd_compr_stream * stream,unsigned long arg,bool is_32bit)255 static int snd_compr_ioctl_avail(struct snd_compr_stream *stream,
256 unsigned long arg, bool is_32bit)
257 {
258 struct snd_compr_avail64 ioctl_avail64;
259 struct snd_compr_avail ioctl_avail32;
260 size_t avail;
261 const void *copy_from = &ioctl_avail64;
262 size_t copy_size = sizeof(ioctl_avail64);
263
264 if (stream->direction == SND_COMPRESS_ACCEL)
265 return -EBADFD;
266
267 avail = snd_compr_calc_avail(stream, &ioctl_avail64);
268 ioctl_avail64.avail = avail;
269 if (is_32bit) {
270 snd_compr_avail32_from_64(&ioctl_avail32, &ioctl_avail64);
271 copy_from = &ioctl_avail32;
272 copy_size = sizeof(ioctl_avail32);
273 }
274
275 switch (stream->runtime->state) {
276 case SNDRV_PCM_STATE_OPEN:
277 return -EBADFD;
278 case SNDRV_PCM_STATE_XRUN:
279 return -EPIPE;
280 default:
281 break;
282 }
283
284 if (copy_to_user((__u64 __user *)arg, copy_from, copy_size))
285 return -EFAULT;
286 return 0;
287 }
288
snd_compr_write_data(struct snd_compr_stream * stream,const char __user * buf,size_t count)289 static int snd_compr_write_data(struct snd_compr_stream *stream,
290 const char __user *buf, size_t count)
291 {
292 void *dstn;
293 size_t copy;
294 struct snd_compr_runtime *runtime = stream->runtime;
295 /* 64-bit Modulus */
296 u64 app_pointer = div64_u64(runtime->total_bytes_available,
297 runtime->buffer_size);
298 app_pointer = runtime->total_bytes_available -
299 (app_pointer * runtime->buffer_size);
300
301 dstn = runtime->buffer + app_pointer;
302 pr_debug("copying %lu at %llu\n", (unsigned long)count, app_pointer);
303 if (count < runtime->buffer_size - app_pointer) {
304 if (copy_from_user(dstn, buf, count))
305 return -EFAULT;
306 } else {
307 copy = runtime->buffer_size - app_pointer;
308 if (copy_from_user(dstn, buf, copy))
309 return -EFAULT;
310 if (copy_from_user(runtime->buffer, buf + copy, count - copy))
311 return -EFAULT;
312 }
313 /* if DSP cares, let it know data has been written */
314 if (stream->ops->ack)
315 stream->ops->ack(stream, count);
316 return count;
317 }
318
snd_compr_write(struct file * f,const char __user * buf,size_t count,loff_t * offset)319 static ssize_t snd_compr_write(struct file *f, const char __user *buf,
320 size_t count, loff_t *offset)
321 {
322 struct snd_compr_file *data = f->private_data;
323 struct snd_compr_stream *stream;
324 size_t avail;
325 int retval;
326
327 if (snd_BUG_ON(!data))
328 return -EFAULT;
329
330 stream = &data->stream;
331 if (stream->direction == SND_COMPRESS_ACCEL)
332 return -EBADFD;
333 guard(mutex)(&stream->device->lock);
334 /* write is allowed when stream is running or has been setup */
335 switch (stream->runtime->state) {
336 case SNDRV_PCM_STATE_SETUP:
337 case SNDRV_PCM_STATE_PREPARED:
338 case SNDRV_PCM_STATE_RUNNING:
339 break;
340 default:
341 return -EBADFD;
342 }
343
344 avail = snd_compr_get_avail(stream);
345 pr_debug("avail returned %lu\n", (unsigned long)avail);
346 /* calculate how much we can write to buffer */
347 if (avail > count)
348 avail = count;
349
350 if (stream->ops->copy) {
351 char __user* cbuf = (char __user*)buf;
352 retval = stream->ops->copy(stream, cbuf, avail);
353 } else {
354 retval = snd_compr_write_data(stream, buf, avail);
355 }
356 if (retval > 0)
357 stream->runtime->total_bytes_available += retval;
358
359 /* while initiating the stream, write should be called before START
360 * call, so in setup move state */
361 if (stream->runtime->state == SNDRV_PCM_STATE_SETUP) {
362 stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
363 pr_debug("stream prepared, Houston we are good to go\n");
364 }
365
366 return retval;
367 }
368
369
snd_compr_read(struct file * f,char __user * buf,size_t count,loff_t * offset)370 static ssize_t snd_compr_read(struct file *f, char __user *buf,
371 size_t count, loff_t *offset)
372 {
373 struct snd_compr_file *data = f->private_data;
374 struct snd_compr_stream *stream;
375 size_t avail;
376 int retval;
377
378 if (snd_BUG_ON(!data))
379 return -EFAULT;
380
381 stream = &data->stream;
382 if (stream->direction == SND_COMPRESS_ACCEL)
383 return -EBADFD;
384 guard(mutex)(&stream->device->lock);
385
386 /* read is allowed when stream is running, paused, draining and setup
387 * (yes setup is state which we transition to after stop, so if user
388 * wants to read data after stop we allow that)
389 */
390 switch (stream->runtime->state) {
391 case SNDRV_PCM_STATE_OPEN:
392 case SNDRV_PCM_STATE_PREPARED:
393 case SNDRV_PCM_STATE_SUSPENDED:
394 case SNDRV_PCM_STATE_DISCONNECTED:
395 return -EBADFD;
396 case SNDRV_PCM_STATE_XRUN:
397 return -EPIPE;
398 }
399
400 avail = snd_compr_get_avail(stream);
401 pr_debug("avail returned %lu\n", (unsigned long)avail);
402 /* calculate how much we can read from buffer */
403 if (avail > count)
404 avail = count;
405
406 if (stream->ops->copy)
407 retval = stream->ops->copy(stream, buf, avail);
408 else
409 return -ENXIO;
410 if (retval > 0)
411 stream->runtime->total_bytes_transferred += retval;
412
413 return retval;
414 }
415
snd_compr_mmap(struct file * f,struct vm_area_struct * vma)416 static int snd_compr_mmap(struct file *f, struct vm_area_struct *vma)
417 {
418 return -ENXIO;
419 }
420
snd_compr_get_poll(struct snd_compr_stream * stream)421 static __poll_t snd_compr_get_poll(struct snd_compr_stream *stream)
422 {
423 if (stream->direction == SND_COMPRESS_PLAYBACK)
424 return EPOLLOUT | EPOLLWRNORM;
425 else
426 return EPOLLIN | EPOLLRDNORM;
427 }
428
snd_compr_poll(struct file * f,poll_table * wait)429 static __poll_t snd_compr_poll(struct file *f, poll_table *wait)
430 {
431 struct snd_compr_file *data = f->private_data;
432 struct snd_compr_stream *stream;
433 struct snd_compr_runtime *runtime;
434 size_t avail;
435 __poll_t retval = 0;
436
437 if (snd_BUG_ON(!data))
438 return EPOLLERR;
439
440 stream = &data->stream;
441 runtime = stream->runtime;
442
443 guard(mutex)(&stream->device->lock);
444
445 switch (runtime->state) {
446 case SNDRV_PCM_STATE_OPEN:
447 case SNDRV_PCM_STATE_XRUN:
448 return snd_compr_get_poll(stream) | EPOLLERR;
449 default:
450 break;
451 }
452
453 poll_wait(f, &runtime->sleep, wait);
454
455 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)
456 if (stream->direction == SND_COMPRESS_ACCEL) {
457 struct snd_compr_task_runtime *task;
458 if (runtime->fragments > runtime->active_tasks)
459 retval |= EPOLLOUT | EPOLLWRNORM;
460 task = list_first_entry_or_null(&runtime->tasks,
461 struct snd_compr_task_runtime,
462 list);
463 if (task && task->state == SND_COMPRESS_TASK_STATE_FINISHED)
464 retval |= EPOLLIN | EPOLLRDNORM;
465 return retval;
466 }
467 #endif
468
469 avail = snd_compr_get_avail(stream);
470 pr_debug("avail is %lu\n", (unsigned long)avail);
471 /* check if we have at least one fragment to fill */
472 switch (runtime->state) {
473 case SNDRV_PCM_STATE_DRAINING:
474 /* stream has been woken up after drain is complete
475 * draining done so set stream state to stopped
476 */
477 retval = snd_compr_get_poll(stream);
478 runtime->state = SNDRV_PCM_STATE_SETUP;
479 break;
480 case SNDRV_PCM_STATE_RUNNING:
481 case SNDRV_PCM_STATE_PREPARED:
482 case SNDRV_PCM_STATE_PAUSED:
483 if (avail >= runtime->fragment_size)
484 retval = snd_compr_get_poll(stream);
485 break;
486 default:
487 return snd_compr_get_poll(stream) | EPOLLERR;
488 }
489
490 return retval;
491 }
492
493 static int
snd_compr_get_caps(struct snd_compr_stream * stream,unsigned long arg)494 snd_compr_get_caps(struct snd_compr_stream *stream, unsigned long arg)
495 {
496 int retval;
497 struct snd_compr_caps caps;
498
499 if (!stream->ops->get_caps)
500 return -ENXIO;
501
502 memset(&caps, 0, sizeof(caps));
503 retval = stream->ops->get_caps(stream, &caps);
504 if (retval)
505 goto out;
506 if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
507 retval = -EFAULT;
508 out:
509 return retval;
510 }
511
512 #ifndef COMPR_CODEC_CAPS_OVERFLOW
513 static int
snd_compr_get_codec_caps(struct snd_compr_stream * stream,unsigned long arg)514 snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg)
515 {
516 int retval;
517 struct snd_compr_codec_caps *caps __free(kfree) = NULL;
518
519 if (!stream->ops->get_codec_caps)
520 return -ENXIO;
521
522 caps = kzalloc(sizeof(*caps), GFP_KERNEL);
523 if (!caps)
524 return -ENOMEM;
525
526 retval = stream->ops->get_codec_caps(stream, caps);
527 if (retval)
528 return retval;
529 if (copy_to_user((void __user *)arg, caps, sizeof(*caps)))
530 return -EFAULT;
531 return retval;
532 }
533 #endif /* !COMPR_CODEC_CAPS_OVERFLOW */
534
snd_compr_malloc_pages(struct snd_compr_stream * stream,size_t size)535 int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size)
536 {
537 struct snd_dma_buffer *dmab;
538 int ret;
539
540 if (snd_BUG_ON(!(stream) || !(stream)->runtime))
541 return -EINVAL;
542 dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
543 if (!dmab)
544 return -ENOMEM;
545 dmab->dev = stream->dma_buffer.dev;
546 ret = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, size, dmab);
547 if (ret < 0) {
548 kfree(dmab);
549 return ret;
550 }
551
552 snd_compr_set_runtime_buffer(stream, dmab);
553 stream->runtime->dma_bytes = size;
554 return 1;
555 }
556 EXPORT_SYMBOL(snd_compr_malloc_pages);
557
snd_compr_free_pages(struct snd_compr_stream * stream)558 int snd_compr_free_pages(struct snd_compr_stream *stream)
559 {
560 struct snd_compr_runtime *runtime;
561
562 if (snd_BUG_ON(!(stream) || !(stream)->runtime))
563 return -EINVAL;
564 runtime = stream->runtime;
565 if (runtime->dma_area == NULL)
566 return 0;
567 if (runtime->dma_buffer_p != &stream->dma_buffer) {
568 /* It's a newly allocated buffer. Release it now. */
569 snd_dma_free_pages(runtime->dma_buffer_p);
570 kfree(runtime->dma_buffer_p);
571 }
572
573 snd_compr_set_runtime_buffer(stream, NULL);
574 return 0;
575 }
576 EXPORT_SYMBOL(snd_compr_free_pages);
577
578 /* revisit this with snd_pcm_preallocate_xxx */
snd_compr_allocate_buffer(struct snd_compr_stream * stream,struct snd_compr_params * params)579 static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
580 struct snd_compr_params *params)
581 {
582 unsigned int buffer_size;
583 void *buffer = NULL;
584
585 if (stream->direction == SND_COMPRESS_ACCEL)
586 goto params;
587
588 buffer_size = params->buffer.fragment_size * params->buffer.fragments;
589 if (stream->ops->copy) {
590 buffer = NULL;
591 /* if copy is defined the driver will be required to copy
592 * the data from core
593 */
594 } else {
595 if (stream->runtime->dma_buffer_p) {
596
597 if (buffer_size > stream->runtime->dma_buffer_p->bytes)
598 dev_err(stream->device->dev,
599 "Not enough DMA buffer");
600 else
601 buffer = stream->runtime->dma_buffer_p->area;
602
603 } else {
604 buffer = kmalloc(buffer_size, GFP_KERNEL);
605 }
606
607 if (!buffer)
608 return -ENOMEM;
609 }
610
611 stream->runtime->buffer = buffer;
612 stream->runtime->buffer_size = buffer_size;
613 params:
614 stream->runtime->fragment_size = params->buffer.fragment_size;
615 stream->runtime->fragments = params->buffer.fragments;
616 return 0;
617 }
618
619 static int
snd_compress_check_input(struct snd_compr_stream * stream,struct snd_compr_params * params)620 snd_compress_check_input(struct snd_compr_stream *stream, struct snd_compr_params *params)
621 {
622 u32 max_fragments;
623
624 /* first let's check the buffer parameter's */
625 if (params->buffer.fragment_size == 0)
626 return -EINVAL;
627
628 if (stream->direction == SND_COMPRESS_ACCEL)
629 max_fragments = 64; /* safe value */
630 else
631 max_fragments = U32_MAX / params->buffer.fragment_size;
632
633 if (params->buffer.fragments > max_fragments ||
634 params->buffer.fragments == 0)
635 return -EINVAL;
636
637 /* now codec parameters */
638 if (params->codec.id == 0 || params->codec.id > SND_AUDIOCODEC_MAX)
639 return -EINVAL;
640
641 if (params->codec.ch_in == 0 || params->codec.ch_out == 0)
642 return -EINVAL;
643
644 return 0;
645 }
646
647 static int
snd_compr_set_params(struct snd_compr_stream * stream,unsigned long arg)648 snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
649 {
650 struct snd_compr_params *params __free(kfree) = NULL;
651 int retval;
652
653 if (stream->runtime->state == SNDRV_PCM_STATE_OPEN || stream->next_track) {
654 /*
655 * we should allow parameter change only when stream has been
656 * opened not in other cases
657 */
658 params = memdup_user((void __user *)arg, sizeof(*params));
659 if (IS_ERR(params))
660 return PTR_ERR(params);
661
662 retval = snd_compress_check_input(stream, params);
663 if (retval)
664 return retval;
665
666 retval = snd_compr_allocate_buffer(stream, params);
667 if (retval)
668 return -ENOMEM;
669
670 retval = stream->ops->set_params(stream, params);
671 if (retval)
672 return retval;
673
674 if (stream->next_track)
675 return retval;
676
677 stream->metadata_set = false;
678 stream->next_track = false;
679
680 stream->runtime->state = SNDRV_PCM_STATE_SETUP;
681 } else {
682 return -EPERM;
683 }
684 return retval;
685 }
686
687 static int
snd_compr_get_params(struct snd_compr_stream * stream,unsigned long arg)688 snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg)
689 {
690 struct snd_codec *params __free(kfree) = NULL;
691 int retval;
692
693 if (!stream->ops->get_params)
694 return -EBADFD;
695
696 params = kzalloc(sizeof(*params), GFP_KERNEL);
697 if (!params)
698 return -ENOMEM;
699 retval = stream->ops->get_params(stream, params);
700 if (retval)
701 return retval;
702 if (copy_to_user((char __user *)arg, params, sizeof(*params)))
703 return -EFAULT;
704 return retval;
705 }
706
707 static int
snd_compr_get_metadata(struct snd_compr_stream * stream,unsigned long arg)708 snd_compr_get_metadata(struct snd_compr_stream *stream, unsigned long arg)
709 {
710 struct snd_compr_metadata metadata;
711 int retval;
712
713 if (!stream->ops->get_metadata)
714 return -ENXIO;
715
716 if (copy_from_user(&metadata, (void __user *)arg, sizeof(metadata)))
717 return -EFAULT;
718
719 retval = stream->ops->get_metadata(stream, &metadata);
720 if (retval != 0)
721 return retval;
722
723 if (copy_to_user((void __user *)arg, &metadata, sizeof(metadata)))
724 return -EFAULT;
725
726 return 0;
727 }
728
729 static int
snd_compr_set_metadata(struct snd_compr_stream * stream,unsigned long arg)730 snd_compr_set_metadata(struct snd_compr_stream *stream, unsigned long arg)
731 {
732 struct snd_compr_metadata metadata;
733 int retval;
734
735 if (!stream->ops->set_metadata)
736 return -ENXIO;
737 /*
738 * we should allow parameter change only when stream has been
739 * opened not in other cases
740 */
741 if (copy_from_user(&metadata, (void __user *)arg, sizeof(metadata)))
742 return -EFAULT;
743
744 retval = stream->ops->set_metadata(stream, &metadata);
745 stream->metadata_set = true;
746
747 return retval;
748 }
749
snd_compr_tstamp(struct snd_compr_stream * stream,unsigned long arg,bool is_32bit)750 static inline int snd_compr_tstamp(struct snd_compr_stream *stream,
751 unsigned long arg, bool is_32bit)
752 {
753 struct snd_compr_tstamp64 tstamp64 = { 0 };
754 struct snd_compr_tstamp tstamp32 = { 0 };
755 const void *copy_from = &tstamp64;
756 size_t copy_size = sizeof(tstamp64);
757 int ret;
758
759 ret = snd_compr_update_tstamp(stream, &tstamp64);
760 if (ret == 0) {
761 if (is_32bit) {
762 snd_compr_tstamp32_from_64(&tstamp32, &tstamp64);
763 copy_from = &tstamp32;
764 copy_size = sizeof(tstamp32);
765 }
766 ret = copy_to_user((void __user *)arg, copy_from, copy_size) ?
767 -EFAULT :
768 0;
769 }
770 return ret;
771 }
772
snd_compr_pause(struct snd_compr_stream * stream)773 static int snd_compr_pause(struct snd_compr_stream *stream)
774 {
775 int retval;
776
777 switch (stream->runtime->state) {
778 case SNDRV_PCM_STATE_RUNNING:
779 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
780 if (!retval)
781 stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
782 break;
783 case SNDRV_PCM_STATE_DRAINING:
784 if (!stream->device->use_pause_in_draining)
785 return -EPERM;
786 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
787 if (!retval)
788 stream->pause_in_draining = true;
789 break;
790 default:
791 return -EPERM;
792 }
793 return retval;
794 }
795
snd_compr_resume(struct snd_compr_stream * stream)796 static int snd_compr_resume(struct snd_compr_stream *stream)
797 {
798 int retval;
799
800 switch (stream->runtime->state) {
801 case SNDRV_PCM_STATE_PAUSED:
802 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
803 if (!retval)
804 stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
805 break;
806 case SNDRV_PCM_STATE_DRAINING:
807 if (!stream->pause_in_draining)
808 return -EPERM;
809 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
810 if (!retval)
811 stream->pause_in_draining = false;
812 break;
813 default:
814 return -EPERM;
815 }
816 return retval;
817 }
818
snd_compr_start(struct snd_compr_stream * stream)819 static int snd_compr_start(struct snd_compr_stream *stream)
820 {
821 int retval;
822
823 switch (stream->runtime->state) {
824 case SNDRV_PCM_STATE_SETUP:
825 if (stream->direction != SND_COMPRESS_CAPTURE)
826 return -EPERM;
827 break;
828 case SNDRV_PCM_STATE_PREPARED:
829 break;
830 default:
831 return -EPERM;
832 }
833
834 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_START);
835 if (!retval)
836 stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
837 return retval;
838 }
839
snd_compr_stop(struct snd_compr_stream * stream)840 static int snd_compr_stop(struct snd_compr_stream *stream)
841 {
842 int retval;
843
844 switch (stream->runtime->state) {
845 case SNDRV_PCM_STATE_OPEN:
846 case SNDRV_PCM_STATE_SETUP:
847 case SNDRV_PCM_STATE_PREPARED:
848 return -EPERM;
849 default:
850 break;
851 }
852
853 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
854 if (!retval) {
855 /* clear flags and stop any drain wait */
856 stream->partial_drain = false;
857 stream->metadata_set = false;
858 stream->pause_in_draining = false;
859 snd_compr_drain_notify(stream);
860 stream->runtime->total_bytes_available = 0;
861 stream->runtime->total_bytes_transferred = 0;
862 }
863 return retval;
864 }
865
error_delayed_work(struct work_struct * work)866 static void error_delayed_work(struct work_struct *work)
867 {
868 struct snd_compr_stream *stream;
869
870 stream = container_of(work, struct snd_compr_stream, error_work.work);
871
872 guard(mutex)(&stream->device->lock);
873
874 stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
875 wake_up(&stream->runtime->sleep);
876 }
877
878 /**
879 * snd_compr_stop_error: Report a fatal error on a stream
880 * @stream: pointer to stream
881 * @state: state to transition the stream to
882 *
883 * Stop the stream and set its state.
884 *
885 * Should be called with compressed device lock held.
886 *
887 * Return: zero if successful, or a negative error code
888 */
snd_compr_stop_error(struct snd_compr_stream * stream,snd_pcm_state_t state)889 int snd_compr_stop_error(struct snd_compr_stream *stream,
890 snd_pcm_state_t state)
891 {
892 if (stream->runtime->state == state)
893 return 0;
894
895 stream->runtime->state = state;
896
897 pr_debug("Changing state to: %d\n", state);
898
899 queue_delayed_work(system_power_efficient_wq, &stream->error_work, 0);
900
901 return 0;
902 }
903 EXPORT_SYMBOL_GPL(snd_compr_stop_error);
904
snd_compress_wait_for_drain(struct snd_compr_stream * stream)905 static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
906 {
907 int ret;
908
909 /*
910 * We are called with lock held. So drop the lock while we wait for
911 * drain complete notification from the driver
912 *
913 * It is expected that driver will notify the drain completion and then
914 * stream will be moved to SETUP state, even if draining resulted in an
915 * error. We can trigger next track after this.
916 */
917 stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
918 mutex_unlock(&stream->device->lock);
919
920 /* we wait for drain to complete here, drain can return when
921 * interruption occurred, wait returned error or success.
922 * For the first two cases we don't do anything different here and
923 * return after waking up
924 */
925
926 ret = wait_event_interruptible(stream->runtime->sleep,
927 (stream->runtime->state != SNDRV_PCM_STATE_DRAINING));
928 if (ret == -ERESTARTSYS)
929 pr_debug("wait aborted by a signal\n");
930 else if (ret)
931 pr_debug("wait for drain failed with %d\n", ret);
932
933
934 wake_up(&stream->runtime->sleep);
935 mutex_lock(&stream->device->lock);
936
937 return ret;
938 }
939
snd_compr_drain(struct snd_compr_stream * stream)940 static int snd_compr_drain(struct snd_compr_stream *stream)
941 {
942 int retval;
943
944 switch (stream->runtime->state) {
945 case SNDRV_PCM_STATE_OPEN:
946 case SNDRV_PCM_STATE_SETUP:
947 case SNDRV_PCM_STATE_PREPARED:
948 case SNDRV_PCM_STATE_PAUSED:
949 return -EPERM;
950 case SNDRV_PCM_STATE_XRUN:
951 return -EPIPE;
952 default:
953 break;
954 }
955
956 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
957 if (retval) {
958 pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
959 wake_up(&stream->runtime->sleep);
960 return retval;
961 }
962
963 return snd_compress_wait_for_drain(stream);
964 }
965
snd_compr_next_track(struct snd_compr_stream * stream)966 static int snd_compr_next_track(struct snd_compr_stream *stream)
967 {
968 int retval;
969
970 /* only a running stream can transition to next track */
971 if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
972 return -EPERM;
973
974 /* next track doesn't have any meaning for capture streams */
975 if (stream->direction == SND_COMPRESS_CAPTURE)
976 return -EPERM;
977
978 /* you can signal next track if this is intended to be a gapless stream
979 * and current track metadata is set
980 */
981 if (stream->metadata_set == false)
982 return -EPERM;
983
984 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_NEXT_TRACK);
985 if (retval != 0)
986 return retval;
987 stream->metadata_set = false;
988 stream->next_track = true;
989 return 0;
990 }
991
snd_compr_partial_drain(struct snd_compr_stream * stream)992 static int snd_compr_partial_drain(struct snd_compr_stream *stream)
993 {
994 int retval;
995
996 switch (stream->runtime->state) {
997 case SNDRV_PCM_STATE_OPEN:
998 case SNDRV_PCM_STATE_SETUP:
999 case SNDRV_PCM_STATE_PREPARED:
1000 case SNDRV_PCM_STATE_PAUSED:
1001 return -EPERM;
1002 case SNDRV_PCM_STATE_XRUN:
1003 return -EPIPE;
1004 default:
1005 break;
1006 }
1007
1008 /* partial drain doesn't have any meaning for capture streams */
1009 if (stream->direction == SND_COMPRESS_CAPTURE)
1010 return -EPERM;
1011
1012 /* stream can be drained only when next track has been signalled */
1013 if (stream->next_track == false)
1014 return -EPERM;
1015
1016 stream->partial_drain = true;
1017 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN);
1018 if (retval) {
1019 pr_debug("Partial drain returned failure\n");
1020 wake_up(&stream->runtime->sleep);
1021 return retval;
1022 }
1023
1024 stream->next_track = false;
1025 return snd_compress_wait_for_drain(stream);
1026 }
1027
1028 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)
1029
1030 static struct snd_compr_task_runtime *
snd_compr_find_task(struct snd_compr_stream * stream,__u64 seqno)1031 snd_compr_find_task(struct snd_compr_stream *stream, __u64 seqno)
1032 {
1033 struct snd_compr_task_runtime *task;
1034
1035 list_for_each_entry(task, &stream->runtime->tasks, list) {
1036 if (task->seqno == seqno)
1037 return task;
1038 }
1039 return NULL;
1040 }
1041
snd_compr_task_free(struct snd_compr_task_runtime * task)1042 static void snd_compr_task_free(struct snd_compr_task_runtime *task)
1043 {
1044 if (task->output)
1045 dma_buf_put(task->output);
1046 if (task->input)
1047 dma_buf_put(task->input);
1048 kfree(task);
1049 }
1050
snd_compr_seqno_next(struct snd_compr_stream * stream)1051 static u64 snd_compr_seqno_next(struct snd_compr_stream *stream)
1052 {
1053 u64 seqno = ++stream->runtime->task_seqno;
1054 if (seqno == 0)
1055 seqno = ++stream->runtime->task_seqno;
1056 return seqno;
1057 }
1058
snd_compr_task_new(struct snd_compr_stream * stream,struct snd_compr_task * utask)1059 static int snd_compr_task_new(struct snd_compr_stream *stream, struct snd_compr_task *utask)
1060 {
1061 struct snd_compr_task_runtime *task;
1062 int retval, fd_i, fd_o;
1063
1064 if (stream->runtime->total_tasks >= stream->runtime->fragments)
1065 return -EBUSY;
1066 if (utask->origin_seqno != 0 || utask->input_size != 0)
1067 return -EINVAL;
1068 task = kzalloc(sizeof(*task), GFP_KERNEL);
1069 if (task == NULL)
1070 return -ENOMEM;
1071 task->seqno = utask->seqno = snd_compr_seqno_next(stream);
1072 task->input_size = utask->input_size;
1073 retval = stream->ops->task_create(stream, task);
1074 if (retval < 0)
1075 goto cleanup;
1076 /* similar functionality as in dma_buf_fd(), but ensure that both
1077 file descriptors are allocated before fd_install() */
1078 if (!task->input || !task->input->file || !task->output || !task->output->file) {
1079 retval = -EINVAL;
1080 goto cleanup;
1081 }
1082 fd_i = get_unused_fd_flags(O_WRONLY|O_CLOEXEC);
1083 if (fd_i < 0)
1084 goto cleanup;
1085 fd_o = get_unused_fd_flags(O_RDONLY|O_CLOEXEC);
1086 if (fd_o < 0) {
1087 put_unused_fd(fd_i);
1088 goto cleanup;
1089 }
1090 /* keep dmabuf reference until freed with task free ioctl */
1091 get_dma_buf(task->input);
1092 get_dma_buf(task->output);
1093 fd_install(fd_i, task->input->file);
1094 fd_install(fd_o, task->output->file);
1095 utask->input_fd = fd_i;
1096 utask->output_fd = fd_o;
1097 list_add_tail(&task->list, &stream->runtime->tasks);
1098 stream->runtime->total_tasks++;
1099 return 0;
1100 cleanup:
1101 snd_compr_task_free(task);
1102 return retval;
1103 }
1104
snd_compr_task_create(struct snd_compr_stream * stream,unsigned long arg)1105 static int snd_compr_task_create(struct snd_compr_stream *stream, unsigned long arg)
1106 {
1107 struct snd_compr_task *task __free(kfree) = NULL;
1108 int retval;
1109
1110 if (stream->runtime->state != SNDRV_PCM_STATE_SETUP)
1111 return -EPERM;
1112 task = memdup_user((void __user *)arg, sizeof(*task));
1113 if (IS_ERR(task))
1114 return PTR_ERR(task);
1115 retval = snd_compr_task_new(stream, task);
1116 if (retval >= 0)
1117 if (copy_to_user((void __user *)arg, task, sizeof(*task)))
1118 retval = -EFAULT;
1119 return retval;
1120 }
1121
snd_compr_task_start_prepare(struct snd_compr_task_runtime * task,struct snd_compr_task * utask)1122 static int snd_compr_task_start_prepare(struct snd_compr_task_runtime *task,
1123 struct snd_compr_task *utask)
1124 {
1125 if (task == NULL)
1126 return -EINVAL;
1127 if (task->state >= SND_COMPRESS_TASK_STATE_FINISHED)
1128 return -EBUSY;
1129 if (utask->input_size > task->input->size)
1130 return -EINVAL;
1131 task->flags = utask->flags;
1132 task->input_size = utask->input_size;
1133 task->state = SND_COMPRESS_TASK_STATE_IDLE;
1134 return 0;
1135 }
1136
snd_compr_task_start(struct snd_compr_stream * stream,struct snd_compr_task * utask)1137 static int snd_compr_task_start(struct snd_compr_stream *stream, struct snd_compr_task *utask)
1138 {
1139 struct snd_compr_task_runtime *task;
1140 int retval;
1141
1142 if (utask->origin_seqno > 0) {
1143 task = snd_compr_find_task(stream, utask->origin_seqno);
1144 retval = snd_compr_task_start_prepare(task, utask);
1145 if (retval < 0)
1146 return retval;
1147 task->seqno = utask->seqno = snd_compr_seqno_next(stream);
1148 utask->origin_seqno = 0;
1149 list_move_tail(&task->list, &stream->runtime->tasks);
1150 } else {
1151 task = snd_compr_find_task(stream, utask->seqno);
1152 if (task && task->state != SND_COMPRESS_TASK_STATE_IDLE)
1153 return -EBUSY;
1154 retval = snd_compr_task_start_prepare(task, utask);
1155 if (retval < 0)
1156 return retval;
1157 }
1158 retval = stream->ops->task_start(stream, task);
1159 if (retval >= 0) {
1160 task->state = SND_COMPRESS_TASK_STATE_ACTIVE;
1161 stream->runtime->active_tasks++;
1162 }
1163 return retval;
1164 }
1165
snd_compr_task_start_ioctl(struct snd_compr_stream * stream,unsigned long arg)1166 static int snd_compr_task_start_ioctl(struct snd_compr_stream *stream, unsigned long arg)
1167 {
1168 struct snd_compr_task *task __free(kfree) = NULL;
1169 int retval;
1170
1171 if (stream->runtime->state != SNDRV_PCM_STATE_SETUP)
1172 return -EPERM;
1173 task = memdup_user((void __user *)arg, sizeof(*task));
1174 if (IS_ERR(task))
1175 return PTR_ERR(task);
1176 retval = snd_compr_task_start(stream, task);
1177 if (retval >= 0)
1178 if (copy_to_user((void __user *)arg, task, sizeof(*task)))
1179 retval = -EFAULT;
1180 return retval;
1181 }
1182
snd_compr_task_stop_one(struct snd_compr_stream * stream,struct snd_compr_task_runtime * task)1183 static void snd_compr_task_stop_one(struct snd_compr_stream *stream,
1184 struct snd_compr_task_runtime *task)
1185 {
1186 if (task->state != SND_COMPRESS_TASK_STATE_ACTIVE)
1187 return;
1188 stream->ops->task_stop(stream, task);
1189 if (!snd_BUG_ON(stream->runtime->active_tasks == 0))
1190 stream->runtime->active_tasks--;
1191 list_move_tail(&task->list, &stream->runtime->tasks);
1192 task->state = SND_COMPRESS_TASK_STATE_IDLE;
1193 }
1194
snd_compr_task_free_one(struct snd_compr_stream * stream,struct snd_compr_task_runtime * task)1195 static void snd_compr_task_free_one(struct snd_compr_stream *stream,
1196 struct snd_compr_task_runtime *task)
1197 {
1198 snd_compr_task_stop_one(stream, task);
1199 stream->ops->task_free(stream, task);
1200 list_del(&task->list);
1201 snd_compr_task_free(task);
1202 stream->runtime->total_tasks--;
1203 }
1204
snd_compr_task_free_all(struct snd_compr_stream * stream)1205 static void snd_compr_task_free_all(struct snd_compr_stream *stream)
1206 {
1207 struct snd_compr_task_runtime *task, *temp;
1208
1209 list_for_each_entry_safe_reverse(task, temp, &stream->runtime->tasks, list)
1210 snd_compr_task_free_one(stream, task);
1211 }
1212
1213 typedef void (*snd_compr_seq_func_t)(struct snd_compr_stream *stream,
1214 struct snd_compr_task_runtime *task);
1215
snd_compr_task_seq(struct snd_compr_stream * stream,unsigned long arg,snd_compr_seq_func_t fcn)1216 static int snd_compr_task_seq(struct snd_compr_stream *stream, unsigned long arg,
1217 snd_compr_seq_func_t fcn)
1218 {
1219 struct snd_compr_task_runtime *task, *temp;
1220 __u64 seqno;
1221 int retval;
1222
1223 if (stream->runtime->state != SNDRV_PCM_STATE_SETUP)
1224 return -EPERM;
1225 retval = copy_from_user(&seqno, (__u64 __user *)arg, sizeof(seqno));
1226 if (retval)
1227 return -EFAULT;
1228 retval = 0;
1229 if (seqno == 0) {
1230 list_for_each_entry_safe_reverse(task, temp, &stream->runtime->tasks, list)
1231 fcn(stream, task);
1232 } else {
1233 task = snd_compr_find_task(stream, seqno);
1234 if (task == NULL) {
1235 retval = -EINVAL;
1236 } else {
1237 fcn(stream, task);
1238 }
1239 }
1240 return retval;
1241 }
1242
snd_compr_task_status(struct snd_compr_stream * stream,struct snd_compr_task_status * status)1243 static int snd_compr_task_status(struct snd_compr_stream *stream,
1244 struct snd_compr_task_status *status)
1245 {
1246 struct snd_compr_task_runtime *task;
1247
1248 task = snd_compr_find_task(stream, status->seqno);
1249 if (task == NULL)
1250 return -EINVAL;
1251 status->input_size = task->input_size;
1252 status->output_size = task->output_size;
1253 status->state = task->state;
1254 return 0;
1255 }
1256
snd_compr_task_status_ioctl(struct snd_compr_stream * stream,unsigned long arg)1257 static int snd_compr_task_status_ioctl(struct snd_compr_stream *stream, unsigned long arg)
1258 {
1259 struct snd_compr_task_status *status __free(kfree) = NULL;
1260 int retval;
1261
1262 if (stream->runtime->state != SNDRV_PCM_STATE_SETUP)
1263 return -EPERM;
1264 status = memdup_user((void __user *)arg, sizeof(*status));
1265 if (IS_ERR(status))
1266 return PTR_ERR(status);
1267 retval = snd_compr_task_status(stream, status);
1268 if (retval >= 0)
1269 if (copy_to_user((void __user *)arg, status, sizeof(*status)))
1270 retval = -EFAULT;
1271 return retval;
1272 }
1273
1274 /**
1275 * snd_compr_task_finished: Notify that the task was finished
1276 * @stream: pointer to stream
1277 * @task: runtime task structure
1278 *
1279 * Set the finished task state and notify waiters.
1280 */
snd_compr_task_finished(struct snd_compr_stream * stream,struct snd_compr_task_runtime * task)1281 void snd_compr_task_finished(struct snd_compr_stream *stream,
1282 struct snd_compr_task_runtime *task)
1283 {
1284 guard(mutex)(&stream->device->lock);
1285 if (!snd_BUG_ON(stream->runtime->active_tasks == 0))
1286 stream->runtime->active_tasks--;
1287 task->state = SND_COMPRESS_TASK_STATE_FINISHED;
1288 wake_up(&stream->runtime->sleep);
1289 }
1290 EXPORT_SYMBOL_GPL(snd_compr_task_finished);
1291
1292 MODULE_IMPORT_NS("DMA_BUF");
1293 #endif /* CONFIG_SND_COMPRESS_ACCEL */
1294
snd_compr_ioctl(struct file * f,unsigned int cmd,unsigned long arg)1295 static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
1296 {
1297 struct snd_compr_file *data = f->private_data;
1298 struct snd_compr_stream *stream;
1299
1300 if (snd_BUG_ON(!data))
1301 return -EFAULT;
1302
1303 stream = &data->stream;
1304
1305 guard(mutex)(&stream->device->lock);
1306 switch (cmd) {
1307 case SNDRV_COMPRESS_IOCTL_VERSION:
1308 return put_user(SNDRV_COMPRESS_VERSION,
1309 (int __user *)arg) ? -EFAULT : 0;
1310 case SNDRV_COMPRESS_GET_CAPS:
1311 return snd_compr_get_caps(stream, arg);
1312 #ifndef COMPR_CODEC_CAPS_OVERFLOW
1313 case SNDRV_COMPRESS_GET_CODEC_CAPS:
1314 return snd_compr_get_codec_caps(stream, arg);
1315 #endif
1316 case SNDRV_COMPRESS_SET_PARAMS:
1317 return snd_compr_set_params(stream, arg);
1318 case SNDRV_COMPRESS_GET_PARAMS:
1319 return snd_compr_get_params(stream, arg);
1320 case SNDRV_COMPRESS_SET_METADATA:
1321 return snd_compr_set_metadata(stream, arg);
1322 case SNDRV_COMPRESS_GET_METADATA:
1323 return snd_compr_get_metadata(stream, arg);
1324 }
1325
1326 if (stream->direction == SND_COMPRESS_ACCEL) {
1327 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)
1328 switch (cmd) {
1329 case SNDRV_COMPRESS_TASK_CREATE:
1330 return snd_compr_task_create(stream, arg);
1331 case SNDRV_COMPRESS_TASK_FREE:
1332 return snd_compr_task_seq(stream, arg, snd_compr_task_free_one);
1333 case SNDRV_COMPRESS_TASK_START:
1334 return snd_compr_task_start_ioctl(stream, arg);
1335 case SNDRV_COMPRESS_TASK_STOP:
1336 return snd_compr_task_seq(stream, arg, snd_compr_task_stop_one);
1337 case SNDRV_COMPRESS_TASK_STATUS:
1338 return snd_compr_task_status_ioctl(stream, arg);
1339 }
1340 #endif
1341 return -ENOTTY;
1342 }
1343
1344 switch (cmd) {
1345 case SNDRV_COMPRESS_TSTAMP:
1346 return snd_compr_tstamp(stream, arg, true);
1347 case SNDRV_COMPRESS_TSTAMP64:
1348 return snd_compr_tstamp(stream, arg, false);
1349 case SNDRV_COMPRESS_AVAIL:
1350 return snd_compr_ioctl_avail(stream, arg, true);
1351 case SNDRV_COMPRESS_AVAIL64:
1352 return snd_compr_ioctl_avail(stream, arg, false);
1353 case SNDRV_COMPRESS_PAUSE:
1354 return snd_compr_pause(stream);
1355 case SNDRV_COMPRESS_RESUME:
1356 return snd_compr_resume(stream);
1357 case SNDRV_COMPRESS_START:
1358 return snd_compr_start(stream);
1359 case SNDRV_COMPRESS_STOP:
1360 return snd_compr_stop(stream);
1361 case SNDRV_COMPRESS_DRAIN:
1362 return snd_compr_drain(stream);
1363 case SNDRV_COMPRESS_PARTIAL_DRAIN:
1364 return snd_compr_partial_drain(stream);
1365 case SNDRV_COMPRESS_NEXT_TRACK:
1366 return snd_compr_next_track(stream);
1367 }
1368
1369 return -ENOTTY;
1370 }
1371
1372 /* support of 32bit userspace on 64bit platforms */
1373 #ifdef CONFIG_COMPAT
snd_compr_ioctl_compat(struct file * file,unsigned int cmd,unsigned long arg)1374 static long snd_compr_ioctl_compat(struct file *file, unsigned int cmd,
1375 unsigned long arg)
1376 {
1377 return snd_compr_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
1378 }
1379 #endif
1380
1381 static const struct file_operations snd_compr_file_ops = {
1382 .owner = THIS_MODULE,
1383 .open = snd_compr_open,
1384 .release = snd_compr_free,
1385 .write = snd_compr_write,
1386 .read = snd_compr_read,
1387 .unlocked_ioctl = snd_compr_ioctl,
1388 #ifdef CONFIG_COMPAT
1389 .compat_ioctl = snd_compr_ioctl_compat,
1390 #endif
1391 .mmap = snd_compr_mmap,
1392 .poll = snd_compr_poll,
1393 };
1394
snd_compress_dev_register(struct snd_device * device)1395 static int snd_compress_dev_register(struct snd_device *device)
1396 {
1397 int ret;
1398 struct snd_compr *compr;
1399
1400 if (snd_BUG_ON(!device || !device->device_data))
1401 return -EBADFD;
1402 compr = device->device_data;
1403
1404 pr_debug("reg device %s, direction %d\n", compr->name,
1405 compr->direction);
1406 /* register compressed device */
1407 ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS,
1408 compr->card, compr->device,
1409 &snd_compr_file_ops, compr, compr->dev);
1410 if (ret < 0) {
1411 pr_err("snd_register_device failed %d\n", ret);
1412 return ret;
1413 }
1414 return ret;
1415
1416 }
1417
snd_compress_dev_disconnect(struct snd_device * device)1418 static int snd_compress_dev_disconnect(struct snd_device *device)
1419 {
1420 struct snd_compr *compr;
1421
1422 compr = device->device_data;
1423 snd_unregister_device(compr->dev);
1424 return 0;
1425 }
1426
1427 #ifdef CONFIG_SND_VERBOSE_PROCFS
snd_compress_proc_info_read(struct snd_info_entry * entry,struct snd_info_buffer * buffer)1428 static void snd_compress_proc_info_read(struct snd_info_entry *entry,
1429 struct snd_info_buffer *buffer)
1430 {
1431 struct snd_compr *compr = (struct snd_compr *)entry->private_data;
1432
1433 snd_iprintf(buffer, "card: %d\n", compr->card->number);
1434 snd_iprintf(buffer, "device: %d\n", compr->device);
1435 snd_iprintf(buffer, "stream: %s\n",
1436 compr->direction == SND_COMPRESS_PLAYBACK
1437 ? "PLAYBACK" : "CAPTURE");
1438 snd_iprintf(buffer, "id: %s\n", compr->id);
1439 }
1440
snd_compress_proc_init(struct snd_compr * compr)1441 static int snd_compress_proc_init(struct snd_compr *compr)
1442 {
1443 struct snd_info_entry *entry;
1444 char name[16];
1445
1446 sprintf(name, "compr%i", compr->device);
1447 entry = snd_info_create_card_entry(compr->card, name,
1448 compr->card->proc_root);
1449 if (!entry)
1450 return -ENOMEM;
1451 entry->mode = S_IFDIR | 0555;
1452 compr->proc_root = entry;
1453
1454 entry = snd_info_create_card_entry(compr->card, "info",
1455 compr->proc_root);
1456 if (entry)
1457 snd_info_set_text_ops(entry, compr,
1458 snd_compress_proc_info_read);
1459 compr->proc_info_entry = entry;
1460
1461 return 0;
1462 }
1463
snd_compress_proc_done(struct snd_compr * compr)1464 static void snd_compress_proc_done(struct snd_compr *compr)
1465 {
1466 snd_info_free_entry(compr->proc_info_entry);
1467 compr->proc_info_entry = NULL;
1468 snd_info_free_entry(compr->proc_root);
1469 compr->proc_root = NULL;
1470 }
1471
snd_compress_set_id(struct snd_compr * compr,const char * id)1472 static inline void snd_compress_set_id(struct snd_compr *compr, const char *id)
1473 {
1474 strscpy(compr->id, id, sizeof(compr->id));
1475 }
1476 #else
snd_compress_proc_init(struct snd_compr * compr)1477 static inline int snd_compress_proc_init(struct snd_compr *compr)
1478 {
1479 return 0;
1480 }
1481
snd_compress_proc_done(struct snd_compr * compr)1482 static inline void snd_compress_proc_done(struct snd_compr *compr)
1483 {
1484 }
1485
snd_compress_set_id(struct snd_compr * compr,const char * id)1486 static inline void snd_compress_set_id(struct snd_compr *compr, const char *id)
1487 {
1488 }
1489 #endif
1490
snd_compress_dev_free(struct snd_device * device)1491 static int snd_compress_dev_free(struct snd_device *device)
1492 {
1493 struct snd_compr *compr;
1494
1495 compr = device->device_data;
1496 snd_compress_proc_done(compr);
1497 put_device(compr->dev);
1498 return 0;
1499 }
1500
1501 /**
1502 * snd_compress_new: create new compress device
1503 * @card: sound card pointer
1504 * @device: device number
1505 * @dirn: device direction, should be of type enum snd_compr_direction
1506 * @id: ID string
1507 * @compr: compress device pointer
1508 *
1509 * Return: zero if successful, or a negative error code
1510 */
snd_compress_new(struct snd_card * card,int device,int dirn,const char * id,struct snd_compr * compr)1511 int snd_compress_new(struct snd_card *card, int device,
1512 int dirn, const char *id, struct snd_compr *compr)
1513 {
1514 static const struct snd_device_ops ops = {
1515 .dev_free = snd_compress_dev_free,
1516 .dev_register = snd_compress_dev_register,
1517 .dev_disconnect = snd_compress_dev_disconnect,
1518 };
1519 int ret;
1520
1521 #if !IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)
1522 if (snd_BUG_ON(dirn == SND_COMPRESS_ACCEL))
1523 return -EINVAL;
1524 #endif
1525
1526 compr->card = card;
1527 compr->device = device;
1528 compr->direction = dirn;
1529 mutex_init(&compr->lock);
1530
1531 snd_compress_set_id(compr, id);
1532
1533 ret = snd_device_alloc(&compr->dev, card);
1534 if (ret)
1535 return ret;
1536 dev_set_name(compr->dev, "comprC%iD%i", card->number, device);
1537
1538 ret = snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);
1539 if (ret == 0)
1540 snd_compress_proc_init(compr);
1541 else
1542 put_device(compr->dev);
1543
1544 return ret;
1545 }
1546 EXPORT_SYMBOL_GPL(snd_compress_new);
1547
1548 MODULE_DESCRIPTION("ALSA Compressed offload framework");
1549 MODULE_AUTHOR("Vinod Koul <vinod.koul@linux.intel.com>");
1550 MODULE_LICENSE("GPL v2");
1551