hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/sound/core/pcm_native.c
....@@ -1,24 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Digital Audio (PCM) abstract layer
34 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4
- *
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
- *
205 */
216
7
+#include <linux/compat.h>
228 #include <linux/mm.h>
239 #include <linux/module.h>
2410 #include <linux/file.h>
....@@ -28,6 +14,7 @@
2814 #include <linux/pm_qos.h>
2915 #include <linux/io.h>
3016 #include <linux/dma-mapping.h>
17
+#include <linux/vmalloc.h>
3118 #include <sound/core.h>
3219 #include <sound/control.h>
3320 #include <sound/info.h>
....@@ -85,71 +72,30 @@
8572 *
8673 */
8774
88
-static DEFINE_RWLOCK(snd_pcm_link_rwlock);
8975 static DECLARE_RWSEM(snd_pcm_link_rwsem);
9076
91
-/* Writer in rwsem may block readers even during its waiting in queue,
92
- * and this may lead to a deadlock when the code path takes read sem
93
- * twice (e.g. one in snd_pcm_action_nonatomic() and another in
94
- * snd_pcm_stream_lock()). As a (suboptimal) workaround, let writer to
95
- * sleep until all the readers are completed without blocking by writer.
96
- */
97
-static inline void down_write_nonfifo(struct rw_semaphore *lock)
77
+void snd_pcm_group_init(struct snd_pcm_group *group)
9878 {
99
- while (!down_write_trylock(lock))
100
- msleep(1);
79
+ spin_lock_init(&group->lock);
80
+ mutex_init(&group->mutex);
81
+ INIT_LIST_HEAD(&group->substreams);
82
+ refcount_set(&group->refs, 1);
10183 }
10284
103
-#define PCM_LOCK_DEFAULT 0
104
-#define PCM_LOCK_IRQ 1
105
-#define PCM_LOCK_IRQSAVE 2
106
-
107
-static unsigned long __snd_pcm_stream_lock_mode(struct snd_pcm_substream *substream,
108
- unsigned int mode)
109
-{
110
- unsigned long flags = 0;
111
- if (substream->pcm->nonatomic) {
112
- down_read_nested(&snd_pcm_link_rwsem, SINGLE_DEPTH_NESTING);
113
- mutex_lock(&substream->self_group.mutex);
114
- } else {
115
- switch (mode) {
116
- case PCM_LOCK_DEFAULT:
117
- read_lock(&snd_pcm_link_rwlock);
118
- break;
119
- case PCM_LOCK_IRQ:
120
- read_lock_irq(&snd_pcm_link_rwlock);
121
- break;
122
- case PCM_LOCK_IRQSAVE:
123
- read_lock_irqsave(&snd_pcm_link_rwlock, flags);
124
- break;
125
- }
126
- spin_lock(&substream->self_group.lock);
127
- }
128
- return flags;
85
+/* define group lock helpers */
86
+#define DEFINE_PCM_GROUP_LOCK(action, mutex_action) \
87
+static void snd_pcm_group_ ## action(struct snd_pcm_group *group, bool nonatomic) \
88
+{ \
89
+ if (nonatomic) \
90
+ mutex_ ## mutex_action(&group->mutex); \
91
+ else \
92
+ spin_ ## action(&group->lock); \
12993 }
13094
131
-static void __snd_pcm_stream_unlock_mode(struct snd_pcm_substream *substream,
132
- unsigned int mode, unsigned long flags)
133
-{
134
- if (substream->pcm->nonatomic) {
135
- mutex_unlock(&substream->self_group.mutex);
136
- up_read(&snd_pcm_link_rwsem);
137
- } else {
138
- spin_unlock(&substream->self_group.lock);
139
-
140
- switch (mode) {
141
- case PCM_LOCK_DEFAULT:
142
- read_unlock(&snd_pcm_link_rwlock);
143
- break;
144
- case PCM_LOCK_IRQ:
145
- read_unlock_irq(&snd_pcm_link_rwlock);
146
- break;
147
- case PCM_LOCK_IRQSAVE:
148
- read_unlock_irqrestore(&snd_pcm_link_rwlock, flags);
149
- break;
150
- }
151
- }
152
-}
95
+DEFINE_PCM_GROUP_LOCK(lock, lock);
96
+DEFINE_PCM_GROUP_LOCK(unlock, unlock);
97
+DEFINE_PCM_GROUP_LOCK(lock_irq, lock);
98
+DEFINE_PCM_GROUP_LOCK(unlock_irq, unlock);
15399
154100 /**
155101 * snd_pcm_stream_lock - Lock the PCM stream
....@@ -161,19 +107,19 @@
161107 */
162108 void snd_pcm_stream_lock(struct snd_pcm_substream *substream)
163109 {
164
- __snd_pcm_stream_lock_mode(substream, PCM_LOCK_DEFAULT);
110
+ snd_pcm_group_lock(&substream->self_group, substream->pcm->nonatomic);
165111 }
166112 EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
167113
168114 /**
169
- * snd_pcm_stream_lock - Unlock the PCM stream
115
+ * snd_pcm_stream_unlock - Unlock the PCM stream
170116 * @substream: PCM substream
171117 *
172118 * This unlocks the PCM stream that has been locked via snd_pcm_stream_lock().
173119 */
174120 void snd_pcm_stream_unlock(struct snd_pcm_substream *substream)
175121 {
176
- __snd_pcm_stream_unlock_mode(substream, PCM_LOCK_DEFAULT, 0);
122
+ snd_pcm_group_unlock(&substream->self_group, substream->pcm->nonatomic);
177123 }
178124 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
179125
....@@ -187,9 +133,20 @@
187133 */
188134 void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
189135 {
190
- __snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQ);
136
+ snd_pcm_group_lock_irq(&substream->self_group,
137
+ substream->pcm->nonatomic);
191138 }
192139 EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
140
+
141
+static void snd_pcm_stream_lock_nested(struct snd_pcm_substream *substream)
142
+{
143
+ struct snd_pcm_group *group = &substream->self_group;
144
+
145
+ if (substream->pcm->nonatomic)
146
+ mutex_lock_nested(&group->mutex, SINGLE_DEPTH_NESTING);
147
+ else
148
+ spin_lock_nested(&group->lock, SINGLE_DEPTH_NESTING);
149
+}
193150
194151 /**
195152 * snd_pcm_stream_unlock_irq - Unlock the PCM stream
....@@ -199,13 +156,19 @@
199156 */
200157 void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream)
201158 {
202
- __snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQ, 0);
159
+ snd_pcm_group_unlock_irq(&substream->self_group,
160
+ substream->pcm->nonatomic);
203161 }
204162 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq);
205163
206164 unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream)
207165 {
208
- return __snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQSAVE);
166
+ unsigned long flags = 0;
167
+ if (substream->pcm->nonatomic)
168
+ mutex_lock(&substream->self_group.mutex);
169
+ else
170
+ spin_lock_irqsave(&substream->self_group.lock, flags);
171
+ return flags;
209172 }
210173 EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
211174
....@@ -219,9 +182,22 @@
219182 void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
220183 unsigned long flags)
221184 {
222
- __snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQSAVE, flags);
185
+ if (substream->pcm->nonatomic)
186
+ mutex_unlock(&substream->self_group.mutex);
187
+ else
188
+ spin_unlock_irqrestore(&substream->self_group.lock, flags);
223189 }
224190 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore);
191
+
192
+/* Run PCM ioctl ops */
193
+static int snd_pcm_ops_ioctl(struct snd_pcm_substream *substream,
194
+ unsigned cmd, void *arg)
195
+{
196
+ if (substream->ops->ioctl)
197
+ return substream->ops->ioctl(substream, cmd, arg);
198
+ else
199
+ return snd_pcm_lib_ioctl(substream, cmd, arg);
200
+}
225201
226202 int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
227203 {
....@@ -262,17 +238,29 @@
262238 return err;
263239 }
264240
241
+/* macro for simplified cast */
242
+#define PARAM_MASK_BIT(b) (1U << (__force int)(b))
243
+
265244 static bool hw_support_mmap(struct snd_pcm_substream *substream)
266245 {
267246 if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP))
268247 return false;
269
- /* architecture supports dma_mmap_coherent()? */
270
-#if defined(CONFIG_ARCH_NO_COHERENT_DMA_MMAP) || !defined(CONFIG_HAS_DMA)
271
- if (!substream->ops->mmap &&
272
- substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
273
- return false;
274
-#endif
275
- return true;
248
+
249
+ if (substream->ops->mmap || substream->ops->page)
250
+ return true;
251
+
252
+ switch (substream->dma_buffer.dev.type) {
253
+ case SNDRV_DMA_TYPE_UNKNOWN:
254
+ /* we can't know the device, so just assume that the driver does
255
+ * everything right
256
+ */
257
+ return true;
258
+ case SNDRV_DMA_TYPE_CONTINUOUS:
259
+ case SNDRV_DMA_TYPE_VMALLOC:
260
+ return true;
261
+ default:
262
+ return dma_can_mmap(substream->dma_buffer.dev.dev);
263
+ }
276264 }
277265
278266 static int constrain_mask_params(struct snd_pcm_substream *substream,
....@@ -291,7 +279,7 @@
291279 return -EINVAL;
292280
293281 /* This parameter is not requested to change by a caller. */
294
- if (!(params->rmask & (1 << k)))
282
+ if (!(params->rmask & PARAM_MASK_BIT(k)))
295283 continue;
296284
297285 if (trace_hw_mask_param_enabled())
....@@ -305,7 +293,7 @@
305293
306294 /* Set corresponding flag so that the caller gets it. */
307295 trace_hw_mask_param(substream, k, 0, &old_mask, m);
308
- params->cmask |= 1 << k;
296
+ params->cmask |= PARAM_MASK_BIT(k);
309297 }
310298
311299 return 0;
....@@ -327,7 +315,7 @@
327315 return -EINVAL;
328316
329317 /* This parameter is not requested to change by a caller. */
330
- if (!(params->rmask & (1 << k)))
318
+ if (!(params->rmask & PARAM_MASK_BIT(k)))
331319 continue;
332320
333321 if (trace_hw_interval_param_enabled())
....@@ -341,7 +329,7 @@
341329
342330 /* Set corresponding flag so that the caller gets it. */
343331 trace_hw_interval_param(substream, k, 0, &old_interval, i);
344
- params->cmask |= 1 << k;
332
+ params->cmask |= PARAM_MASK_BIT(k);
345333 }
346334
347335 return 0;
....@@ -383,7 +371,7 @@
383371 * have 0 so that the parameters are never changed anymore.
384372 */
385373 for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++)
386
- vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0;
374
+ vstamps[k] = (params->rmask & PARAM_MASK_BIT(k)) ? 1 : 0;
387375
388376 /* Due to the above design, actual sequence number starts at 2. */
389377 stamp = 2;
....@@ -451,7 +439,7 @@
451439 hw_param_interval(params, r->var));
452440 }
453441
454
- params->cmask |= (1 << r->var);
442
+ params->cmask |= PARAM_MASK_BIT(r->var);
455443 vstamps[r->var] = stamp;
456444 again = true;
457445 }
....@@ -493,8 +481,9 @@
493481 m = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
494482 i = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
495483 if (snd_mask_single(m) && snd_interval_single(i)) {
496
- err = substream->ops->ioctl(substream,
497
- SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
484
+ err = snd_pcm_ops_ioctl(substream,
485
+ SNDRV_PCM_IOCTL1_FIFO_SIZE,
486
+ params);
498487 if (err < 0)
499488 return err;
500489 }
....@@ -519,9 +508,9 @@
519508
520509 params->info = 0;
521510 params->fifo_size = 0;
522
- if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS))
511
+ if (params->rmask & PARAM_MASK_BIT(SNDRV_PCM_HW_PARAM_SAMPLE_BITS))
523512 params->msbits = 0;
524
- if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) {
513
+ if (params->rmask & PARAM_MASK_BIT(SNDRV_PCM_HW_PARAM_RATE)) {
525514 params->rate_num = 0;
526515 params->rate_den = 0;
527516 }
....@@ -584,7 +573,8 @@
584573 return usecs;
585574 }
586575
587
-static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state)
576
+static void snd_pcm_set_state(struct snd_pcm_substream *substream,
577
+ snd_pcm_state_t state)
588578 {
589579 snd_pcm_stream_lock_irq(substream);
590580 if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED)
....@@ -602,8 +592,19 @@
602592 #endif
603593 }
604594
595
+void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq)
596
+{
597
+ if (substream->runtime && substream->runtime->stop_operating) {
598
+ substream->runtime->stop_operating = false;
599
+ if (substream->ops && substream->ops->sync_stop)
600
+ substream->ops->sync_stop(substream);
601
+ else if (sync_irq && substream->pcm->card->sync_irq > 0)
602
+ synchronize_irq(substream->pcm->card->sync_irq);
603
+ }
604
+}
605
+
605606 /**
606
- * snd_pcm_hw_param_choose - choose a configuration defined by @params
607
+ * snd_pcm_hw_params_choose - choose a configuration defined by @params
607608 * @pcm: PCM instance
608609 * @params: the hw_params instance
609610 *
....@@ -666,6 +667,30 @@
666667 return 0;
667668 }
668669
670
+/* acquire buffer_mutex; if it's in r/w operation, return -EBUSY, otherwise
671
+ * block the further r/w operations
672
+ */
673
+static int snd_pcm_buffer_access_lock(struct snd_pcm_runtime *runtime)
674
+{
675
+ if (!atomic_dec_unless_positive(&runtime->buffer_accessing))
676
+ return -EBUSY;
677
+ mutex_lock(&runtime->buffer_mutex);
678
+ return 0; /* keep buffer_mutex, unlocked by below */
679
+}
680
+
681
+/* release buffer_mutex and clear r/w access flag */
682
+static void snd_pcm_buffer_access_unlock(struct snd_pcm_runtime *runtime)
683
+{
684
+ mutex_unlock(&runtime->buffer_mutex);
685
+ atomic_inc(&runtime->buffer_accessing);
686
+}
687
+
688
+#if IS_ENABLED(CONFIG_SND_PCM_OSS)
689
+#define is_oss_stream(substream) ((substream)->oss.oss)
690
+#else
691
+#define is_oss_stream(substream) false
692
+#endif
693
+
669694 static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
670695 struct snd_pcm_hw_params *params)
671696 {
....@@ -677,22 +702,27 @@
677702 if (PCM_RUNTIME_CHECK(substream))
678703 return -ENXIO;
679704 runtime = substream->runtime;
705
+ err = snd_pcm_buffer_access_lock(runtime);
706
+ if (err < 0)
707
+ return err;
680708 snd_pcm_stream_lock_irq(substream);
681709 switch (runtime->status->state) {
682710 case SNDRV_PCM_STATE_OPEN:
683711 case SNDRV_PCM_STATE_SETUP:
684712 case SNDRV_PCM_STATE_PREPARED:
713
+ if (!is_oss_stream(substream) &&
714
+ atomic_read(&substream->mmap_count))
715
+ err = -EBADFD;
685716 break;
686717 default:
687
- snd_pcm_stream_unlock_irq(substream);
688
- return -EBADFD;
718
+ err = -EBADFD;
719
+ break;
689720 }
690721 snd_pcm_stream_unlock_irq(substream);
691
-#if IS_ENABLED(CONFIG_SND_PCM_OSS)
692
- if (!substream->oss.oss)
693
-#endif
694
- if (atomic_read(&substream->mmap_count))
695
- return -EBADFD;
722
+ if (err)
723
+ goto unlock;
724
+
725
+ snd_pcm_sync_stop(substream, true);
696726
697727 params->rmask = ~0U;
698728 err = snd_pcm_hw_refine(substream, params);
....@@ -706,6 +736,14 @@
706736 err = fixup_unreferenced_params(substream, params);
707737 if (err < 0)
708738 goto _error;
739
+
740
+ if (substream->managed_buffer_alloc) {
741
+ err = snd_pcm_lib_malloc_pages(substream,
742
+ params_buffer_bytes(params));
743
+ if (err < 0)
744
+ goto _error;
745
+ runtime->buffer_changed = err > 0;
746
+ }
709747
710748 if (substream->ops->hw_params != NULL) {
711749 err = substream->ops->hw_params(substream, params);
....@@ -764,19 +802,26 @@
764802 snd_pcm_timer_resolution_change(substream);
765803 snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP);
766804
767
- if (pm_qos_request_active(&substream->latency_pm_qos_req))
768
- pm_qos_remove_request(&substream->latency_pm_qos_req);
805
+ if (cpu_latency_qos_request_active(&substream->latency_pm_qos_req))
806
+ cpu_latency_qos_remove_request(&substream->latency_pm_qos_req);
769807 if ((usecs = period_to_usecs(runtime)) >= 0)
770
- pm_qos_add_request(&substream->latency_pm_qos_req,
771
- PM_QOS_CPU_DMA_LATENCY, usecs);
772
- return 0;
808
+ cpu_latency_qos_add_request(&substream->latency_pm_qos_req,
809
+ usecs);
810
+ err = 0;
773811 _error:
774
- /* hardware might be unusable from this time,
775
- so we force application to retry to set
776
- the correct hardware parameter settings */
777
- snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
778
- if (substream->ops->hw_free != NULL)
779
- substream->ops->hw_free(substream);
812
+ if (err) {
813
+ /* hardware might be unusable from this time,
814
+ * so we force application to retry to set
815
+ * the correct hardware parameter settings
816
+ */
817
+ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
818
+ if (substream->ops->hw_free != NULL)
819
+ substream->ops->hw_free(substream);
820
+ if (substream->managed_buffer_alloc)
821
+ snd_pcm_lib_free_pages(substream);
822
+ }
823
+ unlock:
824
+ snd_pcm_buffer_access_unlock(runtime);
780825 return err;
781826 }
782827
....@@ -801,6 +846,18 @@
801846 return err;
802847 }
803848
849
+static int do_hw_free(struct snd_pcm_substream *substream)
850
+{
851
+ int result = 0;
852
+
853
+ snd_pcm_sync_stop(substream, true);
854
+ if (substream->ops->hw_free)
855
+ result = substream->ops->hw_free(substream);
856
+ if (substream->managed_buffer_alloc)
857
+ snd_pcm_lib_free_pages(substream);
858
+ return result;
859
+}
860
+
804861 static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
805862 {
806863 struct snd_pcm_runtime *runtime;
....@@ -809,22 +866,28 @@
809866 if (PCM_RUNTIME_CHECK(substream))
810867 return -ENXIO;
811868 runtime = substream->runtime;
869
+ result = snd_pcm_buffer_access_lock(runtime);
870
+ if (result < 0)
871
+ return result;
812872 snd_pcm_stream_lock_irq(substream);
813873 switch (runtime->status->state) {
814874 case SNDRV_PCM_STATE_SETUP:
815875 case SNDRV_PCM_STATE_PREPARED:
876
+ if (atomic_read(&substream->mmap_count))
877
+ result = -EBADFD;
816878 break;
817879 default:
818
- snd_pcm_stream_unlock_irq(substream);
819
- return -EBADFD;
880
+ result = -EBADFD;
881
+ break;
820882 }
821883 snd_pcm_stream_unlock_irq(substream);
822
- if (atomic_read(&substream->mmap_count))
823
- return -EBADFD;
824
- if (substream->ops->hw_free)
825
- result = substream->ops->hw_free(substream);
884
+ if (result)
885
+ goto unlock;
886
+ result = do_hw_free(substream);
826887 snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
827
- pm_qos_remove_request(&substream->latency_pm_qos_req);
888
+ cpu_latency_qos_remove_request(&substream->latency_pm_qos_req);
889
+ unlock:
890
+ snd_pcm_buffer_access_unlock(runtime);
828891 return result;
829892 }
830893
....@@ -908,8 +971,8 @@
908971 return delay + substream->runtime->delay;
909972 }
910973
911
-int snd_pcm_status(struct snd_pcm_substream *substream,
912
- struct snd_pcm_status *status)
974
+int snd_pcm_status64(struct snd_pcm_substream *substream,
975
+ struct snd_pcm_status64 *status)
913976 {
914977 struct snd_pcm_runtime *runtime = substream->runtime;
915978
....@@ -935,14 +998,22 @@
935998 status->suspended_state = runtime->status->suspended_state;
936999 if (status->state == SNDRV_PCM_STATE_OPEN)
9371000 goto _end;
938
- status->trigger_tstamp = runtime->trigger_tstamp;
1001
+ status->trigger_tstamp_sec = runtime->trigger_tstamp.tv_sec;
1002
+ status->trigger_tstamp_nsec = runtime->trigger_tstamp.tv_nsec;
9391003 if (snd_pcm_running(substream)) {
9401004 snd_pcm_update_hw_ptr(substream);
9411005 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
942
- status->tstamp = runtime->status->tstamp;
943
- status->driver_tstamp = runtime->driver_tstamp;
944
- status->audio_tstamp =
945
- runtime->status->audio_tstamp;
1006
+ status->tstamp_sec = runtime->status->tstamp.tv_sec;
1007
+ status->tstamp_nsec =
1008
+ runtime->status->tstamp.tv_nsec;
1009
+ status->driver_tstamp_sec =
1010
+ runtime->driver_tstamp.tv_sec;
1011
+ status->driver_tstamp_nsec =
1012
+ runtime->driver_tstamp.tv_nsec;
1013
+ status->audio_tstamp_sec =
1014
+ runtime->status->audio_tstamp.tv_sec;
1015
+ status->audio_tstamp_nsec =
1016
+ runtime->status->audio_tstamp.tv_nsec;
9461017 if (runtime->audio_tstamp_report.valid == 1)
9471018 /* backwards compatibility, no report provided in COMPAT mode */
9481019 snd_pcm_pack_audio_tstamp_report(&status->audio_tstamp_data,
....@@ -953,8 +1024,13 @@
9531024 }
9541025 } else {
9551026 /* get tstamp only in fallback mode and only if enabled */
956
- if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
957
- snd_pcm_gettime(runtime, &status->tstamp);
1027
+ if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
1028
+ struct timespec64 tstamp;
1029
+
1030
+ snd_pcm_gettime(runtime, &tstamp);
1031
+ status->tstamp_sec = tstamp.tv_sec;
1032
+ status->tstamp_nsec = tstamp.tv_nsec;
1033
+ }
9581034 }
9591035 _tstamp_end:
9601036 status->appl_ptr = runtime->control->appl_ptr;
....@@ -971,11 +1047,11 @@
9711047 return 0;
9721048 }
9731049
974
-static int snd_pcm_status_user(struct snd_pcm_substream *substream,
975
- struct snd_pcm_status __user * _status,
976
- bool ext)
1050
+static int snd_pcm_status_user64(struct snd_pcm_substream *substream,
1051
+ struct snd_pcm_status64 __user * _status,
1052
+ bool ext)
9771053 {
978
- struct snd_pcm_status status;
1054
+ struct snd_pcm_status64 status;
9791055 int res;
9801056
9811057 memset(&status, 0, sizeof(status));
....@@ -987,11 +1063,60 @@
9871063 if (ext && get_user(status.audio_tstamp_data,
9881064 (u32 __user *)(&_status->audio_tstamp_data)))
9891065 return -EFAULT;
990
- res = snd_pcm_status(substream, &status);
1066
+ res = snd_pcm_status64(substream, &status);
9911067 if (res < 0)
9921068 return res;
9931069 if (copy_to_user(_status, &status, sizeof(status)))
9941070 return -EFAULT;
1071
+ return 0;
1072
+}
1073
+
1074
+static int snd_pcm_status_user32(struct snd_pcm_substream *substream,
1075
+ struct snd_pcm_status32 __user * _status,
1076
+ bool ext)
1077
+{
1078
+ struct snd_pcm_status64 status64;
1079
+ struct snd_pcm_status32 status32;
1080
+ int res;
1081
+
1082
+ memset(&status64, 0, sizeof(status64));
1083
+ memset(&status32, 0, sizeof(status32));
1084
+ /*
1085
+ * with extension, parameters are read/write,
1086
+ * get audio_tstamp_data from user,
1087
+ * ignore rest of status structure
1088
+ */
1089
+ if (ext && get_user(status64.audio_tstamp_data,
1090
+ (u32 __user *)(&_status->audio_tstamp_data)))
1091
+ return -EFAULT;
1092
+ res = snd_pcm_status64(substream, &status64);
1093
+ if (res < 0)
1094
+ return res;
1095
+
1096
+ status32 = (struct snd_pcm_status32) {
1097
+ .state = status64.state,
1098
+ .trigger_tstamp_sec = status64.trigger_tstamp_sec,
1099
+ .trigger_tstamp_nsec = status64.trigger_tstamp_nsec,
1100
+ .tstamp_sec = status64.tstamp_sec,
1101
+ .tstamp_nsec = status64.tstamp_nsec,
1102
+ .appl_ptr = status64.appl_ptr,
1103
+ .hw_ptr = status64.hw_ptr,
1104
+ .delay = status64.delay,
1105
+ .avail = status64.avail,
1106
+ .avail_max = status64.avail_max,
1107
+ .overrange = status64.overrange,
1108
+ .suspended_state = status64.suspended_state,
1109
+ .audio_tstamp_data = status64.audio_tstamp_data,
1110
+ .audio_tstamp_sec = status64.audio_tstamp_sec,
1111
+ .audio_tstamp_nsec = status64.audio_tstamp_nsec,
1112
+ .driver_tstamp_sec = status64.audio_tstamp_sec,
1113
+ .driver_tstamp_nsec = status64.audio_tstamp_nsec,
1114
+ .audio_tstamp_accuracy = status64.audio_tstamp_accuracy,
1115
+ };
1116
+
1117
+ if (copy_to_user(_status, &status32, sizeof(status32)))
1118
+ return -EFAULT;
1119
+
9951120 return 0;
9961121 }
9971122
....@@ -1013,7 +1138,7 @@
10131138 return -EINVAL;
10141139 memset(info, 0, sizeof(*info));
10151140 info->channel = channel;
1016
- return substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_CHANNEL_INFO, info);
1141
+ return snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_CHANNEL_INFO, info);
10171142 }
10181143
10191144 static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
....@@ -1047,11 +1172,17 @@
10471172 runtime->trigger_master = NULL;
10481173 }
10491174
1175
+#define ACTION_ARG_IGNORE (__force snd_pcm_state_t)0
1176
+
10501177 struct action_ops {
1051
- int (*pre_action)(struct snd_pcm_substream *substream, int state);
1052
- int (*do_action)(struct snd_pcm_substream *substream, int state);
1053
- void (*undo_action)(struct snd_pcm_substream *substream, int state);
1054
- void (*post_action)(struct snd_pcm_substream *substream, int state);
1178
+ int (*pre_action)(struct snd_pcm_substream *substream,
1179
+ snd_pcm_state_t state);
1180
+ int (*do_action)(struct snd_pcm_substream *substream,
1181
+ snd_pcm_state_t state);
1182
+ void (*undo_action)(struct snd_pcm_substream *substream,
1183
+ snd_pcm_state_t state);
1184
+ void (*post_action)(struct snd_pcm_substream *substream,
1185
+ snd_pcm_state_t state);
10551186 };
10561187
10571188 /*
....@@ -1061,15 +1192,18 @@
10611192 */
10621193 static int snd_pcm_action_group(const struct action_ops *ops,
10631194 struct snd_pcm_substream *substream,
1064
- int state, int do_lock)
1195
+ snd_pcm_state_t state,
1196
+ bool stream_lock)
10651197 {
10661198 struct snd_pcm_substream *s = NULL;
10671199 struct snd_pcm_substream *s1;
10681200 int res = 0, depth = 1;
10691201
10701202 snd_pcm_group_for_each_entry(s, substream) {
1071
- if (do_lock && s != substream) {
1072
- if (s->pcm->nonatomic)
1203
+ if (s != substream) {
1204
+ if (!stream_lock)
1205
+ mutex_lock_nested(&s->runtime->buffer_mutex, depth);
1206
+ else if (s->pcm->nonatomic)
10731207 mutex_lock_nested(&s->self_group.mutex, depth);
10741208 else
10751209 spin_lock_nested(&s->self_group.lock, depth);
....@@ -1097,18 +1231,18 @@
10971231 ops->post_action(s, state);
10981232 }
10991233 _unlock:
1100
- if (do_lock) {
1101
- /* unlock streams */
1102
- snd_pcm_group_for_each_entry(s1, substream) {
1103
- if (s1 != substream) {
1104
- if (s1->pcm->nonatomic)
1105
- mutex_unlock(&s1->self_group.mutex);
1106
- else
1107
- spin_unlock(&s1->self_group.lock);
1108
- }
1109
- if (s1 == s) /* end */
1110
- break;
1234
+ /* unlock streams */
1235
+ snd_pcm_group_for_each_entry(s1, substream) {
1236
+ if (s1 != substream) {
1237
+ if (!stream_lock)
1238
+ mutex_unlock(&s1->runtime->buffer_mutex);
1239
+ else if (s1->pcm->nonatomic)
1240
+ mutex_unlock(&s1->self_group.mutex);
1241
+ else
1242
+ spin_unlock(&s1->self_group.lock);
11111243 }
1244
+ if (s1 == s) /* end */
1245
+ break;
11121246 }
11131247 return res;
11141248 }
....@@ -1118,7 +1252,7 @@
11181252 */
11191253 static int snd_pcm_action_single(const struct action_ops *ops,
11201254 struct snd_pcm_substream *substream,
1121
- int state)
1255
+ snd_pcm_state_t state)
11221256 {
11231257 int res;
11241258
....@@ -1133,35 +1267,83 @@
11331267 return res;
11341268 }
11351269
1270
+static void snd_pcm_group_assign(struct snd_pcm_substream *substream,
1271
+ struct snd_pcm_group *new_group)
1272
+{
1273
+ substream->group = new_group;
1274
+ list_move(&substream->link_list, &new_group->substreams);
1275
+}
1276
+
1277
+/*
1278
+ * Unref and unlock the group, but keep the stream lock;
1279
+ * when the group becomes empty and no longer referred, destroy itself
1280
+ */
1281
+static void snd_pcm_group_unref(struct snd_pcm_group *group,
1282
+ struct snd_pcm_substream *substream)
1283
+{
1284
+ bool do_free;
1285
+
1286
+ if (!group)
1287
+ return;
1288
+ do_free = refcount_dec_and_test(&group->refs);
1289
+ snd_pcm_group_unlock(group, substream->pcm->nonatomic);
1290
+ if (do_free)
1291
+ kfree(group);
1292
+}
1293
+
1294
+/*
1295
+ * Lock the group inside a stream lock and reference it;
1296
+ * return the locked group object, or NULL if not linked
1297
+ */
1298
+static struct snd_pcm_group *
1299
+snd_pcm_stream_group_ref(struct snd_pcm_substream *substream)
1300
+{
1301
+ bool nonatomic = substream->pcm->nonatomic;
1302
+ struct snd_pcm_group *group;
1303
+ bool trylock;
1304
+
1305
+ for (;;) {
1306
+ if (!snd_pcm_stream_linked(substream))
1307
+ return NULL;
1308
+ group = substream->group;
1309
+ /* block freeing the group object */
1310
+ refcount_inc(&group->refs);
1311
+
1312
+ trylock = nonatomic ? mutex_trylock(&group->mutex) :
1313
+ spin_trylock(&group->lock);
1314
+ if (trylock)
1315
+ break; /* OK */
1316
+
1317
+ /* re-lock for avoiding ABBA deadlock */
1318
+ snd_pcm_stream_unlock(substream);
1319
+ snd_pcm_group_lock(group, nonatomic);
1320
+ snd_pcm_stream_lock(substream);
1321
+
1322
+ /* check the group again; the above opens a small race window */
1323
+ if (substream->group == group)
1324
+ break; /* OK */
1325
+ /* group changed, try again */
1326
+ snd_pcm_group_unref(group, substream);
1327
+ }
1328
+ return group;
1329
+}
1330
+
11361331 /*
11371332 * Note: call with stream lock
11381333 */
11391334 static int snd_pcm_action(const struct action_ops *ops,
11401335 struct snd_pcm_substream *substream,
1141
- int state)
1336
+ snd_pcm_state_t state)
11421337 {
1338
+ struct snd_pcm_group *group;
11431339 int res;
11441340
1145
- if (!snd_pcm_stream_linked(substream))
1146
- return snd_pcm_action_single(ops, substream, state);
1147
-
1148
- if (substream->pcm->nonatomic) {
1149
- if (!mutex_trylock(&substream->group->mutex)) {
1150
- mutex_unlock(&substream->self_group.mutex);
1151
- mutex_lock(&substream->group->mutex);
1152
- mutex_lock(&substream->self_group.mutex);
1153
- }
1154
- res = snd_pcm_action_group(ops, substream, state, 1);
1155
- mutex_unlock(&substream->group->mutex);
1156
- } else {
1157
- if (!spin_trylock(&substream->group->lock)) {
1158
- spin_unlock(&substream->self_group.lock);
1159
- spin_lock(&substream->group->lock);
1160
- spin_lock(&substream->self_group.lock);
1161
- }
1162
- res = snd_pcm_action_group(ops, substream, state, 1);
1163
- spin_unlock(&substream->group->lock);
1164
- }
1341
+ group = snd_pcm_stream_group_ref(substream);
1342
+ if (group)
1343
+ res = snd_pcm_action_group(ops, substream, state, true);
1344
+ else
1345
+ res = snd_pcm_action_single(ops, substream, state);
1346
+ snd_pcm_group_unref(group, substream);
11651347 return res;
11661348 }
11671349
....@@ -1170,7 +1352,7 @@
11701352 */
11711353 static int snd_pcm_action_lock_irq(const struct action_ops *ops,
11721354 struct snd_pcm_substream *substream,
1173
- int state)
1355
+ snd_pcm_state_t state)
11741356 {
11751357 int res;
11761358
....@@ -1184,15 +1366,21 @@
11841366 */
11851367 static int snd_pcm_action_nonatomic(const struct action_ops *ops,
11861368 struct snd_pcm_substream *substream,
1187
- int state)
1369
+ snd_pcm_state_t state)
11881370 {
11891371 int res;
11901372
1373
+ /* Guarantee the group members won't change during non-atomic action */
11911374 down_read(&snd_pcm_link_rwsem);
1375
+ res = snd_pcm_buffer_access_lock(substream->runtime);
1376
+ if (res < 0)
1377
+ goto unlock;
11921378 if (snd_pcm_stream_linked(substream))
1193
- res = snd_pcm_action_group(ops, substream, state, 0);
1379
+ res = snd_pcm_action_group(ops, substream, state, false);
11941380 else
11951381 res = snd_pcm_action_single(ops, substream, state);
1382
+ snd_pcm_buffer_access_unlock(substream->runtime);
1383
+ unlock:
11961384 up_read(&snd_pcm_link_rwsem);
11971385 return res;
11981386 }
....@@ -1200,7 +1388,8 @@
12001388 /*
12011389 * start callbacks
12021390 */
1203
-static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
1391
+static int snd_pcm_pre_start(struct snd_pcm_substream *substream,
1392
+ snd_pcm_state_t state)
12041393 {
12051394 struct snd_pcm_runtime *runtime = substream->runtime;
12061395 if (runtime->status->state != SNDRV_PCM_STATE_PREPARED)
....@@ -1213,20 +1402,25 @@
12131402 return 0;
12141403 }
12151404
1216
-static int snd_pcm_do_start(struct snd_pcm_substream *substream, int state)
1405
+static int snd_pcm_do_start(struct snd_pcm_substream *substream,
1406
+ snd_pcm_state_t state)
12171407 {
12181408 if (substream->runtime->trigger_master != substream)
12191409 return 0;
12201410 return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
12211411 }
12221412
1223
-static void snd_pcm_undo_start(struct snd_pcm_substream *substream, int state)
1413
+static void snd_pcm_undo_start(struct snd_pcm_substream *substream,
1414
+ snd_pcm_state_t state)
12241415 {
1225
- if (substream->runtime->trigger_master == substream)
1416
+ if (substream->runtime->trigger_master == substream) {
12261417 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
1418
+ substream->runtime->stop_operating = true;
1419
+ }
12271420 }
12281421
1229
-static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
1422
+static void snd_pcm_post_start(struct snd_pcm_substream *substream,
1423
+ snd_pcm_state_t state)
12301424 {
12311425 struct snd_pcm_runtime *runtime = substream->runtime;
12321426 snd_pcm_trigger_tstamp(substream);
....@@ -1270,7 +1464,8 @@
12701464 /*
12711465 * stop callbacks
12721466 */
1273
-static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state)
1467
+static int snd_pcm_pre_stop(struct snd_pcm_substream *substream,
1468
+ snd_pcm_state_t state)
12741469 {
12751470 struct snd_pcm_runtime *runtime = substream->runtime;
12761471 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
....@@ -1279,15 +1474,19 @@
12791474 return 0;
12801475 }
12811476
1282
-static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state)
1477
+static int snd_pcm_do_stop(struct snd_pcm_substream *substream,
1478
+ snd_pcm_state_t state)
12831479 {
12841480 if (substream->runtime->trigger_master == substream &&
1285
- snd_pcm_running(substream))
1481
+ snd_pcm_running(substream)) {
12861482 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
1483
+ substream->runtime->stop_operating = true;
1484
+ }
12871485 return 0; /* unconditonally stop all substreams */
12881486 }
12891487
1290
-static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
1488
+static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
1489
+ snd_pcm_state_t state)
12911490 {
12921491 struct snd_pcm_runtime *runtime = substream->runtime;
12931492 if (runtime->status->state != state) {
....@@ -1357,14 +1556,17 @@
13571556 EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun);
13581557
13591558 /*
1360
- * pause callbacks
1559
+ * pause callbacks: pass boolean (to start pause or resume) as state argument
13611560 */
1362
-static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push)
1561
+#define pause_pushed(state) (__force bool)(state)
1562
+
1563
+static int snd_pcm_pre_pause(struct snd_pcm_substream *substream,
1564
+ snd_pcm_state_t state)
13631565 {
13641566 struct snd_pcm_runtime *runtime = substream->runtime;
13651567 if (!(runtime->info & SNDRV_PCM_INFO_PAUSE))
13661568 return -ENOSYS;
1367
- if (push) {
1569
+ if (pause_pushed(state)) {
13681570 if (runtime->status->state != SNDRV_PCM_STATE_RUNNING)
13691571 return -EBADFD;
13701572 } else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED)
....@@ -1373,13 +1575,14 @@
13731575 return 0;
13741576 }
13751577
1376
-static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
1578
+static int snd_pcm_do_pause(struct snd_pcm_substream *substream,
1579
+ snd_pcm_state_t state)
13771580 {
13781581 if (substream->runtime->trigger_master != substream)
13791582 return 0;
13801583 /* some drivers might use hw_ptr to recover from the pause -
13811584 update the hw_ptr now */
1382
- if (push)
1585
+ if (pause_pushed(state))
13831586 snd_pcm_update_hw_ptr(substream);
13841587 /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
13851588 * a delta between the current jiffies, this gives a large enough
....@@ -1387,23 +1590,27 @@
13871590 */
13881591 substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
13891592 return substream->ops->trigger(substream,
1390
- push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH :
1391
- SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
1593
+ pause_pushed(state) ?
1594
+ SNDRV_PCM_TRIGGER_PAUSE_PUSH :
1595
+ SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
13921596 }
13931597
1394
-static void snd_pcm_undo_pause(struct snd_pcm_substream *substream, int push)
1598
+static void snd_pcm_undo_pause(struct snd_pcm_substream *substream,
1599
+ snd_pcm_state_t state)
13951600 {
13961601 if (substream->runtime->trigger_master == substream)
13971602 substream->ops->trigger(substream,
1398
- push ? SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
1603
+ pause_pushed(state) ?
1604
+ SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
13991605 SNDRV_PCM_TRIGGER_PAUSE_PUSH);
14001606 }
14011607
1402
-static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1608
+static void snd_pcm_post_pause(struct snd_pcm_substream *substream,
1609
+ snd_pcm_state_t state)
14031610 {
14041611 struct snd_pcm_runtime *runtime = substream->runtime;
14051612 snd_pcm_trigger_tstamp(substream);
1406
- if (push) {
1613
+ if (pause_pushed(state)) {
14071614 runtime->status->state = SNDRV_PCM_STATE_PAUSED;
14081615 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE);
14091616 wake_up(&runtime->sleep);
....@@ -1424,15 +1631,24 @@
14241631 /*
14251632 * Push/release the pause for all linked streams.
14261633 */
1427
-static int snd_pcm_pause(struct snd_pcm_substream *substream, int push)
1634
+static int snd_pcm_pause(struct snd_pcm_substream *substream, bool push)
14281635 {
1429
- return snd_pcm_action(&snd_pcm_action_pause, substream, push);
1636
+ return snd_pcm_action(&snd_pcm_action_pause, substream,
1637
+ (__force snd_pcm_state_t)push);
1638
+}
1639
+
1640
+static int snd_pcm_pause_lock_irq(struct snd_pcm_substream *substream,
1641
+ bool push)
1642
+{
1643
+ return snd_pcm_action_lock_irq(&snd_pcm_action_pause, substream,
1644
+ (__force snd_pcm_state_t)push);
14301645 }
14311646
14321647 #ifdef CONFIG_PM
1433
-/* suspend */
1648
+/* suspend callback: state argument ignored */
14341649
1435
-static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state)
1650
+static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream,
1651
+ snd_pcm_state_t state)
14361652 {
14371653 struct snd_pcm_runtime *runtime = substream->runtime;
14381654 switch (runtime->status->state) {
....@@ -1448,7 +1664,8 @@
14481664 return 0;
14491665 }
14501666
1451
-static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state)
1667
+static int snd_pcm_do_suspend(struct snd_pcm_substream *substream,
1668
+ snd_pcm_state_t state)
14521669 {
14531670 struct snd_pcm_runtime *runtime = substream->runtime;
14541671 if (runtime->trigger_master != substream)
....@@ -1456,10 +1673,12 @@
14561673 if (! snd_pcm_running(substream))
14571674 return 0;
14581675 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
1676
+ runtime->stop_operating = true;
14591677 return 0; /* suspend unconditionally */
14601678 }
14611679
1462
-static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1680
+static void snd_pcm_post_suspend(struct snd_pcm_substream *substream,
1681
+ snd_pcm_state_t state)
14631682 {
14641683 struct snd_pcm_runtime *runtime = substream->runtime;
14651684 snd_pcm_trigger_tstamp(substream);
....@@ -1476,29 +1695,25 @@
14761695 .post_action = snd_pcm_post_suspend
14771696 };
14781697
1479
-/**
1698
+/*
14801699 * snd_pcm_suspend - trigger SUSPEND to all linked streams
14811700 * @substream: the PCM substream
14821701 *
14831702 * After this call, all streams are changed to SUSPENDED state.
14841703 *
1485
- * Return: Zero if successful (or @substream is %NULL), or a negative error
1486
- * code.
1704
+ * Return: Zero if successful, or a negative error code.
14871705 */
1488
-int snd_pcm_suspend(struct snd_pcm_substream *substream)
1706
+static int snd_pcm_suspend(struct snd_pcm_substream *substream)
14891707 {
14901708 int err;
14911709 unsigned long flags;
14921710
1493
- if (! substream)
1494
- return 0;
1495
-
14961711 snd_pcm_stream_lock_irqsave(substream, flags);
1497
- err = snd_pcm_action(&snd_pcm_action_suspend, substream, 0);
1712
+ err = snd_pcm_action(&snd_pcm_action_suspend, substream,
1713
+ ACTION_ARG_IGNORE);
14981714 snd_pcm_stream_unlock_irqrestore(substream, flags);
14991715 return err;
15001716 }
1501
-EXPORT_SYMBOL(snd_pcm_suspend);
15021717
15031718 /**
15041719 * snd_pcm_suspend_all - trigger SUSPEND to all substreams in the given pcm
....@@ -1535,13 +1750,20 @@
15351750 return err;
15361751 }
15371752 }
1753
+
1754
+ for (stream = 0; stream < 2; stream++)
1755
+ for (substream = pcm->streams[stream].substream;
1756
+ substream; substream = substream->next)
1757
+ snd_pcm_sync_stop(substream, false);
1758
+
15381759 return 0;
15391760 }
15401761 EXPORT_SYMBOL(snd_pcm_suspend_all);
15411762
1542
-/* resume */
1763
+/* resume callbacks: state argument ignored */
15431764
1544
-static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
1765
+static int snd_pcm_pre_resume(struct snd_pcm_substream *substream,
1766
+ snd_pcm_state_t state)
15451767 {
15461768 struct snd_pcm_runtime *runtime = substream->runtime;
15471769 if (!(runtime->info & SNDRV_PCM_INFO_RESUME))
....@@ -1550,7 +1772,8 @@
15501772 return 0;
15511773 }
15521774
1553
-static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state)
1775
+static int snd_pcm_do_resume(struct snd_pcm_substream *substream,
1776
+ snd_pcm_state_t state)
15541777 {
15551778 struct snd_pcm_runtime *runtime = substream->runtime;
15561779 if (runtime->trigger_master != substream)
....@@ -1563,14 +1786,16 @@
15631786 return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
15641787 }
15651788
1566
-static void snd_pcm_undo_resume(struct snd_pcm_substream *substream, int state)
1789
+static void snd_pcm_undo_resume(struct snd_pcm_substream *substream,
1790
+ snd_pcm_state_t state)
15671791 {
15681792 if (substream->runtime->trigger_master == substream &&
15691793 snd_pcm_running(substream))
15701794 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
15711795 }
15721796
1573
-static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
1797
+static void snd_pcm_post_resume(struct snd_pcm_substream *substream,
1798
+ snd_pcm_state_t state)
15741799 {
15751800 struct snd_pcm_runtime *runtime = substream->runtime;
15761801 snd_pcm_trigger_tstamp(substream);
....@@ -1587,7 +1812,8 @@
15871812
15881813 static int snd_pcm_resume(struct snd_pcm_substream *substream)
15891814 {
1590
- return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0);
1815
+ return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream,
1816
+ ACTION_ARG_IGNORE);
15911817 }
15921818
15931819 #else
....@@ -1628,7 +1854,9 @@
16281854 /*
16291855 * reset ioctl
16301856 */
1631
-static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state)
1857
+/* reset callbacks: state argument ignored */
1858
+static int snd_pcm_pre_reset(struct snd_pcm_substream *substream,
1859
+ snd_pcm_state_t state)
16321860 {
16331861 struct snd_pcm_runtime *runtime = substream->runtime;
16341862 switch (runtime->status->state) {
....@@ -1642,27 +1870,33 @@
16421870 }
16431871 }
16441872
1645
-static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
1873
+static int snd_pcm_do_reset(struct snd_pcm_substream *substream,
1874
+ snd_pcm_state_t state)
16461875 {
16471876 struct snd_pcm_runtime *runtime = substream->runtime;
1648
- int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
1877
+ int err = snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
16491878 if (err < 0)
16501879 return err;
1880
+ snd_pcm_stream_lock_irq(substream);
16511881 runtime->hw_ptr_base = 0;
16521882 runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
16531883 runtime->status->hw_ptr % runtime->period_size;
16541884 runtime->silence_start = runtime->status->hw_ptr;
16551885 runtime->silence_filled = 0;
1886
+ snd_pcm_stream_unlock_irq(substream);
16561887 return 0;
16571888 }
16581889
1659
-static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state)
1890
+static void snd_pcm_post_reset(struct snd_pcm_substream *substream,
1891
+ snd_pcm_state_t state)
16601892 {
16611893 struct snd_pcm_runtime *runtime = substream->runtime;
1894
+ snd_pcm_stream_lock_irq(substream);
16621895 runtime->control->appl_ptr = runtime->status->hw_ptr;
16631896 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
16641897 runtime->silence_size > 0)
16651898 snd_pcm_playback_silence(substream, ULONG_MAX);
1899
+ snd_pcm_stream_unlock_irq(substream);
16661900 }
16671901
16681902 static const struct action_ops snd_pcm_action_reset = {
....@@ -1673,17 +1907,20 @@
16731907
16741908 static int snd_pcm_reset(struct snd_pcm_substream *substream)
16751909 {
1676
- return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream, 0);
1910
+ return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream,
1911
+ ACTION_ARG_IGNORE);
16771912 }
16781913
16791914 /*
16801915 * prepare ioctl
16811916 */
1682
-/* we use the second argument for updating f_flags */
1917
+/* pass f_flags as state argument */
16831918 static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
1684
- int f_flags)
1919
+ snd_pcm_state_t state)
16851920 {
16861921 struct snd_pcm_runtime *runtime = substream->runtime;
1922
+ int f_flags = (__force int)state;
1923
+
16871924 if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
16881925 runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
16891926 return -EBADFD;
....@@ -1693,16 +1930,19 @@
16931930 return 0;
16941931 }
16951932
1696
-static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, int state)
1933
+static int snd_pcm_do_prepare(struct snd_pcm_substream *substream,
1934
+ snd_pcm_state_t state)
16971935 {
16981936 int err;
1937
+ snd_pcm_sync_stop(substream, true);
16991938 err = substream->ops->prepare(substream);
17001939 if (err < 0)
17011940 return err;
1702
- return snd_pcm_do_reset(substream, 0);
1941
+ return snd_pcm_do_reset(substream, state);
17031942 }
17041943
1705
-static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state)
1944
+static void snd_pcm_post_prepare(struct snd_pcm_substream *substream,
1945
+ snd_pcm_state_t state)
17061946 {
17071947 struct snd_pcm_runtime *runtime = substream->runtime;
17081948 runtime->control->appl_ptr = runtime->status->hw_ptr;
....@@ -1735,8 +1975,8 @@
17351975 snd_pcm_stream_lock_irq(substream);
17361976 switch (substream->runtime->status->state) {
17371977 case SNDRV_PCM_STATE_PAUSED:
1738
- snd_pcm_pause(substream, 0);
1739
- /* fallthru */
1978
+ snd_pcm_pause(substream, false);
1979
+ fallthrough;
17401980 case SNDRV_PCM_STATE_SUSPENDED:
17411981 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
17421982 break;
....@@ -1744,14 +1984,17 @@
17441984 snd_pcm_stream_unlock_irq(substream);
17451985
17461986 return snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
1747
- substream, f_flags);
1987
+ substream,
1988
+ (__force snd_pcm_state_t)f_flags);
17481989 }
17491990
17501991 /*
17511992 * drain ioctl
17521993 */
17531994
1754
-static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
1995
+/* drain init callbacks: state argument ignored */
1996
+static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream,
1997
+ snd_pcm_state_t state)
17551998 {
17561999 struct snd_pcm_runtime *runtime = substream->runtime;
17572000 switch (runtime->status->state) {
....@@ -1764,7 +2007,8 @@
17642007 return 0;
17652008 }
17662009
1767
-static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
2010
+static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream,
2011
+ snd_pcm_state_t state)
17682012 {
17692013 struct snd_pcm_runtime *runtime = substream->runtime;
17702014 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
....@@ -1790,7 +2034,9 @@
17902034 } else {
17912035 /* stop running stream */
17922036 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
1793
- int new_state = snd_pcm_capture_avail(runtime) > 0 ?
2037
+ snd_pcm_state_t new_state;
2038
+
2039
+ new_state = snd_pcm_capture_avail(runtime) > 0 ?
17942040 SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP;
17952041 snd_pcm_do_stop(substream, new_state);
17962042 snd_pcm_post_stop(substream, new_state);
....@@ -1806,7 +2052,8 @@
18062052 return 0;
18072053 }
18082054
1809
-static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int state)
2055
+static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream,
2056
+ snd_pcm_state_t state)
18102057 {
18112058 }
18122059
....@@ -1815,8 +2062,6 @@
18152062 .do_action = snd_pcm_do_drain_init,
18162063 .post_action = snd_pcm_post_drain_init
18172064 };
1818
-
1819
-static int snd_pcm_drop(struct snd_pcm_substream *substream);
18202065
18212066 /*
18222067 * Drain the stream(s).
....@@ -1831,6 +2076,7 @@
18312076 struct snd_card *card;
18322077 struct snd_pcm_runtime *runtime;
18332078 struct snd_pcm_substream *s;
2079
+ struct snd_pcm_group *group;
18342080 wait_queue_entry_t wait;
18352081 int result = 0;
18362082 int nonblock = 0;
....@@ -1847,14 +2093,14 @@
18472093 } else if (substream->f_flags & O_NONBLOCK)
18482094 nonblock = 1;
18492095
1850
- down_read(&snd_pcm_link_rwsem);
18512096 snd_pcm_stream_lock_irq(substream);
18522097 /* resume pause */
18532098 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
1854
- snd_pcm_pause(substream, 0);
2099
+ snd_pcm_pause(substream, false);
18552100
18562101 /* pre-start/stop - all running streams are changed to DRAINING state */
1857
- result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
2102
+ result = snd_pcm_action(&snd_pcm_action_drain_init, substream,
2103
+ ACTION_ARG_IGNORE);
18582104 if (result < 0)
18592105 goto unlock;
18602106 /* in non-blocking, we don't wait in ioctl but let caller poll */
....@@ -1872,6 +2118,7 @@
18722118 }
18732119 /* find a substream to drain */
18742120 to_check = NULL;
2121
+ group = snd_pcm_stream_group_ref(substream);
18752122 snd_pcm_group_for_each_entry(s, substream) {
18762123 if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
18772124 continue;
....@@ -1881,12 +2128,13 @@
18812128 break;
18822129 }
18832130 }
2131
+ snd_pcm_group_unref(group, substream);
18842132 if (!to_check)
18852133 break; /* all drained */
18862134 init_waitqueue_entry(&wait, current);
2135
+ set_current_state(TASK_INTERRUPTIBLE);
18872136 add_wait_queue(&to_check->sleep, &wait);
18882137 snd_pcm_stream_unlock_irq(substream);
1889
- up_read(&snd_pcm_link_rwsem);
18902138 if (runtime->no_period_wakeup)
18912139 tout = MAX_SCHEDULE_TIMEOUT;
18922140 else {
....@@ -1897,10 +2145,18 @@
18972145 }
18982146 tout = msecs_to_jiffies(tout * 1000);
18992147 }
1900
- tout = schedule_timeout_interruptible(tout);
1901
- down_read(&snd_pcm_link_rwsem);
2148
+ tout = schedule_timeout(tout);
2149
+
19022150 snd_pcm_stream_lock_irq(substream);
1903
- remove_wait_queue(&to_check->sleep, &wait);
2151
+ group = snd_pcm_stream_group_ref(substream);
2152
+ snd_pcm_group_for_each_entry(s, substream) {
2153
+ if (s->runtime == to_check) {
2154
+ remove_wait_queue(&to_check->sleep, &wait);
2155
+ break;
2156
+ }
2157
+ }
2158
+ snd_pcm_group_unref(group, substream);
2159
+
19042160 if (card->shutdown) {
19052161 result = -ENODEV;
19062162 break;
....@@ -1920,7 +2176,6 @@
19202176
19212177 unlock:
19222178 snd_pcm_stream_unlock_irq(substream);
1923
- up_read(&snd_pcm_link_rwsem);
19242179
19252180 return result;
19262181 }
....@@ -1946,7 +2201,7 @@
19462201 snd_pcm_stream_lock_irq(substream);
19472202 /* resume pause */
19482203 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
1949
- snd_pcm_pause(substream, 0);
2204
+ snd_pcm_pause(substream, false);
19502205
19512206 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
19522207 /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
....@@ -1959,13 +2214,19 @@
19592214 static bool is_pcm_file(struct file *file)
19602215 {
19612216 struct inode *inode = file_inode(file);
2217
+ struct snd_pcm *pcm;
19622218 unsigned int minor;
19632219
19642220 if (!S_ISCHR(inode->i_mode) || imajor(inode) != snd_major)
19652221 return false;
19662222 minor = iminor(inode);
1967
- return snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) ||
1968
- snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
2223
+ pcm = snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
2224
+ if (!pcm)
2225
+ pcm = snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
2226
+ if (!pcm)
2227
+ return false;
2228
+ snd_card_unref(pcm->card);
2229
+ return true;
19692230 }
19702231
19712232 /*
....@@ -1976,7 +2237,8 @@
19762237 int res = 0;
19772238 struct snd_pcm_file *pcm_file;
19782239 struct snd_pcm_substream *substream1;
1979
- struct snd_pcm_group *group;
2240
+ struct snd_pcm_group *group, *target_group;
2241
+ bool nonatomic = substream->pcm->nonatomic;
19802242 struct fd f = fdget(fd);
19812243
19822244 if (!f.file)
....@@ -1987,18 +2249,20 @@
19872249 }
19882250 pcm_file = f.file->private_data;
19892251 substream1 = pcm_file->substream;
2252
+
19902253 if (substream == substream1) {
19912254 res = -EINVAL;
19922255 goto _badf;
19932256 }
19942257
1995
- group = kmalloc(sizeof(*group), GFP_KERNEL);
2258
+ group = kzalloc(sizeof(*group), GFP_KERNEL);
19962259 if (!group) {
19972260 res = -ENOMEM;
19982261 goto _nolock;
19992262 }
2000
- down_write_nonfifo(&snd_pcm_link_rwsem);
2001
- write_lock_irq(&snd_pcm_link_rwlock);
2263
+ snd_pcm_group_init(group);
2264
+
2265
+ down_write(&snd_pcm_link_rwsem);
20022266 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
20032267 substream->runtime->status->state != substream1->runtime->status->state ||
20042268 substream->pcm->nonatomic != substream1->pcm->nonatomic) {
....@@ -2009,23 +2273,24 @@
20092273 res = -EALREADY;
20102274 goto _end;
20112275 }
2276
+
2277
+ snd_pcm_stream_lock_irq(substream);
20122278 if (!snd_pcm_stream_linked(substream)) {
2013
- substream->group = group;
2014
- group = NULL;
2015
- spin_lock_init(&substream->group->lock);
2016
- mutex_init(&substream->group->mutex);
2017
- INIT_LIST_HEAD(&substream->group->substreams);
2018
- list_add_tail(&substream->link_list, &substream->group->substreams);
2019
- substream->group->count = 1;
2279
+ snd_pcm_group_assign(substream, group);
2280
+ group = NULL; /* assigned, don't free this one below */
20202281 }
2021
- list_add_tail(&substream1->link_list, &substream->group->substreams);
2022
- substream->group->count++;
2023
- substream1->group = substream->group;
2282
+ target_group = substream->group;
2283
+ snd_pcm_stream_unlock_irq(substream);
2284
+
2285
+ snd_pcm_group_lock_irq(target_group, nonatomic);
2286
+ snd_pcm_stream_lock_nested(substream1);
2287
+ snd_pcm_group_assign(substream1, target_group);
2288
+ refcount_inc(&target_group->refs);
2289
+ snd_pcm_stream_unlock(substream1);
2290
+ snd_pcm_group_unlock_irq(target_group, nonatomic);
20242291 _end:
2025
- write_unlock_irq(&snd_pcm_link_rwlock);
20262292 up_write(&snd_pcm_link_rwsem);
20272293 _nolock:
2028
- snd_card_unref(substream1->pcm->card);
20292294 kfree(group);
20302295 _badf:
20312296 fdput(f);
....@@ -2034,34 +2299,44 @@
20342299
20352300 static void relink_to_local(struct snd_pcm_substream *substream)
20362301 {
2037
- substream->group = &substream->self_group;
2038
- INIT_LIST_HEAD(&substream->self_group.substreams);
2039
- list_add_tail(&substream->link_list, &substream->self_group.substreams);
2302
+ snd_pcm_stream_lock_nested(substream);
2303
+ snd_pcm_group_assign(substream, &substream->self_group);
2304
+ snd_pcm_stream_unlock(substream);
20402305 }
20412306
20422307 static int snd_pcm_unlink(struct snd_pcm_substream *substream)
20432308 {
2044
- struct snd_pcm_substream *s;
2309
+ struct snd_pcm_group *group;
2310
+ bool nonatomic = substream->pcm->nonatomic;
2311
+ bool do_free = false;
20452312 int res = 0;
20462313
2047
- down_write_nonfifo(&snd_pcm_link_rwsem);
2048
- write_lock_irq(&snd_pcm_link_rwlock);
2314
+ down_write(&snd_pcm_link_rwsem);
2315
+
20492316 if (!snd_pcm_stream_linked(substream)) {
20502317 res = -EALREADY;
20512318 goto _end;
20522319 }
2053
- list_del(&substream->link_list);
2054
- substream->group->count--;
2055
- if (substream->group->count == 1) { /* detach the last stream, too */
2056
- snd_pcm_group_for_each_entry(s, substream) {
2057
- relink_to_local(s);
2058
- break;
2059
- }
2060
- kfree(substream->group);
2061
- }
2320
+
2321
+ group = substream->group;
2322
+ snd_pcm_group_lock_irq(group, nonatomic);
2323
+
20622324 relink_to_local(substream);
2325
+ refcount_dec(&group->refs);
2326
+
2327
+ /* detach the last stream, too */
2328
+ if (list_is_singular(&group->substreams)) {
2329
+ relink_to_local(list_first_entry(&group->substreams,
2330
+ struct snd_pcm_substream,
2331
+ link_list));
2332
+ do_free = refcount_dec_and_test(&group->refs);
2333
+ }
2334
+
2335
+ snd_pcm_group_unlock_irq(group, nonatomic);
2336
+ if (do_free)
2337
+ kfree(group);
2338
+
20632339 _end:
2064
- write_unlock_irq(&snd_pcm_link_rwlock);
20652340 up_write(&snd_pcm_link_rwsem);
20662341 return res;
20672342 }
....@@ -2110,21 +2385,21 @@
21102385 static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params,
21112386 struct snd_pcm_hw_rule *rule)
21122387 {
2113
- unsigned int k;
2388
+ snd_pcm_format_t k;
21142389 const struct snd_interval *i =
21152390 hw_param_interval_c(params, rule->deps[0]);
21162391 struct snd_mask m;
21172392 struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
21182393 snd_mask_any(&m);
2119
- for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
2394
+ pcm_for_each_format(k) {
21202395 int bits;
2121
- if (! snd_mask_test(mask, k))
2396
+ if (!snd_mask_test_format(mask, k))
21222397 continue;
21232398 bits = snd_pcm_format_physical_width(k);
21242399 if (bits <= 0)
21252400 continue; /* ignore invalid formats */
21262401 if ((unsigned)bits < i->min || (unsigned)bits > i->max)
2127
- snd_mask_reset(&m, k);
2402
+ snd_mask_reset(&m, (__force unsigned)k);
21282403 }
21292404 return snd_mask_refine(mask, &m);
21302405 }
....@@ -2133,14 +2408,15 @@
21332408 struct snd_pcm_hw_rule *rule)
21342409 {
21352410 struct snd_interval t;
2136
- unsigned int k;
2411
+ snd_pcm_format_t k;
2412
+
21372413 t.min = UINT_MAX;
21382414 t.max = 0;
21392415 t.openmin = 0;
21402416 t.openmax = 0;
2141
- for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
2417
+ pcm_for_each_format(k) {
21422418 int bits;
2143
- if (! snd_mask_test(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k))
2419
+ if (!snd_mask_test_format(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k))
21442420 continue;
21452421 bits = snd_pcm_format_physical_width(k);
21462422 if (bits <= 0)
....@@ -2190,7 +2466,7 @@
21902466 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
21912467 }
21922468
2193
-int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
2469
+static int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
21942470 {
21952471 struct snd_pcm_runtime *runtime = substream->runtime;
21962472 struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
....@@ -2314,7 +2590,7 @@
23142590 return 0;
23152591 }
23162592
2317
-int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
2593
+static int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
23182594 {
23192595 struct snd_pcm_runtime *runtime = substream->runtime;
23202596 struct snd_pcm_hardware *hw = &runtime->hw;
....@@ -2322,16 +2598,16 @@
23222598 unsigned int mask = 0;
23232599
23242600 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
2325
- mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED;
2601
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_RW_INTERLEAVED);
23262602 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
2327
- mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;
2603
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
23282604 if (hw_support_mmap(substream)) {
23292605 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
2330
- mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;
2606
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
23312607 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
2332
- mask |= 1 << SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED;
2608
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED);
23332609 if (hw->info & SNDRV_PCM_INFO_COMPLEX)
2334
- mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX;
2610
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_COMPLEX);
23352611 }
23362612 err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask);
23372613 if (err < 0)
....@@ -2341,7 +2617,8 @@
23412617 if (err < 0)
23422618 return err;
23432619
2344
- err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD);
2620
+ err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT,
2621
+ PARAM_MASK_BIT(SNDRV_PCM_SUBFORMAT_STD));
23452622 if (err < 0)
23462623 return err;
23472624
....@@ -2411,14 +2688,13 @@
24112688
24122689 snd_pcm_drop(substream);
24132690 if (substream->hw_opened) {
2414
- if (substream->ops->hw_free &&
2415
- substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
2416
- substream->ops->hw_free(substream);
2691
+ if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
2692
+ do_hw_free(substream);
24172693 substream->ops->close(substream);
24182694 substream->hw_opened = 0;
24192695 }
2420
- if (pm_qos_request_active(&substream->latency_pm_qos_req))
2421
- pm_qos_remove_request(&substream->latency_pm_qos_req);
2696
+ if (cpu_latency_qos_request_active(&substream->latency_pm_qos_req))
2697
+ cpu_latency_qos_remove_request(&substream->latency_pm_qos_req);
24222698 if (substream->pcm_release) {
24232699 substream->pcm_release(substream);
24242700 substream->pcm_release = NULL;
....@@ -2486,10 +2762,8 @@
24862762 return -ENOMEM;
24872763 }
24882764 pcm_file->substream = substream;
2489
- if (substream->ref_count == 1) {
2490
- substream->file = pcm_file;
2765
+ if (substream->ref_count == 1)
24912766 substream->pcm_release = pcm_release_private;
2492
- }
24932767 file->private_data = pcm_file;
24942768
24952769 return 0;
....@@ -2610,7 +2884,7 @@
26102884 case SNDRV_PCM_STATE_DRAINING:
26112885 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
26122886 return -EBADFD;
2613
- /* Fall through */
2887
+ fallthrough;
26142888 case SNDRV_PCM_STATE_RUNNING:
26152889 return snd_pcm_update_hw_ptr(substream);
26162890 case SNDRV_PCM_STATE_PREPARED:
....@@ -2738,7 +3012,6 @@
27383012 volatile struct snd_pcm_mmap_status *status;
27393013 volatile struct snd_pcm_mmap_control *control;
27403014 int err;
2741
- snd_pcm_uframes_t hw_avail;
27423015
27433016 memset(&sync_ptr, 0, sizeof(sync_ptr));
27443017 if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
....@@ -2767,16 +3040,6 @@
27673040 control->avail_min = sync_ptr.c.control.avail_min;
27683041 else
27693042 sync_ptr.c.control.avail_min = control->avail_min;
2770
-
2771
- if (runtime->render_flag & SNDRV_NON_DMA_MODE) {
2772
- hw_avail = snd_pcm_playback_hw_avail(runtime);
2773
- if ((hw_avail >= runtime->start_threshold)
2774
- && (runtime->render_flag &
2775
- SNDRV_RENDER_STOPPED)) {
2776
- if (substream->ops->restart)
2777
- substream->ops->restart(substream);
2778
- }
2779
- }
27803043 sync_ptr.s.status.state = status->state;
27813044 sync_ptr.s.status.hw_ptr = status->hw_ptr;
27823045 sync_ptr.s.status.tstamp = status->tstamp;
....@@ -2787,6 +3050,112 @@
27873050 return -EFAULT;
27883051 return 0;
27893052 }
3053
+
3054
+struct snd_pcm_mmap_status32 {
3055
+ snd_pcm_state_t state;
3056
+ s32 pad1;
3057
+ u32 hw_ptr;
3058
+ s32 tstamp_sec;
3059
+ s32 tstamp_nsec;
3060
+ snd_pcm_state_t suspended_state;
3061
+ s32 audio_tstamp_sec;
3062
+ s32 audio_tstamp_nsec;
3063
+} __attribute__((packed));
3064
+
3065
+struct snd_pcm_mmap_control32 {
3066
+ u32 appl_ptr;
3067
+ u32 avail_min;
3068
+};
3069
+
3070
+struct snd_pcm_sync_ptr32 {
3071
+ u32 flags;
3072
+ union {
3073
+ struct snd_pcm_mmap_status32 status;
3074
+ unsigned char reserved[64];
3075
+ } s;
3076
+ union {
3077
+ struct snd_pcm_mmap_control32 control;
3078
+ unsigned char reserved[64];
3079
+ } c;
3080
+} __attribute__((packed));
3081
+
3082
+/* recalcuate the boundary within 32bit */
3083
+static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime)
3084
+{
3085
+ snd_pcm_uframes_t boundary;
3086
+
3087
+ if (! runtime->buffer_size)
3088
+ return 0;
3089
+ boundary = runtime->buffer_size;
3090
+ while (boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
3091
+ boundary *= 2;
3092
+ return boundary;
3093
+}
3094
+
3095
+static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
3096
+ struct snd_pcm_sync_ptr32 __user *src)
3097
+{
3098
+ struct snd_pcm_runtime *runtime = substream->runtime;
3099
+ volatile struct snd_pcm_mmap_status *status;
3100
+ volatile struct snd_pcm_mmap_control *control;
3101
+ u32 sflags;
3102
+ struct snd_pcm_mmap_control scontrol;
3103
+ struct snd_pcm_mmap_status sstatus;
3104
+ snd_pcm_uframes_t boundary;
3105
+ int err;
3106
+
3107
+ if (snd_BUG_ON(!runtime))
3108
+ return -EINVAL;
3109
+
3110
+ if (get_user(sflags, &src->flags) ||
3111
+ get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
3112
+ get_user(scontrol.avail_min, &src->c.control.avail_min))
3113
+ return -EFAULT;
3114
+ if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
3115
+ err = snd_pcm_hwsync(substream);
3116
+ if (err < 0)
3117
+ return err;
3118
+ }
3119
+ status = runtime->status;
3120
+ control = runtime->control;
3121
+ boundary = recalculate_boundary(runtime);
3122
+ if (! boundary)
3123
+ boundary = 0x7fffffff;
3124
+ snd_pcm_stream_lock_irq(substream);
3125
+ /* FIXME: we should consider the boundary for the sync from app */
3126
+ if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL)) {
3127
+ err = pcm_lib_apply_appl_ptr(substream,
3128
+ scontrol.appl_ptr);
3129
+ if (err < 0) {
3130
+ snd_pcm_stream_unlock_irq(substream);
3131
+ return err;
3132
+ }
3133
+ } else
3134
+ scontrol.appl_ptr = control->appl_ptr % boundary;
3135
+ if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
3136
+ control->avail_min = scontrol.avail_min;
3137
+ else
3138
+ scontrol.avail_min = control->avail_min;
3139
+ sstatus.state = status->state;
3140
+ sstatus.hw_ptr = status->hw_ptr % boundary;
3141
+ sstatus.tstamp = status->tstamp;
3142
+ sstatus.suspended_state = status->suspended_state;
3143
+ sstatus.audio_tstamp = status->audio_tstamp;
3144
+ snd_pcm_stream_unlock_irq(substream);
3145
+ if (put_user(sstatus.state, &src->s.status.state) ||
3146
+ put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
3147
+ put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
3148
+ put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp_nsec) ||
3149
+ put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
3150
+ put_user(sstatus.audio_tstamp.tv_sec, &src->s.status.audio_tstamp_sec) ||
3151
+ put_user(sstatus.audio_tstamp.tv_nsec, &src->s.status.audio_tstamp_nsec) ||
3152
+ put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
3153
+ put_user(scontrol.avail_min, &src->c.control.avail_min))
3154
+ return -EFAULT;
3155
+
3156
+ return 0;
3157
+}
3158
+#define __SNDRV_PCM_IOCTL_SYNC_PTR32 _IOWR('A', 0x23, struct snd_pcm_sync_ptr32)
27903159
27913160 static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
27923161 {
....@@ -2818,7 +3187,8 @@
28183187 result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
28193188 else
28203189 result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames);
2821
- __put_user(result, &_xferi->result);
3190
+ if (put_user(result, &_xferi->result))
3191
+ return -EFAULT;
28223192 return result < 0 ? result : 0;
28233193 }
28243194
....@@ -2847,7 +3217,8 @@
28473217 else
28483218 result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
28493219 kfree(bufs);
2850
- __put_user(result, &_xfern->result);
3220
+ if (put_user(result, &_xfern->result))
3221
+ return -EFAULT;
28513222 return result < 0 ? result : 0;
28523223 }
28533224
....@@ -2862,7 +3233,8 @@
28623233 if (put_user(0, _frames))
28633234 return -EFAULT;
28643235 result = snd_pcm_rewind(substream, frames);
2865
- __put_user(result, _frames);
3236
+ if (put_user(result, _frames))
3237
+ return -EFAULT;
28663238 return result < 0 ? result : 0;
28673239 }
28683240
....@@ -2877,7 +3249,8 @@
28773249 if (put_user(0, _frames))
28783250 return -EFAULT;
28793251 result = snd_pcm_forward(substream, frames);
2880
- __put_user(result, _frames);
3252
+ if (put_user(result, _frames))
3253
+ return -EFAULT;
28813254 return result < 0 ? result : 0;
28823255 }
28833256
....@@ -2917,10 +3290,14 @@
29173290 return snd_pcm_hw_free(substream);
29183291 case SNDRV_PCM_IOCTL_SW_PARAMS:
29193292 return snd_pcm_sw_params_user(substream, arg);
2920
- case SNDRV_PCM_IOCTL_STATUS:
2921
- return snd_pcm_status_user(substream, arg, false);
2922
- case SNDRV_PCM_IOCTL_STATUS_EXT:
2923
- return snd_pcm_status_user(substream, arg, true);
3293
+ case SNDRV_PCM_IOCTL_STATUS32:
3294
+ return snd_pcm_status_user32(substream, arg, false);
3295
+ case SNDRV_PCM_IOCTL_STATUS_EXT32:
3296
+ return snd_pcm_status_user32(substream, arg, true);
3297
+ case SNDRV_PCM_IOCTL_STATUS64:
3298
+ return snd_pcm_status_user64(substream, arg, false);
3299
+ case SNDRV_PCM_IOCTL_STATUS_EXT64:
3300
+ return snd_pcm_status_user64(substream, arg, true);
29243301 case SNDRV_PCM_IOCTL_CHANNEL_INFO:
29253302 return snd_pcm_channel_info_user(substream, arg);
29263303 case SNDRV_PCM_IOCTL_PREPARE:
....@@ -2952,7 +3329,9 @@
29523329 return -EFAULT;
29533330 return 0;
29543331 }
2955
- case SNDRV_PCM_IOCTL_SYNC_PTR:
3332
+ case __SNDRV_PCM_IOCTL_SYNC_PTR32:
3333
+ return snd_pcm_ioctl_sync_ptr_compat(substream, arg);
3334
+ case __SNDRV_PCM_IOCTL_SYNC_PTR64:
29563335 return snd_pcm_sync_ptr(substream, arg);
29573336 #ifdef CONFIG_SND_SUPPORT_OLD_API
29583337 case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
....@@ -2965,9 +3344,7 @@
29653344 case SNDRV_PCM_IOCTL_DROP:
29663345 return snd_pcm_drop(substream);
29673346 case SNDRV_PCM_IOCTL_PAUSE:
2968
- return snd_pcm_action_lock_irq(&snd_pcm_action_pause,
2969
- substream,
2970
- (int)(unsigned long)arg);
3347
+ return snd_pcm_pause_lock_irq(substream, (unsigned long)arg);
29713348 case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
29723349 case SNDRV_PCM_IOCTL_READI_FRAMES:
29733350 return snd_pcm_xferi_frames_ioctl(substream, arg);
....@@ -3290,8 +3667,6 @@
32903667
32913668 static bool pcm_status_mmap_allowed(struct snd_pcm_file *pcm_file)
32923669 {
3293
- if (pcm_file->no_compat_mmap)
3294
- return false;
32953670 /* See pcm_control_mmap_allowed() below.
32963671 * Since older alsa-lib requires both status and control mmaps to be
32973672 * coupled, we have to disable the status mmap for old alsa-lib, too.
....@@ -3338,7 +3713,18 @@
33383713 snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
33393714 {
33403715 void *vaddr = substream->runtime->dma_area + ofs;
3341
- return virt_to_page(vaddr);
3716
+
3717
+ switch (substream->dma_buffer.dev.type) {
3718
+#ifdef CONFIG_SND_DMA_SGBUF
3719
+ case SNDRV_DMA_TYPE_DEV_SG:
3720
+ case SNDRV_DMA_TYPE_DEV_UC_SG:
3721
+ return snd_pcm_sgbuf_ops_page(substream, ofs);
3722
+#endif /* CONFIG_SND_DMA_SGBUF */
3723
+ case SNDRV_DMA_TYPE_VMALLOC:
3724
+ return vmalloc_to_page(vaddr);
3725
+ default:
3726
+ return virt_to_page(vaddr);
3727
+ }
33423728 }
33433729
33443730 /*
....@@ -3405,15 +3791,14 @@
34053791 area->vm_end - area->vm_start, area->vm_page_prot);
34063792 }
34073793 #endif /* CONFIG_GENERIC_ALLOCATOR */
3408
-#ifndef CONFIG_X86 /* for avoiding warnings arch/x86/mm/pat.c */
34093794 if (IS_ENABLED(CONFIG_HAS_DMA) && !substream->ops->page &&
3410
- substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3795
+ (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV ||
3796
+ substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_UC))
34113797 return dma_mmap_coherent(substream->dma_buffer.dev.dev,
34123798 area,
34133799 substream->runtime->dma_area,
34143800 substream->runtime->dma_addr,
34153801 substream->runtime->dma_bytes);
3416
-#endif /* CONFIG_X86 */
34173802 /* mmap with fault handler */
34183803 area->vm_ops = &snd_pcm_vm_ops_data_fault;
34193804 return 0;
....@@ -3504,11 +3889,19 @@
35043889
35053890 offset = area->vm_pgoff << PAGE_SHIFT;
35063891 switch (offset) {
3507
- case SNDRV_PCM_MMAP_OFFSET_STATUS:
3892
+ case SNDRV_PCM_MMAP_OFFSET_STATUS_OLD:
3893
+ if (pcm_file->no_compat_mmap || !IS_ENABLED(CONFIG_64BIT))
3894
+ return -ENXIO;
3895
+ fallthrough;
3896
+ case SNDRV_PCM_MMAP_OFFSET_STATUS_NEW:
35083897 if (!pcm_status_mmap_allowed(pcm_file))
35093898 return -ENXIO;
35103899 return snd_pcm_mmap_status(substream, file, area);
3511
- case SNDRV_PCM_MMAP_OFFSET_CONTROL:
3900
+ case SNDRV_PCM_MMAP_OFFSET_CONTROL_OLD:
3901
+ if (pcm_file->no_compat_mmap || !IS_ENABLED(CONFIG_64BIT))
3902
+ return -ENXIO;
3903
+ fallthrough;
3904
+ case SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW:
35123905 if (!pcm_control_mmap_allowed(pcm_file))
35133906 return -ENXIO;
35143907 return snd_pcm_mmap_control(substream, file, area);
....@@ -3668,9 +4061,9 @@
36684061 unsigned long offset = pgoff << PAGE_SHIFT;
36694062
36704063 switch (offset) {
3671
- case SNDRV_PCM_MMAP_OFFSET_STATUS:
4064
+ case SNDRV_PCM_MMAP_OFFSET_STATUS_NEW:
36724065 return (unsigned long)runtime->status;
3673
- case SNDRV_PCM_MMAP_OFFSET_CONTROL:
4066
+ case SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW:
36744067 return (unsigned long)runtime->control;
36754068 default:
36764069 return (unsigned long)runtime->dma_area + offset;