aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-04-28 09:13:41 -0400
committerJaroslav Kysela <perex@suse.cz>2006-06-22 15:33:13 -0400
commit0df63e44c3e315ec0fe427ae62558231864108bd (patch)
tree3cff6f5d5fdb7ad047a61c591d891e3ca1bc669e
parentf001c3acf64b8ca18fe40af592629abb261b321e (diff)
[ALSA] Add O_APPEND flag support to PCM
Added O_APPEND flag support to PCM to enable shared substreams among multiple processes. This mechanism is used by dmix and dsnoop plugins. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/asound.h2
-rw-r--r--include/sound/pcm.h5
-rw-r--r--sound/core/oss/pcm_oss.c17
-rw-r--r--sound/core/pcm.c25
-rw-r--r--sound/core/pcm_compat.c4
-rw-r--r--sound/core/pcm_lib.c8
-rw-r--r--sound/core/pcm_native.c81
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
8 files changed, 99 insertions, 45 deletions
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 9cc021c7ee1..41885f48ad9 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -137,7 +137,7 @@ enum {
137 * * 137 * *
138 *****************************************************************************/ 138 *****************************************************************************/
139 139
140#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7) 140#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8)
141 141
142typedef unsigned long snd_pcm_uframes_t; 142typedef unsigned long snd_pcm_uframes_t;
143typedef signed long snd_pcm_sframes_t; 143typedef signed long snd_pcm_sframes_t;
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 998bacefc8f..cebf0310a8d 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -368,7 +368,8 @@ struct snd_pcm_substream {
368 struct snd_pcm_group *group; /* pointer to current group */ 368 struct snd_pcm_group *group; /* pointer to current group */
369 /* -- assigned files -- */ 369 /* -- assigned files -- */
370 void *file; 370 void *file;
371 struct file *ffile; 371 int ref_count;
372 unsigned int f_flags;
372 void (*pcm_release)(struct snd_pcm_substream *); 373 void (*pcm_release)(struct snd_pcm_substream *);
373#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 374#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
374 /* -- OSS things -- */ 375 /* -- OSS things -- */
@@ -387,7 +388,7 @@ struct snd_pcm_substream {
387 unsigned int hw_opened: 1; 388 unsigned int hw_opened: 1;
388}; 389};
389 390
390#define SUBSTREAM_BUSY(substream) ((substream)->file != NULL) 391#define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0)
391 392
392 393
393struct snd_pcm_str { 394struct snd_pcm_str {
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index d8b7416ee00..9803a6ce3d4 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1331,7 +1331,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
1331 if (runtime->oss.period_ptr == 0 || 1331 if (runtime->oss.period_ptr == 0 ||
1332 runtime->oss.period_ptr == runtime->oss.buffer_used) 1332 runtime->oss.period_ptr == runtime->oss.buffer_used)
1333 runtime->oss.buffer_used = 0; 1333 runtime->oss.buffer_used = 0;
1334 else if ((substream->ffile->f_flags & O_NONBLOCK) != 0) 1334 else if ((substream->f_flags & O_NONBLOCK) != 0)
1335 return xfer > 0 ? xfer : -EAGAIN; 1335 return xfer > 0 ? xfer : -EAGAIN;
1336 } 1336 }
1337 } else { 1337 } else {
@@ -1344,7 +1344,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
1344 buf += tmp; 1344 buf += tmp;
1345 bytes -= tmp; 1345 bytes -= tmp;
1346 xfer += tmp; 1346 xfer += tmp;
1347 if ((substream->ffile->f_flags & O_NONBLOCK) != 0 && 1347 if ((substream->f_flags & O_NONBLOCK) != 0 &&
1348 tmp != runtime->oss.period_bytes) 1348 tmp != runtime->oss.period_bytes)
1349 break; 1349 break;
1350 } 1350 }
@@ -1582,10 +1582,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1582 * finish sync: drain the buffer 1582 * finish sync: drain the buffer
1583 */ 1583 */
1584 __direct: 1584 __direct:
1585 saved_f_flags = substream->ffile->f_flags; 1585 saved_f_flags = substream->f_flags;
1586 substream->ffile->f_flags &= ~O_NONBLOCK; 1586 substream->f_flags &= ~O_NONBLOCK;
1587 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); 1587 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
1588 substream->ffile->f_flags = saved_f_flags; 1588 substream->f_flags = saved_f_flags;
1589 if (err < 0) 1589 if (err < 0)
1590 return err; 1590 return err;
1591 runtime->oss.prepare = 1; 1591 runtime->oss.prepare = 1;
@@ -2164,9 +2164,9 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
2164 substream->oss.oss = 1; 2164 substream->oss.oss = 1;
2165 substream->oss.setup = *setup; 2165 substream->oss.setup = *setup;
2166 if (setup->nonblock) 2166 if (setup->nonblock)
2167 substream->ffile->f_flags |= O_NONBLOCK; 2167 substream->f_flags |= O_NONBLOCK;
2168 else if (setup->block) 2168 else if (setup->block)
2169 substream->ffile->f_flags &= ~O_NONBLOCK; 2169 substream->f_flags &= ~O_NONBLOCK;
2170 runtime = substream->runtime; 2170 runtime = substream->runtime;
2171 runtime->oss.params = 1; 2171 runtime->oss.params = 1;
2172 runtime->oss.trigger = 1; 2172 runtime->oss.trigger = 1;
@@ -2223,6 +2223,7 @@ static int snd_pcm_oss_open_file(struct file *file,
2223 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) 2223 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX))
2224 f_mode = FMODE_WRITE; 2224 f_mode = FMODE_WRITE;
2225 2225
2226 file->f_flags &= ~O_APPEND;
2226 for (idx = 0; idx < 2; idx++) { 2227 for (idx = 0; idx < 2; idx++) {
2227 if (setup[idx].disable) 2228 if (setup[idx].disable)
2228 continue; 2229 continue;
@@ -2540,6 +2541,7 @@ static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t coun
2540 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; 2541 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2541 if (substream == NULL) 2542 if (substream == NULL)
2542 return -ENXIO; 2543 return -ENXIO;
2544 substream->f_flags = file->f_flags & O_NONBLOCK;
2543#ifndef OSS_DEBUG 2545#ifndef OSS_DEBUG
2544 return snd_pcm_oss_read1(substream, buf, count); 2546 return snd_pcm_oss_read1(substream, buf, count);
2545#else 2547#else
@@ -2561,6 +2563,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size
2561 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; 2563 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2562 if (substream == NULL) 2564 if (substream == NULL)
2563 return -ENXIO; 2565 return -ENXIO;
2566 substream->f_flags = file->f_flags & O_NONBLOCK;
2564 result = snd_pcm_oss_write1(substream, buf, count); 2567 result = snd_pcm_oss_write1(substream, buf, count);
2565#ifdef OSS_DEBUG 2568#ifdef OSS_DEBUG
2566 printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); 2569 printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result);
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 4f5204175d3..8136be2e606 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -829,6 +829,26 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
829 return -EINVAL; 829 return -EINVAL;
830 } 830 }
831 831
832 if (file->f_flags & O_APPEND) {
833 if (prefer_subdevice < 0) {
834 if (pstr->substream_count > 1)
835 return -EINVAL; /* must be unique */
836 substream = pstr->substream;
837 } else {
838 for (substream = pstr->substream; substream;
839 substream = substream->next)
840 if (substream->number == prefer_subdevice)
841 break;
842 }
843 if (! substream)
844 return -ENODEV;
845 if (! SUBSTREAM_BUSY(substream))
846 return -EBADFD;
847 substream->ref_count++;
848 *rsubstream = substream;
849 return 0;
850 }
851
832 if (prefer_subdevice >= 0) { 852 if (prefer_subdevice >= 0) {
833 for (substream = pstr->substream; substream; substream = substream->next) 853 for (substream = pstr->substream; substream; substream = substream->next)
834 if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice) 854 if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice)
@@ -873,7 +893,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
873 893
874 substream->runtime = runtime; 894 substream->runtime = runtime;
875 substream->private_data = pcm->private_data; 895 substream->private_data = pcm->private_data;
876 substream->ffile = file; 896 substream->ref_count = 1;
897 substream->f_flags = file->f_flags;
877 pstr->substream_opened++; 898 pstr->substream_opened++;
878 *rsubstream = substream; 899 *rsubstream = substream;
879 return 0; 900 return 0;
@@ -882,7 +903,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
882void snd_pcm_detach_substream(struct snd_pcm_substream *substream) 903void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
883{ 904{
884 struct snd_pcm_runtime *runtime; 905 struct snd_pcm_runtime *runtime;
885 substream->file = NULL; 906
886 runtime = substream->runtime; 907 runtime = substream->runtime;
887 snd_assert(runtime != NULL, return); 908 snd_assert(runtime != NULL, return);
888 if (runtime->private_free != NULL) 909 if (runtime->private_free != NULL)
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index e5133033de5..2b8aab6fd6c 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -497,9 +497,9 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
497 case SNDRV_PCM_IOCTL_LINK: 497 case SNDRV_PCM_IOCTL_LINK:
498 case SNDRV_PCM_IOCTL_UNLINK: 498 case SNDRV_PCM_IOCTL_UNLINK:
499 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 499 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
500 return snd_pcm_playback_ioctl1(substream, cmd, argp); 500 return snd_pcm_playback_ioctl1(file, substream, cmd, argp);
501 else 501 else
502 return snd_pcm_capture_ioctl1(substream, cmd, argp); 502 return snd_pcm_capture_ioctl1(file, substream, cmd, argp);
503 case SNDRV_PCM_IOCTL_HW_REFINE32: 503 case SNDRV_PCM_IOCTL_HW_REFINE32:
504 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); 504 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
505 case SNDRV_PCM_IOCTL_HW_PARAMS32: 505 case SNDRV_PCM_IOCTL_HW_PARAMS32:
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a21aa0050e4..0bb142a2853 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1782,7 +1782,7 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v
1782 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1782 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1783 return -EBADFD; 1783 return -EBADFD;
1784 1784
1785 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 1785 nonblock = !!(substream->f_flags & O_NONBLOCK);
1786 1786
1787 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && 1787 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
1788 runtime->channels > 1) 1788 runtime->channels > 1)
@@ -1847,7 +1847,7 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
1847 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1847 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1848 return -EBADFD; 1848 return -EBADFD;
1849 1849
1850 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 1850 nonblock = !!(substream->f_flags & O_NONBLOCK);
1851 1851
1852 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 1852 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
1853 return -EINVAL; 1853 return -EINVAL;
@@ -2059,7 +2059,7 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u
2059 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2059 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2060 return -EBADFD; 2060 return -EBADFD;
2061 2061
2062 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2062 nonblock = !!(substream->f_flags & O_NONBLOCK);
2063 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) 2063 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
2064 return -EINVAL; 2064 return -EINVAL;
2065 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); 2065 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
@@ -2118,7 +2118,7 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
2118 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2118 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2119 return -EBADFD; 2119 return -EBADFD;
2120 2120
2121 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2121 nonblock = !!(substream->f_flags & O_NONBLOCK);
2122 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 2122 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
2123 return -EINVAL; 2123 return -EINVAL;
2124 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); 2124 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 7b5729c4b21..36d6765618a 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1284,13 +1284,16 @@ static int snd_pcm_reset(struct snd_pcm_substream *substream)
1284/* 1284/*
1285 * prepare ioctl 1285 * prepare ioctl
1286 */ 1286 */
1287static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, int state) 1287/* we use the second argument for updating f_flags */
1288static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
1289 int f_flags)
1288{ 1290{
1289 struct snd_pcm_runtime *runtime = substream->runtime; 1291 struct snd_pcm_runtime *runtime = substream->runtime;
1290 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1292 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1291 return -EBADFD; 1293 return -EBADFD;
1292 if (snd_pcm_running(substream)) 1294 if (snd_pcm_running(substream))
1293 return -EBUSY; 1295 return -EBUSY;
1296 substream->f_flags = f_flags;
1294 return 0; 1297 return 0;
1295} 1298}
1296 1299
@@ -1319,17 +1322,26 @@ static struct action_ops snd_pcm_action_prepare = {
1319/** 1322/**
1320 * snd_pcm_prepare 1323 * snd_pcm_prepare
1321 * @substream: the PCM substream instance 1324 * @substream: the PCM substream instance
1325 * @file: file to refer f_flags
1322 * 1326 *
1323 * Prepare the PCM substream to be triggerable. 1327 * Prepare the PCM substream to be triggerable.
1324 */ 1328 */
1325static int snd_pcm_prepare(struct snd_pcm_substream *substream) 1329static int snd_pcm_prepare(struct snd_pcm_substream *substream,
1330 struct file *file)
1326{ 1331{
1327 int res; 1332 int res;
1328 struct snd_card *card = substream->pcm->card; 1333 struct snd_card *card = substream->pcm->card;
1334 int f_flags;
1335
1336 if (file)
1337 f_flags = file->f_flags;
1338 else
1339 f_flags = substream->f_flags;
1329 1340
1330 snd_power_lock(card); 1341 snd_power_lock(card);
1331 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) 1342 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
1332 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, substream, 0); 1343 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
1344 substream, f_flags);
1333 snd_power_unlock(card); 1345 snd_power_unlock(card);
1334 return res; 1346 return res;
1335} 1347}
@@ -1340,7 +1352,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream)
1340 1352
1341static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) 1353static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
1342{ 1354{
1343 if (substream->ffile->f_flags & O_NONBLOCK) 1355 if (substream->f_flags & O_NONBLOCK)
1344 return -EAGAIN; 1356 return -EAGAIN;
1345 substream->runtime->trigger_master = substream; 1357 substream->runtime->trigger_master = substream;
1346 return 0; 1358 return 0;
@@ -2015,6 +2027,10 @@ static void pcm_release_private(struct snd_pcm_substream *substream)
2015 2027
2016void snd_pcm_release_substream(struct snd_pcm_substream *substream) 2028void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2017{ 2029{
2030 substream->ref_count--;
2031 if (substream->ref_count > 0)
2032 return;
2033
2018 snd_pcm_drop(substream); 2034 snd_pcm_drop(substream);
2019 if (substream->hw_opened) { 2035 if (substream->hw_opened) {
2020 if (substream->ops->hw_free != NULL) 2036 if (substream->ops->hw_free != NULL)
@@ -2041,6 +2057,11 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2041 err = snd_pcm_attach_substream(pcm, stream, file, &substream); 2057 err = snd_pcm_attach_substream(pcm, stream, file, &substream);
2042 if (err < 0) 2058 if (err < 0)
2043 return err; 2059 return err;
2060 if (substream->ref_count > 1) {
2061 *rsubstream = substream;
2062 return 0;
2063 }
2064
2044 substream->no_mmap_ctrl = 0; 2065 substream->no_mmap_ctrl = 0;
2045 err = snd_pcm_hw_constraints_init(substream); 2066 err = snd_pcm_hw_constraints_init(substream);
2046 if (err < 0) { 2067 if (err < 0) {
@@ -2086,17 +2107,20 @@ static int snd_pcm_open_file(struct file *file,
2086 if (err < 0) 2107 if (err < 0)
2087 return err; 2108 return err;
2088 2109
2089 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); 2110 if (substream->ref_count > 1)
2090 if (pcm_file == NULL) { 2111 pcm_file = substream->file;
2091 snd_pcm_release_substream(substream); 2112 else {
2092 return -ENOMEM; 2113 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
2114 if (pcm_file == NULL) {
2115 snd_pcm_release_substream(substream);
2116 return -ENOMEM;
2117 }
2118 str = substream->pstr;
2119 substream->file = pcm_file;
2120 substream->pcm_release = pcm_release_private;
2121 pcm_file->substream = substream;
2122 snd_pcm_add_file(str, pcm_file);
2093 } 2123 }
2094 str = substream->pstr;
2095 substream->file = pcm_file;
2096 substream->pcm_release = pcm_release_private;
2097 pcm_file->substream = substream;
2098 snd_pcm_add_file(str, pcm_file);
2099
2100 file->private_data = pcm_file; 2124 file->private_data = pcm_file;
2101 *rpcm_file = pcm_file; 2125 *rpcm_file = pcm_file;
2102 return 0; 2126 return 0;
@@ -2506,7 +2530,8 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
2506 return 0; 2530 return 0;
2507} 2531}
2508 2532
2509static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, 2533static int snd_pcm_common_ioctl1(struct file *file,
2534 struct snd_pcm_substream *substream,
2510 unsigned int cmd, void __user *arg) 2535 unsigned int cmd, void __user *arg)
2511{ 2536{
2512 snd_assert(substream != NULL, return -ENXIO); 2537 snd_assert(substream != NULL, return -ENXIO);
@@ -2531,7 +2556,7 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2531 case SNDRV_PCM_IOCTL_CHANNEL_INFO: 2556 case SNDRV_PCM_IOCTL_CHANNEL_INFO:
2532 return snd_pcm_channel_info_user(substream, arg); 2557 return snd_pcm_channel_info_user(substream, arg);
2533 case SNDRV_PCM_IOCTL_PREPARE: 2558 case SNDRV_PCM_IOCTL_PREPARE:
2534 return snd_pcm_prepare(substream); 2559 return snd_pcm_prepare(substream, file);
2535 case SNDRV_PCM_IOCTL_RESET: 2560 case SNDRV_PCM_IOCTL_RESET:
2536 return snd_pcm_reset(substream); 2561 return snd_pcm_reset(substream);
2537 case SNDRV_PCM_IOCTL_START: 2562 case SNDRV_PCM_IOCTL_START:
@@ -2573,7 +2598,8 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2573 return -ENOTTY; 2598 return -ENOTTY;
2574} 2599}
2575 2600
2576static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, 2601static int snd_pcm_playback_ioctl1(struct file *file,
2602 struct snd_pcm_substream *substream,
2577 unsigned int cmd, void __user *arg) 2603 unsigned int cmd, void __user *arg)
2578{ 2604{
2579 snd_assert(substream != NULL, return -ENXIO); 2605 snd_assert(substream != NULL, return -ENXIO);
@@ -2649,10 +2675,11 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
2649 return result < 0 ? result : 0; 2675 return result < 0 ? result : 0;
2650 } 2676 }
2651 } 2677 }
2652 return snd_pcm_common_ioctl1(substream, cmd, arg); 2678 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
2653} 2679}
2654 2680
2655static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream, 2681static int snd_pcm_capture_ioctl1(struct file *file,
2682 struct snd_pcm_substream *substream,
2656 unsigned int cmd, void __user *arg) 2683 unsigned int cmd, void __user *arg)
2657{ 2684{
2658 snd_assert(substream != NULL, return -ENXIO); 2685 snd_assert(substream != NULL, return -ENXIO);
@@ -2728,7 +2755,7 @@ static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
2728 return result < 0 ? result : 0; 2755 return result < 0 ? result : 0;
2729 } 2756 }
2730 } 2757 }
2731 return snd_pcm_common_ioctl1(substream, cmd, arg); 2758 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
2732} 2759}
2733 2760
2734static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, 2761static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
@@ -2741,7 +2768,8 @@ static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
2741 if (((cmd >> 8) & 0xff) != 'A') 2768 if (((cmd >> 8) & 0xff) != 'A')
2742 return -ENOTTY; 2769 return -ENOTTY;
2743 2770
2744 return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg); 2771 return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
2772 (void __user *)arg);
2745} 2773}
2746 2774
2747static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, 2775static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
@@ -2754,7 +2782,8 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
2754 if (((cmd >> 8) & 0xff) != 'A') 2782 if (((cmd >> 8) & 0xff) != 'A')
2755 return -ENOTTY; 2783 return -ENOTTY;
2756 2784
2757 return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg); 2785 return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,
2786 (void __user *)arg);
2758} 2787}
2759 2788
2760int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, 2789int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
@@ -2766,12 +2795,12 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2766 fs = snd_enter_user(); 2795 fs = snd_enter_user();
2767 switch (substream->stream) { 2796 switch (substream->stream) {
2768 case SNDRV_PCM_STREAM_PLAYBACK: 2797 case SNDRV_PCM_STREAM_PLAYBACK:
2769 result = snd_pcm_playback_ioctl1(substream, 2798 result = snd_pcm_playback_ioctl1(NULL, substream, cmd,
2770 cmd, (void __user *)arg); 2799 (void __user *)arg);
2771 break; 2800 break;
2772 case SNDRV_PCM_STREAM_CAPTURE: 2801 case SNDRV_PCM_STREAM_CAPTURE:
2773 result = snd_pcm_capture_ioctl1(substream, 2802 result = snd_pcm_capture_ioctl1(NULL, substream, cmd,
2774 cmd, (void __user *)arg); 2803 (void __user *)arg);
2775 break; 2804 break;
2776 default: 2805 default:
2777 result = -EINVAL; 2806 result = -EINVAL;
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index fe67a92e2a1..88b72b52590 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -632,7 +632,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card)
632 for (s = 0; s < 2; ++s) { 632 for (s = 0; s < 2; ++s) {
633 struct snd_pcm_substream *substream; 633 struct snd_pcm_substream *substream;
634 substream = pcm->streams[s].substream; 634 substream = pcm->streams[s].substream;
635 if (substream && substream->ffile != NULL) 635 if (SUBSTREAM_BUSY(substream))
636 err = -EBUSY; 636 err = -EBUSY;
637 } 637 }
638 } 638 }