Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
[deliverable/linux.git] / sound / core / pcm_native.c
index 279e24f613051fddb8ca16375ab9031e6a703b03..d126c03361aef87fb1239df1e42f547c5ce36aa9 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/pm_qos.h>
-#include <linux/aio.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
 #include <sound/core.h>
@@ -35,6 +34,7 @@
 #include <sound/pcm_params.h>
 #include <sound/timer.h>
 #include <sound/minors.h>
+#include <linux/uio.h>
 
 /*
  *  Compatibility
@@ -707,6 +707,23 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
 
        snd_pcm_stream_lock_irq(substream);
+
+       snd_pcm_unpack_audio_tstamp_config(status->audio_tstamp_data,
+                                       &runtime->audio_tstamp_config);
+
+       /* backwards compatible behavior */
+       if (runtime->audio_tstamp_config.type_requested ==
+               SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT) {
+               if (runtime->hw.info & SNDRV_PCM_INFO_HAS_WALL_CLOCK)
+                       runtime->audio_tstamp_config.type_requested =
+                               SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK;
+               else
+                       runtime->audio_tstamp_config.type_requested =
+                               SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
+               runtime->audio_tstamp_report.valid = 0;
+       } else
+               runtime->audio_tstamp_report.valid = 1;
+
        status->state = runtime->status->state;
        status->suspended_state = runtime->status->suspended_state;
        if (status->state == SNDRV_PCM_STATE_OPEN)
@@ -716,8 +733,15 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
                snd_pcm_update_hw_ptr(substream);
                if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
                        status->tstamp = runtime->status->tstamp;
+                       status->driver_tstamp = runtime->driver_tstamp;
                        status->audio_tstamp =
                                runtime->status->audio_tstamp;
+                       if (runtime->audio_tstamp_report.valid == 1)
+                               /* backwards compatibility, no report provided in COMPAT mode */
+                               snd_pcm_pack_audio_tstamp_report(&status->audio_tstamp_data,
+                                                               &status->audio_tstamp_accuracy,
+                                                               &runtime->audio_tstamp_report);
+
                        goto _tstamp_end;
                }
        } else {
@@ -753,12 +777,21 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
 }
 
 static int snd_pcm_status_user(struct snd_pcm_substream *substream,
-                              struct snd_pcm_status __user * _status)
+                              struct snd_pcm_status __user * _status,
+                              bool ext)
 {
        struct snd_pcm_status status;
        int res;
-       
+
        memset(&status, 0, sizeof(status));
+       /*
+        * with extension, parameters are read/write,
+        * get audio_tstamp_data from user,
+        * ignore rest of status structure
+        */
+       if (ext && get_user(status.audio_tstamp_data,
+                               (u32 __user *)(&_status->audio_tstamp_data)))
+               return -EFAULT;
        res = snd_pcm_status(substream, &status);
        if (res < 0)
                return res;
@@ -2725,7 +2758,9 @@ static int snd_pcm_common_ioctl1(struct file *file,
        case SNDRV_PCM_IOCTL_SW_PARAMS:
                return snd_pcm_sw_params_user(substream, arg);
        case SNDRV_PCM_IOCTL_STATUS:
-               return snd_pcm_status_user(substream, arg);
+               return snd_pcm_status_user(substream, arg, false);
+       case SNDRV_PCM_IOCTL_STATUS_EXT:
+               return snd_pcm_status_user(substream, arg, true);
        case SNDRV_PCM_IOCTL_CHANNEL_INFO:
                return snd_pcm_channel_info_user(substream, arg);
        case SNDRV_PCM_IOCTL_PREPARE:
@@ -3033,9 +3068,7 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
        return result;
 }
 
-static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
-                            unsigned long nr_segs, loff_t pos)
-
+static ssize_t snd_pcm_readv(struct kiocb *iocb, struct iov_iter *to)
 {
        struct snd_pcm_file *pcm_file;
        struct snd_pcm_substream *substream;
@@ -3052,16 +3085,18 @@ static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
        runtime = substream->runtime;
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
                return -EBADFD;
-       if (nr_segs > 1024 || nr_segs != runtime->channels)
+       if (!iter_is_iovec(to))
+               return -EINVAL;
+       if (to->nr_segs > 1024 || to->nr_segs != runtime->channels)
                return -EINVAL;
-       if (!frame_aligned(runtime, iov->iov_len))
+       if (!frame_aligned(runtime, to->iov->iov_len))
                return -EINVAL;
-       frames = bytes_to_samples(runtime, iov->iov_len);
-       bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
+       frames = bytes_to_samples(runtime, to->iov->iov_len);
+       bufs = kmalloc(sizeof(void *) * to->nr_segs, GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
-       for (i = 0; i < nr_segs; ++i)
-               bufs[i] = iov[i].iov_base;
+       for (i = 0; i < to->nr_segs; ++i)
+               bufs[i] = to->iov[i].iov_base;
        result = snd_pcm_lib_readv(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
@@ -3069,8 +3104,7 @@ static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
        return result;
 }
 
-static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
-                             unsigned long nr_segs, loff_t pos)
+static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from)
 {
        struct snd_pcm_file *pcm_file;
        struct snd_pcm_substream *substream;
@@ -3087,15 +3121,17 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
        runtime = substream->runtime;
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
                return -EBADFD;
-       if (nr_segs > 128 || nr_segs != runtime->channels ||
-           !frame_aligned(runtime, iov->iov_len))
+       if (!iter_is_iovec(from))
+               return -EINVAL;
+       if (from->nr_segs > 128 || from->nr_segs != runtime->channels ||
+           !frame_aligned(runtime, from->iov->iov_len))
                return -EINVAL;
-       frames = bytes_to_samples(runtime, iov->iov_len);
-       bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
+       frames = bytes_to_samples(runtime, from->iov->iov_len);
+       bufs = kmalloc(sizeof(void *) * from->nr_segs, GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
-       for (i = 0; i < nr_segs; ++i)
-               bufs[i] = iov[i].iov_base;
+       for (i = 0; i < from->nr_segs; ++i)
+               bufs[i] = from->iov[i].iov_base;
        result = snd_pcm_lib_writev(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
@@ -3633,7 +3669,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
        {
                .owner =                THIS_MODULE,
                .write =                snd_pcm_write,
-               .aio_write =            snd_pcm_aio_write,
+               .write_iter =           snd_pcm_writev,
                .open =                 snd_pcm_playback_open,
                .release =              snd_pcm_release,
                .llseek =               no_llseek,
@@ -3647,7 +3683,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
        {
                .owner =                THIS_MODULE,
                .read =                 snd_pcm_read,
-               .aio_read =             snd_pcm_aio_read,
+               .read_iter =            snd_pcm_readv,
                .open =                 snd_pcm_capture_open,
                .release =              snd_pcm_release,
                .llseek =               no_llseek,
This page took 0.028636 seconds and 5 git commands to generate.