Hi Takashi et al, I did a bit more research, please find my findings at the end of the email. On Friday, October 6, 2017 4:50 PM Axel Holzinger wrote: > On Friday, October 6, 2017 2:30 PM Takashi Iwai wrote: > > On Tue, 03 Oct 2017 19:23:04 +0200, > > Axel Holzinger wrote: > > > > > > On Thursday, June 8, 2017 10:40 AM Takashi Iwai wrote: > > > > > > > On Thu, 08 Jun 2017 10:15:34 +0200, > > > > Axel Holzinger wrote: > > > > > > > > > > On Tuesday, June 6, 2017 8:27 PM Takashi Iwai wrote: > > > > > > On Mon, 05 Jun 2017 11:49:53 +0200, > > > > > > Axel Holzinger wrote: > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > I'm trying to get a RME HDSPe MADI card to run in an ARM box > with > > > > Linux > > > > > > > 4.1.6. I configured the (vendor specific TI) kernel to support > the > > > card > > > > > (via > > > > > > > hdspm) compiled into the kernel (not as loadable module). > > > > > > > > > > > > > > The MADI card is detected as a PCI device and the ALSA driver is > > > loaded. > > > > > > > Unfortunately playout does NOT work: aplay is reporting an > error: > > > > > > > ALSA lib pcm_mmap.c:374:(snd_pcm_mmap) mmap failed: No > such > > > > device > > > > > > or > > > > > > > address > > > > > > > > > > > > Hm, this sounds odd. But the line doesn't really correspond to > the > > > > > > latest version of alsa-lib. Could you try to upgrade to the > latest > > > > > > version? Otherwise it's hard to debug. > > > > > > > > > > I installed ALSA with Debian apt-get. How would I update to a newer > > > > version? > > > > > > > > Compiling by yourself? > > > > alsa-lib has very few dependency, so it should be easy. > > > > > > > > > > > strace: > > > > > > > open("/dev/snd/pcmC0D0p", > > O_RDWR|O_NONBLOCK|O_CLOEXEC) = > > > > 4 > > > > > > > fcntl64(4, F_SETFD, FD_CLOEXEC) = 0 > > > > > > > ioctl(4, AGPIOC_ACQUIRE or APM_IOC_STANDBY or > > > > > > SNDRV_PCM_IOCTL_INFO, > > > > > > > 0xbecdfb64) = 0 > > > > > > > fcntl64(4, F_GETFL) = 0x802 (flags > > > > > O_RDWR|O_NONBLOCK) > > > > > > > ioctl(4, AGPIOC_INFO or SNDRV_PCM_IOCTL_PVERSION, > > 0xbecdfacc) = > > > > 0 > > > > > > > ioctl(4, AGPIOC_SETUP or SNDRV_PCM_IOCTL_TTSTAMP, > > 0xbecdfad4) > > > > = 0 > > > > > > > mmap2(NULL, 4096, PROT_READ, MAP_SHARED, 4, 0x80000000) = > -1 > > > > ENXIO > > > > > > (No such > > > > > > > device or address) > > > > > > > > > > > > This error is expected and should be OK. It's an mmap of > > > > > > status/control page, and this isn't supported on ARM, thus the > kernel > > > > > > returns -ENXIO. alsa-lib then falls back to the normal ioctl > instead > > > > > > of status/control mmap. > > > > > > > > > > Okay, got it. So is the mmap emulation plugin via asound.conf > > suggested > > > by > > > > > Anders needed then anyhow? > > > > > > > > It's irrelevant with the mmap emulation. > > > > > > > > > > But the ring-buffer mmap is supported as normal on ARM for MADI > > > > > > driver, at least. MADI provides the SG-buffer that is mappable > via > > > > > > DMA coherent pages, and it should work on most of archs as is. > > > > > > > > > > Well I found out something more: If I don't give a "--device" > parameter > > > to > > > > > aplay and the RME card is default, then audio is playing. But I give > the > > > " > > > > > --device=default:CARD=HDSPMx5c74" then the error is occuring. That > > > > doesn't > > > > > make sense to me at all. The tests made were with the asound.conf > > Anders > > > > > suggested. Isn't that strange? > > > > > > > > Are you using dmix or such? It appears more like a configuration > > > > issue. With the unmodified configuration, the "default" PCM for > HDSPM > > > > should be equivalent with "plughw". > > > > > > > > Could you check whether aplay -M works without device option? > > > > > > > > > > You should have another error from mmap, with a different offset > > > > > > value. That's the real error we need to track down. > > > > > > > > > > I attached the complete strace. > > > > > > > > OK, the strace shows the mmap failure of the second channel. > > > > > > > > > > (And, 4.1.x is pretty old, rather too old for debugging, too...) > > > > > > > > > > Well, I know, but the kernel is a TI based manufacturer kernel for a > SoC > > > > > (AM5728). I'm not such an expert to update that to current kernel > > > version > > > > > unfortunately. > > > > > > > > > > If you don't mind I have another question: If specifying a device > > > > > "--device", how would I "send" audio to the "upper" channels/tracks > of > > > the > > > > > MADI card? If I ommit the "--device" parameter audio is playing on > > > > > channels/tracks 1+2. How would I play audio to channels/tracks 33+34 > > for > > > > > example? > > > > > > > > Well, you likely need to fiddle with the asoundrc in such a case. > > > > Maybe a better option is to use JACK or such, I suppose. > > > > > > > > > > > > Takashi > > > > > > Hello Takashi, hello list, > > > > > > I did some further testing with a Sound Blaster Live Audigy Rx (Emu10k1 > > > driver based) and this card works without any change in asound.conf, > etc. > > > > Yes, it's because emu10k1 supports only interleaved stereo format (two > > channels) which works with one-shot mmap via dma_mmap_coherent(). > > Meanwhile HDSP MADI supports only non-interleaved format that > performs > > multiple mmaps, and currently it doesn't work with > > dma_mmap_coherent(). > > Understood. > > > > While with the RME MADI card: > > > > > > debian@arm:~/48kHz$ aplay -vv audio.wav > > > Playing WAVE 'audio.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, > > > Stereo ALSA lib pcm_mmap.c:374:(snd_pcm_mmap) mmap failed: > > > No such device or address > > > > So my previous patch didn't help? > > (BTW, area->pgoff was indeed a typo of area->vm_pgoff, so your change > > should be OK.) > > Correct, didn't help. > > > If it didn't work, try to put some printk() around the call of > > dma_mmap_coherent() and check whether it's really called with which > > value and which return (error) code it gets. > > int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, > struct vm_area_struct *area) > { > area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; > #ifdef CONFIG_GENERIC_ALLOCATOR > if (substream->dma_buffer.dev.type == > SNDRV_DMA_TYPE_DEV_IRAM) { > area->vm_page_prot = > pgprot_writecombine(area->vm_page_prot); > return remap_pfn_range(area, area->vm_start, > substream->dma_buffer.addr >> > PAGE_SHIFT, > area->vm_end - area->vm_start, > area->vm_page_prot); > } > #endif /* CONFIG_GENERIC_ALLOCATOR */ > #ifndef CONFIG_X86 /* for avoiding warnings arch/x86/mm/pat.c */ > if (!substream->ops->page && > substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) { > unsigned long offset = area->vm_pgoff << PAGE_SHIFT; > > const char *init_name = > substream->dma_buffer.dev.dev->init_name; > u64 *dma_mask = > substream->dma_buffer.dev.dev->dma_mask; > u64 u64_dma_mask = dma_mask ? *dma_mask : 0; > u64 coherent_dma_mask = > substream->dma_buffer.dev.dev->coherent_dma_mask; > u64 dma_pfn_offset = > substream->dma_buffer.dev.dev->dma_pfn_offset; > u64 vm_start = area->vm_start; > u64 vm_end = area->vm_end; > u64 vm_size = vm_end - vm_start; > u64 offs = offset; > u64 rb_subtree_gap = area->rb_subtree_gap; > u64 vm_flags = area->vm_flags; > void *cpu_addr = substream->runtime->dma_area > + offset; > u64 dma_addr = substream->runtime->dma_addr > + offset; > > int result = > dma_mmap_coherent(substream->dma_buffer.dev.dev, > area, > substream->runtime->dma_area + > offset, > substream->runtime->dma_addr + > offset, > area->vm_end - area->vm_start); > > printk(KERN_DEBUG "dma_mmap_coherent returned %d, > init_name > = \"%s\", dma_mask = %p, *dma_mask = %llu, coherent_dma_mask = %llu, > dma_pfn_offset = %llu, vm_start = %llu, vm_end = %llu, vm_size = %llu, > offset = %llu, rb_subtree_gap = %llu, vm_flags = %llu, cpu_addr = %p, > dma_addr = %llu", > result, > init_name, > dma_mask, > u64_dma_mask, > coherent_dma_mask, > dma_pfn_offset, > vm_start, > vm_end, > vm_size, > offs, > rb_subtree_gap, > vm_flags, > cpu_addr, > dma_addr); > return result; > } > #endif /* CONFIG_X86 */ > /* mmap with fault handler */ > area->vm_ops = &snd_pcm_vm_ops_data_fault; > return 0; > } > > debian@arm:~/48kHz$ aplay -vv audio.wav > > output: > Playing WAVE 'audio.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, > Stereo > ALSA lib pcm_mmap.c:374:(snd_pcm_mmap) mmap failed: No such device or > address > aplay: set_params:1297: Unable to install hw params: > ACCESS: RW_INTERLEAVED > FORMAT: S16_LE > SUBFORMAT: STD > SAMPLE_BITS: 16 > FRAME_BITS: 32 > CHANNELS: 2 > RATE: 48000 > PERIOD_TIME: (21333 21334) > PERIOD_SIZE: 1024 > PERIOD_BYTES: 4096 > PERIODS: 2 > BUFFER_TIME: (42666 42667) > BUFFER_SIZE: 2048 > BUFFER_BYTES: 8192 > TICK_TIME: 0 > > dmesg: > [ 251.739831] dma_mmap_coherent returned 0, init_name = "(null)", > dma_mask > = ed804c40, *dma_mask = 4294967295, coherent_dma_mask = 4294967295, > dma_pfn_offset = 0, vm_start = 3069702144, vm_end = 3069710336, vm_size > = > 8192, offset = 0, rb_subtree_gap = 0, vm_flags = 67371259, cpu_addr = > f01d1000, dma_addr = 4266655744 > [ 251.739857] dma_mmap_coherent returned -6, init_name = "(null)", > dma_mask > = ed804c40, *dma_mask = 4294967295, coherent_dma_mask = 4294967295, > dma_pfn_offset = 0, vm_start = 3069693952, vm_end = 3069702144, vm_size > = > 8192, offset = 65536, rb_subtree_gap = 0, vm_flags = 67371259, cpu_addr = > f01e1000, dma_addr = 4266721280 > > Thanks a lot > Axel > > > thanks, > > > > Takashi With a lot of printk output I finally found out what's happening and I think Takashi you mentioned that there is only one map area available, so I think my findings proove that opinion of yours. The problem is occurring in the following function in arch/arm/mm/dma-mapping.c at around line 700: /* * Create userspace mapping for the DMA-coherent memory. */ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) { int ret = -ENXIO; #ifdef CONFIG_MMU unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; unsigned long pfn = dma_to_pfn(dev, dma_addr); unsigned long off = vma->vm_pgoff; vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot); if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) return ret; if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) { ret = remap_pfn_range(vma, vma->vm_start, pfn + off, vma->vm_end - vma->vm_start, vma->vm_page_prot); } #endif /* CONFIG_MMU */ return ret; } When this function is called first (by snd_pcm_lib_default_mmap and so on) the if clause is executed (calling remap_pfn_range) because of the following parameters: off = 0 nr_pages = 2 nr_vma_pages = 2 while when called the second time (because asking aplay to play a stereo audio file) the parameters are these off = 16 nr_pages = 2 nr_vma_pages = 2 and so the if clause is not executed, remap_pfn_range is not called and the return value ret remains in its initialised state of -ENXIO (dma_mmap_from_coherent is succeeding and so ret is not changed). So what can I do to make this work? Thank you Axel ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Alsa-user mailing list Alsa-user@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/alsa-user