[meta-xilinx] [linux-xlnx] uio as module fails to link

Hyun Kwon hyun.kwon at xilinx.com
Mon Jul 8 11:51:02 PDT 2019


Hi JFD,

Thanks for reporting the issue.

On Mon, 2019-07-08 at 09:01:03 -0700, Jean-Francois Dagenais wrote:
> Anyone tried that? I get:
> 
> WARNING: modpost: missing MODULE_LICENSE() in drivers/uio/uio_dmabuf.o
> see include/linux/module.h for more information
> ERROR: "uio_dmabuf_map" [drivers/uio/uio.ko] undefined!
> ERROR: "uio_dmabuf_unmap" [drivers/uio/uio.ko] undefined!
> ERROR: "uio_dmabuf_cleanup" [drivers/uio/uio.ko] undefined!
> 
> uio/Makefile shows:
> obj-$(CONFIG_UIO)	+= uio.o uio_dmabuf.o
> 
> I got it to compile by hacking uio.c to #include uio_dmabuf.c instead of the .h but that's probably not the correct way to fix this.
> 

The easiest fix would be to merge uio_dmabuf.c into uio.c. Please see
the attached patch and let me know if you see any other better way.

Thanks,
-hyun

>From 84cbe02cf2775dca911c2b734dded794150698a8 Mon Sep 17 00:00:00 2001
From: Hyun Kwon <hyun.kwon at xilinx.com>
Date: Mon, 8 Jul 2019 11:37:03 -0700
Subject: [PATCH 1/1] uio: dmabuf: Merge the dmabuf functions into uio.c

With a separate uio_dmabuf.c, it's tricky to build the uio as
a separate kernel module.

Reported-by: Jean-Francois Dagenais <jeff.dagenais at gmail.com>
Signed-off-by: Hyun Kwon <hyun.kwon at xilinx.com>
---
 drivers/uio/Makefile     |   2 +-
 drivers/uio/uio.c        | 191 ++++++++++++++++++++++++++++++++++++++++++
 drivers/uio/uio_dmabuf.c | 210 -----------------------------------------------
 3 files changed, 192 insertions(+), 211 deletions(-)
 delete mode 100644 drivers/uio/uio_dmabuf.c

diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index 7af888a..aea3e17 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_UIO)	+= uio.o uio_dmabuf.o
+obj-$(CONFIG_UIO)	+= uio.o
 obj-$(CONFIG_UIO_CIF)	+= uio_cif.o
 obj-$(CONFIG_UIO_PDRV_GENIRQ)	+= uio_pdrv_genirq.o
 obj-$(CONFIG_UIO_DMEM_GENIRQ)	+= uio_dmem_genirq.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index e054fa7..175fb6b 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -26,6 +26,7 @@
 #include <linux/uio_driver.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/dma-buf.h>
 
 #include <uapi/linux/uio/uio.h>
 
@@ -455,6 +456,196 @@ static irqreturn_t uio_interrupt(int irq, void *dev_id)
 	return ret;
 }
 
+struct uio_dmabuf_mem {
+	int dbuf_fd;
+	struct dma_buf *dbuf;
+	struct dma_buf_attachment *dbuf_attach;
+	struct sg_table *sgt;
+	enum dma_data_direction dir;
+	struct list_head list;
+};
+
+long uio_dmabuf_map(struct uio_device *dev, struct list_head *dbufs,
+		    struct mutex *dbufs_lock, void __user *user_args)
+{
+	struct uio_dmabuf_args args;
+	struct uio_dmabuf_mem *dbuf_mem;
+	struct dma_buf *dbuf;
+	struct dma_buf_attachment *dbuf_attach;
+	enum dma_data_direction dir;
+	struct sg_table *sgt;
+	long ret;
+
+	if (copy_from_user(&args, user_args, sizeof(args))) {
+		ret = -EFAULT;
+		dev_err(dev->dev.parent, "failed to copy from user\n");
+		goto err;
+	}
+
+	dbuf = dma_buf_get(args.dbuf_fd);
+	if (IS_ERR(dbuf)) {
+		dev_err(dev->dev.parent, "failed to get dmabuf\n");
+		return PTR_ERR(dbuf);
+	}
+
+	dbuf_attach = dma_buf_attach(dbuf, dev->dev.parent);
+	if (IS_ERR(dbuf_attach)) {
+		dev_err(dev->dev.parent, "failed to attach dmabuf\n");
+		ret = PTR_ERR(dbuf_attach);
+		goto err_put;
+	}
+
+	switch (args.dir) {
+	case UIO_DMABUF_DIR_BIDIR:
+		dir = DMA_BIDIRECTIONAL;
+		break;
+	case UIO_DMABUF_DIR_TO_DEV:
+		dir = DMA_TO_DEVICE;
+		break;
+	case UIO_DMABUF_DIR_FROM_DEV:
+		dir = DMA_FROM_DEVICE;
+		break;
+	default:
+		/* Not needed with check. Just here for any future change  */
+		dev_err(dev->dev.parent, "invalid direction\n");
+		ret = -EINVAL;
+		goto err_detach;
+	}
+
+	sgt = dma_buf_map_attachment(dbuf_attach, dir);
+	if (IS_ERR(sgt)) {
+		dev_err(dev->dev.parent, "failed to get dmabuf scatterlist\n");
+		ret = PTR_ERR(sgt);
+		goto err_detach;
+	}
+
+	/* Accept only contiguous one */
+	if (sgt->nents != 1) {
+		dma_addr_t next_addr = sg_dma_address(sgt->sgl);
+		struct scatterlist *s;
+		unsigned int i;
+
+		for_each_sg(sgt->sgl, s, sgt->nents, i) {
+			if (!sg_dma_len(s))
+				continue;
+
+			if (sg_dma_address(s) != next_addr) {
+				dev_err(dev->dev.parent,
+					"dmabuf not contiguous\n");
+				ret = -EINVAL;
+				goto err_unmap;
+			}
+
+			next_addr = sg_dma_address(s) + sg_dma_len(s);
+		}
+	}
+
+	dbuf_mem = kzalloc(sizeof(*dbuf_mem), GFP_KERNEL);
+	if (!dbuf_mem) {
+		ret = -ENOMEM;
+		goto err_unmap;
+	}
+
+	dbuf_mem->dbuf_fd = args.dbuf_fd;
+	dbuf_mem->dbuf = dbuf;
+	dbuf_mem->dbuf_attach = dbuf_attach;
+	dbuf_mem->sgt = sgt;
+	dbuf_mem->dir = dir;
+	args.dma_addr = sg_dma_address(sgt->sgl);
+	args.size = dbuf->size;
+
+	if (copy_to_user(user_args, &args, sizeof(args))) {
+		ret = -EFAULT;
+		dev_err(dev->dev.parent, "failed to copy to user\n");
+		goto err_free;
+	}
+
+	mutex_lock(dbufs_lock);
+	list_add(&dbuf_mem->list, dbufs);
+	mutex_unlock(dbufs_lock);
+
+	return 0;
+
+err_free:
+	kfree(dbuf_mem);
+err_unmap:
+	dma_buf_unmap_attachment(dbuf_attach, sgt, dir);
+err_detach:
+	dma_buf_detach(dbuf, dbuf_attach);
+err_put:
+	dma_buf_put(dbuf);
+err:
+	return ret;
+}
+
+long uio_dmabuf_unmap(struct uio_device *dev, struct list_head *dbufs,
+		      struct mutex *dbufs_lock, void __user *user_args)
+
+{
+	struct uio_dmabuf_args args;
+	struct uio_dmabuf_mem *dbuf_mem;
+	long ret;
+
+	if (copy_from_user(&args, user_args, sizeof(args))) {
+		ret = -EFAULT;
+		goto err;
+	}
+
+	mutex_lock(dbufs_lock);
+	list_for_each_entry(dbuf_mem, dbufs, list) {
+		if (dbuf_mem->dbuf_fd == args.dbuf_fd)
+			break;
+	}
+
+	if (dbuf_mem->dbuf_fd != args.dbuf_fd) {
+		dev_err(dev->dev.parent, "failed to find the dmabuf (%d)\n",
+			args.dbuf_fd);
+		ret = -EINVAL;
+		goto err_unlock;
+	}
+	list_del(&dbuf_mem->list);
+	mutex_unlock(dbufs_lock);
+
+	dma_buf_unmap_attachment(dbuf_mem->dbuf_attach, dbuf_mem->sgt,
+				 dbuf_mem->dir);
+	dma_buf_detach(dbuf_mem->dbuf, dbuf_mem->dbuf_attach);
+	dma_buf_put(dbuf_mem->dbuf);
+	kfree(dbuf_mem);
+
+	memset(&args, 0x0, sizeof(args));
+
+	if (copy_to_user(user_args, &args, sizeof(args))) {
+		ret = -EFAULT;
+		goto err;
+	}
+
+	return 0;
+
+err_unlock:
+	mutex_unlock(dbufs_lock);
+err:
+	return ret;
+}
+
+int uio_dmabuf_cleanup(struct uio_device *dev, struct list_head *dbufs,
+		       struct mutex *dbufs_lock)
+{
+	struct uio_dmabuf_mem *dbuf_mem, *next;
+
+	mutex_lock(dbufs_lock);
+	list_for_each_entry_safe(dbuf_mem, next, dbufs, list) {
+		list_del(&dbuf_mem->list);
+		dma_buf_unmap_attachment(dbuf_mem->dbuf_attach, dbuf_mem->sgt,
+					 dbuf_mem->dir);
+		dma_buf_detach(dbuf_mem->dbuf, dbuf_mem->dbuf_attach);
+		dma_buf_put(dbuf_mem->dbuf);
+		kfree(dbuf_mem);
+	}
+	mutex_unlock(dbufs_lock);
+
+	return 0;
+}
+
 struct uio_listener {
 	struct uio_device *dev;
 	s32 event_count;
diff --git a/drivers/uio/uio_dmabuf.c b/drivers/uio/uio_dmabuf.c
deleted file mode 100644
index b18f146..0000000
--- a/drivers/uio/uio_dmabuf.c
+++ /dev/null
@@ -1,210 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2019 Xilinx, Inc.
- *
- * Author: Hyun Woo Kwon <hyun.kwon at xilinx.com>
- *
- * DMA buf support for UIO device
- *
- */
-
-#include <linux/dma-buf.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/uio_driver.h>
-#include <linux/slab.h>
-
-#include <uapi/linux/uio/uio.h>
-
-#include "uio_dmabuf.h"
-
-struct uio_dmabuf_mem {
-	int dbuf_fd;
-	struct dma_buf *dbuf;
-	struct dma_buf_attachment *dbuf_attach;
-	struct sg_table *sgt;
-	enum dma_data_direction dir;
-	struct list_head list;
-};
-
-long uio_dmabuf_map(struct uio_device *dev, struct list_head *dbufs,
-		    struct mutex *dbufs_lock, void __user *user_args)
-{
-	struct uio_dmabuf_args args;
-	struct uio_dmabuf_mem *dbuf_mem;
-	struct dma_buf *dbuf;
-	struct dma_buf_attachment *dbuf_attach;
-	enum dma_data_direction dir;
-	struct sg_table *sgt;
-	long ret;
-
-	if (copy_from_user(&args, user_args, sizeof(args))) {
-		ret = -EFAULT;
-		dev_err(dev->dev.parent, "failed to copy from user\n");
-		goto err;
-	}
-
-	dbuf = dma_buf_get(args.dbuf_fd);
-	if (IS_ERR(dbuf)) {
-		dev_err(dev->dev.parent, "failed to get dmabuf\n");
-		return PTR_ERR(dbuf);
-	}
-
-	dbuf_attach = dma_buf_attach(dbuf, dev->dev.parent);
-	if (IS_ERR(dbuf_attach)) {
-		dev_err(dev->dev.parent, "failed to attach dmabuf\n");
-		ret = PTR_ERR(dbuf_attach);
-		goto err_put;
-	}
-
-	switch (args.dir) {
-	case UIO_DMABUF_DIR_BIDIR:
-		dir = DMA_BIDIRECTIONAL;
-		break;
-	case UIO_DMABUF_DIR_TO_DEV:
-		dir = DMA_TO_DEVICE;
-		break;
-	case UIO_DMABUF_DIR_FROM_DEV:
-		dir = DMA_FROM_DEVICE;
-		break;
-	default:
-		/* Not needed with check. Just here for any future change  */
-		dev_err(dev->dev.parent, "invalid direction\n");
-		ret = -EINVAL;
-		goto err_detach;
-	}
-
-	sgt = dma_buf_map_attachment(dbuf_attach, dir);
-	if (IS_ERR(sgt)) {
-		dev_err(dev->dev.parent, "failed to get dmabuf scatterlist\n");
-		ret = PTR_ERR(sgt);
-		goto err_detach;
-	}
-
-	/* Accept only contiguous one */
-	if (sgt->nents != 1) {
-		dma_addr_t next_addr = sg_dma_address(sgt->sgl);
-		struct scatterlist *s;
-		unsigned int i;
-
-		for_each_sg(sgt->sgl, s, sgt->nents, i) {
-			if (!sg_dma_len(s))
-				continue;
-
-			if (sg_dma_address(s) != next_addr) {
-				dev_err(dev->dev.parent,
-					"dmabuf not contiguous\n");
-				ret = -EINVAL;
-				goto err_unmap;
-			}
-
-			next_addr = sg_dma_address(s) + sg_dma_len(s);
-		}
-	}
-
-	dbuf_mem = kzalloc(sizeof(*dbuf_mem), GFP_KERNEL);
-	if (!dbuf_mem) {
-		ret = -ENOMEM;
-		goto err_unmap;
-	}
-
-	dbuf_mem->dbuf_fd = args.dbuf_fd;
-	dbuf_mem->dbuf = dbuf;
-	dbuf_mem->dbuf_attach = dbuf_attach;
-	dbuf_mem->sgt = sgt;
-	dbuf_mem->dir = dir;
-	args.dma_addr = sg_dma_address(sgt->sgl);
-	args.size = dbuf->size;
-
-	if (copy_to_user(user_args, &args, sizeof(args))) {
-		ret = -EFAULT;
-		dev_err(dev->dev.parent, "failed to copy to user\n");
-		goto err_free;
-	}
-
-	mutex_lock(dbufs_lock);
-	list_add(&dbuf_mem->list, dbufs);
-	mutex_unlock(dbufs_lock);
-
-	return 0;
-
-err_free:
-	kfree(dbuf_mem);
-err_unmap:
-	dma_buf_unmap_attachment(dbuf_attach, sgt, dir);
-err_detach:
-	dma_buf_detach(dbuf, dbuf_attach);
-err_put:
-	dma_buf_put(dbuf);
-err:
-	return ret;
-}
-
-long uio_dmabuf_unmap(struct uio_device *dev, struct list_head *dbufs,
-		      struct mutex *dbufs_lock, void __user *user_args)
-
-{
-	struct uio_dmabuf_args args;
-	struct uio_dmabuf_mem *dbuf_mem;
-	long ret;
-
-	if (copy_from_user(&args, user_args, sizeof(args))) {
-		ret = -EFAULT;
-		goto err;
-	}
-
-	mutex_lock(dbufs_lock);
-	list_for_each_entry(dbuf_mem, dbufs, list) {
-		if (dbuf_mem->dbuf_fd == args.dbuf_fd)
-			break;
-	}
-
-	if (dbuf_mem->dbuf_fd != args.dbuf_fd) {
-		dev_err(dev->dev.parent, "failed to find the dmabuf (%d)\n",
-			args.dbuf_fd);
-		ret = -EINVAL;
-		goto err_unlock;
-	}
-	list_del(&dbuf_mem->list);
-	mutex_unlock(dbufs_lock);
-
-	dma_buf_unmap_attachment(dbuf_mem->dbuf_attach, dbuf_mem->sgt,
-				 dbuf_mem->dir);
-	dma_buf_detach(dbuf_mem->dbuf, dbuf_mem->dbuf_attach);
-	dma_buf_put(dbuf_mem->dbuf);
-	kfree(dbuf_mem);
-
-	memset(&args, 0x0, sizeof(args));
-
-	if (copy_to_user(user_args, &args, sizeof(args))) {
-		ret = -EFAULT;
-		goto err;
-	}
-
-	return 0;
-
-err_unlock:
-	mutex_unlock(dbufs_lock);
-err:
-	return ret;
-}
-
-int uio_dmabuf_cleanup(struct uio_device *dev, struct list_head *dbufs,
-		       struct mutex *dbufs_lock)
-{
-	struct uio_dmabuf_mem *dbuf_mem, *next;
-
-	mutex_lock(dbufs_lock);
-	list_for_each_entry_safe(dbuf_mem, next, dbufs, list) {
-		list_del(&dbuf_mem->list);
-		dma_buf_unmap_attachment(dbuf_mem->dbuf_attach, dbuf_mem->sgt,
-					 dbuf_mem->dir);
-		dma_buf_detach(dbuf_mem->dbuf, dbuf_mem->dbuf_attach);
-		dma_buf_put(dbuf_mem->dbuf);
-		kfree(dbuf_mem);
-	}
-	mutex_unlock(dbufs_lock);
-
-	return 0;
-}
-- 
2.7.4

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-uio-dmabuf-Merge-the-dmabuf-functions-into-uio.c.patch
Type: text/x-diff
Size: 11049 bytes
Desc: not available
URL: <http://lists.yoctoproject.org/pipermail/meta-xilinx/attachments/20190708/e47a225d/attachment.patch>


More information about the meta-xilinx mailing list