]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - sound/core/pcm_native.c
Merge branch 'for-2.6.19' of git://brick.kernel.dk/data/git/linux-2.6-block
[mv-sheeva.git] / sound / core / pcm_native.c
index 0224c70414f516a9666966f38c4b83aa0d5e44e4..37b4b10850ae0358cdbbf654fffd6754aa5a11d4 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/file.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/latency.h>
 #include <linux/uio.h>
 #include <sound/core.h>
 #include <sound/control.h>
@@ -347,11 +348,26 @@ out:
        return err;
 }
 
+static int period_to_usecs(struct snd_pcm_runtime *runtime)
+{
+       int usecs;
+
+       if (! runtime->rate)
+               return -1; /* invalid */
+
+       /* take 75% of period time as the deadline */
+       usecs = (750000 / runtime->rate) * runtime->period_size;
+       usecs += ((750000 % runtime->rate) * runtime->period_size) /
+               runtime->rate;
+
+       return usecs;
+}
+
 static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params)
 {
        struct snd_pcm_runtime *runtime;
-       int err;
+       int err, usecs;
        unsigned int bits;
        snd_pcm_uframes_t frames;
 
@@ -431,6 +447,10 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
 
        snd_pcm_timer_resolution_change(substream);
        runtime->status->state = SNDRV_PCM_STATE_SETUP;
+
+       remove_acceptable_latency(substream->latency_id);
+       if ((usecs = period_to_usecs(runtime)) >= 0)
+               set_acceptable_latency(substream->latency_id, usecs);
        return 0;
  _error:
        /* hardware might be unuseable from this time,
@@ -490,6 +510,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
        if (substream->ops->hw_free)
                result = substream->ops->hw_free(substream);
        runtime->status->state = SNDRV_PCM_STATE_OPEN;
+       remove_acceptable_latency(substream->latency_id);
        return result;
 }
 
@@ -2831,8 +2852,8 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
        return result;
 }
 
-static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
-                            unsigned long count, loff_t * offset)
+static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
+                            unsigned long nr_segs, loff_t pos)
 
 {
        struct snd_pcm_file *pcm_file;
@@ -2843,22 +2864,22 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
        void __user **bufs;
        snd_pcm_uframes_t frames;
 
-       pcm_file = file->private_data;
+       pcm_file = iocb->ki_filp->private_data;
        substream = pcm_file->substream;
        snd_assert(substream != NULL, return -ENXIO);
        runtime = substream->runtime;
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
                return -EBADFD;
-       if (count > 1024 || count != runtime->channels)
+       if (nr_segs > 1024 || nr_segs != runtime->channels)
                return -EINVAL;
-       if (!frame_aligned(runtime, _vector->iov_len))
+       if (!frame_aligned(runtime, iov->iov_len))
                return -EINVAL;
-       frames = bytes_to_samples(runtime, _vector->iov_len);
-       bufs = kmalloc(sizeof(void *) * count, GFP_KERNEL);
+       frames = bytes_to_samples(runtime, iov->iov_len);
+       bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
-       for (i = 0; i < count; ++i)
-               bufs[i] = _vector[i].iov_base;
+       for (i = 0; i < nr_segs; ++i)
+               bufs[i] = iov[i].iov_base;
        result = snd_pcm_lib_readv(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
@@ -2866,8 +2887,8 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
        return result;
 }
 
-static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
-                             unsigned long count, loff_t * offset)
+static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
+                             unsigned long nr_segs, loff_t pos)
 {
        struct snd_pcm_file *pcm_file;
        struct snd_pcm_substream *substream;
@@ -2877,7 +2898,7 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
        void __user **bufs;
        snd_pcm_uframes_t frames;
 
-       pcm_file = file->private_data;
+       pcm_file = iocb->ki_filp->private_data;
        substream = pcm_file->substream;
        snd_assert(substream != NULL, result = -ENXIO; goto end);
        runtime = substream->runtime;
@@ -2885,17 +2906,17 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
                result = -EBADFD;
                goto end;
        }
-       if (count > 128 || count != runtime->channels ||
-           !frame_aligned(runtime, _vector->iov_len)) {
+       if (nr_segs > 128 || nr_segs != runtime->channels ||
+           !frame_aligned(runtime, iov->iov_len)) {
                result = -EINVAL;
                goto end;
        }
-       frames = bytes_to_samples(runtime, _vector->iov_len);
-       bufs = kmalloc(sizeof(void *) * count, GFP_KERNEL);
+       frames = bytes_to_samples(runtime, iov->iov_len);
+       bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
-       for (i = 0; i < count; ++i)
-               bufs[i] = _vector[i].iov_base;
+       for (i = 0; i < nr_segs; ++i)
+               bufs[i] = iov[i].iov_base;
        result = snd_pcm_lib_writev(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
@@ -3405,7 +3426,7 @@ struct file_operations snd_pcm_f_ops[2] = {
        {
                .owner =                THIS_MODULE,
                .write =                snd_pcm_write,
-               .writev =               snd_pcm_writev,
+               .aio_write =            snd_pcm_aio_write,
                .open =                 snd_pcm_playback_open,
                .release =              snd_pcm_release,
                .poll =                 snd_pcm_playback_poll,
@@ -3417,7 +3438,7 @@ struct file_operations snd_pcm_f_ops[2] = {
        {
                .owner =                THIS_MODULE,
                .read =                 snd_pcm_read,
-               .readv =                snd_pcm_readv,
+               .aio_read =             snd_pcm_aio_read,
                .open =                 snd_pcm_capture_open,
                .release =              snd_pcm_release,
                .poll =                 snd_pcm_capture_poll,