From: Takashi Iwai <tiwai@suse.de>
To: "David S. Miller" <davem@davemloft.net>
Cc: linux-kernel@vger.kernel.org, perex@suse.de
Subject: Re: ALSA update broke Sparc
Date: Tue, 31 Aug 2004 21:07:19 +0200 [thread overview]
Message-ID: <s5heklnyvmg.wl@alsa2.suse.de> (raw)
In-Reply-To: <s5h4qmkkjl5.wl@alsa2.suse.de>
At Mon, 30 Aug 2004 12:26:30 +0200,
I wrote:
>
> > Can I make a small formal request of the ALSA folks? Can you
> > at least setup a cross-compiler to make sure your ALSA merges
> > don't explode on sparc64? As it stands, 1 out of every 2 ALSA
> > merges breaks the build on that platform.
>
> I'll try to set up.
Although I still couldn't set up the sparc cross-compile environment,
I fixed/updated the ALSA pcm layer.
David, could you try the attached patch? With this, the problematic
part will be disabled on sparc (it won't work on every architecture,
anyway).
thanks,
Takashi
--- linux/sound/core/pcm.c 3 Aug 2004 16:44:01 -0000 1.43
+++ linux/sound/core/pcm.c 31 Aug 2004 18:35:21 -0000
@@ -1050,6 +1050,9 @@
EXPORT_SYMBOL(snd_pcm_playback_poll);
EXPORT_SYMBOL(snd_pcm_capture_poll);
EXPORT_SYMBOL(snd_pcm_mmap_data);
+#if SNDRV_PCM_INFO_MMAP_IOMEM
+EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
+#endif
/* pcm_misc.c */
EXPORT_SYMBOL(snd_pcm_format_signed);
EXPORT_SYMBOL(snd_pcm_format_unsigned);
--- linux/sound/core/pcm_native.c 16 Aug 2004 10:02:10 -0000 1.81
+++ linux/sound/core/pcm_native.c 31 Aug 2004 18:35:27 -0000
@@ -2907,6 +2907,18 @@
return mask;
}
+/*
+ * mmap support
+ */
+
+/*
+ * Only on coherent architectures, we can mmap the status and the control records
+ * for effcient data transfer. On others, we have to use HWSYNC ioctl...
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__alpha__)
+/*
+ * mmap status record
+ */
static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, unsigned long address, int *type)
{
snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
@@ -2929,8 +2941,8 @@
.nopage = snd_pcm_mmap_status_nopage,
};
-int snd_pcm_mmap_status(snd_pcm_substream_t *substream, struct file *file,
- struct vm_area_struct *area)
+static int snd_pcm_mmap_status(snd_pcm_substream_t *substream, struct file *file,
+ struct vm_area_struct *area)
{
snd_pcm_runtime_t *runtime;
long size;
@@ -2947,6 +2959,9 @@
return 0;
}
+/*
+ * mmap control record
+ */
static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, unsigned long address, int *type)
{
snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
@@ -2986,20 +3001,26 @@
area->vm_flags |= VM_RESERVED;
return 0;
}
-
-static void snd_pcm_mmap_data_open(struct vm_area_struct *area)
+#else /* ! coherent mmap */
+/*
+ * don't support mmap for status and control records.
+ */
+static int snd_pcm_mmap_status(snd_pcm_substream_t *substream, struct file *file,
+ struct vm_area_struct *area)
{
- snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
- atomic_inc(&substream->runtime->mmap_count);
+ return -ENXIO;
}
-
-static void snd_pcm_mmap_data_close(struct vm_area_struct *area)
+static int snd_pcm_mmap_control(snd_pcm_substream_t *substream, struct file *file,
+ struct vm_area_struct *area)
{
- snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
- atomic_dec(&substream->runtime->mmap_count);
+ return -ENXIO;
}
+#endif /* coherent mmap */
-static struct page * snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsigned long address, int *type)
+/*
+ * nopage callback for mmapping a RAM page
+ */
+static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsigned long address, int *type)
{
snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
snd_pcm_runtime_t *runtime;
@@ -3039,12 +3060,52 @@
.nopage = snd_pcm_mmap_data_nopage,
};
+/*
+ * mmap the DMA buffer on RAM
+ */
+static int snd_pcm_default_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *area)
+{
+ area->vm_ops = &snd_pcm_vm_ops_data;
+ area->vm_private_data = substream;
+ area->vm_flags |= VM_RESERVED;
+ atomic_inc(&substream->runtime->mmap_count);
+ return 0;
+}
+
+/*
+ * mmap the DMA buffer on I/O memory area
+ */
+#if SNDRV_PCM_INFO_MMAP_IOMEM
static struct vm_operations_struct snd_pcm_vm_ops_data_mmio =
{
.open = snd_pcm_mmap_data_open,
.close = snd_pcm_mmap_data_close,
};
+int snd_pcm_lib_mmap_iomem(snd_pcm_substream_t *substream, struct vm_area_struct *area)
+{
+ long size;
+ unsigned long offset;
+
+#ifdef pgprot_noncached
+ area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
+#endif
+ area->vm_ops = &snd_pcm_vm_ops_data_mmio;
+ area->vm_flags |= VM_IO;
+ size = area->vm_end - area->vm_start;
+ offset = area->vm_pgoff << PAGE_SHIFT;
+ if (io_remap_page_range(area, area->vm_start,
+ substream->runtime->dma_addr + offset,
+ size, area->vm_page_prot))
+ return -EAGAIN;
+ atomic_inc(&substream->runtime->mmap_count);
+ return 0;
+}
+#endif /* SNDRV_PCM_INFO_MMAP */
+
+/*
+ * mmap DMA buffer
+ */
int snd_pcm_mmap_data(snd_pcm_substream_t *substream, struct file *file,
struct vm_area_struct *area)
{
@@ -3077,19 +3138,10 @@
if (offset > dma_bytes - size)
return -EINVAL;
- area->vm_ops = &snd_pcm_vm_ops_data;
- area->vm_private_data = substream;
- area->vm_flags |= VM_RESERVED;
- if (runtime->hw.info & SNDRV_PCM_INFO_MMAP_IOMEM) {
- area->vm_ops = &snd_pcm_vm_ops_data_mmio;
- area->vm_flags |= VM_IO;
- if (io_remap_page_range(area, area->vm_start,
- runtime->dma_addr + offset,
- size, area->vm_page_prot))
- return -EAGAIN;
- }
- atomic_inc(&runtime->mmap_count);
- return 0;
+ if (substream->ops->mmap)
+ return substream->ops->mmap(substream, area);
+ else
+ return snd_pcm_default_mmap(substream, area);
}
static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
--- linux/include/sound/asound.h 3 Aug 2004 16:45:38 -0000 1.36
+++ linux/include/sound/asound.h 31 Aug 2004 18:31:28 -0000
@@ -275,7 +275,6 @@
#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */
#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */
#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */
-#define SNDRV_PCM_INFO_MMAP_IOMEM 0x01000000 /* mmap on IO memory */
enum sndrv_pcm_state {
SNDRV_PCM_STATE_OPEN = 0, /* stream is open */
--- linux/include/sound/pcm.h 30 Jul 2004 12:44:58 -0000 1.47
+++ linux/include/sound/pcm.h 31 Aug 2004 18:35:31 -0000
@@ -97,6 +97,7 @@
int (*silence)(snd_pcm_substream_t *substream, int channel,
snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
struct page *(*page)(snd_pcm_substream_t *substream, unsigned long offset);
+ int (*mmap)(snd_pcm_substream_t *substream, struct vm_area_struct *vma);
int (*ack)(snd_pcm_substream_t *substream);
} snd_pcm_ops_t;
@@ -938,6 +939,28 @@
#define snd_pcm_sgbuf_get_addr(sgbuf,ofs) snd_sgbuf_get_addr(sgbuf,ofs)
struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
+/* handle mmap counter - PCM mmap callback should handle this counter properly */
+static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
+{
+ snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+ atomic_inc(&substream->runtime->mmap_count);
+}
+
+static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
+{
+ snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+ atomic_dec(&substream->runtime->mmap_count);
+}
+
+/* mmap for io-memory area */
+#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__alpha__)
+#define SNDRV_PCM_INFO_MMAP_IOMEM SNDRV_PCM_INFO_MMAP
+int snd_pcm_lib_mmap_iomem(snd_pcm_substream_t *substream, struct vm_area_struct *area);
+#else
+#define SNDRV_PCM_INFO_MMAP 0
+#define snd_pcm_lib_mmap_iomem NULL
+#endif
+
static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
{
*max = dma < 4 ? 64 * 1024 : 128 * 1024;
--- linux/sound/pci/rme32.c 27 Jul 2004 12:40:29 -0000 1.47
+++ linux/sound/pci/rme32.c 31 Aug 2004 18:31:28 -0000
@@ -331,9 +331,8 @@
* SPDIF I/O capabilites (half-duplex mode)
*/
static snd_pcm_hardware_t snd_rme32_spdif_info = {
- .info = (SNDRV_PCM_INFO_MMAP |
+ .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_SYNC_START),
@@ -359,9 +358,8 @@
*/
static snd_pcm_hardware_t snd_rme32_adat_info =
{
- .info = (SNDRV_PCM_INFO_MMAP |
+ .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_SYNC_START),
@@ -1246,6 +1244,7 @@
.pointer = snd_rme32_playback_pointer,
.copy = snd_rme32_playback_copy,
.silence = snd_rme32_playback_silence,
+ .mmap = snd_pcm_lib_mmap_iomem,
};
static snd_pcm_ops_t snd_rme32_capture_spdif_ops = {
@@ -1258,6 +1257,7 @@
.trigger = snd_rme32_pcm_trigger,
.pointer = snd_rme32_capture_pointer,
.copy = snd_rme32_capture_copy,
+ .mmap = snd_pcm_lib_mmap_iomem,
};
static snd_pcm_ops_t snd_rme32_playback_adat_ops = {
@@ -1270,6 +1270,7 @@
.pointer = snd_rme32_playback_pointer,
.copy = snd_rme32_playback_copy,
.silence = snd_rme32_playback_silence,
+ .mmap = snd_pcm_lib_mmap_iomem,
};
static snd_pcm_ops_t snd_rme32_capture_adat_ops = {
@@ -1281,6 +1282,7 @@
.trigger = snd_rme32_pcm_trigger,
.pointer = snd_rme32_capture_pointer,
.copy = snd_rme32_capture_copy,
+ .mmap = snd_pcm_lib_mmap_iomem,
};
/* for fullduplex mode */
--- linux/sound/pci/rme96.c 27 Jul 2004 11:20:09 -0000 1.41
+++ linux/sound/pci/rme96.c 31 Aug 2004 18:31:28 -0000
@@ -383,9 +383,8 @@
*/
static snd_pcm_hardware_t snd_rme96_playback_spdif_info =
{
- .info = (SNDRV_PCM_INFO_MMAP |
+ .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -413,9 +412,8 @@
*/
static snd_pcm_hardware_t snd_rme96_capture_spdif_info =
{
- .info = (SNDRV_PCM_INFO_MMAP |
+ .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -443,9 +441,8 @@
*/
static snd_pcm_hardware_t snd_rme96_playback_adat_info =
{
- .info = (SNDRV_PCM_INFO_MMAP |
+ .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -469,9 +466,8 @@
*/
static snd_pcm_hardware_t snd_rme96_capture_adat_info =
{
- .info = (SNDRV_PCM_INFO_MMAP |
+ .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -1494,6 +1490,7 @@
.pointer = snd_rme96_playback_pointer,
.copy = snd_rme96_playback_copy,
.silence = snd_rme96_playback_silence,
+ .mmap = snd_pcm_lib_mmap_iomem,
};
static snd_pcm_ops_t snd_rme96_capture_spdif_ops = {
@@ -1505,6 +1502,7 @@
.trigger = snd_rme96_capture_trigger,
.pointer = snd_rme96_capture_pointer,
.copy = snd_rme96_capture_copy,
+ .mmap = snd_pcm_lib_mmap_iomem,
};
static snd_pcm_ops_t snd_rme96_playback_adat_ops = {
@@ -1517,6 +1515,7 @@
.pointer = snd_rme96_playback_pointer,
.copy = snd_rme96_playback_copy,
.silence = snd_rme96_playback_silence,
+ .mmap = snd_pcm_lib_mmap_iomem,
};
static snd_pcm_ops_t snd_rme96_capture_adat_ops = {
@@ -1528,6 +1527,7 @@
.trigger = snd_rme96_capture_trigger,
.pointer = snd_rme96_capture_pointer,
.copy = snd_rme96_capture_copy,
+ .mmap = snd_pcm_lib_mmap_iomem,
};
static void
--- linux/sound/pci/nm256/nm256.c 3 Aug 2004 15:03:54 -0000 1.52
+++ linux/sound/pci/nm256/nm256.c 31 Aug 2004 18:31:28 -0000
@@ -742,8 +742,7 @@
*/
static snd_pcm_hardware_t snd_nm256_playback =
{
- .info = SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID|
- SNDRV_PCM_INFO_MMAP_IOMEM|
+ .info = SNDRV_PCM_INFO_MMAP_IOMEM |SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
/*SNDRV_PCM_INFO_PAUSE |*/
SNDRV_PCM_INFO_RESUME,
@@ -762,8 +761,7 @@
static snd_pcm_hardware_t snd_nm256_capture =
{
- .info = SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID|
- SNDRV_PCM_INFO_MMAP_IOMEM|
+ .info = SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
/*SNDRV_PCM_INFO_PAUSE |*/
SNDRV_PCM_INFO_RESUME,
@@ -864,6 +862,7 @@
.copy = snd_nm256_playback_copy,
.silence = snd_nm256_playback_silence,
#endif
+ .mmap = snd_pcm_lib_mmap_iomem,
};
static snd_pcm_ops_t snd_nm256_capture_ops = {
@@ -877,6 +876,7 @@
#ifndef __i386__
.copy = snd_nm256_capture_copy,
#endif
+ .mmap = snd_pcm_lib_mmap_iomem,
};
static int __devinit
next prev parent reply other threads:[~2004-08-31 19:12 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-28 1:36 ALSA update broke Sparc David S. Miller
2004-08-28 7:45 ` Russell King
2004-08-30 10:26 ` Takashi Iwai
2004-08-31 19:07 ` Takashi Iwai [this message]
2004-08-31 20:56 ` David S. Miller
2004-09-01 8:12 ` Takashi Iwai
2004-08-31 20:58 ` David S. Miller
2004-09-01 8:14 ` Takashi Iwai
2004-08-31 22:20 ` Andrew Morton
2004-09-01 8:16 ` Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5heklnyvmg.wl@alsa2.suse.de \
--to=tiwai@suse.de \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=perex@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox