@@ -168,4 +168,15 @@ config SYS_HYPERVISOR
bool
default n
+config SHARED_BUFFER
+ bool "Framework for buffer sharing between drivers"
+ depends on ANON_INODES
+ help
+ This option enables the framework for buffer sharing between
+ multiple drivers. A buffer is associated with a file descriptor
+ using driver API's extensions. The descriptor is passed to other
+ driver.
+
+ If you are unsure about this, Say N here.
+
endmenu
@@ -8,6 +8,7 @@ obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
obj-y += power/
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
+obj-$(CONFIG_SHARED_BUFFER) += shared-buffer.o
obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
new file mode 100644
@@ -0,0 +1,96 @@
+/*
+ * Framework for shared buffer
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Author: Tomasz Stanislawski, <t.stanislaws@samsung.com>
+ *
+ * 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.
+ */
+
+#include <linux/anon_inodes.h>
+#include <linux/dma-mapping.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/shared-buffer.h>
+
+/**
+ * shrbuf_release() - release resources of shrbuf file
+ * @inode: a file's inode, not used
+ * @file: file pointer
+ *
+ * The function unbinds shrbuf structure from a file
+ */
+static int shrbuf_release(struct inode *inode, struct file *file)
+{
+ struct shrbuf *sb = file->private_data;
+
+ /* decrease reference counter increased in shrbuf_export */
+ sb->put(sb);
+ return 0;
+}
+
+static const struct file_operations shrbuf_fops = {
+ .release = shrbuf_release,
+};
+
+/**
+ * shrbuf_export() - transforms shrbuf into a file descriptor
+ * @sb: shared buffer instance to be exported
+ *
+ * The function creates a file descriptor associated with a shared buffer
+ *
+ * Returns file descriptor or appropriate error on failure
+ */
+int shrbuf_export(struct shrbuf *sb)
+{
+ int fd;
+
+ BUG_ON(!sb || !sb->get || !sb->put);
+ /* binding shrbuf to a file so reference count in increased */
+ sb->get(sb);
+ /* obtaing file descriptor without inode */
+ fd = anon_inode_getfd("shrbuf", &shrbuf_fops, sb, 0);
+ /* releasing shrbuf on failure */
+ if (fd < 0)
+ sb->put(sb);
+ return fd;
+}
+
+EXPORT_SYMBOL(shrbuf_export);
+
+/**
+ * shrbuf_import() - obtain shrbuf structure from a file descriptor
+ * @fd: file descriptor
+ *
+ * The function obtains an instance of a shared buffer from a file
descriptor
+ * Call sb->put when imported buffer is not longer needed
+ *
+ * Returns pointer to a shared buffer or error pointer on failure
+ */
+struct shrbuf *shrbuf_import(int fd)
+{
+ struct file *file;
+ struct shrbuf *sb;
+
+ /* obtain a file, assure that it will not be released */
+ file = fget(fd);
+ /* check if descriptor is incorrect */
+ if (!file)
+ return ERR_PTR(-EBADF);
+ /* check if dealing with shrbuf-file */
+ if (file->f_op != &shrbuf_fops) {
+ fput(file);
+ return ERR_PTR(-EINVAL);
+ }
+ /* add user of shared buffer */
+ sb = file->private_data;
+ sb->get(sb);
+ /* release the file */
+ fput(file);
+
+ return sb;
+}
+
+EXPORT_SYMBOL(shrbuf_import);
+
new file mode 100644
@@ -0,0 +1,55 @@
+/*
+ * Framework for shared buffer
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Author: Tomasz Stanislawski, <t.stanislaws@samsung.com>
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_SHARED_BUFFER_H
+#define _LINUX_SHARED_BUFFER_H
+
+#include <linux/err.h>
+
+/**
+ * struct shrbuf - shared buffer instance
+ * @get: increase number of a buffer's users
+ * @put: decrease number of a buffer's user, release resources if needed
+ * @dma_addr: start address of a contiguous buffer
+ * @size: size of a contiguous buffer
+ *
+ * Both get/put methods are required. The structure is dedicated for
+ * embedding. The fields dma_addr and size are used for proof-of-concept
+ * purpose. They will be substituted by scatter-gatter lists.
+ */
+struct shrbuf {
+ void (*get)(struct shrbuf *);
+ void (*put)(struct shrbuf *);
+ unsigned long dma_addr;
+ unsigned long size;
+};
+
+#ifdef CONFIG_SHARED_BUFFER
+
+int shrbuf_export(struct shrbuf *sb);
+
+struct shrbuf *shrbuf_import(int fd);
+
+#else
+
+static inline int shrbuf_export(struct shrbuf *sb)
+{
+ return -ENODEV;
+}
+
+static inline struct shrbuf *shrbuf_import(int fd)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+#endif /* CONFIG_SHARED_BUFFER */
+
+#endif /* _LINUX_SHARED_BUFFER_H */