summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Makefile.am6
-rw-r--r--bmm_drv.h42
-rw-r--r--bmm_lib.c726
-rw-r--r--bmm_lib.h28
-rw-r--r--bmm_lib.pmem.c287
-rw-r--r--bmm_lib_priv.h51
-rw-r--r--bmm_test.c324
-rw-r--r--configure.ac6
-rw-r--r--debian/changelog7
-rw-r--r--debian/control17
-rw-r--r--debian/libbmm-dev.install1
-rw-r--r--debian/libbmm2.install (renamed from debian/libbmm1.install)0
-rwxr-xr-xdebian/rules3
14 files changed, 219 insertions, 1284 deletions
diff --git a/.gitignore b/.gitignore
index e1d0b76..2b9488f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,10 +19,13 @@ debian/*.log
debian/*.substvars
debian/libbmm-common/
debian/libbmm-dev/
-debian/libbmm1/
+debian/libbmm2/
debian/libbmm*-dbg/
debian/tmp/
debian/*.dirs
debian/*.shlibs
debian/*.symbols
debian/files
+debian/*.debhelper
+debian/autoreconf.after
+debian/autoreconf.before
diff --git a/Makefile.am b/Makefile.am
index fe67d9c..c32571d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,7 @@ libbmm_la_LTLIBRARIES = libbmm.la
libbmm_ladir = $(libdir)
libbmm_la_LDFLAGS = -no-undefined -export-symbols-regex "bmm_*" \
-version-info @ABI_VERSION@:@ABI_REVISION@:@ABI_AGE@
-libbmm_la_SOURCES = bmm_lib.c bmm_lib_priv.h rb.c rb.h
+libbmm_la_SOURCES = bmm_lib.c bmm_drv.h rb.c rb.h
libbmm_laincludedir = $(includedir)
libbmm_lainclude_HEADERS = bmm_lib.h
@@ -13,10 +13,6 @@ libbmm_lainclude_HEADERS = bmm_lib.h
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libbmm.pc
-bin_PROGRAMS = bmm_test
-bmm_test_SOURCES = bmm_test.c
-bmm_test_LDADD = libbmm.la
-
dataudevdir = @udevrulesdir@
dataudev_DATA = etc/udev/rules.d/99-bmm.rules
diff --git a/bmm_drv.h b/bmm_drv.h
new file mode 100644
index 0000000..77855d4
--- /dev/null
+++ b/bmm_drv.h
@@ -0,0 +1,42 @@
+/*
+ * bmm_drv.h
+ *
+ * Copyright (C) 2013 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, you can distribute this file under the GNU Lesser
+ * General Public License version 2.1 as published by the Free Software
+ * Foundation.
+ */
+#ifndef __BMM_DRV_H__
+#define __BMM_DRV_H__
+
+#include <stdint.h>
+
+#define BMM_DEVICE_FILE "/dev/bmm"
+#define BMM_MINOR 94
+
+/* ioctl commands */
+struct bmm_dmabuf_alloc {
+ uint64_t size;
+ uint64_t align;
+ uint32_t attr;
+ int32_t fd;
+};
+
+struct bmm_dmabuf_flush {
+ uint64_t size;
+ uint64_t offset;
+ uint64_t ptr;
+ int32_t fd;
+ uint32_t direction;
+};
+
+#define BMEM_IOCTL_MAGIC 'G'
+#define BMM_DMABUF_ALLOC _IOWR(BMEM_IOCTL_MAGIC, 64, struct bmm_dmabuf_alloc)
+#define BMM_DMABUF_FLUSH _IOW(BMEM_IOCTL_MAGIC, 65, struct bmm_dmabuf_flush)
+
+#endif /* __BMM_DRV_H__ */
diff --git a/bmm_lib.c b/bmm_lib.c
index d6a3271..3a202f3 100644
--- a/bmm_lib.c
+++ b/bmm_lib.c
@@ -16,13 +16,14 @@
#include <sys/stat.h>
#include <sys/mman.h>
#include <assert.h>
+#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include "bmm_lib_priv.h"
+#include "bmm_drv.h"
#include "bmm_lib.h"
#include "rb.h"
@@ -34,35 +35,15 @@
#define pr_debug(fmt, arg...) do { if (0) fprintf(stderr, fmt, ##arg); } while (0)
#endif
-#define API_FEAT_MIN 0x0000
-#define API_COMP_MAX 0x0001
-#define API_FEAT(x) ((x) >> 16)
-#define API_COMP(x) ((x) & 0xffff)
-#define API_FEAT_GET_DMABUF_FD 0x0001
-#define API_FEAT_FREE_PHYS 0x0002
-#define API_FEAT_KEEP_FORK 0x0003
-
-static unsigned bmm_api;
static int bmm_fd = -1;
+static int bmm_use;
static pthread_mutex_t bmm_mutex = PTHREAD_MUTEX_INITIALIZER;
-static Rb_node virt_rb;
-static Rb_node phys_rb;
-
-struct bmm_virt_buffer;
-
-struct bmm_phys_buffer {
- unsigned long paddr;
- size_t size;
- int attr;
- struct bmm_virt_buffer *virt;
- unsigned attach;
-};
+static Rb_node bmm_virt_rb;
struct bmm_virt_buffer {
void *vaddr;
size_t size;
- unsigned phys_offset;
- struct bmm_phys_buffer *phys;
+ int fd;
};
static int cmp_virt(const void *key, const void *val)
@@ -70,17 +51,7 @@ static int cmp_virt(const void *key, const void *val)
const struct bmm_virt_buffer *vbuf = val;
void *k = (void *)key;
- return (k < vbuf->vaddr) ? -1 :
- (k - vbuf->vaddr < vbuf->size) ? 0 : 1;
-}
-
-static int cmp_phys(const void *key, const void *val)
-{
- const struct bmm_phys_buffer *pbuf = val;
- unsigned long k = (unsigned long)key;
-
- return (k < pbuf->paddr) ? -1 :
- (k - pbuf->paddr < pbuf->size) ? 0 : 1;
+ return (k < vbuf->vaddr) ? -1 : (k - vbuf->vaddr < vbuf->size) ? 0 : 1;
}
static struct bmm_virt_buffer *bmm_buf_find_virt(void *virt)
@@ -89,12 +60,12 @@ static struct bmm_virt_buffer *bmm_buf_find_virt(void *virt)
Rb_node node;
int found = 0;
- node = rb_find_key_n(virt_rb, virt, cmp_virt, &found);
+ node = rb_find_key_n(bmm_virt_rb, virt, cmp_virt, &found);
if (found) {
vbuf = rb_val(node);
- pr_debug("rb: %s(%p) phys=0x%08lx virt=%p size=0x%08zx\n",
- "find_virt", virt, vbuf->phys->paddr, vbuf->vaddr,
+ pr_debug("rb: %s(%p) virt=%p size=0x%08zx\n",
+ "find_virt", virt, vbuf->vaddr,
vbuf->size);
} else {
pr_debug("rb: %s(%p): not found\n",
@@ -104,66 +75,15 @@ static struct bmm_virt_buffer *bmm_buf_find_virt(void *virt)
return vbuf;
}
-static struct bmm_phys_buffer *bmm_buf_find_phys(unsigned long phys)
-{
- struct bmm_phys_buffer *pbuf = NULL;
- Rb_node node;
- int found = 0;
-
- node = rb_find_key_n(phys_rb, (void *)phys, cmp_phys, &found);
- if (found) {
- pbuf = rb_val(node);
-
- pr_debug("rb: %s(0x%08lx) phys=0x%08lx size=0x%08zx\n",
- "find_phys", (unsigned long)phys, pbuf->paddr, pbuf->size);
- } else {
- pr_debug("rb: %s(0x%08lx): not found\n",
- "find_phys", (unsigned long)phys);
- }
-
- return pbuf;
-}
-
-static void bmm_rb_phys_remove(struct bmm_phys_buffer *pbuf)
-{
- Rb_node node;
- int found = 0;
-
- pr_debug("%s: phys=0x%08lx size=0x%08zx\n",
- __FUNCTION__, pbuf->paddr, pbuf->size);
-
- node = rb_find_key_n(phys_rb, (void *)pbuf->paddr, cmp_phys, &found);
- assert(found);
- rb_delete_node(node);
-}
-
-static void bmm_rb_phys_insert(struct bmm_phys_buffer *pbuf)
-{
- Rb_node node;
- int found = 0;
-
- pr_debug("%s: phys=0x%08lx size=0x%08zx\n",
- __FUNCTION__, pbuf->paddr, pbuf->size);
-
- node = rb_find_key_n(phys_rb, (void *)pbuf->paddr, cmp_phys, &found);
- if (found) {
- struct bmm_phys_buffer *f = rb_val(node);
- pr_debug("rb: found: %p\n", f);
- pr_debug(" p0x%08lx s0x%08zx\n", f->paddr, f->size);
- }
- assert(found == 0);
- rb_insert_b(node, pbuf);
-}
-
static void bmm_rb_virt_remove(struct bmm_virt_buffer *vbuf)
{
Rb_node node;
int found = 0;
- pr_debug("%s: phys=0x%08lx virt=%p size=0x%08zx\n",
- __FUNCTION__, vbuf->phys->paddr, vbuf->vaddr, vbuf->size);
+ pr_debug("%s: virt=%p size=0x%08zx\n",
+ __FUNCTION__, vbuf->vaddr, vbuf->size);
- node = rb_find_key_n(virt_rb, vbuf->vaddr, cmp_virt, &found);
+ node = rb_find_key_n(bmm_virt_rb, vbuf->vaddr, cmp_virt, &found);
assert(found);
rb_delete_node(node);
}
@@ -173,583 +93,229 @@ static void bmm_rb_virt_insert(struct bmm_virt_buffer *vbuf)
Rb_node node;
int found = 0;
- pr_debug("%s: phys=0x%08lx virt=%p size=0x%08zx\n",
- __FUNCTION__, vbuf->phys->paddr, vbuf->vaddr, vbuf->size);
+ pr_debug("%s: virt=%p size=0x%08zx\n",
+ __FUNCTION__, vbuf->vaddr, vbuf->size);
- node = rb_find_key_n(virt_rb, vbuf->vaddr, cmp_virt, &found);
+ node = rb_find_key_n(bmm_virt_rb, vbuf->vaddr, cmp_virt, &found);
if (found) {
struct bmm_virt_buffer *f = rb_val(node);
pr_debug("rb: found: %p\n", f);
- pr_debug(" p0x%08lx v%p s0x%08zx\n", f->phys->paddr, f->vaddr, f->size);
+ pr_debug(" v%p s0x%08zx\n", f->vaddr, f->size);
}
assert(found == 0);
rb_insert_b(node, vbuf);
}
-static int bmm_get_api_version(void)
+/**
+ * bmm_dmabuf_alloc - allocate a DMA buffer
+ * @size: size of DMA buffer
+ * @attr: attributes of DMA buffer
+ * @align: requested alignment
+ *
+ * Returns: dma_buf file descriptor referring to buffer
+ */
+int bmm_dmabuf_alloc(unsigned long size, int attr, unsigned align)
{
- ioctl_arg_t io;
-
- /* Get the BMM API version */
- io.input = 0;
- io.arg = 0;
- io.output = 0;
- if (ioctl(bmm_fd, BMM_API_VERSION, &io) == 0 &&
- io.input == 0xdeaddead && io.arg == 0xfacebeef)
- bmm_api = io.output;
- else
- bmm_api = 0;
-
- pr_debug("BMM API version %08x\n", bmm_api);
-
- if (API_FEAT(bmm_api) < API_FEAT_MIN ||
- API_COMP(bmm_api) > API_COMP_MAX)
- return -1;
-
- return 0;
-}
+ struct bmm_dmabuf_alloc arg;
+ int ret;
-int bmm_init(void)
-{
- if (bmm_fd < 0) {
- virt_rb = make_rb();
- phys_rb = make_rb();
- if (!virt_rb || !phys_rb)
- goto err_rb;
+ /* obsolete, only for back-compatible */
+ if (attr & BMM_ATTR_NONBUFFERABLE && attr & BMM_ATTR_NONCACHEABLE)
+ attr = BMM_ATTR_NONCACHED;
- /* attempt to open the BMM driver */
- bmm_fd = open(BMM_DEVICE_FILE, O_RDWR | O_CLOEXEC);
- pr_debug("BMM device fd: %d\n", bmm_fd);
- if (bmm_fd < 0)
- goto err_open;
+ if (!(attr & BMM_ATTR_NONBUFFERABLE) && attr & BMM_ATTR_NONCACHEABLE)
+ attr = BMM_ATTR_WRITECOMBINE;
- if (bmm_get_api_version() < 0)
- goto err_api;
- }
+ arg.size = size;
+ arg.align = align;
+ arg.attr = attr;
- return bmm_fd;
+ ret = ioctl(bmm_fd, BMM_DMABUF_ALLOC, &arg);
- err_api:
- close(bmm_fd);
- bmm_fd = -1;
- err_open:
- err_rb:
- if (phys_rb)
- rb_free_tree(phys_rb);
- if (virt_rb)
- rb_free_tree(virt_rb);
- phys_rb = virt_rb = NULL;
- return bmm_fd;
-}
-
-void bmm_exit(void)
-{
- if (bmm_fd >= 0) {
- close(bmm_fd);
- rb_free_tree(phys_rb);
- rb_free_tree(virt_rb);
- phys_rb = virt_rb = NULL;
- }
- bmm_fd = -1;
+ return ret < 0 ? ret : arg.fd;
}
-void *bmm_malloc_aligned_phys(unsigned long size, int attr, unsigned align,
- unsigned long *paddr)
+/**
+ * bmm_dmabuf_map - map an allcoated DMA buffer
+ * @fd: dma_buf file descriptor
+ * @offset: page aligned offset into DMA buffer
+ * @size: size of buffer to map
+ *
+ * Map the requested buffer into userspace with the requested offset and size.
+ *
+ * Returns: address of mapped buffer, or NULL on error
+ */
+void *bmm_dmabuf_map(int fd, unsigned offset, unsigned size)
{
- struct bmm_phys_buffer *pbuf;
struct bmm_virt_buffer *vbuf;
- int ret;
void *vaddr;
- ioctl_arg_t io;
-
- if(size == 0)
- return NULL;
- if(bmm_init() < 0)
+ vaddr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
+ if (vaddr == (void *)-1)
return NULL;
- pbuf = malloc(sizeof(*pbuf));
vbuf = malloc(sizeof(*vbuf));
- if (!pbuf || !vbuf) {
- if (pbuf)
- free(pbuf);
- if (vbuf)
- free(vbuf);
+ if (!vbuf) {
+ munmap(vaddr, size);
return NULL;
}
- pr_debug("%s(size=%lu,attr=%x,align=%u,paddr=%p)\n",
- __FUNCTION__, size, attr, align, paddr);
-
- /* obsolete, only for back-compatible */
- if ((attr & BMM_ATTR_NONBUFFERABLE)&&(attr & BMM_ATTR_NONCACHEABLE))
- attr = BMM_ATTR_NONCACHED;
-
- if ((!(attr & BMM_ATTR_NONBUFFERABLE))&&(attr & BMM_ATTR_NONCACHEABLE))
- attr = BMM_ATTR_WRITECOMBINE;
-
- io.input = align;
- io.length = size;
- io.output = 0;
- io.arg = attr;
- ret = ioctl(bmm_fd, BMM_MALLOC_ALIGNED, &io);
- if (ret < 0 || io.output == 0)
- goto err_free_buf;
-
- pr_debug("%s return paddr = 0x%08lx\n", __FUNCTION__, io.output);
-
- vaddr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, bmm_fd, io.output);
- if ((int)vaddr == -1)
- goto err_free_bmm;
-
- if (paddr)
- *paddr = io.output;
-
- pbuf->paddr = io.output;
- pbuf->size = size;
- pbuf->attr = attr;
- pbuf->virt = vbuf;
- pbuf->attach = 1;
-
vbuf->vaddr = vaddr;
vbuf->size = size;
- vbuf->phys_offset = 0;
- vbuf->phys = pbuf;
+ vbuf->fd = fd;
pthread_mutex_lock(&bmm_mutex);
- bmm_rb_phys_insert(pbuf);
bmm_rb_virt_insert(vbuf);
pthread_mutex_unlock(&bmm_mutex);
- /*
- * If we keep bmm buffers across fork, they're reference
- * counted, so we can drop the allocation reference here.
- * This also "disowns" this buffer from this thread group.
- */
- if (API_FEAT(bmm_api) >= API_FEAT_KEEP_FORK) {
- io.input = io.output;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_FREE_PHYS, &io);
- }
-
return vaddr;
-
- err_free_bmm:
- if (API_FEAT(bmm_api) >= API_FEAT_FREE_PHYS) {
- /* Modern APIs allow us to free this failed allocation */
- io.input = io.output;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_FREE_PHYS, &io);
- }
-
- err_free_buf:
- free(pbuf);
- free(vbuf);
- return NULL;
}
-void *bmm_malloc_aligned(unsigned long size, int attr, unsigned align)
-{
- return bmm_malloc_aligned_phys(size, attr, align, NULL);
-}
-
-void *bmm_malloc(unsigned long size, int attr)
-{
- return bmm_malloc_aligned_phys(size, attr, sizeof(int), NULL);
-}
-
-void bmm_free(void *vaddr)
+/*
+ * bmm_dmabuf_unmap - unmap a dma_buf mapped previously with bmm_dmabuf_map
+ * @vaddr: virtual address returned from bmm_dmabuf_map()
+ */
+void bmm_dmabuf_unmap(void *vaddr)
{
- struct bmm_phys_buffer *pbuf = NULL;
struct bmm_virt_buffer *vbuf;
- ioctl_arg_t io;
-
- if (bmm_init() < 0)
- return;
pthread_mutex_lock(&bmm_mutex);
vbuf = bmm_buf_find_virt(vaddr);
- if (vbuf) {
- pbuf = vbuf->phys;
- if (pbuf->virt == vbuf)
- pbuf->virt = NULL;
+ if (vbuf)
bmm_rb_virt_remove(vbuf);
- if (--pbuf->attach == 0)
- bmm_rb_phys_remove(pbuf);
- }
pthread_mutex_unlock(&bmm_mutex);
- assert(vbuf);
- assert(pbuf);
-
- munmap(vbuf->vaddr, vbuf->size);
-
- /*
- * If we keep bmm buffers across fork, they're reference
- * counted, so we don't need to free them on the last munmap.
- */
- if (API_FEAT(bmm_api) < API_FEAT_KEEP_FORK) {
- if (API_FEAT(bmm_api) >= API_FEAT_FREE_PHYS) {
- io.input = pbuf->paddr;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_FREE_PHYS, &io);
- } else {
- io.input = (unsigned long)vbuf->vaddr;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_FREE, &io);
- }
+ if (vbuf) {
+ munmap(vbuf->vaddr, vbuf->size);
+ free(vbuf);
}
- if (pbuf->attach == 0)
- free(pbuf);
- free(vbuf);
}
-void *bmm_attach(unsigned long paddr, unsigned long len)
+int bmm_dmabuf_flush(int fd, void *addr, unsigned offset, unsigned size, unsigned direction)
{
- struct bmm_phys_buffer *pbuf, *new_pbuf;
struct bmm_virt_buffer *vbuf;
- void *vaddr;
-
- if(len == 0)
- return NULL;
-
- if(bmm_init() < 0)
- return NULL;
-
- /* Try to map it */
- vaddr = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, bmm_fd, paddr);
- if (vaddr == (void *)-1)
- return NULL;
-
- vbuf = malloc(sizeof(*vbuf));
- new_pbuf = malloc(sizeof(*new_pbuf));
- if (!vbuf || !new_pbuf) {
- if (vbuf)
- free(vbuf);
- if (new_pbuf)
- free(new_pbuf);
- munmap(vaddr, len);
- return NULL;
- }
-
- vbuf->vaddr = vaddr;
- vbuf->size = len;
+ int ret = 0;
pthread_mutex_lock(&bmm_mutex);
- pbuf = bmm_buf_find_phys(paddr);
- if (pbuf) {
- /*
- * If we find the buffer, it means we already know about
- * this buffer. Increment the number of attachments we
- * know about for it, and insert the new virtual buffer.
- */
- pbuf->attach++;
- } else {
- /*
- * Otherwise, we're importing a new buffer which we know
- * nothing about. Create a new pbuf entry.
- */
- new_pbuf->paddr = paddr;
- new_pbuf->size = len;
- new_pbuf->attr = 0;
- new_pbuf->virt = NULL;
- new_pbuf->attach = 1;
- pbuf = new_pbuf;
-
- bmm_rb_phys_insert(new_pbuf);
- }
-
- if (!pbuf->virt)
- pbuf->virt = vbuf;
- vbuf->phys_offset = paddr - pbuf->paddr;
- vbuf->phys = pbuf;
- bmm_rb_virt_insert(vbuf);
-
+ vbuf = bmm_buf_find_virt(addr);
pthread_mutex_unlock(&bmm_mutex);
- /* If the new pbuf wasn't used, free it. */
- if (pbuf != new_pbuf)
- free(new_pbuf);
-
- return vaddr;
-}
-
-void bmm_detach(void *vaddr, unsigned long len)
-{
- struct bmm_virt_buffer *vbuf;
- struct bmm_phys_buffer *pbuf;
-
- if(bmm_init() < 0)
- return;
-
- pthread_mutex_lock(&bmm_mutex);
- vbuf = bmm_buf_find_virt(vaddr);
if (vbuf) {
- pbuf = vbuf->phys;
- assert(pbuf->attach > 0);
+ struct bmm_dmabuf_flush arg;
- if (pbuf->virt == vbuf)
- pbuf->virt = NULL;
+ if (fd != vbuf->fd) {
+ errno = EINVAL;
+ return -1;
+ }
- bmm_rb_virt_remove(vbuf);
+ arg.size = size;
+ arg.offset = offset;
+ arg.ptr = (uint64_t)(uintptr_t)addr;
+ arg.fd = vbuf->fd;
+ arg.direction = direction;
- if (--pbuf->attach == 0)
- bmm_rb_phys_remove(pbuf);
- else
- pbuf = NULL;
- } else {
- pbuf = NULL;
+ ret = ioctl(bmm_fd, BMM_DMABUF_FLUSH, &arg);
}
- pthread_mutex_unlock(&bmm_mutex);
-
- munmap(vbuf->vaddr, vbuf->size);
-
- free(vbuf);
- if (pbuf)
- free(pbuf);
-}
-
-void *bmm_get_vaddr(unsigned long paddr)
-{
- struct bmm_phys_buffer *pbuf;
- void *va = NULL;
-
- if (bmm_init() < 0)
- return 0;
-
- pthread_mutex_lock(&bmm_mutex);
- pbuf = bmm_buf_find_phys(paddr);
- if (pbuf && pbuf->virt)
- va = pbuf->virt->vaddr + (paddr - pbuf->paddr);
- pthread_mutex_unlock(&bmm_mutex);
-
- return va;
+ return ret;
}
-unsigned long bmm_get_paddr(void *vaddr)
+/**
+ * bmm_dmabuf_fd - return the dma_buf file descriptor for a mapped dma_buf
+ * @vaddr: virtual address returned from bmm_dmabuf_map()
+ *
+ * Returns the dma_buf file descriptor for the dma_buf previously mapped
+ * with bmm_dmabuf_map(), or -1 on error.
+ */
+int bmm_dmabuf_fd(void *vaddr)
{
struct bmm_virt_buffer *vbuf;
- unsigned long pa = 0;
-
- if (bmm_init() < 0)
- return 0;
+ int fd = -1;
pthread_mutex_lock(&bmm_mutex);
vbuf = bmm_buf_find_virt(vaddr);
if (vbuf)
- pa = vbuf->phys->paddr + vbuf->phys_offset +
- (vaddr - vbuf->vaddr);
+ fd = vbuf->fd;
pthread_mutex_unlock(&bmm_mutex);
- return pa;
+ return fd;
}
-int bmm_get_dmabuf_fd(void *vaddr)
-{
- int ret;
- ioctl_arg_t io;
-
- if (bmm_init() < 0 || API_FEAT(bmm_api) < API_FEAT_GET_DMABUF_FD)
- return -1;
-
- io.input = (unsigned long)vaddr;
- io.output = 0;
- io.arg = 0;
-
- ret = ioctl(bmm_fd, BMM_GET_DMABUF_FD, &io);
-
- return ret < 0 ? -1 : io.output;
-}
-
-int bmm_get_phys_dmabuf_fd(unsigned long paddr)
+/**
+ * bmm_dmabuf_free - free the dma_buf file descriptor
+ * @fd: dma_buf file descriptor returned by bmm_dmabuf_alloc()
+ *
+ * Closes the file descriptor associated with the DMA buffer. The actual
+ * DMA buffer will only be freed when all references to it are gone - in
+ * other words, after the buffer has been completely unmapped and any
+ * imported references are also released.
+ *
+ * After this call has completed, the file descriptor returned by a call
+ * to bmm_dmabuf_fd() is invalid.
+ */
+void bmm_dmabuf_free(int fd)
{
- int ret;
- ioctl_arg_t io;
-
- if (bmm_init() < 0 || API_FEAT(bmm_api) < API_FEAT_GET_DMABUF_FD)
- return -1;
-
- io.input = paddr;
- io.output = 0;
- io.arg = 0;
-
- ret = ioctl(bmm_fd, BMM_GET_PHYS_DMABUF_FD, &io);
-
- return ret < 0 ? -1 : io.output;
+ close(fd);
}
-unsigned long bmm_get_mem_size(void *vaddr)
+int bmm_init(void)
{
- struct bmm_virt_buffer *vbuf;
- unsigned long size = 0;
-
- if (bmm_init() < 0)
- return 0;
-
pthread_mutex_lock(&bmm_mutex);
- vbuf = bmm_buf_find_virt(vaddr);
- if (vbuf)
- size = vbuf->size;
- pthread_mutex_unlock(&bmm_mutex);
-
- return size;
-}
-
-int bmm_get_mem_attr(void *vaddr)
-{
- struct bmm_virt_buffer *vbuf;
- int attr = 0;
-
- if (bmm_init() < 0)
- return 0;
+ if (bmm_use++ == 0) {
+ bmm_virt_rb = make_rb();
+ if (!bmm_virt_rb)
+ goto err_rb;
- pthread_mutex_lock(&bmm_mutex);
- vbuf = bmm_buf_find_virt(vaddr);
- if (vbuf)
- attr = vbuf->phys->attr;
+ /* attempt to open the BMM driver */
+ bmm_fd = open(BMM_DEVICE_FILE, O_RDWR | O_CLOEXEC);
+ pr_debug("BMM device fd: %d\n", bmm_fd);
+ if (bmm_fd < 0)
+ goto err_open;
+ }
pthread_mutex_unlock(&bmm_mutex);
- return attr;
-}
-
-int bmm_set_mem_attr(void *vaddr, int attr)
-{
- struct bmm_virt_buffer *vbuf;
- int ret;
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return 0;
-
- io.input = (unsigned long)vaddr;
- io.output = 0;
- io.arg = attr;
- ret = ioctl(bmm_fd, BMM_SET_MEM_ATTR, &io);
- if(ret < 0)
- return 0;
-
- attr = io.output;
+ return bmm_fd;
- pthread_mutex_lock(&bmm_mutex);
- vbuf = bmm_buf_find_virt(vaddr);
- if (vbuf)
- vbuf->phys->attr = attr;
+ err_open:
+ rb_free_tree(bmm_virt_rb);
+ bmm_virt_rb = NULL;
+ err_rb:
+ bmm_use--;
pthread_mutex_unlock(&bmm_mutex);
-
- return attr;
-}
-
-unsigned long bmm_get_total_space(void)
-{
- int ret;
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return 0;
-
- io.input = 0;
- io.output = 0;
- io.arg = 0;
- ret = ioctl(bmm_fd, BMM_GET_TOTAL_SPACE, &io);
- if(ret < 0)
- return 0;
-
- return io.output;
-}
-
-unsigned long bmm_get_free_space(void)
-{
- int ret;
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return 0;
-
- io.input = 0;
- io.output = 0;
- io.arg = 0;
- ret = ioctl(bmm_fd, BMM_GET_FREE_SPACE, &io);
- if(ret < 0)
- return 0;
-
- return io.output;
-}
-
-unsigned long bmm_get_allocated_space(void)
-{
- int ret;
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return 0;
-
- io.input = 0;
- io.output = 0;
- io.arg = 0;
- ret = ioctl(bmm_fd, BMM_GET_ALLOCATED_SPACE, &io);
- if(ret < 0)
- return 0;
-
- return io.output;
+ return bmm_fd;
}
-void bmm_flush_cache(void *vaddr, int dir)
+void bmm_exit(void)
{
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return;
-
- io.input = (unsigned long)vaddr;
- io.output = 0;
- io.arg = dir;
- ioctl(bmm_fd, BMM_FLUSH_CACHE, &io);
-}
+ pthread_mutex_lock(&bmm_mutex);
+ if (bmm_use && --bmm_use == 0) {
+ Rb_node node;
-void bmm_flush_cache_range(void *start, size_t size, int direction)
-{
- ioctl_arg_t io;
+ /* Clean up dangling buffers which the app hasn't released. */
+ rb_traverse(node, bmm_virt_rb) {
+ struct bmm_virt_buffer *vbuf = rb_val(node);
- if(bmm_init() < 0)
- return;
+ munmap(vbuf->vaddr, vbuf->size);
+ close(vbuf->fd);
+ free(vbuf);
+ }
- io.input = (unsigned long)start;
- io.length = size;
- io.output = 0;
- io.arg = direction;
- ioctl(bmm_fd, BMM_CONSISTENT_SYNC, &io);
-}
+ rb_free_tree(bmm_virt_rb);
+ bmm_virt_rb = NULL;
-void bmm_flush_user(void *start, long size, int direction)
-{
- ioctl_arg_t io;
-
- if (bmm_init() < 0)
- return;
- if (size <= 0)
- return;
-
- io.input = (unsigned long)start;
- io.length = size;
- io.output = 0;
- io.arg = direction;
- ioctl(bmm_fd, BMM_SYNC_USER, &io);
+ close(bmm_fd);
+ bmm_fd = -1;
+ }
+ pthread_mutex_unlock(&bmm_mutex);
}
-void bmm_dump(void)
+/*
+ * Destructor for this library: ensure it gets cleaned up when the
+ * library is unloaded.
+ */
+static void __attribute__((destructor)) bmm_destruct(void)
{
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return;
-
- io.input = 0;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_DUMP, &io);
+ if (bmm_use) {
+ bmm_use = 1;
+ bmm_exit();
+ }
}
-
diff --git a/bmm_lib.h b/bmm_lib.h
index 09348ef..a381f25 100644
--- a/bmm_lib.h
+++ b/bmm_lib.h
@@ -40,27 +40,13 @@ extern "C" {
int bmm_init(void);
void bmm_exit(void);
-void *bmm_malloc(unsigned long size, int attr);
-void *bmm_malloc_aligned(unsigned long size, int attr, unsigned align);
-void *bmm_malloc_aligned_phys(unsigned long size, int attr, unsigned align,
- unsigned long *paddr);
-void bmm_free(void *vaddr);
-void *bmm_attach(unsigned long paddr, unsigned long len);
-void bmm_detach(void *vaddr, unsigned long len);
-void *bmm_get_vaddr(unsigned long paddr);
-unsigned long bmm_get_paddr(void *vaddr);
-int bmm_get_dmabuf_fd(void *vaddr);
-int bmm_get_phys_dmabuf_fd(unsigned long paddr);
-int bmm_get_mem_attr(void *vaddr);
-int bmm_set_mem_attr(void *vaddr, int attr); /* Not supported yet */
-unsigned long bmm_get_mem_size(void *vaddr);
-unsigned long bmm_get_total_space(void);
-unsigned long bmm_get_free_space(void);
-unsigned long bmm_get_allocated_space(void);
-void bmm_flush_cache(void *vaddr, int dir);
-void bmm_flush_cache_range(void *start, size_t size, int direction);
-void bmm_flush_user(void *start, long size, int direction);
-void bmm_dump(void); /* for debugging */
+
+int bmm_dmabuf_alloc(unsigned long size, int attr, unsigned align);
+void *bmm_dmabuf_map(int fd, unsigned offset, unsigned size);
+void bmm_dmabuf_unmap(void *addr);
+int bmm_dmabuf_flush(int fd, void *addr, unsigned offset, unsigned size, unsigned direction);
+int bmm_dmabuf_fd(void *addr);
+void bmm_dmabuf_free(int fd);
#if defined (__cplusplus)
}
diff --git a/bmm_lib.pmem.c b/bmm_lib.pmem.c
deleted file mode 100644
index cb74a11..0000000
--- a/bmm_lib.pmem.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * bmm_lib.c
- *
- * Buffer Management Module for vMeta
- *
- * based on Android PMEM
- *
- * Steve Guo (steve.guo@marvell.com)
-
- *(C) Copyright 2007 Marvell International Ltd.
- * All Rights Reserved
- */
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <linux/android_pmem.h>
-#include <stdio.h>
-#include <stdlib.h>
-#define LOG_TAG "bmm-lib"
-#include <utils/Log.h>
-
-#include "bmm_lib.h"
-
-//#define DEBUG
-
-#ifdef DEBUG
- #define pr_debug(fmt, arg...) LOGD(fmt, ##arg)
-#else
- #define pr_debug(fmt, arg...) do { } while(0)
-#endif
-
-#define pr_error(fmt, arg...) LOGE(fmt, ##arg)
-#define NO_IMPLEMENTED LOGE("%s is not implemented yet.", __FUNCTION__)
-
-#define PMEM_DEVICE_FILE "/dev/pmem_adsp"
-
-
-/* We recorded all malloced physical address into a list. Due to the implementation of
-pmem, we can only open a new file to malloc some memory and close it to free memory. So
-we also record the opened fd associated with physical and virtual address map. */
-struct memory_item
-{
- int fd;
- void *paddr;
- void *vaddr;
- int size;
- struct memory_item *next;
-};
-
-static struct memory_item *header = NULL;
-
-int bmm_init()
-{
- pr_debug("bmm_init");
- header = NULL;
- return 0;
-}
-
-void bmm_exit()
-{
- struct memory_item *cur = header;
- struct memory_item *next = NULL;
- pr_debug("bmm_exit");
- while(cur != NULL)
- {
- next = cur->next;
- munmap(cur->vaddr, cur->size);
- close(cur->fd);
- free(cur);
- cur = next;
- }
-}
-
-void *bmm_malloc(unsigned long size, int attr)
-{
- void *vaddr;
- int pmem_fd = 0;
- struct memory_item *item = NULL;
- struct pmem_region region;
- int ret;
-
- if(size == 0)
- return NULL;
-
- pr_debug("bmm_malloc %d", size);
-
- /* attempt to open the PMEM driver */
- pmem_fd = open(PMEM_DEVICE_FILE, O_RDWR);
- if(pmem_fd <=0)
- {
- pr_error("cannot open %s file", PMEM_DEVICE_FILE);
- return NULL;
- }
-
- vaddr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, pmem_fd, 0);
- if((int)vaddr == -1)
- {
- pr_error("mmap %d failed, most likely no memory", size);
- close(pmem_fd);
- return NULL;
- }
-
- ret = ioctl(pmem_fd, PMEM_GET_PHYS, &region);
- if(ret != 0)
- {
- pr_error("call PMEM_GET_PHYS failed");
- munmap(vaddr, size);
- close(pmem_fd);
- return NULL;
- }
-
- item = (struct memory_item*)malloc(sizeof(struct memory_item));
- memset(item, 0 , sizeof(struct memory_item));
- item->fd = pmem_fd;
- item->paddr = (void*)region.offset;
- item->vaddr = vaddr;
- item->size = size;
-
- if(header == NULL)
- {
- header = item;
- }
- else
- {
- item->next = header;
- header = item;
- }
- return vaddr;
-}
-
-void bmm_free(void *vaddr)
-{
- pr_debug("bmm_free");
- struct memory_item *cur = header;
- struct memory_item *prev = NULL;
- struct memory_item *next = NULL;
- while(cur != NULL)
- {
- next = cur->next;
- if(cur->vaddr == vaddr)
- {
- munmap(cur->vaddr, cur->size);
- close(cur->fd);
- if(prev == NULL)
- {
- header = next;
- }
- else
- {
- prev->next = next;
- }
- free(cur);
- return;
- }
- prev = cur;
- cur = next;
- }
-}
-
-void *bmm_attach(void *paddr, unsigned long len)
-{
- NO_IMPLEMENTED;
- return NULL;
-}
-
-void bmm_detach(void *vaddr, unsigned long len)
-{
- NO_IMPLEMENTED;
-}
-
-void *bmm_get_vaddr(void *paddr)
-{
- pr_debug("bmm_get_vaddr");
- struct memory_item *cur = header;
- while(cur != NULL)
- {
- if(cur->paddr == paddr)
- return cur->vaddr;
- cur = cur->next;
- }
- return NULL;
-}
-
-void *bmm_get_paddr(void *vaddr)
-{
- pr_debug("bmm_get_paddr");
- struct memory_item *cur = header;
- while(cur != NULL)
- {
- if(cur->vaddr == vaddr)
- return cur->paddr;
- cur = cur->next;
- }
- return NULL;
-}
-
-unsigned long bmm_get_mem_size(void *vaddr)
-{
- struct memory_item *cur = header;
- while(cur != NULL)
- {
- if(cur->vaddr == vaddr)
- return cur->size;
- cur = cur->next;
- }
- return 0;
-}
-
-int bmm_get_mem_attr(void *vaddr)
-{
- NO_IMPLEMENTED;
- return 0;
-}
-
-int bmm_set_mem_attr(void *vaddr, int attr)
-{
- NO_IMPLEMENTED;
- return 0;
-}
-
-unsigned long bmm_get_total_space()
-{
- int pmem_fd = 0;
- struct pmem_region region;
- int ret;
-
- /* attempt to open the PMEM driver */
- pmem_fd = open(PMEM_DEVICE_FILE, O_RDWR);
- if(pmem_fd <=0)
- {
- pr_error("cannot open %s file", PMEM_DEVICE_FILE);
- return 0;
- }
-
- ret = ioctl(pmem_fd, PMEM_GET_TOTAL_SIZE, &region);
- if(ret != 0)
- {
- pr_error("call PMEM_GET_TOTAL_SIZE failed");
- close(pmem_fd);
- return 0;
- }
- close(pmem_fd);
- return region.len;
-}
-
-unsigned long bmm_get_free_space()
-{
- NO_IMPLEMENTED;
- return 0;
-}
-
-unsigned long bmm_get_allocated_space()
-{
- NO_IMPLEMENTED;
- return 0;
-}
-
-void bmm_flush_cache(void *vaddr, int dir)
-{
- NO_IMPLEMENTED;
-}
-
-void *bmm_dma_memcpy(void *dest, const void *src, size_t n)
-{
- NO_IMPLEMENTED;
- return NULL;
-}
-
-void bmm_dma_sync()
-{
- NO_IMPLEMENTED;
-}
-
-void bmm_flush_cache_range(void *start, size_t size, int direction)
-{
- NO_IMPLEMENTED;
-}
-
-void bmm_dump()
-{
- NO_IMPLEMENTED;
-}
-
diff --git a/bmm_lib_priv.h b/bmm_lib_priv.h
deleted file mode 100644
index 42d4e64..0000000
--- a/bmm_lib_priv.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * bmm_lib_priv.h
- *
- * Buffer Management Module
- *
- * User level BMM Defines/Globals/Functions
- *
- * Li Li (lea.li@marvell.com)
-
- *(C) Copyright 2007 Marvell International Ltd.
- * All Rights Reserved
- */
-
-#ifndef __BMM_LIB_PRIV_H__
-#define __BMM_LIB_PRIV_H__
-
-#define BMM_MINOR (94)
-
-typedef struct {
- unsigned long input; /* the starting address of the block of memory */
- unsigned long output; /* the starting address of the block of memory */
- unsigned long length; /* the length of the block of memory */
- unsigned long arg; /* the arg of cmd */
-} ioctl_arg_t;
-
-#define BMEM_IOCTL_MAGIC 'G'
-/* ioctl commands */
-#define BMM_MALLOC _IOWR(BMEM_IOCTL_MAGIC, 0, ioctl_arg_t)
-#define BMM_FREE _IOWR(BMEM_IOCTL_MAGIC, 1, ioctl_arg_t)
-#define BMM_GET_VIRT_ADDR _IOWR(BMEM_IOCTL_MAGIC, 2, ioctl_arg_t)
-#define BMM_GET_PHYS_ADDR _IOWR(BMEM_IOCTL_MAGIC, 3, ioctl_arg_t)
-#define BMM_GET_MEM_ATTR _IOWR(BMEM_IOCTL_MAGIC, 4, ioctl_arg_t)
-#define BMM_SET_MEM_ATTR _IOWR(BMEM_IOCTL_MAGIC, 5, ioctl_arg_t)
-#define BMM_GET_MEM_SIZE _IOWR(BMEM_IOCTL_MAGIC, 6, ioctl_arg_t)
-#define BMM_GET_TOTAL_SPACE _IOWR(BMEM_IOCTL_MAGIC, 7, ioctl_arg_t)
-#define BMM_GET_FREE_SPACE _IOWR(BMEM_IOCTL_MAGIC, 8, ioctl_arg_t)
-#define BMM_FLUSH_CACHE _IOWR(BMEM_IOCTL_MAGIC, 9, ioctl_arg_t)
-#define BMM_CONSISTENT_SYNC _IOWR(BMEM_IOCTL_MAGIC, 12, ioctl_arg_t)
-#define BMM_DUMP _IOWR(BMEM_IOCTL_MAGIC, 13, ioctl_arg_t)
-#define BMM_GET_ALLOCATED_SPACE _IOWR(BMEM_IOCTL_MAGIC, 14, ioctl_arg_t)
-#define BMM_GET_KERN_PHYS_ADDR _IOWR(BMEM_IOCTL_MAGIC, 15, ioctl_arg_t)
-#define BMM_SYNC_USER _IOWR(BMEM_IOCTL_MAGIC, 16, ioctl_arg_t)
-#define BMM_MALLOC_ALIGNED _IOWR(BMEM_IOCTL_MAGIC, 17, ioctl_arg_t)
-#define BMM_API_VERSION _IOWR(BMEM_IOCTL_MAGIC, 18, ioctl_arg_t)
-#define BMM_GET_DMABUF_FD _IOWR(BMEM_IOCTL_MAGIC, 19, ioctl_arg_t)
-#define BMM_FREE_PHYS _IOWR(BMEM_IOCTL_MAGIC, 20, ioctl_arg_t)
-#define BMM_GET_PHYS_DMABUF_FD _IOWR(BMEM_IOCTL_MAGIC, 21, ioctl_arg_t)
-
-#define BMM_DEVICE_FILE "/dev/bmm"
-
-#endif /* __BMM_LIB_PRIV_H__ */
diff --git a/bmm_test.c b/bmm_test.c
deleted file mode 100644
index ceadf9c..0000000
--- a/bmm_test.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * bmm_test.c
- *
- * Buffer Management Module
- *
- * User test application
- *
- * Li Li (lea.li@marvell.com)
-
- *(C) Copyright 2007 Marvell International Ltd.
- * All Rights Reserved
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include "bmm_lib.h"
-
-static int debug = 0;
-
-int test_count = 0;
-int pass_count = 0;
-int fail_count = 0;
-
-#define PRINT_TEST_NAME printf("Testing %d: %s()\n", test_count++, __FUNCTION__)
-#define PRINT_TEST_RESULT(x) \
- do { \
- if(!x) \
- pass_count++, printf("\tPassed.\n"); \
- else \
- fail_count++, printf("\tFailed.\n"); \
- } while(0)
-#define PRINT_TEST_RESULTS() printf("Passed/Failed = %d/%d\n", pass_count, fail_count)
-
-static int test_bmm_init(void)
-{
- int ret;
-
- PRINT_TEST_NAME;
-
- ret = bmm_init();
- printf("\tbmm_init() return %d\n", ret);
-
- return (ret <= 0);
-}
-
-static int test_bmm_get_space(void)
-{
- unsigned long total_size;
- unsigned long free_size;
-
- PRINT_TEST_NAME;
-
- total_size = bmm_get_total_space();
- free_size = bmm_get_free_space();
-
- printf("\tbmm_get_total_space() return %ldKB\n", total_size/1024);
- printf("\tbmm_get_free_space() return %ldKB\n", free_size/1024);
-
- return (total_size <= 0 || total_size != free_size);
-}
-
-static int test_bmm_malloc(unsigned long size, int attr)
-{
- void *vaddr;
- unsigned long allocated_size1, free_size1;
- unsigned long allocated_size2, free_size2;
- unsigned long allocated_size3, free_size3;
- int off = 0;
- PRINT_TEST_NAME;
-
- allocated_size1 = bmm_get_allocated_space();
- free_size1 = bmm_get_free_space();
- vaddr = bmm_malloc(size, attr);
- if(vaddr == NULL) {
- printf("\tno enough memory\n");
- return -1;
- }
- for(off = 0; off < size; off += 1024*1024){
- unsigned long get_paddr = bmm_get_paddr(vaddr+off);
- void *get_vaddr = bmm_get_vaddr(get_paddr);
- int get_attr = bmm_get_mem_attr(get_vaddr);
- printf("\toff = 0x%x, vaddr=0x%p, get_vaddr=0x%p, get_paddr=0x%08lx\n", off, vaddr+off, get_vaddr, get_paddr);
- printf("\tset_attr=0x%x, get_attr=0x%x\n", attr, get_attr);
- if(vaddr+off != get_vaddr)
- return -1;
- }
-
- allocated_size2 = bmm_get_allocated_space();
- free_size2 = bmm_get_free_space();
- bmm_free(vaddr);
- allocated_size3 = bmm_get_allocated_space();
- free_size3 = bmm_get_free_space();
-
- printf("\tbmm_malloc(%ldKB) return 0x%08lx\n", size/1024, (unsigned long)vaddr);
- printf("\tbmm_get_allocated_space() return %ldKB %ldKB %ldKB\n",
- allocated_size1/1024, allocated_size2/1024, allocated_size3/1024);
- printf("\tbmm_get_free_space() return %ldKB %ldKB %ldKB\n",
- free_size1/1024, free_size2/1024, free_size3/1024);
-
- return (
- allocated_size2 - allocated_size1 != size ||
- allocated_size1 != allocated_size3 ||
- free_size1 - free_size2 != size ||
- free_size1 != free_size3);
-}
-
-static long gettickcount(void)
-{
- struct timeval g_tv;
- struct timezone g_tz;
-
- gettimeofday(&g_tv, &g_tz);
-
- return g_tv.tv_sec * 1000000 + g_tv.tv_usec;
-}
-
-static int test_bmm_flush_user(unsigned long size)
-{
- char *src;
- long t1 = 0, t2 = 0;
-
- PRINT_TEST_NAME;
-
- src = malloc(size);
- if (src == NULL) {
- printf("\tno enough memory\n");
- return -1;
- }
- t1 = gettickcount();
- bmm_flush_user(src, size, BMM_DMA_TO_DEVICE);
- t2 = gettickcount();
- printf("bmm_flush_user 0x%lx memory cost %ldusec\n", size, t2-t1);
- free(src);
-
- src = bmm_malloc(size, BMM_ATTR_DEFAULT);
- if (src == NULL) {
- printf("\tno enough memory\n");
- return -1;
- }
- t1 = gettickcount();
- bmm_flush_cache_range(src, size, BMM_DMA_TO_DEVICE);
- t2 = gettickcount();
- printf("bmm_flush_cache_range 0x%lx memory cost %ldusec\n", size, t2-t1);
- bmm_free(src);
-
- return 0;
-}
-
-static int test_bmm_share(unsigned long size)
-{
- char *src;
- char *dst;
- unsigned long psrc;
- unsigned long pdst;
- unsigned long i;
- unsigned long off, len;
- unsigned long free_size1;
- unsigned long free_size2;
- unsigned long free_size3;
- int ret = 0;
- int pid = 0;
- int pid1 = 0;
- int pid2 = 0;
- int ret1 = 0;
- int ret2 = 0;
-
- PRINT_TEST_NAME;
-
- free_size1 = bmm_get_free_space();
- src = bmm_malloc(size, BMM_ATTR_DEFAULT);
- memset(src, 0, size);
- free_size2 = bmm_get_free_space();
- if(src == NULL) {
- printf("\tno enough memory\n");
- return -1;
- }
- psrc = bmm_get_paddr(src);
- printf("\tFork 3 sub processes...\n");
- pid1 = fork();
- if(pid1 != 0) {
- pid2 = fork();
- if(pid2 != 0) {
- off = 0;
- len = size;
- dst = bmm_attach(psrc + off, len);
- for(i=0; i<size; i++)
- src[i] = i;
- bmm_flush_cache(src, BMM_DMA_TO_DEVICE);
- sleep(1);
- kill(0, SIGCONT);
- waitpid(pid2, &ret2, 0);
- waitpid(pid1, &ret1, 0);
- ret2 = WEXITSTATUS(ret2) ? -1 : 0;
- ret1 = WEXITSTATUS(ret1) ? -1 : 0;
- pid = 0;
- } else {
- raise(SIGSTOP);
- off = 4096;
- len = 4096;
- dst = bmm_attach(psrc + off, len);
- pid = 1;
- }
- } else {
- pid2 = fork();
- if(pid2 != 0) {
- raise(SIGSTOP);
- off = size / 4;
- len = size / 2;
- dst = bmm_attach(psrc + off, len);
- waitpid(pid2, &ret2, 0);
- ret2 = WEXITSTATUS(ret2) ? -1 : 0;
- pid = 2;
- } else {
- raise(SIGSTOP);
- off = size - 4096;
- len = 4096;
- dst = bmm_attach(psrc + off, len);
- pid = 3;
- }
- }
-
- pdst = bmm_get_paddr(dst);
- if(pdst == psrc + off)
- printf("\t[%d] pdst(0x%08lx) == psrc(0x%08lx) + off(%lx)\n", pid, pdst, psrc, off);
- else
- printf("\t[%d] Error: pdst(0x%08lx) != psrc(0x%08lx) + off(%lx)\n", pid, pdst, psrc, off);
-
- bmm_flush_cache(dst, BMM_DMA_FROM_DEVICE);
- for(i=0; i<len; i++) {
- if(dst[i] != (char)(off+i)) {
- ret--;
- if(debug)
- printf("\t[%d] [%ld+%ld]: %d != %d\n", pid, off, i, dst[i], (char)(off+i));
- else
- break;
- }
- }
-
- bmm_detach(dst, len);
-
- printf("\t[%d] bmm_share(%ldKB/%ld-%ld) = %d\n", pid, size/1024, off, len, ret);
-
- if(pid1 == 0 || pid2 == 0)
- exit(ret);
-
- bmm_free(src);
- free_size3 = bmm_get_free_space();
-
- printf("\t[%d] bmm_get_free_space() return %ldKB %ldKB %ldKB\n",
- pid, free_size1/1024, free_size2/1024, free_size3/1024);
-
- if(ret || ret1 || ret2)
- return ret + ret1 + ret2;
-
- printf("\tShare content OK. Checking free space...\n");
-
- return (free_size1 - free_size2 != size || free_size1 != free_size3);
-}
-
-int main(int argc, char * argv[])
-{
- int ret;
- unsigned long i, n;
- pid_t pid = getpid();
-
- if(argc > 1) {
- debug = 1;
- if(!strcmp(argv[1], "dump")) {
- ret = test_bmm_get_space();
- PRINT_TEST_RESULT(ret);
- bmm_dump();
- return 0;
- }
- }
-
- printf("%s running with pid=%d/%x\n", argv[0], pid, pid);
-
- if(debug)
- bmm_dump();
-
- ret = test_bmm_init();
- PRINT_TEST_RESULT(ret);
-
- ret = test_bmm_get_space();
- PRINT_TEST_RESULT(ret);
-
- n = 8;
- for(i=1; i<=n; i++) {
- ret = test_bmm_malloc(i*1024*1024, BMM_ATTR_DEFAULT);
- PRINT_TEST_RESULT(ret);
- }
- for(i=n; i>=1; i--) {
- ret = test_bmm_malloc(i*1024*1024, BMM_ATTR_NONCACHED);
- PRINT_TEST_RESULT(ret);
- }
-
- n = 8;
- for(i=1; i<=n; i++) {
- ret = test_bmm_share(i*1024*1024);
- PRINT_TEST_RESULT(ret);
- }
-
- n = 1;
- ret = test_bmm_flush_user(n*1024*1024);
- PRINT_TEST_RESULT(ret);
- PRINT_TEST_RESULTS();
-
- if(debug)
- bmm_dump();
-
- bmm_exit();
-
- if(debug)
- bmm_dump();
-
- return 0;
-}
-
diff --git a/configure.ac b/configure.ac
index 68200e6..5c3317b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,14 +1,14 @@
AC_PREREQ([2.63])
-AC_INIT([libbmm], [1.1.0], [], [libbmm])
+AC_INIT([libbmm], [2.0.0], [], [libbmm])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.10 foreign dist-bzip2])
AM_MAINTAINER_MODE([enable])
-ABI_VERSION=2
+ABI_VERSION=3
ABI_REVISION=0
-ABI_AGE=1
+ABI_AGE=0
AC_SUBST(ABI_VERSION)
AC_SUBST(ABI_REVISION)
AC_SUBST(ABI_AGE)
diff --git a/debian/changelog b/debian/changelog
index ad0235c..bd83008 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+libbmm (2.0.0) precise; urgency=low
+
+ * Major update, now using purely dma_buf as a management system for
+ buffers.
+
+ -- Russell King <rmk@arm.linux.org.uk> Sat, 7 Dec 2013 15:01:15 +0000
+
marvell-libbmm (1.1.3) precise; urgency=low
* Fix dma_import() handling of offset buffers
diff --git a/debian/control b/debian/control
index de0a4bf..f375bbd 100644
--- a/debian/control
+++ b/debian/control
@@ -1,11 +1,10 @@
-Source: marvell-libbmm
+Source: libbmm
Priority: extra
-Maintainer: Michael Casadevall <mcasadevall@ubuntu.com>
+Maintainer: Russell King <rmk@arm.linux.org.uk>
XSBC-Original-Maintainer: Li Li <lea.li@marvell.com>
Build-Depends: debhelper (>= 7)
Standards-Version: 3.9.1
Section: libs
-Vcs-Bzr: https://code.launchpad.net/~adana-team/adana/marvell-libbmm
Package: libbmm-common
Section: libs
@@ -16,25 +15,23 @@ Description: Block/buffer memory management
Package: libbmm-dev
Section: libdevel
Architecture: armel armhf
-Depends: libbmm1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
+Depends: libbmm2 (= ${binary:Version}), ${misc:Depends}
Description: Block/buffer memory management
Header files, static library and unit test case for BMM
-Package: libbmm1
+Package: libbmm2
Section: libs
Architecture: armel armhf
Depends: libbmm-common, ${shlibs:Depends}, ${misc:Depends}
Description: Block/buffer memory management
Allocate, manage and share large block of physical continuous memory
-Package: libbmm1-dbg
+Package: libbmm2-dbg
Section: debug
Priority: extra
Architecture: linux-any
-Depends:
- libbmm1 (= ${binary:Version}),
- ${misc:Depends},
+Depends: libbmm2 (= ${binary:Version}), ${misc:Depends},
Multi-Arch: same
Description: Block/buffer memory management
.
- This package provides debugging symbols for the libbmm0u package.
+ This package provides debugging symbols for the libbmm2 package.
diff --git a/debian/libbmm-dev.install b/debian/libbmm-dev.install
index 57bfa73..e5091ec 100644
--- a/debian/libbmm-dev.install
+++ b/debian/libbmm-dev.install
@@ -2,4 +2,3 @@ debian/tmp/usr/include/*.h
debian/tmp/usr/lib/*.a
debian/tmp/usr/lib/*.so
debian/tmp/usr/lib/pkgconfig/*.pc
-debian/tmp/usr/bin/bmm_test
diff --git a/debian/libbmm1.install b/debian/libbmm2.install
index 79bbe2f..79bbe2f 100644
--- a/debian/libbmm1.install
+++ b/debian/libbmm2.install
diff --git a/debian/rules b/debian/rules
index ced92e5..b0098b2 100755
--- a/debian/rules
+++ b/debian/rules
@@ -8,6 +8,7 @@
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
+LIBBMM=libbmm2
override_dh_auto_install:
dh_auto_install --destdir=debian/tmp
@@ -17,7 +18,7 @@ override_dh_install:
dh_install --fail-missing
override_dh_strip:
- dh_strip -plibbmm1 --dbg-package=libbmm1-dbg
+ dh_strip -p$(LIBBMM) --dbg-package=$(LIBBMM)-dbg
dh_strip -s --remaining-packages
%: