27 #include <linux/pci.h>
28 #include <linux/time.h>
37 #define __set_tlb_bus(trident,page,ptr,addr) \
38 do { (trident)->tlb.entries[page] = cpu_to_le32((addr) & ~(SNDRV_TRIDENT_PAGE_SIZE-1)); \
39 (trident)->tlb.shadow_entries[page] = (ptr); } while (0)
40 #define __tlb_to_ptr(trident,page) \
41 (void*)((trident)->tlb.shadow_entries[page])
42 #define __tlb_to_addr(trident,page) \
43 (dma_addr_t)le32_to_cpu((trident->tlb.entries[page]) & ~(SNDRV_TRIDENT_PAGE_SIZE - 1))
47 #define ALIGN_PAGE_SIZE PAGE_SIZE
48 #define MAX_ALIGN_PAGES SNDRV_TRIDENT_MAX_PAGES
50 #define set_tlb_bus(trident,page,ptr,addr) __set_tlb_bus(trident,page,ptr,addr)
52 #define set_silent_tlb(trident,page) __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr)
54 #define get_aligned_page(offset) ((offset) >> 12)
56 #define aligned_page_offset(page) ((page) << 12)
58 #define page_to_ptr(trident,page) __tlb_to_ptr(trident, page)
60 #define page_to_addr(trident,page) __tlb_to_addr(trident, page)
62 #elif PAGE_SIZE == 8192
64 #define ALIGN_PAGE_SIZE PAGE_SIZE
65 #define MAX_ALIGN_PAGES (SNDRV_TRIDENT_MAX_PAGES / 2)
66 #define get_aligned_page(offset) ((offset) >> 13)
67 #define aligned_page_offset(page) ((page) << 13)
68 #define page_to_ptr(trident,page) __tlb_to_ptr(trident, (page) << 1)
69 #define page_to_addr(trident,page) __tlb_to_addr(trident, (page) << 1)
79 static inline void set_silent_tlb(
struct snd_trident *trident,
int page)
82 __set_tlb_bus(trident, page, (
unsigned long)trident->
tlb.silent_page.area, trident->
tlb.silent_page.addr);
83 __set_tlb_bus(trident, page+1, (
unsigned long)trident->
tlb.silent_page.area, trident->
tlb.silent_page.addr);
88 #define UNIT_PAGES (PAGE_SIZE / SNDRV_TRIDENT_PAGE_SIZE)
89 #define ALIGN_PAGE_SIZE (SNDRV_TRIDENT_PAGE_SIZE * UNIT_PAGES)
90 #define MAX_ALIGN_PAGES (SNDRV_TRIDENT_MAX_PAGES / UNIT_PAGES)
96 #define get_aligned_page(offset) ((offset) / ALIGN_PAGE_SIZE)
97 #define aligned_page_offset(page) ((page) * ALIGN_PAGE_SIZE)
98 #define page_to_ptr(trident,page) __tlb_to_ptr(trident, (page) * UNIT_PAGES)
99 #define page_to_addr(trident,page) __tlb_to_addr(trident, (page) * UNIT_PAGES)
102 static inline void set_tlb_bus(
struct snd_trident *trident,
int page,
113 static inline void set_silent_tlb(
struct snd_trident *trident,
int page)
118 __set_tlb_bus(trident, page, (
unsigned long)trident->
tlb.silent_page.area, trident->
tlb.silent_page.addr);
133 #define firstpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->first_page)
134 #define lastpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->last_page)
151 if (page + psize <=
firstpg(blk))
165 lastpg(blk) = page + psize - 1;
173 static int is_valid_page(
unsigned long ptr)
175 if (ptr & ~0x3fffffffUL) {
190 snd_trident_alloc_sg_pages(
struct snd_trident *trident,
202 hdr = trident->
tlb.memhdr;
209 blk = search_empty(hdr, runtime->
dma_bytes);
217 for (page =
firstpg(blk); page <=
lastpg(blk); page++, idx++) {
220 unsigned long ptr = (
unsigned long)
221 snd_pcm_sgbuf_get_ptr(substream, ofs);
222 if (! is_valid_page(addr)) {
227 set_tlb_bus(trident, page, ptr, addr);
237 snd_trident_alloc_cont_pages(
struct snd_trident *trident,
249 SNDRV_TRIDENT_PAGE_SIZE))
251 hdr = trident->
tlb.memhdr;
256 blk = search_empty(hdr, runtime->
dma_bytes);
267 if (! is_valid_page(addr)) {
272 set_tlb_bus(trident, page, ptr, addr);
288 return snd_trident_alloc_sg_pages(trident, substream);
290 return snd_trident_alloc_cont_pages(trident, substream);
306 hdr = trident->
tlb.memhdr;
310 set_silent_tlb(trident, page);