Commit 094686d3 authored by Ingo Molnar's avatar Ingo Molnar

- the new vmalloc_to_page() interface should be used to determine the physical...

- the new vmalloc_to_page() interface should be used to determine the physical page a given vmalloc() area virtual address is mapped to.
parent f3ebe654
......@@ -173,36 +173,11 @@ static struct hpsb_highlevel *hl_handle = NULL;
* defined way to get at the kernel page tables.
*/
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
unsigned long ret = 0UL;
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, adr);
if (!pmd_none(*pmd)) {
ptep = pte_offset(pmd, adr);
pte = *ptep;
if(pte_present(pte)) {
ret = (unsigned long)
page_address(pte_page(pte));
ret |= (adr & (PAGE_SIZE - 1));
}
}
}
MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
return ret;
}
static inline unsigned long uvirt_to_bus(unsigned long adr)
{
unsigned long kva, ret;
kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
kva = page_address(vmalloc_to_page(pgd_offset(current->mm, adr), adr));
ret = virt_to_bus((void *)kva);
MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
return ret;
......@@ -213,7 +188,7 @@ static inline unsigned long kvirt_to_bus(unsigned long adr)
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = virt_to_bus((void *)kva);
MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
return ret;
......@@ -228,7 +203,7 @@ static inline unsigned long kvirt_to_pa(unsigned long adr)
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
return ret;
......
......@@ -141,36 +141,11 @@ __setup("bttv.radio=", p_radio);
* defined way to get at the kernel page tables.
*/
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
unsigned long ret = 0UL;
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, adr);
if (!pmd_none(*pmd)) {
ptep = pte_offset(pmd, adr);
pte = *ptep;
if(pte_present(pte)) {
ret = (unsigned long) page_address(pte_page(pte));
ret |= (adr & (PAGE_SIZE - 1));
}
}
}
MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
return ret;
}
static inline unsigned long uvirt_to_bus(unsigned long adr)
{
unsigned long kva, ret;
kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
kva = page_address(vmalloc_to_page(pgd_offset(current->mm, adr), adr));
ret = virt_to_bus((void *)kva);
MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
return ret;
......@@ -181,7 +156,7 @@ static inline unsigned long kvirt_to_bus(unsigned long adr)
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = virt_to_bus((void *)kva);
MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
return ret;
......@@ -196,7 +171,7 @@ static inline unsigned long kvirt_to_pa(unsigned long adr)
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
return ret;
......
......@@ -178,40 +178,8 @@ static void reset_camera_struct(struct cam_data *cam);
*
* Memory management
*
* This is a shameless copy from the USB-cpia driver (linux kernel
* version 2.3.29 or so, I have no idea what this code actually does ;).
* Actually it seems to be a copy of a shameless copy of the bttv-driver.
* Or that is a copy of a shameless copy of ... (To the powers: is there
* no generic kernel-function to do this sort of stuff?)
*
* Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
* there will be one, but apparentely not yet - jerdfelt
*
**********************************************************************/
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
unsigned long ret = 0UL;
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, adr);
if (!pmd_none(*pmd)) {
ptep = pte_offset(pmd, adr);
pte = *ptep;
if (pte_present(pte)) {
ret = (unsigned long) page_address(pte_page(pte));
ret |= (adr & (PAGE_SIZE-1));
}
}
}
return ret;
}
/* 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.
......@@ -221,7 +189,7 @@ static inline unsigned long kvirt_to_pa(unsigned long adr)
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = __pa(kva);
return ret;
}
......
......@@ -118,30 +118,6 @@ static inline int meye_emptyq(struct meye_queue *queue, int *elem) {
#define MDEBUG(x) do {} while (0)
/* #define MDEBUG(x) x */
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) {
unsigned long ret = 0UL;
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, adr);
if (!pmd_none(*pmd)) {
ptep = pte_offset(pmd, adr);
pte = *ptep;
if(pte_present(pte)) {
ret = (unsigned long)page_address(pte_page(pte));
ret |= (adr & (PAGE_SIZE - 1));
}
}
}
MDEBUG(printk("uv2kva(%lx-->%lx)\n", adr, ret));
return ret;
}
/* 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.
......@@ -150,7 +126,7 @@ static inline unsigned long kvirt_to_pa(unsigned long adr) {
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)\n", adr, ret));
return ret;
......
......@@ -47,6 +47,7 @@
#include <asm/semaphore.h>
#include <asm/processor.h>
#include <linux/wrapper.h>
#include <linux/mm.h>
#if defined (__i386__)
#include <asm/cpufeature.h>
......@@ -372,48 +373,6 @@ static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE;
static unsigned char yQuanTable518[] = OV518_YQUANTABLE;
static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE;
/**********************************************************************
*
* Memory management
*
* This is a shameless copy from the USB-cpia driver (linux kernel
* version 2.3.29 or so, I have no idea what this code actually does ;).
* Actually it seems to be a copy of a shameless copy of the bttv-driver.
* Or that is a copy of a shameless copy of ... (To the powers: is there
* no generic kernel-function to do this sort of stuff?)
*
* Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
* there will be one, but apparentely not yet -jerdfelt
*
* So I copied it again for the OV511 driver -claudio
**********************************************************************/
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
static inline unsigned long
uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
unsigned long ret = 0UL;
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, adr);
if (!pmd_none(*pmd)) {
ptep = pte_offset(pmd, adr);
pte = *ptep;
if (pte_present(pte)) {
ret = (unsigned long)
page_address(pte_page(pte));
ret |= (adr & (PAGE_SIZE - 1));
}
}
}
return ret;
}
/* 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.
......@@ -424,7 +383,7 @@ kvirt_to_pa(unsigned long adr)
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = __pa(kva);
return ret;
}
......
......@@ -52,6 +52,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/wrapper.h>
#include <linux/mm.h>
#include <asm/io.h>
#include "pwc.h"
......@@ -177,37 +178,6 @@ static struct video_device pwc_template = {
/***************************************************************************/
/* Private functions */
/* Memory management functions, nicked from cpia.c, which nicked them from
bttv.c. So far, I've counted duplication of this code 6 times
(bttv, cpia, ibmcam, ov511, pwc, ieee1394).
*/
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
unsigned long ret = 0UL;
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, adr);
if (!pmd_none(*pmd)) {
ptep = pte_offset(pmd, adr);
pte = *ptep;
if(pte_present(pte)) {
ret = (unsigned long) page_address(pte_page(pte));
ret |= (adr & (PAGE_SIZE - 1));
}
}
}
return ret;
}
/* 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.
......@@ -217,7 +187,7 @@ static inline unsigned long kvirt_to_pa(unsigned long adr)
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = __pa(kva);
return ret;
}
......
......@@ -40,6 +40,7 @@ static const char version[] = "0.23";
#include <asm/io.h>
#include <asm/semaphore.h>
#include <linux/wrapper.h>
#include <linux/mm.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
#define virt_to_page(arg) MAP_NR(arg)
......@@ -80,44 +81,8 @@ static struct usb_driver se401_driver;
*
* Memory management
*
* This is a shameless copy from the USB-cpia driver (linux kernel
* version 2.3.29 or so, I have no idea what this code actually does ;).
* Actually it seems to be a copy of a shameless copy of the bttv-driver.
* Or that is a copy of a shameless copy of ... (To the powers: is there
* no generic kernel-function to do this sort of stuff?)
*
* Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
* there will be one, but apparentely not yet -jerdfelt
*
* So I copied it again for the ov511 driver -claudio
*
* Same for the se401 driver -Jeroen
**********************************************************************/
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
unsigned long ret = 0UL;
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, adr);
if (!pmd_none(*pmd)) {
ptep = pte_offset(pmd, adr);
pte = *ptep;
if (pte_present(pte)) {
ret = (unsigned long) page_address(pte_page(pte));
ret |= (adr & (PAGE_SIZE - 1));
}
}
}
return ret;
}
/* 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.
......@@ -127,7 +92,7 @@ static inline unsigned long kvirt_to_pa(unsigned long adr)
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = __pa(kva);
return ret;
}
......
......@@ -26,6 +26,7 @@
#include <linux/wrapper.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <asm/io.h>
......@@ -60,30 +61,6 @@ static int usbvideo_default_procfs_write_proc(
#define MDEBUG(x) do { } while(0) /* Debug memory management */
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
unsigned long usbvideo_uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
unsigned long ret = 0UL;
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, adr);
if (!pmd_none(*pmd)) {
ptep = pte_offset(pmd, adr);
pte = *ptep;
if (pte_present(pte)) {
ret = (unsigned long) page_address(pte_page(pte));
ret |= (adr & (PAGE_SIZE-1));
}
}
}
MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
return ret;
}
/*
* Here we want the physical address of the memory.
* This is used when initializing the contents of the
......@@ -94,7 +71,7 @@ unsigned long usbvideo_kvirt_to_pa(unsigned long adr)
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = usbvideo_uvirt_to_kva(pgd_offset_k(va), va);
kva = page_address(vmalloc_to_page(pgd_offset_k(va), va));
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
return ret;
......
......@@ -330,7 +330,6 @@ void usbvideo_TestPattern(uvd_t *uvd, int fullframe, int pmode);
void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs);
/* Memory allocation routines */
unsigned long usbvideo_uvirt_to_kva(pgd_t *pgd, unsigned long adr);
unsigned long usbvideo_kvirt_to_pa(unsigned long adr);
void *usbvideo_rvmalloc(unsigned long size);
void usbvideo_rvfree(void *mem, unsigned long size);
......
......@@ -516,6 +516,8 @@ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * m
extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
extern struct page * vmalloc_to_page(pgd_t *pgd, unsigned long adr);
#endif /* __KERNEL__ */
#endif
......@@ -1440,3 +1440,27 @@ int make_pages_present(unsigned long addr, unsigned long end)
len, write, 0, NULL, NULL);
return ret == len ? 0 : -1;
}
/*
* Map a vmalloc()-space virtual address to the physical page.
*/
struct page * vmalloc_to_page(pgd_t *pgd, unsigned long addr)
{
struct page *page = NULL;
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, addr);
if (!pmd_none(*pmd)) {
preempt_disable();
ptep = pte_offset_map(pmd, addr);
pte = *ptep;
if (pte_present(pte))
page = pte_page(pte);
pte_unmap(ptep);
preempt_enable();
}
}
return page;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment