arch/parisc/kernel/pci-dma.c

Source file repositories/reference/linux-study-clean/arch/parisc/kernel/pci-dma.c

File Facts

System
Linux kernel
Corpus path
arch/parisc/kernel/pci-dma.c
Extension
.c
Size
11825 bytes
Lines
465
Domain
Architecture Layer
Bucket
arch/parisc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

static inline void dump_resmap(void) {;}
#endif

static inline int map_pte_uncached(pte_t * pte,
		unsigned long vaddr,
		unsigned long size, unsigned long *paddr_ptr)
{
	unsigned long end;
	unsigned long orig_vaddr = vaddr;

	vaddr &= ~PMD_MASK;
	end = vaddr + size;
	if (end > PMD_SIZE)
		end = PMD_SIZE;
	do {
		unsigned long flags;

		if (!pte_none(*pte))
			printk(KERN_ERR "map_pte_uncached: page already exists\n");
		purge_tlb_start(flags);
		set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC));
		pdtlb(SR_KERNEL, orig_vaddr);
		purge_tlb_end(flags);
		vaddr += PAGE_SIZE;
		orig_vaddr += PAGE_SIZE;
		(*paddr_ptr) += PAGE_SIZE;
		pte++;
	} while (vaddr < end);
	return 0;
}

static inline int map_pmd_uncached(pmd_t * pmd, unsigned long vaddr,
		unsigned long size, unsigned long *paddr_ptr)
{
	unsigned long end;
	unsigned long orig_vaddr = vaddr;

	vaddr &= ~PGDIR_MASK;
	end = vaddr + size;
	if (end > PGDIR_SIZE)
		end = PGDIR_SIZE;
	do {
		pte_t * pte = pte_alloc_kernel(pmd, vaddr);
		if (!pte)
			return -ENOMEM;
		if (map_pte_uncached(pte, orig_vaddr, end - vaddr, paddr_ptr))
			return -ENOMEM;
		vaddr = (vaddr + PMD_SIZE) & PMD_MASK;
		orig_vaddr += PMD_SIZE;
		pmd++;
	} while (vaddr < end);
	return 0;
}

static inline int map_uncached_pages(unsigned long vaddr, unsigned long size,
		unsigned long paddr)
{
	pgd_t * dir;
	unsigned long end = vaddr + size;

	dir = pgd_offset_k(vaddr);
	do {
		p4d_t *p4d;
		pud_t *pud;
		pmd_t *pmd;

		p4d = p4d_offset(dir, vaddr);
		pud = pud_offset(p4d, vaddr);
		pmd = pmd_alloc(NULL, pud, vaddr);

		if (!pmd)
			return -ENOMEM;
		if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr))
			return -ENOMEM;
		vaddr = vaddr + PGDIR_SIZE;
		dir++;
	} while (vaddr && (vaddr < end));
	return 0;
}

static inline void unmap_uncached_pte(pmd_t * pmd, unsigned long vaddr,
		unsigned long size)
{
	pte_t * pte;
	unsigned long end;
	unsigned long orig_vaddr = vaddr;

	if (pmd_none(*pmd))
		return;
	if (pmd_bad(*pmd)) {

Annotation

Implementation Notes