]> err.no Git - linux-2.6/blobdiff - sound/core/oss/pcm_oss.c
Merge HEAD from master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
[linux-2.6] / sound / core / oss / pcm_oss.c
index 131522ea4b935a87075e165ab1549607e4ac9ff1..a13bd7bb4c9f08cf6628ce8856f1c56896ba2e9c 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/time.h>
 #include <linux/vmalloc.h>
 #include <linux/moduleparam.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/pcm.h>
@@ -129,7 +130,16 @@ static long snd_pcm_oss_bytes(snd_pcm_substream_t *substream, long frames)
        long bytes = frames_to_bytes(runtime, frames);
        if (buffer_size == runtime->oss.buffer_bytes)
                return bytes;
-       return (long)(((int64_t)runtime->oss.buffer_bytes * (int64_t)bytes) / (int64_t)buffer_size);
+#if BITS_PER_LONG >= 64
+       return runtime->oss.buffer_bytes * bytes / buffer_size;
+#else
+       {
+               u64 bsize = (u64)runtime->oss.buffer_bytes * (u64)bytes;
+               u32 rem;
+               div64_32(&bsize, buffer_size, &rem);
+               return (long)bsize;
+       }
+#endif
 }
 
 static long snd_pcm_alsa_frames(snd_pcm_substream_t *substream, long bytes)
@@ -1528,12 +1538,15 @@ static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, str
                        snd_pcm_oss_simulate_fill(substream, delay);
                info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
        } else {
-               delay = snd_pcm_oss_bytes(substream, delay) + fixup;
-               info.blocks = delay / runtime->oss.period_bytes;
-               if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+               delay = snd_pcm_oss_bytes(substream, delay);
+               if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                       info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
                        info.bytes = (runtime->oss.bytes - delay) & INT_MAX;
-               else
+               } else {
+                       delay += fixup;
+                       info.blocks = delay / runtime->oss.period_bytes;
                        info.bytes = (runtime->oss.bytes + delay) & INT_MAX;
+               }
        }
        if (copy_to_user(_info, &info, sizeof(info)))
                return -EFAULT;
@@ -1692,13 +1705,12 @@ static int snd_pcm_oss_release_file(snd_pcm_oss_file_t *pcm_oss_file)
                if (snd_pcm_running(substream))
                        snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
                snd_pcm_stream_unlock_irq(substream);
-               if (substream->open_flag) {
+               if (substream->ffile != NULL) {
                        if (substream->ops->hw_free != NULL)
                                substream->ops->hw_free(substream);
                        substream->ops->close(substream);
-                       substream->open_flag = 0;
+                       substream->ffile = NULL;
                }
-               substream->ffile = NULL;
                snd_pcm_oss_release_substream(substream);
                snd_pcm_release_substream(substream);
        }
@@ -1765,14 +1777,13 @@ static int snd_pcm_oss_open_file(struct file *file,
                        snd_pcm_oss_release_file(pcm_oss_file);
                        return err;
                }
-               psubstream->open_flag = 1;
+               psubstream->ffile = file;
                err = snd_pcm_hw_constraints_complete(psubstream);
                if (err < 0) {
                        snd_printd("snd_pcm_hw_constraint_complete failed\n");
                        snd_pcm_oss_release_file(pcm_oss_file);
                        return err;
                }
-               psubstream->ffile = file;
                snd_pcm_oss_init_substream(psubstream, psetup, minor);
        }
        if (csubstream != NULL) {
@@ -1787,14 +1798,13 @@ static int snd_pcm_oss_open_file(struct file *file,
                        snd_pcm_oss_release_file(pcm_oss_file);
                        return err;
                }
-               csubstream->open_flag = 1;
+               csubstream->ffile = file;
                err = snd_pcm_hw_constraints_complete(csubstream);
                if (err < 0) {
                        snd_printd("snd_pcm_hw_constraint_complete failed\n");
                        snd_pcm_oss_release_file(pcm_oss_file);
                        return err;
                }
-               csubstream->ffile = file;
                snd_pcm_oss_init_substream(csubstream, csetup, minor);
        }
 
@@ -2348,7 +2358,7 @@ static void snd_pcm_oss_proc_write(snd_info_entry_t *entry,
                                        for (setup1 = pstr->oss.setup_list; setup1->next; setup1 = setup1->next);
                                        setup1->next = setup;
                                }
-                               template.task_name = snd_kmalloc_strdup(task_name, GFP_KERNEL);
+                               template.task_name = kstrdup(task_name, GFP_KERNEL);
                        } else {
                                buffer->error = -ENOMEM;
                        }