tree 9cdbf08c070d430c1959ce2ee60a2714681e8150
parent cff79742fc9e80242a9147a348621e4373c76287
author Takashi Iwai <[EMAIL PROTECTED]> Mon, 15 Aug 2005 15:01:10 +0200
committer Jaroslav Kysela <[EMAIL PROTECTED]> Tue, 30 Aug 2005 08:46:06 +0200

[ALSA] Fix PCM 32bit compat layer

PCM Midlevel
Fixed the handling of boundary in PCM 32bit compat layer.
Positions in hwsync are bound in the 32bit boundary size.

Signed-off-by: Takashi Iwai <[EMAIL PROTECTED]>

 sound/core/pcm_compat.c |   42 ++++++++++++++++++++++++++++--------------
 1 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -103,10 +103,24 @@ struct sndrv_pcm_sw_params32 {
        unsigned char reserved[64];
 };
 
+/* recalcuate the boundary within 32bit */
+static snd_pcm_uframes_t recalculate_boundary(snd_pcm_runtime_t *runtime)
+{
+       snd_pcm_uframes_t boundary;
+
+       if (! runtime->buffer_size)
+               return 0;
+       boundary = runtime->buffer_size;
+       while (boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
+               boundary *= 2;
+       return boundary;
+}
+
 static int snd_pcm_ioctl_sw_params_compat(snd_pcm_substream_t *substream,
                                          struct sndrv_pcm_sw_params32 __user 
*src)
 {
        snd_pcm_sw_params_t params;
+       snd_pcm_uframes_t boundary;
        int err;
 
        memset(&params, 0, sizeof(params));
@@ -120,10 +134,17 @@ static int snd_pcm_ioctl_sw_params_compa
            get_user(params.silence_threshold, &src->silence_threshold) ||
            get_user(params.silence_size, &src->silence_size))
                return -EFAULT;
+       /*
+        * Check silent_size parameter.  Since we have 64bit boundary,
+        * silence_size must be compared with the 32bit boundary.
+        */
+       boundary = recalculate_boundary(substream->runtime);
+       if (boundary && params.silence_size >= boundary)
+               params.silence_size = substream->runtime->boundary;
        err = snd_pcm_sw_params(substream, &params);
        if (err < 0)
                return err;
-       if (put_user(params.boundary, &src->boundary))
+       if (put_user(boundary, &src->boundary))
                return -EFAULT;
        return err;
 }
@@ -199,16 +220,6 @@ static int snd_pcm_status_user_compat(sn
        return err;
 }
 
-/* recalcuate the boundary within 32bit */
-static void recalculate_boundary(snd_pcm_runtime_t *runtime)
-{
-       if (! runtime->buffer_size)
-               return;
-       runtime->boundary = runtime->buffer_size;
-       while (runtime->boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
-               runtime->boundary *= 2;
-}
-
 /* both for HW_PARAMS and HW_REFINE */
 static int snd_pcm_ioctl_hw_params_compat(snd_pcm_substream_t *substream,
                                          int refine, 
@@ -242,7 +253,7 @@ static int snd_pcm_ioctl_hw_params_compa
        }
 
        if (! refine)
-               recalculate_boundary(runtime);
+               runtime->boundary = recalculate_boundary(runtime);
  error:
        kfree(data);
        return err;
@@ -380,6 +391,7 @@ static int snd_pcm_ioctl_sync_ptr_compat
        u32 sflags;
        struct sndrv_pcm_mmap_control scontrol;
        struct sndrv_pcm_mmap_status sstatus;
+       snd_pcm_uframes_t boundary;
        int err;
 
        snd_assert(runtime, return -EINVAL);
@@ -395,17 +407,19 @@ static int snd_pcm_ioctl_sync_ptr_compat
        }
        status = runtime->status;
        control = runtime->control;
+       boundary = recalculate_boundary(runtime);
        snd_pcm_stream_lock_irq(substream);
+       /* FIXME: we should consider the boundary for the sync from app */
        if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
                control->appl_ptr = scontrol.appl_ptr;
        else
-               scontrol.appl_ptr = control->appl_ptr;
+               scontrol.appl_ptr = control->appl_ptr % boundary;
        if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
                control->avail_min = scontrol.avail_min;
        else
                scontrol.avail_min = control->avail_min;
        sstatus.state = status->state;
-       sstatus.hw_ptr = status->hw_ptr;
+       sstatus.hw_ptr = status->hw_ptr % boundary;
        sstatus.tstamp = status->tstamp;
        sstatus.suspended_state = status->suspended_state;
        snd_pcm_stream_unlock_irq(substream);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to