hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/core/sgbuf.c
....@@ -1,22 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Scatter-Gather buffer
34 *
45 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
- *
206 */
217
228 #include <linux/slab.h>
....@@ -43,6 +29,8 @@
4329 dmab->area = NULL;
4430
4531 tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
32
+ if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC_SG)
33
+ tmpb.dev.type = SNDRV_DMA_TYPE_DEV_UC;
4634 tmpb.dev.dev = sgbuf->dev;
4735 for (i = 0; i < sgbuf->pages; i++) {
4836 if (!(sgbuf->table[i].addr & ~PAGE_MASK))
....@@ -72,12 +60,20 @@
7260 struct snd_dma_buffer tmpb;
7361 struct snd_sg_page *table;
7462 struct page **pgtable;
63
+ int type = SNDRV_DMA_TYPE_DEV;
64
+ pgprot_t prot = PAGE_KERNEL;
7565
7666 dmab->area = NULL;
7767 dmab->addr = 0;
7868 dmab->private_data = sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL);
7969 if (! sgbuf)
8070 return NULL;
71
+ if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC_SG) {
72
+ type = SNDRV_DMA_TYPE_DEV_UC;
73
+#ifdef pgprot_noncached
74
+ prot = pgprot_noncached(PAGE_KERNEL);
75
+#endif
76
+ }
8177 sgbuf->dev = device;
8278 pages = snd_sgbuf_aligned_pages(size);
8379 sgbuf->tblsize = sgbuf_align_table(pages);
....@@ -98,7 +94,7 @@
9894 if (chunk > maxpages)
9995 chunk = maxpages;
10096 chunk <<= PAGE_SHIFT;
101
- if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device,
97
+ if (snd_dma_alloc_pages_fallback(type, device,
10298 chunk, &tmpb) < 0) {
10399 if (!sgbuf->pages)
104100 goto _failed;
....@@ -125,7 +121,7 @@
125121 }
126122
127123 sgbuf->size = size;
128
- dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL);
124
+ dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, prot);
129125 if (! dmab->area)
130126 goto _failed;
131127 if (res_size)
....@@ -146,6 +142,9 @@
146142 struct snd_sg_buf *sg = dmab->private_data;
147143 unsigned int start, end, pg;
148144
145
+ if (!sg)
146
+ return size;
147
+
149148 start = ofs >> PAGE_SHIFT;
150149 end = (ofs + size - 1) >> PAGE_SHIFT;
151150 /* check page continuity */