* [PATCH 0/1] UIO: Add a write() function to enable/disable interrupts @ 2008-05-22 19:22 Hans J. Koch 2008-05-22 19:26 ` [PATCH 1/1] " Hans J. Koch 0 siblings, 1 reply; 34+ messages in thread From: Hans J. Koch @ 2008-05-22 19:22 UTC (permalink / raw) To: linux-kernel Cc: Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Uwe Kleine-König, Magnus Damm At the moment, I've got two examples of hardware where the UIO interrupt handling has problems: 1) A PCI card with several internal interrupt sources that can activate the single IRQ line of the card. The card's PCI bridge has an irq acknowledge register that can be mapped to userspace, but setting a bit in it would be a read-modify-write operation which is racy from userspace. 2) An FPGA that has several internal interrupt sources OR'ed to one interrupt line that is connected to a GPIO of an ARM processor. The chip only has a single IRQ register where different bits show the status of the different interrupt sources. To acknowledge an IRQ, I have to clear the respective bit, which would leave the userspace part of the driver with a cleared register, unable to determine the source of the interrupt. My only chance is to disable the GPIO interrupt, but this leads to the problem that userspace cannot turn it on again. The patch that I'll send in response to this mail solves these problems by adding a write() function for /dev/uioX. Userspace can write a 32-bit int value to /dev/uioX. This value will usually be 0 or 1 to disable or enable the device's interrupts. The kernel part of the driver can implement an irqcontrol() hook that is called by the UIO core. Magnus Damm also ran into this problem when developing a generic UIO platform handler and came up with a different solution: http://lkml.org/lkml/2008/5/21/60 However, extending the UIO specs by adding a write function seems to be a more generic approach. It allows enabling _and_ disabling of interrupts. For devices that don't need this functionality, nothing changes. They can simply ignore the new irqcontrol() pointer, and UIO behaves as it always did. My patch is completely compatible with existing UIO drivers, no changes to drivers are required. Thanks to Jan Altenberg for testing this, and to Magnus Damm for telling me that I'm not the only one who has these problems ;-) Thanks, Hans ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-22 19:22 [PATCH 0/1] UIO: Add a write() function to enable/disable interrupts Hans J. Koch @ 2008-05-22 19:26 ` Hans J. Koch 2008-05-22 19:47 ` Tom Spink 2008-05-23 5:55 ` Uwe Kleine-König 0 siblings, 2 replies; 34+ messages in thread From: Hans J. Koch @ 2008-05-22 19:26 UTC (permalink / raw) To: Hans J. Koch Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Uwe Kleine-König, Magnus Damm Sometimes it is necessary to enable/disable the interrupt of a UIO device from the userspace part of the driver. With this patch, the UIO kernel driver can implement an "irqcontrol()" function that does this. Userspace can write an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The UIO core will then call the driver's irqcontrol function. Signed-off-by: Hans J. Koch <hjk@linutronix.de> --- Documentation/DocBook/uio-howto.tmpl | 40 ++++++++++++++++++++++++++++++++++- drivers/uio/uio.c | 26 ++++++++++++++++++++++ include/linux/uio_driver.h | 2 + 3 files changed, 67 insertions(+), 1 deletion(-) Index: linux-2.6.26-rc/include/linux/uio_driver.h =================================================================== --- linux-2.6.26-rc.orig/include/linux/uio_driver.h 2008-05-22 20:22:57.000000000 +0200 +++ linux-2.6.26-rc/include/linux/uio_driver.h 2008-05-22 20:23:12.000000000 +0200 @@ -53,6 +53,7 @@ * @mmap: mmap operation for this uio device * @open: open operation for this uio device * @release: release operation for this uio device + * @irqcontrol: disable/enable irqs when 0/1 is written to /dev/uioX */ struct uio_info { struct uio_device *uio_dev; @@ -66,6 +67,7 @@ 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); + int (*irqcontrol)(struct uio_info *info, s32 irq_on); }; extern int __must_check Index: linux-2.6.26-rc/drivers/uio/uio.c =================================================================== --- linux-2.6.26-rc.orig/drivers/uio/uio.c 2008-05-22 20:23:07.000000000 +0200 +++ linux-2.6.26-rc/drivers/uio/uio.c 2008-05-22 20:23:12.000000000 +0200 @@ -420,6 +420,31 @@ return retval; } +static ssize_t uio_write(struct file *filep, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct uio_listener *listener = filep->private_data; + struct uio_device *idev = listener->dev; + ssize_t retval; + s32 irq_on; + + if (idev->info->irq == UIO_IRQ_NONE) + return -EIO; + + if (count != sizeof(s32)) + return -EINVAL; + + if (copy_from_user(&irq_on, buf, count)) + return -EFAULT; + + if (!idev->info->irqcontrol) + return -ENOSYS; + + retval = idev->info->irqcontrol(idev->info, irq_on); + + return retval ? retval : sizeof(s32); +} + static int uio_find_mem_index(struct vm_area_struct *vma) { int mi; @@ -539,6 +564,7 @@ .open = uio_open, .release = uio_release, .read = uio_read, + .write = uio_write, .mmap = uio_mmap, .poll = uio_poll, .fasync = uio_fasync, Index: linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl =================================================================== --- linux-2.6.26-rc.orig/Documentation/DocBook/uio-howto.tmpl 2008-05-22 20:22:57.000000000 +0200 +++ linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl 2008-05-22 20:23:12.000000000 +0200 @@ -30,6 +30,12 @@ <revhistory> <revision> + <revnumber>0.5</revnumber> + <date>2008-05-22</date> + <authorinitials>hjk</authorinitials> + <revremark>Added description of write() function.</revremark> + </revision> + <revision> <revnumber>0.4</revnumber> <date>2007-11-26</date> <authorinitials>hjk</authorinitials> @@ -64,7 +70,7 @@ <?dbhtml filename="copyright.html"?> <title>Copyright and License</title> <para> - Copyright (c) 2006 by Hans-JÃŒrgen Koch.</para> + Copyright (c) 2006-2008 by Hans-JÃŒrgen Koch.</para> <para> This documentation is Free Software licensed under the terms of the GPL version 2. @@ -189,6 +195,30 @@ represents the total interrupt count. You can use this number to figure out if you missed some interrupts. </para> + <para> + For some hardware that has more than one interrupt source internally, + but not seperate IRQ mask and status registers, there might be + situations where userspace cannot determine what the interrupt source + was if the kernel handler disables them by writing to the chip's IRQ + register. In such a case, the kernel has to disable the IRQ completely + to leave the chip's register untouched. Now the userspace part can + determine the cause of the interrupt, but it cannot re-enable + interrupts. Another cornercase are chips where re-enabling interrupts + is a read-modify-write operation to a combined IRQ status/acknowledge + register. This would be racy if a new interrupt occured + simultaneously. + </para> + <para> + To address these problems, UIO also implements a write() function. It + is normally not used and can be ignored for hardware that has only a + single interrupt source or has seperate IRQ mask and status registers. + If you need it, however, a write to <filename>/dev/uioX</filename> + will call the <function>irqcontrol()</function> function implemented + by the driver. You have to write a 32-bit value that is usually either + 0 or 1 do disable or enable interrupts. If a driver does not implement + <function>irqcontrol()</function>, <function>write()</function> will + return with <varname>-ENOSYS</varname>. + </para> <para> To handle interrupts properly, your custom kernel module can @@ -362,6 +392,14 @@ <function>open()</function>, you will probably also want a custom <function>release()</function> function. </para></listitem> + +<listitem><para> +<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on) +</varname>: Optional. If you need to be able to enable or disable +interrupts from userspace by writing to <filename>/dev/uioX</filename>, +you can implement this function. The parameter <varname>irq_on</varname> +will be 0 to disable interrupts and 1 to enable them. +</para></listitem> </itemizedlist> <para> ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-22 19:26 ` [PATCH 1/1] " Hans J. Koch @ 2008-05-22 19:47 ` Tom Spink 2008-05-22 20:08 ` Hans J. Koch 2008-05-23 5:55 ` Uwe Kleine-König 1 sibling, 1 reply; 34+ messages in thread From: Tom Spink @ 2008-05-22 19:47 UTC (permalink / raw) To: Hans J. Koch Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Uwe Kleine-König, Magnus Damm 2008/5/22 Hans J. Koch <hjk@linutronix.de>: > Sometimes it is necessary to enable/disable the interrupt of a UIO device > from the userspace part of the driver. With this patch, the UIO kernel driver > can implement an "irqcontrol()" function that does this. Userspace can write > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The > UIO core will then call the driver's irqcontrol function. > > Signed-off-by: Hans J. Koch <hjk@linutronix.de> <snip> Hi, I wonder if it would be better to implement this as an ioctl, rather than a write to the device. Writing to a device is a pretty generic thing, and this patch would tie that up to specifically controlling interrupts. An ioctl would be more appropriate, IMO, as you are issuing a controlling command, i.e. disable or enable interrupts. By the way, I have absolutely no idea how the UIO driver works, other than reading http://lwn.net/Articles/232575/ -- Tom Spink ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-22 19:47 ` Tom Spink @ 2008-05-22 20:08 ` Hans J. Koch 2008-05-22 20:26 ` Tom Spink 0 siblings, 1 reply; 34+ messages in thread From: Hans J. Koch @ 2008-05-22 20:08 UTC (permalink / raw) To: Tom Spink Cc: Hans J. Koch, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Uwe Kleine-König, Magnus Damm On Thu, May 22, 2008 at 08:47:16PM +0100, Tom Spink wrote: Hi Tom, > 2008/5/22 Hans J. Koch <hjk@linutronix.de>: > > Sometimes it is necessary to enable/disable the interrupt of a UIO device > > from the userspace part of the driver. With this patch, the UIO kernel driver > > can implement an "irqcontrol()" function that does this. Userspace can write > > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The > > UIO core will then call the driver's irqcontrol function. > > > > Signed-off-by: Hans J. Koch <hjk@linutronix.de> > > <snip> > > Hi, > > I wonder if it would be better to implement this as an ioctl, No way. We don't want to introduce new ioctls. > rather > than a write to the device. Writing to a device is a pretty generic > thing, and this patch would tie that up to specifically controlling > interrupts. UIO userspace drivers do their whole work by accessing the device's memory directly. The purpose of the kernel part is mainly 1) allow this memory to be mapped 2) handle interrupts We have an mmap() implementation for 1) and a read() implementation to wait for interrupts. Now we add write to enable/disable interrupts, which completes 2). Looks clean to me. > An ioctl would be more appropriate, IMO, as you are > issuing a controlling command, i.e. disable or enable interrupts. > > By the way, I have absolutely no idea how the UIO driver works, other > than reading http://lwn.net/Articles/232575/ You could read the docs that come with the kernel sources: Documentation/DocBook/uio_howto Thanks, Hans ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-22 20:08 ` Hans J. Koch @ 2008-05-22 20:26 ` Tom Spink 2008-05-23 5:41 ` Uwe Kleine-König 0 siblings, 1 reply; 34+ messages in thread From: Tom Spink @ 2008-05-22 20:26 UTC (permalink / raw) To: Hans J. Koch Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Uwe Kleine-König, Magnus Damm 2008/5/22 Hans J. Koch <hjk@linutronix.de>: > On Thu, May 22, 2008 at 08:47:16PM +0100, Tom Spink wrote: > > Hi Tom, > >> 2008/5/22 Hans J. Koch <hjk@linutronix.de>: >> > Sometimes it is necessary to enable/disable the interrupt of a UIO device >> > from the userspace part of the driver. With this patch, the UIO kernel driver >> > can implement an "irqcontrol()" function that does this. Userspace can write >> > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The >> > UIO core will then call the driver's irqcontrol function. >> > >> > Signed-off-by: Hans J. Koch <hjk@linutronix.de> >> >> <snip> >> >> Hi, >> >> I wonder if it would be better to implement this as an ioctl, > > No way. We don't want to introduce new ioctls. Why not? A typical usage scenario would then be: fd = open("/dev/uio0", O_RDONLY); ... ioctl(fd, UIO_IOC_SETIRQ, 0); ... ioctl(fd, UIO_IOC_SETIRQ, 1); ... close(fd); The added benefit is that the code becomes less complex, as you don't have to check buffer sizes and copy the integer from userspace. You just implement an ioctl handle on the uio char device, reducing the code to something like this (not compiled or tested in any way, and missing the definition of UIO_IOC_SETIRQ): diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 55cc7b8..9edc7c0 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -534,11 +534,31 @@ static int uio_mmap(struct file *filep, struct vm_area_struct *vma) } } +static int uio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct uio_listener *listener = filp->private_data; + struct uio_device *idev = listener->dev; + + switch (cmd) { + case UIO_IOC_SETIRQ: + if (idev->info->irq == UIO_IRQ_NONE) + return -EIO; + + if (idev->info->irqcontrol) + return idev->info->irqcontrol(idev->info, arg); + else + return -ENOSYS; + } + + return -ENOTTY; +} + static const struct file_operations uio_fops = { .owner = THIS_MODULE, .open = uio_open, .release = uio_release, .read = uio_read, + .ioctl = uio_ioctl, .mmap = uio_mmap, .poll = uio_poll, .fasync = uio_fasync, > >> rather >> than a write to the device. Writing to a device is a pretty generic >> thing, and this patch would tie that up to specifically controlling >> interrupts. > > UIO userspace drivers do their whole work by accessing the device's > memory directly. The purpose of the kernel part is mainly > > 1) allow this memory to be mapped > 2) handle interrupts > > We have an mmap() implementation for 1) and a read() implementation to > wait for interrupts. Now we add write to enable/disable interrupts, > which completes 2). Looks clean to me. Okay, I understand that. Fair point, but what happens if later write needs to do something else? > >> An ioctl would be more appropriate, IMO, as you are >> issuing a controlling command, i.e. disable or enable interrupts. >> >> By the way, I have absolutely no idea how the UIO driver works, other >> than reading http://lwn.net/Articles/232575/ > > You could read the docs that come with the kernel sources: > Documentation/DocBook/uio_howto Thanks! That document certainly helps. > Thanks, > Hans -- Tom Spink ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-22 20:26 ` Tom Spink @ 2008-05-23 5:41 ` Uwe Kleine-König 2008-05-23 8:51 ` Hans J. Koch 2008-05-23 11:48 ` Tom Spink 0 siblings, 2 replies; 34+ messages in thread From: Uwe Kleine-König @ 2008-05-23 5:41 UTC (permalink / raw) To: Tom Spink Cc: Hans J. Koch, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Hello Tom, Tom Spink wrote: > The added benefit is that the code becomes less complex, as you don't > have to check buffer sizes and copy the integer from userspace. AFAIK this is wrong. You need to copy the integer from userspace in uio_ioctl. Actually it's a value coming from user space, so you need to do it somewhere. Best regards Uwe -- Uwe Kleine-König, Software Engineer Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 5:41 ` Uwe Kleine-König @ 2008-05-23 8:51 ` Hans J. Koch 2008-05-23 11:48 ` Tom Spink 1 sibling, 0 replies; 34+ messages in thread From: Hans J. Koch @ 2008-05-23 8:51 UTC (permalink / raw) To: Uwe Kleine-König Cc: Tom Spink, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Am Fri, 23 May 2008 07:41:15 +0200 schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > Hello Tom, > > Tom Spink wrote: > > The added benefit is that the code becomes less complex, as you > > don't have to check buffer sizes and copy the integer from > > userspace. > AFAIK this is wrong. You need to copy the integer from userspace in > uio_ioctl. Actually it's a value coming from user space, so you need > to do it somewhere. True. Also note that this is not type-safe. All ioctl calls blindly trust userspace to pass in correct data. This has to be tolerated for ancient well-known filesystem ioctls, because you'd break almost all of userspace if you changed that, but we certainly don't want to add new stuff to this mess. Thanks, Hans ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 5:41 ` Uwe Kleine-König 2008-05-23 8:51 ` Hans J. Koch @ 2008-05-23 11:48 ` Tom Spink 2008-05-23 11:58 ` Uwe Kleine-König 1 sibling, 1 reply; 34+ messages in thread From: Tom Spink @ 2008-05-23 11:48 UTC (permalink / raw) To: Uwe Kleine-König Cc: Hans J. Koch, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm 2008/5/23 Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > Hello Tom, Hi Uwe, > Tom Spink wrote: >> The added benefit is that the code becomes less complex, as you don't >> have to check buffer sizes and copy the integer from userspace. > AFAIK this is wrong. You need to copy the integer from userspace in > uio_ioctl. Actually it's a value coming from user space, so you need to > do it somewhere. Not really in this case. It's not a *pointer* to a value in userspace, so you don't need to copy anything. If it was being used to point to a memory location holding a value, then yes, it would need to be copied across. But in this case, it's just being used to pass across 1 or 0. For example, look at the drivers/char/tty_ioctl.c file, and see how they use arg as a simple value. arg doesn't have to be a pointer to userspace. > Best regards > Uwe -- Tom Spink ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 11:48 ` Tom Spink @ 2008-05-23 11:58 ` Uwe Kleine-König 2008-05-23 12:00 ` Tom Spink 0 siblings, 1 reply; 34+ messages in thread From: Uwe Kleine-König @ 2008-05-23 11:58 UTC (permalink / raw) To: Tom Spink Cc: Hans J. Koch, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Hello Tom, > > Tom Spink wrote: > >> The added benefit is that the code becomes less complex, as you don't > >> have to check buffer sizes and copy the integer from userspace. > > AFAIK this is wrong. You need to copy the integer from userspace in > > uio_ioctl. Actually it's a value coming from user space, so you need to > > do it somewhere. > > Not really in this case. It's not a *pointer* to a value in > userspace, so you don't need to copy anything. If it was being used > to point to a memory location holding a value, then yes, it would need > to be copied across. But in this case, it's just being used to pass > across 1 or 0. ah, OK, you're right. Thanks for correcting my correction :-) Uwe -- Uwe Kleine-König, Software Engineer Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 11:58 ` Uwe Kleine-König @ 2008-05-23 12:00 ` Tom Spink 2008-05-23 12:14 ` Hans J. Koch 0 siblings, 1 reply; 34+ messages in thread From: Tom Spink @ 2008-05-23 12:00 UTC (permalink / raw) To: Uwe Kleine-König Cc: Hans J. Koch, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm 2008/5/23 Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > Hello Tom, > >> > Tom Spink wrote: >> >> The added benefit is that the code becomes less complex, as you don't >> >> have to check buffer sizes and copy the integer from userspace. >> > AFAIK this is wrong. You need to copy the integer from userspace in >> > uio_ioctl. Actually it's a value coming from user space, so you need to >> > do it somewhere. >> >> Not really in this case. It's not a *pointer* to a value in >> userspace, so you don't need to copy anything. If it was being used >> to point to a memory location holding a value, then yes, it would need >> to be copied across. But in this case, it's just being used to pass >> across 1 or 0. > ah, OK, you're right. Thanks for correcting my correction :-) Heh, no problem. My initial idea was just a thought anyway, just to maintain a bit of extensibility if .write is ever needed for something else. :-) > Uwe -- Tom Spink ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 12:00 ` Tom Spink @ 2008-05-23 12:14 ` Hans J. Koch 2008-05-23 12:20 ` Tom Spink 0 siblings, 1 reply; 34+ messages in thread From: Hans J. Koch @ 2008-05-23 12:14 UTC (permalink / raw) To: Tom Spink Cc: Uwe Kleine-König, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Am Fri, 23 May 2008 13:00:17 +0100 schrieb "Tom Spink" <tspink@gmail.com>: > My initial idea was just a thought anyway, just to > maintain a bit of extensibility if .write is ever needed for something > else. :-) Hi Tom, thanks for your contribution, but for me it's just the other way round: I'm glad write() gets a defined purpose before people do something stupid with it. It's good to remember that all data exchange with the device has to be done through the mapped memory. If this is not possible, the hardware is no candidate for a UIO driver. BTW, I wait for the first UIO driver which abuses this write() function to write many different values to trigger different actions. I wonder if I should restrict write() to the value 0 and 1... Thanks, Hans ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 12:14 ` Hans J. Koch @ 2008-05-23 12:20 ` Tom Spink 2008-05-23 13:01 ` Hans J. Koch 0 siblings, 1 reply; 34+ messages in thread From: Tom Spink @ 2008-05-23 12:20 UTC (permalink / raw) To: Hans J. Koch Cc: Uwe Kleine-König, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm 2008/5/23 Hans J. Koch <hjk@linutronix.de>: > Am Fri, 23 May 2008 13:00:17 +0100 > schrieb "Tom Spink" <tspink@gmail.com>: > >> My initial idea was just a thought anyway, just to >> maintain a bit of extensibility if .write is ever needed for something >> else. :-) > > Hi Tom, > thanks for your contribution, but for me it's just the other way round: > I'm glad write() gets a defined purpose before people do something > stupid with it. It's good to remember that all data exchange with the > device has to be done through the mapped memory. If this is not > possible, the hardware is no candidate for a UIO driver. > > BTW, I wait for the first UIO driver which abuses this write() > function to write many different values to trigger different actions. > I wonder if I should restrict write() to the value 0 and 1... > > Thanks, > Hans Hi Hans, Thanks for your explanation. Another thing, I noticed then, is that in your return statement, you blindly return the the value of irqcontrol if it's non-zero, and if it's zero, then the length of the data written. However, if irqcontrol returns a value that's > 0, it could potentially confuse writers. I guess it's up to the implementer of irqcontrol to ensure they stick to -EXXX and 0, but it's just a thought (while you were on the subject of input validation!) -- Tom Spink ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 12:20 ` Tom Spink @ 2008-05-23 13:01 ` Hans J. Koch 0 siblings, 0 replies; 34+ messages in thread From: Hans J. Koch @ 2008-05-23 13:01 UTC (permalink / raw) To: Tom Spink Cc: Uwe Kleine-König, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Am Fri, 23 May 2008 13:20:50 +0100 schrieb "Tom Spink" <tspink@gmail.com>: > 2008/5/23 Hans J. Koch <hjk@linutronix.de>: > > Am Fri, 23 May 2008 13:00:17 +0100 > > schrieb "Tom Spink" <tspink@gmail.com>: > > > >> My initial idea was just a thought anyway, just to > >> maintain a bit of extensibility if .write is ever needed for > >> something else. :-) > > > > Hi Tom, > > thanks for your contribution, but for me it's just the other way > > round: I'm glad write() gets a defined purpose before people do > > something stupid with it. It's good to remember that all data > > exchange with the device has to be done through the mapped memory. > > If this is not possible, the hardware is no candidate for a UIO > > driver. > > > > BTW, I wait for the first UIO driver which abuses this write() > > function to write many different values to trigger different > > actions. I wonder if I should restrict write() to the value 0 and > > 1... > > > > Thanks, > > Hans > > Hi Hans, > > Thanks for your explanation. Another thing, I noticed then, is that > in your return statement, you blindly return the the value of > irqcontrol if it's non-zero, and if it's zero, then the length of the > data written. However, if irqcontrol returns a value that's > 0, it > could potentially confuse writers. I guess it's up to the implementer > of irqcontrol to ensure they stick to -EXXX and 0 True. And it's not even worth fixing this by checking retval<0, because if irqcontrol returns values>0, it's broken anyway. It is supposed to return zero if successful, and negative errors otherwise. This is common practice in the kernel, and people frequently use if (ret)... to detect errors without checking if ret is a legal negative error number. Thanks, Hans ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-22 19:26 ` [PATCH 1/1] " Hans J. Koch 2008-05-22 19:47 ` Tom Spink @ 2008-05-23 5:55 ` Uwe Kleine-König 2008-05-23 8:44 ` Hans J. Koch 1 sibling, 1 reply; 34+ messages in thread From: Uwe Kleine-König @ 2008-05-23 5:55 UTC (permalink / raw) To: Hans J. Koch Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Hello Hans, > - Copyright (c) 2006 by Hans-JÃŒrgen Koch.</para> > + Copyright (c) 2006-2008 by Hans-JÃŒrgen Koch.</para> This looks wrong. ukleinek@zentaur:~$ echo Hans-JÃŒrgen | iconv -t ISO8859-15 Hans-Jürgen Best regards Uwe -- Uwe Kleine-König, Software Engineer Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 5:55 ` Uwe Kleine-König @ 2008-05-23 8:44 ` Hans J. Koch 2008-05-23 9:10 ` Uwe Kleine-König 0 siblings, 1 reply; 34+ messages in thread From: Hans J. Koch @ 2008-05-23 8:44 UTC (permalink / raw) To: Uwe Kleine-König Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Am Fri, 23 May 2008 07:55:27 +0200 schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > Hello Hans, > > > - Copyright (c) 2006 by Hans-JÃŒrgen Koch.</para> > > + Copyright (c) 2006-2008 by Hans-JÃŒrgen Koch.</para> > This looks wrong. DocBook XML is supposed to be UTF-8. Thanks, Hans > > ukleinek@zentaur:~$ echo Hans-JÃŒrgen | iconv -t ISO8859-15 > Hans-Jürgen > > Best regards > Uwe > ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 8:44 ` Hans J. Koch @ 2008-05-23 9:10 ` Uwe Kleine-König 2008-05-23 10:03 ` Hans J. Koch 0 siblings, 1 reply; 34+ messages in thread From: Uwe Kleine-König @ 2008-05-23 9:10 UTC (permalink / raw) To: Hans J. Koch Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Hans J. Koch wrote: > Am Fri, 23 May 2008 07:55:27 +0200 > schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > > > Hello Hans, > > > > > - Copyright (c) 2006 by Hans-JÃŒrgen Koch.</para> > > > + Copyright (c) 2006-2008 by Hans-JÃŒrgen Koch.</para> > > This looks wrong. > > DocBook XML is supposed to be UTF-8. Correct. But still the problem is real. The headers of your mail claim the content to be encoded in UTF-8, but actually it's latin1. So I cannot apply the patch you sent with git am without hand editing. Best regards Uwe -- Uwe Kleine-König, Software Engineer Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 9:10 ` Uwe Kleine-König @ 2008-05-23 10:03 ` Hans J. Koch 2008-05-23 10:56 ` Uwe Kleine-König 0 siblings, 1 reply; 34+ messages in thread From: Hans J. Koch @ 2008-05-23 10:03 UTC (permalink / raw) To: Uwe Kleine-König Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Am Fri, 23 May 2008 11:10:09 +0200 schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > Hans J. Koch wrote: > > Am Fri, 23 May 2008 07:55:27 +0200 > > schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > > > > > Hello Hans, > > > > > > > - Copyright (c) 2006 by Hans-JÃŒrgen Koch.</para> > > > > + Copyright (c) 2006-2008 by Hans-JÃŒrgen Koch.</para> > > > This looks wrong. > > > > DocBook XML is supposed to be UTF-8. > Correct. But still the problem is real. The headers of your mail > claim the content to be encoded in UTF-8, but actually it's latin1. > So I cannot apply the patch you sent with git am without hand editing. Try the version below. Thanks, Hans > > Best regards > Uwe > From: Hans J. Koch <hjk@linutronix.de> To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@suse.de>, Jan Altenberg <jan.altenberg@linutronix.de>, Thomas Gleixner <tglx@linutronix.de>, Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>, Magnus Damm <magnus.damm@gmail.com> Subject: UIO: Add write function to allow irq masking Date: Thu, 22 May 2008 20:43:09 +0200 Sometimes it is necessary to enable/disable the interrupt of a UIO device from the userspace part of the driver. With this patch, the UIO kernel driver can implement an "irqcontrol()" function that does this. Userspace can write an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The UIO core will then call the driver's irqcontrol function. Signed-off-by: Hans J. Koch <hjk@linutronix.de> --- Documentation/DocBook/uio-howto.tmpl | 40 ++++++++++++++++++++++++++++++++++- drivers/uio/uio.c | 26 ++++++++++++++++++++++ include/linux/uio_driver.h | 2 + 3 files changed, 67 insertions(+), 1 deletion(-) Index: linux-2.6.26-rc/include/linux/uio_driver.h =================================================================== --- linux-2.6.26-rc.orig/include/linux/uio_driver.h 2008-05-22 20:22:57.000000000 +0200 +++ linux-2.6.26-rc/include/linux/uio_driver.h 2008-05-22 20:23:12.000000000 +0200 @@ -53,6 +53,7 @@ * @mmap: mmap operation for this uio device * @open: open operation for this uio device * @release: release operation for this uio device + * @irqcontrol: disable/enable irqs when 0/1 is written to /dev/uioX */ struct uio_info { struct uio_device *uio_dev; @@ -66,6 +67,7 @@ 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); + int (*irqcontrol)(struct uio_info *info, s32 irq_on); }; extern int __must_check Index: linux-2.6.26-rc/drivers/uio/uio.c =================================================================== --- linux-2.6.26-rc.orig/drivers/uio/uio.c 2008-05-22 20:23:07.000000000 +0200 +++ linux-2.6.26-rc/drivers/uio/uio.c 2008-05-22 20:23:12.000000000 +0200 @@ -420,6 +420,31 @@ return retval; } +static ssize_t uio_write(struct file *filep, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct uio_listener *listener = filep->private_data; + struct uio_device *idev = listener->dev; + ssize_t retval; + s32 irq_on; + + if (idev->info->irq == UIO_IRQ_NONE) + return -EIO; + + if (count != sizeof(s32)) + return -EINVAL; + + if (copy_from_user(&irq_on, buf, count)) + return -EFAULT; + + if (!idev->info->irqcontrol) + return -ENOSYS; + + retval = idev->info->irqcontrol(idev->info, irq_on); + + return retval ? retval : sizeof(s32); +} + static int uio_find_mem_index(struct vm_area_struct *vma) { int mi; @@ -539,6 +564,7 @@ .open = uio_open, .release = uio_release, .read = uio_read, + .write = uio_write, .mmap = uio_mmap, .poll = uio_poll, .fasync = uio_fasync, Index: linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl =================================================================== --- linux-2.6.26-rc.orig/Documentation/DocBook/uio-howto.tmpl 2008-05-22 20:22:57.000000000 +0200 +++ linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl 2008-05-23 11:57:23.000000000 +0200 @@ -30,6 +30,12 @@ <revhistory> <revision> + <revnumber>0.5</revnumber> + <date>2008-05-22</date> + <authorinitials>hjk</authorinitials> + <revremark>Added description of write() function.</revremark> + </revision> + <revision> <revnumber>0.4</revnumber> <date>2007-11-26</date> <authorinitials>hjk</authorinitials> @@ -64,7 +70,7 @@ <?dbhtml filename="copyright.html"?> <title>Copyright and License</title> <para> - Copyright (c) 2006 by Hans-Jürgen Koch.</para> + Copyright (c) 2006-2008 by Hans-Jürgen Koch.</para> <para> This documentation is Free Software licensed under the terms of the GPL version 2. @@ -189,6 +195,30 @@ represents the total interrupt count. You can use this number to figure out if you missed some interrupts. </para> + <para> + For some hardware that has more than one interrupt source internally, + but not seperate IRQ mask and status registers, there might be + situations where userspace cannot determine what the interrupt source + was if the kernel handler disables them by writing to the chip's IRQ + register. In such a case, the kernel has to disable the IRQ completely + to leave the chip's register untouched. Now the userspace part can + determine the cause of the interrupt, but it cannot re-enable + interrupts. Another cornercase are chips where re-enabling interrupts + is a read-modify-write operation to a combined IRQ status/acknowledge + register. This would be racy if a new interrupt occured + simultaneously. + </para> + <para> + To address these problems, UIO also implements a write() function. It + is normally not used and can be ignored for hardware that has only a + single interrupt source or has seperate IRQ mask and status registers. + If you need it, however, a write to <filename>/dev/uioX</filename> + will call the <function>irqcontrol()</function> function implemented + by the driver. You have to write a 32-bit value that is usually either + 0 or 1 do disable or enable interrupts. If a driver does not implement + <function>irqcontrol()</function>, <function>write()</function> will + return with <varname>-ENOSYS</varname>. + </para> <para> To handle interrupts properly, your custom kernel module can @@ -362,6 +392,14 @@ <function>open()</function>, you will probably also want a custom <function>release()</function> function. </para></listitem> + +<listitem><para> +<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on) +</varname>: Optional. If you need to be able to enable or disable +interrupts from userspace by writing to <filename>/dev/uioX</filename>, +you can implement this function. The parameter <varname>irq_on</varname> +will be 0 to disable interrupts and 1 to enable them. +</para></listitem> </itemizedlist> <para> ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 10:03 ` Hans J. Koch @ 2008-05-23 10:56 ` Uwe Kleine-König 2008-05-23 11:55 ` Hans J. Koch 0 siblings, 1 reply; 34+ messages in thread From: Uwe Kleine-König @ 2008-05-23 10:56 UTC (permalink / raw) To: Hans J. Koch Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Hello Hans, Hans J. Koch wrote: > Am Fri, 23 May 2008 11:10:09 +0200 > schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > > > Hans J. Koch wrote: > > > Am Fri, 23 May 2008 07:55:27 +0200 > > > schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > > > > > > > Hello Hans, > > > > > > > > > - Copyright (c) 2006 by Hans-JÃŒrgen Koch.</para> > > > > > + Copyright (c) 2006-2008 by Hans-JÃŒrgen Koch.</para> > > > > This looks wrong. > > > > > > DocBook XML is supposed to be UTF-8. > > Correct. But still the problem is real. The headers of your mail > > claim the content to be encoded in UTF-8, but actually it's latin1. > > So I cannot apply the patch you sent with git am without hand editing. > > Try the version below. This one is better---I can apply it. > + if (copy_from_user(&irq_on, buf, count)) > + return -EFAULT; > + > + if (!idev->info->irqcontrol) > + return -ENOSYS; I would swap these two. copy_from_user is more expensive than testing idev->info->irqcontrol. (Is it really?) Anyhow only fetching a value from userspace if you really need it looks more clean to me. Otherwise the patch looks fine. Uwe -- Uwe Kleine-König, Software Engineer Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 10:56 ` Uwe Kleine-König @ 2008-05-23 11:55 ` Hans J. Koch 2008-05-23 12:03 ` Uwe Kleine-König ` (3 more replies) 0 siblings, 4 replies; 34+ messages in thread From: Hans J. Koch @ 2008-05-23 11:55 UTC (permalink / raw) To: Uwe Kleine-König Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Am Fri, 23 May 2008 12:56:04 +0200 schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > Hello Hans, > > Hans J. Koch wrote: > > Am Fri, 23 May 2008 11:10:09 +0200 > > schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > > > > > Hans J. Koch wrote: > > > > Am Fri, 23 May 2008 07:55:27 +0200 > > > > schrieb Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>: > > > > > > > > > Hello Hans, > > > > > > > > > > > - Copyright (c) 2006 by Hans-JÃŒrgen Koch.</para> > > > > > > + Copyright (c) 2006-2008 by Hans-JÃŒrgen Koch.</para> > > > > > This looks wrong. > > > > > > > > DocBook XML is supposed to be UTF-8. > > > Correct. But still the problem is real. The headers of your mail > > > claim the content to be encoded in UTF-8, but actually it's > > > latin1. So I cannot apply the patch you sent with git am without > > > hand editing. > > > > Try the version below. > This one is better---I can apply it. OK. Was a problem with my mail client. > > > + if (copy_from_user(&irq_on, buf, count)) > > + return -EFAULT; > > + > > + if (!idev->info->irqcontrol) > > + return -ENOSYS; > I would swap these two. copy_from_user is more expensive than testing > idev->info->irqcontrol. (Is it really?) Anyhow only fetching a value > from userspace if you really need it looks more clean to me. Agreed. See updated version below. > > Otherwise the patch looks fine. Thanks for your review! Could you add your Signed-off-by? Hans From: Hans J. Koch <hjk@linutronix.de> To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@suse.de>, Jan Altenberg <jan.altenberg@linutronix.de>, Thomas Gleixner <tglx@linutronix.de>, Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>, Magnus Damm <magnus.damm@gmail.com> Subject: UIO: Add write function to allow irq masking Date: Thu, Fri, 23 May 2008 13:50:14 +0200 Sometimes it is necessary to enable/disable the interrupt of a UIO device from the userspace part of the driver. With this patch, the UIO kernel driver can implement an "irqcontrol()" function that does this. Userspace can write an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The UIO core will then call the driver's irqcontrol function. Signed-off-by: Hans J. Koch <hjk@linutronix.de> --- Documentation/DocBook/uio-howto.tmpl | 40 ++++++++++++++++++++++++++++++++++- drivers/uio/uio.c | 26 ++++++++++++++++++++++ include/linux/uio_driver.h | 2 + 3 files changed, 67 insertions(+), 1 deletion(-) Index: linux-2.6.26-rc/include/linux/uio_driver.h =================================================================== --- linux-2.6.26-rc.orig/include/linux/uio_driver.h 2008-05-22 20:22:57.000000000 +0200 +++ linux-2.6.26-rc/include/linux/uio_driver.h 2008-05-22 20:23:12.000000000 +0200 @@ -53,6 +53,7 @@ * @mmap: mmap operation for this uio device * @open: open operation for this uio device * @release: release operation for this uio device + * @irqcontrol: disable/enable irqs when 0/1 is written to /dev/uioX */ struct uio_info { struct uio_device *uio_dev; @@ -66,6 +67,7 @@ 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); + int (*irqcontrol)(struct uio_info *info, s32 irq_on); }; extern int __must_check Index: linux-2.6.26-rc/drivers/uio/uio.c =================================================================== --- linux-2.6.26-rc.orig/drivers/uio/uio.c 2008-05-22 20:23:07.000000000 +0200 +++ linux-2.6.26-rc/drivers/uio/uio.c 2008-05-23 13:49:40.000000000 +0200 @@ -420,6 +420,31 @@ return retval; } +static ssize_t uio_write(struct file *filep, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct uio_listener *listener = filep->private_data; + struct uio_device *idev = listener->dev; + ssize_t retval; + s32 irq_on; + + if (idev->info->irq == UIO_IRQ_NONE) + return -EIO; + + if (count != sizeof(s32)) + return -EINVAL; + + if (!idev->info->irqcontrol) + return -ENOSYS; + + if (copy_from_user(&irq_on, buf, count)) + return -EFAULT; + + retval = idev->info->irqcontrol(idev->info, irq_on); + + return retval ? retval : sizeof(s32); +} + static int uio_find_mem_index(struct vm_area_struct *vma) { int mi; @@ -539,6 +564,7 @@ .open = uio_open, .release = uio_release, .read = uio_read, + .write = uio_write, .mmap = uio_mmap, .poll = uio_poll, .fasync = uio_fasync, Index: linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl =================================================================== --- linux-2.6.26-rc.orig/Documentation/DocBook/uio-howto.tmpl 2008-05-22 20:22:57.000000000 +0200 +++ linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl 2008-05-23 11:57:23.000000000 +0200 @@ -30,6 +30,12 @@ <revhistory> <revision> + <revnumber>0.5</revnumber> + <date>2008-05-22</date> + <authorinitials>hjk</authorinitials> + <revremark>Added description of write() function.</revremark> + </revision> + <revision> <revnumber>0.4</revnumber> <date>2007-11-26</date> <authorinitials>hjk</authorinitials> @@ -64,7 +70,7 @@ <?dbhtml filename="copyright.html"?> <title>Copyright and License</title> <para> - Copyright (c) 2006 by Hans-Jürgen Koch.</para> + Copyright (c) 2006-2008 by Hans-Jürgen Koch.</para> <para> This documentation is Free Software licensed under the terms of the GPL version 2. @@ -189,6 +195,30 @@ represents the total interrupt count. You can use this number to figure out if you missed some interrupts. </para> + <para> + For some hardware that has more than one interrupt source internally, + but not seperate IRQ mask and status registers, there might be + situations where userspace cannot determine what the interrupt source + was if the kernel handler disables them by writing to the chip's IRQ + register. In such a case, the kernel has to disable the IRQ completely + to leave the chip's register untouched. Now the userspace part can + determine the cause of the interrupt, but it cannot re-enable + interrupts. Another cornercase are chips where re-enabling interrupts + is a read-modify-write operation to a combined IRQ status/acknowledge + register. This would be racy if a new interrupt occured + simultaneously. + </para> + <para> + To address these problems, UIO also implements a write() function. It + is normally not used and can be ignored for hardware that has only a + single interrupt source or has seperate IRQ mask and status registers. + If you need it, however, a write to <filename>/dev/uioX</filename> + will call the <function>irqcontrol()</function> function implemented + by the driver. You have to write a 32-bit value that is usually either + 0 or 1 do disable or enable interrupts. If a driver does not implement + <function>irqcontrol()</function>, <function>write()</function> will + return with <varname>-ENOSYS</varname>. + </para> <para> To handle interrupts properly, your custom kernel module can @@ -362,6 +392,14 @@ <function>open()</function>, you will probably also want a custom <function>release()</function> function. </para></listitem> + +<listitem><para> +<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on) +</varname>: Optional. If you need to be able to enable or disable +interrupts from userspace by writing to <filename>/dev/uioX</filename>, +you can implement this function. The parameter <varname>irq_on</varname> +will be 0 to disable interrupts and 1 to enable them. +</para></listitem> </itemizedlist> <para> ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 11:55 ` Hans J. Koch @ 2008-05-23 12:03 ` Uwe Kleine-König 2008-05-23 18:36 ` Randy Dunlap ` (2 subsequent siblings) 3 siblings, 0 replies; 34+ messages in thread From: Uwe Kleine-König @ 2008-05-23 12:03 UTC (permalink / raw) To: Hans J. Koch Cc: linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Hello Hans, > > Otherwise the patch looks fine. > > Thanks for your review! Could you add your Signed-off-by? I don't consider my feed back valueable enough for a Signed-off-by, but you can get an ... > From: Hans J. Koch <hjk@linutronix.de> > To: linux-kernel@vger.kernel.org > Cc: Greg Kroah-Hartman <gregkh@suse.de>, > Jan Altenberg <jan.altenberg@linutronix.de>, > Thomas Gleixner <tglx@linutronix.de>, > Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>, > Magnus Damm <magnus.damm@gmail.com> > Subject: UIO: Add write function to allow irq masking > Date: Thu, Fri, 23 May 2008 13:50:14 +0200 > > Sometimes it is necessary to enable/disable the interrupt of a UIO device > from the userspace part of the driver. With this patch, the UIO kernel driver > can implement an "irqcontrol()" function that does this. Userspace can write > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The > UIO core will then call the driver's irqcontrol function. > > Signed-off-by: Hans J. Koch <hjk@linutronix.de> Acked-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>, Best regards Uwe ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 11:55 ` Hans J. Koch 2008-05-23 12:03 ` Uwe Kleine-König @ 2008-05-23 18:36 ` Randy Dunlap 2008-05-23 22:49 ` Hans-Jürgen Koch 2008-05-23 20:44 ` Leon Woestenberg 2008-05-24 4:43 ` Greg KH 3 siblings, 1 reply; 34+ messages in thread From: Randy Dunlap @ 2008-05-23 18:36 UTC (permalink / raw) To: Hans J. Koch Cc: Uwe Kleine-König, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm On Fri, 23 May 2008 13:55:57 +0200 Hans J. Koch wrote: > Documentation/DocBook/uio-howto.tmpl | 40 ++++++++++++++++++++++++++++++++++- > drivers/uio/uio.c | 26 ++++++++++++++++++++++ > include/linux/uio_driver.h | 2 + > 3 files changed, 67 insertions(+), 1 deletion(-) > > Index: linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl > =================================================================== > --- linux-2.6.26-rc.orig/Documentation/DocBook/uio-howto.tmpl 2008-05-22 20:22:57.000000000 +0200 > +++ linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl 2008-05-23 11:57:23.000000000 +0200 > @@ -30,6 +30,12 @@ > > <revhistory> > <revision> > + <revnumber>0.5</revnumber> > + <date>2008-05-22</date> > + <authorinitials>hjk</authorinitials> > + <revremark>Added description of write() function.</revremark> > + </revision> > + <revision> > <revnumber>0.4</revnumber> > <date>2007-11-26</date> > <authorinitials>hjk</authorinitials> > @@ -64,7 +70,7 @@ > <?dbhtml filename="copyright.html"?> > <title>Copyright and License</title> > <para> > - Copyright (c) 2006 by Hans-Jürgen Koch.</para> > + Copyright (c) 2006-2008 by Hans-Jürgen Koch.</para> > <para> > This documentation is Free Software licensed under the terms of the > GPL version 2. > @@ -189,6 +195,30 @@ > represents the total interrupt count. You can use this number > to figure out if you missed some interrupts. > </para> > + <para> > + For some hardware that has more than one interrupt source internally, > + but not seperate IRQ mask and status registers, there might be separate > + situations where userspace cannot determine what the interrupt source > + was if the kernel handler disables them by writing to the chip's IRQ > + register. In such a case, the kernel has to disable the IRQ completely > + to leave the chip's register untouched. Now the userspace part can > + determine the cause of the interrupt, but it cannot re-enable > + interrupts. Another cornercase are chips where re-enabling interrupts is > + is a read-modify-write operation to a combined IRQ status/acknowledge > + register. This would be racy if a new interrupt occured occurred > + simultaneously. > + </para> > + <para> > + To address these problems, UIO also implements a write() function. It > + is normally not used and can be ignored for hardware that has only a > + single interrupt source or has seperate IRQ mask and status registers. separate ["There's <a rat> in separate."] > + If you need it, however, a write to <filename>/dev/uioX</filename> > + will call the <function>irqcontrol()</function> function implemented > + by the driver. You have to write a 32-bit value that is usually either > + 0 or 1 do disable or enable interrupts. If a driver does not implement to > + <function>irqcontrol()</function>, <function>write()</function> will > + return with <varname>-ENOSYS</varname>. > + </para> --- ~Randy ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 18:36 ` Randy Dunlap @ 2008-05-23 22:49 ` Hans-Jürgen Koch 2008-06-04 6:30 ` Uwe Kleine-König 0 siblings, 1 reply; 34+ messages in thread From: Hans-Jürgen Koch @ 2008-05-23 22:49 UTC (permalink / raw) To: Randy Dunlap Cc: Uwe Kleine-König, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Am Fri, 23 May 2008 11:36:50 -0700 schrieb Randy Dunlap <randy.dunlap@oracle.com>: > > > + For some hardware that has more than one interrupt source internally, > > + but not seperate IRQ mask and status registers, there might be > > separate > > > + situations where userspace cannot determine what the interrupt source > > + was if the kernel handler disables them by writing to the chip's IRQ > > + register. In such a case, the kernel has to disable the IRQ completely > > + to leave the chip's register untouched. Now the userspace part can > > + determine the cause of the interrupt, but it cannot re-enable > > + interrupts. Another cornercase are chips where re-enabling interrupts > > is > > > + is a read-modify-write operation to a combined IRQ status/acknowledge > > + register. This would be racy if a new interrupt occured > > occurred > > > + simultaneously. > > + </para> > > + <para> > > + To address these problems, UIO also implements a write() function. It > > + is normally not used and can be ignored for hardware that has only a > > + single interrupt source or has seperate IRQ mask and status registers. > > separate > ["There's <a rat> in separate."] I'll certainly remember that one :-) > > > + If you need it, however, a write to <filename>/dev/uioX</filename> > > + will call the <function>irqcontrol()</function> function implemented > > + by the driver. You have to write a 32-bit value that is usually either > > + 0 or 1 do disable or enable interrupts. If a driver does not implement > > to > > > + <function>irqcontrol()</function>, <function>write()</function> will > > + return with <varname>-ENOSYS</varname>. > > + </para> > > --- > ~Randy Thanks a lot for reviewing this! Corrected patch below. Hans From: Hans J. Koch <hjk@linutronix.de> To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@suse.de>, Jan Altenberg <jan.altenberg@linutronix.de>, Thomas Gleixner <tglx@linutronix.de>, Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>, Magnus Damm <magnus.damm@gmail.com> Subject: UIO: Add write function to allow irq masking Date: Thu, Fri, 23 May 2008 13:50:14 +0200 Sometimes it is necessary to enable/disable the interrupt of a UIO device from the userspace part of the driver. With this patch, the UIO kernel driver can implement an "irqcontrol()" function that does this. Userspace can write an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The UIO core will then call the driver's irqcontrol function. Signed-off-by: Hans J. Koch <hjk@linutronix.de> --- Documentation/DocBook/uio-howto.tmpl | 40 ++++++++++++++++++++++++++++++++++- drivers/uio/uio.c | 26 ++++++++++++++++++++++ include/linux/uio_driver.h | 2 + 3 files changed, 67 insertions(+), 1 deletion(-) Index: linux-2.6.26-rc/include/linux/uio_driver.h =================================================================== --- linux-2.6.26-rc.orig/include/linux/uio_driver.h 2008-05-22 20:22:57.000000000 +0200 +++ linux-2.6.26-rc/include/linux/uio_driver.h 2008-05-22 20:23:12.000000000 +0200 @@ -53,6 +53,7 @@ * @mmap: mmap operation for this uio device * @open: open operation for this uio device * @release: release operation for this uio device + * @irqcontrol: disable/enable irqs when 0/1 is written to /dev/uioX */ struct uio_info { struct uio_device *uio_dev; @@ -66,6 +67,7 @@ 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); + int (*irqcontrol)(struct uio_info *info, s32 irq_on); }; extern int __must_check Index: linux-2.6.26-rc/drivers/uio/uio.c =================================================================== --- linux-2.6.26-rc.orig/drivers/uio/uio.c 2008-05-22 20:23:07.000000000 +0200 +++ linux-2.6.26-rc/drivers/uio/uio.c 2008-05-23 13:49:40.000000000 +0200 @@ -420,6 +420,31 @@ return retval; } +static ssize_t uio_write(struct file *filep, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct uio_listener *listener = filep->private_data; + struct uio_device *idev = listener->dev; + ssize_t retval; + s32 irq_on; + + if (idev->info->irq == UIO_IRQ_NONE) + return -EIO; + + if (count != sizeof(s32)) + return -EINVAL; + + if (!idev->info->irqcontrol) + return -ENOSYS; + + if (copy_from_user(&irq_on, buf, count)) + return -EFAULT; + + retval = idev->info->irqcontrol(idev->info, irq_on); + + return retval ? retval : sizeof(s32); +} + static int uio_find_mem_index(struct vm_area_struct *vma) { int mi; @@ -539,6 +564,7 @@ .open = uio_open, .release = uio_release, .read = uio_read, + .write = uio_write, .mmap = uio_mmap, .poll = uio_poll, .fasync = uio_fasync, Index: linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl =================================================================== --- linux-2.6.26-rc.orig/Documentation/DocBook/uio-howto.tmpl 2008-05-22 20:22:57.000000000 +0200 +++ linux-2.6.26-rc/Documentation/DocBook/uio-howto.tmpl 2008-05-24 00:33:48.000000000 +0200 @@ -30,6 +30,12 @@ <revhistory> <revision> + <revnumber>0.5</revnumber> + <date>2008-05-22</date> + <authorinitials>hjk</authorinitials> + <revremark>Added description of write() function.</revremark> + </revision> + <revision> <revnumber>0.4</revnumber> <date>2007-11-26</date> <authorinitials>hjk</authorinitials> @@ -64,7 +70,7 @@ <?dbhtml filename="copyright.html"?> <title>Copyright and License</title> <para> - Copyright (c) 2006 by Hans-Jürgen Koch.</para> + Copyright (c) 2006-2008 by Hans-Jürgen Koch.</para> <para> This documentation is Free Software licensed under the terms of the GPL version 2. @@ -189,6 +195,30 @@ represents the total interrupt count. You can use this number to figure out if you missed some interrupts. </para> + <para> + For some hardware that has more than one interrupt source internally, + but not separate IRQ mask and status registers, there might be + situations where userspace cannot determine what the interrupt source + was if the kernel handler disables them by writing to the chip's IRQ + register. In such a case, the kernel has to disable the IRQ completely + to leave the chip's register untouched. Now the userspace part can + determine the cause of the interrupt, but it cannot re-enable + interrupts. Another cornercase is chips where re-enabling interrupts + is a read-modify-write operation to a combined IRQ status/acknowledge + register. This would be racy if a new interrupt occurred + simultaneously. + </para> + <para> + To address these problems, UIO also implements a write() function. It + is normally not used and can be ignored for hardware that has only a + single interrupt source or has separate IRQ mask and status registers. + If you need it, however, a write to <filename>/dev/uioX</filename> + will call the <function>irqcontrol()</function> function implemented + by the driver. You have to write a 32-bit value that is usually either + 0 or 1 to disable or enable interrupts. If a driver does not implement + <function>irqcontrol()</function>, <function>write()</function> will + return with <varname>-ENOSYS</varname>. + </para> <para> To handle interrupts properly, your custom kernel module can @@ -362,6 +392,14 @@ <function>open()</function>, you will probably also want a custom <function>release()</function> function. </para></listitem> + +<listitem><para> +<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on) +</varname>: Optional. If you need to be able to enable or disable +interrupts from userspace by writing to <filename>/dev/uioX</filename>, +you can implement this function. The parameter <varname>irq_on</varname> +will be 0 to disable interrupts and 1 to enable them. +</para></listitem> </itemizedlist> <para> ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 22:49 ` Hans-Jürgen Koch @ 2008-06-04 6:30 ` Uwe Kleine-König 2008-06-04 7:05 ` Thomas Gleixner 0 siblings, 1 reply; 34+ messages in thread From: Uwe Kleine-König @ 2008-06-04 6:30 UTC (permalink / raw) To: Hans-Jürgen Koch Cc: Randy Dunlap, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Hello Hans-Jürgen, > Sometimes it is necessary to enable/disable the interrupt of a UIO device > from the userspace part of the driver. With this patch, the UIO kernel driver > can implement an "irqcontrol()" function that does this. Userspace can write > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The > UIO core will then call the driver's irqcontrol function. IMHO it would make sense to demand that irqcontrol() is idempotent and then call irqcontrol(ON) before blocking in read and poll. Best regards Uwe -- Uwe Kleine-König, Software Engineer Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-06-04 6:30 ` Uwe Kleine-König @ 2008-06-04 7:05 ` Thomas Gleixner 0 siblings, 0 replies; 34+ messages in thread From: Thomas Gleixner @ 2008-06-04 7:05 UTC (permalink / raw) To: Uwe Kleine-König Cc: Hans-Jürgen Koch, Randy Dunlap, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Magnus Damm [-- Attachment #1: Type: TEXT/PLAIN, Size: 700 bytes --] On Wed, 4 Jun 2008, Uwe Kleine-König wrote: > Hello Hans-Jürgen, > > > Sometimes it is necessary to enable/disable the interrupt of a UIO device > > from the userspace part of the driver. With this patch, the UIO kernel driver > > can implement an "irqcontrol()" function that does this. Userspace can write > > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The > > UIO core will then call the driver's irqcontrol function. > IMHO it would make sense to demand that irqcontrol() is idempotent and > then call irqcontrol(ON) before blocking in read and poll. We thought about that, but it is racy. Also explicit control is way better than automagic hackery. Thanks, tglx ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 11:55 ` Hans J. Koch 2008-05-23 12:03 ` Uwe Kleine-König 2008-05-23 18:36 ` Randy Dunlap @ 2008-05-23 20:44 ` Leon Woestenberg 2008-05-23 22:43 ` Hans J. Koch 2008-05-24 4:43 ` Greg KH 3 siblings, 1 reply; 34+ messages in thread From: Leon Woestenberg @ 2008-05-23 20:44 UTC (permalink / raw) To: Hans J. Koch Cc: Uwe Kleine-König, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Hello, On Fri, May 23, 2008 at 1:55 PM, Hans J. Koch <hjk@linutronix.de> wrote: > +static ssize_t uio_write(struct file *filep, const char __user *buf, > + size_t count, loff_t *ppos) > +{ > + struct uio_listener *listener = filep->private_data; > + struct uio_device *idev = listener->dev; > + ssize_t retval; > + s32 irq_on; > + > + if (idev->info->irq == UIO_IRQ_NONE) > + return -EIO; > + > + if (count != sizeof(s32)) > + return -EINVAL; > + > + if (!idev->info->irqcontrol) > + return -ENOSYS; > + > + if (copy_from_user(&irq_on, buf, count)) > + return -EFAULT; > + > + retval = idev->info->irqcontrol(idev->info, irq_on); > + > + return retval ? retval : sizeof(s32); > +} > + Shouldn't this be more future-proof, what if we need to abuse write() for something else in the future? I would suggest a check for ppos to be 0 (zero) as well, just to be sure and future-proof and backwards-safe. Regards, -- Leon ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 20:44 ` Leon Woestenberg @ 2008-05-23 22:43 ` Hans J. Koch 2008-05-24 0:02 ` Leon Woestenberg 0 siblings, 1 reply; 34+ messages in thread From: Hans J. Koch @ 2008-05-23 22:43 UTC (permalink / raw) To: Leon Woestenberg Cc: Hans J. Koch, Uwe Kleine-König, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm On Fri, May 23, 2008 at 10:44:42PM +0200, Leon Woestenberg wrote: > Hello, > > On Fri, May 23, 2008 at 1:55 PM, Hans J. Koch <hjk@linutronix.de> wrote: > > +static ssize_t uio_write(struct file *filep, const char __user *buf, > > + size_t count, loff_t *ppos) > > +{ > > + struct uio_listener *listener = filep->private_data; > > + struct uio_device *idev = listener->dev; > > + ssize_t retval; > > + s32 irq_on; > > + > > + if (idev->info->irq == UIO_IRQ_NONE) > > + return -EIO; > > + > > + if (count != sizeof(s32)) > > + return -EINVAL; > > + > > + if (!idev->info->irqcontrol) > > + return -ENOSYS; > > + > > + if (copy_from_user(&irq_on, buf, count)) > > + return -EFAULT; > > + > > + retval = idev->info->irqcontrol(idev->info, irq_on); > > + > > + return retval ? retval : sizeof(s32); > > +} > > + > > Shouldn't this be more future-proof, what if we need to abuse write() > for something else in the future? We don't. I'm thinking about letting the function fail if irq_on is not 0 or 1, just to stop any ideas of abusing write(). read() and write() only deal with irq handling, all data exchange with the device is done through mapped memory. > > I would suggest a check for ppos to be 0 (zero) as well, just to be > sure and future-proof and backwards-safe. write() is only for enabling/disabling irqs, there's only one possible value of count, and we don't have a seek function. So why check ppos? Thanks, Hans ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 22:43 ` Hans J. Koch @ 2008-05-24 0:02 ` Leon Woestenberg 0 siblings, 0 replies; 34+ messages in thread From: Leon Woestenberg @ 2008-05-24 0:02 UTC (permalink / raw) To: Hans J. Koch Cc: Uwe Kleine-König, linux-kernel, Greg Kroah-Hartman, Jan Altenberg, Thomas Gleixner, Magnus Damm Hello, On Sat, May 24, 2008 at 12:43 AM, Hans J. Koch <hjk@linutronix.de> wrote: > On Fri, May 23, 2008 at 10:44:42PM +0200, Leon Woestenberg wrote: >> >> Shouldn't this be more future-proof, what if we need to abuse write() >> for something else in the future? > > We don't. I'm thinking about letting the function fail if irq_on is not > 0 or 1, just to stop any ideas of abusing write(). > We don't want to be future-proof? With kernel UIO and userspace driver in seperate source repositories, expect serious API drift in the longer term. I.e. the UIO interface must be backwards and forwards proof IMHO. > read() and write() only deal with irq handling, all data exchange with the > device is done through mapped memory. > *Currently*, read() and write() only deal with irq handling. In the future you might want to add a second control. I cannot think of what that should be now, much like it was not foreseen a write() call was needed. >> I would suggest a check for ppos to be 0 (zero) as well, just to be >> sure and future-proof and backwards-safe. > > write() is only for enabling/disabling irqs, there's only one possible > value of count, and we don't have a seek function. So why check ppos? > So that *if* we have a second write()able location (again, for something I cannot foresee now), you at least check that the userspace proper wants to enable/disable the interrupt. AFAIK, POSIX pwrite() does not require a seek() implementation in the driver, but will come in with a different ppos. Idea and patch looks fine, I just wanted to bring this up so that it is considered. Regards, -- Leon ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-23 11:55 ` Hans J. Koch ` (2 preceding siblings ...) 2008-05-23 20:44 ` Leon Woestenberg @ 2008-05-24 4:43 ` Greg KH 2008-05-24 22:20 ` Hans J. Koch 2008-05-24 22:22 ` Thomas Gleixner 3 siblings, 2 replies; 34+ messages in thread From: Greg KH @ 2008-05-24 4:43 UTC (permalink / raw) To: Hans J. Koch Cc: Uwe Kleine-K??nig, linux-kernel, Jan Altenberg, Thomas Gleixner, Magnus Damm On Fri, May 23, 2008 at 01:55:57PM +0200, Hans J. Koch wrote: > Sometimes it is necessary to enable/disable the interrupt of a UIO device > from the userspace part of the driver. With this patch, the UIO kernel driver > can implement an "irqcontrol()" function that does this. Userspace can write > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The > UIO core will then call the driver's irqcontrol function. Why not just a new sysfs file for the uio device, irq_enabled, or something like that? That way our main read/write path is left alone. thanks, greg k-h ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-24 4:43 ` Greg KH @ 2008-05-24 22:20 ` Hans J. Koch 2008-05-24 22:22 ` Thomas Gleixner 1 sibling, 0 replies; 34+ messages in thread From: Hans J. Koch @ 2008-05-24 22:20 UTC (permalink / raw) To: Greg KH Cc: Hans J. Koch, Uwe Kleine-K??nig, linux-kernel, Jan Altenberg, Thomas Gleixner, Magnus Damm On Fri, May 23, 2008 at 09:43:54PM -0700, Greg KH wrote: > On Fri, May 23, 2008 at 01:55:57PM +0200, Hans J. Koch wrote: > > Sometimes it is necessary to enable/disable the interrupt of a UIO device > > from the userspace part of the driver. With this patch, the UIO kernel driver > > can implement an "irqcontrol()" function that does this. Userspace can write > > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The > > UIO core will then call the driver's irqcontrol function. > > Why not just a new sysfs file for the uio device, irq_enabled, or > something like that? That way our main read/write path is left alone. Hi Greg, this is in a fast path, so I'm not sure if a sysfs file is not too much overhead. Special devices in embedded boards sometimes generate a considerable irq load, and I think it might be problem to do a sysfs write operation a few thousand times per second. Thanks, Hans ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-24 4:43 ` Greg KH 2008-05-24 22:20 ` Hans J. Koch @ 2008-05-24 22:22 ` Thomas Gleixner 2008-05-24 22:34 ` Tom Spink 2008-05-27 17:55 ` Greg KH 1 sibling, 2 replies; 34+ messages in thread From: Thomas Gleixner @ 2008-05-24 22:22 UTC (permalink / raw) To: Greg KH Cc: Hans J. Koch, Uwe Kleine-K??nig, linux-kernel, Jan Altenberg, Magnus Damm On Fri, 23 May 2008, Greg KH wrote: > On Fri, May 23, 2008 at 01:55:57PM +0200, Hans J. Koch wrote: > > Sometimes it is necessary to enable/disable the interrupt of a UIO device > > from the userspace part of the driver. With this patch, the UIO kernel driver > > can implement an "irqcontrol()" function that does this. Userspace can write > > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The > > UIO core will then call the driver's irqcontrol function. > > Why not just a new sysfs file for the uio device, irq_enabled, or > something like that? That way our main read/write path is left alone. It makes a certain amount of sense to use write. You hold the device file descriptor anyway for the read (wait for interrupt) operation, so using the same file descriptor is not a too bad idea: while (!stop) { /* wait for interrupt */ read(fd); do_stuff(); /*reenable interrupt */ write(fd); } I thought about using a sysfs entry for a while, but looking at the actual use case made the write() solution a more natural choice. Thanks, tglx ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-24 22:22 ` Thomas Gleixner @ 2008-05-24 22:34 ` Tom Spink 2008-05-24 22:46 ` Thomas Gleixner 2008-05-27 17:55 ` Greg KH 1 sibling, 1 reply; 34+ messages in thread From: Tom Spink @ 2008-05-24 22:34 UTC (permalink / raw) To: Thomas Gleixner Cc: Greg KH, Hans J. Koch, Uwe Kleine-K??nig, linux-kernel, Jan Altenberg, Magnus Damm 2008/5/24 Thomas Gleixner <tglx@linutronix.de>: > On Fri, 23 May 2008, Greg KH wrote: > >> On Fri, May 23, 2008 at 01:55:57PM +0200, Hans J. Koch wrote: >> > Sometimes it is necessary to enable/disable the interrupt of a UIO device >> > from the userspace part of the driver. With this patch, the UIO kernel driver >> > can implement an "irqcontrol()" function that does this. Userspace can write >> > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The >> > UIO core will then call the driver's irqcontrol function. >> >> Why not just a new sysfs file for the uio device, irq_enabled, or >> something like that? That way our main read/write path is left alone. Hi, > It makes a certain amount of sense to use write. You hold the device > file descriptor anyway for the read (wait for interrupt) operation, > so using the same file descriptor is not a too bad idea: What do you think about my ioctl idea, earlier in the thread? > while (!stop) { > > /* wait for interrupt */ > read(fd); > > do_stuff(); > > /*reenable interrupt */ > write(fd); > } So, instead of write, you'd use ioctl(fd, ...). > I thought about using a sysfs entry for a while, but looking at the > actual use case made the write() solution a more natural choice. I thought ioctl would be more natural, as [en,dis]abling interrupts is a "controlling" operation :-) > Thanks, > > tglx -- Tom Spink ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-24 22:34 ` Tom Spink @ 2008-05-24 22:46 ` Thomas Gleixner 2008-05-24 23:00 ` Tom Spink 0 siblings, 1 reply; 34+ messages in thread From: Thomas Gleixner @ 2008-05-24 22:46 UTC (permalink / raw) To: Tom Spink Cc: Greg KH, Hans J. Koch, Uwe Kleine-K??nig, linux-kernel, Jan Altenberg, Magnus Damm On Sat, 24 May 2008, Tom Spink wrote: > 2008/5/24 Thomas Gleixner <tglx@linutronix.de>: > > It makes a certain amount of sense to use write. You hold the device > > file descriptor anyway for the read (wait for interrupt) operation, > > so using the same file descriptor is not a too bad idea: > > What do you think about my ioctl idea, earlier in the thread? I think it's a pretty bad idea. > > while (!stop) { > > > > /* wait for interrupt */ > > read(fd); > > > > do_stuff(); > > > > /*reenable interrupt */ > > write(fd); > > } > > So, instead of write, you'd use ioctl(fd, ...). And what's the actual gain ? > > I thought about using a sysfs entry for a while, but looking at the > > actual use case made the write() solution a more natural choice. > > I thought ioctl would be more natural, as [en,dis]abling interrupts is > a "controlling" operation :-) Oh no. We are not going to open the bottomless pit of ioctls in UIO. Once we have an ioctl channel in place we have the same mess which we want to avoid in the first place. Also when a driver needs more than the obvious interrupt wait / control functions (which are pretty symetric btw.) aside of the mmapped access to the device then it does not belong into the category of an UIO driver. Thanks, tglx ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-24 22:46 ` Thomas Gleixner @ 2008-05-24 23:00 ` Tom Spink 0 siblings, 0 replies; 34+ messages in thread From: Tom Spink @ 2008-05-24 23:00 UTC (permalink / raw) To: Thomas Gleixner Cc: Greg KH, Hans J. Koch, Uwe Kleine-K??nig, linux-kernel, Jan Altenberg, Magnus Damm 2008/5/24 Thomas Gleixner <tglx@linutronix.de>: > On Sat, 24 May 2008, Tom Spink wrote: >> 2008/5/24 Thomas Gleixner <tglx@linutronix.de>: >> > It makes a certain amount of sense to use write. You hold the device >> > file descriptor anyway for the read (wait for interrupt) operation, >> > so using the same file descriptor is not a too bad idea: >> >> What do you think about my ioctl idea, earlier in the thread? > > I think it's a pretty bad idea. <grin> > >> > while (!stop) { >> > >> > /* wait for interrupt */ >> > read(fd); >> > >> > do_stuff(); >> > >> > /*reenable interrupt */ >> > write(fd); >> > } >> >> So, instead of write, you'd use ioctl(fd, ...). > > And what's the actual gain ? Simpler implementation, simpler use and future-proofing (in the sense that ->write is no longer tied to this operation) > >> > I thought about using a sysfs entry for a while, but looking at the >> > actual use case made the write() solution a more natural choice. >> >> I thought ioctl would be more natural, as [en,dis]abling interrupts is >> a "controlling" operation :-) > > Oh no. We are not going to open the bottomless pit of ioctls in > UIO. Once we have an ioctl channel in place we have the same mess > which we want to avoid in the first place. > > Also when a driver needs more than the obvious interrupt wait / > control functions (which are pretty symetric btw.) aside of the > mmapped access to the device then it does not belong into the category > of an UIO driver. Fair enough :-) symmetry is good. This is pretty much the response I got from Hans. > Thanks, > > tglx -- Tom Spink ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/1] UIO: Add a write() function to enable/disable interrupts 2008-05-24 22:22 ` Thomas Gleixner 2008-05-24 22:34 ` Tom Spink @ 2008-05-27 17:55 ` Greg KH 1 sibling, 0 replies; 34+ messages in thread From: Greg KH @ 2008-05-27 17:55 UTC (permalink / raw) To: Thomas Gleixner Cc: Hans J. Koch, Uwe Kleine-K??nig, linux-kernel, Jan Altenberg, Magnus Damm On Sun, May 25, 2008 at 12:22:20AM +0200, Thomas Gleixner wrote: > On Fri, 23 May 2008, Greg KH wrote: > > > On Fri, May 23, 2008 at 01:55:57PM +0200, Hans J. Koch wrote: > > > Sometimes it is necessary to enable/disable the interrupt of a UIO device > > > from the userspace part of the driver. With this patch, the UIO kernel driver > > > can implement an "irqcontrol()" function that does this. Userspace can write > > > an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The > > > UIO core will then call the driver's irqcontrol function. > > > > Why not just a new sysfs file for the uio device, irq_enabled, or > > something like that? That way our main read/write path is left alone. > > It makes a certain amount of sense to use write. You hold the device > file descriptor anyway for the read (wait for interrupt) operation, > so using the same file descriptor is not a too bad idea: > > while (!stop) { > > /* wait for interrupt */ > read(fd); > > do_stuff(); > > /*reenable interrupt */ > write(fd); > } > > I thought about using a sysfs entry for a while, but looking at the > actual use case made the write() solution a more natural choice. Ok, that makes sense, I can accept this. Anyone care to respin the patches with the latest updates and send them to me? thanks, greg k-h ^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2008-06-04 7:06 UTC | newest] Thread overview: 34+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-05-22 19:22 [PATCH 0/1] UIO: Add a write() function to enable/disable interrupts Hans J. Koch 2008-05-22 19:26 ` [PATCH 1/1] " Hans J. Koch 2008-05-22 19:47 ` Tom Spink 2008-05-22 20:08 ` Hans J. Koch 2008-05-22 20:26 ` Tom Spink 2008-05-23 5:41 ` Uwe Kleine-König 2008-05-23 8:51 ` Hans J. Koch 2008-05-23 11:48 ` Tom Spink 2008-05-23 11:58 ` Uwe Kleine-König 2008-05-23 12:00 ` Tom Spink 2008-05-23 12:14 ` Hans J. Koch 2008-05-23 12:20 ` Tom Spink 2008-05-23 13:01 ` Hans J. Koch 2008-05-23 5:55 ` Uwe Kleine-König 2008-05-23 8:44 ` Hans J. Koch 2008-05-23 9:10 ` Uwe Kleine-König 2008-05-23 10:03 ` Hans J. Koch 2008-05-23 10:56 ` Uwe Kleine-König 2008-05-23 11:55 ` Hans J. Koch 2008-05-23 12:03 ` Uwe Kleine-König 2008-05-23 18:36 ` Randy Dunlap 2008-05-23 22:49 ` Hans-Jürgen Koch 2008-06-04 6:30 ` Uwe Kleine-König 2008-06-04 7:05 ` Thomas Gleixner 2008-05-23 20:44 ` Leon Woestenberg 2008-05-23 22:43 ` Hans J. Koch 2008-05-24 0:02 ` Leon Woestenberg 2008-05-24 4:43 ` Greg KH 2008-05-24 22:20 ` Hans J. Koch 2008-05-24 22:22 ` Thomas Gleixner 2008-05-24 22:34 ` Tom Spink 2008-05-24 22:46 ` Thomas Gleixner 2008-05-24 23:00 ` Tom Spink 2008-05-27 17:55 ` Greg KH
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox