1*4882a593Smuzhiyun======================= 2*4882a593SmuzhiyunThe Userspace I/O HOWTO 3*4882a593Smuzhiyun======================= 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun:Author: Hans-Jürgen Koch Linux developer, Linutronix 6*4882a593Smuzhiyun:Date: 2006-12-11 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunAbout this document 9*4882a593Smuzhiyun=================== 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunTranslations 12*4882a593Smuzhiyun------------ 13*4882a593Smuzhiyun 14*4882a593SmuzhiyunIf you know of any translations for this document, or you are interested 15*4882a593Smuzhiyunin translating it, please email me hjk@hansjkoch.de. 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunPreface 18*4882a593Smuzhiyun------- 19*4882a593Smuzhiyun 20*4882a593SmuzhiyunFor many types of devices, creating a Linux kernel driver is overkill. 21*4882a593SmuzhiyunAll that is really needed is some way to handle an interrupt and provide 22*4882a593Smuzhiyunaccess to the memory space of the device. The logic of controlling the 23*4882a593Smuzhiyundevice does not necessarily have to be within the kernel, as the device 24*4882a593Smuzhiyundoes not need to take advantage of any of other resources that the 25*4882a593Smuzhiyunkernel provides. One such common class of devices that are like this are 26*4882a593Smuzhiyunfor industrial I/O cards. 27*4882a593Smuzhiyun 28*4882a593SmuzhiyunTo address this situation, the userspace I/O system (UIO) was designed. 29*4882a593SmuzhiyunFor typical industrial I/O cards, only a very small kernel module is 30*4882a593Smuzhiyunneeded. The main part of the driver will run in user space. This 31*4882a593Smuzhiyunsimplifies development and reduces the risk of serious bugs within a 32*4882a593Smuzhiyunkernel module. 33*4882a593Smuzhiyun 34*4882a593SmuzhiyunPlease note that UIO is not an universal driver interface. Devices that 35*4882a593Smuzhiyunare already handled well by other kernel subsystems (like networking or 36*4882a593Smuzhiyunserial or USB) are no candidates for an UIO driver. Hardware that is 37*4882a593Smuzhiyunideally suited for an UIO driver fulfills all of the following: 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun- The device has memory that can be mapped. The device can be 40*4882a593Smuzhiyun controlled completely by writing to this memory. 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun- The device usually generates interrupts. 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun- The device does not fit into one of the standard kernel subsystems. 45*4882a593Smuzhiyun 46*4882a593SmuzhiyunAcknowledgments 47*4882a593Smuzhiyun--------------- 48*4882a593Smuzhiyun 49*4882a593SmuzhiyunI'd like to thank Thomas Gleixner and Benedikt Spranger of Linutronix, 50*4882a593Smuzhiyunwho have not only written most of the UIO code, but also helped greatly 51*4882a593Smuzhiyunwriting this HOWTO by giving me all kinds of background information. 52*4882a593Smuzhiyun 53*4882a593SmuzhiyunFeedback 54*4882a593Smuzhiyun-------- 55*4882a593Smuzhiyun 56*4882a593SmuzhiyunFind something wrong with this document? (Or perhaps something right?) I 57*4882a593Smuzhiyunwould love to hear from you. Please email me at hjk@hansjkoch.de. 58*4882a593Smuzhiyun 59*4882a593SmuzhiyunAbout UIO 60*4882a593Smuzhiyun========= 61*4882a593Smuzhiyun 62*4882a593SmuzhiyunIf you use UIO for your card's driver, here's what you get: 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun- only one small kernel module to write and maintain. 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun- develop the main part of your driver in user space, with all the 67*4882a593Smuzhiyun tools and libraries you're used to. 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun- bugs in your driver won't crash the kernel. 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun- updates of your driver can take place without recompiling the kernel. 72*4882a593Smuzhiyun 73*4882a593SmuzhiyunHow UIO works 74*4882a593Smuzhiyun------------- 75*4882a593Smuzhiyun 76*4882a593SmuzhiyunEach UIO device is accessed through a device file and several sysfs 77*4882a593Smuzhiyunattribute files. The device file will be called ``/dev/uio0`` for the 78*4882a593Smuzhiyunfirst device, and ``/dev/uio1``, ``/dev/uio2`` and so on for subsequent 79*4882a593Smuzhiyundevices. 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun``/dev/uioX`` is used to access the address space of the card. Just use 82*4882a593Smuzhiyun:c:func:`mmap()` to access registers or RAM locations of your card. 83*4882a593Smuzhiyun 84*4882a593SmuzhiyunInterrupts are handled by reading from ``/dev/uioX``. A blocking 85*4882a593Smuzhiyun:c:func:`read()` from ``/dev/uioX`` will return as soon as an 86*4882a593Smuzhiyuninterrupt occurs. You can also use :c:func:`select()` on 87*4882a593Smuzhiyun``/dev/uioX`` to wait for an interrupt. The integer value read from 88*4882a593Smuzhiyun``/dev/uioX`` represents the total interrupt count. You can use this 89*4882a593Smuzhiyunnumber to figure out if you missed some interrupts. 90*4882a593Smuzhiyun 91*4882a593SmuzhiyunFor some hardware that has more than one interrupt source internally, 92*4882a593Smuzhiyunbut not separate IRQ mask and status registers, there might be 93*4882a593Smuzhiyunsituations where userspace cannot determine what the interrupt source 94*4882a593Smuzhiyunwas if the kernel handler disables them by writing to the chip's IRQ 95*4882a593Smuzhiyunregister. In such a case, the kernel has to disable the IRQ completely 96*4882a593Smuzhiyunto leave the chip's register untouched. Now the userspace part can 97*4882a593Smuzhiyundetermine the cause of the interrupt, but it cannot re-enable 98*4882a593Smuzhiyuninterrupts. Another cornercase is chips where re-enabling interrupts is 99*4882a593Smuzhiyuna read-modify-write operation to a combined IRQ status/acknowledge 100*4882a593Smuzhiyunregister. This would be racy if a new interrupt occurred simultaneously. 101*4882a593Smuzhiyun 102*4882a593SmuzhiyunTo address these problems, UIO also implements a write() function. It is 103*4882a593Smuzhiyunnormally not used and can be ignored for hardware that has only a single 104*4882a593Smuzhiyuninterrupt source or has separate IRQ mask and status registers. If you 105*4882a593Smuzhiyunneed it, however, a write to ``/dev/uioX`` will call the 106*4882a593Smuzhiyun:c:func:`irqcontrol()` function implemented by the driver. You have 107*4882a593Smuzhiyunto write a 32-bit value that is usually either 0 or 1 to disable or 108*4882a593Smuzhiyunenable interrupts. If a driver does not implement 109*4882a593Smuzhiyun:c:func:`irqcontrol()`, :c:func:`write()` will return with 110*4882a593Smuzhiyun``-ENOSYS``. 111*4882a593Smuzhiyun 112*4882a593SmuzhiyunTo handle interrupts properly, your custom kernel module can provide its 113*4882a593Smuzhiyunown interrupt handler. It will automatically be called by the built-in 114*4882a593Smuzhiyunhandler. 115*4882a593Smuzhiyun 116*4882a593SmuzhiyunFor cards that don't generate interrupts but need to be polled, there is 117*4882a593Smuzhiyunthe possibility to set up a timer that triggers the interrupt handler at 118*4882a593Smuzhiyunconfigurable time intervals. This interrupt simulation is done by 119*4882a593Smuzhiyuncalling :c:func:`uio_event_notify()` from the timer's event 120*4882a593Smuzhiyunhandler. 121*4882a593Smuzhiyun 122*4882a593SmuzhiyunEach driver provides attributes that are used to read or write 123*4882a593Smuzhiyunvariables. These attributes are accessible through sysfs files. A custom 124*4882a593Smuzhiyunkernel driver module can add its own attributes to the device owned by 125*4882a593Smuzhiyunthe uio driver, but not added to the UIO device itself at this time. 126*4882a593SmuzhiyunThis might change in the future if it would be found to be useful. 127*4882a593Smuzhiyun 128*4882a593SmuzhiyunThe following standard attributes are provided by the UIO framework: 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun- ``name``: The name of your device. It is recommended to use the name 131*4882a593Smuzhiyun of your kernel module for this. 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun- ``version``: A version string defined by your driver. This allows the 134*4882a593Smuzhiyun user space part of your driver to deal with different versions of the 135*4882a593Smuzhiyun kernel module. 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun- ``event``: The total number of interrupts handled by the driver since 138*4882a593Smuzhiyun the last time the device node was read. 139*4882a593Smuzhiyun 140*4882a593SmuzhiyunThese attributes appear under the ``/sys/class/uio/uioX`` directory. 141*4882a593SmuzhiyunPlease note that this directory might be a symlink, and not a real 142*4882a593Smuzhiyundirectory. Any userspace code that accesses it must be able to handle 143*4882a593Smuzhiyunthis. 144*4882a593Smuzhiyun 145*4882a593SmuzhiyunEach UIO device can make one or more memory regions available for memory 146*4882a593Smuzhiyunmapping. This is necessary because some industrial I/O cards require 147*4882a593Smuzhiyunaccess to more than one PCI memory region in a driver. 148*4882a593Smuzhiyun 149*4882a593SmuzhiyunEach mapping has its own directory in sysfs, the first mapping appears 150*4882a593Smuzhiyunas ``/sys/class/uio/uioX/maps/map0/``. Subsequent mappings create 151*4882a593Smuzhiyundirectories ``map1/``, ``map2/``, and so on. These directories will only 152*4882a593Smuzhiyunappear if the size of the mapping is not 0. 153*4882a593Smuzhiyun 154*4882a593SmuzhiyunEach ``mapX/`` directory contains four read-only files that show 155*4882a593Smuzhiyunattributes of the memory: 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun- ``name``: A string identifier for this mapping. This is optional, the 158*4882a593Smuzhiyun string can be empty. Drivers can set this to make it easier for 159*4882a593Smuzhiyun userspace to find the correct mapping. 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun- ``addr``: The address of memory that can be mapped. 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun- ``size``: The size, in bytes, of the memory pointed to by addr. 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun- ``offset``: The offset, in bytes, that has to be added to the pointer 166*4882a593Smuzhiyun returned by :c:func:`mmap()` to get to the actual device memory. 167*4882a593Smuzhiyun This is important if the device's memory is not page aligned. 168*4882a593Smuzhiyun Remember that pointers returned by :c:func:`mmap()` are always 169*4882a593Smuzhiyun page aligned, so it is good style to always add this offset. 170*4882a593Smuzhiyun 171*4882a593SmuzhiyunFrom userspace, the different mappings are distinguished by adjusting 172*4882a593Smuzhiyunthe ``offset`` parameter of the :c:func:`mmap()` call. To map the 173*4882a593Smuzhiyunmemory of mapping N, you have to use N times the page size as your 174*4882a593Smuzhiyunoffset:: 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun offset = N * getpagesize(); 177*4882a593Smuzhiyun 178*4882a593SmuzhiyunSometimes there is hardware with memory-like regions that can not be 179*4882a593Smuzhiyunmapped with the technique described here, but there are still ways to 180*4882a593Smuzhiyunaccess them from userspace. The most common example are x86 ioports. On 181*4882a593Smuzhiyunx86 systems, userspace can access these ioports using 182*4882a593Smuzhiyun:c:func:`ioperm()`, :c:func:`iopl()`, :c:func:`inb()`, 183*4882a593Smuzhiyun:c:func:`outb()`, and similar functions. 184*4882a593Smuzhiyun 185*4882a593SmuzhiyunSince these ioport regions can not be mapped, they will not appear under 186*4882a593Smuzhiyun``/sys/class/uio/uioX/maps/`` like the normal memory described above. 187*4882a593SmuzhiyunWithout information about the port regions a hardware has to offer, it 188*4882a593Smuzhiyunbecomes difficult for the userspace part of the driver to find out which 189*4882a593Smuzhiyunports belong to which UIO device. 190*4882a593Smuzhiyun 191*4882a593SmuzhiyunTo address this situation, the new directory 192*4882a593Smuzhiyun``/sys/class/uio/uioX/portio/`` was added. It only exists if the driver 193*4882a593Smuzhiyunwants to pass information about one or more port regions to userspace. 194*4882a593SmuzhiyunIf that is the case, subdirectories named ``port0``, ``port1``, and so 195*4882a593Smuzhiyunon, will appear underneath ``/sys/class/uio/uioX/portio/``. 196*4882a593Smuzhiyun 197*4882a593SmuzhiyunEach ``portX/`` directory contains four read-only files that show name, 198*4882a593Smuzhiyunstart, size, and type of the port region: 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun- ``name``: A string identifier for this port region. The string is 201*4882a593Smuzhiyun optional and can be empty. Drivers can set it to make it easier for 202*4882a593Smuzhiyun userspace to find a certain port region. 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun- ``start``: The first port of this region. 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun- ``size``: The number of ports in this region. 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun- ``porttype``: A string describing the type of port. 209*4882a593Smuzhiyun 210*4882a593SmuzhiyunWriting your own kernel module 211*4882a593Smuzhiyun============================== 212*4882a593Smuzhiyun 213*4882a593SmuzhiyunPlease have a look at ``uio_cif.c`` as an example. The following 214*4882a593Smuzhiyunparagraphs explain the different sections of this file. 215*4882a593Smuzhiyun 216*4882a593Smuzhiyunstruct uio_info 217*4882a593Smuzhiyun--------------- 218*4882a593Smuzhiyun 219*4882a593SmuzhiyunThis structure tells the framework the details of your driver, Some of 220*4882a593Smuzhiyunthe members are required, others are optional. 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun- ``const char *name``: Required. The name of your driver as it will 223*4882a593Smuzhiyun appear in sysfs. I recommend using the name of your module for this. 224*4882a593Smuzhiyun 225*4882a593Smuzhiyun- ``const char *version``: Required. This string appears in 226*4882a593Smuzhiyun ``/sys/class/uio/uioX/version``. 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun- ``struct uio_mem mem[ MAX_UIO_MAPS ]``: Required if you have memory 229*4882a593Smuzhiyun that can be mapped with :c:func:`mmap()`. For each mapping you 230*4882a593Smuzhiyun need to fill one of the ``uio_mem`` structures. See the description 231*4882a593Smuzhiyun below for details. 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun- ``struct uio_port port[ MAX_UIO_PORTS_REGIONS ]``: Required if you 234*4882a593Smuzhiyun want to pass information about ioports to userspace. For each port 235*4882a593Smuzhiyun region you need to fill one of the ``uio_port`` structures. See the 236*4882a593Smuzhiyun description below for details. 237*4882a593Smuzhiyun 238*4882a593Smuzhiyun- ``long irq``: Required. If your hardware generates an interrupt, it's 239*4882a593Smuzhiyun your modules task to determine the irq number during initialization. 240*4882a593Smuzhiyun If you don't have a hardware generated interrupt but want to trigger 241*4882a593Smuzhiyun the interrupt handler in some other way, set ``irq`` to 242*4882a593Smuzhiyun ``UIO_IRQ_CUSTOM``. If you had no interrupt at all, you could set 243*4882a593Smuzhiyun ``irq`` to ``UIO_IRQ_NONE``, though this rarely makes sense. 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun- ``unsigned long irq_flags``: Required if you've set ``irq`` to a 246*4882a593Smuzhiyun hardware interrupt number. The flags given here will be used in the 247*4882a593Smuzhiyun call to :c:func:`request_irq()`. 248*4882a593Smuzhiyun 249*4882a593Smuzhiyun- ``int (*mmap)(struct uio_info *info, struct vm_area_struct *vma)``: 250*4882a593Smuzhiyun Optional. If you need a special :c:func:`mmap()` 251*4882a593Smuzhiyun function, you can set it here. If this pointer is not NULL, your 252*4882a593Smuzhiyun :c:func:`mmap()` will be called instead of the built-in one. 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun- ``int (*open)(struct uio_info *info, struct inode *inode)``: 255*4882a593Smuzhiyun Optional. You might want to have your own :c:func:`open()`, 256*4882a593Smuzhiyun e.g. to enable interrupts only when your device is actually used. 257*4882a593Smuzhiyun 258*4882a593Smuzhiyun- ``int (*release)(struct uio_info *info, struct inode *inode)``: 259*4882a593Smuzhiyun Optional. If you define your own :c:func:`open()`, you will 260*4882a593Smuzhiyun probably also want a custom :c:func:`release()` function. 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun- ``int (*irqcontrol)(struct uio_info *info, s32 irq_on)``: 263*4882a593Smuzhiyun Optional. If you need to be able to enable or disable interrupts 264*4882a593Smuzhiyun from userspace by writing to ``/dev/uioX``, you can implement this 265*4882a593Smuzhiyun function. The parameter ``irq_on`` will be 0 to disable interrupts 266*4882a593Smuzhiyun and 1 to enable them. 267*4882a593Smuzhiyun 268*4882a593SmuzhiyunUsually, your device will have one or more memory regions that can be 269*4882a593Smuzhiyunmapped to user space. For each region, you have to set up a 270*4882a593Smuzhiyun``struct uio_mem`` in the ``mem[]`` array. Here's a description of the 271*4882a593Smuzhiyunfields of ``struct uio_mem``: 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun- ``const char *name``: Optional. Set this to help identify the memory 274*4882a593Smuzhiyun region, it will show up in the corresponding sysfs node. 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun- ``int memtype``: Required if the mapping is used. Set this to 277*4882a593Smuzhiyun ``UIO_MEM_PHYS`` if you have physical memory on your card to be 278*4882a593Smuzhiyun mapped. Use ``UIO_MEM_LOGICAL`` for logical memory (e.g. allocated 279*4882a593Smuzhiyun with :c:func:`__get_free_pages()` but not kmalloc()). There's also 280*4882a593Smuzhiyun ``UIO_MEM_VIRTUAL`` for virtual memory. 281*4882a593Smuzhiyun 282*4882a593Smuzhiyun- ``phys_addr_t addr``: Required if the mapping is used. Fill in the 283*4882a593Smuzhiyun address of your memory block. This address is the one that appears in 284*4882a593Smuzhiyun sysfs. 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun- ``resource_size_t size``: Fill in the size of the memory block that 287*4882a593Smuzhiyun ``addr`` points to. If ``size`` is zero, the mapping is considered 288*4882a593Smuzhiyun unused. Note that you *must* initialize ``size`` with zero for all 289*4882a593Smuzhiyun unused mappings. 290*4882a593Smuzhiyun 291*4882a593Smuzhiyun- ``void *internal_addr``: If you have to access this memory region 292*4882a593Smuzhiyun from within your kernel module, you will want to map it internally by 293*4882a593Smuzhiyun using something like :c:func:`ioremap()`. Addresses returned by 294*4882a593Smuzhiyun this function cannot be mapped to user space, so you must not store 295*4882a593Smuzhiyun it in ``addr``. Use ``internal_addr`` instead to remember such an 296*4882a593Smuzhiyun address. 297*4882a593Smuzhiyun 298*4882a593SmuzhiyunPlease do not touch the ``map`` element of ``struct uio_mem``! It is 299*4882a593Smuzhiyunused by the UIO framework to set up sysfs files for this mapping. Simply 300*4882a593Smuzhiyunleave it alone. 301*4882a593Smuzhiyun 302*4882a593SmuzhiyunSometimes, your device can have one or more port regions which can not 303*4882a593Smuzhiyunbe mapped to userspace. But if there are other possibilities for 304*4882a593Smuzhiyunuserspace to access these ports, it makes sense to make information 305*4882a593Smuzhiyunabout the ports available in sysfs. For each region, you have to set up 306*4882a593Smuzhiyuna ``struct uio_port`` in the ``port[]`` array. Here's a description of 307*4882a593Smuzhiyunthe fields of ``struct uio_port``: 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun- ``char *porttype``: Required. Set this to one of the predefined 310*4882a593Smuzhiyun constants. Use ``UIO_PORT_X86`` for the ioports found in x86 311*4882a593Smuzhiyun architectures. 312*4882a593Smuzhiyun 313*4882a593Smuzhiyun- ``unsigned long start``: Required if the port region is used. Fill in 314*4882a593Smuzhiyun the number of the first port of this region. 315*4882a593Smuzhiyun 316*4882a593Smuzhiyun- ``unsigned long size``: Fill in the number of ports in this region. 317*4882a593Smuzhiyun If ``size`` is zero, the region is considered unused. Note that you 318*4882a593Smuzhiyun *must* initialize ``size`` with zero for all unused regions. 319*4882a593Smuzhiyun 320*4882a593SmuzhiyunPlease do not touch the ``portio`` element of ``struct uio_port``! It is 321*4882a593Smuzhiyunused internally by the UIO framework to set up sysfs files for this 322*4882a593Smuzhiyunregion. Simply leave it alone. 323*4882a593Smuzhiyun 324*4882a593SmuzhiyunAdding an interrupt handler 325*4882a593Smuzhiyun--------------------------- 326*4882a593Smuzhiyun 327*4882a593SmuzhiyunWhat you need to do in your interrupt handler depends on your hardware 328*4882a593Smuzhiyunand on how you want to handle it. You should try to keep the amount of 329*4882a593Smuzhiyuncode in your kernel interrupt handler low. If your hardware requires no 330*4882a593Smuzhiyunaction that you *have* to perform after each interrupt, then your 331*4882a593Smuzhiyunhandler can be empty. 332*4882a593Smuzhiyun 333*4882a593SmuzhiyunIf, on the other hand, your hardware *needs* some action to be performed 334*4882a593Smuzhiyunafter each interrupt, then you *must* do it in your kernel module. Note 335*4882a593Smuzhiyunthat you cannot rely on the userspace part of your driver. Your 336*4882a593Smuzhiyunuserspace program can terminate at any time, possibly leaving your 337*4882a593Smuzhiyunhardware in a state where proper interrupt handling is still required. 338*4882a593Smuzhiyun 339*4882a593SmuzhiyunThere might also be applications where you want to read data from your 340*4882a593Smuzhiyunhardware at each interrupt and buffer it in a piece of kernel memory 341*4882a593Smuzhiyunyou've allocated for that purpose. With this technique you could avoid 342*4882a593Smuzhiyunloss of data if your userspace program misses an interrupt. 343*4882a593Smuzhiyun 344*4882a593SmuzhiyunA note on shared interrupts: Your driver should support interrupt 345*4882a593Smuzhiyunsharing whenever this is possible. It is possible if and only if your 346*4882a593Smuzhiyundriver can detect whether your hardware has triggered the interrupt or 347*4882a593Smuzhiyunnot. This is usually done by looking at an interrupt status register. If 348*4882a593Smuzhiyunyour driver sees that the IRQ bit is actually set, it will perform its 349*4882a593Smuzhiyunactions, and the handler returns IRQ_HANDLED. If the driver detects 350*4882a593Smuzhiyunthat it was not your hardware that caused the interrupt, it will do 351*4882a593Smuzhiyunnothing and return IRQ_NONE, allowing the kernel to call the next 352*4882a593Smuzhiyunpossible interrupt handler. 353*4882a593Smuzhiyun 354*4882a593SmuzhiyunIf you decide not to support shared interrupts, your card won't work in 355*4882a593Smuzhiyuncomputers with no free interrupts. As this frequently happens on the PC 356*4882a593Smuzhiyunplatform, you can save yourself a lot of trouble by supporting interrupt 357*4882a593Smuzhiyunsharing. 358*4882a593Smuzhiyun 359*4882a593SmuzhiyunUsing uio_pdrv for platform devices 360*4882a593Smuzhiyun----------------------------------- 361*4882a593Smuzhiyun 362*4882a593SmuzhiyunIn many cases, UIO drivers for platform devices can be handled in a 363*4882a593Smuzhiyungeneric way. In the same place where you define your 364*4882a593Smuzhiyun``struct platform_device``, you simply also implement your interrupt 365*4882a593Smuzhiyunhandler and fill your ``struct uio_info``. A pointer to this 366*4882a593Smuzhiyun``struct uio_info`` is then used as ``platform_data`` for your platform 367*4882a593Smuzhiyundevice. 368*4882a593Smuzhiyun 369*4882a593SmuzhiyunYou also need to set up an array of ``struct resource`` containing 370*4882a593Smuzhiyunaddresses and sizes of your memory mappings. This information is passed 371*4882a593Smuzhiyunto the driver using the ``.resource`` and ``.num_resources`` elements of 372*4882a593Smuzhiyun``struct platform_device``. 373*4882a593Smuzhiyun 374*4882a593SmuzhiyunYou now have to set the ``.name`` element of ``struct platform_device`` 375*4882a593Smuzhiyunto ``"uio_pdrv"`` to use the generic UIO platform device driver. This 376*4882a593Smuzhiyundriver will fill the ``mem[]`` array according to the resources given, 377*4882a593Smuzhiyunand register the device. 378*4882a593Smuzhiyun 379*4882a593SmuzhiyunThe advantage of this approach is that you only have to edit a file you 380*4882a593Smuzhiyunneed to edit anyway. You do not have to create an extra driver. 381*4882a593Smuzhiyun 382*4882a593SmuzhiyunUsing uio_pdrv_genirq for platform devices 383*4882a593Smuzhiyun------------------------------------------ 384*4882a593Smuzhiyun 385*4882a593SmuzhiyunEspecially in embedded devices, you frequently find chips where the irq 386*4882a593Smuzhiyunpin is tied to its own dedicated interrupt line. In such cases, where 387*4882a593Smuzhiyunyou can be really sure the interrupt is not shared, we can take the 388*4882a593Smuzhiyunconcept of ``uio_pdrv`` one step further and use a generic interrupt 389*4882a593Smuzhiyunhandler. That's what ``uio_pdrv_genirq`` does. 390*4882a593Smuzhiyun 391*4882a593SmuzhiyunThe setup for this driver is the same as described above for 392*4882a593Smuzhiyun``uio_pdrv``, except that you do not implement an interrupt handler. The 393*4882a593Smuzhiyun``.handler`` element of ``struct uio_info`` must remain ``NULL``. The 394*4882a593Smuzhiyun``.irq_flags`` element must not contain ``IRQF_SHARED``. 395*4882a593Smuzhiyun 396*4882a593SmuzhiyunYou will set the ``.name`` element of ``struct platform_device`` to 397*4882a593Smuzhiyun``"uio_pdrv_genirq"`` to use this driver. 398*4882a593Smuzhiyun 399*4882a593SmuzhiyunThe generic interrupt handler of ``uio_pdrv_genirq`` will simply disable 400*4882a593Smuzhiyunthe interrupt line using :c:func:`disable_irq_nosync()`. After 401*4882a593Smuzhiyundoing its work, userspace can reenable the interrupt by writing 402*4882a593Smuzhiyun0x00000001 to the UIO device file. The driver already implements an 403*4882a593Smuzhiyun:c:func:`irq_control()` to make this possible, you must not 404*4882a593Smuzhiyunimplement your own. 405*4882a593Smuzhiyun 406*4882a593SmuzhiyunUsing ``uio_pdrv_genirq`` not only saves a few lines of interrupt 407*4882a593Smuzhiyunhandler code. You also do not need to know anything about the chip's 408*4882a593Smuzhiyuninternal registers to create the kernel part of the driver. All you need 409*4882a593Smuzhiyunto know is the irq number of the pin the chip is connected to. 410*4882a593Smuzhiyun 411*4882a593SmuzhiyunWhen used in a device-tree enabled system, the driver needs to be 412*4882a593Smuzhiyunprobed with the ``"of_id"`` module parameter set to the ``"compatible"`` 413*4882a593Smuzhiyunstring of the node the driver is supposed to handle. By default, the 414*4882a593Smuzhiyunnode's name (without the unit address) is exposed as name for the 415*4882a593SmuzhiyunUIO device in userspace. To set a custom name, a property named 416*4882a593Smuzhiyun``"linux,uio-name"`` may be specified in the DT node. 417*4882a593Smuzhiyun 418*4882a593SmuzhiyunUsing uio_dmem_genirq for platform devices 419*4882a593Smuzhiyun------------------------------------------ 420*4882a593Smuzhiyun 421*4882a593SmuzhiyunIn addition to statically allocated memory ranges, they may also be a 422*4882a593Smuzhiyundesire to use dynamically allocated regions in a user space driver. In 423*4882a593Smuzhiyunparticular, being able to access memory made available through the 424*4882a593Smuzhiyundma-mapping API, may be particularly useful. The ``uio_dmem_genirq`` 425*4882a593Smuzhiyundriver provides a way to accomplish this. 426*4882a593Smuzhiyun 427*4882a593SmuzhiyunThis driver is used in a similar manner to the ``"uio_pdrv_genirq"`` 428*4882a593Smuzhiyundriver with respect to interrupt configuration and handling. 429*4882a593Smuzhiyun 430*4882a593SmuzhiyunSet the ``.name`` element of ``struct platform_device`` to 431*4882a593Smuzhiyun``"uio_dmem_genirq"`` to use this driver. 432*4882a593Smuzhiyun 433*4882a593SmuzhiyunWhen using this driver, fill in the ``.platform_data`` element of 434*4882a593Smuzhiyun``struct platform_device``, which is of type 435*4882a593Smuzhiyun``struct uio_dmem_genirq_pdata`` and which contains the following 436*4882a593Smuzhiyunelements: 437*4882a593Smuzhiyun 438*4882a593Smuzhiyun- ``struct uio_info uioinfo``: The same structure used as the 439*4882a593Smuzhiyun ``uio_pdrv_genirq`` platform data 440*4882a593Smuzhiyun 441*4882a593Smuzhiyun- ``unsigned int *dynamic_region_sizes``: Pointer to list of sizes of 442*4882a593Smuzhiyun dynamic memory regions to be mapped into user space. 443*4882a593Smuzhiyun 444*4882a593Smuzhiyun- ``unsigned int num_dynamic_regions``: Number of elements in 445*4882a593Smuzhiyun ``dynamic_region_sizes`` array. 446*4882a593Smuzhiyun 447*4882a593SmuzhiyunThe dynamic regions defined in the platform data will be appended to the 448*4882a593Smuzhiyun`` mem[] `` array after the platform device resources, which implies 449*4882a593Smuzhiyunthat the total number of static and dynamic memory regions cannot exceed 450*4882a593Smuzhiyun``MAX_UIO_MAPS``. 451*4882a593Smuzhiyun 452*4882a593SmuzhiyunThe dynamic memory regions will be allocated when the UIO device file, 453*4882a593Smuzhiyun``/dev/uioX`` is opened. Similar to static memory resources, the memory 454*4882a593Smuzhiyunregion information for dynamic regions is then visible via sysfs at 455*4882a593Smuzhiyun``/sys/class/uio/uioX/maps/mapY/*``. The dynamic memory regions will be 456*4882a593Smuzhiyunfreed when the UIO device file is closed. When no processes are holding 457*4882a593Smuzhiyunthe device file open, the address returned to userspace is ~0. 458*4882a593Smuzhiyun 459*4882a593SmuzhiyunWriting a driver in userspace 460*4882a593Smuzhiyun============================= 461*4882a593Smuzhiyun 462*4882a593SmuzhiyunOnce you have a working kernel module for your hardware, you can write 463*4882a593Smuzhiyunthe userspace part of your driver. You don't need any special libraries, 464*4882a593Smuzhiyunyour driver can be written in any reasonable language, you can use 465*4882a593Smuzhiyunfloating point numbers and so on. In short, you can use all the tools 466*4882a593Smuzhiyunand libraries you'd normally use for writing a userspace application. 467*4882a593Smuzhiyun 468*4882a593SmuzhiyunGetting information about your UIO device 469*4882a593Smuzhiyun----------------------------------------- 470*4882a593Smuzhiyun 471*4882a593SmuzhiyunInformation about all UIO devices is available in sysfs. The first thing 472*4882a593Smuzhiyunyou should do in your driver is check ``name`` and ``version`` to make 473*4882a593Smuzhiyunsure you're talking to the right device and that its kernel driver has 474*4882a593Smuzhiyunthe version you expect. 475*4882a593Smuzhiyun 476*4882a593SmuzhiyunYou should also make sure that the memory mapping you need exists and 477*4882a593Smuzhiyunhas the size you expect. 478*4882a593Smuzhiyun 479*4882a593SmuzhiyunThere is a tool called ``lsuio`` that lists UIO devices and their 480*4882a593Smuzhiyunattributes. It is available here: 481*4882a593Smuzhiyun 482*4882a593Smuzhiyunhttp://www.osadl.org/projects/downloads/UIO/user/ 483*4882a593Smuzhiyun 484*4882a593SmuzhiyunWith ``lsuio`` you can quickly check if your kernel module is loaded and 485*4882a593Smuzhiyunwhich attributes it exports. Have a look at the manpage for details. 486*4882a593Smuzhiyun 487*4882a593SmuzhiyunThe source code of ``lsuio`` can serve as an example for getting 488*4882a593Smuzhiyuninformation about an UIO device. The file ``uio_helper.c`` contains a 489*4882a593Smuzhiyunlot of functions you could use in your userspace driver code. 490*4882a593Smuzhiyun 491*4882a593Smuzhiyunmmap() device memory 492*4882a593Smuzhiyun-------------------- 493*4882a593Smuzhiyun 494*4882a593SmuzhiyunAfter you made sure you've got the right device with the memory mappings 495*4882a593Smuzhiyunyou need, all you have to do is to call :c:func:`mmap()` to map the 496*4882a593Smuzhiyundevice's memory to userspace. 497*4882a593Smuzhiyun 498*4882a593SmuzhiyunThe parameter ``offset`` of the :c:func:`mmap()` call has a special 499*4882a593Smuzhiyunmeaning for UIO devices: It is used to select which mapping of your 500*4882a593Smuzhiyundevice you want to map. To map the memory of mapping N, you have to use 501*4882a593SmuzhiyunN times the page size as your offset:: 502*4882a593Smuzhiyun 503*4882a593Smuzhiyun offset = N * getpagesize(); 504*4882a593Smuzhiyun 505*4882a593SmuzhiyunN starts from zero, so if you've got only one memory range to map, set 506*4882a593Smuzhiyun``offset = 0``. A drawback of this technique is that memory is always 507*4882a593Smuzhiyunmapped beginning with its start address. 508*4882a593Smuzhiyun 509*4882a593SmuzhiyunWaiting for interrupts 510*4882a593Smuzhiyun---------------------- 511*4882a593Smuzhiyun 512*4882a593SmuzhiyunAfter you successfully mapped your devices memory, you can access it 513*4882a593Smuzhiyunlike an ordinary array. Usually, you will perform some initialization. 514*4882a593SmuzhiyunAfter that, your hardware starts working and will generate an interrupt 515*4882a593Smuzhiyunas soon as it's finished, has some data available, or needs your 516*4882a593Smuzhiyunattention because an error occurred. 517*4882a593Smuzhiyun 518*4882a593Smuzhiyun``/dev/uioX`` is a read-only file. A :c:func:`read()` will always 519*4882a593Smuzhiyunblock until an interrupt occurs. There is only one legal value for the 520*4882a593Smuzhiyun``count`` parameter of :c:func:`read()`, and that is the size of a 521*4882a593Smuzhiyunsigned 32 bit integer (4). Any other value for ``count`` causes 522*4882a593Smuzhiyun:c:func:`read()` to fail. The signed 32 bit integer read is the 523*4882a593Smuzhiyuninterrupt count of your device. If the value is one more than the value 524*4882a593Smuzhiyunyou read the last time, everything is OK. If the difference is greater 525*4882a593Smuzhiyunthan one, you missed interrupts. 526*4882a593Smuzhiyun 527*4882a593SmuzhiyunYou can also use :c:func:`select()` on ``/dev/uioX``. 528*4882a593Smuzhiyun 529*4882a593SmuzhiyunGeneric PCI UIO driver 530*4882a593Smuzhiyun====================== 531*4882a593Smuzhiyun 532*4882a593SmuzhiyunThe generic driver is a kernel module named uio_pci_generic. It can 533*4882a593Smuzhiyunwork with any device compliant to PCI 2.3 (circa 2002) and any compliant 534*4882a593SmuzhiyunPCI Express device. Using this, you only need to write the userspace 535*4882a593Smuzhiyundriver, removing the need to write a hardware-specific kernel module. 536*4882a593Smuzhiyun 537*4882a593SmuzhiyunMaking the driver recognize the device 538*4882a593Smuzhiyun-------------------------------------- 539*4882a593Smuzhiyun 540*4882a593SmuzhiyunSince the driver does not declare any device ids, it will not get loaded 541*4882a593Smuzhiyunautomatically and will not automatically bind to any devices, you must 542*4882a593Smuzhiyunload it and allocate id to the driver yourself. For example:: 543*4882a593Smuzhiyun 544*4882a593Smuzhiyun modprobe uio_pci_generic 545*4882a593Smuzhiyun echo "8086 10f5" > /sys/bus/pci/drivers/uio_pci_generic/new_id 546*4882a593Smuzhiyun 547*4882a593SmuzhiyunIf there already is a hardware specific kernel driver for your device, 548*4882a593Smuzhiyunthe generic driver still won't bind to it, in this case if you want to 549*4882a593Smuzhiyunuse the generic driver (why would you?) you'll have to manually unbind 550*4882a593Smuzhiyunthe hardware specific driver and bind the generic driver, like this:: 551*4882a593Smuzhiyun 552*4882a593Smuzhiyun echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind 553*4882a593Smuzhiyun echo -n 0000:00:19.0 > /sys/bus/pci/drivers/uio_pci_generic/bind 554*4882a593Smuzhiyun 555*4882a593SmuzhiyunYou can verify that the device has been bound to the driver by looking 556*4882a593Smuzhiyunfor it in sysfs, for example like the following:: 557*4882a593Smuzhiyun 558*4882a593Smuzhiyun ls -l /sys/bus/pci/devices/0000:00:19.0/driver 559*4882a593Smuzhiyun 560*4882a593SmuzhiyunWhich if successful should print:: 561*4882a593Smuzhiyun 562*4882a593Smuzhiyun .../0000:00:19.0/driver -> ../../../bus/pci/drivers/uio_pci_generic 563*4882a593Smuzhiyun 564*4882a593SmuzhiyunNote that the generic driver will not bind to old PCI 2.2 devices. If 565*4882a593Smuzhiyunbinding the device failed, run the following command:: 566*4882a593Smuzhiyun 567*4882a593Smuzhiyun dmesg 568*4882a593Smuzhiyun 569*4882a593Smuzhiyunand look in the output for failure reasons. 570*4882a593Smuzhiyun 571*4882a593SmuzhiyunThings to know about uio_pci_generic 572*4882a593Smuzhiyun------------------------------------ 573*4882a593Smuzhiyun 574*4882a593SmuzhiyunInterrupts are handled using the Interrupt Disable bit in the PCI 575*4882a593Smuzhiyuncommand register and Interrupt Status bit in the PCI status register. 576*4882a593SmuzhiyunAll devices compliant to PCI 2.3 (circa 2002) and all compliant PCI 577*4882a593SmuzhiyunExpress devices should support these bits. uio_pci_generic detects 578*4882a593Smuzhiyunthis support, and won't bind to devices which do not support the 579*4882a593SmuzhiyunInterrupt Disable Bit in the command register. 580*4882a593Smuzhiyun 581*4882a593SmuzhiyunOn each interrupt, uio_pci_generic sets the Interrupt Disable bit. 582*4882a593SmuzhiyunThis prevents the device from generating further interrupts until the 583*4882a593Smuzhiyunbit is cleared. The userspace driver should clear this bit before 584*4882a593Smuzhiyunblocking and waiting for more interrupts. 585*4882a593Smuzhiyun 586*4882a593SmuzhiyunWriting userspace driver using uio_pci_generic 587*4882a593Smuzhiyun------------------------------------------------ 588*4882a593Smuzhiyun 589*4882a593SmuzhiyunUserspace driver can use pci sysfs interface, or the libpci library that 590*4882a593Smuzhiyunwraps it, to talk to the device and to re-enable interrupts by writing 591*4882a593Smuzhiyunto the command register. 592*4882a593Smuzhiyun 593*4882a593SmuzhiyunExample code using uio_pci_generic 594*4882a593Smuzhiyun---------------------------------- 595*4882a593Smuzhiyun 596*4882a593SmuzhiyunHere is some sample userspace driver code using uio_pci_generic:: 597*4882a593Smuzhiyun 598*4882a593Smuzhiyun #include <stdlib.h> 599*4882a593Smuzhiyun #include <stdio.h> 600*4882a593Smuzhiyun #include <unistd.h> 601*4882a593Smuzhiyun #include <sys/types.h> 602*4882a593Smuzhiyun #include <sys/stat.h> 603*4882a593Smuzhiyun #include <fcntl.h> 604*4882a593Smuzhiyun #include <errno.h> 605*4882a593Smuzhiyun 606*4882a593Smuzhiyun int main() 607*4882a593Smuzhiyun { 608*4882a593Smuzhiyun int uiofd; 609*4882a593Smuzhiyun int configfd; 610*4882a593Smuzhiyun int err; 611*4882a593Smuzhiyun int i; 612*4882a593Smuzhiyun unsigned icount; 613*4882a593Smuzhiyun unsigned char command_high; 614*4882a593Smuzhiyun 615*4882a593Smuzhiyun uiofd = open("/dev/uio0", O_RDONLY); 616*4882a593Smuzhiyun if (uiofd < 0) { 617*4882a593Smuzhiyun perror("uio open:"); 618*4882a593Smuzhiyun return errno; 619*4882a593Smuzhiyun } 620*4882a593Smuzhiyun configfd = open("/sys/class/uio/uio0/device/config", O_RDWR); 621*4882a593Smuzhiyun if (configfd < 0) { 622*4882a593Smuzhiyun perror("config open:"); 623*4882a593Smuzhiyun return errno; 624*4882a593Smuzhiyun } 625*4882a593Smuzhiyun 626*4882a593Smuzhiyun /* Read and cache command value */ 627*4882a593Smuzhiyun err = pread(configfd, &command_high, 1, 5); 628*4882a593Smuzhiyun if (err != 1) { 629*4882a593Smuzhiyun perror("command config read:"); 630*4882a593Smuzhiyun return errno; 631*4882a593Smuzhiyun } 632*4882a593Smuzhiyun command_high &= ~0x4; 633*4882a593Smuzhiyun 634*4882a593Smuzhiyun for(i = 0;; ++i) { 635*4882a593Smuzhiyun /* Print out a message, for debugging. */ 636*4882a593Smuzhiyun if (i == 0) 637*4882a593Smuzhiyun fprintf(stderr, "Started uio test driver.\n"); 638*4882a593Smuzhiyun else 639*4882a593Smuzhiyun fprintf(stderr, "Interrupts: %d\n", icount); 640*4882a593Smuzhiyun 641*4882a593Smuzhiyun /****************************************/ 642*4882a593Smuzhiyun /* Here we got an interrupt from the 643*4882a593Smuzhiyun device. Do something to it. */ 644*4882a593Smuzhiyun /****************************************/ 645*4882a593Smuzhiyun 646*4882a593Smuzhiyun /* Re-enable interrupts. */ 647*4882a593Smuzhiyun err = pwrite(configfd, &command_high, 1, 5); 648*4882a593Smuzhiyun if (err != 1) { 649*4882a593Smuzhiyun perror("config write:"); 650*4882a593Smuzhiyun break; 651*4882a593Smuzhiyun } 652*4882a593Smuzhiyun 653*4882a593Smuzhiyun /* Wait for next interrupt. */ 654*4882a593Smuzhiyun err = read(uiofd, &icount, 4); 655*4882a593Smuzhiyun if (err != 4) { 656*4882a593Smuzhiyun perror("uio read:"); 657*4882a593Smuzhiyun break; 658*4882a593Smuzhiyun } 659*4882a593Smuzhiyun 660*4882a593Smuzhiyun } 661*4882a593Smuzhiyun return errno; 662*4882a593Smuzhiyun } 663*4882a593Smuzhiyun 664*4882a593SmuzhiyunGeneric Hyper-V UIO driver 665*4882a593Smuzhiyun========================== 666*4882a593Smuzhiyun 667*4882a593SmuzhiyunThe generic driver is a kernel module named uio_hv_generic. It 668*4882a593Smuzhiyunsupports devices on the Hyper-V VMBus similar to uio_pci_generic on 669*4882a593SmuzhiyunPCI bus. 670*4882a593Smuzhiyun 671*4882a593SmuzhiyunMaking the driver recognize the device 672*4882a593Smuzhiyun-------------------------------------- 673*4882a593Smuzhiyun 674*4882a593SmuzhiyunSince the driver does not declare any device GUID's, it will not get 675*4882a593Smuzhiyunloaded automatically and will not automatically bind to any devices, you 676*4882a593Smuzhiyunmust load it and allocate id to the driver yourself. For example, to use 677*4882a593Smuzhiyunthe network device class GUID:: 678*4882a593Smuzhiyun 679*4882a593Smuzhiyun modprobe uio_hv_generic 680*4882a593Smuzhiyun echo "f8615163-df3e-46c5-913f-f2d2f965ed0e" > /sys/bus/vmbus/drivers/uio_hv_generic/new_id 681*4882a593Smuzhiyun 682*4882a593SmuzhiyunIf there already is a hardware specific kernel driver for the device, 683*4882a593Smuzhiyunthe generic driver still won't bind to it, in this case if you want to 684*4882a593Smuzhiyunuse the generic driver for a userspace library you'll have to manually unbind 685*4882a593Smuzhiyunthe hardware specific driver and bind the generic driver, using the device specific GUID 686*4882a593Smuzhiyunlike this:: 687*4882a593Smuzhiyun 688*4882a593Smuzhiyun echo -n ed963694-e847-4b2a-85af-bc9cfc11d6f3 > /sys/bus/vmbus/drivers/hv_netvsc/unbind 689*4882a593Smuzhiyun echo -n ed963694-e847-4b2a-85af-bc9cfc11d6f3 > /sys/bus/vmbus/drivers/uio_hv_generic/bind 690*4882a593Smuzhiyun 691*4882a593SmuzhiyunYou can verify that the device has been bound to the driver by looking 692*4882a593Smuzhiyunfor it in sysfs, for example like the following:: 693*4882a593Smuzhiyun 694*4882a593Smuzhiyun ls -l /sys/bus/vmbus/devices/ed963694-e847-4b2a-85af-bc9cfc11d6f3/driver 695*4882a593Smuzhiyun 696*4882a593SmuzhiyunWhich if successful should print:: 697*4882a593Smuzhiyun 698*4882a593Smuzhiyun .../ed963694-e847-4b2a-85af-bc9cfc11d6f3/driver -> ../../../bus/vmbus/drivers/uio_hv_generic 699*4882a593Smuzhiyun 700*4882a593SmuzhiyunThings to know about uio_hv_generic 701*4882a593Smuzhiyun----------------------------------- 702*4882a593Smuzhiyun 703*4882a593SmuzhiyunOn each interrupt, uio_hv_generic sets the Interrupt Disable bit. This 704*4882a593Smuzhiyunprevents the device from generating further interrupts until the bit is 705*4882a593Smuzhiyuncleared. The userspace driver should clear this bit before blocking and 706*4882a593Smuzhiyunwaiting for more interrupts. 707*4882a593Smuzhiyun 708*4882a593SmuzhiyunWhen host rescinds a device, the interrupt file descriptor is marked down 709*4882a593Smuzhiyunand any reads of the interrupt file descriptor will return -EIO. Similar 710*4882a593Smuzhiyunto a closed socket or disconnected serial device. 711*4882a593Smuzhiyun 712*4882a593SmuzhiyunThe vmbus device regions are mapped into uio device resources: 713*4882a593Smuzhiyun 0) Channel ring buffers: guest to host and host to guest 714*4882a593Smuzhiyun 1) Guest to host interrupt signalling pages 715*4882a593Smuzhiyun 2) Guest to host monitor page 716*4882a593Smuzhiyun 3) Network receive buffer region 717*4882a593Smuzhiyun 4) Network send buffer region 718*4882a593Smuzhiyun 719*4882a593SmuzhiyunIf a subchannel is created by a request to host, then the uio_hv_generic 720*4882a593Smuzhiyundevice driver will create a sysfs binary file for the per-channel ring buffer. 721*4882a593SmuzhiyunFor example:: 722*4882a593Smuzhiyun 723*4882a593Smuzhiyun /sys/bus/vmbus/devices/3811fe4d-0fa0-4b62-981a-74fc1084c757/channels/21/ring 724*4882a593Smuzhiyun 725*4882a593SmuzhiyunFurther information 726*4882a593Smuzhiyun=================== 727*4882a593Smuzhiyun 728*4882a593Smuzhiyun- `OSADL homepage. <http://www.osadl.org>`_ 729*4882a593Smuzhiyun 730*4882a593Smuzhiyun- `Linutronix homepage. <http://www.linutronix.de>`_ 731