Commit 33110a83 authored by Ingo Molnar's avatar Ingo Molnar

- cleanup patch from Hugh Dickins, fix up drivers to use vmalloc_to_page()...

- cleanup patch from Hugh Dickins, fix up drivers to use vmalloc_to_page() instead of local hacks of uvirt_to_kva(). (and related fixes.)
parent 38432d05
......@@ -332,35 +332,8 @@ perfmon_get_stamp(void)
return ia64_get_itc();
}
/* 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));
}
}
}
DBprintk(("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.
* This is used when initializing the contents of the area.
*/
static inline unsigned long
kvirt_to_pa(unsigned long adr)
......@@ -374,19 +347,15 @@ static void *
rvmalloc(unsigned long size)
{
void *mem;
unsigned long adr, page;
unsigned long adr;
/* XXX: may have to revisit this part because
* vmalloc() does not necessarily return a page-aligned buffer.
* This maybe a security problem when mapped at user level
*/
size=PAGE_ALIGN(size);
mem=vmalloc(size);
if (mem) {
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
adr=(unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......@@ -397,13 +366,12 @@ rvmalloc(unsigned long size)
static void
rvfree(void *mem, unsigned long size)
{
unsigned long adr, page;
unsigned long adr;
if (mem) {
adr=(unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
while ((long) size > 0) {
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......@@ -515,7 +483,6 @@ pfm_smpl_buffer_alloc(pfm_context_t *ctx, unsigned long which_pmds, unsigned lon
vma->vm_file = NULL;
vma->vm_raend = 0;
/* XXX: see rvmalloc() for page alignment problem */
smpl_buf = rvmalloc(size);
if (smpl_buf == NULL) goto no_buffer;
......
......@@ -66,9 +66,6 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
drm_scatter_gather_t request;
drm_sg_mem_t *entry;
unsigned long pages, i, j;
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte, pte_entry;
DRM_DEBUG( "%s\n", __FUNCTION__ );
......@@ -135,25 +132,9 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
pgd = pgd_offset_k( i );
if ( !pgd_present( *pgd ) )
entry->pagelist[j] = vmalloc_to_page((void *)i);
if (!entry->pagelist[j])
goto failed;
pmd = pmd_offset( pgd, i );
if ( !pmd_present( *pmd ) )
goto failed;
preempt_disable();
pte = pte_offset_map(pmd, i);
pte_entry = *pte;
pte_unmap(pte);
preempt_enable();
if (!pte_present(pte_entry))
goto failed;
entry->pagelist[j] = pte_page(pte_entry);
SetPageReserved(entry->pagelist[j]);
}
......
......@@ -152,9 +152,6 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
#endif
unsigned long offset;
unsigned long i;
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte, entry;
struct page *page;
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
......@@ -162,26 +159,9 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
offset = address - vma->vm_start;
i = (unsigned long)map->handle + offset;
/* We have to walk page tables here because we need large SAREA's, and
* they need to be virtually contiguous in kernel space.
*/
pgd = pgd_offset_k( i );
if (!pgd_present(*pgd))
goto oom;
pmd = pmd_offset( pgd, i );
if (!pmd_present(*pmd))
goto oom;
preempt_disable();
pte = pte_offset_map(pmd, i);
entry = *pte;
pte_unmap(pte);
preempt_enable();
if (!pte_present(entry))
goto oom;
page = pte_page(entry);
page = vmalloc_to_page((void *)i);
if (!page)
return NOPAGE_OOM;
get_page(page);
DRM_DEBUG("shm_nopage 0x%lx\n", address);
......@@ -190,8 +170,6 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
#else
return page;
#endif
oom:
return NOPAGE_OOM;
}
/* Special close routine which deletes map information if we are the last
......
......@@ -185,78 +185,19 @@ static inline struct video_card* file_to_video_card(struct file *file)
/* Memory management functions */
/*******************************/
#define MDEBUG(x) do { } while(0) /* Debug memory management */
/* [DaveM] I've recoded most of this so that:
* 1) It's easier to tell what is happening
* 2) It's more portable, especially for translating things
* out of vmalloc mapped areas in the kernel.
* 3) Less unnecessary translations happen.
*
* The code used to assume that the kernel vmalloc mappings
* existed in the page tables of every process, this is simply
* not guarenteed. We now use pgd_offset_k which is the
* defined way to get at the kernel page tables.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
#define page_address(x) (x)
#endif
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
static inline struct page *uvirt_to_page(pgd_t *pgd, unsigned long adr)
{
pmd_t *pmd;
pte_t *ptep, pte;
struct page *ret = NULL;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, adr);
if (!pmd_none(*pmd)) {
preempt_disable();
ptep = pte_offset_map(pmd, adr);
pte = *ptep;
pte_unmap(pte);
preempt_enable();
if(pte_present(pte))
ret = pte_page(pte);
}
}
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, and for
* handling page faults on the rvmalloc()ed buffer
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
unsigned long va, kva, ret;
va = VMALLOC_VMADDR(adr);
kva = (unsigned long) page_address(uvirt_to_page(pgd_offset_k(va), va));
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
return ret;
}
static void * rvmalloc(unsigned long size)
{
void * mem;
unsigned long adr, page;
unsigned long adr;
size=PAGE_ALIGN(size);
mem=vmalloc_32(size);
if (mem) {
memset(mem, 0, size); /* Clear the ram out,
no junk to the user */
adr=(unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......@@ -266,13 +207,12 @@ static void * rvmalloc(unsigned long size)
static void rvfree(void * mem, unsigned long size)
{
unsigned long adr, page;
unsigned long adr;
if (mem) {
adr=(unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
while ((long) size > 0) {
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......@@ -1166,9 +1106,9 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
/* fill the sglist with the kernel addresses of pages in the non-contiguous buffer */
for(i = 0; i < video->user_dma.n_pages; i++) {
unsigned long va = VMALLOC_VMADDR( (unsigned long) video->user_buf + i * PAGE_SIZE );
unsigned long va = (unsigned long) video->user_buf + i * PAGE_SIZE;
video->user_dma.sglist[i].page = uvirt_to_page(pgd_offset_k(va), va);
video->user_dma.sglist[i].page = vmalloc_to_page((void *)va);
video->user_dma.sglist[i].length = PAGE_SIZE;
}
......@@ -1492,7 +1432,7 @@ static int do_dv1394_shutdown(struct video_card *video, int free_user_buf)
static struct page * dv1394_nopage(struct vm_area_struct * area, unsigned long address, int write_access)
{
unsigned long offset;
unsigned long page, kernel_virt_addr;
unsigned long kernel_virt_addr;
struct page *ret = NOPAGE_SIGBUS;
struct video_card *video = (struct video_card*) area->vm_private_data;
......@@ -1510,10 +1450,7 @@ static struct page * dv1394_nopage(struct vm_area_struct * area, unsigned long a
offset = address - area->vm_start;
kernel_virt_addr = (unsigned long) video->user_buf + offset;
page = kvirt_to_pa(kernel_virt_addr);
ret = virt_to_page(__va(page));
ret = vmalloc_to_page((void *)kernel_virt_addr);
get_page(ret);
out:
......
......@@ -159,49 +159,35 @@ static struct hpsb_highlevel *hl_handle = NULL;
/* Memory management functions */
/*******************************/
#define MDEBUG(x) do { } while(0) /* Debug memory management */
/* [DaveM] I've recoded most of this so that:
* 1) It's easier to tell what is happening
* 2) It's more portable, especially for translating things
* out of vmalloc mapped areas in the kernel.
* 3) Less unnecessary translations happen.
*
* The code used to assume that the kernel vmalloc mappings
* existed in the page tables of every process, this is simply
* not guaranteed. We now use pgd_offset_k which is the
* defined way to get at the kernel page tables.
*/
static inline unsigned long kvirt_to_bus(unsigned long adr)
{
unsigned long kva, ret;
kva = page_address(vmalloc_to_page((void *)adr));
kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
ret = virt_to_bus((void *)kva);
MDEBUG(printk("kv2b(%lx-->%lx)", 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.
* This is used when initializing the contents of the area.
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
unsigned long kva, ret;
kva = page_address(vmalloc_to_page((void *)adr));
kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
return ret;
}
static void * rvmalloc(unsigned long size)
{
void * mem;
unsigned long adr, page;
unsigned long adr;
size=PAGE_ALIGN(size);
mem=vmalloc_32(size);
if (mem)
{
......@@ -210,8 +196,7 @@ static void * rvmalloc(unsigned long size)
adr=(unsigned long) mem;
while (size > 0)
{
page = kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......@@ -221,15 +206,14 @@ static void * rvmalloc(unsigned long size)
static void rvfree(void * mem, unsigned long size)
{
unsigned long adr, page;
unsigned long adr;
if (mem)
{
adr=(unsigned long) mem;
while (size > 0)
while ((long) size > 0)
{
page = kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......@@ -1369,7 +1353,7 @@ int video1394_mmap(struct file *file, struct vm_area_struct *vma)
if (video->current_ctx == NULL) {
PRINT(KERN_ERR, ohci->id, "Current iso context not set");
} else
res = do_iso_mmap(ohci, video->current_ctx,
res = do_iso_mmap(vma, ohci, video->current_ctx,
(char *)vma->vm_start,
(unsigned long)(vma->vm_end-vma->vm_start));
unlock_kernel();
......
......@@ -172,8 +172,7 @@ static inline unsigned long kvirt_to_bus(unsigned long addr)
}
/* 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.
* This is used when initializing the contents of the area.
*/
static inline unsigned long kvirt_to_pa(unsigned long addr)
{
......@@ -183,14 +182,15 @@ static inline unsigned long kvirt_to_pa(unsigned long addr)
return ret;
}
static void * rvmalloc(signed long size)
static void * rvmalloc(unsigned long size)
{
void * mem;
unsigned long adr;
size=PAGE_ALIGN(size);
mem=vmalloc_32(size);
if (NULL == mem)
printk(KERN_INFO "bttv: vmalloc_32(%ld) failed\n",size);
printk(KERN_INFO "bttv: vmalloc_32(%lu) failed\n",size);
else {
/* Clear the ram out, no junk to the user */
memset(mem, 0, size);
......@@ -205,14 +205,14 @@ static void * rvmalloc(signed long size)
return mem;
}
static void rvfree(void * mem, signed long size)
static void rvfree(void * mem, unsigned long size)
{
unsigned long adr;
if (mem)
{
adr=(unsigned long) mem;
while (size > 0)
while ((long) size > 0)
{
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
......
......@@ -181,14 +181,14 @@ static void reset_camera_struct(struct cam_data *cam);
**********************************************************************/
/* 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.
* This is used when initializing the contents of the area.
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
unsigned long kva, ret;
kva = page_address(vmalloc_to_page((void *)adr));
kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
ret = __pa(kva);
return ret;
}
......@@ -196,12 +196,9 @@ static inline unsigned long kvirt_to_pa(unsigned long adr)
static void *rvmalloc(unsigned long size)
{
void *mem;
unsigned long adr, page;
/* Round it off to PAGE_SIZE */
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
unsigned long adr;
size = PAGE_ALIGN(size);
mem = vmalloc_32(size);
if (!mem)
return NULL;
......@@ -209,13 +206,9 @@ static void *rvmalloc(unsigned long size)
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
adr = (unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
return mem;
......@@ -223,23 +216,16 @@ static void *rvmalloc(unsigned long size)
static void rvfree(void *mem, unsigned long size)
{
unsigned long adr, page;
unsigned long adr;
if (!mem)
return;
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
adr = (unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
while ((long) size > 0) {
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
vfree(mem);
}
......
......@@ -115,33 +115,29 @@ static inline int meye_emptyq(struct meye_queue *queue, int *elem) {
/* Memory allocation routines (stolen from bttv-driver.c) */
/****************************************************************************/
#define MDEBUG(x) do {} while (0)
/* #define MDEBUG(x) x */
/* 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.
* This is used when initializing the contents of the area.
*/
static inline unsigned long kvirt_to_pa(unsigned long adr) {
unsigned long kva, ret;
kva = page_address(vmalloc_to_page((void *) adr));
kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)\n", adr, ret));
return ret;
}
static void *rvmalloc(signed long size) {
static void *rvmalloc(unsigned long size) {
void *mem;
unsigned long adr, page;
unsigned long adr;
size = PAGE_ALIGN(size);
mem = vmalloc_32(size);
if (mem) {
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
adr = (unsigned long)mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
size -= PAGE_SIZE;
}
......@@ -149,14 +145,13 @@ static void *rvmalloc(signed long size) {
return mem;
}
static void rvfree(void * mem, signed long size) {
unsigned long adr, page;
static void rvfree(void * mem, unsigned long size) {
unsigned long adr;
if (mem) {
adr = (unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
while ((long) size > 0) {
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
size -= PAGE_SIZE;
}
......
......@@ -379,15 +379,15 @@ static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE;
**********************************************************************/
/* 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.
* This is used when initializing the contents of the area.
*/
static inline unsigned long
kvirt_to_pa(unsigned long adr)
{
unsigned long kva, ret;
kva = page_address(vmalloc_to_page((void *)adr));
kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
ret = __pa(kva);
return ret;
}
......@@ -396,12 +396,9 @@ static void *
rvmalloc(unsigned long size)
{
void *mem;
unsigned long adr, page;
/* Round it off to PAGE_SIZE */
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
unsigned long adr;
size = PAGE_ALIGN(size);
mem = vmalloc_32(size);
if (!mem)
return NULL;
......@@ -409,13 +406,9 @@ rvmalloc(unsigned long size)
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
adr = (unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
return mem;
......@@ -424,23 +417,16 @@ rvmalloc(unsigned long size)
static void
rvfree(void *mem, unsigned long size)
{
unsigned long adr, page;
unsigned long adr;
if (!mem)
return;
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
adr=(unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
adr = (unsigned long) mem;
while ((long) size > 0) {
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
vfree(mem);
}
......
......@@ -179,27 +179,24 @@ static struct video_device pwc_template = {
/* Private functions */
/* 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.
* This is used when initializing the contents of the area.
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
unsigned long kva, ret;
kva = page_address(vmalloc_to_page((void *)adr));
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(signed long size)
static void * rvmalloc(unsigned long size)
{
void * mem;
unsigned long adr, page;
unsigned long adr;
/* Round it off to PAGE_SIZE */
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
size=PAGE_ALIGN(size);
mem=vmalloc_32(size);
if (mem)
{
......@@ -207,8 +204,7 @@ static void * rvmalloc(signed long size)
adr=(unsigned long) mem;
while (size > 0)
{
page = kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......@@ -216,20 +212,16 @@ static void * rvmalloc(signed long size)
return mem;
}
static void rvfree(void * mem, signed long size)
static void rvfree(void * mem, unsigned long size)
{
unsigned long adr, page;
/* Round it off to PAGE_SIZE */
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
unsigned long adr;
if (mem)
{
adr=(unsigned long) mem;
while (size > 0)
while ((long) size > 0)
{
page = kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......
......@@ -84,14 +84,14 @@ static struct usb_driver se401_driver;
**********************************************************************/
/* 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.
* This is used when initializing the contents of the area.
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
unsigned long kva, ret;
kva = page_address(vmalloc_to_page((void *)adr));
kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
ret = __pa(kva);
return ret;
}
......@@ -99,12 +99,9 @@ static inline unsigned long kvirt_to_pa(unsigned long adr)
static void *rvmalloc(unsigned long size)
{
void *mem;
unsigned long adr, page;
/* Round it off to PAGE_SIZE */
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
unsigned long adr;
size = PAGE_ALIGN(size);
mem = vmalloc_32(size);
if (!mem)
return NULL;
......@@ -112,13 +109,9 @@ static void *rvmalloc(unsigned long size)
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
adr = (unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
return mem;
......@@ -126,23 +119,16 @@ static void *rvmalloc(unsigned long size)
static void rvfree(void *mem, unsigned long size)
{
unsigned long adr, page;
unsigned long adr;
if (!mem)
return;
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
adr=(unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
adr = (unsigned long) mem;
while ((long) size > 0) {
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
vfree(mem);
}
......
......@@ -127,54 +127,25 @@ EXPORT_NO_SYMBOLS;
* And the STV0680 driver - Kevin
********************************************************************/
/* 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)) {
preempt_disable();
ptep = pte_offset_map (pmd, adr);
pte = *ptep;
pte_unmap(pte);
preempt_enable();
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.
/* Here we want the physical address of the memory.
* This is used when initializing the contents of the area.
*/
static inline unsigned long kvirt_to_pa (unsigned long adr)
{
unsigned long va, kva, ret;
unsigned long kva, ret;
va = VMALLOC_VMADDR (adr);
kva = uvirt_to_kva (pgd_offset_k (va), va);
ret = __pa (kva);
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, page;
/* Round it off to PAGE_SIZE */
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
unsigned long adr;
size = PAGE_ALIGN(size);
mem = vmalloc_32 (size);
if (!mem)
return NULL;
......@@ -182,36 +153,25 @@ static void *rvmalloc (unsigned long size)
memset (mem, 0, size); /* Clear the ram out, no junk to the user */
adr = (unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa (adr);
mem_map_reserve (virt_to_page (__va (page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
return mem;
}
static void rvfree (void *mem, unsigned long size)
{
unsigned long adr, page;
unsigned long adr;
if (!mem)
return;
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
adr = (unsigned long) mem;
while (size > 0) {
page = kvirt_to_pa (adr);
mem_map_unreserve (virt_to_page (__va (page)));
while ((long) size > 0) {
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
vfree (mem);
}
......
......@@ -59,32 +59,26 @@ static int usbvideo_default_procfs_write_proc(
/* Memory management functions */
/*******************************/
#define MDEBUG(x) do { } while(0) /* Debug memory management */
/*
* 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.
* This is used when initializing the contents of the area.
*/
unsigned long usbvideo_kvirt_to_pa(unsigned long adr)
{
unsigned long kva, ret;
kva = page_address(vmalloc_to_page((void *)adr));
kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
return ret;
}
void *usbvideo_rvmalloc(unsigned long size)
{
void *mem;
unsigned long adr, page;
/* Round it off to PAGE_SIZE */
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
unsigned long adr;
size = PAGE_ALIGN(size);
mem = vmalloc_32(size);
if (!mem)
return NULL;
......@@ -92,13 +86,9 @@ void *usbvideo_rvmalloc(unsigned long size)
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
adr = (unsigned long) mem;
while (size > 0) {
page = usbvideo_kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
return mem;
......@@ -106,23 +96,16 @@ void *usbvideo_rvmalloc(unsigned long size)
void usbvideo_rvfree(void *mem, unsigned long size)
{
unsigned long adr, page;
unsigned long adr;
if (!mem)
return;
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
adr=(unsigned long) mem;
while (size > 0) {
page = usbvideo_kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
adr = (unsigned long) mem;
while ((long) size > 0) {
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
size -= PAGE_SIZE;
}
vfree(mem);
}
......
......@@ -93,83 +93,25 @@ static int vicam_parameters(struct usb_vicam *vicam);
*
******************************************************************************/
/* [DaveM] I've recoded most of this so that:
* 1) It's easier to tell what is happening
* 2) It's more portable, especially for translating things
* out of vmalloc mapped areas in the kernel.
* 3) Less unnecessary translations happen.
*
* The code used to assume that the kernel vmalloc mappings
* existed in the page tables of every process, this is simply
* not guarenteed. We now use pgd_offset_k which is the
* 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)) {
preempt_disable();
ptep = pte_offset_map(pmd, adr);
pte = *ptep;
pte_unmap(pte);
preempt_enable();
if(pte_present(pte)) {
ret = (unsigned long) page_address(pte_page(pte));
ret |= (adr & (PAGE_SIZE - 1));
}
}
}
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);
ret = virt_to_bus((void *)kva);
return ret;
}
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);
ret = virt_to_bus((void *)kva);
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.
* This is used when initializing the contents of the area.
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
unsigned long va, kva, ret;
unsigned long kva, ret;
va = VMALLOC_VMADDR(adr);
kva = uvirt_to_kva(pgd_offset_k(va), va);
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(signed long size)
static void * rvmalloc(unsigned long size)
{
void * mem;
unsigned long adr, page;
unsigned long adr;
size=PAGE_ALIGN(size);
mem=vmalloc_32(size);
if (mem)
{
......@@ -177,8 +119,7 @@ static void * rvmalloc(signed long size)
adr=(unsigned long) mem;
while (size > 0)
{
page = kvirt_to_pa(adr);
mem_map_reserve(virt_to_page(__va(page)));
mem_map_reserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......@@ -186,17 +127,16 @@ static void * rvmalloc(signed long size)
return mem;
}
static void rvfree(void * mem, signed long size)
static void rvfree(void * mem, unsigned long size)
{
unsigned long adr, page;
unsigned long adr;
if (mem)
{
adr=(unsigned long) mem;
while (size > 0)
while ((long) size > 0)
{
page = kvirt_to_pa(adr);
mem_map_unreserve(virt_to_page(__va(page)));
mem_map_unreserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
......
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