From patchwork Sat Jan 27 14:42:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej S. Szmigiero" X-Patchwork-Id: 10187509 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2441C602C8 for ; Sat, 27 Jan 2018 14:43:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 05F0428B9B for ; Sat, 27 Jan 2018 14:43:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EE69B28BA1; Sat, 27 Jan 2018 14:43:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4AABE28B9B for ; Sat, 27 Jan 2018 14:43:16 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 2ED722670D5; Sat, 27 Jan 2018 15:42:55 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id CC23F266FD8; Sat, 27 Jan 2018 15:42:53 +0100 (CET) Received: from vps-vb.mhejs.net (vps-vb.mhejs.net [37.28.154.113]) by alsa0.perex.cz (Postfix) with ESMTP id 5DB7D266FDE for ; Sat, 27 Jan 2018 15:42:49 +0100 (CET) Received: by vps-vb.mhejs.net with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.89) (envelope-from ) id 1efRgu-0006HG-Bk; Sat, 27 Jan 2018 15:42:48 +0100 From: "Maciej S. Szmigiero" To: Jaroslav Kysela , Takashi Iwai Message-ID: <619e9569-717a-1b4b-6470-4fa6b186bf41@maciej.szmigiero.name> Date: Sat, 27 Jan 2018 15:42:47 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2 MIME-Version: 1.0 Content-Language: en-US Cc: alsa-devel@alsa-project.org, linux-kernel Subject: [alsa-devel] [PATCH v2 4/5] ALSA: emu10k1: make sure synth DMA pages are allocated with DMA functions X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Commit a5003fc04113 ("[ALSA] emu10k1 - simplify page allocation for synth") switched from using the DMA allocator for synth DMA pages to manually calling alloc_page(). However, this usage has an implicit assumption that the DMA address space for the emu10k1-family chip is the same as the CPU physical address space which is not true for a system with a IOMMU. Since this made the synth part of the driver non-functional on such systems let's effectively revert that commit. Signed-off-by: Maciej S. Szmigiero --- Changes from v1: None in this patch. sound/pci/emu10k1/memory.c | 70 ++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index fcb04cbbc9ab..5cdffe2d31e1 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -457,49 +457,44 @@ static void get_single_page_range(struct snd_util_memhdr *hdr, *last_page_ret = last_page; } -/* release allocated pages */ -static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page, - int last_page) -{ - int page; - - for (page = first_page; page <= last_page; page++) { - free_page((unsigned long)emu->page_ptr_table[page]); - emu->page_addr_table[page] = 0; - emu->page_ptr_table[page] = NULL; - } -} - /* * allocate kernel pages */ static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) { int page, first_page, last_page; + struct snd_dma_buffer dmab; emu10k1_memblk_init(blk); get_single_page_range(emu->memhdr, blk, &first_page, &last_page); /* allocate kernel pages */ for (page = first_page; page <= last_page; page++) { - /* first try to allocate from <4GB zone */ - struct page *p = alloc_page(GFP_KERNEL | GFP_DMA32 | - __GFP_NOWARN); - if (!p || (page_to_pfn(p) & ~(emu->dma_mask >> PAGE_SHIFT))) { - if (p) - __free_page(p); - /* try to allocate from <16MB zone */ - p = alloc_page(GFP_ATOMIC | GFP_DMA | - __GFP_NORETRY | /* no OOM-killer */ - __GFP_NOWARN); - } - if (!p) { - __synth_free_pages(emu, first_page, page - 1); - return -ENOMEM; + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(emu->pci), + PAGE_SIZE, &dmab) < 0) + goto __fail; + if (!is_valid_page(emu, dmab.addr)) { + snd_dma_free_pages(&dmab); + goto __fail; } - emu->page_addr_table[page] = page_to_phys(p); - emu->page_ptr_table[page] = page_address(p); + emu->page_addr_table[page] = dmab.addr; + emu->page_ptr_table[page] = dmab.area; } return 0; + +__fail: + /* release allocated pages */ + last_page = page - 1; + for (page = first_page; page <= last_page; page++) { + dmab.area = emu->page_ptr_table[page]; + dmab.addr = emu->page_addr_table[page]; + dmab.bytes = PAGE_SIZE; + snd_dma_free_pages(&dmab); + emu->page_addr_table[page] = 0; + emu->page_ptr_table[page] = NULL; + } + + return -ENOMEM; } /* @@ -507,10 +502,23 @@ static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk */ static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) { - int first_page, last_page; + int page, first_page, last_page; + struct snd_dma_buffer dmab; get_single_page_range(emu->memhdr, blk, &first_page, &last_page); - __synth_free_pages(emu, first_page, last_page); + dmab.dev.type = SNDRV_DMA_TYPE_DEV; + dmab.dev.dev = snd_dma_pci_data(emu->pci); + for (page = first_page; page <= last_page; page++) { + if (emu->page_ptr_table[page] == NULL) + continue; + dmab.area = emu->page_ptr_table[page]; + dmab.addr = emu->page_addr_table[page]; + dmab.bytes = PAGE_SIZE; + snd_dma_free_pages(&dmab); + emu->page_addr_table[page] = 0; + emu->page_ptr_table[page] = NULL; + } + return 0; }