mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 05:48:40 +00:00
![Hans J. Koch](/assets/img/avatar_default.png)
Devices sometimes have memory where all or parts of it can not be mapped to userspace. But it might still be possible to access this memory from userspace by other means. An example are PCI cards that advertise not only mappable memory but also ioport ranges. On x86 architectures, these can be accessed with ioperm, iopl, inb, outb, and friends. Mike Frysinger (CCed) reported a similar problem on Blackfin arch where it doesn't seem to be easy to mmap non-cached memory but it can still be accessed from userspace. This patch allows kernel drivers to pass information about such ports to userspace. Similar to the existing mem[] array, it adds a port[] array to struct uio_info. Each port range is described by start, size, and porttype. If a driver fills in at least one such port range, the UIO core will simply pass this information to userspace by creating a new directory "portio" underneath /sys/class/uio/uioN/. Similar to the "mem" directory, it will contain a subdirectory (portX) for each port range given. Note that UIO simply passes this information to userspace, it performs no action whatsoever with this data. It's userspace's responsibility to obtain access to these ports and to solve arch dependent issues. The "porttype" attribute tells userspace what kind of port it is dealing with. This mechanism could also be used to give userspace information about GPIOs related to a device. You frequently find such hardware in embedded devices, so I added a UIO_PORT_GPIO definition. I'm not really sure if this is a good idea since there are other solutions to this problem, but it won't hurt much anyway. Signed-off-by: Hans J. Koch <hjk@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
121 lines
3.2 KiB
C
121 lines
3.2 KiB
C
/*
|
|
* 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>
|
|
|
|
struct uio_map;
|
|
|
|
/**
|
|
* struct uio_mem - description of a UIO memory region
|
|
* @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
|
|
* @map: for use by the UIO core only.
|
|
*/
|
|
struct uio_mem {
|
|
unsigned long addr;
|
|
unsigned long size;
|
|
int memtype;
|
|
void __iomem *internal_addr;
|
|
struct uio_map *map;
|
|
};
|
|
|
|
#define MAX_UIO_MAPS 5
|
|
|
|
struct uio_portio;
|
|
|
|
/**
|
|
* struct uio_port - description of a UIO port region
|
|
* @start: start of port region
|
|
* @size: size of port region
|
|
* @porttype: type of port (see UIO_PORT_* below)
|
|
* @portio: for use by the UIO core only.
|
|
*/
|
|
struct uio_port {
|
|
unsigned long start;
|
|
unsigned long size;
|
|
int porttype;
|
|
struct uio_portio *portio;
|
|
};
|
|
|
|
#define MAX_UIO_PORT_REGIONS 5
|
|
|
|
struct uio_device;
|
|
|
|
/**
|
|
* 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
|
|
* @port: list of port 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
|
|
* @irqcontrol: disable/enable irqs when 0/1 is written to /dev/uioX
|
|
*/
|
|
struct uio_info {
|
|
struct uio_device *uio_dev;
|
|
char *name;
|
|
char *version;
|
|
struct uio_mem mem[MAX_UIO_MAPS];
|
|
struct uio_port port[MAX_UIO_PORT_REGIONS];
|
|
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);
|
|
int (*irqcontrol)(struct uio_info *info, s32 irq_on);
|
|
};
|
|
|
|
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_info->irq */
|
|
#define UIO_IRQ_CUSTOM -1
|
|
#define UIO_IRQ_NONE -2
|
|
|
|
/* defines for uio_mem->memtype */
|
|
#define UIO_MEM_NONE 0
|
|
#define UIO_MEM_PHYS 1
|
|
#define UIO_MEM_LOGICAL 2
|
|
#define UIO_MEM_VIRTUAL 3
|
|
|
|
/* defines for uio_port->porttype */
|
|
#define UIO_PORT_NONE 0
|
|
#define UIO_PORT_X86 1
|
|
#define UIO_PORT_GPIO 2
|
|
#define UIO_PORT_OTHER 3
|
|
|
|
#endif /* _LINUX_UIO_DRIVER_H_ */
|