linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT PATCH] UIO patches for 2.6.21
@ 2007-04-27 22:49 Greg KH
  2007-04-27 22:50 ` [PATCH 1/3] UIO: Add the User IO core code Greg Kroah-Hartman
                   ` (3 more replies)
  0 siblings, 4 replies; 42+ messages in thread
From: Greg KH @ 2007-04-27 22:49 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton
  Cc: linux-kernel, tglx, Benedikt Spranger, Hans J. Koch

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=unknown-8bit, Size: 1831 bytes --]

Here are the updated UIO (Userspace I/O driver framework) patches for
2.6.21.

They have been revamped from the last time you have seen them, and they
include a real driver, the Hilscher CIF DeviceNet and Profibus card
controller, which is being used in production systems with this driver
framework right now.  The kernel driver they replaced was a total mess,
with over 60+ ioctls to try to control the different aspects of the
device.  See the last patch in this series for more details on this
driver.

These patches include full documentation, are self-contained from the
rest of the kernel, and have been in the -mm tree for the past few
months with no complaints.

Please pull from:
	master.kernel.org:/pub/scm/linux/kernel/git/gregkh/uio-2.6.git/

Patches will be sent as a follow-on to this message to lkml for people
to see.

thanks,

greg k-h


 Documentation/DocBook/kernel-api.tmpl |    4 +
 Documentation/DocBook/uio-howto.tmpl  |  498 +++++++++++++++++++++++
 drivers/Kconfig                       |    1 +
 drivers/Makefile                      |    1 +
 drivers/uio/Kconfig                   |   27 ++
 drivers/uio/Makefile                  |    2 +
 drivers/uio/uio.c                     |  702 +++++++++++++++++++++++++++++++++
 drivers/uio/uio_cif.c                 |  156 ++++++++
 include/linux/uio_driver.h            |   91 +++++
 9 files changed, 1482 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/DocBook/uio-howto.tmpl
 create mode 100644 drivers/uio/Kconfig
 create mode 100644 drivers/uio/Makefile
 create mode 100644 drivers/uio/uio.c
 create mode 100644 drivers/uio/uio_cif.c
 create mode 100644 include/linux/uio_driver.h

---------------

Hans J. Koch (2):
      UIO: Add the User IO core code
      UIO: Documentation

Hans-Jürgen Koch (1):
      UIO: Hilscher CIF card driver


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/3] UIO: Add the User IO core code
  2007-04-27 22:49 [GIT PATCH] UIO patches for 2.6.21 Greg KH
@ 2007-04-27 22:50 ` Greg Kroah-Hartman
  2007-04-27 22:50   ` [PATCH 2/3] UIO: Documentation Greg Kroah-Hartman
  2007-04-27 23:19   ` Flaws with "UIO: Add the User IO core code" Alan Cox
  2007-04-27 23:04 ` [GIT PATCH] UIO patches for 2.6.21 Andrew Morton
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 42+ messages in thread
From: Greg Kroah-Hartman @ 2007-04-27 22:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: torvalds, Thomas Gleixner, Benedikt Spranger, Greg Kroah-Hartman

From: Hans J. Koch <hjk@linutronix.de>

This interface allows the ability to write the majority of a driver in
userspace with only a very small shell of a driver in the kernel itself.
It uses a char device and sysfs to interact with a userspace process to
process interrupts and control memory accesses.

See the docbook documentation for more details on how to use this
interface.

From: Hans J. Koch <hjk@linutronix.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/Kconfig            |    1 +
 drivers/Makefile           |    1 +
 drivers/uio/Kconfig        |   14 +
 drivers/uio/Makefile       |    1 +
 drivers/uio/uio.c          |  702 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/uio_driver.h |   91 ++++++
 6 files changed, 810 insertions(+), 0 deletions(-)
 create mode 100644 drivers/uio/Kconfig
 create mode 100644 drivers/uio/Makefile
 create mode 100644 drivers/uio/uio.c
 create mode 100644 include/linux/uio_driver.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 050323f..325a108 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -84,4 +84,5 @@ source "drivers/auxdisplay/Kconfig"
 
 source "drivers/kvm/Kconfig"
 
+source "drivers/uio/Kconfig"
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 920c975..5cf267f 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_SCSI)		+= scsi/
 obj-$(CONFIG_ATA)		+= ata/
 obj-$(CONFIG_FUSION)		+= message/
 obj-$(CONFIG_IEEE1394)		+= ieee1394/
+obj-$(CONFIG_UIO)		+= uio/
 obj-y				+= cdrom/
 obj-y				+= auxdisplay/
 obj-$(CONFIG_MTD)		+= mtd/
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
new file mode 100644
index 0000000..8fcef21
--- /dev/null
+++ b/drivers/uio/Kconfig
@@ -0,0 +1,14 @@
+menu "Userspace I/O"
+config UIO
+	tristate "Userspace I/O drivers"
+	default n
+	help
+	  Enable this to allow the userspace driver core code to be
+	  built.  This code allows userspace programs easy access to
+	  kernel interrupts and memory locations, allowing some drivers
+	  to be written in userspace.  Note that a small kernel driver
+	  is also required for interrupt handling to work properly.
+
+	  If you don't know what to do here, say N.
+
+endmenu
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
new file mode 100644
index 0000000..9b7c830
--- /dev/null
+++ b/drivers/uio/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_UIO) += uio.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
new file mode 100644
index 0000000..6ca3379
--- /dev/null
+++ b/drivers/uio/uio.c
@@ -0,0 +1,702 @@
+/*
+ * drivers/uio/uio.c
+ *
+ * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
+ * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
+ * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
+ * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
+ *
+ * Userspace IO
+ *
+ * Base Functions
+ *
+ * Licensed under the GPLv2 only.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/idr.h>
+#include <linux/string.h>
+#include <linux/kobject.h>
+#include <linux/uio_driver.h>
+
+#define UIO_MAX_DEVICES 255
+
+struct uio_device {
+	struct module		*owner;
+	struct device		*dev;
+	int			minor;
+	atomic_t		event;
+	struct fasync_struct	*async_queue;
+	wait_queue_head_t	wait;
+	int			vma_count;
+	struct uio_info		*info;
+	struct kset 		map_attr_kset;
+};
+
+static int uio_major;
+static DEFINE_IDR(uio_idr);
+static struct file_operations uio_fops;
+
+/* UIO class infrastructure */
+static struct uio_class {
+	struct kref kref;
+	struct class *class;
+} *uio_class;
+
+/*
+ * attributes
+ */
+
+static struct attribute attr_addr = {
+	.name  = "addr",
+	.mode  = S_IRUGO,
+};
+
+static struct attribute attr_size = {
+	.name  = "size",
+	.mode  = S_IRUGO,
+};
+
+static struct attribute* map_attrs[] = {
+	&attr_addr, &attr_size, NULL
+};
+
+static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr,
+			     char *buf)
+{
+	struct uio_mem *mem = container_of(kobj, struct uio_mem, kobj);
+
+	if (strncmp(attr->name,"addr",4) == 0)
+		return sprintf(buf, "0x%lx\n", mem->addr);
+
+	if (strncmp(attr->name,"size",4) == 0)
+		return sprintf(buf, "0x%lx\n", mem->size);
+
+	return -ENODEV;
+}
+
+static void map_attr_release(struct kobject *kobj)
+{
+	/* TODO ??? */
+}
+
+static struct sysfs_ops map_attr_ops = {
+	.show  = map_attr_show,
+};
+
+static struct kobj_type map_attr_type = {
+	.release	= map_attr_release,
+	.sysfs_ops	= &map_attr_ops,
+	.default_attrs	= map_attrs,
+};
+
+static ssize_t show_name(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	struct uio_device *idev = dev_get_drvdata(dev);
+	if (idev)
+		return sprintf(buf, "%s\n", idev->info->name);
+	else
+		return -ENODEV;
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+static ssize_t show_version(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct uio_device *idev = dev_get_drvdata(dev);
+	if (idev)
+		return sprintf(buf, "%s\n", idev->info->version);
+	else
+		return -ENODEV;
+}
+static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
+
+static ssize_t show_event(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	struct uio_device *idev = dev_get_drvdata(dev);
+	if (idev)
+		return sprintf(buf, "%u\n",
+				(unsigned int)atomic_read(&idev->event));
+	else
+		return -ENODEV;
+}
+static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
+
+static struct attribute *uio_attrs[] = {
+	&dev_attr_name.attr,
+	&dev_attr_version.attr,
+	&dev_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group uio_attr_grp = {
+	.attrs = uio_attrs,
+};
+
+/*
+ * device functions
+ */
+static int uio_dev_add_attributes(struct uio_device *idev)
+{
+	int ret;
+	int mi;
+	int map_found = 0;
+	struct uio_mem *mem;
+
+	ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp);
+	if (ret)
+		goto err_group;
+
+	for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
+		mem = &idev->info->mem[mi];
+		if (mem->size == 0)
+			break;
+		if (!map_found) {
+			map_found = 1;
+			kobject_set_name(&idev->map_attr_kset.kobj,"maps");
+			idev->map_attr_kset.ktype = &map_attr_type;
+			idev->map_attr_kset.kobj.parent = &idev->dev->kobj;
+			idev->map_attr_kset.subsys = &uio_class->class->subsys;
+			ret = kset_register(&idev->map_attr_kset);
+			if (ret)
+				goto err_remove_group;
+		}
+		kobject_init(&mem->kobj);
+		kobject_set_name(&mem->kobj,"map%d",mi);
+		mem->kobj.parent = &idev->map_attr_kset.kobj;
+		mem->kobj.kset = &idev->map_attr_kset;
+		ret = kobject_add(&mem->kobj);
+		if (ret)
+			goto err_remove_maps;
+	}
+
+	return 0;
+
+err_remove_maps:
+	for (mi--; mi>=0; mi--) {
+		mem = &idev->info->mem[mi];
+		kobject_unregister(&mem->kobj);
+	}
+	kset_unregister(&idev->map_attr_kset); /* Needed ? */
+err_remove_group:
+	sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
+err_group:
+	dev_err(idev->dev, "error creating sysfs files (%d)\n", ret);
+	return ret;
+}
+
+static void uio_dev_del_attributes(struct uio_device *idev)
+{
+	int mi;
+	struct uio_mem *mem;
+	for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
+		mem = &idev->info->mem[mi];
+		if (mem->size == 0)
+			break;
+		kobject_unregister(&mem->kobj);
+	}
+	kset_unregister(&idev->map_attr_kset);
+	sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
+}
+
+static int uio_get_minor(struct uio_device *idev)
+{
+	static DEFINE_MUTEX(minor_lock);
+	int retval = -ENOMEM;
+	int id;
+
+	mutex_lock(&minor_lock);
+	if (idr_pre_get(&uio_idr, GFP_KERNEL) == 0)
+		goto exit;
+
+	retval = idr_get_new(&uio_idr, idev, &id);
+	if (retval < 0) {
+		if (retval == -EAGAIN)
+			retval = -ENOMEM;
+		goto exit;
+	}
+	idev->minor = id & MAX_ID_MASK;
+exit:
+	mutex_unlock(&minor_lock);
+	return retval;
+}
+
+static void uio_free_minor(struct uio_device *idev)
+{
+	idr_remove(&uio_idr, idev->minor);
+}
+
+/**
+ * uio_event_notify - trigger an interrupt event
+ * @idev: UIO device where the event occured
+ */
+void uio_event_notify(struct uio_info *info)
+{
+	struct uio_device *idev = info->uio_dev;
+
+	atomic_inc(&idev->event);
+	wake_up_interruptible(&idev->wait);
+	kill_fasync(&idev->async_queue, SIGIO, POLL_IN);
+}
+EXPORT_SYMBOL_GPL(uio_event_notify);
+
+/**
+ * uio_interrupt - hardware interrupt handler
+ * @irq: IRQ number, can be UIO_IRQ_CYCLIC for cyclic timer
+ * @dev_id: Pointer to the devices uio_device structure
+ */
+static irqreturn_t uio_interrupt(int irq, void *dev_id)
+{
+	struct uio_device *idev = (struct uio_device *)dev_id;
+	irqreturn_t ret = idev->info->handler(irq, idev->info);
+
+	if (ret == IRQ_HANDLED)
+		uio_event_notify(idev->info);
+
+	return ret;
+}
+
+struct uio_listener {
+	struct uio_device *dev;
+	int event_count;
+};
+
+static int uio_open(struct inode *inode, struct file *filep)
+{
+	struct uio_device *idev;
+	struct uio_listener *listener;
+	int ret = 0;
+
+	idev = idr_find(&uio_idr, iminor(inode));
+	if (!idev)
+		return -ENODEV;
+
+	listener = kmalloc(sizeof(*listener), GFP_KERNEL);
+	if (!listener)
+		return -ENOMEM;
+
+	listener->dev = idev;
+	listener->event_count = atomic_read(&idev->event);
+	filep->private_data = listener;
+
+	if (idev->info->open) {
+		if (!try_module_get(idev->owner))
+			return -ENODEV;
+		ret = idev->info->open(idev->info, inode);
+		module_put(idev->owner);
+	}
+
+	if (ret)
+		kfree(listener);
+
+	return ret;
+}
+
+static int uio_fasync(int fd, struct file *filep, int on)
+{
+	struct uio_listener *listener = filep->private_data;
+	struct uio_device *idev = listener->dev;
+
+	return fasync_helper(fd, filep, on, &idev->async_queue);
+}
+
+static int uio_release(struct inode *inode, struct file *filep)
+{
+	int ret = 0;
+	struct uio_listener *listener = filep->private_data;
+	struct uio_device *idev = listener->dev;
+
+	if (idev->info->release) {
+		if (!try_module_get(idev->owner))
+			return -ENODEV;
+		ret = idev->info->release(idev->info, inode);
+		module_put(idev->owner);
+	}
+	if (filep->f_flags & FASYNC)
+		ret = uio_fasync(-1, filep, 0);
+	kfree(listener);
+	return ret;
+}
+
+static unsigned int uio_poll(struct file *filep, poll_table *wait)
+{
+	struct uio_listener *listener = filep->private_data;
+	struct uio_device *idev = listener->dev;
+
+	if (idev->info->irq == UIO_IRQ_NONE)
+		return -EIO;
+
+	poll_wait(filep, &idev->wait, wait);
+	if (listener->event_count != atomic_read(&idev->event))
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+static ssize_t uio_read(struct file *filep, char __user *buf,
+			size_t count, loff_t *ppos)
+{
+	struct uio_listener *listener = filep->private_data;
+	struct uio_device *idev = listener->dev;
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t retval;
+	int event_count;
+
+	if (idev->info->irq == UIO_IRQ_NONE)
+		return -EIO;
+
+	if (count != sizeof(int))
+		return -EINVAL;
+
+	add_wait_queue(&idev->wait, &wait);
+
+	do {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		event_count = atomic_read(&idev->event);
+		if (event_count != listener->event_count) {
+			if (copy_to_user(buf, &event_count, count))
+				retval = -EFAULT;
+			else {
+				listener->event_count = event_count;
+				retval = count;
+			}
+			break;
+		}
+
+		if (filep->f_flags & O_NONBLOCK) {
+			retval = -EAGAIN;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	} while (1);
+
+	__set_current_state(TASK_RUNNING);
+	remove_wait_queue(&idev->wait, &wait);
+
+	return retval;
+}
+
+static int uio_find_mem_index(struct vm_area_struct *vma)
+{
+	int mi;
+	struct uio_device *idev = vma->vm_private_data;
+
+	for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
+		if (idev->info->mem[mi].size == 0)
+			return -1;
+		if (vma->vm_pgoff == mi)
+			return mi;
+	}
+	return -1;
+}
+
+static void uio_vma_open(struct vm_area_struct *vma)
+{
+	struct uio_device *idev = vma->vm_private_data;
+	idev->vma_count++;
+}
+
+static void uio_vma_close(struct vm_area_struct *vma)
+{
+	struct uio_device *idev = vma->vm_private_data;
+	idev->vma_count--;
+}
+
+static struct page *uio_vma_nopage(struct vm_area_struct *vma,
+				   unsigned long address, int *type)
+{
+	struct uio_device *idev = vma->vm_private_data;
+	struct page* page = NOPAGE_SIGBUS;
+
+	int mi = uio_find_mem_index(vma);
+	if (mi < 0)
+		return page;
+
+	if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
+		page = virt_to_page(idev->info->mem[mi].addr);
+	else
+		page = vmalloc_to_page((void*)idev->info->mem[mi].addr);
+	get_page(page);
+	if (type)
+		*type = VM_FAULT_MINOR;
+	return page;
+}
+
+static struct vm_operations_struct uio_vm_ops = {
+	.open = uio_vma_open,
+	.close = uio_vma_close,
+	.nopage = uio_vma_nopage,
+};
+
+static int uio_mmap_physical(struct vm_area_struct *vma)
+{
+	struct uio_device *idev = vma->vm_private_data;
+	int mi = uio_find_mem_index(vma);
+	if (mi < 0)
+		return -EINVAL;
+
+	vma->vm_flags |= VM_IO | VM_RESERVED;
+
+	return remap_pfn_range(vma,
+			       vma->vm_start,
+			       idev->info->mem[mi].addr >> PAGE_SHIFT,
+			       vma->vm_end - vma->vm_start,
+			       vma->vm_page_prot);
+}
+
+static int uio_mmap_logical(struct vm_area_struct *vma)
+{
+	vma->vm_flags |= VM_RESERVED;
+	vma->vm_ops = &uio_vm_ops;
+	uio_vma_open(vma);
+	return 0;
+}
+
+static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
+{
+	struct uio_listener *listener = filep->private_data;
+	struct uio_device *idev = listener->dev;
+	int mi;
+	unsigned long requested_pages, actual_pages;
+	int ret = 0;
+
+	if (vma->vm_end < vma->vm_start)
+		return -EINVAL;
+
+	vma->vm_private_data = idev;
+
+	mi = uio_find_mem_index(vma);
+	if (mi < 0)
+		return -EINVAL;
+
+	requested_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+	actual_pages = (idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
+	if (requested_pages > actual_pages)
+		return -EINVAL;
+
+	if (idev->info->mmap) {
+		if (!try_module_get(idev->owner))
+			return -ENODEV;
+		ret = idev->info->mmap(idev->info, vma);
+		module_put(idev->owner);
+		return ret;
+	}
+
+	switch (idev->info->mem[mi].memtype) {
+		case UIO_MEM_PHYS:
+			return uio_mmap_physical(vma);
+		case UIO_MEM_LOGICAL:
+		case UIO_MEM_VIRTUAL:
+			return uio_mmap_logical(vma);
+		default:
+			return -EINVAL;
+	}
+}
+
+static struct file_operations uio_fops = {
+	.owner		= THIS_MODULE,
+	.open		= uio_open,
+	.release	= uio_release,
+	.read		= uio_read,
+	.mmap		= uio_mmap,
+	.poll		= uio_poll,
+	.fasync		= uio_fasync,
+};
+
+static int uio_major_init(void)
+{
+	uio_major = register_chrdev(0, "uio", &uio_fops);
+	if (uio_major < 0)
+		return uio_major;
+	return 0;
+}
+
+static void uio_major_cleanup(void)
+{
+	unregister_chrdev(uio_major, "uio");
+}
+
+static int init_uio_class(void)
+{
+	int ret = 0;
+
+	if (uio_class != NULL) {
+		kref_get(&uio_class->kref);
+		goto exit;
+	}
+
+	/* This is the first time in here, set everything up properly */
+	ret = uio_major_init();
+	if (ret)
+		goto exit;
+
+	uio_class = kzalloc(sizeof(*uio_class), GFP_KERNEL);
+	if (!uio_class) {
+		ret = -ENOMEM;
+		goto err_kzalloc;
+	}
+
+	kref_init(&uio_class->kref);
+	uio_class->class = class_create(THIS_MODULE, "uio");
+	if (IS_ERR(uio_class->class)) {
+		ret = IS_ERR(uio_class->class);
+		printk(KERN_ERR "class_create failed for uio\n");
+		goto err_class_create;
+	}
+	return 0;
+
+err_class_create:
+	kfree(uio_class);
+	uio_class = NULL;
+err_kzalloc:
+	uio_major_cleanup();
+exit:
+	return ret;
+}
+
+static void release_uio_class(struct kref *kref)
+{
+	/* Ok, we cheat as we know we only have one uio_class */
+	class_destroy(uio_class->class);
+	kfree(uio_class);
+	uio_major_cleanup();
+	uio_class = NULL;
+}
+
+static void uio_class_destroy(void)
+{
+	if (uio_class)
+		kref_put(&uio_class->kref, release_uio_class);
+}
+
+/**
+ * uio_register_device - register a new userspace IO device
+ *
+ * @parent:	parent device
+ * @idev:	device capabilities
+ *
+ * returns zero on success or a negative error code.
+ */
+int __uio_register_device(struct module *owner,
+			  struct device *parent,
+			  struct uio_info *info)
+{
+	struct uio_device *idev;
+	int ret = 0;
+
+	if (!parent || !info || !info->name || !info->version)
+		return -EINVAL;
+
+	info->uio_dev = NULL;
+
+	ret = init_uio_class();
+	if (ret)
+		return ret;
+
+	idev = kzalloc(sizeof(*idev), GFP_KERNEL);
+	if (!idev) {
+		ret = -ENOMEM;
+		goto err_kzalloc;
+	}
+
+	idev->owner = owner;
+	idev->info = info;
+	init_waitqueue_head(&idev->wait);
+	atomic_set(&idev->event, 0);
+
+	ret = uio_get_minor(idev);
+	if (ret)
+		goto err_get_minor;
+
+	idev->dev = device_create(uio_class->class, parent,
+				  MKDEV(uio_major, idev->minor),
+				  "uio%d", idev->minor);
+	if (IS_ERR(idev->dev)) {
+		printk(KERN_ERR "UIO: device register failed\n");
+		ret = PTR_ERR(idev->dev);
+		goto err_device_create;
+	}
+	dev_set_drvdata(idev->dev, idev);
+
+	ret = uio_dev_add_attributes(idev);
+	if (ret)
+		goto err_uio_dev_add_attributes;
+
+	if (idev->info->irq >= 0) {
+		ret = request_irq(idev->info->irq, uio_interrupt,
+				  idev->info->irq_flags, idev->info->name, idev);
+		if (ret)
+			goto err_request_irq;
+	}
+
+	info->uio_dev = idev;
+	return 0;
+
+err_request_irq:
+	uio_dev_del_attributes(idev);
+err_uio_dev_add_attributes:
+	device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
+err_device_create:
+	uio_free_minor(idev);
+err_get_minor:
+	kfree(idev);
+err_kzalloc:
+	uio_class_destroy();
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__uio_register_device);
+
+/**
+ * uio_unregister_device - unregister a industrial IO device
+ * @uiodev:	UIO device driver identifier
+ *
+ * returns 0 on success
+ */
+void uio_unregister_device(struct uio_info *info)
+{
+	struct uio_device *idev;
+
+	if (!info || !info->uio_dev)
+		return;
+
+	idev = info->uio_dev;
+
+	uio_free_minor(idev);
+
+	if (info->irq >= 0)
+		free_irq(info->irq, idev);
+
+	uio_dev_del_attributes(idev);
+
+	dev_set_drvdata(idev->dev, NULL);
+	device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
+	kfree(idev);
+	uio_class_destroy();
+
+	return;
+}
+EXPORT_SYMBOL_GPL(uio_unregister_device);
+
+static int __init uio_init(void)
+{
+	return 0;
+}
+
+static void __exit uio_exit(void)
+{
+}
+
+module_init(uio_init)
+module_exit(uio_exit)
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
new file mode 100644
index 0000000..13d9f90
--- /dev/null
+++ b/include/linux/uio_driver.h
@@ -0,0 +1,91 @@
+/*
+ * include/linux/uio_driver.h
+ *
+ * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
+ * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
+ * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
+ * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
+ *
+ * Userspace IO driver.
+ *
+ * Licensed under the GPLv2 only.
+ */
+
+#ifndef _UIO_DRIVER_H_
+#define _UIO_DRIVER_H_
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+
+/**
+ * uio_mem - description of a UIO memory region
+ * @kobj:		kobject for this mapping
+ * @addr:		address of the device's memory
+ * @size:		size of IO
+ * @memtype:		type of memory addr points to
+ * @internal_addr:	ioremap-ped version of addr, for driver internal use
+ */
+struct uio_mem {
+	struct kobject		kobj;
+	unsigned long		addr;
+	unsigned long		size;
+	int			memtype;
+	void __iomem		*internal_addr;
+};
+
+#define MAX_UIO_MAPS 	5
+
+struct uio_device;
+
+/**
+ * uio_info - UIO device capabilities
+ * @uio_dev:		the UIO device this info belongs to
+ * @name:		device name
+ * @version:		device driver version
+ * @mem:		list of mappable memory regions, size==0 for end of list
+ * @irq:		interrupt number or UIO_IRQ_CUSTOM
+ * @irq_flags		flags for request_irq()
+ * @priv:		optional private data
+ * @handler:		the device's irq handler
+ * @mmap:		mmap operation for this uio device
+ * @open:		open operation for this uio device
+ * @release:		release operation for this uio device
+ */
+struct uio_info {
+	struct uio_device	*uio_dev;
+	char			*name;
+	char			*version;
+	struct uio_mem		mem[ MAX_UIO_MAPS ];
+	long			irq;
+	unsigned long		irq_flags;
+	void			*priv;
+	irqreturn_t (*handler)(int irq, struct uio_info *dev_info);
+	int (*mmap)(struct uio_info *info, struct vm_area_struct *vma);
+	int (*open)(struct uio_info *info, struct inode *inode);
+	int (*release)(struct uio_info *info, struct inode *inode);
+};
+
+extern int __must_check
+	__uio_register_device(struct module *owner,
+			      struct device *parent,
+			      struct uio_info *info);
+static inline int __must_check
+	uio_register_device(struct device *parent, struct uio_info *info)
+{
+	return __uio_register_device(THIS_MODULE, parent, info);
+}
+extern void uio_unregister_device(struct uio_info *info);
+extern void uio_event_notify(struct uio_info *info);
+
+/* defines for uio_device->irq */
+#define UIO_IRQ_CUSTOM	-1
+#define UIO_IRQ_NONE	-2
+
+/* defines for uio_device->memtype */
+#define UIO_MEM_NONE	0
+#define UIO_MEM_PHYS	1
+#define UIO_MEM_LOGICAL	2
+#define UIO_MEM_VIRTUAL 3
+
+#endif /* _LINUX_UIO_DRIVER_H_ */
-- 
1.5.1.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 2/3] UIO: Documentation
  2007-04-27 22:50 ` [PATCH 1/3] UIO: Add the User IO core code Greg Kroah-Hartman
@ 2007-04-27 22:50   ` Greg Kroah-Hartman
  2007-04-27 22:50     ` [PATCH 3/3] UIO: Hilscher CIF card driver Greg Kroah-Hartman
  2007-05-01 23:42     ` [PATCH 2/3] UIO: Documentation Randy Dunlap
  2007-04-27 23:19   ` Flaws with "UIO: Add the User IO core code" Alan Cox
  1 sibling, 2 replies; 42+ messages in thread
From: Greg Kroah-Hartman @ 2007-04-27 22:50 UTC (permalink / raw)
  To: linux-kernel; +Cc: torvalds, Greg Kroah-Hartman

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 18214 bytes --]

From: Hans J. Koch <hjk@linutronix.de>

Documentation for the UIO interface

From: Hans J. Koch <hjk@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 Documentation/DocBook/kernel-api.tmpl |    4 +
 Documentation/DocBook/uio-howto.tmpl  |  498 +++++++++++++++++++++++++++++++++
 2 files changed, 502 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/DocBook/uio-howto.tmpl

diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 0bb9023..40e968d 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -396,6 +396,10 @@ X!Edrivers/pnp/system.c
 !Edrivers/pnp/manager.c
 !Edrivers/pnp/support.c
      </sect1>
+     <sect1><title>Userspace IO devices</title>
+!Edrivers/uio/uio.c
+!Iinclude/linux/uio_driver.h
+     </sect1>
   </chapter>
 
   <chapter id="blkdev">
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
new file mode 100644
index 0000000..bd2209f
--- /dev/null
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -0,0 +1,498 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<article id="index">
+<articleinfo>
+<title>The Userspace I/O HOWTO</title>
+
+<author>
+      <firstname>Hans-Jürgen</firstname>
+      <surname>Koch</surname>
+      <authorblurb><para>Linux developer, Linutronix</para></authorblurb>
+	<affiliation>
+	<orgname>
+		<ulink url="http://www.linutronix.de">Linutronix</ulink>
+	</orgname>
+
+	<address>
+	   <email>hjk@linutronix.de</email>
+	</address>
+    </affiliation>
+</author>
+
+<pubdate>2006-12-11</pubdate>
+
+<abstract>
+	<para>This HOWTO describes concept and usage of Linux kernel's
+		Userspace I/O system.</para>
+</abstract>
+
+<revhistory>
+	<revision>
+	<revnumber>0.2</revnumber>
+	<date>2007-02-13</date>
+	<authorinitials>hjk</authorinitials>
+	<revremark>Update after multiple mappings were added.</revremark>
+	</revision>
+	<revision>
+	<revnumber>0.1</revnumber>
+	<date>2006-12-11</date>
+	<authorinitials>hjk</authorinitials>
+	<revremark>First draft.</revremark>
+	</revision>
+</revhistory>
+</articleinfo>
+
+<sect1 id="aboutthisdoc">
+<?dbhtml filename="about.html"?>
+<title>About this document</title>
+
+<sect2 id="copyright">
+<?dbhtml filename="copyright.html"?>
+<title>Copyright and License</title>
+<para>
+      Copyright (c) 2006 by Hans-Jürgen Koch.</para>
+<para>
+This documentation is Free Software licensed under the terms of the
+GPL version 2.
+</para>
+</sect2>
+
+<sect2 id="translations">
+<?dbhtml filename="translations.html"?>
+<title>Translations</title>
+
+<para>If you know of any translations for this document, or you are
+interested in translating it, please email me
+<email>hjk@linutronix.de</email>.
+</para>
+</sect2>
+
+<sect2 id="preface">
+<title>Preface</title>
+	<para>
+	For many types of devices, creating a Linux kernel driver is
+	overkill.  All that is really needed is some way to handle an
+	interrupt and provide access to the memory space of the
+	device.  The logic of controlling the device does not
+	necessarily have to be within the kernel, as the device does
+	not need to take advantage of any of other resources that the
+	kernel provides.  One such common class of devices that are
+	like this are for industrial I/O cards.
+	</para>
+	<para>
+	To address this situation, the userspace I/O system (UIO) was
+	designed.  For typical industrial I/O cards, only a very small
+	kernel module is needed. The main part of the driver will run in
+	user space. This simplifies development and reduces the risk of
+	serious bugs within a kernel module.
+	</para>
+</sect2>
+
+<sect2 id="thanks">
+<title>Acknowledgments</title>
+	<para>I'd like to thank Thomas Gleixner and Benedikt Spranger of
+	Linutronix, who have not only written most of the UIO code, but also
+	helped greatly writing this HOWTO by giving me all kinds of background
+	information.</para>
+</sect2>
+
+<sect2 id="feedback">
+<title>Feedback</title>
+	<para>Find something wrong with this document? (Or perhaps something
+	right?) I would love to hear from you. Please email me at
+	<email>hjk@linutronix.de</email>.</para>
+</sect2>
+</sect1>
+
+<sect1 id="about">
+<?dbhtml filename="about.html"?>
+<title>About UIO</title>
+
+<para>If you use UIO for your card's driver, here's what you get:</para>
+
+<itemizedlist>
+<listitem>
+	<para>only one small kernel module to write and maintain.</para>
+</listitem>
+<listitem>
+	<para>develop the main part of your driver in user space,
+	with all the tools and libraries you're used to.</para>
+</listitem>
+<listitem>
+	<para>bugs in your driver won't crash the kernel.</para>
+</listitem>
+<listitem>
+	<para>updates of your driver can take place without recompiling
+	the kernel.</para>
+</listitem>
+<listitem>
+	<para>if you need to keep some parts of your driver closed source,
+	you can do so without violating the GPL license on the kernel.</para>
+</listitem>
+</itemizedlist>
+
+<sect2 id="how_uio_works">
+<title>How UIO works</title>
+	<para>
+	Each UIO device is accessed through a device file and several
+	sysfs attribute files. The device file will be called
+	<filename>/dev/uio0</filename> for the first device, and
+	<filename>/dev/uio1</filename>, <filename>/dev/uio2</filename>
+	and so on for subsequent devices.
+	</para>
+
+	<para><filename>/dev/uioX</filename> is used to access the
+	address space of the card. Just use
+	<function>mmap()</function> to access registers or RAM
+	locations of your card.
+	</para>
+
+	<para>
+	Interrupts are handled by reading from
+	<filename>/dev/uioX</filename>. A blocking
+	<function>read()</function> from
+	<filename>/dev/uioX</filename> will return as soon as an
+	interrupt occurs. You can also use
+	<function>select()</function> on
+	<filename>/dev/uioX</filename> to wait for an interrupt. The
+	integer value read from <filename>/dev/uioX</filename>
+	represents the total interrupt count. You can use this number
+	to figure out if you missed some interrupts.
+	</para>
+
+	<para>
+	To handle interrupts properly, your custom kernel module can
+	provide its own interrupt handler. It will automatically be
+	called by the built-in handler.
+	</para>
+
+	<para>
+	For cards that don't generate interrupts but need to be
+	polled, there is the possibility to set up a timer that
+	triggers the interrupt handler at configurable time intervals.
+	See <filename>drivers/uio/uio_dummy.c</filename> for an
+	example of this technique.
+	</para>
+
+	<para>
+	Each driver provides attributes that are used to read or write
+	variables. These attributes are accessible through sysfs
+	files.  A custom kernel driver module can add its own
+	attributes to the device owned by the uio driver, but not added
+	to the UIO device itself at this time.  This might change in the
+	future if it would be found to be useful
+	</para>
+
+	<para>
+	The following standard attributes are provided by the UIO
+	framework:
+	</para>
+<itemizedlist>
+<listitem>
+	<para>
+	<filename>name</filename>: The name of your device. It is
+	recommended to use the name of your kernel module for this.
+	</para>
+</listitem>
+<listitem>
+	<para>
+	<filename>version</filename>: A version string defined by your
+	driver. This allows the user space part of your driver to deal
+	with different versions of the kernel module.
+	</para>
+</listitem>
+<listitem>
+	<para>
+	<filename>event</filename>: The total number of interrupts
+	handled by the driver since the last time the device node was
+	read.
+	</para>
+</listitem>
+</itemizedlist>
+<para>
+	These attributes appear under the
+	<filename>/sys/class/uio/uioX</filename> directory.  Please
+	note that this directory might be a symlink, and not a real
+	directory.  Any userspace code that accesses it must be able
+	to handle this.
+</para>
+<para>
+	Each UIO device can make one or more memory regions available for
+	memory mapping. This is necessary because some industrial I/O cards
+	require access to more than one PCI memory region in a driver.
+</para>
+<para>
+	Each mapping has its own directory in sysfs, the first mapping
+	appears as <filename>/sys/class/uio/uioX/maps/map0/</filename>.
+	Subsequent mappings create directories <filename>map1/</filename>,
+	<filename>map2/</filename>, and so on. These directories will only
+	appear if the size of the mapping is not 0.
+</para>
+<para>
+	Each <filename>mapX/</filename> directory contains two read-only files
+	that show start address and size of the memory:
+</para>
+<itemizedlist>
+<listitem>
+	<para>
+	<filename>addr</filename>: The address of memory that can be mapped.
+	</para>
+</listitem>
+<listitem>
+	<para>
+	<filename>size</filename>: The size, in bytes, of the memory
+	pointed to by addr.
+	</para>
+</listitem>
+</itemizedlist>
+
+<para>
+	From userspace, the different mappings are distinguished by adjusting
+	the <varname>offset</varname> parameter of the
+	<function>mmap()</function> call. To map the memory of mapping N, you
+	have to use N times the page size as your offset:
+</para>
+<programlisting format="linespecific">
+offset = N * getpagesize();
+</programlisting>
+
+</sect2>
+</sect1>
+
+<sect1 id="using-uio_dummy" xreflabel="Using uio_dummy">
+<?dbhtml filename="using-uio_dummy.html"?>
+<title>Using uio_dummy</title>
+	<para>
+	Well, there is no real use for uio_dummy. Its only purpose is
+	to test most parts of the UIO system (everything except
+	hardware interrupts), and to serve as an example for the
+	kernel module that you will have to write yourself.
+	</para>
+
+<sect2 id="what_uio_dummy_does">
+<title>What uio_dummy does</title>
+	<para>
+	The kernel module <filename>uio_dummy.ko</filename> creates a
+	device that uses a timer to generate periodic interrupts. The
+	interrupt handler does nothing but increment a counter. The
+	driver adds two custom attributes, <varname>count</varname>
+	and <varname>freq</varname>, that appear under
+	<filename>/sys/devices/platform/uio_dummy/</filename>.
+	</para>
+
+	<para>
+	The attribute <varname>count</varname> can be read and
+	written.  The associated file
+	<filename>/sys/devices/platform/uio_dummy/count</filename>
+	appears as a normal text file and contains the total number of
+	timer interrupts. If you look at it (e.g. using
+	<function>cat</function>), you'll notice it is slowly counting
+	up.
+	</para>
+
+	<para>
+	The attribute <varname>freq</varname> can be read and written.
+	The content of
+	<filename>/sys/devices/platform/uio_dummy/freq</filename>
+	represents the number of system timer ticks between two timer
+	interrupts. The default value of <varname>freq</varname> is
+	the value of the kernel variable <varname>HZ</varname>, which
+	gives you an interval of one second. Lower values will
+	increase the frequency. Try the following:
+	</para>
+<programlisting format="linespecific">
+cd /sys/devices/platform/uio_dummy/
+echo 100 > freq
+</programlisting>
+	<para>
+	Use <function>cat count</function> to see how the interrupt
+	frequency changes.
+	</para>
+</sect2>
+</sect1>
+
+<sect1 id="custom_kernel_module" xreflabel="Writing your own kernel module">
+<?dbhtml filename="custom_kernel_module.html"?>
+<title>Writing your own kernel module</title>
+	<para>
+	Please have a look at <filename>uio_dummy.c</filename> as an
+	example. The following paragraphs explain the different
+	sections of this file.
+	</para>
+
+<sect2 id="uio_info">
+<title>struct uio_info</title>
+	<para>
+	This structure tells the framework the details of your driver,
+	Some of the members are required, others are optional.
+	</para>
+
+<itemizedlist>
+<listitem>
+<varname>char *name</varname>: Required. The name of your driver as
+it will appear in sysfs. I recommend using the name of your module for this.
+</listitem>
+
+<listitem>
+<varname>char *version</varname>: Required. This string appears in
+<filename>/sys/class/uio/uioX/version</filename>.
+</listitem>
+
+<listitem>
+<varname>struct uio_mem mem[ MAX_UIO_MAPS ]</varname>: Required if you
+have memory that can be mapped with <function>mmap()</function>. For each
+mapping you need to fill one of the <varname>uio_mem</varname> structures.
+See the description below for details.
+</listitem>
+
+<listitem>
+<varname>long irq</varname>: Required. If your hardware generates an
+interrupt, it's your modules task to determine the irq number during
+initialization. If you don't have a hardware generated interrupt but
+want to trigger the interrupt handler in some other way, set
+<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>. The
+uio_dummy module does this as it triggers the event mechanism in a timer
+routine. If you had no interrupt at all, you could set
+<varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
+rarely makes sense.
+</listitem>
+
+<listitem>
+<varname>unsigned long irq_flags</varname>: Required if you've set
+<varname>irq</varname> to a hardware interrupt number. The flags given
+here will be used in the call to <function>request_irq()</function>.
+</listitem>
+
+<listitem>
+<varname>int (*mmap)(struct uio_info *info, struct vm_area_struct
+*vma)</varname>: Optional. If you need a special
+<function>mmap()</function> function, you can set it here. If this
+pointer is not NULL, your <function>mmap()</function> will be called
+instead of the built-in one.
+</listitem>
+
+<listitem>
+<varname>int (*open)(struct uio_info *info, struct inode *inode)
+</varname>: Optional. You might want to have your own
+<function>open()</function>, e.g. to enable interrupts only when your
+device is actually used.
+</listitem>
+
+<listitem>
+<varname>int (*release)(struct uio_info *info, struct inode *inode)
+</varname>: Optional. If you define your own
+<function>open()</function>, you will probably also want a custom
+<function>release()</function> function.
+</listitem>
+</itemizedlist>
+
+<para>
+Usually, your device will have one or more memory regions that can be mapped
+to user space. For each region, you have to set up a
+<varname>struct uio_mem</varname> in the <varname>mem[]</varname> array.
+Here's a description of the fields of <varname>struct uio_mem</varname>:
+</para>
+
+<itemizedlist>
+<listitem>
+<varname>int memtype</varname>: Required if the mapping is used. Set this to
+<varname>UIO_MEM_PHYS</varname> if you you have physical memory on your
+card to be mapped. Use <varname>UIO_MEM_LOGICAL</varname> for logical
+memory (e.g. allocated with <function>kmalloc()</function>). There's also
+<varname>UIO_MEM_VIRTUAL</varname> for virtual memory.
+</listitem>
+
+<listitem>
+<varname>unsigned long addr</varname>: Required if the mapping is used.
+Fill in the address of your memory block. This address is the one that
+appears in sysfs.
+</listitem>
+
+<listitem>
+<varname>unsigned long size</varname>: Fill in the size of the
+memory block that <varname>addr</varname> points to. If <varname>size</varname>
+is zero, the mapping is considered unused. Note that you
+<emphasis>must</emphasis> initialize <varname>size</varname> with zero for
+all unused mappings.
+</listitem>
+
+<listitem>
+<varname>void *internal_addr</varname>: If you have to access this memory
+region from within your kernel module, you will want to map it internally by
+using something like <function>ioremap_nocache()</function>. Addresses
+returned by this function can not be mapped to user space, so you must not
+store it in <varname>addr</varname>. Use <varname>internal_addr</varname>
+instead to remember such an address.
+</listitem>
+</itemizedlist>
+
+<para>
+Please do not touch the <varname>kobj</varname> element of
+<varname>struct uio_mem</varname>! It is used by the UIO framework
+to set up sysfs files for this mapping. Simply leave it alone.
+</para>
+</sect2>
+
+<sect2 id="adding_irq_handler">
+<title>Adding an interrupt handler</title>
+	<para>
+	What you need to do in your interrupt handler depends on your
+	hardware and on how you want to	handle it. You should try to
+	keep the amount of code in your kernel interrupt handler low.
+	If your hardware requires no action that you
+	<emphasis>have</emphasis> to perform after each interrupt,
+	then your handler can be empty.</para> <para>If, on the other
+	hand, your hardware <emphasis>needs</emphasis> some action to
+	be performed after each interrupt, then you
+	<emphasis>must</emphasis> do it in your kernel module. Note
+	that you cannot rely on the userspace part of your driver.Your
+	userspace program can terminate at any time, possibly leaving
+	your hardware in a state where proper interrupt handling is
+	still required.
+	</para>
+
+	<para>
+	There might also be applications where you want to read data
+	from your hardware at each interrupt and buffer it in a piece
+	of kernel memory you've allocated for that purpose.  With this
+	technique you could avoid loss of data if your userspace
+	program misses an interrupt.
+	</para>
+
+	<para>
+	A note on shared interrupts: Your driver should support
+	interrupt sharing whenever this is possible. It is possible if
+	and only if your driver can detect whether your hardware has
+	triggered the interrupt or not. This is usually done by looking
+	at an interrupt status register. If your driver sees that the
+	IRQ bit is actually set, it will perform its actions, and the
+	handler returns IRQ_HANDLED. If the driver detects that it was
+	not your hardware that caused the interrupt, it will do nothing
+	and return IRQ_NONE, allowing the kernel to call the next
+	possible interrupt handler.
+	</para>
+
+	<para>
+	If you decide not to support shared interrupts, your card
+	won't work in computers with no free interrupts. As this
+	frequently happens on the PC platform, you can save yourself a
+	lot of trouble by supporting interrupt sharing.
+	</para>
+</sect2>
+
+</sect1>
+
+<appendix id="app1">
+<title>Further information</title>
+<itemizedlist>
+	<listitem><para>
+		<ulink url="http://www.linutronix.de">
+		 Linutronix homepage.</ulink>
+		</para></listitem>
+	<listitem><para>...</para></listitem>
+</itemizedlist>
+</appendix>
+
+</article>
-- 
1.5.1.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 3/3] UIO: Hilscher CIF card driver
  2007-04-27 22:50   ` [PATCH 2/3] UIO: Documentation Greg Kroah-Hartman
@ 2007-04-27 22:50     ` Greg Kroah-Hartman
  2007-04-29 19:44       ` [PATCH 3/3] UIO: Hilscher CIF card driver (with patch) Hans-Jürgen Koch
  2007-05-01 23:42     ` [PATCH 2/3] UIO: Documentation Randy Dunlap
  1 sibling, 1 reply; 42+ messages in thread
From: Greg Kroah-Hartman @ 2007-04-27 22:50 UTC (permalink / raw)
  To: linux-kernel; +Cc: torvalds, Hans-Jürgen Koch, Greg Kroah-Hartman

From: Hans-Jürgen Koch <hjk@linutronix.de>

this is a patch that adds support for Hilscher CIF DeviceNet and
Profibus cards. I tested it on a Kontron CPX board, and Thomas reviewed
it.

You can find the user space part here:

http://www.osadl.org/projects/downloads/UIO/user/cif-0.1.0.tar.gz

Notes: cif_api.c is the main file you want to look at. It contains the
functions to open, close, mmap and so on. cif_dps.c adds functions
specific to Profibus cards, and cif_dn.c contains functions for
DeviceNet cards.  cif.c is a universal playground, it's just a small
test program.  The user space part of this UIO driver is still work in
progress, and not everything is tested yet. At the moment, the thread in
cif_api.c contains some code that artificially makes the card generate
interrupts, this was added for testing and will be removed later. But
the driver already contains all the functions needed for useful
operation, so it gives a good idea of how such a thing looks like.

For comparison, here's what you get from the manufacturer
(www.hilscher.com) when you ask for a Linux 2.6 driver:

http://www.tglx.de/private/hjk/cif-orig-2.6.tar.bz2

WARNING: Don't look at the code for too long, you might become sick :-)


Signed-off-by: Hans-Jürgen Koch <hjk@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/uio/Kconfig   |   13 ++++
 drivers/uio/Makefile  |    3 +-
 drivers/uio/uio_cif.c |  156 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 171 insertions(+), 1 deletions(-)
 create mode 100644 drivers/uio/uio_cif.c

diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 8fcef21..279f26c 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -11,4 +11,17 @@ config UIO
 
 	  If you don't know what to do here, say N.
 
+config UIO_CIF
+	tristate "generic Hilscher CIF Card driver"
+	depends on UIO && PCI
+	default n
+	help
+	  Driver for Hilscher CIF DeviceNet and Profibus cards.  This
+	  driver requires a userspace component that handles all of the
+	  heavy lifting and can be found at:
+	  	http://www.osadl.org/projects/downloads/UIO/user/cif-*
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called uio_cif.
+
 endmenu
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index 9b7c830..7fecfb4 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -1 +1,2 @@
-obj-$(CONFIG_UIO) += uio.o
+obj-$(CONFIG_UIO)	+= uio.o
+obj-$(CONFIG_UIO_CIF)	+= uio_cif.o
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
new file mode 100644
index 0000000..9ac625c
--- /dev/null
+++ b/drivers/uio/uio_cif.c
@@ -0,0 +1,156 @@
+/*
+ * UIO Hilscher CIF card driver
+ *
+ * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * Original code (C) 2005 Benedikt Spranger <b.spranger@linutronix.de>
+ *
+ * Licensed under GPL version 2 only.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/uio_driver.h>
+
+#include <asm/io.h>
+
+#ifndef PCI_DEVICE_ID_PLX_9030
+#define PCI_DEVICE_ID_PLX_9030	0x9030
+#endif
+
+#define PLX9030_INTCSR		0x4C
+#define INTSCR_INT1_ENABLE	0x01
+#define INTSCR_INT1_STATUS	0x04
+#define INT1_ENABLED_AND_ACTIVE	(INTSCR_INT1_ENABLE | INTSCR_INT1_STATUS)
+
+#define PCI_SUBVENDOR_ID_PEP	0x1518
+#define CIF_SUBDEVICE_PROFIBUS	0x430
+#define CIF_SUBDEVICE_DEVICENET	0x432
+
+
+static irqreturn_t hilscher_handler(int irq, struct uio_info *dev_info)
+{
+	void __iomem *plx_intscr = dev_info->mem[0].internal_addr
+					+ PLX9030_INTCSR;
+
+	if ((ioread8(plx_intscr) & INT1_ENABLED_AND_ACTIVE)
+	    != INT1_ENABLED_AND_ACTIVE)
+		return IRQ_NONE;
+
+	/* Disable interrupt */
+	iowrite8(ioread8(plx_intscr) & ~INTSCR_INT1_ENABLE, plx_intscr);
+	return IRQ_HANDLED;
+}
+
+static int __devinit hilscher_pci_probe(struct pci_dev *dev,
+					const struct pci_device_id *id)
+{
+	struct uio_info *info;
+
+	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	if (pci_enable_device(dev))
+		goto out_free;
+
+	if (pci_request_regions(dev, "hilscher"))
+		goto out_disable;
+
+	info->mem[0].addr = pci_resource_start(dev, 0);
+	if (!info->mem[0].addr)
+		goto out_release;
+	info->mem[0].internal_addr = ioremap_nocache(pci_resource_start(dev, 0),
+						     pci_resource_len(dev, 0));
+	if (!info->mem[0].internal_addr)
+		goto out_release;
+
+	info->mem[0].size = pci_resource_len(dev, 0);
+	info->mem[0].memtype = UIO_MEM_PHYS;
+	info->mem[1].addr = pci_resource_start(dev, 2);
+	info->mem[1].size = pci_resource_len(dev, 2);
+	info->mem[1].memtype = UIO_MEM_PHYS;
+	switch (id->subdevice) {
+		case CIF_SUBDEVICE_PROFIBUS:
+			info->name = "CIF_Profibus";
+			break;
+		case CIF_SUBDEVICE_DEVICENET:
+			info->name = "CIF_Devicenet";
+			break;
+		default:
+			info->name = "CIF_???";
+	}
+	info->version = "0.0.1";
+	info->irq = dev->irq;
+	info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
+	info->handler = hilscher_handler;
+
+	if (uio_register_device(&dev->dev, info))
+		goto out_unmap;
+
+	pci_set_drvdata(dev, info);
+
+	return 0;
+out_unmap:
+	iounmap(info->mem[0].internal_addr);
+out_release:
+	pci_release_regions(dev);
+out_disable:
+	pci_disable_device(dev);
+out_free:
+	kfree (info);
+	return -ENODEV;
+}
+
+static void hilscher_pci_remove(struct pci_dev *dev)
+{
+	struct uio_info *info = pci_get_drvdata(dev);
+
+	uio_unregister_device(info);
+	pci_release_regions(dev);
+	pci_disable_device(dev);
+	pci_set_drvdata(dev, NULL);
+	iounmap(info->mem[0].internal_addr);
+
+	kfree (info);
+}
+
+static struct pci_device_id hilscher_pci_ids[] = {
+	{
+		.vendor =	PCI_VENDOR_ID_PLX,
+		.device =	PCI_DEVICE_ID_PLX_9030,
+		.subvendor =	PCI_SUBVENDOR_ID_PEP,
+		.subdevice =	CIF_SUBDEVICE_PROFIBUS,
+	},
+	{
+		.vendor =	PCI_VENDOR_ID_PLX,
+		.device =	PCI_DEVICE_ID_PLX_9030,
+		.subvendor =	PCI_SUBVENDOR_ID_PEP,
+		.subdevice =	CIF_SUBDEVICE_DEVICENET,
+	},
+	{ 0, }
+};
+
+static struct pci_driver hilscher_pci_driver = {
+	.name = "hilscher",
+	.id_table = hilscher_pci_ids,
+	.probe = hilscher_pci_probe,
+	.remove = hilscher_pci_remove,
+};
+
+static int __init hilscher_init_module(void)
+{
+	return pci_register_driver(&hilscher_pci_driver);
+}
+
+static void __exit hilscher_exit_module(void)
+{
+	pci_unregister_driver(&hilscher_pci_driver);
+}
+
+module_init(hilscher_init_module);
+module_exit(hilscher_exit_module);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger");
-- 
1.5.1.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-27 22:49 [GIT PATCH] UIO patches for 2.6.21 Greg KH
  2007-04-27 22:50 ` [PATCH 1/3] UIO: Add the User IO core code Greg Kroah-Hartman
@ 2007-04-27 23:04 ` Andrew Morton
  2007-04-27 23:11   ` Greg KH
                     ` (2 more replies)
  2007-04-28 13:00 ` Matthieu CASTET
  2007-04-28 19:56 ` Bill Davidsen
  3 siblings, 3 replies; 42+ messages in thread
From: Andrew Morton @ 2007-04-27 23:04 UTC (permalink / raw)
  To: Greg KH
  Cc: Linus Torvalds, linux-kernel, tglx, Benedikt Spranger, Hans J. Koch

On Fri, 27 Apr 2007 15:49:57 -0700
Greg KH <gregkh@suse.de> wrote:

> Here are the updated UIO (Userspace I/O driver framework) patches for
> 2.6.21.

I'm a bit uncertain about the whole UIO idea, really.  I have this vague
feeling that we'd prefer to encourage people to move device drivers into
GPL'ed kernel rather than encouraging them to do closed-source userspace
implementations which will probably end up being slower, less reliable and
unavailable on various architectures, distros, etc.

But I don't think I have the capacity to actually think about this further
- just tossing it out there ;)

> They have been revamped from the last time you have seen them, and they
> include a real driver, the Hilscher CIF DeviceNet and Profibus card
> controller, which is being used in production systems with this driver
> framework right now.  The kernel driver they replaced was a total mess,
> with over 60+ ioctls to try to control the different aspects of the
> device.  See the last patch in this series for more details on this
> driver.
> 
> These patches include full documentation, are self-contained from the
> rest of the kernel, and have been in the -mm tree for the past few
> months with no complaints.
> 
> Please pull from:
> 	master.kernel.org:/pub/scm/linux/kernel/git/gregkh/uio-2.6.git/
> 
> Patches will be sent as a follow-on to this message to lkml for people
> to see.
> 
>  drivers/uio/uio_cif.c                 |  156 ++++++++

eh?  How come a particular device requires 156 lines of kernel code to
support a userspace driver?  Doesn't that kind of defeat the point?


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-27 23:04 ` [GIT PATCH] UIO patches for 2.6.21 Andrew Morton
@ 2007-04-27 23:11   ` Greg KH
  2007-04-28 11:38     ` Thomas Gleixner
  2007-04-27 23:26   ` Alan Cox
  2007-04-28  0:28   ` Hans-Jürgen Koch
  2 siblings, 1 reply; 42+ messages in thread
From: Greg KH @ 2007-04-27 23:11 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Linus Torvalds, linux-kernel, tglx, Benedikt Spranger, Hans J. Koch

On Fri, Apr 27, 2007 at 04:04:25PM -0700, Andrew Morton wrote:
> On Fri, 27 Apr 2007 15:49:57 -0700
> Greg KH <gregkh@suse.de> wrote:
> 
> > Here are the updated UIO (Userspace I/O driver framework) patches for
> > 2.6.21.
> 
> I'm a bit uncertain about the whole UIO idea, really.  I have this vague
> feeling that we'd prefer to encourage people to move device drivers into
> GPL'ed kernel rather than encouraging them to do closed-source userspace
> implementations which will probably end up being slower, less reliable and
> unavailable on various architectures, distros, etc.

It's not a closed vs. open issue, it just turns out that a lot of people
keep trying to write PCI drivers in userspace (how many different papers
were published on this topic alone in the past year...).  This framework
is to allow this to happen in a sane and correct way.

Lots of different types of odd devices do not fit into the "kernelspace
driver" framework very well for a variety of reasons:
	- zillions of different controls in the card
	- floating point is needed to compute the next step of an
	  operation in moving a physical object

With this framework, we provide a solid and simple way to provide for
these kinds of devices.  The Linutronix guys have had a lot of
experience in supporting this kind of hardware in the past and can
provide better examples if you need.

But yes, it does allow you to write a PCI driver in userspace, being
closed source, if you really want to.  But if you do that, then you get
_no_ advantages of being in the kernel (caching, common userspace
interface, resource management, etc.) and need to handle that all
yourself.  Heck, that's pretty much what X does today for lots of old
video cards :)

> > They have been revamped from the last time you have seen them, and they
> > include a real driver, the Hilscher CIF DeviceNet and Profibus card
> > controller, which is being used in production systems with this driver
> > framework right now.  The kernel driver they replaced was a total mess,
> > with over 60+ ioctls to try to control the different aspects of the
> > device.  See the last patch in this series for more details on this
> > driver.
> > 
> > These patches include full documentation, are self-contained from the
> > rest of the kernel, and have been in the -mm tree for the past few
> > months with no complaints.
> > 
> > Please pull from:
> > 	master.kernel.org:/pub/scm/linux/kernel/git/gregkh/uio-2.6.git/
> > 
> > Patches will be sent as a follow-on to this message to lkml for people
> > to see.
> > 
> >  drivers/uio/uio_cif.c                 |  156 ++++++++
> 
> eh?  How come a particular device requires 156 lines of kernel code to
> support a userspace driver?  Doesn't that kind of defeat the point?

No, you still need kernel code to handle the interrupt properly, we do
not want userspace to do this as it would slow the system down and do
all sorts of other bad things.  That's the main problem with all of
those other proposals that people have for trying to do this kind of
work in the past (can't share irqs, can't block on userspace in an
interrupt handler, etc.)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Flaws with "UIO: Add the User IO core code"
  2007-04-27 22:50 ` [PATCH 1/3] UIO: Add the User IO core code Greg Kroah-Hartman
  2007-04-27 22:50   ` [PATCH 2/3] UIO: Documentation Greg Kroah-Hartman
@ 2007-04-27 23:19   ` Alan Cox
  2007-04-28 11:39     ` Thomas Gleixner
  2007-04-28 18:52     ` Flaws with "UIO: Add the User IO core code" (with patch) Hans-Jürgen Koch
  1 sibling, 2 replies; 42+ messages in thread
From: Alan Cox @ 2007-04-27 23:19 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, torvalds, Thomas Gleixner, Benedikt Spranger,
	Greg Kroah-Hartman

> +static ssize_t uio_read(struct file *filep, char __user *buf,
> +			size_t count, loff_t *ppos)
> +{
> +	struct uio_listener *listener = filep->private_data;
> +	struct uio_device *idev = listener->dev;
> +	DECLARE_WAITQUEUE(wait, current);
> +	ssize_t retval;
> +	int event_count;
> +
> +	if (idev->info->irq == UIO_IRQ_NONE)
> +		return -EIO;
> +
> +	if (count != sizeof(int))
> +		return -EINVAL;

AFAIK we don't currently have any platform that runs binaries with
different sizes of "int" but this is a) an unsigned value anyway, and b)
should be a fixed type (eg u32)

Otherwise it looks ok at the momenmt, although there is a real nasty
waiting for anyone who tries to use it. At the point open is possible or
IRQs can be enabled you are safe in the core merged as idev->info is
always valid, but any driver module trying to go back via info->uio_dev
has a NULL pointer for an early IRQ or open event.

This means that the fasync support in the current code is basically
unusable until this is fixed

Alan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-27 23:04 ` [GIT PATCH] UIO patches for 2.6.21 Andrew Morton
  2007-04-27 23:11   ` Greg KH
@ 2007-04-27 23:26   ` Alan Cox
  2007-04-28  0:28   ` Hans-Jürgen Koch
  2 siblings, 0 replies; 42+ messages in thread
From: Alan Cox @ 2007-04-27 23:26 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Greg KH, Linus Torvalds, linux-kernel, tglx, Benedikt Spranger,
	Hans J. Koch

> I'm a bit uncertain about the whole UIO idea, really.  I have this vague
> feeling that we'd prefer to encourage people to move device drivers into
> GPL'ed kernel rather than encouraging them to do closed-source userspace
> implementations which will probably end up being slower, less reliable and
> unavailable on various architectures, distros, etc.

UIO is suprisingly close to chunks of the drm driver so the basic design
seems to have some sanity to it. 

Alan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-27 23:04 ` [GIT PATCH] UIO patches for 2.6.21 Andrew Morton
  2007-04-27 23:11   ` Greg KH
  2007-04-27 23:26   ` Alan Cox
@ 2007-04-28  0:28   ` Hans-Jürgen Koch
  2 siblings, 0 replies; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-04-28  0:28 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Greg KH, Linus Torvalds, linux-kernel, tglx, Benedikt Spranger

Am Samstag 28 April 2007 01:04 schrieb Andrew Morton:
> On Fri, 27 Apr 2007 15:49:57 -0700
>
> Greg KH <gregkh@suse.de> wrote:
> > Here are the updated UIO (Userspace I/O driver framework) patches for
> > 2.6.21.
>
> I'm a bit uncertain about the whole UIO idea, really.  I have this vague
> feeling that we'd prefer to encourage people to move device drivers into
> GPL'ed kernel rather than encouraging them to do closed-source userspace
> implementations which will probably end up being slower, less reliable and
> unavailable on various architectures, distros, etc.
>
> But I don't think I have the capacity to actually think about this further
> - just tossing it out there ;)

Thanks for tossing it out ;-) I understand your uncertainty and I share your
opinion about encouraging industry developers to GPL their drivers. It really
took me some time until I understood that sometimes there are _good_ reasons
for a closed driver. UIO is not intended for mass products like graphic cards.
We're talking about companies who developed special hardware for use in
special applications like machine control. They sometimes need to keep a 
part of their driver closed, at least for some time. Sometimes it's because
they want to protect themselves, sometimes because their customer demands it.
Usually, they know about the disadvantages you mentioned (if they're our
customers, be sure we tell them!).

Anyway, UIO is not just a system to allow closed drivers. There are enough
other reasons why these industry developers want userspace drivers. The most
important one is that they're usually no experienced kernel developers. They
can let somebody write the kernel part for them, and then write their driver
using the tools and libraries they know, with floating point and all that 
stuff. It's just convenient. If I had to write a driver for a fieldbus card
today, I'd use UIO. And I'd make it free software. UIO doesn't force anybody 
to close his drivers.

>
> > They have been revamped from the last time you have seen them, and they
> > include a real driver, the Hilscher CIF DeviceNet and Profibus card
> > controller, which is being used in production systems with this driver
> > framework right now.  The kernel driver they replaced was a total mess,
> > with over 60+ ioctls to try to control the different aspects of the
> > device.  See the last patch in this series for more details on this
> > driver.
> >
> > These patches include full documentation, are self-contained from the
> > rest of the kernel, and have been in the -mm tree for the past few
> > months with no complaints.
> >
> > Please pull from:
> > 	master.kernel.org:/pub/scm/linux/kernel/git/gregkh/uio-2.6.git/
> >
> > Patches will be sent as a follow-on to this message to lkml for people
> > to see.
> >
> >  drivers/uio/uio_cif.c                 |  156 ++++++++
>
> eh?  How come a particular device requires 156 lines of kernel code to
> support a userspace driver?  Doesn't that kind of defeat the point?

This is quite a large kernel module for an UIO device due to quite 
stupid hardware design. It needs two memory mappings, and the interrupt
handler is not the simplest thing possible. BTW, I don't think that
156 lines is so much. It allows to handle quite a complex PCI card. And
it's so simple that it can be even explained to industry programmers
who are no kernel gurus.

Thanks,
Hans


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-27 23:11   ` Greg KH
@ 2007-04-28 11:38     ` Thomas Gleixner
  0 siblings, 0 replies; 42+ messages in thread
From: Thomas Gleixner @ 2007-04-28 11:38 UTC (permalink / raw)
  To: Greg KH
  Cc: Andrew Morton, Linus Torvalds, linux-kernel, Benedikt Spranger,
	Hans J. Koch

On Fri, 2007-04-27 at 16:11 -0700, Greg KH wrote:
> > I'm a bit uncertain about the whole UIO idea, really.  I have this vague
> > feeling that we'd prefer to encourage people to move device drivers into
> > GPL'ed kernel rather than encouraging them to do closed-source userspace
> > implementations which will probably end up being slower, less reliable and
> > unavailable on various architectures, distros, etc.
> 
> It's not a closed vs. open issue, it just turns out that a lot of people
> keep trying to write PCI drivers in userspace (how many different papers
> were published on this topic alone in the past year...).  This framework
> is to allow this to happen in a sane and correct way.

Right, we don't need another dozen of attempts to get it wrong.

Interestingly enough some talks at ELC were using UIO already for
testing and prototyping and the feedback from these guys was positive on
the technical side and not at all focussed on the ability to do closed
source hackery.

> Lots of different types of odd devices do not fit into the "kernelspace
> driver" framework very well for a variety of reasons:
> 	- zillions of different controls in the card
> 	- floating point is needed to compute the next step of an
> 	  operation in moving a physical object

It's not necessarily slower. We were able to optimize an application by
using UIO and we got >20% performance gain, due to the fact that we can
operate on the device directly instead of copying data back and forth
between kernel and userspace for no good reason.

Removing the insane amount of 68 ioctls of the original in kernel
driver, which are just there to flip some bit in the chip registers is
definitely a win.

Having a sane user space driver instead of an eye-cancer causing kernel
driver and a user space library, which needs to hide the ioctl madness
away from the application programmer reduced the overall code size from

5264 lines of kernel code + 3275 lines of user space code

to 

 156 lines of kernel code + 2970 lines of user space code.

> With this framework, we provide a solid and simple way to provide for
> these kinds of devices.  The Linutronix guys have had a lot of
> experience in supporting this kind of hardware in the past and can
> provide better examples if you need.

UIO is not targeted on devices which are part of a kernel subsystem, it
is targeted for self contained special devices, which have currently
tons of out of tree drivers with an average quality of 0. Those devices
do not fit in the in kernel driver landscape at all and we really should
give those folks something sane to work from.

> But yes, it does allow you to write a PCI driver in userspace, being
> closed source, if you really want to.  But if you do that, then you get
> _no_ advantages of being in the kernel (caching, common userspace
> interface, resource management, etc.) and need to handle that all
> yourself.  Heck, that's pretty much what X does today for lots of old
> video cards :)

Right, you can do closed source drivers and I prefer when people use
this interface instead of fiddling with faked licenses and creating
legal bordercases. 

All drivers we did so far have LGPL user space counterparts and that's
the preferred way to go.

Also we have the user space driver support for USB already and I have
not seen negative impact from this one yet.

> > >  drivers/uio/uio_cif.c                 |  156 ++++++++
> > 
> > eh?  How come a particular device requires 156 lines of kernel code to
> > support a userspace driver?  Doesn't that kind of defeat the point?
> 
> No, you still need kernel code to handle the interrupt properly, we do
> not want userspace to do this as it would slow the system down and do
> all sorts of other bad things.  That's the main problem with all of
> those other proposals that people have for trying to do this kind of
> work in the past (can't share irqs, can't block on userspace in an
> interrupt handler, etc.)

Ack.

	tglx



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Flaws with "UIO: Add the User IO core code"
  2007-04-27 23:19   ` Flaws with "UIO: Add the User IO core code" Alan Cox
@ 2007-04-28 11:39     ` Thomas Gleixner
  2007-04-28 18:52     ` Flaws with "UIO: Add the User IO core code" (with patch) Hans-Jürgen Koch
  1 sibling, 0 replies; 42+ messages in thread
From: Thomas Gleixner @ 2007-04-28 11:39 UTC (permalink / raw)
  To: Alan Cox; +Cc: Greg Kroah-Hartman, linux-kernel, torvalds, Benedikt Spranger

On Sat, 2007-04-28 at 00:19 +0100, Alan Cox wrote:
> > +static ssize_t uio_read(struct file *filep, char __user *buf,
> > +			size_t count, loff_t *ppos)
> > +{
> > +	struct uio_listener *listener = filep->private_data;
> > +	struct uio_device *idev = listener->dev;
> > +	DECLARE_WAITQUEUE(wait, current);
> > +	ssize_t retval;
> > +	int event_count;
> > +
> > +	if (idev->info->irq == UIO_IRQ_NONE)
> > +		return -EIO;
> > +
> > +	if (count != sizeof(int))
> > +		return -EINVAL;
> 
> AFAIK we don't currently have any platform that runs binaries with
> different sizes of "int" but this is a) an unsigned value anyway, and b)
> should be a fixed type (eg u32)

Good point.

> Otherwise it looks ok at the momenmt, although there is a real nasty
> waiting for anyone who tries to use it. At the point open is possible or
> IRQs can be enabled you are safe in the core merged as idev->info is
> always valid, but any driver module trying to go back via info->uio_dev
> has a NULL pointer for an early IRQ or open event.
> 
> This means that the fasync support in the current code is basically
> unusable until this is fixed

We'll fix that ASAP.

	tglx



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-27 22:49 [GIT PATCH] UIO patches for 2.6.21 Greg KH
  2007-04-27 22:50 ` [PATCH 1/3] UIO: Add the User IO core code Greg Kroah-Hartman
  2007-04-27 23:04 ` [GIT PATCH] UIO patches for 2.6.21 Andrew Morton
@ 2007-04-28 13:00 ` Matthieu CASTET
  2007-04-28 13:49   ` Hans-Jürgen Koch
  2007-04-28 19:56 ` Bill Davidsen
  3 siblings, 1 reply; 42+ messages in thread
From: Matthieu CASTET @ 2007-04-28 13:00 UTC (permalink / raw)
  To: linux-kernel

Hi,

On Fri, 27 Apr 2007 15:49:57 -0700, Greg KH wrote:

> Here are the updated UIO (Userspace I/O driver framework) patches for
> 2.6.21.
> 

> 
>  Documentation/DocBook/kernel-api.tmpl |    4 +
>  Documentation/DocBook/uio-howto.tmpl  |  498 +++++++++++++++++++++++
>  drivers/Kconfig                       |    1 + drivers/Makefile        
>               |    1 + drivers/uio/Kconfig                   |   27 ++
>  drivers/uio/Makefile                  |    2 + drivers/uio/uio.c       
>               |  702 +++++++++++++++++++++++++++++++++
>  drivers/uio/uio_cif.c                 |  156 ++++++++
>  include/linux/uio_driver.h            |   91 +++++ 9 files changed,
>  1482 insertions(+), 0 deletions(-) create mode 100644
>  Documentation/DocBook/uio-howto.tmpl create mode 100644
>  drivers/uio/Kconfig create mode 100644 drivers/uio/Makefile create mode
>  100644 drivers/uio/uio.c
>  create mode 100644 drivers/uio/uio_cif.c create mode 100644
>  include/linux/uio_driver.h
> 
uio_dummy.c (that should be present according documentation) seems 
missing.

I find the doc not very clear for the devices where there is no 
interrupt : they speak of some kernel timer, but a userspace timer could 
be used (and even the userspace driver could be written without kernel 
support at all).

At the end of the doc there is something about IRQ_HANDLED vs IRQ_NONE.
Last time I check kernel irq code, in both case next irq handler are 
called. The only difference was that if all handler reply IRQ_NONE, the 
kernel gave an error about an unexpected interrupt.

Also why sysfs is used for describing the mapping instead of something 
like an ioctl ?
UIO could be useful in embedded system where sysfs is not always 
desirable.


Matthieu


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-28 13:00 ` Matthieu CASTET
@ 2007-04-28 13:49   ` Hans-Jürgen Koch
  0 siblings, 0 replies; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-04-28 13:49 UTC (permalink / raw)
  To: Matthieu CASTET; +Cc: linux-kernel

Am Samstag 28 April 2007 15:00 schrieb Matthieu CASTET:
>
> uio_dummy.c (that should be present according documentation) seems
> missing.

Well, uio_dummy was created during development to have something to
test with. It calls uio_event_notify() from a timer routine to 
simulate interrupts without having a real hardware device.

Besides that, uio_dummy has no real use. It might or might not be
useful to put it in mainline. IMHO, we should include it because
it shows ow UIO works and gives developers the possibility to test
at least parts of their userspace code without having the real hardware
(e.g. on their laptop).

>
> I find the doc not very clear for the devices where there is no
> interrupt : they speak of some kernel timer, but a userspace timer could
> be used (and even the userspace driver could be written without kernel
> support at all).

I'm afraid the doc too much emphasizes that timer. The reason was probably
that I worked with uio_dummy at the time I wrote the doc. Fact is that you
will rarely use a timer to generate interrupts. The only application I can
think of is something where you want to poll a device, say, every 10msec.
Then it might sometimes be the simplest solution to do it that way. But even
then there are probably userspace-only solutions most of the time.

But in general you're right, if a device doesn't generate hardware 
interrupts, you don't need UIO.

>
> At the end of the doc there is something about IRQ_HANDLED vs IRQ_NONE.
> Last time I check kernel irq code, in both case next irq handler are
> called. The only difference was that if all handler reply IRQ_NONE, the
> kernel gave an error about an unexpected interrupt.

It works like any other driver that handles interrupts. If you want to
support shared interrupts, your handler needs to be able to find out 
whether its device caused the interrupt or something else. You return
IRQ_HANDLED in the first case and IRQ_NONE in the second. If an interrupt
occurs and there's no driver that handles it, then the kernel has every
right to complain. Whoever enabled the interrupt must also be able to
handle it. That's one of the reasons why we need a kernel module to
handle interrupts, you can't do that from userspace.

>
> Also why sysfs is used for describing the mapping instead of something
> like an ioctl ?

Introducing new ioctls is ugly.

> UIO could be useful in embedded system where sysfs is not always
> desirable.

I see your point. But we need to make some information available for
userspace, in a standardized way. It was a design decision, and I still
find it quite good.

Thanks,
Hans
 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Flaws with "UIO: Add the User IO core code" (with patch)
  2007-04-27 23:19   ` Flaws with "UIO: Add the User IO core code" Alan Cox
  2007-04-28 11:39     ` Thomas Gleixner
@ 2007-04-28 18:52     ` Hans-Jürgen Koch
  2007-04-28 20:24       ` Alan Cox
  1 sibling, 1 reply; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-04-28 18:52 UTC (permalink / raw)
  To: Alan Cox
  Cc: Greg Kroah-Hartman, linux-kernel, torvalds, Thomas Gleixner,
	Benedikt Spranger

Am Samstag 28 April 2007 01:19 schrieb Alan Cox:
> > +static ssize_t uio_read(struct file *filep, char __user *buf,
> > +			size_t count, loff_t *ppos)
> > +{
> > +	struct uio_listener *listener = filep->private_data;
> > +	struct uio_device *idev = listener->dev;
> > +	DECLARE_WAITQUEUE(wait, current);
> > +	ssize_t retval;
> > +	int event_count;
> > +
> > +	if (idev->info->irq == UIO_IRQ_NONE)
> > +		return -EIO;
> > +
> > +	if (count != sizeof(int))
> > +		return -EINVAL;
> 
> AFAIK we don't currently have any platform that runs binaries with
> different sizes of "int" but this is a) an unsigned value anyway, and b)
> should be a fixed type (eg u32)

I reviewed the code once more and find it OK. There is only one legal
value for the parameter "count" of uio_read(), and that's sizeof(int).
The data that is actually read is the element "event" of struct uio_device,
which is of type atomic_t. The latter has the size of an int.

Unfortunately, the fact that the read count _must_ be sizeof(int) is not
mentioned in the documentation. I'll send a patch for that ASAP.

> 
> Otherwise it looks ok at the momenmt, although there is a real nasty
> waiting for anyone who tries to use it. At the point open is possible or
> IRQs can be enabled you are safe in the core merged as idev->info is
> always valid, but any driver module trying to go back via info->uio_dev
> has a NULL pointer for an early IRQ or open event.

This patch should fix it:


Index: linux-2.6.22-rc/drivers/uio/uio.c
===================================================================
--- linux-2.6.22-rc.orig/drivers/uio/uio.c	2007-04-28 20:01:02.000000000 +0200
+++ linux-2.6.22-rc/drivers/uio/uio.c	2007-04-28 20:15:00.000000000 +0200
@@ -633,6 +633,8 @@
 	if (ret)
 		goto err_uio_dev_add_attributes;
 
+	info->uio_dev = idev;
+
 	if (idev->info->irq >= 0) {
 		ret = request_irq(idev->info->irq, uio_interrupt,
 				  idev->info->irq_flags, idev->info->name, idev);
@@ -640,7 +642,6 @@
 			goto err_request_irq;
 	}
 
-	info->uio_dev = idev;
 	return 0;
 
 err_request_irq:


Thanks for your review,
Hans


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-27 22:49 [GIT PATCH] UIO patches for 2.6.21 Greg KH
                   ` (2 preceding siblings ...)
  2007-04-28 13:00 ` Matthieu CASTET
@ 2007-04-28 19:56 ` Bill Davidsen
  2007-04-28 20:02   ` Thomas Gleixner
  2007-04-28 20:03   ` Hans-Jürgen Koch
  3 siblings, 2 replies; 42+ messages in thread
From: Bill Davidsen @ 2007-04-28 19:56 UTC (permalink / raw)
  To: Greg KH
  Cc: Linus Torvalds, Andrew Morton, linux-kernel, tglx,
	Benedikt Spranger, Hans J. Koch

Greg KH wrote:
> Here are the updated UIO (Userspace I/O driver framework) patches for
> 2.6.21.
> 
> They have been revamped from the last time you have seen them, and they
> include a real driver, the Hilscher CIF DeviceNet and Profibus card
> controller, which is being used in production systems with this driver
> framework right now.  The kernel driver they replaced was a total mess,
> with over 60+ ioctls to try to control the different aspects of the
> device.  See the last patch in this series for more details on this
> driver.
> 
I have a political question, if I have a user space driver, is my kernel 
tainted or not? Does this open another multi-month flame war around GPL, 
BSD, NDA, source available but not GPL, and all the other things we 
talked to death about inserting non-GPL modules?

-- 
Bill Davidsen <davidsen@tmr.com>
   "We have more to fear from the bungling of the incompetent than from
the machinations of the wicked."  - from Slashdot

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-28 19:56 ` Bill Davidsen
@ 2007-04-28 20:02   ` Thomas Gleixner
  2007-04-28 20:03   ` Hans-Jürgen Koch
  1 sibling, 0 replies; 42+ messages in thread
From: Thomas Gleixner @ 2007-04-28 20:02 UTC (permalink / raw)
  To: Bill Davidsen
  Cc: Greg KH, Linus Torvalds, Andrew Morton, linux-kernel,
	Benedikt Spranger, Hans J. Koch

On Sat, 2007-04-28 at 15:56 -0400, Bill Davidsen wrote:
> Greg KH wrote:
> > Here are the updated UIO (Userspace I/O driver framework) patches for
> > 2.6.21.
> > 
> > They have been revamped from the last time you have seen them, and they
> > include a real driver, the Hilscher CIF DeviceNet and Profibus card
> > controller, which is being used in production systems with this driver
> > framework right now.  The kernel driver they replaced was a total mess,
> > with over 60+ ioctls to try to control the different aspects of the
> > device.  See the last patch in this series for more details on this
> > driver.
> > 
> I have a political question, if I have a user space driver, is my kernel 
> tainted or not? Does this open another multi-month flame war around GPL, 
> BSD, NDA, source available but not GPL, and all the other things we 
> talked to death about inserting non-GPL modules?

The kernel driver has to be GPL, the user space part can be as any user
space code closed source. Of course we recommend to make it open as
those user space drivers which we did so far are all licensed under
LPGL.

There is nothing to flame, the user space boundary is entirely clear.

	tglx



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-28 19:56 ` Bill Davidsen
  2007-04-28 20:02   ` Thomas Gleixner
@ 2007-04-28 20:03   ` Hans-Jürgen Koch
  2007-04-28 20:15     ` Alan Cox
  1 sibling, 1 reply; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-04-28 20:03 UTC (permalink / raw)
  To: Bill Davidsen
  Cc: Greg KH, Linus Torvalds, Andrew Morton, linux-kernel, tglx,
	Benedikt Spranger

Am Samstag 28 April 2007 21:56 schrieb Bill Davidsen:
> Greg KH wrote:
> > Here are the updated UIO (Userspace I/O driver framework) patches for
> > 2.6.21.
> > 
> > They have been revamped from the last time you have seen them, and they
> > include a real driver, the Hilscher CIF DeviceNet and Profibus card
> > controller, which is being used in production systems with this driver
> > framework right now.  The kernel driver they replaced was a total mess,
> > with over 60+ ioctls to try to control the different aspects of the
> > device.  See the last patch in this series for more details on this
> > driver.
> > 
> I have a political question, if I have a user space driver, is my kernel 
> tainted or not? 

Surely not. By using the kernel's userspace interface, you create no
"derived work" of the kernel. See COPYING in the root directory of the 
kernel sources for details.

> Does this open another multi-month flame war around GPL,  
> BSD, NDA, source available but not GPL, and all the other things we 
> talked to death about inserting non-GPL modules?

Hopefully not. BTW, all existing UIO userspace drivers I know about 
are GPL or LGPL.

Hans


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-28 20:03   ` Hans-Jürgen Koch
@ 2007-04-28 20:15     ` Alan Cox
  2007-04-28 20:31       ` Thomas Gleixner
  0 siblings, 1 reply; 42+ messages in thread
From: Alan Cox @ 2007-04-28 20:15 UTC (permalink / raw)
  To: Hans-Jürgen Koch
  Cc: Bill Davidsen, Greg KH, Linus Torvalds, Andrew Morton,
	linux-kernel, tglx, Benedikt Spranger

> > I have a political question, if I have a user space driver, is my kernel 
> > tainted or not? 
> 
> Surely not. By using the kernel's userspace interface, you create no
> "derived work" of the kernel. See COPYING in the root directory of the 
> kernel sources for details.

That only covers normal system calls - but I don't think thats what is
relevant, taints are for debug assistance not politics.

I think we should have a taint flag for UIO type drivers. Not for any
licensing or political reason but for the simple fact it means that there
may be other complexities to debugging - and not the same one as a binary
module. Probably we want the same marker for mmap /dev/mem too.

Alan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Flaws with "UIO: Add the User IO core code" (with patch)
  2007-04-28 18:52     ` Flaws with "UIO: Add the User IO core code" (with patch) Hans-Jürgen Koch
@ 2007-04-28 20:24       ` Alan Cox
  2007-04-28 20:38         ` Thomas Gleixner
  2007-04-28 21:03         ` Hans-Jürgen Koch
  0 siblings, 2 replies; 42+ messages in thread
From: Alan Cox @ 2007-04-28 20:24 UTC (permalink / raw)
  To: Hans-Jürgen Koch
  Cc: Greg Kroah-Hartman, linux-kernel, torvalds, Thomas Gleixner,
	Benedikt Spranger

> > AFAIK we don't currently have any platform that runs binaries with
> > different sizes of "int" but this is a) an unsigned value anyway, and b)
> > should be a fixed type (eg u32)
> 
> I reviewed the code once more and find it OK. There is only one legal
> value for the parameter "count" of uio_read(), and that's sizeof(int).

If you are a box with multiple supported binary types how big is an
"int". We use explicit sizes to ensure that uio_read() will work when/if
we get platforms which support binaries with differing ideas of the size
of "int". Thus it should use s32 or s64 or similar.

> The data that is actually read is the element "event" of struct uio_device,
> which is of type atomic_t. The latter has the size of an int.

The latter is the size of a kernel "int".

Other patch looks fine.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-28 20:15     ` Alan Cox
@ 2007-04-28 20:31       ` Thomas Gleixner
  2007-04-29  1:23         ` Greg KH
  0 siblings, 1 reply; 42+ messages in thread
From: Thomas Gleixner @ 2007-04-28 20:31 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans-Jürgen Koch, Bill Davidsen, Greg KH, Linus Torvalds,
	Andrew Morton, linux-kernel, Benedikt Spranger

On Sat, 2007-04-28 at 21:15 +0100, Alan Cox wrote:
> > > I have a political question, if I have a user space driver, is my kernel 
> > > tainted or not? 
> > 
> > Surely not. By using the kernel's userspace interface, you create no
> > "derived work" of the kernel. See COPYING in the root directory of the 
> > kernel sources for details.
> 
> That only covers normal system calls - but I don't think thats what is
> relevant, taints are for debug assistance not politics.
> 
> I think we should have a taint flag for UIO type drivers. Not for any
> licensing or political reason but for the simple fact it means that there
> may be other complexities to debugging - and not the same one as a binary
> module. Probably we want the same marker for mmap /dev/mem too.

I agree, if we make it entirely clear that the flag is nonpolitical. 

	tglx



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Flaws with "UIO: Add the User IO core code" (with patch)
  2007-04-28 20:24       ` Alan Cox
@ 2007-04-28 20:38         ` Thomas Gleixner
  2007-04-28 21:03         ` Hans-Jürgen Koch
  1 sibling, 0 replies; 42+ messages in thread
From: Thomas Gleixner @ 2007-04-28 20:38 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans-Jürgen Koch, Greg Kroah-Hartman, linux-kernel,
	torvalds, Benedikt Spranger

On Sat, 2007-04-28 at 21:24 +0100, Alan Cox wrote:
> > > AFAIK we don't currently have any platform that runs binaries with
> > > different sizes of "int" but this is a) an unsigned value anyway, and b)
> > > should be a fixed type (eg u32)
> > 
> > I reviewed the code once more and find it OK. There is only one legal
> > value for the parameter "count" of uio_read(), and that's sizeof(int).
> 
> If you are a box with multiple supported binary types how big is an
> "int". We use explicit sizes to ensure that uio_read() will work when/if
> we get platforms which support binaries with differing ideas of the size
> of "int". Thus it should use s32 or s64 or similar.

Well, it is kind of academic, as probably half of the user space
interfaces will explode, but in theory you are right.

Hans, let's change it to u32 to get this out of the way.

	tglx



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Flaws with "UIO: Add the User IO core code" (with patch)
  2007-04-28 20:24       ` Alan Cox
  2007-04-28 20:38         ` Thomas Gleixner
@ 2007-04-28 21:03         ` Hans-Jürgen Koch
  2007-04-28 21:08           ` Thomas Gleixner
  1 sibling, 1 reply; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-04-28 21:03 UTC (permalink / raw)
  To: Alan Cox
  Cc: Greg Kroah-Hartman, linux-kernel, torvalds, Thomas Gleixner,
	Benedikt Spranger

Am Samstag 28 April 2007 22:24 schrieb Alan Cox:
> > > AFAIK we don't currently have any platform that runs binaries with
> > > different sizes of "int" but this is a) an unsigned value anyway, and b)
> > > should be a fixed type (eg u32)
> > 
> > I reviewed the code once more and find it OK. There is only one legal
> > value for the parameter "count" of uio_read(), and that's sizeof(int).
> 
> If you are a box with multiple supported binary types how big is an
> "int". We use explicit sizes to ensure that uio_read() will work when/if
> we get platforms which support binaries with differing ideas of the size
> of "int". Thus it should use s32 or s64 or similar.

Here's a fix to that effect:

Index: linux-2.6.22-rc/drivers/uio/uio.c
===================================================================
--- linux-2.6.22-rc.orig/drivers/uio/uio.c	2007-04-28 22:46:34.000000000 +0200
+++ linux-2.6.22-rc/drivers/uio/uio.c	2007-04-28 22:59:40.000000000 +0200
@@ -264,7 +264,7 @@
 
 struct uio_listener {
 	struct uio_device *dev;
-	int event_count;
+	s32 event_count;
 };
 
 static int uio_open(struct inode *inode, struct file *filep)
@@ -345,12 +345,12 @@
 	struct uio_device *idev = listener->dev;
 	DECLARE_WAITQUEUE(wait, current);
 	ssize_t retval;
-	int event_count;
+	s32 event_count;
 
 	if (idev->info->irq == UIO_IRQ_NONE)
 		return -EIO;
 
-	if (count != sizeof(int))
+	if (count != sizeof(s32))
 		return -EINVAL;
 
 	add_wait_queue(&idev->wait, &wait);


Thanks,
Hans

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Flaws with "UIO: Add the User IO core code" (with patch)
  2007-04-28 21:03         ` Hans-Jürgen Koch
@ 2007-04-28 21:08           ` Thomas Gleixner
  2007-04-28 21:14             ` Flaws with "UIO: Add the User IO core code" Hans-Jürgen Koch
  0 siblings, 1 reply; 42+ messages in thread
From: Thomas Gleixner @ 2007-04-28 21:08 UTC (permalink / raw)
  To: Hans-Jürgen Koch
  Cc: Alan Cox, Greg Kroah-Hartman, linux-kernel, torvalds, Benedikt Spranger

On Sat, 2007-04-28 at 23:03 +0200, Hans-Jürgen Koch wrote:
> Am Samstag 28 April 2007 22:24 schrieb Alan Cox:
> > > > AFAIK we don't currently have any platform that runs binaries with
> > > > different sizes of "int" but this is a) an unsigned value anyway, and b)
> > > > should be a fixed type (eg u32)
> > > 
> > > I reviewed the code once more and find it OK. There is only one legal
> > > value for the parameter "count" of uio_read(), and that's sizeof(int).
> > 
> > If you are a box with multiple supported binary types how big is an
> > "int". We use explicit sizes to ensure that uio_read() will work when/if
> > we get platforms which support binaries with differing ideas of the size
> > of "int". Thus it should use s32 or s64 or similar.
> 
> Here's a fix to that effect:

Can you please add a matching paragraph to the documentation ?

	tglx



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Flaws with "UIO: Add the User IO core code"
  2007-04-28 21:08           ` Thomas Gleixner
@ 2007-04-28 21:14             ` Hans-Jürgen Koch
  2007-04-29 22:18               ` Flaws with "UIO: Add the User IO core code" (with patch) Hans-Jürgen Koch
  0 siblings, 1 reply; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-04-28 21:14 UTC (permalink / raw)
  To: tglx
  Cc: Alan Cox, Greg Kroah-Hartman, linux-kernel, torvalds, Benedikt Spranger

Am Samstag 28 April 2007 23:08 schrieb Thomas Gleixner:
> On Sat, 2007-04-28 at 23:03 +0200, Hans-Jürgen Koch wrote:
> > Am Samstag 28 April 2007 22:24 schrieb Alan Cox:
> > > > > AFAIK we don't currently have any platform that runs binaries with
> > > > > different sizes of "int" but this is a) an unsigned value anyway, and b)
> > > > > should be a fixed type (eg u32)
> > > > 
> > > > I reviewed the code once more and find it OK. There is only one legal
> > > > value for the parameter "count" of uio_read(), and that's sizeof(int).
> > > 
> > > If you are a box with multiple supported binary types how big is an
> > > "int". We use explicit sizes to ensure that uio_read() will work when/if
> > > we get platforms which support binaries with differing ideas of the size
> > > of "int". Thus it should use s32 or s64 or similar.
> > 
> > Here's a fix to that effect:
> 
> Can you please add a matching paragraph to the documentation ?
> 

Yes, I'll add a "How to write userspace code" section tomorrow. I'll send a 
patch as soon as it's ready.

Hans
 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-28 20:31       ` Thomas Gleixner
@ 2007-04-29  1:23         ` Greg KH
  2007-04-29  8:30           ` Thomas Gleixner
  0 siblings, 1 reply; 42+ messages in thread
From: Greg KH @ 2007-04-29  1:23 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Alan Cox, Hans-J?rgen Koch, Bill Davidsen, Linus Torvalds,
	Andrew Morton, linux-kernel, Benedikt Spranger

On Sat, Apr 28, 2007 at 10:31:37PM +0200, Thomas Gleixner wrote:
> On Sat, 2007-04-28 at 21:15 +0100, Alan Cox wrote:
> > > > I have a political question, if I have a user space driver, is my kernel 
> > > > tainted or not? 
> > > 
> > > Surely not. By using the kernel's userspace interface, you create no
> > > "derived work" of the kernel. See COPYING in the root directory of the 
> > > kernel sources for details.
> > 
> > That only covers normal system calls - but I don't think thats what is
> > relevant, taints are for debug assistance not politics.
> > 
> > I think we should have a taint flag for UIO type drivers. Not for any
> > licensing or political reason but for the simple fact it means that there
> > may be other complexities to debugging - and not the same one as a binary
> > module. Probably we want the same marker for mmap /dev/mem too.
> 
> I agree, if we make it entirely clear that the flag is nonpolitical. 

Hm, I don't know, what makes this different from the fact that we can
mmap PCI device space today through the proc and sysfs entries?  That's
how X gets direct access to the hardware for a number of different
cards, and that's pretty much the same thing as the UIO interface is
doing.

Unless you think we should also use the same "taint" flag on those
accesses too, and if so, I have no objection.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-29  1:23         ` Greg KH
@ 2007-04-29  8:30           ` Thomas Gleixner
  2007-04-29 12:09             ` Jan Engelhardt
  2007-05-07 20:02             ` Pavel Machek
  0 siblings, 2 replies; 42+ messages in thread
From: Thomas Gleixner @ 2007-04-29  8:30 UTC (permalink / raw)
  To: Greg KH
  Cc: Alan Cox, Hans-J?rgen Koch, Bill Davidsen, Linus Torvalds,
	Andrew Morton, linux-kernel, Benedikt Spranger

On Sat, 2007-04-28 at 18:23 -0700, Greg KH wrote:
> On Sat, Apr 28, 2007 at 10:31:37PM +0200, Thomas Gleixner wrote:
> > On Sat, 2007-04-28 at 21:15 +0100, Alan Cox wrote:
> > > > > I have a political question, if I have a user space driver, is my kernel 
> > > > > tainted or not? 
> > > > 
> > > > Surely not. By using the kernel's userspace interface, you create no
> > > > "derived work" of the kernel. See COPYING in the root directory of the 
> > > > kernel sources for details.
> > > 
> > > That only covers normal system calls - but I don't think thats what is
> > > relevant, taints are for debug assistance not politics.
> > > 
> > > I think we should have a taint flag for UIO type drivers. Not for any
> > > licensing or political reason but for the simple fact it means that there
> > > may be other complexities to debugging - and not the same one as a binary
> > > module. Probably we want the same marker for mmap /dev/mem too.
> > 
> > I agree, if we make it entirely clear that the flag is nonpolitical. 
> 
> Hm, I don't know, what makes this different from the fact that we can
> mmap PCI device space today through the proc and sysfs entries?  That's
> how X gets direct access to the hardware for a number of different
> cards, and that's pretty much the same thing as the UIO interface is
> doing.
> 
> Unless you think we should also use the same "taint" flag on those
> accesses too, and if so, I have no objection.

Right, this is just a hint, that something in user space is accessing
the hardware directly. Not a too bad idea, but pretty much useless when
we add X to the picture as it will be set always :)

	tglx



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-29  8:30           ` Thomas Gleixner
@ 2007-04-29 12:09             ` Jan Engelhardt
  2007-04-29 16:27               ` Alan Cox
  2007-05-07 20:02             ` Pavel Machek
  1 sibling, 1 reply; 42+ messages in thread
From: Jan Engelhardt @ 2007-04-29 12:09 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Greg KH, Alan Cox, Hans-J?rgen Koch, Bill Davidsen,
	Linus Torvalds, Andrew Morton, linux-kernel, Benedikt Spranger


On Apr 29 2007 10:30, Thomas Gleixner wrote:
>> 
>> Unless you think we should also use the same "taint" flag on those
>> accesses too, and if so, I have no objection.
>
>Right, this is just a hint, that something in user space is accessing
>the hardware directly. Not a too bad idea, but pretty much useless when
>we add X to the picture as it will be set always :)

Index: linux-2.6.21-mm_20040728/drivers/char/mem.c
===================================================================
--- linux-2.6.21-mm_20040728.orig/drivers/char/mem.c
+++ linux-2.6.21-mm_20040728/drivers/char/mem.c
@@ -274,6 +274,9 @@ static int mmap_mem(struct file * file, 
 	if (!private_mapping_ok(vma))
 		return -ENOSYS;
 
+	if (strcmp(current->comm, "Xorg") != 0)
+		tainted |= TAINT_USER;
+
 	vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
 						 size,
 						 vma->vm_page_prot);
#<EOF>


Jan
-- 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-29 12:09             ` Jan Engelhardt
@ 2007-04-29 16:27               ` Alan Cox
  0 siblings, 0 replies; 42+ messages in thread
From: Alan Cox @ 2007-04-29 16:27 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: Thomas Gleixner, Greg KH, Hans-J?rgen Koch, Bill Davidsen,
	Linus Torvalds, Andrew Morton, linux-kernel, Benedikt Spranger

> >Right, this is just a hint, that something in user space is accessing
> >the hardware directly. Not a too bad idea, but pretty much useless when
> >we add X to the picture as it will be set always :)
> 
> Index: linux-2.6.21-mm_20040728/drivers/char/mem.c
> ===================================================================
> --- linux-2.6.21-mm_20040728.orig/drivers/char/mem.c
> +++ linux-2.6.21-mm_20040728/drivers/char/mem.c
> @@ -274,6 +274,9 @@ static int mmap_mem(struct file * file, 
>  	if (!private_mapping_ok(vma))
>  		return -ENOSYS;
>  
> +	if (strcmp(current->comm, "Xorg") != 0)
> +		tainted |= TAINT_USER;
> +

The X server has many names.  Xorg isn't the name of the server here for
example (its "X"). 

Alan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 3/3] UIO: Hilscher CIF card driver (with patch)
  2007-04-27 22:50     ` [PATCH 3/3] UIO: Hilscher CIF card driver Greg Kroah-Hartman
@ 2007-04-29 19:44       ` Hans-Jürgen Koch
  0 siblings, 0 replies; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-04-29 19:44 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, torvalds

Am Samstag 28 April 2007 00:50 schrieb Greg Kroah-Hartman:

> +static int __devinit hilscher_pci_probe(struct pci_dev *dev,
> +					const struct pci_device_id *id)
> +{
> +	struct uio_info *info;
> +
> +	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
> +	if (!info)
> +		return -ENOMEM;
> +
> +	if (pci_enable_device(dev))
> +		goto out_free;
> +
> +	if (pci_request_regions(dev, "hilscher"))
> +		goto out_disable;
> +
> +	info->mem[0].addr = pci_resource_start(dev, 0);
> +	if (!info->mem[0].addr)
> +		goto out_release;
> +	info->mem[0].internal_addr = ioremap_nocache(pci_resource_start(dev, 0),
> +						     pci_resource_len(dev, 0));
> +	if (!info->mem[0].internal_addr)
> +		goto out_release;

Alan Cox pointed out (offlist) that ioremap_nocache() is unneccessary here.
This patch replaces it with ioremap():

Thanks, Alan!

hjk

Index: linux-2.6.22-rc/drivers/uio/uio_cif.c
===================================================================
--- linux-2.6.22-rc.orig/drivers/uio/uio_cif.c	2007-04-29 21:34:45.000000000 +0200
+++ linux-2.6.22-rc/drivers/uio/uio_cif.c	2007-04-29 21:36:31.000000000 +0200
@@ -64,9 +64,8 @@
 	info->mem[0].addr = pci_resource_start(dev, 0);
 	if (!info->mem[0].addr)
 		goto out_release;
-	info->mem[0].internal_addr = ioremap_nocache(
-						pci_resource_start(dev, 0),
-						pci_resource_len(dev, 0) );
+	info->mem[0].internal_addr = ioremap(pci_resource_start(dev, 0),
+					     pci_resource_len(dev, 0) );
 	if (!info->mem[0].internal_addr)
 		goto out_release;
 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Flaws with "UIO: Add the User IO core code" (with patch)
  2007-04-28 21:14             ` Flaws with "UIO: Add the User IO core code" Hans-Jürgen Koch
@ 2007-04-29 22:18               ` Hans-Jürgen Koch
  0 siblings, 0 replies; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-04-29 22:18 UTC (permalink / raw)
  To: tglx
  Cc: Alan Cox, Greg Kroah-Hartman, linux-kernel, torvalds, Benedikt Spranger

Am Samstag 28 April 2007 23:14 schrieb Hans-Jürgen Koch:
> Am Samstag 28 April 2007 23:08 schrieb Thomas Gleixner:
> > On Sat, 2007-04-28 at 23:03 +0200, Hans-Jürgen Koch wrote:
> > > Am Samstag 28 April 2007 22:24 schrieb Alan Cox:
> > > > > > AFAIK we don't currently have any platform that runs binaries with
> > > > > > different sizes of "int" but this is a) an unsigned value anyway, and b)
> > > > > > should be a fixed type (eg u32)
> > > > > 
> > > > > I reviewed the code once more and find it OK. There is only one legal
> > > > > value for the parameter "count" of uio_read(), and that's sizeof(int).
> > > > 
> > > > If you are a box with multiple supported binary types how big is an
> > > > "int". We use explicit sizes to ensure that uio_read() will work when/if
> > > > we get platforms which support binaries with differing ideas of the size
> > > > of "int". Thus it should use s32 or s64 or similar.
> > > 
> > > Here's a fix to that effect:
> > 
> > Can you please add a matching paragraph to the documentation ?
> > 
> 
> Yes, I'll add a "How to write userspace code" section tomorrow. I'll send a 
> patch as soon as it's ready.
> 
> Hans
>  

Here's the promised update for the documentation:

Hans


Index: linux-2.6.22-rc/Documentation/DocBook/uio-howto.tmpl
===================================================================
--- linux-2.6.22-rc.orig/Documentation/DocBook/uio-howto.tmpl	2007-04-29 22:17:45.000000000 +0200
+++ linux-2.6.22-rc/Documentation/DocBook/uio-howto.tmpl	2007-04-30 00:15:38.000000000 +0200
@@ -30,6 +30,12 @@
 
 <revhistory>
 	<revision>
+	<revnumber>0.3</revnumber>
+	<date>2007-04-29</date>
+	<authorinitials>hjk</authorinitials>
+	<revremark>Added section about userspace drivers.</revremark>
+	</revision>
+	<revision>
 	<revnumber>0.2</revnumber>
 	<date>2007-02-13</date>
 	<authorinitials>hjk</authorinitials>
@@ -484,14 +490,121 @@
 
 </sect1>
 
+<sect1 id="userspace_driver" xreflabel="Writing a driver in user space">
+<?dbhtml filename="userspace_driver.html"?>
+<title>Writing a driver in userspace</title>
+	<para>
+	Once you have a working kernel module for your hardware, you can
+	write the userspace part of your driver. You don't need any special
+	libraries, your driver can be written in any reasonable language,
+	you can use floating point numbers and so on. In short, you can
+	use all the tools and libraries you'd normally use for writing a
+	userspace application.
+	</para>
+
+<sect2 id="getting_uio_information">
+<title>Getting information about your UIO device</title>
+	<para>
+	Information about all UIO devices is available in sysfs. The
+	first thing you should do in your driver is check
+	<varname>name</varname> and <varname>version</varname> to
+	make sure your talking to the right device and that its kernel
+	driver has the version you expect.
+	</para>
+	<para>
+	You should also make sure that the memory mapping you need
+	exists and has the size you expect.
+	</para>
+	<para>
+	There is a tool called <varname>lsuio</varname> that lists
+	UIO devices and their attributes. It is available here:
+	</para>
+	<para>
+	<ulink url="http://www.osadl.org/projects/downloads/UIO/user/">
+		http://www.osadl.org/projects/downloads/UIO/user/</ulink>
+	</para>
+	<para>
+	With <varname>lsuio</varname> you can quickly check if your
+	kernel module is loaded and which attributes it exports.
+	Have a look at the manpage for details.
+	</para>
+	<para>
+	The source code of <varname>lsuio</varname> can serve as an
+	example for getting information about an UIO device.
+	The file <filename>uio_helper.c</filename> contains a lot of
+	functions you could use in your userspace driver code.
+	</para>
+</sect2>
+
+<sect2 id="mmap_device_memory">
+<title>mmap() device memory</title>
+	<para>
+	After you made sure you've got the right device with the
+	memory mappings you need, all you have to do is to call
+	<function>mmap()</function> to map the device's memory
+	to userspace.
+	</para>
+	<para>
+	The parameter <varname>offset</varname> of the
+	<function>mmap()</function> call has a special meaning
+	for UIO devices: It is used to select which mapping of
+	your device you want to map. To map the memory of
+	mapping N, you have to use N times the page size as
+	your offset:
+	</para>
+<programlisting format="linespecific">
+	offset = N * getpagesize();
+</programlisting>
+	<para>
+	N starts from zero, so if you've got only one memory
+	range to map, set <varname>offset = 0</varname>.
+	A drawback of this technique is that memory is always
+	mapped beginning with its start address.
+	</para>
+</sect2>
+
+<sect2 id="wait_for_interrupts">
+<title>Waiting for interrupts</title>
+	<para>
+	After you successfully mapped your devices memory, you
+	can access it like an ordinary array. Usually, you will
+	perform some initialization. After that, your hardware
+	starts working and will generate an interrupt as soon
+	as it's finished, has some data available, or needs your
+	attention because an error occured.
+	</para>
+	<para>
+	<filename>/dev/uioX</filename> is a read-only file. A
+	<function>read()</function> will always block until an
+	interrupt occurs. There is only one legal value for the
+	<varname>count</varname> parameter of
+	<function>read()</function>, and that is the size of a
+	signed 32 bit integer (4). Any other value for
+	<varname>count</varname> causes <function>read()</function>
+	to fail. The signed 32 bit integer read is the interrupt
+	count of your device. If the value is one more than the value
+	you read the last time, everything is OK. If the difference
+	is greater than one, you missed interrupts.
+	</para>
+	<para>
+	You can also use <function>select()</function> on
+	<filename>/dev/uioX</filename>.
+	</para>
+</sect2>
+
+</sect1>
+
 <appendix id="app1">
 <title>Further information</title>
 <itemizedlist>
 	<listitem><para>
+			<ulink url="http://www.osadl.org">
+				OSADL homepage.</ulink>
+		</para></listitem>
+	<listitem><para>
 		<ulink url="http://www.linutronix.de">
 		 Linutronix homepage.</ulink>
 		</para></listitem>
-	<listitem><para>...</para></listitem>
 </itemizedlist>
 </appendix>
 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-04-27 22:50   ` [PATCH 2/3] UIO: Documentation Greg Kroah-Hartman
  2007-04-27 22:50     ` [PATCH 3/3] UIO: Hilscher CIF card driver Greg Kroah-Hartman
@ 2007-05-01 23:42     ` Randy Dunlap
  2007-05-02  8:41       ` Hans-Jürgen Koch
  1 sibling, 1 reply; 42+ messages in thread
From: Randy Dunlap @ 2007-05-01 23:42 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, torvalds, hjk

On Fri, 27 Apr 2007 15:50:57 -0700 Greg Kroah-Hartman wrote:

> From: Hans J. Koch <hjk@linutronix.de>
> 
> Documentation for the UIO interface
> 
> From: Hans J. Koch <hjk@linutronix.de>
> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
> ---
>  Documentation/DocBook/kernel-api.tmpl |    4 +
>  Documentation/DocBook/uio-howto.tmpl  |  498 +++++++++++++++++++++++++++++++++
>  2 files changed, 502 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/DocBook/uio-howto.tmpl

> diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
> new file mode 100644
> index 0000000..bd2209f
> --- /dev/null
> +++ b/Documentation/DocBook/uio-howto.tmpl
> @@ -0,0 +1,498 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
> +"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
> +
> +<article id="index">
> +<articleinfo>
> +<title>The Userspace I/O HOWTO</title>

Most of this reads well.  Thanks.
A few typo corrections are below...


But it doesn't build for me with 'make htmldocs'.
Did you test it?

Warning(/tester/linsrc/linux-2.6.21-rc7-mm2//drivers/uio/uio.c:240): No description found for parameter 'info'
Warning(/tester/linsrc/linux-2.6.21-rc7-mm2//drivers/uio/uio.c:594): No description found for parameter 'owner'
Warning(/tester/linsrc/linux-2.6.21-rc7-mm2//drivers/uio/uio.c:594): No description found for parameter 'info'
Warning(/tester/linsrc/linux-2.6.21-rc7-mm2//drivers/uio/uio.c:667): No description found for parameter 'info'
Error(/tester/linsrc/linux-2.6.21-rc7-mm2//include/linux/uio_driver.h:29): cannot understand prototype: 'struct uio_mem '
Error(/tester/linsrc/linux-2.6.21-rc7-mm2//include/linux/uio_driver.h:55): cannot understand prototype: 'struct uio_info '
Warning(/tester/linsrc/linux-2.6.21-rc7-mm2//include/linux/uio_driver.h): no structured comments found

Patch below for all of is these (including typos).

However, it still fails 'make htmldocs' for me.
What am I missing?  How did it work for you?
My DTD doesn't like to see <varname> inside a <listitem>:


linux-2.6.21-rc7-mm2/Documentation/DocBook/uio-howto.xml:333: element listitem: validity error : Element listitem content does not follow the DTD, expecting (calloutlist | glosslist | itemizedlist | orderedlist | segmentedlist | simplelist | variablelist | caution | important | note | tip | warning | literallayout | programlisting | programlistingco | screen | screenco | screenshot | synopsis | cmdsynopsis | funcsynopsis | classsynopsis | fieldsynopsis | constructorsynopsis | destructorsynopsis | methodsynopsis | formalpara | para | simpara | address | blockquote | graphic | graphicco | mediaobject | mediaobjectco | informalequation | informalexample | informalfigure | informaltable | equation | example | figure | table | msgset | procedure | sidebar | qandaset | anchor | bridgehead | remark | highlights | abstract | authorblurb | epigraph | indexterm | beginpage)+, got (varname CDATA)


so I removed most of the <varname>s and still had errors.
Any suggestions?


...

> +	<para>
> +	Each driver provides attributes that are used to read or write
> +	variables. These attributes are accessible through sysfs
> +	files.  A custom kernel driver module can add its own
> +	attributes to the device owned by the uio driver, but not added
> +	to the UIO device itself at this time.  This might change in the
> +	future if it would be found to be useful

Period at end of sentence.

> +	</para>
> +
> +	<para>
> +	The following standard attributes are provided by the UIO
> +	framework:
> +	</para>

> <listitem>
> +<varname>void *internal_addr</varname>: If you have to access this memory
> +region from within your kernel module, you will want to map it internally by
> +using something like <function>ioremap_nocache()</function>. Addresses
> +returned by this function can not be mapped to user space, so you must not

                             cannot

> +store it in <varname>addr</varname>. Use <varname>internal_addr</varname>
> +instead to remember such an address.
> +</listitem>
> +</itemizedlist>

> +<sect2 id="adding_irq_handler">
> +<title>Adding an interrupt handler</title>
> +	<para>
> +	What you need to do in your interrupt handler depends on your
> +	hardware and on how you want to	handle it. You should try to
> +	keep the amount of code in your kernel interrupt handler low.
> +	If your hardware requires no action that you
> +	<emphasis>have</emphasis> to perform after each interrupt,
> +	then your handler can be empty.</para> <para>If, on the other
> +	hand, your hardware <emphasis>needs</emphasis> some action to
> +	be performed after each interrupt, then you
> +	<emphasis>must</emphasis> do it in your kernel module. Note
> +	that you cannot rely on the userspace part of your driver.Your

                                                                 . Your

> +	userspace program can terminate at any time, possibly leaving
> +	your hardware in a state where proper interrupt handling is
> +	still required.
> +	</para>



Some fixes:

From: Randy Dunlap <randy.dunlap@oracle.com>

Fix UIO kernel-doc typos and warnings.
Include uio-howto in list of docbook files.
Change DOCTYPE version to same as all other docbook files.

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
---
 Documentation/DocBook/Makefile       |    2 +-
 Documentation/DocBook/uio-howto.tmpl |   10 +++++-----
 drivers/uio/uio.c                    |   10 +++++-----
 include/linux/uio_driver.h           |    8 ++++----
 4 files changed, 15 insertions(+), 15 deletions(-)

--- linux-2.6.21-rc7-mm2.orig/include/linux/uio_driver.h
+++ linux-2.6.21-rc7-mm2/include/linux/uio_driver.h
@@ -19,7 +19,7 @@
 #include <linux/interrupt.h>
 
 /**
- * uio_mem - description of a UIO memory region
+ * struct uio_mem - description of a UIO memory region
  * @kobj:		kobject for this mapping
  * @addr:		address of the device's memory
  * @size:		size of IO
@@ -39,13 +39,13 @@ struct uio_mem {
 struct uio_device;
 
 /**
- * uio_info - UIO device capabilities
+ * struct uio_info - UIO device capabilities
  * @uio_dev:		the UIO device this info belongs to
  * @name:		device name
  * @version:		device driver version
  * @mem:		list of mappable memory regions, size==0 for end of list
  * @irq:		interrupt number or UIO_IRQ_CUSTOM
- * @irq_flags		flags for request_irq()
+ * @irq_flags:		flags for request_irq()
  * @priv:		optional private data
  * @handler:		the device's irq handler
  * @mmap:		mmap operation for this uio device
@@ -56,7 +56,7 @@ struct uio_info {
 	struct uio_device	*uio_dev;
 	char			*name;
 	char			*version;
-	struct uio_mem		mem[ MAX_UIO_MAPS ];
+	struct uio_mem		mem[MAX_UIO_MAPS];
 	long			irq;
 	unsigned long		irq_flags;
 	void			*priv;
--- linux-2.6.21-rc7-mm2.orig/drivers/uio/uio.c
+++ linux-2.6.21-rc7-mm2/drivers/uio/uio.c
@@ -234,7 +234,7 @@ static void uio_free_minor(struct uio_de
 
 /**
  * uio_event_notify - trigger an interrupt event
- * @idev: UIO device where the event occured
+ * @info: UIO device capabilities
  */
 void uio_event_notify(struct uio_info *info)
 {
@@ -582,9 +582,9 @@ static void uio_class_destroy(void)
 
 /**
  * uio_register_device - register a new userspace IO device
- *
+ * @owner:	module pointer
  * @parent:	parent device
- * @idev:	device capabilities
+ * @info:	device capabilities
  *
  * returns zero on success or a negative error code.
  */
@@ -658,8 +658,8 @@ err_kzalloc:
 EXPORT_SYMBOL_GPL(__uio_register_device);
 
 /**
- * uio_unregister_device - unregister a industrial IO device
- * @uiodev:	UIO device driver identifier
+ * uio_unregister_device - unregister an industrial IO device
+ * @info:	UIO device driver capabilities
  *
  * returns 0 on success
  */
--- linux-2.6.21-rc7-mm2.orig/Documentation/DocBook/uio-howto.tmpl
+++ linux-2.6.21-rc7-mm2/Documentation/DocBook/uio-howto.tmpl
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
 
 <article id="index">
 <articleinfo>
@@ -182,7 +182,7 @@ interested in translating it, please ema
 	files.  A custom kernel driver module can add its own
 	attributes to the device owned by the uio driver, but not added
 	to the UIO device itself at this time.  This might change in the
-	future if it would be found to be useful
+	future if it would be found to be useful.
 	</para>
 
 	<para>
@@ -422,7 +422,7 @@ all unused mappings.
 <varname>void *internal_addr</varname>: If you have to access this memory
 region from within your kernel module, you will want to map it internally by
 using something like <function>ioremap_nocache()</function>. Addresses
-returned by this function can not be mapped to user space, so you must not
+returned by this function cannot be mapped to user space, so you must not
 store it in <varname>addr</varname>. Use <varname>internal_addr</varname>
 instead to remember such an address.
 </listitem>
@@ -447,7 +447,7 @@ to set up sysfs files for this mapping. 
 	hand, your hardware <emphasis>needs</emphasis> some action to
 	be performed after each interrupt, then you
 	<emphasis>must</emphasis> do it in your kernel module. Note
-	that you cannot rely on the userspace part of your driver.Your
+	that you cannot rely on the userspace part of your driver. Your
 	userspace program can terminate at any time, possibly leaving
 	your hardware in a state where proper interrupt handling is
 	still required.
--- linux-2.6.21-rc7-mm2.orig/Documentation/DocBook/Makefile
+++ linux-2.6.21-rc7-mm2/Documentation/DocBook/Makefile
@@ -11,7 +11,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mc
 	    procfs-guide.xml writing_usb_driver.xml \
 	    kernel-api.xml filesystems.xml lsm.xml usb.xml \
 	    gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
-	    genericirq.xml
+	    genericirq.xml uio-howto.xml
 
 ###
 # The build process is as follows (targets):

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-05-01 23:42     ` [PATCH 2/3] UIO: Documentation Randy Dunlap
@ 2007-05-02  8:41       ` Hans-Jürgen Koch
  2007-05-02 20:52         ` Randy Dunlap
  0 siblings, 1 reply; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-05-02  8:41 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: Greg Kroah-Hartman, linux-kernel, torvalds, tglx

Am Mittwoch 02 Mai 2007 01:42 schrieb Randy Dunlap:

> > +<title>The Userspace I/O HOWTO</title>
> 
> Most of this reads well.  Thanks.
> A few typo corrections are below...

Thank you for your work. I generated a new patch that includes all your 
suggestions and also fixes the build problems.

[...]
> 
> However, it still fails 'make htmldocs' for me.
> What am I missing?  How did it work for you?
> My DTD doesn't like to see <varname> inside a <listitem>:
> 
> 
> linux-2.6.21-rc7-mm2/Documentation/DocBook/uio-howto.xml:333: element listitem: validity error : Element listitem content does not follow the DTD, expecting (calloutlist | glosslist | itemizedlist | orderedlist | segmentedlist | simplelist | variablelist | caution | important | note | tip | warning | literallayout | programlisting | programlistingco | screen | screenco | screenshot | synopsis | cmdsynopsis | funcsynopsis | classsynopsis | fieldsynopsis | constructorsynopsis | destructorsynopsis | methodsynopsis | formalpara | para | simpara | address | blockquote | graphic | graphicco | mediaobject | mediaobjectco | informalequation | informalexample | informalfigure | informaltable | equation | example | figure | table | msgset | procedure | sidebar | qandaset | anchor | bridgehead | remark | highlights | abstract | authorblurb | epigraph | indexterm | beginpage)+, got (varname CDATA)
> 
> 
> so I removed most of the <varname>s and still had errors.
> Any suggestions?

Yes, this only occurs when the <listitem> content is not surrounded by 
<para></para>. I fixed that. I also changed the whole thing from
"article" to "book" as all the other *.tmpl files are books. 


[...]
> > <listitem>
> > +<varname>void *internal_addr</varname>: If you have to access this memory
> > +region from within your kernel module, you will want to map it internally by
> > +using something like <function>ioremap_nocache()</function>. Addresses
> > +returned by this function can not be mapped to user space, so you must not
> 
>                              cannot

Here I also replaced ioremap_nocache() by ioremap(). I just fixed that in
uio_cif.c and don't want to encourage other people to write the same nonsense.

Here's my patch, as I said, it should include your fixes as well:

Index: linux-2.6.22-rc/drivers/uio/uio.c
===================================================================
--- linux-2.6.22-rc.orig/drivers/uio/uio.c	2007-05-02 08:32:19.000000000 +0200
+++ linux-2.6.22-rc/drivers/uio/uio.c	2007-05-02 09:10:40.000000000 +0200
@@ -234,7 +234,7 @@
 
 /**
  * uio_event_notify - trigger an interrupt event
- * @idev: UIO device where the event occured
+ * @info: UIO device capabilities
  */
 void uio_event_notify(struct uio_info *info)
 {
@@ -583,8 +583,9 @@
 /**
  * uio_register_device - register a new userspace IO device
  *
+ * @owner:	module that creates the new device
  * @parent:	parent device
- * @idev:	device capabilities
+ * @info:	UIO device capabilities
  *
  * returns zero on success or a negative error code.
  */
@@ -660,9 +661,8 @@
 
 /**
  * uio_unregister_device - unregister a industrial IO device
- * @uiodev:	UIO device driver identifier
+ * @info:	UIO device capabilities
  *
- * returns 0 on success
  */
 void uio_unregister_device(struct uio_info *info)
 {
Index: linux-2.6.22-rc/include/linux/uio_driver.h
===================================================================
--- linux-2.6.22-rc.orig/include/linux/uio_driver.h	2007-05-02 08:24:38.000000000 +0200
+++ linux-2.6.22-rc/include/linux/uio_driver.h	2007-05-02 08:42:42.000000000 +0200
@@ -19,7 +19,7 @@
 #include <linux/interrupt.h>
 
 /**
- * uio_mem - description of a UIO memory region
+ * struct uio_mem - description of a UIO memory region
  * @kobj:		kobject for this mapping
  * @addr:		address of the device's memory
  * @size:		size of IO
@@ -39,13 +39,13 @@
 struct uio_device;
 
 /**
- * uio_info - UIO device capabilities
+ * struct uio_info - UIO device capabilities
  * @uio_dev:		the UIO device this info belongs to
  * @name:		device name
  * @version:		device driver version
  * @mem:		list of mappable memory regions, size==0 for end of list
  * @irq:		interrupt number or UIO_IRQ_CUSTOM
- * @irq_flags		flags for request_irq()
+ * @irq_flags:		flags for request_irq()
  * @priv:		optional private data
  * @handler:		the device's irq handler
  * @mmap:		mmap operation for this uio device
@@ -56,7 +56,7 @@
 	struct uio_device	*uio_dev;
 	char			*name;
 	char			*version;
-	struct uio_mem		mem[ MAX_UIO_MAPS ];
+	struct uio_mem		mem[MAX_UIO_MAPS];
 	long			irq;
 	unsigned long		irq_flags;
 	void			*priv;
Index: linux-2.6.22-rc/Documentation/DocBook/Makefile
===================================================================
--- linux-2.6.22-rc.orig/Documentation/DocBook/Makefile	2007-05-02 09:00:32.000000000 +0200
+++ linux-2.6.22-rc/Documentation/DocBook/Makefile	2007-05-02 09:43:06.000000000 +0200
@@ -11,7 +11,7 @@
 	    procfs-guide.xml writing_usb_driver.xml \
 	    kernel-api.xml filesystems.xml lsm.xml usb.xml \
 	    gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
-	    genericirq.xml
+	    genericirq.xml uio-howto.xml
 
 ###
 # The build process is as follows (targets):
Index: linux-2.6.22-rc/Documentation/DocBook/uio-howto.tmpl
===================================================================
--- linux-2.6.22-rc.orig/Documentation/DocBook/uio-howto.tmpl	2007-05-02 08:54:24.000000000 +0200
+++ linux-2.6.22-rc/Documentation/DocBook/uio-howto.tmpl	2007-05-02 10:24:18.000000000 +0200
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
 
-<article id="index">
-<articleinfo>
+<book id="index">
+<bookinfo>
 <title>The Userspace I/O HOWTO</title>
 
 <author>
@@ -48,13 +48,13 @@
 	<revremark>First draft.</revremark>
 	</revision>
 </revhistory>
-</articleinfo>
+</bookinfo>
 
-<sect1 id="aboutthisdoc">
+<chapter id="aboutthisdoc">
 <?dbhtml filename="about.html"?>
 <title>About this document</title>
 
-<sect2 id="copyright">
+<sect1 id="copyright">
 <?dbhtml filename="copyright.html"?>
 <title>Copyright and License</title>
 <para>
@@ -63,9 +63,9 @@
 This documentation is Free Software licensed under the terms of the
 GPL version 2.
 </para>
-</sect2>
+</sect1>
 
-<sect2 id="translations">
+<sect1 id="translations">
 <?dbhtml filename="translations.html"?>
 <title>Translations</title>
 
@@ -73,9 +73,9 @@
 interested in translating it, please email me
 <email>hjk@linutronix.de</email>.
 </para>
-</sect2>
+</sect1>
 
-<sect2 id="preface">
+<sect1 id="preface">
 <title>Preface</title>
 	<para>
 	For many types of devices, creating a Linux kernel driver is
@@ -94,25 +94,25 @@
 	user space. This simplifies development and reduces the risk of
 	serious bugs within a kernel module.
 	</para>
-</sect2>
+</sect1>
 
-<sect2 id="thanks">
+<sect1 id="thanks">
 <title>Acknowledgments</title>
 	<para>I'd like to thank Thomas Gleixner and Benedikt Spranger of
 	Linutronix, who have not only written most of the UIO code, but also
 	helped greatly writing this HOWTO by giving me all kinds of background
 	information.</para>
-</sect2>
+</sect1>
 
-<sect2 id="feedback">
+<sect1 id="feedback">
 <title>Feedback</title>
 	<para>Find something wrong with this document? (Or perhaps something
 	right?) I would love to hear from you. Please email me at
 	<email>hjk@linutronix.de</email>.</para>
-</sect2>
 </sect1>
+</chapter>
 
-<sect1 id="about">
+<chapter id="about">
 <?dbhtml filename="about.html"?>
 <title>About UIO</title>
 
@@ -139,7 +139,7 @@
 </listitem>
 </itemizedlist>
 
-<sect2 id="how_uio_works">
+<sect1 id="how_uio_works">
 <title>How UIO works</title>
 	<para>
 	Each UIO device is accessed through a device file and several
@@ -188,7 +188,7 @@
 	files.  A custom kernel driver module can add its own
 	attributes to the device owned by the uio driver, but not added
 	to the UIO device itself at this time.  This might change in the
-	future if it would be found to be useful
+	future if it would be found to be useful.
 	</para>
 
 	<para>
@@ -264,10 +264,10 @@
 offset = N * getpagesize();
 </programlisting>
 
-</sect2>
 </sect1>
+</chapter>
 
-<sect1 id="using-uio_dummy" xreflabel="Using uio_dummy">
+<chapter id="using-uio_dummy" xreflabel="Using uio_dummy">
 <?dbhtml filename="using-uio_dummy.html"?>
 <title>Using uio_dummy</title>
 	<para>
@@ -277,7 +277,7 @@
 	kernel module that you will have to write yourself.
 	</para>
 
-<sect2 id="what_uio_dummy_does">
+<sect1 id="what_uio_dummy_does">
 <title>What uio_dummy does</title>
 	<para>
 	The kernel module <filename>uio_dummy.ko</filename> creates a
@@ -316,10 +316,10 @@
 	Use <function>cat count</function> to see how the interrupt
 	frequency changes.
 	</para>
-</sect2>
 </sect1>
+</chapter>
 
-<sect1 id="custom_kernel_module" xreflabel="Writing your own kernel module">
+<chapter id="custom_kernel_module" xreflabel="Writing your own kernel module">
 <?dbhtml filename="custom_kernel_module.html"?>
 <title>Writing your own kernel module</title>
 	<para>
@@ -328,7 +328,7 @@
 	sections of this file.
 	</para>
 
-<sect2 id="uio_info">
+<sect1 id="uio_info">
 <title>struct uio_info</title>
 	<para>
 	This structure tells the framework the details of your driver,
@@ -336,24 +336,24 @@
 	</para>
 
 <itemizedlist>
-<listitem>
+<listitem><para>
 <varname>char *name</varname>: Required. The name of your driver as
 it will appear in sysfs. I recommend using the name of your module for this.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>char *version</varname>: Required. This string appears in
 <filename>/sys/class/uio/uioX/version</filename>.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>struct uio_mem mem[ MAX_UIO_MAPS ]</varname>: Required if you
 have memory that can be mapped with <function>mmap()</function>. For each
 mapping you need to fill one of the <varname>uio_mem</varname> structures.
 See the description below for details.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>long irq</varname>: Required. If your hardware generates an
 interrupt, it's your modules task to determine the irq number during
 initialization. If you don't have a hardware generated interrupt but
@@ -363,35 +363,35 @@
 routine. If you had no interrupt at all, you could set
 <varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
 rarely makes sense.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>unsigned long irq_flags</varname>: Required if you've set
 <varname>irq</varname> to a hardware interrupt number. The flags given
 here will be used in the call to <function>request_irq()</function>.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>int (*mmap)(struct uio_info *info, struct vm_area_struct
 *vma)</varname>: Optional. If you need a special
 <function>mmap()</function> function, you can set it here. If this
 pointer is not NULL, your <function>mmap()</function> will be called
 instead of the built-in one.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>int (*open)(struct uio_info *info, struct inode *inode)
 </varname>: Optional. You might want to have your own
 <function>open()</function>, e.g. to enable interrupts only when your
 device is actually used.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>int (*release)(struct uio_info *info, struct inode *inode)
 </varname>: Optional. If you define your own
 <function>open()</function>, you will probably also want a custom
 <function>release()</function> function.
-</listitem>
+</para></listitem>
 </itemizedlist>
 
 <para>
@@ -402,36 +402,36 @@
 </para>
 
 <itemizedlist>
-<listitem>
+<listitem><para>
 <varname>int memtype</varname>: Required if the mapping is used. Set this to
 <varname>UIO_MEM_PHYS</varname> if you you have physical memory on your
 card to be mapped. Use <varname>UIO_MEM_LOGICAL</varname> for logical
 memory (e.g. allocated with <function>kmalloc()</function>). There's also
 <varname>UIO_MEM_VIRTUAL</varname> for virtual memory.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>unsigned long addr</varname>: Required if the mapping is used.
 Fill in the address of your memory block. This address is the one that
 appears in sysfs.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>unsigned long size</varname>: Fill in the size of the
 memory block that <varname>addr</varname> points to. If <varname>size</varname>
 is zero, the mapping is considered unused. Note that you
 <emphasis>must</emphasis> initialize <varname>size</varname> with zero for
 all unused mappings.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>void *internal_addr</varname>: If you have to access this memory
 region from within your kernel module, you will want to map it internally by
-using something like <function>ioremap_nocache()</function>. Addresses
-returned by this function can not be mapped to user space, so you must not
+using something like <function>ioremap()</function>. Addresses
+returned by this function cannot be mapped to user space, so you must not
 store it in <varname>addr</varname>. Use <varname>internal_addr</varname>
 instead to remember such an address.
-</listitem>
+</para></listitem>
 </itemizedlist>
 
 <para>
@@ -439,9 +439,9 @@
 <varname>struct uio_mem</varname>! It is used by the UIO framework
 to set up sysfs files for this mapping. Simply leave it alone.
 </para>
-</sect2>
+</sect1>
 
-<sect2 id="adding_irq_handler">
+<sect1 id="adding_irq_handler">
 <title>Adding an interrupt handler</title>
 	<para>
 	What you need to do in your interrupt handler depends on your
@@ -453,7 +453,7 @@
 	hand, your hardware <emphasis>needs</emphasis> some action to
 	be performed after each interrupt, then you
 	<emphasis>must</emphasis> do it in your kernel module. Note
-	that you cannot rely on the userspace part of your driver.Your
+	that you cannot rely on the userspace part of your driver. Your
 	userspace program can terminate at any time, possibly leaving
 	your hardware in a state where proper interrupt handling is
 	still required.
@@ -486,11 +486,11 @@
 	frequently happens on the PC platform, you can save yourself a
 	lot of trouble by supporting interrupt sharing.
 	</para>
-</sect2>
-
 </sect1>
 
-<sect1 id="userspace_driver" xreflabel="Writing a driver in user space">
+</chapter>
+
+<chapter id="userspace_driver" xreflabel="Writing a driver in user space">
 <?dbhtml filename="userspace_driver.html"?>
 <title>Writing a driver in userspace</title>
 	<para>
@@ -502,7 +502,7 @@
 	userspace application.
 	</para>
 
-<sect2 id="getting_uio_information">
+<sect1 id="getting_uio_information">
 <title>Getting information about your UIO device</title>
 	<para>
 	Information about all UIO devices is available in sysfs. The
@@ -534,9 +534,9 @@
 	The file <filename>uio_helper.c</filename> contains a lot of
 	functions you could use in your userspace driver code.
 	</para>
-</sect2>
+</sect1>
 
-<sect2 id="mmap_device_memory">
+<sect1 id="mmap_device_memory">
 <title>mmap() device memory</title>
 	<para>
 	After you made sure you've got the right device with the
@@ -561,9 +561,9 @@
 	A drawback of this technique is that memory is always
 	mapped beginning with its start address.
 	</para>
-</sect2>
+</sect1>
 
-<sect2 id="wait_for_interrupts">
+<sect1 id="wait_for_interrupts">
 <title>Waiting for interrupts</title>
 	<para>
 	After you successfully mapped your devices memory, you
@@ -590,10 +590,10 @@
 	You can also use <function>select()</function> on
 	<filename>/dev/uioX</filename>.
 	</para>
-</sect2>
-
 </sect1>
 
+</chapter>
+
 <appendix id="app1">
 <title>Further information</title>
 <itemizedlist>
@@ -608,4 +608,4 @@
 </itemizedlist>
 </appendix>
 
-</article>
+</book>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-05-02  8:41       ` Hans-Jürgen Koch
@ 2007-05-02 20:52         ` Randy Dunlap
  2007-05-02 22:00           ` Hans-Jürgen Koch
  0 siblings, 1 reply; 42+ messages in thread
From: Randy Dunlap @ 2007-05-02 20:52 UTC (permalink / raw)
  To: Hans-Jürgen Koch; +Cc: Greg Kroah-Hartman, linux-kernel, torvalds, tglx

On Wed, 2 May 2007 10:41:35 +0200 Hans-Jürgen Koch wrote:

> Am Mittwoch 02 Mai 2007 01:42 schrieb Randy Dunlap:
> 
> > > +<title>The Userspace I/O HOWTO</title>
> > 
> > Most of this reads well.  Thanks.
> > A few typo corrections are below...
> 
> Thank you for your work. I generated a new patch that includes all your 
> suggestions and also fixes the build problems.

Hi,
What does your patch apply to, please?  I get patch errors with it.


> [...]
> > 
> > However, it still fails 'make htmldocs' for me.
> > What am I missing?  How did it work for you?
> > My DTD doesn't like to see <varname> inside a <listitem>:
> > 
> > 
> > linux-2.6.21-rc7-mm2/Documentation/DocBook/uio-howto.xml:333: element listitem: validity error : Element listitem content does not follow the DTD, expecting (calloutlist | glosslist | itemizedlist | orderedlist | segmentedlist | simplelist | variablelist | caution | important | note | tip | warning | literallayout | programlisting | programlistingco | screen | screenco | screenshot | synopsis | cmdsynopsis | funcsynopsis | classsynopsis | fieldsynopsis | constructorsynopsis | destructorsynopsis | methodsynopsis | formalpara | para | simpara | address | blockquote | graphic | graphicco | mediaobject | mediaobjectco | informalequation | informalexample | informalfigure | informaltable | equation | example | figure | table | msgset | procedure | sidebar | qandaset | anchor | bridgehead | remark | highlights | abstract | authorblurb | epigraph | indexterm | beginpage)+, got (varname CDATA)
> > 
> > 
> > so I removed most of the <varname>s and still had errors.
> > Any suggestions?
> 
> Yes, this only occurs when the <listitem> content is not surrounded by 
> <para></para>. I fixed that. I also changed the whole thing from
> "article" to "book" as all the other *.tmpl files are books. 
> 
> 
> [...]
> > > <listitem>
> > > +<varname>void *internal_addr</varname>: If you have to access this memory
> > > +region from within your kernel module, you will want to map it internally by
> > > +using something like <function>ioremap_nocache()</function>. Addresses
> > > +returned by this function can not be mapped to user space, so you must not
> > 
> >                              cannot
> 
> Here I also replaced ioremap_nocache() by ioremap(). I just fixed that in
> uio_cif.c and don't want to encourage other people to write the same nonsense.
> 
> Here's my patch, as I said, it should include your fixes as well:
> 
> Index: linux-2.6.22-rc/drivers/uio/uio.c


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-05-02 20:52         ` Randy Dunlap
@ 2007-05-02 22:00           ` Hans-Jürgen Koch
  2007-05-02 23:37             ` Randy Dunlap
  0 siblings, 1 reply; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-05-02 22:00 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: Greg Kroah-Hartman, linux-kernel, torvalds, tglx

Am Mittwoch 02 Mai 2007 schrieb Randy Dunlap:
> On Wed, 2 May 2007 10:41:35 +0200 Hans-Jürgen Koch wrote:
> > Am Mittwoch 02 Mai 2007 01:42 schrieb Randy Dunlap:
> > > > +<title>The Userspace I/O HOWTO</title>
> > >
> > > Most of this reads well.  Thanks.
> > > A few typo corrections are below...
> >
> > Thank you for your work. I generated a new patch that includes all your
> > suggestions and also fixes the build problems.
>
> Hi,
> What does your patch apply to, please?  I get patch errors with it.
>

The patch goes on top of Greg's original patch plus the one I recently 
sent (adding the chapter about the userspace driver part). 
If you haven't got it handy, I mean this one:

http://marc.info/?l=linux-kernel&m=117788526325956&w=2

Thanks,
Hans



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-05-02 22:00           ` Hans-Jürgen Koch
@ 2007-05-02 23:37             ` Randy Dunlap
  2007-05-03  5:37               ` Greg KH
  0 siblings, 1 reply; 42+ messages in thread
From: Randy Dunlap @ 2007-05-02 23:37 UTC (permalink / raw)
  To: Hans-Jürgen Koch; +Cc: Greg Kroah-Hartman, linux-kernel, torvalds, tglx

On Thu, 3 May 2007 00:00:28 +0200 Hans-Jürgen Koch wrote:

> Am Mittwoch 02 Mai 2007 schrieb Randy Dunlap:
> > On Wed, 2 May 2007 10:41:35 +0200 Hans-Jürgen Koch wrote:
> > > Am Mittwoch 02 Mai 2007 01:42 schrieb Randy Dunlap:
> > > > > +<title>The Userspace I/O HOWTO</title>
> > > >
> > > > Most of this reads well.  Thanks.
> > > > A few typo corrections are below...
> > >
> > > Thank you for your work. I generated a new patch that includes all your
> > > suggestions and also fixes the build problems.

OK, your fixes all look good, but still needs one minor fix (below).

Acked-by: Randy Dunlap <randy.dunlap@oracle.com>

---

From: Randy Dunlap <randy.dunlap@oracle.com>

Fix last UIO kernel-doc problem.

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
---
 drivers/uio/uio.c |    1 -
 1 file changed, 1 deletion(-)

--- linux-2.6.21-git4.orig/drivers/uio/uio.c
+++ linux-2.6.21-git4/drivers/uio/uio.c
@@ -582,7 +582,6 @@ static void uio_class_destroy(void)
 
 /**
  * uio_register_device - register a new userspace IO device
- *
  * @owner:	module that creates the new device
  * @parent:	parent device
  * @info:	UIO device capabilities

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-05-02 23:37             ` Randy Dunlap
@ 2007-05-03  5:37               ` Greg KH
  2007-05-03  6:39                 ` Hans-Jürgen Koch
  0 siblings, 1 reply; 42+ messages in thread
From: Greg KH @ 2007-05-03  5:37 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Hans-J?rgen Koch, Greg Kroah-Hartman, linux-kernel, torvalds, tglx

On Wed, May 02, 2007 at 04:37:34PM -0700, Randy Dunlap wrote:
> On Thu, 3 May 2007 00:00:28 +0200 Hans-J?rgen Koch wrote:
> 
> > Am Mittwoch 02 Mai 2007 schrieb Randy Dunlap:
> > > On Wed, 2 May 2007 10:41:35 +0200 Hans-J?rgen Koch wrote:
> > > > Am Mittwoch 02 Mai 2007 01:42 schrieb Randy Dunlap:
> > > > > > +<title>The Userspace I/O HOWTO</title>
> > > > >
> > > > > Most of this reads well.  Thanks.
> > > > > A few typo corrections are below...
> > > >
> > > > Thank you for your work. I generated a new patch that includes all your
> > > > suggestions and also fixes the build problems.
> 
> OK, your fixes all look good, but still needs one minor fix (below).
> 
> Acked-by: Randy Dunlap <randy.dunlap@oracle.com>

Hm, I have about 3 different patches here now, all dependant on each
other, yet I can't tell which goes first :(

Can someone just send me 1, or 3 with the correct order in which to
apply them?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-05-03  5:37               ` Greg KH
@ 2007-05-03  6:39                 ` Hans-Jürgen Koch
  2007-05-04  9:37                   ` Hans-Jürgen Koch
  0 siblings, 1 reply; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-05-03  6:39 UTC (permalink / raw)
  To: Greg KH
  Cc: Randy Dunlap, Greg Kroah-Hartman, linux-kernel, torvalds, tglx,
	Benedikt Spranger

[-- Attachment #1: Type: text/plain, Size: 1683 bytes --]

Am Donnerstag 03 Mai 2007 07:37 schrieb Greg KH:
> On Wed, May 02, 2007 at 04:37:34PM -0700, Randy Dunlap wrote:
> > On Thu, 3 May 2007 00:00:28 +0200 Hans-J?rgen Koch wrote:
> > 
> > > Am Mittwoch 02 Mai 2007 schrieb Randy Dunlap:
> > > > On Wed, 2 May 2007 10:41:35 +0200 Hans-J?rgen Koch wrote:
> > > > > Am Mittwoch 02 Mai 2007 01:42 schrieb Randy Dunlap:
> > > > > > > +<title>The Userspace I/O HOWTO</title>
> > > > > >
> > > > > > Most of this reads well.  Thanks.
> > > > > > A few typo corrections are below...
> > > > >
> > > > > Thank you for your work. I generated a new patch that includes all your
> > > > > suggestions and also fixes the build problems.
> > 
> > OK, your fixes all look good, but still needs one minor fix (below).
> > 
> > Acked-by: Randy Dunlap <randy.dunlap@oracle.com>
> 
> Hm, I have about 3 different patches here now, all dependant on each
> other, yet I can't tell which goes first :(
> 
> Can someone just send me 1, or 3 with the correct order in which to
> apply them?
> 
> thanks,
> 
> greg k-h
>

Hi Greg,
I attached all the UIO patches I collected so far. This is my series file:

uio.patch
fix-early-irq-problem-in-uio.patch
uio-documentation.patch
fix-uio_read-type-problem.patch
uio-dummy.patch
uio-hilscher-cif-card-driver.patch
ioremap-in-uio-hilscher-cif.patch
add-userspace-howto-to-uio-doc.patch
fix-uio-doc-build-problems.patch

It should also work without uio-dummy.patch.
I added Randy's last one-line patch to fix-uio-doc-build-problems.patch.

All patches are
Signed-off-by: Hans J. Koch <hjk@linutronix.de>

fix-uio-doc-build-problems.patch is also
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>

Thanks,
Hans







[-- Attachment #2: fix-uio-doc-build-problems.patch --]
[-- Type: text/x-diff, Size: 13835 bytes --]

Index: linux-2.6.22-rc/drivers/uio/uio.c
===================================================================
--- linux-2.6.22-rc.orig/drivers/uio/uio.c	2007-05-02 08:32:19.000000000 +0200
+++ linux-2.6.22-rc/drivers/uio/uio.c	2007-05-03 08:21:39.000000000 +0200
@@ -234,7 +234,7 @@
 
 /**
  * uio_event_notify - trigger an interrupt event
- * @idev: UIO device where the event occured
+ * @info: UIO device capabilities
  */
 void uio_event_notify(struct uio_info *info)
 {
@@ -582,9 +582,9 @@
 
 /**
  * uio_register_device - register a new userspace IO device
- *
+ * @owner:	module that creates the new device
  * @parent:	parent device
- * @idev:	device capabilities
+ * @info:	UIO device capabilities
  *
  * returns zero on success or a negative error code.
  */
@@ -660,9 +660,8 @@
 
 /**
  * uio_unregister_device - unregister a industrial IO device
- * @uiodev:	UIO device driver identifier
+ * @info:	UIO device capabilities
  *
- * returns 0 on success
  */
 void uio_unregister_device(struct uio_info *info)
 {
Index: linux-2.6.22-rc/include/linux/uio_driver.h
===================================================================
--- linux-2.6.22-rc.orig/include/linux/uio_driver.h	2007-05-02 08:24:38.000000000 +0200
+++ linux-2.6.22-rc/include/linux/uio_driver.h	2007-05-02 08:42:42.000000000 +0200
@@ -19,7 +19,7 @@
 #include <linux/interrupt.h>
 
 /**
- * uio_mem - description of a UIO memory region
+ * struct uio_mem - description of a UIO memory region
  * @kobj:		kobject for this mapping
  * @addr:		address of the device's memory
  * @size:		size of IO
@@ -39,13 +39,13 @@
 struct uio_device;
 
 /**
- * uio_info - UIO device capabilities
+ * struct uio_info - UIO device capabilities
  * @uio_dev:		the UIO device this info belongs to
  * @name:		device name
  * @version:		device driver version
  * @mem:		list of mappable memory regions, size==0 for end of list
  * @irq:		interrupt number or UIO_IRQ_CUSTOM
- * @irq_flags		flags for request_irq()
+ * @irq_flags:		flags for request_irq()
  * @priv:		optional private data
  * @handler:		the device's irq handler
  * @mmap:		mmap operation for this uio device
@@ -56,7 +56,7 @@
 	struct uio_device	*uio_dev;
 	char			*name;
 	char			*version;
-	struct uio_mem		mem[ MAX_UIO_MAPS ];
+	struct uio_mem		mem[MAX_UIO_MAPS];
 	long			irq;
 	unsigned long		irq_flags;
 	void			*priv;
Index: linux-2.6.22-rc/Documentation/DocBook/Makefile
===================================================================
--- linux-2.6.22-rc.orig/Documentation/DocBook/Makefile	2007-05-02 09:00:32.000000000 +0200
+++ linux-2.6.22-rc/Documentation/DocBook/Makefile	2007-05-02 09:43:06.000000000 +0200
@@ -11,7 +11,7 @@
 	    procfs-guide.xml writing_usb_driver.xml \
 	    kernel-api.xml filesystems.xml lsm.xml usb.xml \
 	    gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
-	    genericirq.xml
+	    genericirq.xml uio-howto.xml
 
 ###
 # The build process is as follows (targets):
Index: linux-2.6.22-rc/Documentation/DocBook/uio-howto.tmpl
===================================================================
--- linux-2.6.22-rc.orig/Documentation/DocBook/uio-howto.tmpl	2007-05-02 08:54:24.000000000 +0200
+++ linux-2.6.22-rc/Documentation/DocBook/uio-howto.tmpl	2007-05-02 10:24:18.000000000 +0200
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
 
-<article id="index">
-<articleinfo>
+<book id="index">
+<bookinfo>
 <title>The Userspace I/O HOWTO</title>
 
 <author>
@@ -48,13 +48,13 @@
 	<revremark>First draft.</revremark>
 	</revision>
 </revhistory>
-</articleinfo>
+</bookinfo>
 
-<sect1 id="aboutthisdoc">
+<chapter id="aboutthisdoc">
 <?dbhtml filename="about.html"?>
 <title>About this document</title>
 
-<sect2 id="copyright">
+<sect1 id="copyright">
 <?dbhtml filename="copyright.html"?>
 <title>Copyright and License</title>
 <para>
@@ -63,9 +63,9 @@
 This documentation is Free Software licensed under the terms of the
 GPL version 2.
 </para>
-</sect2>
+</sect1>
 
-<sect2 id="translations">
+<sect1 id="translations">
 <?dbhtml filename="translations.html"?>
 <title>Translations</title>
 
@@ -73,9 +73,9 @@
 interested in translating it, please email me
 <email>hjk@linutronix.de</email>.
 </para>
-</sect2>
+</sect1>
 
-<sect2 id="preface">
+<sect1 id="preface">
 <title>Preface</title>
 	<para>
 	For many types of devices, creating a Linux kernel driver is
@@ -94,25 +94,25 @@
 	user space. This simplifies development and reduces the risk of
 	serious bugs within a kernel module.
 	</para>
-</sect2>
+</sect1>
 
-<sect2 id="thanks">
+<sect1 id="thanks">
 <title>Acknowledgments</title>
 	<para>I'd like to thank Thomas Gleixner and Benedikt Spranger of
 	Linutronix, who have not only written most of the UIO code, but also
 	helped greatly writing this HOWTO by giving me all kinds of background
 	information.</para>
-</sect2>
+</sect1>
 
-<sect2 id="feedback">
+<sect1 id="feedback">
 <title>Feedback</title>
 	<para>Find something wrong with this document? (Or perhaps something
 	right?) I would love to hear from you. Please email me at
 	<email>hjk@linutronix.de</email>.</para>
-</sect2>
 </sect1>
+</chapter>
 
-<sect1 id="about">
+<chapter id="about">
 <?dbhtml filename="about.html"?>
 <title>About UIO</title>
 
@@ -139,7 +139,7 @@
 </listitem>
 </itemizedlist>
 
-<sect2 id="how_uio_works">
+<sect1 id="how_uio_works">
 <title>How UIO works</title>
 	<para>
 	Each UIO device is accessed through a device file and several
@@ -188,7 +188,7 @@
 	files.  A custom kernel driver module can add its own
 	attributes to the device owned by the uio driver, but not added
 	to the UIO device itself at this time.  This might change in the
-	future if it would be found to be useful
+	future if it would be found to be useful.
 	</para>
 
 	<para>
@@ -264,10 +264,10 @@
 offset = N * getpagesize();
 </programlisting>
 
-</sect2>
 </sect1>
+</chapter>
 
-<sect1 id="using-uio_dummy" xreflabel="Using uio_dummy">
+<chapter id="using-uio_dummy" xreflabel="Using uio_dummy">
 <?dbhtml filename="using-uio_dummy.html"?>
 <title>Using uio_dummy</title>
 	<para>
@@ -277,7 +277,7 @@
 	kernel module that you will have to write yourself.
 	</para>
 
-<sect2 id="what_uio_dummy_does">
+<sect1 id="what_uio_dummy_does">
 <title>What uio_dummy does</title>
 	<para>
 	The kernel module <filename>uio_dummy.ko</filename> creates a
@@ -316,10 +316,10 @@
 	Use <function>cat count</function> to see how the interrupt
 	frequency changes.
 	</para>
-</sect2>
 </sect1>
+</chapter>
 
-<sect1 id="custom_kernel_module" xreflabel="Writing your own kernel module">
+<chapter id="custom_kernel_module" xreflabel="Writing your own kernel module">
 <?dbhtml filename="custom_kernel_module.html"?>
 <title>Writing your own kernel module</title>
 	<para>
@@ -328,7 +328,7 @@
 	sections of this file.
 	</para>
 
-<sect2 id="uio_info">
+<sect1 id="uio_info">
 <title>struct uio_info</title>
 	<para>
 	This structure tells the framework the details of your driver,
@@ -336,24 +336,24 @@
 	</para>
 
 <itemizedlist>
-<listitem>
+<listitem><para>
 <varname>char *name</varname>: Required. The name of your driver as
 it will appear in sysfs. I recommend using the name of your module for this.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>char *version</varname>: Required. This string appears in
 <filename>/sys/class/uio/uioX/version</filename>.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>struct uio_mem mem[ MAX_UIO_MAPS ]</varname>: Required if you
 have memory that can be mapped with <function>mmap()</function>. For each
 mapping you need to fill one of the <varname>uio_mem</varname> structures.
 See the description below for details.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>long irq</varname>: Required. If your hardware generates an
 interrupt, it's your modules task to determine the irq number during
 initialization. If you don't have a hardware generated interrupt but
@@ -363,35 +363,35 @@
 routine. If you had no interrupt at all, you could set
 <varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
 rarely makes sense.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>unsigned long irq_flags</varname>: Required if you've set
 <varname>irq</varname> to a hardware interrupt number. The flags given
 here will be used in the call to <function>request_irq()</function>.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>int (*mmap)(struct uio_info *info, struct vm_area_struct
 *vma)</varname>: Optional. If you need a special
 <function>mmap()</function> function, you can set it here. If this
 pointer is not NULL, your <function>mmap()</function> will be called
 instead of the built-in one.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>int (*open)(struct uio_info *info, struct inode *inode)
 </varname>: Optional. You might want to have your own
 <function>open()</function>, e.g. to enable interrupts only when your
 device is actually used.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>int (*release)(struct uio_info *info, struct inode *inode)
 </varname>: Optional. If you define your own
 <function>open()</function>, you will probably also want a custom
 <function>release()</function> function.
-</listitem>
+</para></listitem>
 </itemizedlist>
 
 <para>
@@ -402,36 +402,36 @@
 </para>
 
 <itemizedlist>
-<listitem>
+<listitem><para>
 <varname>int memtype</varname>: Required if the mapping is used. Set this to
 <varname>UIO_MEM_PHYS</varname> if you you have physical memory on your
 card to be mapped. Use <varname>UIO_MEM_LOGICAL</varname> for logical
 memory (e.g. allocated with <function>kmalloc()</function>). There's also
 <varname>UIO_MEM_VIRTUAL</varname> for virtual memory.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>unsigned long addr</varname>: Required if the mapping is used.
 Fill in the address of your memory block. This address is the one that
 appears in sysfs.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>unsigned long size</varname>: Fill in the size of the
 memory block that <varname>addr</varname> points to. If <varname>size</varname>
 is zero, the mapping is considered unused. Note that you
 <emphasis>must</emphasis> initialize <varname>size</varname> with zero for
 all unused mappings.
-</listitem>
+</para></listitem>
 
-<listitem>
+<listitem><para>
 <varname>void *internal_addr</varname>: If you have to access this memory
 region from within your kernel module, you will want to map it internally by
-using something like <function>ioremap_nocache()</function>. Addresses
-returned by this function can not be mapped to user space, so you must not
+using something like <function>ioremap()</function>. Addresses
+returned by this function cannot be mapped to user space, so you must not
 store it in <varname>addr</varname>. Use <varname>internal_addr</varname>
 instead to remember such an address.
-</listitem>
+</para></listitem>
 </itemizedlist>
 
 <para>
@@ -439,9 +439,9 @@
 <varname>struct uio_mem</varname>! It is used by the UIO framework
 to set up sysfs files for this mapping. Simply leave it alone.
 </para>
-</sect2>
+</sect1>
 
-<sect2 id="adding_irq_handler">
+<sect1 id="adding_irq_handler">
 <title>Adding an interrupt handler</title>
 	<para>
 	What you need to do in your interrupt handler depends on your
@@ -453,7 +453,7 @@
 	hand, your hardware <emphasis>needs</emphasis> some action to
 	be performed after each interrupt, then you
 	<emphasis>must</emphasis> do it in your kernel module. Note
-	that you cannot rely on the userspace part of your driver.Your
+	that you cannot rely on the userspace part of your driver. Your
 	userspace program can terminate at any time, possibly leaving
 	your hardware in a state where proper interrupt handling is
 	still required.
@@ -486,11 +486,11 @@
 	frequently happens on the PC platform, you can save yourself a
 	lot of trouble by supporting interrupt sharing.
 	</para>
-</sect2>
-
 </sect1>
 
-<sect1 id="userspace_driver" xreflabel="Writing a driver in user space">
+</chapter>
+
+<chapter id="userspace_driver" xreflabel="Writing a driver in user space">
 <?dbhtml filename="userspace_driver.html"?>
 <title>Writing a driver in userspace</title>
 	<para>
@@ -502,7 +502,7 @@
 	userspace application.
 	</para>
 
-<sect2 id="getting_uio_information">
+<sect1 id="getting_uio_information">
 <title>Getting information about your UIO device</title>
 	<para>
 	Information about all UIO devices is available in sysfs. The
@@ -534,9 +534,9 @@
 	The file <filename>uio_helper.c</filename> contains a lot of
 	functions you could use in your userspace driver code.
 	</para>
-</sect2>
+</sect1>
 
-<sect2 id="mmap_device_memory">
+<sect1 id="mmap_device_memory">
 <title>mmap() device memory</title>
 	<para>
 	After you made sure you've got the right device with the
@@ -561,9 +561,9 @@
 	A drawback of this technique is that memory is always
 	mapped beginning with its start address.
 	</para>
-</sect2>
+</sect1>
 
-<sect2 id="wait_for_interrupts">
+<sect1 id="wait_for_interrupts">
 <title>Waiting for interrupts</title>
 	<para>
 	After you successfully mapped your devices memory, you
@@ -590,10 +590,10 @@
 	You can also use <function>select()</function> on
 	<filename>/dev/uioX</filename>.
 	</para>
-</sect2>
-
 </sect1>
 
+</chapter>
+
 <appendix id="app1">
 <title>Further information</title>
 <itemizedlist>
@@ -608,4 +608,4 @@
 </itemizedlist>
 </appendix>
 
-</article>
+</book>

[-- Attachment #3: fix-early-irq-problem-in-uio.patch --]
[-- Type: text/x-diff, Size: 603 bytes --]

Index: linux-2.6.22-rc/drivers/uio/uio.c
===================================================================
--- linux-2.6.22-rc.orig/drivers/uio/uio.c	2007-04-28 20:01:02.000000000 +0200
+++ linux-2.6.22-rc/drivers/uio/uio.c	2007-04-28 20:15:00.000000000 +0200
@@ -633,6 +633,8 @@
 	if (ret)
 		goto err_uio_dev_add_attributes;
 
+	info->uio_dev = idev;
+
 	if (idev->info->irq >= 0) {
 		ret = request_irq(idev->info->irq, uio_interrupt,
 				  idev->info->irq_flags, idev->info->name, idev);
@@ -640,7 +642,6 @@
 			goto err_request_irq;
 	}
 
-	info->uio_dev = idev;
 	return 0;
 
 err_request_irq:

[-- Attachment #4: add-userspace-howto-to-uio-doc.patch --]
[-- Type: text/x-diff, Size: 4929 bytes --]

Index: linux-2.6.22-rc/Documentation/DocBook/uio-howto.tmpl
===================================================================
--- linux-2.6.22-rc.orig/Documentation/DocBook/uio-howto.tmpl	2007-04-29 22:17:45.000000000 +0200
+++ linux-2.6.22-rc/Documentation/DocBook/uio-howto.tmpl	2007-04-30 00:15:38.000000000 +0200
@@ -30,6 +30,12 @@
 
 <revhistory>
 	<revision>
+	<revnumber>0.3</revnumber>
+	<date>2007-04-29</date>
+	<authorinitials>hjk</authorinitials>
+	<revremark>Added section about userspace drivers.</revremark>
+	</revision>
+	<revision>
 	<revnumber>0.2</revnumber>
 	<date>2007-02-13</date>
 	<authorinitials>hjk</authorinitials>
@@ -484,14 +490,121 @@
 
 </sect1>
 
+<sect1 id="userspace_driver" xreflabel="Writing a driver in user space">
+<?dbhtml filename="userspace_driver.html"?>
+<title>Writing a driver in userspace</title>
+	<para>
+	Once you have a working kernel module for your hardware, you can
+	write the userspace part of your driver. You don't need any special
+	libraries, your driver can be written in any reasonable language,
+	you can use floating point numbers and so on. In short, you can
+	use all the tools and libraries you'd normally use for writing a
+	userspace application.
+	</para>
+
+<sect2 id="getting_uio_information">
+<title>Getting information about your UIO device</title>
+	<para>
+	Information about all UIO devices is available in sysfs. The
+	first thing you should do in your driver is check
+	<varname>name</varname> and <varname>version</varname> to
+	make sure your talking to the right device and that its kernel
+	driver has the version you expect.
+	</para>
+	<para>
+	You should also make sure that the memory mapping you need
+	exists and has the size you expect.
+	</para>
+	<para>
+	There is a tool called <varname>lsuio</varname> that lists
+	UIO devices and their attributes. It is available here:
+	</para>
+	<para>
+	<ulink url="http://www.osadl.org/projects/downloads/UIO/user/">
+		http://www.osadl.org/projects/downloads/UIO/user/</ulink>
+	</para>
+	<para>
+	With <varname>lsuio</varname> you can quickly check if your
+	kernel module is loaded and which attributes it exports.
+	Have a look at the manpage for details.
+	</para>
+	<para>
+	The source code of <varname>lsuio</varname> can serve as an
+	example for getting information about an UIO device.
+	The file <filename>uio_helper.c</filename> contains a lot of
+	functions you could use in your userspace driver code.
+	</para>
+</sect2>
+
+<sect2 id="mmap_device_memory">
+<title>mmap() device memory</title>
+	<para>
+	After you made sure you've got the right device with the
+	memory mappings you need, all you have to do is to call
+	<function>mmap()</function> to map the device's memory
+	to userspace.
+	</para>
+	<para>
+	The parameter <varname>offset</varname> of the
+	<function>mmap()</function> call has a special meaning
+	for UIO devices: It is used to select which mapping of
+	your device you want to map. To map the memory of
+	mapping N, you have to use N times the page size as
+	your offset:
+	</para>
+<programlisting format="linespecific">
+	offset = N * getpagesize();
+</programlisting>
+	<para>
+	N starts from zero, so if you've got only one memory
+	range to map, set <varname>offset = 0</varname>.
+	A drawback of this technique is that memory is always
+	mapped beginning with its start address.
+	</para>
+</sect2>
+
+<sect2 id="wait_for_interrupts">
+<title>Waiting for interrupts</title>
+	<para>
+	After you successfully mapped your devices memory, you
+	can access it like an ordinary array. Usually, you will
+	perform some initialization. After that, your hardware
+	starts working and will generate an interrupt as soon
+	as it's finished, has some data available, or needs your
+	attention because an error occured.
+	</para>
+	<para>
+	<filename>/dev/uioX</filename> is a read-only file. A
+	<function>read()</function> will always block until an
+	interrupt occurs. There is only one legal value for the
+	<varname>count</varname> parameter of
+	<function>read()</function>, and that is the size of a
+	signed 32 bit integer (4). Any other value for
+	<varname>count</varname> causes <function>read()</function>
+	to fail. The signed 32 bit integer read is the interrupt
+	count of your device. If the value is one more than the value
+	you read the last time, everything is OK. If the difference
+	is greater than one, you missed interrupts.
+	</para>
+	<para>
+	You can also use <function>select()</function> on
+	<filename>/dev/uioX</filename>.
+	</para>
+</sect2>
+
+</sect1>
+
 <appendix id="app1">
 <title>Further information</title>
 <itemizedlist>
 	<listitem><para>
+			<ulink url="http://www.osadl.org">
+				OSADL homepage.</ulink>
+		</para></listitem>
+	<listitem><para>
 		<ulink url="http://www.linutronix.de">
 		 Linutronix homepage.</ulink>
 		</para></listitem>
-	<listitem><para>...</para></listitem>
 </itemizedlist>
 </appendix>
 

[-- Attachment #5: ioremap-in-uio-hilscher-cif.patch --]
[-- Type: text/x-diff, Size: 671 bytes --]

Index: linux-2.6.22-rc/drivers/uio/uio_cif.c
===================================================================
--- linux-2.6.22-rc.orig/drivers/uio/uio_cif.c	2007-04-29 21:34:45.000000000 +0200
+++ linux-2.6.22-rc/drivers/uio/uio_cif.c	2007-04-29 21:36:31.000000000 +0200
@@ -64,9 +64,8 @@
 	info->mem[0].addr = pci_resource_start(dev, 0);
 	if (!info->mem[0].addr)
 		goto out_release;
-	info->mem[0].internal_addr = ioremap_nocache(
-						pci_resource_start(dev, 0),
-						pci_resource_len(dev, 0) );
+	info->mem[0].internal_addr = ioremap(pci_resource_start(dev, 0),
+					     pci_resource_len(dev, 0) );
 	if (!info->mem[0].internal_addr)
 		goto out_release;
 

[-- Attachment #6: fix-uio_read-type-problem.patch --]
[-- Type: text/x-diff, Size: 770 bytes --]

Index: linux-2.6.22-rc/drivers/uio/uio.c
===================================================================
--- linux-2.6.22-rc.orig/drivers/uio/uio.c	2007-04-28 22:46:34.000000000 +0200
+++ linux-2.6.22-rc/drivers/uio/uio.c	2007-04-28 22:59:40.000000000 +0200
@@ -264,7 +264,7 @@
 
 struct uio_listener {
 	struct uio_device *dev;
-	int event_count;
+	s32 event_count;
 };
 
 static int uio_open(struct inode *inode, struct file *filep)
@@ -345,12 +345,12 @@
 	struct uio_device *idev = listener->dev;
 	DECLARE_WAITQUEUE(wait, current);
 	ssize_t retval;
-	int event_count;
+	s32 event_count;
 
 	if (idev->info->irq == UIO_IRQ_NONE)
 		return -EIO;
 
-	if (count != sizeof(int))
+	if (count != sizeof(s32))
 		return -EINVAL;
 
 	add_wait_queue(&idev->wait, &wait);

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-05-03  6:39                 ` Hans-Jürgen Koch
@ 2007-05-04  9:37                   ` Hans-Jürgen Koch
  2007-05-07 17:46                     ` Randy Dunlap
  0 siblings, 1 reply; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-05-04  9:37 UTC (permalink / raw)
  To: Greg KH
  Cc: Randy Dunlap, Greg Kroah-Hartman, linux-kernel, torvalds, tglx,
	Benedikt Spranger

Am Donnerstag 03 Mai 2007 08:39 schrieb Hans-Jürgen Koch:
> > 
> > Hm, I have about 3 different patches here now, all dependant on each
> > other, yet I can't tell which goes first :(
> > 
> > Can someone just send me 1, or 3 with the correct order in which to
> > apply them?
> > 
> > thanks,
> > 
> > greg k-h
> >
> 
> Hi Greg,
> I attached all the UIO patches I collected so far. This is my series file:
> 
> uio.patch
> fix-early-irq-problem-in-uio.patch
> uio-documentation.patch
> fix-uio_read-type-problem.patch
> uio-dummy.patch
> uio-hilscher-cif-card-driver.patch
> ioremap-in-uio-hilscher-cif.patch
> add-userspace-howto-to-uio-doc.patch
> fix-uio-doc-build-problems.patch
> 
> It should also work without uio-dummy.patch.
> I added Randy's last one-line patch to fix-uio-doc-build-problems.patch.
> 
> All patches are
> Signed-off-by: Hans J. Koch <hjk@linutronix.de>
> 
> fix-uio-doc-build-problems.patch is also
> Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
> 

I also updated the original patch set with all these changes. They can be 
found here:

http://www.osadl.org/projects/downloads/UIO/kernel/

Thanks,
Hans

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-05-04  9:37                   ` Hans-Jürgen Koch
@ 2007-05-07 17:46                     ` Randy Dunlap
  2007-05-07 20:01                       ` Hans-Jürgen Koch
  0 siblings, 1 reply; 42+ messages in thread
From: Randy Dunlap @ 2007-05-07 17:46 UTC (permalink / raw)
  To: Hans-Jürgen Koch, akpm
  Cc: Greg KH, Greg Kroah-Hartman, linux-kernel, torvalds, tglx,
	Benedikt Spranger

On Fri, 4 May 2007 11:37:09 +0200 Hans-Jürgen Koch wrote:

> Am Donnerstag 03 Mai 2007 08:39 schrieb Hans-Jürgen Koch:
> > > 
> > > Hm, I have about 3 different patches here now, all dependant on each
> > > other, yet I can't tell which goes first :(
> > > 
> > > Can someone just send me 1, or 3 with the correct order in which to
> > > apply them?
> > > 
> > > thanks,
> > > 
> > > greg k-h
> > >
> > 
> > Hi Greg,
> > I attached all the UIO patches I collected so far. This is my series file:
> > 
> > uio.patch
> > fix-early-irq-problem-in-uio.patch
> > uio-documentation.patch
> > fix-uio_read-type-problem.patch
> > uio-dummy.patch
> > uio-hilscher-cif-card-driver.patch
> > ioremap-in-uio-hilscher-cif.patch
> > add-userspace-howto-to-uio-doc.patch
> > fix-uio-doc-build-problems.patch
> > 
> > It should also work without uio-dummy.patch.
> > I added Randy's last one-line patch to fix-uio-doc-build-problems.patch.
> > 
> > All patches are
> > Signed-off-by: Hans J. Koch <hjk@linutronix.de>
> > 
> > fix-uio-doc-build-problems.patch is also
> > Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
> > 
> 
> I also updated the original patch set with all these changes. They can be 
> found here:
> 
> http://www.osadl.org/projects/downloads/UIO/kernel/

Can one of you make sure that Andrew has a version in -mm that
will build without bombing?  Current 2.6.21-mm1 does this on UIO docs,
but all of these have been fixed via email AFAIK:

Warning(/tester/linsrc/linux-2621-mm1//drivers/uio/uio.c:240): No description found for parameter 'info'
Warning(/tester/linsrc/linux-2621-mm1//drivers/uio/uio.c:594): No description found for parameter 'owner'
Warning(/tester/linsrc/linux-2621-mm1//drivers/uio/uio.c:594): No description found for parameter 'info'
Warning(/tester/linsrc/linux-2621-mm1//drivers/uio/uio.c:667): No description found for parameter 'info'
Error(/tester/linsrc/linux-2621-mm1//include/linux/uio_driver.h:29): cannot understand prototype: 'struct uio_mem '
Error(/tester/linsrc/linux-2621-mm1//include/linux/uio_driver.h:55): cannot understand prototype: 'struct uio_info '
Warning(/tester/linsrc/linux-2621-mm1//include/linux/uio_driver.h): no structured comments found
make[1]: *** [Documentation/DocBook/kernel-api.xml] Error 2
make: *** [mandocs] Error 2


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 2/3] UIO: Documentation
  2007-05-07 17:46                     ` Randy Dunlap
@ 2007-05-07 20:01                       ` Hans-Jürgen Koch
  0 siblings, 0 replies; 42+ messages in thread
From: Hans-Jürgen Koch @ 2007-05-07 20:01 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: akpm, Greg KH, Greg Kroah-Hartman, linux-kernel, torvalds, tglx,
	Benedikt Spranger

Am Montag 07 Mai 2007 19:46 schrieb Randy Dunlap:
> On Fri, 4 May 2007 11:37:09 +0200 Hans-Jürgen Koch wrote:
> 
> > Am Donnerstag 03 Mai 2007 08:39 schrieb Hans-Jürgen Koch:
> > > > 
> > > > Hm, I have about 3 different patches here now, all dependant on each
> > > > other, yet I can't tell which goes first :(
> > > > 
> > > > Can someone just send me 1, or 3 with the correct order in which to
> > > > apply them?
> > > > 
> > > > thanks,
> > > > 
> > > > greg k-h
> > > >
> > > 
> > > Hi Greg,
> > > I attached all the UIO patches I collected so far. This is my series file:
> > > 
> > > uio.patch
> > > fix-early-irq-problem-in-uio.patch
> > > uio-documentation.patch
> > > fix-uio_read-type-problem.patch
> > > uio-dummy.patch
> > > uio-hilscher-cif-card-driver.patch
> > > ioremap-in-uio-hilscher-cif.patch
> > > add-userspace-howto-to-uio-doc.patch
> > > fix-uio-doc-build-problems.patch
> > > 
> > > It should also work without uio-dummy.patch.
> > > I added Randy's last one-line patch to fix-uio-doc-build-problems.patch.
> > > 
> > > All patches are
> > > Signed-off-by: Hans J. Koch <hjk@linutronix.de>
> > > 
> > > fix-uio-doc-build-problems.patch is also
> > > Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
> > > 
> > 
> > I also updated the original patch set with all these changes. They can be 
> > found here:
> > 
> > http://www.osadl.org/projects/downloads/UIO/kernel/
> 
> Can one of you make sure that Andrew has a version in -mm that
> will build without bombing?  

Andrew usually takes Greg's patches AFAIK. The patches in
http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/driver/
are definitely out of date. Greg, could you update them?

> Current 2.6.21-mm1 does this on UIO docs, 
> but all of these have been fixed via email AFAIK:
> 
> Warning(/tester/linsrc/linux-2621-mm1//drivers/uio/uio.c:240): No description found for parameter 'info'
> Warning(/tester/linsrc/linux-2621-mm1//drivers/uio/uio.c:594): No description found for parameter 'owner'
> Warning(/tester/linsrc/linux-2621-mm1//drivers/uio/uio.c:594): No description found for parameter 'info'
> Warning(/tester/linsrc/linux-2621-mm1//drivers/uio/uio.c:667): No description found for parameter 'info'
> Error(/tester/linsrc/linux-2621-mm1//include/linux/uio_driver.h:29): cannot understand prototype: 'struct uio_mem '
> Error(/tester/linsrc/linux-2621-mm1//include/linux/uio_driver.h:55): cannot understand prototype: 'struct uio_info '
> Warning(/tester/linsrc/linux-2621-mm1//include/linux/uio_driver.h): no structured comments found
> make[1]: *** [Documentation/DocBook/kernel-api.xml] Error 2
> make: *** [mandocs] Error 2

Yes, all of these are fixed in the patches I sent.

Thanks,
Hans



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [GIT PATCH] UIO patches for 2.6.21
  2007-04-29  8:30           ` Thomas Gleixner
  2007-04-29 12:09             ` Jan Engelhardt
@ 2007-05-07 20:02             ` Pavel Machek
  1 sibling, 0 replies; 42+ messages in thread
From: Pavel Machek @ 2007-05-07 20:02 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Greg KH, Alan Cox, Hans-J?rgen Koch, Bill Davidsen,
	Linus Torvalds, Andrew Morton, linux-kernel, Benedikt Spranger

Hi!

> > > I agree, if we make it entirely clear that the flag is nonpolitical. 
> > 
> > Hm, I don't know, what makes this different from the fact that we can
> > mmap PCI device space today through the proc and sysfs entries?  That's
> > how X gets direct access to the hardware for a number of different
> > cards, and that's pretty much the same thing as the UIO interface is
> > doing.
> > 
> > Unless you think we should also use the same "taint" flag on those
> > accesses too, and if so, I have no objection.
> 
> Right, this is just a hint, that something in user space is accessing
> the hardware directly. Not a too bad idea, but pretty much useless when
> we add X to the picture as it will be set always :)

Some people -- like me -- use X68_fbcon over vesafb, in order not to
be tainted this way.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [GIT PATCH] UIO patches for 2.6.21
@ 2007-05-08 14:04 Greg KH
  0 siblings, 0 replies; 42+ messages in thread
From: Greg KH @ 2007-05-08 14:04 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton
  Cc: linux-kernel, tglx, Benedikt Spranger, Hans J. Koch

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=unknown-8bit, Size: 1352 bytes --]

Here is another round of the updated UIO (Userspace I/O driver framework)
patches for 2.6.21.

All of the issues raised from the last time the patches were posted
(last week) have been fixed in this version.

Many thanks for all of the review comments from everyone who took the
time to read over the code.

These patches include full documentation, are self-contained from the
rest of the kernel, and have been in the -mm tree for the past few
months with no complaints.

Please pull from:
	master.kernel.org:/pub/scm/linux/kernel/git/gregkh/uio-2.6.git/

Patches will be sent as a follow-on to this message to lkml for people
to see.

thanks,

greg k-h



 Documentation/DocBook/kernel-api.tmpl |    4 
 Documentation/DocBook/uio-howto.tmpl  |  611 +++++++++++++++++++++++++++++
 drivers/Kconfig                       |    1 
 drivers/Makefile                      |    1 
 drivers/uio/Kconfig                   |   27 +
 drivers/uio/Makefile                  |    2 
 drivers/uio/uio.c                     |  701 ++++++++++++++++++++++++++++++++++
 drivers/uio/uio_cif.c                 |  156 +++++++
 include/linux/uio_driver.h            |   91 ++++
 9 files changed, 1594 insertions(+)

---------------

Hans J. Koch (2):
      UIO: Add the User IO core code
      UIO: Documentation

Hans-Jürgen Koch (1):
      UIO: Hilscher CIF card driver


^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2007-05-09 12:29 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-27 22:49 [GIT PATCH] UIO patches for 2.6.21 Greg KH
2007-04-27 22:50 ` [PATCH 1/3] UIO: Add the User IO core code Greg Kroah-Hartman
2007-04-27 22:50   ` [PATCH 2/3] UIO: Documentation Greg Kroah-Hartman
2007-04-27 22:50     ` [PATCH 3/3] UIO: Hilscher CIF card driver Greg Kroah-Hartman
2007-04-29 19:44       ` [PATCH 3/3] UIO: Hilscher CIF card driver (with patch) Hans-Jürgen Koch
2007-05-01 23:42     ` [PATCH 2/3] UIO: Documentation Randy Dunlap
2007-05-02  8:41       ` Hans-Jürgen Koch
2007-05-02 20:52         ` Randy Dunlap
2007-05-02 22:00           ` Hans-Jürgen Koch
2007-05-02 23:37             ` Randy Dunlap
2007-05-03  5:37               ` Greg KH
2007-05-03  6:39                 ` Hans-Jürgen Koch
2007-05-04  9:37                   ` Hans-Jürgen Koch
2007-05-07 17:46                     ` Randy Dunlap
2007-05-07 20:01                       ` Hans-Jürgen Koch
2007-04-27 23:19   ` Flaws with "UIO: Add the User IO core code" Alan Cox
2007-04-28 11:39     ` Thomas Gleixner
2007-04-28 18:52     ` Flaws with "UIO: Add the User IO core code" (with patch) Hans-Jürgen Koch
2007-04-28 20:24       ` Alan Cox
2007-04-28 20:38         ` Thomas Gleixner
2007-04-28 21:03         ` Hans-Jürgen Koch
2007-04-28 21:08           ` Thomas Gleixner
2007-04-28 21:14             ` Flaws with "UIO: Add the User IO core code" Hans-Jürgen Koch
2007-04-29 22:18               ` Flaws with "UIO: Add the User IO core code" (with patch) Hans-Jürgen Koch
2007-04-27 23:04 ` [GIT PATCH] UIO patches for 2.6.21 Andrew Morton
2007-04-27 23:11   ` Greg KH
2007-04-28 11:38     ` Thomas Gleixner
2007-04-27 23:26   ` Alan Cox
2007-04-28  0:28   ` Hans-Jürgen Koch
2007-04-28 13:00 ` Matthieu CASTET
2007-04-28 13:49   ` Hans-Jürgen Koch
2007-04-28 19:56 ` Bill Davidsen
2007-04-28 20:02   ` Thomas Gleixner
2007-04-28 20:03   ` Hans-Jürgen Koch
2007-04-28 20:15     ` Alan Cox
2007-04-28 20:31       ` Thomas Gleixner
2007-04-29  1:23         ` Greg KH
2007-04-29  8:30           ` Thomas Gleixner
2007-04-29 12:09             ` Jan Engelhardt
2007-04-29 16:27               ` Alan Cox
2007-05-07 20:02             ` Pavel Machek
2007-05-08 14:04 Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).