public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Alan Cox <alan@lxorguk.ukuu.org.uk>
To: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: "Brian D. McGrew" <brian@visionpro.com>, linux-kernel@vger.kernel.org
Subject: Re: PCI Device Driver / remap_pfn_range()
Date: Tue, 18 Apr 2006 12:21:15 +0100	[thread overview]
Message-ID: <1145359275.18736.22.camel@localhost.localdomain> (raw)
In-Reply-To: <4443DC09.20606@yahoo.com.au>

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);
}


  reply	other threads:[~2006-04-18 11:11 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-17 17:45 PCI Device Driver / remap_pfn_range() Brian D. McGrew
2006-04-17 18:18 ` Nick Piggin
2006-04-18 11:21   ` Alan Cox [this message]
2006-04-18 11:51     ` Nick Piggin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1145359275.18736.22.camel@localhost.localdomain \
    --to=alan@lxorguk.ukuu.org.uk \
    --cc=brian@visionpro.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nickpiggin@yahoo.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox