hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
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,23 @@
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 {
12251416 if (substream->runtime->trigger_master == substream)
12261417 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
12271418 }
12281419
1229
-static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
1420
+static void snd_pcm_post_start(struct snd_pcm_substream *substream,
1421
+ snd_pcm_state_t state)
12301422 {
12311423 struct snd_pcm_runtime *runtime = substream->runtime;
12321424 snd_pcm_trigger_tstamp(substream);
....@@ -1270,7 +1462,8 @@
12701462 /*
12711463 * stop callbacks
12721464 */
1273
-static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state)
1465
+static int snd_pcm_pre_stop(struct snd_pcm_substream *substream,
1466
+ snd_pcm_state_t state)
12741467 {
12751468 struct snd_pcm_runtime *runtime = substream->runtime;
12761469 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
....@@ -1279,15 +1472,19 @@
12791472 return 0;
12801473 }
12811474
1282
-static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state)
1475
+static int snd_pcm_do_stop(struct snd_pcm_substream *substream,
1476
+ snd_pcm_state_t state)
12831477 {
12841478 if (substream->runtime->trigger_master == substream &&
1285
- snd_pcm_running(substream))
1479
+ snd_pcm_running(substream)) {
12861480 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
1481
+ substream->runtime->stop_operating = true;
1482
+ }
12871483 return 0; /* unconditonally stop all substreams */
12881484 }
12891485
1290
-static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
1486
+static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
1487
+ snd_pcm_state_t state)
12911488 {
12921489 struct snd_pcm_runtime *runtime = substream->runtime;
12931490 if (runtime->status->state != state) {
....@@ -1357,14 +1554,17 @@
13571554 EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun);
13581555
13591556 /*
1360
- * pause callbacks
1557
+ * pause callbacks: pass boolean (to start pause or resume) as state argument
13611558 */
1362
-static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push)
1559
+#define pause_pushed(state) (__force bool)(state)
1560
+
1561
+static int snd_pcm_pre_pause(struct snd_pcm_substream *substream,
1562
+ snd_pcm_state_t state)
13631563 {
13641564 struct snd_pcm_runtime *runtime = substream->runtime;
13651565 if (!(runtime->info & SNDRV_PCM_INFO_PAUSE))
13661566 return -ENOSYS;
1367
- if (push) {
1567
+ if (pause_pushed(state)) {
13681568 if (runtime->status->state != SNDRV_PCM_STATE_RUNNING)
13691569 return -EBADFD;
13701570 } else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED)
....@@ -1373,13 +1573,14 @@
13731573 return 0;
13741574 }
13751575
1376
-static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
1576
+static int snd_pcm_do_pause(struct snd_pcm_substream *substream,
1577
+ snd_pcm_state_t state)
13771578 {
13781579 if (substream->runtime->trigger_master != substream)
13791580 return 0;
13801581 /* some drivers might use hw_ptr to recover from the pause -
13811582 update the hw_ptr now */
1382
- if (push)
1583
+ if (pause_pushed(state))
13831584 snd_pcm_update_hw_ptr(substream);
13841585 /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
13851586 * a delta between the current jiffies, this gives a large enough
....@@ -1387,23 +1588,27 @@
13871588 */
13881589 substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
13891590 return substream->ops->trigger(substream,
1390
- push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH :
1391
- SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
1591
+ pause_pushed(state) ?
1592
+ SNDRV_PCM_TRIGGER_PAUSE_PUSH :
1593
+ SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
13921594 }
13931595
1394
-static void snd_pcm_undo_pause(struct snd_pcm_substream *substream, int push)
1596
+static void snd_pcm_undo_pause(struct snd_pcm_substream *substream,
1597
+ snd_pcm_state_t state)
13951598 {
13961599 if (substream->runtime->trigger_master == substream)
13971600 substream->ops->trigger(substream,
1398
- push ? SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
1601
+ pause_pushed(state) ?
1602
+ SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
13991603 SNDRV_PCM_TRIGGER_PAUSE_PUSH);
14001604 }
14011605
1402
-static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1606
+static void snd_pcm_post_pause(struct snd_pcm_substream *substream,
1607
+ snd_pcm_state_t state)
14031608 {
14041609 struct snd_pcm_runtime *runtime = substream->runtime;
14051610 snd_pcm_trigger_tstamp(substream);
1406
- if (push) {
1611
+ if (pause_pushed(state)) {
14071612 runtime->status->state = SNDRV_PCM_STATE_PAUSED;
14081613 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE);
14091614 wake_up(&runtime->sleep);
....@@ -1424,15 +1629,24 @@
14241629 /*
14251630 * Push/release the pause for all linked streams.
14261631 */
1427
-static int snd_pcm_pause(struct snd_pcm_substream *substream, int push)
1632
+static int snd_pcm_pause(struct snd_pcm_substream *substream, bool push)
14281633 {
1429
- return snd_pcm_action(&snd_pcm_action_pause, substream, push);
1634
+ return snd_pcm_action(&snd_pcm_action_pause, substream,
1635
+ (__force snd_pcm_state_t)push);
1636
+}
1637
+
1638
+static int snd_pcm_pause_lock_irq(struct snd_pcm_substream *substream,
1639
+ bool push)
1640
+{
1641
+ return snd_pcm_action_lock_irq(&snd_pcm_action_pause, substream,
1642
+ (__force snd_pcm_state_t)push);
14301643 }
14311644
14321645 #ifdef CONFIG_PM
1433
-/* suspend */
1646
+/* suspend callback: state argument ignored */
14341647
1435
-static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state)
1648
+static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream,
1649
+ snd_pcm_state_t state)
14361650 {
14371651 struct snd_pcm_runtime *runtime = substream->runtime;
14381652 switch (runtime->status->state) {
....@@ -1448,7 +1662,8 @@
14481662 return 0;
14491663 }
14501664
1451
-static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state)
1665
+static int snd_pcm_do_suspend(struct snd_pcm_substream *substream,
1666
+ snd_pcm_state_t state)
14521667 {
14531668 struct snd_pcm_runtime *runtime = substream->runtime;
14541669 if (runtime->trigger_master != substream)
....@@ -1456,10 +1671,12 @@
14561671 if (! snd_pcm_running(substream))
14571672 return 0;
14581673 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
1674
+ runtime->stop_operating = true;
14591675 return 0; /* suspend unconditionally */
14601676 }
14611677
1462
-static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1678
+static void snd_pcm_post_suspend(struct snd_pcm_substream *substream,
1679
+ snd_pcm_state_t state)
14631680 {
14641681 struct snd_pcm_runtime *runtime = substream->runtime;
14651682 snd_pcm_trigger_tstamp(substream);
....@@ -1476,29 +1693,25 @@
14761693 .post_action = snd_pcm_post_suspend
14771694 };
14781695
1479
-/**
1696
+/*
14801697 * snd_pcm_suspend - trigger SUSPEND to all linked streams
14811698 * @substream: the PCM substream
14821699 *
14831700 * After this call, all streams are changed to SUSPENDED state.
14841701 *
1485
- * Return: Zero if successful (or @substream is %NULL), or a negative error
1486
- * code.
1702
+ * Return: Zero if successful, or a negative error code.
14871703 */
1488
-int snd_pcm_suspend(struct snd_pcm_substream *substream)
1704
+static int snd_pcm_suspend(struct snd_pcm_substream *substream)
14891705 {
14901706 int err;
14911707 unsigned long flags;
14921708
1493
- if (! substream)
1494
- return 0;
1495
-
14961709 snd_pcm_stream_lock_irqsave(substream, flags);
1497
- err = snd_pcm_action(&snd_pcm_action_suspend, substream, 0);
1710
+ err = snd_pcm_action(&snd_pcm_action_suspend, substream,
1711
+ ACTION_ARG_IGNORE);
14981712 snd_pcm_stream_unlock_irqrestore(substream, flags);
14991713 return err;
15001714 }
1501
-EXPORT_SYMBOL(snd_pcm_suspend);
15021715
15031716 /**
15041717 * snd_pcm_suspend_all - trigger SUSPEND to all substreams in the given pcm
....@@ -1535,13 +1748,20 @@
15351748 return err;
15361749 }
15371750 }
1751
+
1752
+ for (stream = 0; stream < 2; stream++)
1753
+ for (substream = pcm->streams[stream].substream;
1754
+ substream; substream = substream->next)
1755
+ snd_pcm_sync_stop(substream, false);
1756
+
15381757 return 0;
15391758 }
15401759 EXPORT_SYMBOL(snd_pcm_suspend_all);
15411760
1542
-/* resume */
1761
+/* resume callbacks: state argument ignored */
15431762
1544
-static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
1763
+static int snd_pcm_pre_resume(struct snd_pcm_substream *substream,
1764
+ snd_pcm_state_t state)
15451765 {
15461766 struct snd_pcm_runtime *runtime = substream->runtime;
15471767 if (!(runtime->info & SNDRV_PCM_INFO_RESUME))
....@@ -1550,7 +1770,8 @@
15501770 return 0;
15511771 }
15521772
1553
-static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state)
1773
+static int snd_pcm_do_resume(struct snd_pcm_substream *substream,
1774
+ snd_pcm_state_t state)
15541775 {
15551776 struct snd_pcm_runtime *runtime = substream->runtime;
15561777 if (runtime->trigger_master != substream)
....@@ -1563,14 +1784,16 @@
15631784 return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
15641785 }
15651786
1566
-static void snd_pcm_undo_resume(struct snd_pcm_substream *substream, int state)
1787
+static void snd_pcm_undo_resume(struct snd_pcm_substream *substream,
1788
+ snd_pcm_state_t state)
15671789 {
15681790 if (substream->runtime->trigger_master == substream &&
15691791 snd_pcm_running(substream))
15701792 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
15711793 }
15721794
1573
-static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
1795
+static void snd_pcm_post_resume(struct snd_pcm_substream *substream,
1796
+ snd_pcm_state_t state)
15741797 {
15751798 struct snd_pcm_runtime *runtime = substream->runtime;
15761799 snd_pcm_trigger_tstamp(substream);
....@@ -1587,7 +1810,8 @@
15871810
15881811 static int snd_pcm_resume(struct snd_pcm_substream *substream)
15891812 {
1590
- return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0);
1813
+ return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream,
1814
+ ACTION_ARG_IGNORE);
15911815 }
15921816
15931817 #else
....@@ -1628,7 +1852,9 @@
16281852 /*
16291853 * reset ioctl
16301854 */
1631
-static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state)
1855
+/* reset callbacks: state argument ignored */
1856
+static int snd_pcm_pre_reset(struct snd_pcm_substream *substream,
1857
+ snd_pcm_state_t state)
16321858 {
16331859 struct snd_pcm_runtime *runtime = substream->runtime;
16341860 switch (runtime->status->state) {
....@@ -1642,27 +1868,33 @@
16421868 }
16431869 }
16441870
1645
-static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
1871
+static int snd_pcm_do_reset(struct snd_pcm_substream *substream,
1872
+ snd_pcm_state_t state)
16461873 {
16471874 struct snd_pcm_runtime *runtime = substream->runtime;
1648
- int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
1875
+ int err = snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
16491876 if (err < 0)
16501877 return err;
1878
+ snd_pcm_stream_lock_irq(substream);
16511879 runtime->hw_ptr_base = 0;
16521880 runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
16531881 runtime->status->hw_ptr % runtime->period_size;
16541882 runtime->silence_start = runtime->status->hw_ptr;
16551883 runtime->silence_filled = 0;
1884
+ snd_pcm_stream_unlock_irq(substream);
16561885 return 0;
16571886 }
16581887
1659
-static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state)
1888
+static void snd_pcm_post_reset(struct snd_pcm_substream *substream,
1889
+ snd_pcm_state_t state)
16601890 {
16611891 struct snd_pcm_runtime *runtime = substream->runtime;
1892
+ snd_pcm_stream_lock_irq(substream);
16621893 runtime->control->appl_ptr = runtime->status->hw_ptr;
16631894 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
16641895 runtime->silence_size > 0)
16651896 snd_pcm_playback_silence(substream, ULONG_MAX);
1897
+ snd_pcm_stream_unlock_irq(substream);
16661898 }
16671899
16681900 static const struct action_ops snd_pcm_action_reset = {
....@@ -1673,17 +1905,20 @@
16731905
16741906 static int snd_pcm_reset(struct snd_pcm_substream *substream)
16751907 {
1676
- return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream, 0);
1908
+ return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream,
1909
+ ACTION_ARG_IGNORE);
16771910 }
16781911
16791912 /*
16801913 * prepare ioctl
16811914 */
1682
-/* we use the second argument for updating f_flags */
1915
+/* pass f_flags as state argument */
16831916 static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
1684
- int f_flags)
1917
+ snd_pcm_state_t state)
16851918 {
16861919 struct snd_pcm_runtime *runtime = substream->runtime;
1920
+ int f_flags = (__force int)state;
1921
+
16871922 if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
16881923 runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
16891924 return -EBADFD;
....@@ -1693,16 +1928,19 @@
16931928 return 0;
16941929 }
16951930
1696
-static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, int state)
1931
+static int snd_pcm_do_prepare(struct snd_pcm_substream *substream,
1932
+ snd_pcm_state_t state)
16971933 {
16981934 int err;
1935
+ snd_pcm_sync_stop(substream, true);
16991936 err = substream->ops->prepare(substream);
17001937 if (err < 0)
17011938 return err;
1702
- return snd_pcm_do_reset(substream, 0);
1939
+ return snd_pcm_do_reset(substream, state);
17031940 }
17041941
1705
-static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state)
1942
+static void snd_pcm_post_prepare(struct snd_pcm_substream *substream,
1943
+ snd_pcm_state_t state)
17061944 {
17071945 struct snd_pcm_runtime *runtime = substream->runtime;
17081946 runtime->control->appl_ptr = runtime->status->hw_ptr;
....@@ -1735,8 +1973,8 @@
17351973 snd_pcm_stream_lock_irq(substream);
17361974 switch (substream->runtime->status->state) {
17371975 case SNDRV_PCM_STATE_PAUSED:
1738
- snd_pcm_pause(substream, 0);
1739
- /* fallthru */
1976
+ snd_pcm_pause(substream, false);
1977
+ fallthrough;
17401978 case SNDRV_PCM_STATE_SUSPENDED:
17411979 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
17421980 break;
....@@ -1744,14 +1982,17 @@
17441982 snd_pcm_stream_unlock_irq(substream);
17451983
17461984 return snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
1747
- substream, f_flags);
1985
+ substream,
1986
+ (__force snd_pcm_state_t)f_flags);
17481987 }
17491988
17501989 /*
17511990 * drain ioctl
17521991 */
17531992
1754
-static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
1993
+/* drain init callbacks: state argument ignored */
1994
+static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream,
1995
+ snd_pcm_state_t state)
17551996 {
17561997 struct snd_pcm_runtime *runtime = substream->runtime;
17571998 switch (runtime->status->state) {
....@@ -1764,7 +2005,8 @@
17642005 return 0;
17652006 }
17662007
1767
-static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
2008
+static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream,
2009
+ snd_pcm_state_t state)
17682010 {
17692011 struct snd_pcm_runtime *runtime = substream->runtime;
17702012 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
....@@ -1790,7 +2032,9 @@
17902032 } else {
17912033 /* stop running stream */
17922034 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
1793
- int new_state = snd_pcm_capture_avail(runtime) > 0 ?
2035
+ snd_pcm_state_t new_state;
2036
+
2037
+ new_state = snd_pcm_capture_avail(runtime) > 0 ?
17942038 SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP;
17952039 snd_pcm_do_stop(substream, new_state);
17962040 snd_pcm_post_stop(substream, new_state);
....@@ -1806,7 +2050,8 @@
18062050 return 0;
18072051 }
18082052
1809
-static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int state)
2053
+static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream,
2054
+ snd_pcm_state_t state)
18102055 {
18112056 }
18122057
....@@ -1815,8 +2060,6 @@
18152060 .do_action = snd_pcm_do_drain_init,
18162061 .post_action = snd_pcm_post_drain_init
18172062 };
1818
-
1819
-static int snd_pcm_drop(struct snd_pcm_substream *substream);
18202063
18212064 /*
18222065 * Drain the stream(s).
....@@ -1831,6 +2074,7 @@
18312074 struct snd_card *card;
18322075 struct snd_pcm_runtime *runtime;
18332076 struct snd_pcm_substream *s;
2077
+ struct snd_pcm_group *group;
18342078 wait_queue_entry_t wait;
18352079 int result = 0;
18362080 int nonblock = 0;
....@@ -1847,14 +2091,14 @@
18472091 } else if (substream->f_flags & O_NONBLOCK)
18482092 nonblock = 1;
18492093
1850
- down_read(&snd_pcm_link_rwsem);
18512094 snd_pcm_stream_lock_irq(substream);
18522095 /* resume pause */
18532096 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
1854
- snd_pcm_pause(substream, 0);
2097
+ snd_pcm_pause(substream, false);
18552098
18562099 /* pre-start/stop - all running streams are changed to DRAINING state */
1857
- result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
2100
+ result = snd_pcm_action(&snd_pcm_action_drain_init, substream,
2101
+ ACTION_ARG_IGNORE);
18582102 if (result < 0)
18592103 goto unlock;
18602104 /* in non-blocking, we don't wait in ioctl but let caller poll */
....@@ -1872,6 +2116,7 @@
18722116 }
18732117 /* find a substream to drain */
18742118 to_check = NULL;
2119
+ group = snd_pcm_stream_group_ref(substream);
18752120 snd_pcm_group_for_each_entry(s, substream) {
18762121 if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
18772122 continue;
....@@ -1881,12 +2126,13 @@
18812126 break;
18822127 }
18832128 }
2129
+ snd_pcm_group_unref(group, substream);
18842130 if (!to_check)
18852131 break; /* all drained */
18862132 init_waitqueue_entry(&wait, current);
2133
+ set_current_state(TASK_INTERRUPTIBLE);
18872134 add_wait_queue(&to_check->sleep, &wait);
18882135 snd_pcm_stream_unlock_irq(substream);
1889
- up_read(&snd_pcm_link_rwsem);
18902136 if (runtime->no_period_wakeup)
18912137 tout = MAX_SCHEDULE_TIMEOUT;
18922138 else {
....@@ -1897,10 +2143,18 @@
18972143 }
18982144 tout = msecs_to_jiffies(tout * 1000);
18992145 }
1900
- tout = schedule_timeout_interruptible(tout);
1901
- down_read(&snd_pcm_link_rwsem);
2146
+ tout = schedule_timeout(tout);
2147
+
19022148 snd_pcm_stream_lock_irq(substream);
1903
- remove_wait_queue(&to_check->sleep, &wait);
2149
+ group = snd_pcm_stream_group_ref(substream);
2150
+ snd_pcm_group_for_each_entry(s, substream) {
2151
+ if (s->runtime == to_check) {
2152
+ remove_wait_queue(&to_check->sleep, &wait);
2153
+ break;
2154
+ }
2155
+ }
2156
+ snd_pcm_group_unref(group, substream);
2157
+
19042158 if (card->shutdown) {
19052159 result = -ENODEV;
19062160 break;
....@@ -1920,7 +2174,6 @@
19202174
19212175 unlock:
19222176 snd_pcm_stream_unlock_irq(substream);
1923
- up_read(&snd_pcm_link_rwsem);
19242177
19252178 return result;
19262179 }
....@@ -1946,7 +2199,7 @@
19462199 snd_pcm_stream_lock_irq(substream);
19472200 /* resume pause */
19482201 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
1949
- snd_pcm_pause(substream, 0);
2202
+ snd_pcm_pause(substream, false);
19502203
19512204 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
19522205 /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
....@@ -1959,13 +2212,19 @@
19592212 static bool is_pcm_file(struct file *file)
19602213 {
19612214 struct inode *inode = file_inode(file);
2215
+ struct snd_pcm *pcm;
19622216 unsigned int minor;
19632217
19642218 if (!S_ISCHR(inode->i_mode) || imajor(inode) != snd_major)
19652219 return false;
19662220 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);
2221
+ pcm = snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
2222
+ if (!pcm)
2223
+ pcm = snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
2224
+ if (!pcm)
2225
+ return false;
2226
+ snd_card_unref(pcm->card);
2227
+ return true;
19692228 }
19702229
19712230 /*
....@@ -1976,7 +2235,8 @@
19762235 int res = 0;
19772236 struct snd_pcm_file *pcm_file;
19782237 struct snd_pcm_substream *substream1;
1979
- struct snd_pcm_group *group;
2238
+ struct snd_pcm_group *group, *target_group;
2239
+ bool nonatomic = substream->pcm->nonatomic;
19802240 struct fd f = fdget(fd);
19812241
19822242 if (!f.file)
....@@ -1987,18 +2247,20 @@
19872247 }
19882248 pcm_file = f.file->private_data;
19892249 substream1 = pcm_file->substream;
2250
+
19902251 if (substream == substream1) {
19912252 res = -EINVAL;
19922253 goto _badf;
19932254 }
19942255
1995
- group = kmalloc(sizeof(*group), GFP_KERNEL);
2256
+ group = kzalloc(sizeof(*group), GFP_KERNEL);
19962257 if (!group) {
19972258 res = -ENOMEM;
19982259 goto _nolock;
19992260 }
2000
- down_write_nonfifo(&snd_pcm_link_rwsem);
2001
- write_lock_irq(&snd_pcm_link_rwlock);
2261
+ snd_pcm_group_init(group);
2262
+
2263
+ down_write(&snd_pcm_link_rwsem);
20022264 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
20032265 substream->runtime->status->state != substream1->runtime->status->state ||
20042266 substream->pcm->nonatomic != substream1->pcm->nonatomic) {
....@@ -2009,23 +2271,24 @@
20092271 res = -EALREADY;
20102272 goto _end;
20112273 }
2274
+
2275
+ snd_pcm_stream_lock_irq(substream);
20122276 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;
2277
+ snd_pcm_group_assign(substream, group);
2278
+ group = NULL; /* assigned, don't free this one below */
20202279 }
2021
- list_add_tail(&substream1->link_list, &substream->group->substreams);
2022
- substream->group->count++;
2023
- substream1->group = substream->group;
2280
+ target_group = substream->group;
2281
+ snd_pcm_stream_unlock_irq(substream);
2282
+
2283
+ snd_pcm_group_lock_irq(target_group, nonatomic);
2284
+ snd_pcm_stream_lock_nested(substream1);
2285
+ snd_pcm_group_assign(substream1, target_group);
2286
+ refcount_inc(&target_group->refs);
2287
+ snd_pcm_stream_unlock(substream1);
2288
+ snd_pcm_group_unlock_irq(target_group, nonatomic);
20242289 _end:
2025
- write_unlock_irq(&snd_pcm_link_rwlock);
20262290 up_write(&snd_pcm_link_rwsem);
20272291 _nolock:
2028
- snd_card_unref(substream1->pcm->card);
20292292 kfree(group);
20302293 _badf:
20312294 fdput(f);
....@@ -2034,34 +2297,44 @@
20342297
20352298 static void relink_to_local(struct snd_pcm_substream *substream)
20362299 {
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);
2300
+ snd_pcm_stream_lock_nested(substream);
2301
+ snd_pcm_group_assign(substream, &substream->self_group);
2302
+ snd_pcm_stream_unlock(substream);
20402303 }
20412304
20422305 static int snd_pcm_unlink(struct snd_pcm_substream *substream)
20432306 {
2044
- struct snd_pcm_substream *s;
2307
+ struct snd_pcm_group *group;
2308
+ bool nonatomic = substream->pcm->nonatomic;
2309
+ bool do_free = false;
20452310 int res = 0;
20462311
2047
- down_write_nonfifo(&snd_pcm_link_rwsem);
2048
- write_lock_irq(&snd_pcm_link_rwlock);
2312
+ down_write(&snd_pcm_link_rwsem);
2313
+
20492314 if (!snd_pcm_stream_linked(substream)) {
20502315 res = -EALREADY;
20512316 goto _end;
20522317 }
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
- }
2318
+
2319
+ group = substream->group;
2320
+ snd_pcm_group_lock_irq(group, nonatomic);
2321
+
20622322 relink_to_local(substream);
2323
+ refcount_dec(&group->refs);
2324
+
2325
+ /* detach the last stream, too */
2326
+ if (list_is_singular(&group->substreams)) {
2327
+ relink_to_local(list_first_entry(&group->substreams,
2328
+ struct snd_pcm_substream,
2329
+ link_list));
2330
+ do_free = refcount_dec_and_test(&group->refs);
2331
+ }
2332
+
2333
+ snd_pcm_group_unlock_irq(group, nonatomic);
2334
+ if (do_free)
2335
+ kfree(group);
2336
+
20632337 _end:
2064
- write_unlock_irq(&snd_pcm_link_rwlock);
20652338 up_write(&snd_pcm_link_rwsem);
20662339 return res;
20672340 }
....@@ -2110,21 +2383,21 @@
21102383 static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params,
21112384 struct snd_pcm_hw_rule *rule)
21122385 {
2113
- unsigned int k;
2386
+ snd_pcm_format_t k;
21142387 const struct snd_interval *i =
21152388 hw_param_interval_c(params, rule->deps[0]);
21162389 struct snd_mask m;
21172390 struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
21182391 snd_mask_any(&m);
2119
- for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
2392
+ pcm_for_each_format(k) {
21202393 int bits;
2121
- if (! snd_mask_test(mask, k))
2394
+ if (!snd_mask_test_format(mask, k))
21222395 continue;
21232396 bits = snd_pcm_format_physical_width(k);
21242397 if (bits <= 0)
21252398 continue; /* ignore invalid formats */
21262399 if ((unsigned)bits < i->min || (unsigned)bits > i->max)
2127
- snd_mask_reset(&m, k);
2400
+ snd_mask_reset(&m, (__force unsigned)k);
21282401 }
21292402 return snd_mask_refine(mask, &m);
21302403 }
....@@ -2133,14 +2406,15 @@
21332406 struct snd_pcm_hw_rule *rule)
21342407 {
21352408 struct snd_interval t;
2136
- unsigned int k;
2409
+ snd_pcm_format_t k;
2410
+
21372411 t.min = UINT_MAX;
21382412 t.max = 0;
21392413 t.openmin = 0;
21402414 t.openmax = 0;
2141
- for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
2415
+ pcm_for_each_format(k) {
21422416 int bits;
2143
- if (! snd_mask_test(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k))
2417
+ if (!snd_mask_test_format(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k))
21442418 continue;
21452419 bits = snd_pcm_format_physical_width(k);
21462420 if (bits <= 0)
....@@ -2190,7 +2464,7 @@
21902464 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
21912465 }
21922466
2193
-int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
2467
+static int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
21942468 {
21952469 struct snd_pcm_runtime *runtime = substream->runtime;
21962470 struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
....@@ -2314,7 +2588,7 @@
23142588 return 0;
23152589 }
23162590
2317
-int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
2591
+static int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
23182592 {
23192593 struct snd_pcm_runtime *runtime = substream->runtime;
23202594 struct snd_pcm_hardware *hw = &runtime->hw;
....@@ -2322,16 +2596,16 @@
23222596 unsigned int mask = 0;
23232597
23242598 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
2325
- mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED;
2599
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_RW_INTERLEAVED);
23262600 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
2327
- mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;
2601
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
23282602 if (hw_support_mmap(substream)) {
23292603 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
2330
- mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;
2604
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
23312605 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
2332
- mask |= 1 << SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED;
2606
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED);
23332607 if (hw->info & SNDRV_PCM_INFO_COMPLEX)
2334
- mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX;
2608
+ mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_COMPLEX);
23352609 }
23362610 err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask);
23372611 if (err < 0)
....@@ -2341,7 +2615,8 @@
23412615 if (err < 0)
23422616 return err;
23432617
2344
- err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD);
2618
+ err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT,
2619
+ PARAM_MASK_BIT(SNDRV_PCM_SUBFORMAT_STD));
23452620 if (err < 0)
23462621 return err;
23472622
....@@ -2411,14 +2686,13 @@
24112686
24122687 snd_pcm_drop(substream);
24132688 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);
2689
+ if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
2690
+ do_hw_free(substream);
24172691 substream->ops->close(substream);
24182692 substream->hw_opened = 0;
24192693 }
2420
- if (pm_qos_request_active(&substream->latency_pm_qos_req))
2421
- pm_qos_remove_request(&substream->latency_pm_qos_req);
2694
+ if (cpu_latency_qos_request_active(&substream->latency_pm_qos_req))
2695
+ cpu_latency_qos_remove_request(&substream->latency_pm_qos_req);
24222696 if (substream->pcm_release) {
24232697 substream->pcm_release(substream);
24242698 substream->pcm_release = NULL;
....@@ -2486,10 +2760,8 @@
24862760 return -ENOMEM;
24872761 }
24882762 pcm_file->substream = substream;
2489
- if (substream->ref_count == 1) {
2490
- substream->file = pcm_file;
2763
+ if (substream->ref_count == 1)
24912764 substream->pcm_release = pcm_release_private;
2492
- }
24932765 file->private_data = pcm_file;
24942766
24952767 return 0;
....@@ -2610,7 +2882,7 @@
26102882 case SNDRV_PCM_STATE_DRAINING:
26112883 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
26122884 return -EBADFD;
2613
- /* Fall through */
2885
+ fallthrough;
26142886 case SNDRV_PCM_STATE_RUNNING:
26152887 return snd_pcm_update_hw_ptr(substream);
26162888 case SNDRV_PCM_STATE_PREPARED:
....@@ -2738,7 +3010,6 @@
27383010 volatile struct snd_pcm_mmap_status *status;
27393011 volatile struct snd_pcm_mmap_control *control;
27403012 int err;
2741
- snd_pcm_uframes_t hw_avail;
27423013
27433014 memset(&sync_ptr, 0, sizeof(sync_ptr));
27443015 if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
....@@ -2767,16 +3038,6 @@
27673038 control->avail_min = sync_ptr.c.control.avail_min;
27683039 else
27693040 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
- }
27803041 sync_ptr.s.status.state = status->state;
27813042 sync_ptr.s.status.hw_ptr = status->hw_ptr;
27823043 sync_ptr.s.status.tstamp = status->tstamp;
....@@ -2787,6 +3048,112 @@
27873048 return -EFAULT;
27883049 return 0;
27893050 }
3051
+
3052
+struct snd_pcm_mmap_status32 {
3053
+ snd_pcm_state_t state;
3054
+ s32 pad1;
3055
+ u32 hw_ptr;
3056
+ s32 tstamp_sec;
3057
+ s32 tstamp_nsec;
3058
+ snd_pcm_state_t suspended_state;
3059
+ s32 audio_tstamp_sec;
3060
+ s32 audio_tstamp_nsec;
3061
+} __attribute__((packed));
3062
+
3063
+struct snd_pcm_mmap_control32 {
3064
+ u32 appl_ptr;
3065
+ u32 avail_min;
3066
+};
3067
+
3068
+struct snd_pcm_sync_ptr32 {
3069
+ u32 flags;
3070
+ union {
3071
+ struct snd_pcm_mmap_status32 status;
3072
+ unsigned char reserved[64];
3073
+ } s;
3074
+ union {
3075
+ struct snd_pcm_mmap_control32 control;
3076
+ unsigned char reserved[64];
3077
+ } c;
3078
+} __attribute__((packed));
3079
+
3080
+/* recalcuate the boundary within 32bit */
3081
+static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime)
3082
+{
3083
+ snd_pcm_uframes_t boundary;
3084
+
3085
+ if (! runtime->buffer_size)
3086
+ return 0;
3087
+ boundary = runtime->buffer_size;
3088
+ while (boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
3089
+ boundary *= 2;
3090
+ return boundary;
3091
+}
3092
+
3093
+static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
3094
+ struct snd_pcm_sync_ptr32 __user *src)
3095
+{
3096
+ struct snd_pcm_runtime *runtime = substream->runtime;
3097
+ volatile struct snd_pcm_mmap_status *status;
3098
+ volatile struct snd_pcm_mmap_control *control;
3099
+ u32 sflags;
3100
+ struct snd_pcm_mmap_control scontrol;
3101
+ struct snd_pcm_mmap_status sstatus;
3102
+ snd_pcm_uframes_t boundary;
3103
+ int err;
3104
+
3105
+ if (snd_BUG_ON(!runtime))
3106
+ return -EINVAL;
3107
+
3108
+ if (get_user(sflags, &src->flags) ||
3109
+ get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
3110
+ get_user(scontrol.avail_min, &src->c.control.avail_min))
3111
+ return -EFAULT;
3112
+ if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
3113
+ err = snd_pcm_hwsync(substream);
3114
+ if (err < 0)
3115
+ return err;
3116
+ }
3117
+ status = runtime->status;
3118
+ control = runtime->control;
3119
+ boundary = recalculate_boundary(runtime);
3120
+ if (! boundary)
3121
+ boundary = 0x7fffffff;
3122
+ snd_pcm_stream_lock_irq(substream);
3123
+ /* FIXME: we should consider the boundary for the sync from app */
3124
+ if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL)) {
3125
+ err = pcm_lib_apply_appl_ptr(substream,
3126
+ scontrol.appl_ptr);
3127
+ if (err < 0) {
3128
+ snd_pcm_stream_unlock_irq(substream);
3129
+ return err;
3130
+ }
3131
+ } else
3132
+ scontrol.appl_ptr = control->appl_ptr % boundary;
3133
+ if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
3134
+ control->avail_min = scontrol.avail_min;
3135
+ else
3136
+ scontrol.avail_min = control->avail_min;
3137
+ sstatus.state = status->state;
3138
+ sstatus.hw_ptr = status->hw_ptr % boundary;
3139
+ sstatus.tstamp = status->tstamp;
3140
+ sstatus.suspended_state = status->suspended_state;
3141
+ sstatus.audio_tstamp = status->audio_tstamp;
3142
+ snd_pcm_stream_unlock_irq(substream);
3143
+ if (put_user(sstatus.state, &src->s.status.state) ||
3144
+ put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
3145
+ put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
3146
+ put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp_nsec) ||
3147
+ put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
3148
+ put_user(sstatus.audio_tstamp.tv_sec, &src->s.status.audio_tstamp_sec) ||
3149
+ put_user(sstatus.audio_tstamp.tv_nsec, &src->s.status.audio_tstamp_nsec) ||
3150
+ put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
3151
+ put_user(scontrol.avail_min, &src->c.control.avail_min))
3152
+ return -EFAULT;
3153
+
3154
+ return 0;
3155
+}
3156
+#define __SNDRV_PCM_IOCTL_SYNC_PTR32 _IOWR('A', 0x23, struct snd_pcm_sync_ptr32)
27903157
27913158 static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
27923159 {
....@@ -2818,7 +3185,8 @@
28183185 result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
28193186 else
28203187 result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames);
2821
- __put_user(result, &_xferi->result);
3188
+ if (put_user(result, &_xferi->result))
3189
+ return -EFAULT;
28223190 return result < 0 ? result : 0;
28233191 }
28243192
....@@ -2847,7 +3215,8 @@
28473215 else
28483216 result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
28493217 kfree(bufs);
2850
- __put_user(result, &_xfern->result);
3218
+ if (put_user(result, &_xfern->result))
3219
+ return -EFAULT;
28513220 return result < 0 ? result : 0;
28523221 }
28533222
....@@ -2862,7 +3231,8 @@
28623231 if (put_user(0, _frames))
28633232 return -EFAULT;
28643233 result = snd_pcm_rewind(substream, frames);
2865
- __put_user(result, _frames);
3234
+ if (put_user(result, _frames))
3235
+ return -EFAULT;
28663236 return result < 0 ? result : 0;
28673237 }
28683238
....@@ -2877,7 +3247,8 @@
28773247 if (put_user(0, _frames))
28783248 return -EFAULT;
28793249 result = snd_pcm_forward(substream, frames);
2880
- __put_user(result, _frames);
3250
+ if (put_user(result, _frames))
3251
+ return -EFAULT;
28813252 return result < 0 ? result : 0;
28823253 }
28833254
....@@ -2917,10 +3288,14 @@
29173288 return snd_pcm_hw_free(substream);
29183289 case SNDRV_PCM_IOCTL_SW_PARAMS:
29193290 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);
3291
+ case SNDRV_PCM_IOCTL_STATUS32:
3292
+ return snd_pcm_status_user32(substream, arg, false);
3293
+ case SNDRV_PCM_IOCTL_STATUS_EXT32:
3294
+ return snd_pcm_status_user32(substream, arg, true);
3295
+ case SNDRV_PCM_IOCTL_STATUS64:
3296
+ return snd_pcm_status_user64(substream, arg, false);
3297
+ case SNDRV_PCM_IOCTL_STATUS_EXT64:
3298
+ return snd_pcm_status_user64(substream, arg, true);
29243299 case SNDRV_PCM_IOCTL_CHANNEL_INFO:
29253300 return snd_pcm_channel_info_user(substream, arg);
29263301 case SNDRV_PCM_IOCTL_PREPARE:
....@@ -2952,7 +3327,9 @@
29523327 return -EFAULT;
29533328 return 0;
29543329 }
2955
- case SNDRV_PCM_IOCTL_SYNC_PTR:
3330
+ case __SNDRV_PCM_IOCTL_SYNC_PTR32:
3331
+ return snd_pcm_ioctl_sync_ptr_compat(substream, arg);
3332
+ case __SNDRV_PCM_IOCTL_SYNC_PTR64:
29563333 return snd_pcm_sync_ptr(substream, arg);
29573334 #ifdef CONFIG_SND_SUPPORT_OLD_API
29583335 case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
....@@ -2965,9 +3342,7 @@
29653342 case SNDRV_PCM_IOCTL_DROP:
29663343 return snd_pcm_drop(substream);
29673344 case SNDRV_PCM_IOCTL_PAUSE:
2968
- return snd_pcm_action_lock_irq(&snd_pcm_action_pause,
2969
- substream,
2970
- (int)(unsigned long)arg);
3345
+ return snd_pcm_pause_lock_irq(substream, (unsigned long)arg);
29713346 case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
29723347 case SNDRV_PCM_IOCTL_READI_FRAMES:
29733348 return snd_pcm_xferi_frames_ioctl(substream, arg);
....@@ -3290,8 +3665,6 @@
32903665
32913666 static bool pcm_status_mmap_allowed(struct snd_pcm_file *pcm_file)
32923667 {
3293
- if (pcm_file->no_compat_mmap)
3294
- return false;
32953668 /* See pcm_control_mmap_allowed() below.
32963669 * Since older alsa-lib requires both status and control mmaps to be
32973670 * coupled, we have to disable the status mmap for old alsa-lib, too.
....@@ -3338,7 +3711,18 @@
33383711 snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
33393712 {
33403713 void *vaddr = substream->runtime->dma_area + ofs;
3341
- return virt_to_page(vaddr);
3714
+
3715
+ switch (substream->dma_buffer.dev.type) {
3716
+#ifdef CONFIG_SND_DMA_SGBUF
3717
+ case SNDRV_DMA_TYPE_DEV_SG:
3718
+ case SNDRV_DMA_TYPE_DEV_UC_SG:
3719
+ return snd_pcm_sgbuf_ops_page(substream, ofs);
3720
+#endif /* CONFIG_SND_DMA_SGBUF */
3721
+ case SNDRV_DMA_TYPE_VMALLOC:
3722
+ return vmalloc_to_page(vaddr);
3723
+ default:
3724
+ return virt_to_page(vaddr);
3725
+ }
33423726 }
33433727
33443728 /*
....@@ -3405,15 +3789,14 @@
34053789 area->vm_end - area->vm_start, area->vm_page_prot);
34063790 }
34073791 #endif /* CONFIG_GENERIC_ALLOCATOR */
3408
-#ifndef CONFIG_X86 /* for avoiding warnings arch/x86/mm/pat.c */
34093792 if (IS_ENABLED(CONFIG_HAS_DMA) && !substream->ops->page &&
3410
- substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3793
+ (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV ||
3794
+ substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_UC))
34113795 return dma_mmap_coherent(substream->dma_buffer.dev.dev,
34123796 area,
34133797 substream->runtime->dma_area,
34143798 substream->runtime->dma_addr,
34153799 substream->runtime->dma_bytes);
3416
-#endif /* CONFIG_X86 */
34173800 /* mmap with fault handler */
34183801 area->vm_ops = &snd_pcm_vm_ops_data_fault;
34193802 return 0;
....@@ -3504,11 +3887,19 @@
35043887
35053888 offset = area->vm_pgoff << PAGE_SHIFT;
35063889 switch (offset) {
3507
- case SNDRV_PCM_MMAP_OFFSET_STATUS:
3890
+ case SNDRV_PCM_MMAP_OFFSET_STATUS_OLD:
3891
+ if (pcm_file->no_compat_mmap || !IS_ENABLED(CONFIG_64BIT))
3892
+ return -ENXIO;
3893
+ fallthrough;
3894
+ case SNDRV_PCM_MMAP_OFFSET_STATUS_NEW:
35083895 if (!pcm_status_mmap_allowed(pcm_file))
35093896 return -ENXIO;
35103897 return snd_pcm_mmap_status(substream, file, area);
3511
- case SNDRV_PCM_MMAP_OFFSET_CONTROL:
3898
+ case SNDRV_PCM_MMAP_OFFSET_CONTROL_OLD:
3899
+ if (pcm_file->no_compat_mmap || !IS_ENABLED(CONFIG_64BIT))
3900
+ return -ENXIO;
3901
+ fallthrough;
3902
+ case SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW:
35123903 if (!pcm_control_mmap_allowed(pcm_file))
35133904 return -ENXIO;
35143905 return snd_pcm_mmap_control(substream, file, area);
....@@ -3668,9 +4059,9 @@
36684059 unsigned long offset = pgoff << PAGE_SHIFT;
36694060
36704061 switch (offset) {
3671
- case SNDRV_PCM_MMAP_OFFSET_STATUS:
4062
+ case SNDRV_PCM_MMAP_OFFSET_STATUS_NEW:
36724063 return (unsigned long)runtime->status;
3673
- case SNDRV_PCM_MMAP_OFFSET_CONTROL:
4064
+ case SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW:
36744065 return (unsigned long)runtime->control;
36754066 default:
36764067 return (unsigned long)runtime->dma_area + offset;