blob: 3f1b4a7716290c372b9b6d88ee54d009abde1a5a [file] [log] [blame]
/*
* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef ADSPRPC_H
#define ADSPRPC_H
#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/pagemap.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/list.h>
#include <linux/hash.h>
#include <linux/msm_ion.h>
#include <mach/msm_smd.h>
#include <mach/ion.h>
#include "adsprpc_shared.h"
#ifndef ION_ADSPRPC_HEAP_ID
#define ION_ADSPRPC_HEAP_ID ION_AUDIO_HEAP_ID
#endif
#define RPC_TIMEOUT (5 * HZ)
#define RPC_HASH_BITS 5
#define RPC_HASH_SZ (1 << RPC_HASH_BITS)
#define BALIGN 32
#define LOCK_MMAP(kernel)\
do {\
if (!kernel)\
down_read(&current->mm->mmap_sem);\
} while (0)
#define UNLOCK_MMAP(kernel)\
do {\
if (!kernel)\
up_read(&current->mm->mmap_sem);\
} while (0)
static inline uint32_t buf_page_start(void *buf)
{
uint32_t start = (uint32_t) buf & PAGE_MASK;
return start;
}
static inline uint32_t buf_page_offset(void *buf)
{
uint32_t offset = (uint32_t) buf & (PAGE_SIZE - 1);
return offset;
}
static inline int buf_num_pages(void *buf, int len)
{
uint32_t start = buf_page_start(buf) >> PAGE_SHIFT;
uint32_t end = (((uint32_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
int nPages = end - start + 1;
return nPages;
}
static inline uint32_t buf_page_size(uint32_t size)
{
uint32_t sz = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
return sz > PAGE_SIZE ? sz : PAGE_SIZE;
}
static inline int buf_get_pages(void *addr, int sz, int nr_pages, int access,
struct smq_phy_page *pages, int nr_elems)
{
struct vm_area_struct *vma;
uint32_t start = buf_page_start(addr);
uint32_t len = nr_pages << PAGE_SHIFT;
unsigned long pfn;
int n = -1, err = 0;
VERIFY(err, 0 != access_ok(access ? VERIFY_WRITE : VERIFY_READ,
(void __user *)start, len));
if (err)
goto bail;
VERIFY(err, 0 != (vma = find_vma(current->mm, start)));
if (err)
goto bail;
VERIFY(err, ((uint32_t)addr + sz) <= vma->vm_end);
if (err)
goto bail;
n = 0;
VERIFY(err, 0 == follow_pfn(vma, start, &pfn));
if (err)
goto bail;
VERIFY(err, nr_elems > 0);
if (err)
goto bail;
pages->addr = __pfn_to_phys(pfn);
pages->size = len;
n++;
bail:
return n;
}
#endif