staging: tidspbridge - rename bridge_brd_mem_map/unmap to a proper name

Now these functions only map user space addresses to dsp virtual
addresses, so now the functions have a more meaningful name.
Also now user_to_dsp_map returns the mapped address.

Signed-off-by: Fernando Guzman Lugo <x0095840@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Fernando Guzman Lugo 2010-10-05 15:35:36 -05:00 committed by Greg Kroah-Hartman
parent 0c10e91b6c
commit 4dd1944ab7
5 changed files with 117 additions and 142 deletions

View File

@ -383,4 +383,28 @@ extern s32 dsp_debug;
*/
int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val);
/**
* user_to_dsp_map() - maps user to dsp virtual address
* @mmu: Pointer to iommu handle.
* @uva: Virtual user space address.
* @da DSP address
* @size Buffer size to map.
* @usr_pgs struct page array pointer where the user pages will be stored
*
* This function maps a user space buffer into DSP virtual address.
*
*/
u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size,
struct page **usr_pgs);
/**
* user_to_dsp_unmap() - unmaps DSP virtual buffer.
* @mmu: Pointer to iommu handle.
* @da DSP address
*
* This function unmaps a user space buffer into DSP virtual address.
*
*/
int user_to_dsp_unmap(struct iommu *mmu, u32 da);
#endif /* _TIOMAP_ */

View File

@ -97,12 +97,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt,
static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
u8 *host_buff, u32 dsp_addr,
u32 ul_num_bytes, u32 mem_type);
static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
u32 ul_mpu_addr, u32 virt_addr,
u32 ul_num_bytes, u32 ul_map_attr,
struct page **mapped_pages);
static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
u32 da);
static int bridge_dev_create(struct bridge_dev_context
**dev_cntxt,
struct dev_object *hdev_obj,
@ -110,9 +104,6 @@ static int bridge_dev_create(struct bridge_dev_context
static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
u32 dw_cmd, void *pargs);
static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt);
static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
struct page **usr_pgs);
static u32 user_va2_pa(struct mm_struct *mm, u32 address);
static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
u32 va, u32 size,
struct hw_mmu_map_attrs_t *map_attrs);
@ -182,8 +173,6 @@ static struct bridge_drv_interface drv_interface_fxns = {
bridge_brd_set_state,
bridge_brd_mem_copy,
bridge_brd_mem_write,
bridge_brd_mem_map,
bridge_brd_mem_un_map,
/* The following CHNL functions are provided by chnl_io.lib: */
bridge_chnl_create,
bridge_chnl_destroy,
@ -1154,22 +1143,77 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
}
/*
* ======== bridge_brd_mem_map ========
* This function maps MPU buffer to the DSP address space. It performs
* linear to physical address translation if required. It translates each
* page since linear addresses can be physically non-contiguous
* All address & size arguments are assumed to be page aligned (in proc.c)
*
* TODO: Disable MMU while updating the page tables (but that'll stall DSP)
* ======== user_va2_pa ========
* Purpose:
* This function walks through the page tables to convert a userland
* virtual address to physical address
*/
static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx,
u32 uva, u32 da, u32 size, u32 attr,
struct page **usr_pgs)
static u32 user_va2_pa(struct mm_struct *mm, u32 address)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t *ptep, pte;
pgd = pgd_offset(mm, address);
if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
pmd = pmd_offset(pgd, address);
if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
ptep = pte_offset_map(pmd, address);
if (ptep) {
pte = *ptep;
if (pte_present(pte))
return pte & PAGE_MASK;
}
}
}
return 0;
}
/**
* get_io_pages() - pin and get pages of io user's buffer.
* @mm: mm_struct Pointer of the process.
* @uva: Virtual user space address.
* @pages Pages to be pined.
* @usr_pgs struct page array pointer where the user pages will be stored
*
*/
static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
struct page **usr_pgs)
{
u32 pa;
int i;
struct page *pg;
for (i = 0; i < pages; i++) {
pa = user_va2_pa(mm, uva);
if (!pfn_valid(__phys_to_pfn(pa)))
break;
pg = PHYS_TO_PAGE(pa);
usr_pgs[i] = pg;
get_page(pg);
}
return i;
}
/**
* user_to_dsp_map() - maps user to dsp virtual address
* @mmu: Pointer to iommu handle.
* @uva: Virtual user space address.
* @da DSP address
* @size Buffer size to map.
* @usr_pgs struct page array pointer where the user pages will be stored
*
* This function maps a user space buffer into DSP virtual address.
*
*/
u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size,
struct page **usr_pgs)
{
int res, w;
unsigned pages, i;
struct iommu *mmu = dev_ctx->dsp_mmu;
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
struct sg_table *sgt;
@ -1226,7 +1270,7 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx,
da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
if (!IS_ERR_VALUE(da))
return 0;
return da;
res = (int)da;
sg_free_table(sgt);
@ -1239,21 +1283,21 @@ err_pages:
return res;
}
/*
* ======== bridge_brd_mem_un_map ========
* Invalidate the PTEs for the DSP VA block to be unmapped.
/**
* user_to_dsp_unmap() - unmaps DSP virtual buffer.
* @mmu: Pointer to iommu handle.
* @da DSP address
*
* This function unmaps a user space buffer into DSP virtual address.
*
* PTEs of a mapped memory block are contiguous in any page table
* So, instead of looking up the PTE address for every 4K block,
* we clear consecutive PTEs until we unmap all the bytes
*/
static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da)
int user_to_dsp_unmap(struct iommu *mmu, u32 da)
{
unsigned i;
struct sg_table *sgt;
struct scatterlist *sg;
sgt = iommu_vunmap(dev_ctx->dsp_mmu, da);
sgt = iommu_vunmap(mmu, da);
if (!sgt)
return -EFAULT;
@ -1265,55 +1309,6 @@ static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da)
return 0;
}
static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
struct page **usr_pgs)
{
u32 pa;
int i;
struct page *pg;
for (i = 0; i < pages; i++) {
pa = user_va2_pa(mm, uva);
if (!pfn_valid(__phys_to_pfn(pa)))
break;
pg = PHYS_TO_PAGE(pa);
usr_pgs[i] = pg;
get_page(pg);
}
return i;
}
/*
* ======== user_va2_pa ========
* Purpose:
* This function walks through the page tables to convert a userland
* virtual address to physical address
*/
static u32 user_va2_pa(struct mm_struct *mm, u32 address)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t *ptep, pte;
pgd = pgd_offset(mm, address);
if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
pmd = pmd_offset(pgd, address);
if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
ptep = pte_offset_map(pmd, address);
if (ptep) {
pte = *ptep;
if (pte_present(pte))
return pte & PAGE_MASK;
}
}
}
return 0;
}
/*
* ======== pte_update ========
* This function calculates the optimum page-aligned addresses and sizes

View File

@ -161,48 +161,6 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context
u32 dsp_addr, u32 ul_num_bytes,
u32 mem_type);
/*
* ======== bridge_brd_mem_map ========
* Purpose:
* Map a MPU memory region to a DSP/IVA memory space
* Parameters:
* dev_ctxt: Handle to Bridge driver defined device info.
* ul_mpu_addr: MPU memory region start address.
* virt_addr: DSP/IVA memory region u8 address.
* ul_num_bytes: Number of bytes to map.
* map_attrs: Mapping attributes (e.g. endianness).
* Returns:
* 0: Success.
* -EPERM: Other, unspecified error.
* Requires:
* dev_ctxt != NULL;
* Ensures:
*/
typedef int(*fxn_brd_memmap) (struct bridge_dev_context
* dev_ctxt, u32 ul_mpu_addr,
u32 virt_addr, u32 ul_num_bytes,
u32 map_attr,
struct page **mapped_pages);
/*
* ======== bridge_brd_mem_un_map ========
* Purpose:
* UnMap an MPU memory region from DSP/IVA memory space
* Parameters:
* dev_ctxt: Handle to Bridge driver defined device info.
* virt_addr: DSP/IVA memory region u8 address.
* ul_num_bytes: Number of bytes to unmap.
* Returns:
* 0: Success.
* -EPERM: Other, unspecified error.
* Requires:
* dev_ctxt != NULL;
* Ensures:
*/
typedef int(*fxn_brd_memunmap) (struct bridge_dev_context
* dev_ctxt,
u32 da);
/*
* ======== bridge_brd_stop ========
* Purpose:
@ -993,8 +951,6 @@ struct bridge_drv_interface {
fxn_brd_setstate pfn_brd_set_state; /* Sets the Board State */
fxn_brd_memcopy pfn_brd_mem_copy; /* Copies DSP Memory */
fxn_brd_memwrite pfn_brd_mem_write; /* Write DSP Memory w/o halt */
fxn_brd_memmap pfn_brd_mem_map; /* Maps MPU mem to DSP mem */
fxn_brd_memunmap pfn_brd_mem_un_map; /* Unmaps MPU mem to DSP mem */
fxn_chnl_create pfn_chnl_create; /* Create channel manager. */
fxn_chnl_destroy pfn_chnl_destroy; /* Destroy channel manager. */
fxn_chnl_open pfn_chnl_open; /* Create a new channel. */

View File

@ -1118,8 +1118,6 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
STORE_FXN(fxn_brd_setstate, pfn_brd_set_state);
STORE_FXN(fxn_brd_memcopy, pfn_brd_mem_copy);
STORE_FXN(fxn_brd_memwrite, pfn_brd_mem_write);
STORE_FXN(fxn_brd_memmap, pfn_brd_mem_map);
STORE_FXN(fxn_brd_memunmap, pfn_brd_mem_un_map);
STORE_FXN(fxn_chnl_create, pfn_chnl_create);
STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy);
STORE_FXN(fxn_chnl_open, pfn_chnl_open);

View File

@ -52,6 +52,7 @@
#include <dspbridge/msg.h>
#include <dspbridge/dspioctl.h>
#include <dspbridge/drv.h>
#include <_tiomap.h>
/* ----------------------------------- This */
#include <dspbridge/proc.h>
@ -1357,7 +1358,6 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
int status = 0;
struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
struct dmm_map_object *map_obj;
u32 tmp_addr = 0;
#ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK
if ((ul_map_attr & BUFMODE_MASK) != RBUF) {
@ -1390,24 +1390,27 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
/* Add mapping to the page tables. */
if (!status) {
/* Mapped address = MSB of VA | LSB of PA */
tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1)));
/* mapped memory resource tracking */
map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr,
map_obj = add_mapping_info(pr_ctxt, pa_align, va_align,
size_align);
if (!map_obj)
if (!map_obj) {
status = -ENOMEM;
else
status = (*p_proc_object->intf_fxns->pfn_brd_mem_map)
(p_proc_object->hbridge_context, pa_align, va_align,
size_align, ul_map_attr, map_obj->pages);
} else {
va_align = user_to_dsp_map(
p_proc_object->hbridge_context->dsp_mmu,
pa_align, va_align, size_align,
map_obj->pages);
if (IS_ERR_VALUE(va_align))
status = (int)va_align;
}
}
if (!status) {
/* Mapped address = MSB of VA | LSB of PA */
*pp_map_addr = (void *) tmp_addr;
map_obj->dsp_addr = (va_align |
((u32)pmpu_addr & (PG_SIZE4K - 1)));
*pp_map_addr = (void *)map_obj->dsp_addr;
} else {
remove_mapping_information(pr_ctxt, tmp_addr, size_align);
remove_mapping_information(pr_ctxt, va_align, size_align);
dmm_un_map_memory(dmm_mgr, va_align, &size_align);
}
mutex_unlock(&proc_lock);
@ -1721,10 +1724,9 @@ int proc_un_map(void *hprocessor, void *map_addr,
*/
status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);
/* Remove mapping from the page tables. */
if (!status) {
status = (*p_proc_object->intf_fxns->pfn_brd_mem_un_map)
(p_proc_object->hbridge_context, va_align);
}
if (!status)
status = user_to_dsp_unmap(
p_proc_object->hbridge_context->dsp_mmu, va_align);
mutex_unlock(&proc_lock);
if (status)