Re: ALSA support for ARM XScale

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



At Fri, 02 Jun 2006 18:51:45 +0200,
Lars Bergmann wrote:
> 
> I see two types of failure:
> 1) PCI audio device drivers exit with snd_pcm_mmap_data_nopage (see below)

This is a known problem.  A workaround patch for ARM is below, but it
still doesn't work for some devices with SG buffer.

A better but more intrusive fix is pending on my tree, which will be
hopefully merged sometime later.

> 2) USB audio driver plays for some seconds (reporting underruns) and 
> will then fail:
> 
> # /usr/local/bin/aplay /home/lars/tori-test-48k.wav
> Playing WAVE '/home/lars/tori-test-48k.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
> underrun!!! (at least 4.662 ms long)
> underrun!!! (at least 0.134 ms long)
> underrun!!! (at least 25.856 ms long)
> underrun!!! (at least 0.138 ms long)
> underrun!!! (at least 5.296 ms long)
> ...
> aplay: pcm_write:1222: write error: Input/output error
> timeout: still 12 active urbs..
> # usb 1-2: USB disconnect, address 2
> 
> Playback via USB audio will also produce stack traces from either khubd 
> or pdflush (see below).
> 
> PCI and USB problems might be completely unrelated: Looking at the USB 
> audio driver, I think they did not use ALSA API for memory allocation 
> and I/O mapping - instead they create URBs allocated by the USB core.

The usb-audio driver does memory allocation and mmaping indeed.


Takashi


diff -r c11fa10a4838 core/pcm_native.c
--- a/core/pcm_native.c	Tue Jun 06 15:44:34 2006 +0200
+++ b/core/pcm_native.c	Tue Jun 06 16:24:57 2006 +0200
@@ -3124,6 +3124,10 @@ static int snd_pcm_mmap_control(struct s
 }
 #endif /* coherent mmap */
 
+#if defined(CONFIG_ARM)
+#define HAVE_DMA_MMAP_COHERENT
+#endif
+
 /*
  * nopage callback for mmapping a RAM page
  */
@@ -3167,6 +3171,14 @@ static struct vm_operations_struct snd_p
 	.nopage =	snd_pcm_mmap_data_nopage,
 };
 
+#ifdef HAVE_DMA_MMAP_COHERENT
+static struct vm_operations_struct snd_pcm_vm_ops_data_one_map =
+{
+	.open =		snd_pcm_mmap_data_open,
+	.close =	snd_pcm_mmap_data_close,
+};
+#endif
+
 /*
  * mmap the DMA buffer on RAM
  */
@@ -3176,6 +3188,16 @@ static int snd_pcm_default_mmap(struct s
 	area->vm_ops = &snd_pcm_vm_ops_data;
 	area->vm_private_data = substream;
 	area->vm_flags |= VM_RESERVED;
+#ifdef HAVE_DMA_MMAP_COHERENT
+	if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) {
+		area->vm_ops = &snd_pcm_vm_ops_data_one_map;
+		if (dma_mmap_coherent(substream->dma_buffer.dev.dev, area,
+				      substream->runtime->dma_area,
+				      substream->runtime->dma_addr,
+				      area->vm_end - area->vm_start))
+			return -EAGAIN;
+	}
+#endif
 	atomic_inc(&substream->mmap_count);
 	return 0;
 }



_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux