Line 52... |
Line 52... |
|
|
return error;
|
return error;
|
}
|
}
|
|
|
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
/*
|
|
static int copy_memory_descriptors(unsigned long arg, struct memory_descriptor *md, struct memory_block **mb)
|
|
{
|
|
struct memory_block *mblocks = NULL;
|
|
int error = 0;
|
|
//int i = 0;
|
|
|
|
if(copy_from_user((void*)md, (void*)arg, sizeof(struct memory_descriptor))) {
|
|
err_msg(err_trace, "%s(): Error copy memory descriptor from user space\n", __FUNCTION__);
|
|
error = -EINVAL;
|
|
goto do_exit;
|
|
}
|
|
|
|
dbg_msg(dbg_trace, "%s(): md.total_blocks = %zd\n", __FUNCTION__, md->total_blocks );
|
|
dbg_msg(dbg_trace, "%s(): md.blocks = %p\n", __FUNCTION__, md->blocks );
|
|
|
|
mblocks = kzalloc(md->total_blocks*sizeof(struct memory_block), GFP_KERNEL);
|
|
if(!mblocks) {
|
|
err_msg(err_trace, "%s(): Error allocate memory for memory descriptors\n", __FUNCTION__);
|
|
error = -ENOMEM;
|
|
goto do_exit;
|
|
}
|
|
|
|
if(copy_from_user((void*)mblocks, (void*)md->blocks, md->total_blocks*sizeof(struct memory_block))) {
|
|
err_msg(err_trace, "%s(): Error copy memory blocks from user space\n", __FUNCTION__);
|
|
error = -EINVAL;
|
|
goto do_free_mem;
|
|
}
|
|
|
|
//for(i=0; i<md->total_blocks; i++) {
|
|
// dbg_msg(dbg_trace, "%s(): mb[%d].size = 0x%x\n", __FUNCTION__, i, mblocks[i].size );
|
|
//}
|
|
|
|
*mb = mblocks;
|
|
|
|
return 0;
|
|
|
|
do_free_mem:
|
|
kfree(mb);
|
|
|
|
do_exit:
|
|
return error;
|
|
}
|
|
*/
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static void* allocate_memory_block(struct pex_device *brd, size_t block_size, dma_addr_t *dma_addr)
|
|
{
|
|
struct mem_t *m = NULL;
|
|
void *cpu_addr = NULL;
|
|
dma_addr_t dma_handle = {0};
|
|
int locked = 0;
|
|
|
|
spin_lock(&brd->m_MemListLock);
|
|
|
|
m = (struct mem_t*)kzalloc(sizeof(struct mem_t), GFP_KERNEL);
|
|
if(!m) {
|
|
err_msg(err_trace, "%s(): Error allocate memory for mem_t descriptor\n", __FUNCTION__);
|
|
goto do_exit;
|
|
}
|
|
|
|
cpu_addr = dma_alloc_coherent(&brd->m_pci->dev, block_size, &dma_handle, GFP_KERNEL);
|
|
if(!cpu_addr) {
|
|
err_msg(err_trace, "%s(): Error allocate physical memory block.\n", __FUNCTION__);
|
|
goto do_free_mem;
|
|
}
|
|
|
|
*dma_addr = dma_handle;
|
|
m->dma_handle = dma_handle;
|
|
m->cpu_addr = cpu_addr;
|
|
m->size = block_size;
|
|
|
|
locked = lock_pages(m->cpu_addr, m->size);
|
|
|
|
list_add_tail(&m->list, &brd->m_MemList);
|
|
|
|
atomic_inc(&brd->m_MemListCount);
|
|
|
|
dbg_msg(dbg_trace, "%s(): %d: PA = 0x%zx, VA = %p, SZ = 0x%zx, PAGES = %d\n",
|
|
__FUNCTION__, atomic_read(&brd->m_MemListCount), (size_t)m->dma_handle, m->cpu_addr, m->size, locked );
|
|
|
|
spin_unlock(&brd->m_MemListLock);
|
|
|
|
return cpu_addr;
|
|
|
|
do_free_mem:
|
|
kfree(m);
|
|
|
|
do_exit:
|
|
spin_unlock(&brd->m_MemListLock);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
static int free_memory_block(struct pex_device *brd, struct memory_block mb)
|
|
{
|
|
struct list_head *pos, *n;
|
|
struct mem_t *m = NULL;
|
|
int unlocked = 0;
|
|
|
|
spin_lock(&brd->m_MemListLock);
|
|
|
|
list_for_each_safe(pos, n, &brd->m_MemList) {
|
|
|
|
m = list_entry(pos, struct mem_t, list);
|
|
|
|
if(m->dma_handle != mb.phys)
|
|
continue;
|
|
|
|
unlocked = unlock_pages(m->cpu_addr, m->size);
|
|
|
|
dma_free_coherent(&brd->m_pci->dev, m->size, m->cpu_addr, m->dma_handle);
|
|
|
|
dbg_msg(dbg_trace, "%s(): %d: PA = 0x%zx, VA = %p, SZ = 0x%zx, PAGES = %d\n",
|
|
__FUNCTION__, atomic_read(&brd->m_MemListCount), (size_t)m->dma_handle, m->cpu_addr, m->size, unlocked );
|
|
|
|
list_del(pos);
|
|
|
|
atomic_dec(&brd->m_MemListCount);
|
|
|
|
kfree(m);
|
|
}
|
|
|
|
spin_unlock(&brd->m_MemListLock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
int ioctl_memory_alloc(struct pex_device *brd, unsigned long arg)
|
int ioctl_memory_alloc(struct pex_device *brd, unsigned long arg)
|
{
|
{
|
struct memory_block mb = {0};
|
struct memory_block mb = {0};
|
dma_addr_t dma_handle = {0};
|
dma_addr_t dma_handle = {0};
|