Re: PCI Device Driver / remap_pfn_range()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Maw, 2006-04-18 at 04:18 +1000, Nick Piggin wrote:
> I'm pretty sure you can't remap_pfn_range vmalloced memory because
> it doesn't use contiguous page frames.

To remap vmalloc memory you need something like this. Note that vmalloc
memory may not be DMA accessible, vmalloc_32 memory maybe. Alternatively
you can build your own scatter gather  lists from pages subject to
hardware limits.

The following GPL code from various drivers shows how to do vmalloc
mapping into an application. Having a common helper for this is a
discussion/todo item when that area of the vm gets future adjustments
but for now this code should do the trick:

/* Here we want the physical address of the memory.
 * This is used when initializing the contents of the
 * area and marking the pages as reserved.
 */
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
        unsigned long kva, ret;

        kva = (unsigned long) page_address(vmalloc_to_page((void
*)adr));
        kva |= adr & (PAGE_SIZE-1); /* restore the offset */
        ret = __pa(kva);
        return ret;
}

static void *rvmalloc(unsigned long size)
{
        void *mem;
        unsigned long adr;

        /* Round it off to PAGE_SIZE */
        size = PAGE_ALIGN(size);

        mem = vmalloc_32(size);
        if (!mem)
                return NULL;

        memset(mem, 0, size);   /* Clear the ram out, no junk to the
user */
        adr = (unsigned long) mem;

        while ((long)size > 0) {
                SetPageReserved(vmalloc_to_page((void *)adr));
                adr += PAGE_SIZE;
                size -= PAGE_SIZE;
        }
        return mem;
}

static void rvfree(void *mem, unsigned long size)
{
        unsigned long adr;

        if (!mem)
                return;

        size = PAGE_ALIGN(size);

        adr = (unsigned long) mem;
        while ((long)size > 0) {
                ClearPageReserved(vmalloc_to_page((void *)adr));
                adr += PAGE_SIZE;
                size -= PAGE_SIZE;
        }
        vfree(mem);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux