linux/drivers/uio/uio.c
<<
>>
Prefs
   1/*
   2 * drivers/uio/uio.c
   3 *
   4 * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
   5 * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
   6 * Copyright(C) 2006, Hans J. Koch <hjk@hansjkoch.de>
   7 * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
   8 *
   9 * Userspace IO
  10 *
  11 * Base Functions
  12 *
  13 * Licensed under the GPLv2 only.
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/init.h>
  18#include <linux/poll.h>
  19#include <linux/device.h>
  20#include <linux/slab.h>
  21#include <linux/mm.h>
  22#include <linux/idr.h>
  23#include <linux/sched.h>
  24#include <linux/string.h>
  25#include <linux/kobject.h>
  26#include <linux/cdev.h>
  27#include <linux/uio_driver.h>
  28
  29#define UIO_MAX_DEVICES         (1U << MINORBITS)
  30
  31struct uio_device {
  32        struct module           *owner;
  33        struct device           *dev;
  34        int                     minor;
  35        atomic_t                event;
  36        struct fasync_struct    *async_queue;
  37        wait_queue_head_t       wait;
  38        struct uio_info         *info;
  39        struct kobject          *map_dir;
  40        struct kobject          *portio_dir;
  41};
  42
  43static int uio_major;
  44static struct cdev *uio_cdev;
  45static DEFINE_IDR(uio_idr);
  46static const struct file_operations uio_fops;
  47
  48/* Protect idr accesses */
  49static DEFINE_MUTEX(minor_lock);
  50
  51/*
  52 * attributes
  53 */
  54
  55struct uio_map {
  56        struct kobject kobj;
  57        struct uio_mem *mem;
  58};
  59#define to_map(map) container_of(map, struct uio_map, kobj)
  60
  61static ssize_t map_name_show(struct uio_mem *mem, char *buf)
  62{
  63        if (unlikely(!mem->name))
  64                mem->name = "";
  65
  66        return sprintf(buf, "%s\n", mem->name);
  67}
  68
  69static ssize_t map_addr_show(struct uio_mem *mem, char *buf)
  70{
  71        return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr);
  72}
  73
  74static ssize_t map_size_show(struct uio_mem *mem, char *buf)
  75{
  76        return sprintf(buf, "0x%lx\n", mem->size);
  77}
  78
  79static ssize_t map_offset_show(struct uio_mem *mem, char *buf)
  80{
  81        return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr & ~PAGE_MASK);
  82}
  83
  84struct map_sysfs_entry {
  85        struct attribute attr;
  86        ssize_t (*show)(struct uio_mem *, char *);
  87        ssize_t (*store)(struct uio_mem *, const char *, size_t);
  88};
  89
  90static struct map_sysfs_entry name_attribute =
  91        __ATTR(name, S_IRUGO, map_name_show, NULL);
  92static struct map_sysfs_entry addr_attribute =
  93        __ATTR(addr, S_IRUGO, map_addr_show, NULL);
  94static struct map_sysfs_entry size_attribute =
  95        __ATTR(size, S_IRUGO, map_size_show, NULL);
  96static struct map_sysfs_entry offset_attribute =
  97        __ATTR(offset, S_IRUGO, map_offset_show, NULL);
  98
  99static struct attribute *attrs[] = {
 100        &name_attribute.attr,
 101        &addr_attribute.attr,
 102        &size_attribute.attr,
 103        &offset_attribute.attr,
 104        NULL,   /* need to NULL terminate the list of attributes */
 105};
 106
 107static void map_release(struct kobject *kobj)
 108{
 109        struct uio_map *map = to_map(kobj);
 110        kfree(map);
 111}
 112
 113static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr,
 114                             char *buf)
 115{
 116        struct uio_map *map = to_map(kobj);
 117        struct uio_mem *mem = map->mem;
 118        struct map_sysfs_entry *entry;
 119
 120        entry = container_of(attr, struct map_sysfs_entry, attr);
 121
 122        if (!entry->show)
 123                return -EIO;
 124
 125        return entry->show(mem, buf);
 126}
 127
 128static const struct sysfs_ops map_sysfs_ops = {
 129        .show = map_type_show,
 130};
 131
 132static struct kobj_type map_attr_type = {
 133        .release        = map_release,
 134        .sysfs_ops      = &map_sysfs_ops,
 135        .default_attrs  = attrs,
 136};
 137
 138struct uio_portio {
 139        struct kobject kobj;
 140        struct uio_port *port;
 141};
 142#define to_portio(portio) container_of(portio, struct uio_portio, kobj)
 143
 144static ssize_t portio_name_show(struct uio_port *port, char *buf)
 145{
 146        if (unlikely(!port->name))
 147                port->name = "";
 148
 149        return sprintf(buf, "%s\n", port->name);
 150}
 151
 152static ssize_t portio_start_show(struct uio_port *port, char *buf)
 153{
 154        return sprintf(buf, "0x%lx\n", port->start);
 155}
 156
 157static ssize_t portio_size_show(struct uio_port *port, char *buf)
 158{
 159        return sprintf(buf, "0x%lx\n", port->size);
 160}
 161
 162static ssize_t portio_porttype_show(struct uio_port *port, char *buf)
 163{
 164        const char *porttypes[] = {"none", "x86", "gpio", "other"};
 165
 166        if ((port->porttype < 0) || (port->porttype > UIO_PORT_OTHER))
 167                return -EINVAL;
 168
 169        return sprintf(buf, "port_%s\n", porttypes[port->porttype]);
 170}
 171
 172struct portio_sysfs_entry {
 173        struct attribute attr;
 174        ssize_t (*show)(struct uio_port *, char *);
 175        ssize_t (*store)(struct uio_port *, const char *, size_t);
 176};
 177
 178static struct portio_sysfs_entry portio_name_attribute =
 179        __ATTR(name, S_IRUGO, portio_name_show, NULL);
 180static struct portio_sysfs_entry portio_start_attribute =
 181        __ATTR(start, S_IRUGO, portio_start_show, NULL);
 182static struct portio_sysfs_entry portio_size_attribute =
 183        __ATTR(size, S_IRUGO, portio_size_show, NULL);
 184static struct portio_sysfs_entry portio_porttype_attribute =
 185        __ATTR(porttype, S_IRUGO, portio_porttype_show, NULL);
 186
 187static struct attribute *portio_attrs[] = {
 188        &portio_name_attribute.attr,
 189        &portio_start_attribute.attr,
 190        &portio_size_attribute.attr,
 191        &portio_porttype_attribute.attr,
 192        NULL,
 193};
 194
 195static void portio_release(struct kobject *kobj)
 196{
 197        struct uio_portio *portio = to_portio(kobj);
 198        kfree(portio);
 199}
 200
 201static ssize_t portio_type_show(struct kobject *kobj, struct attribute *attr,
 202                             char *buf)
 203{
 204        struct uio_portio *portio = to_portio(kobj);
 205        struct uio_port *port = portio->port;
 206        struct portio_sysfs_entry *entry;
 207
 208        entry = container_of(attr, struct portio_sysfs_entry, attr);
 209
 210        if (!entry->show)
 211                return -EIO;
 212
 213        return entry->show(port, buf);
 214}
 215
 216static const struct sysfs_ops portio_sysfs_ops = {
 217        .show = portio_type_show,
 218};
 219
 220static struct kobj_type portio_attr_type = {
 221        .release        = portio_release,
 222        .sysfs_ops      = &portio_sysfs_ops,
 223        .default_attrs  = portio_attrs,
 224};
 225
 226static ssize_t name_show(struct device *dev,
 227                         struct device_attribute *attr, char *buf)
 228{
 229        struct uio_device *idev = dev_get_drvdata(dev);
 230        return sprintf(buf, "%s\n", idev->info->name);
 231}
 232static DEVICE_ATTR_RO(name);
 233
 234static ssize_t version_show(struct device *dev,
 235                            struct device_attribute *attr, char *buf)
 236{
 237        struct uio_device *idev = dev_get_drvdata(dev);
 238        return sprintf(buf, "%s\n", idev->info->version);
 239}
 240static DEVICE_ATTR_RO(version);
 241
 242static ssize_t event_show(struct device *dev,
 243                          struct device_attribute *attr, char *buf)
 244{
 245        struct uio_device *idev = dev_get_drvdata(dev);
 246        return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event));
 247}
 248static DEVICE_ATTR_RO(event);
 249
 250static struct attribute *uio_attrs[] = {
 251        &dev_attr_name.attr,
 252        &dev_attr_version.attr,
 253        &dev_attr_event.attr,
 254        NULL,
 255};
 256ATTRIBUTE_GROUPS(uio);
 257
 258/* UIO class infrastructure */
 259static struct class uio_class = {
 260        .name = "uio",
 261        .dev_groups = uio_groups,
 262};
 263
 264/*
 265 * device functions
 266 */
 267static int uio_dev_add_attributes(struct uio_device *idev)
 268{
 269        int ret;
 270        int mi, pi;
 271        int map_found = 0;
 272        int portio_found = 0;
 273        struct uio_mem *mem;
 274        struct uio_map *map;
 275        struct uio_port *port;
 276        struct uio_portio *portio;
 277
 278        for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
 279                mem = &idev->info->mem[mi];
 280                if (mem->size == 0)
 281                        break;
 282                if (!map_found) {
 283                        map_found = 1;
 284                        idev->map_dir = kobject_create_and_add("maps",
 285                                                        &idev->dev->kobj);
 286                        if (!idev->map_dir)
 287                                goto err_map;
 288                }
 289                map = kzalloc(sizeof(*map), GFP_KERNEL);
 290                if (!map)
 291                        goto err_map;
 292                kobject_init(&map->kobj, &map_attr_type);
 293                map->mem = mem;
 294                mem->map = map;
 295                ret = kobject_add(&map->kobj, idev->map_dir, "map%d", mi);
 296                if (ret)
 297                        goto err_map;
 298                ret = kobject_uevent(&map->kobj, KOBJ_ADD);
 299                if (ret)
 300                        goto err_map;
 301        }
 302
 303        for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) {
 304                port = &idev->info->port[pi];
 305                if (port->size == 0)
 306                        break;
 307                if (!portio_found) {
 308                        portio_found = 1;
 309                        idev->portio_dir = kobject_create_and_add("portio",
 310                                                        &idev->dev->kobj);
 311                        if (!idev->portio_dir)
 312                                goto err_portio;
 313                }
 314                portio = kzalloc(sizeof(*portio), GFP_KERNEL);
 315                if (!portio)
 316                        goto err_portio;
 317                kobject_init(&portio->kobj, &portio_attr_type);
 318                portio->port = port;
 319                port->portio = portio;
 320                ret = kobject_add(&portio->kobj, idev->portio_dir,
 321                                                        "port%d", pi);
 322                if (ret)
 323                        goto err_portio;
 324                ret = kobject_uevent(&portio->kobj, KOBJ_ADD);
 325                if (ret)
 326                        goto err_portio;
 327        }
 328
 329        return 0;
 330
 331err_portio:
 332        for (pi--; pi >= 0; pi--) {
 333                port = &idev->info->port[pi];
 334                portio = port->portio;
 335                kobject_put(&portio->kobj);
 336        }
 337        kobject_put(idev->portio_dir);
 338err_map:
 339        for (mi--; mi>=0; mi--) {
 340                mem = &idev->info->mem[mi];
 341                map = mem->map;
 342                kobject_put(&map->kobj);
 343        }
 344        kobject_put(idev->map_dir);
 345        dev_err(idev->dev, "error creating sysfs files (%d)\n", ret);
 346        return ret;
 347}
 348
 349static void uio_dev_del_attributes(struct uio_device *idev)
 350{
 351        int i;
 352        struct uio_mem *mem;
 353        struct uio_port *port;
 354
 355        for (i = 0; i < MAX_UIO_MAPS; i++) {
 356                mem = &idev->info->mem[i];
 357                if (mem->size == 0)
 358                        break;
 359                kobject_put(&mem->map->kobj);
 360        }
 361        kobject_put(idev->map_dir);
 362
 363        for (i = 0; i < MAX_UIO_PORT_REGIONS; i++) {
 364                port = &idev->info->port[i];
 365                if (port->size == 0)
 366                        break;
 367                kobject_put(&port->portio->kobj);
 368        }
 369        kobject_put(idev->portio_dir);
 370}
 371
 372static int uio_get_minor(struct uio_device *idev)
 373{
 374        int retval = -ENOMEM;
 375
 376        mutex_lock(&minor_lock);
 377        retval = idr_alloc(&uio_idr, idev, 0, UIO_MAX_DEVICES, GFP_KERNEL);
 378        if (retval >= 0) {
 379                idev->minor = retval;
 380                retval = 0;
 381        } else if (retval == -ENOSPC) {
 382                dev_err(idev->dev, "too many uio devices\n");
 383                retval = -EINVAL;
 384        }
 385        mutex_unlock(&minor_lock);
 386        return retval;
 387}
 388
 389static void uio_free_minor(struct uio_device *idev)
 390{
 391        mutex_lock(&minor_lock);
 392        idr_remove(&uio_idr, idev->minor);
 393        mutex_unlock(&minor_lock);
 394}
 395
 396/**
 397 * uio_event_notify - trigger an interrupt event
 398 * @info: UIO device capabilities
 399 */
 400void uio_event_notify(struct uio_info *info)
 401{
 402        struct uio_device *idev = info->uio_dev;
 403
 404        atomic_inc(&idev->event);
 405        wake_up_interruptible(&idev->wait);
 406        kill_fasync(&idev->async_queue, SIGIO, POLL_IN);
 407}
 408EXPORT_SYMBOL_GPL(uio_event_notify);
 409
 410/**
 411 * uio_interrupt - hardware interrupt handler
 412 * @irq: IRQ number, can be UIO_IRQ_CYCLIC for cyclic timer
 413 * @dev_id: Pointer to the devices uio_device structure
 414 */
 415static irqreturn_t uio_interrupt(int irq, void *dev_id)
 416{
 417        struct uio_device *idev = (struct uio_device *)dev_id;
 418        irqreturn_t ret = idev->info->handler(irq, idev->info);
 419
 420        if (ret == IRQ_HANDLED)
 421                uio_event_notify(idev->info);
 422
 423        return ret;
 424}
 425
 426struct uio_listener {
 427        struct uio_device *dev;
 428        s32 event_count;
 429};
 430
 431static int uio_open(struct inode *inode, struct file *filep)
 432{
 433        struct uio_device *idev;
 434        struct uio_listener *listener;
 435        int ret = 0;
 436
 437        mutex_lock(&minor_lock);
 438        idev = idr_find(&uio_idr, iminor(inode));
 439        mutex_unlock(&minor_lock);
 440        if (!idev) {
 441                ret = -ENODEV;
 442                goto out;
 443        }
 444
 445        if (!try_module_get(idev->owner)) {
 446                ret = -ENODEV;
 447                goto out;
 448        }
 449
 450        listener = kmalloc(sizeof(*listener), GFP_KERNEL);
 451        if (!listener) {
 452                ret = -ENOMEM;
 453                goto err_alloc_listener;
 454        }
 455
 456        listener->dev = idev;
 457        listener->event_count = atomic_read(&idev->event);
 458        filep->private_data = listener;
 459
 460        if (idev->info->open) {
 461                ret = idev->info->open(idev->info, inode);
 462                if (ret)
 463                        goto err_infoopen;
 464        }
 465        return 0;
 466
 467err_infoopen:
 468        kfree(listener);
 469
 470err_alloc_listener:
 471        module_put(idev->owner);
 472
 473out:
 474        return ret;
 475}
 476
 477static int uio_fasync(int fd, struct file *filep, int on)
 478{
 479        struct uio_listener *listener = filep->private_data;
 480        struct uio_device *idev = listener->dev;
 481
 482        return fasync_helper(fd, filep, on, &idev->async_queue);
 483}
 484
 485static int uio_release(struct inode *inode, struct file *filep)
 486{
 487        int ret = 0;
 488        struct uio_listener *listener = filep->private_data;
 489        struct uio_device *idev = listener->dev;
 490
 491        if (idev->info->release)
 492                ret = idev->info->release(idev->info, inode);
 493
 494        module_put(idev->owner);
 495        kfree(listener);
 496        return ret;
 497}
 498
 499static unsigned int uio_poll(struct file *filep, poll_table *wait)
 500{
 501        struct uio_listener *listener = filep->private_data;
 502        struct uio_device *idev = listener->dev;
 503
 504        if (!idev->info->irq)
 505                return -EIO;
 506
 507        poll_wait(filep, &idev->wait, wait);
 508        if (listener->event_count != atomic_read(&idev->event))
 509                return POLLIN | POLLRDNORM;
 510        return 0;
 511}
 512
 513static ssize_t uio_read(struct file *filep, char __user *buf,
 514                        size_t count, loff_t *ppos)
 515{
 516        struct uio_listener *listener = filep->private_data;
 517        struct uio_device *idev = listener->dev;
 518        DECLARE_WAITQUEUE(wait, current);
 519        ssize_t retval;
 520        s32 event_count;
 521
 522        if (!idev->info->irq)
 523                return -EIO;
 524
 525        if (count != sizeof(s32))
 526                return -EINVAL;
 527
 528        add_wait_queue(&idev->wait, &wait);
 529
 530        do {
 531                set_current_state(TASK_INTERRUPTIBLE);
 532
 533                event_count = atomic_read(&idev->event);
 534                if (event_count != listener->event_count) {
 535                        if (copy_to_user(buf, &event_count, count))
 536                                retval = -EFAULT;
 537                        else {
 538                                listener->event_count = event_count;
 539                                retval = count;
 540                        }
 541                        break;
 542                }
 543
 544                if (filep->f_flags & O_NONBLOCK) {
 545                        retval = -EAGAIN;
 546                        break;
 547                }
 548
 549                if (signal_pending(current)) {
 550                        retval = -ERESTARTSYS;
 551                        break;
 552                }
 553                schedule();
 554        } while (1);
 555
 556        __set_current_state(TASK_RUNNING);
 557        remove_wait_queue(&idev->wait, &wait);
 558
 559        return retval;
 560}
 561
 562static ssize_t uio_write(struct file *filep, const char __user *buf,
 563                        size_t count, loff_t *ppos)
 564{
 565        struct uio_listener *listener = filep->private_data;
 566        struct uio_device *idev = listener->dev;
 567        ssize_t retval;
 568        s32 irq_on;
 569
 570        if (!idev->info->irq)
 571                return -EIO;
 572
 573        if (count != sizeof(s32))
 574                return -EINVAL;
 575
 576        if (!idev->info->irqcontrol)
 577                return -ENOSYS;
 578
 579        if (copy_from_user(&irq_on, buf, count))
 580                return -EFAULT;
 581
 582        retval = idev->info->irqcontrol(idev->info, irq_on);
 583
 584        return retval ? retval : sizeof(s32);
 585}
 586
 587static int uio_find_mem_index(struct vm_area_struct *vma)
 588{
 589        struct uio_device *idev = vma->vm_private_data;
 590
 591        if (vma->vm_pgoff < MAX_UIO_MAPS) {
 592                if (idev->info->mem[vma->vm_pgoff].size == 0)
 593                        return -1;
 594                return (int)vma->vm_pgoff;
 595        }
 596        return -1;
 597}
 598
 599static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 600{
 601        struct uio_device *idev = vma->vm_private_data;
 602        struct page *page;
 603        unsigned long offset;
 604
 605        int mi = uio_find_mem_index(vma);
 606        if (mi < 0)
 607                return VM_FAULT_SIGBUS;
 608
 609        /*
 610         * We need to subtract mi because userspace uses offset = N*PAGE_SIZE
 611         * to use mem[N].
 612         */
 613        offset = (vmf->pgoff - mi) << PAGE_SHIFT;
 614
 615        if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
 616                page = virt_to_page(idev->info->mem[mi].addr + offset);
 617        else
 618                page = vmalloc_to_page((void *)(unsigned long)idev->info->mem[mi].addr + offset);
 619        get_page(page);
 620        vmf->page = page;
 621        return 0;
 622}
 623
 624static const struct vm_operations_struct uio_logical_vm_ops = {
 625        .fault = uio_vma_fault,
 626};
 627
 628static int uio_mmap_logical(struct vm_area_struct *vma)
 629{
 630        vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 631        vma->vm_ops = &uio_logical_vm_ops;
 632        return 0;
 633}
 634
 635static const struct vm_operations_struct uio_physical_vm_ops = {
 636#ifdef CONFIG_HAVE_IOREMAP_PROT
 637        .access = generic_access_phys,
 638#endif
 639};
 640
 641static int uio_mmap_physical(struct vm_area_struct *vma)
 642{
 643        struct uio_device *idev = vma->vm_private_data;
 644        int mi = uio_find_mem_index(vma);
 645        struct uio_mem *mem;
 646        if (mi < 0)
 647                return -EINVAL;
 648        mem = idev->info->mem + mi;
 649
 650        if (vma->vm_end - vma->vm_start > mem->size)
 651                return -EINVAL;
 652
 653        vma->vm_ops = &uio_physical_vm_ops;
 654        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 655
 656        /*
 657         * We cannot use the vm_iomap_memory() helper here,
 658         * because vma->vm_pgoff is the map index we looked
 659         * up above in uio_find_mem_index(), rather than an
 660         * actual page offset into the mmap.
 661         *
 662         * So we just do the physical mmap without a page
 663         * offset.
 664         */
 665        return remap_pfn_range(vma,
 666                               vma->vm_start,
 667                               mem->addr >> PAGE_SHIFT,
 668                               vma->vm_end - vma->vm_start,
 669                               vma->vm_page_prot);
 670}
 671
 672static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
 673{
 674        struct uio_listener *listener = filep->private_data;
 675        struct uio_device *idev = listener->dev;
 676        int mi;
 677        unsigned long requested_pages, actual_pages;
 678        int ret = 0;
 679
 680        if (vma->vm_end < vma->vm_start)
 681                return -EINVAL;
 682
 683        vma->vm_private_data = idev;
 684
 685        mi = uio_find_mem_index(vma);
 686        if (mi < 0)
 687                return -EINVAL;
 688
 689        requested_pages = vma_pages(vma);
 690        actual_pages = ((idev->info->mem[mi].addr & ~PAGE_MASK)
 691                        + idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
 692        if (requested_pages > actual_pages)
 693                return -EINVAL;
 694
 695        if (idev->info->mmap) {
 696                ret = idev->info->mmap(idev->info, vma);
 697                return ret;
 698        }
 699
 700        switch (idev->info->mem[mi].memtype) {
 701                case UIO_MEM_PHYS:
 702                        return uio_mmap_physical(vma);
 703                case UIO_MEM_LOGICAL:
 704                case UIO_MEM_VIRTUAL:
 705                        return uio_mmap_logical(vma);
 706                default:
 707                        return -EINVAL;
 708        }
 709}
 710
 711static const struct file_operations uio_fops = {
 712        .owner          = THIS_MODULE,
 713        .open           = uio_open,
 714        .release        = uio_release,
 715        .read           = uio_read,
 716        .write          = uio_write,
 717        .mmap           = uio_mmap,
 718        .poll           = uio_poll,
 719        .fasync         = uio_fasync,
 720        .llseek         = noop_llseek,
 721};
 722
 723static int uio_major_init(void)
 724{
 725        static const char name[] = "uio";
 726        struct cdev *cdev = NULL;
 727        dev_t uio_dev = 0;
 728        int result;
 729
 730        result = alloc_chrdev_region(&uio_dev, 0, UIO_MAX_DEVICES, name);
 731        if (result)
 732                goto out;
 733
 734        result = -ENOMEM;
 735        cdev = cdev_alloc();
 736        if (!cdev)
 737                goto out_unregister;
 738
 739        cdev->owner = THIS_MODULE;
 740        cdev->ops = &uio_fops;
 741        kobject_set_name(&cdev->kobj, "%s", name);
 742
 743        result = cdev_add(cdev, uio_dev, UIO_MAX_DEVICES);
 744        if (result)
 745                goto out_put;
 746
 747        uio_major = MAJOR(uio_dev);
 748        uio_cdev = cdev;
 749        return 0;
 750out_put:
 751        kobject_put(&cdev->kobj);
 752out_unregister:
 753        unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES);
 754out:
 755        return result;
 756}
 757
 758static void uio_major_cleanup(void)
 759{
 760        unregister_chrdev_region(MKDEV(uio_major, 0), UIO_MAX_DEVICES);
 761        cdev_del(uio_cdev);
 762}
 763
 764static int init_uio_class(void)
 765{
 766        int ret;
 767
 768        /* This is the first time in here, set everything up properly */
 769        ret = uio_major_init();
 770        if (ret)
 771                goto exit;
 772
 773        ret = class_register(&uio_class);
 774        if (ret) {
 775                printk(KERN_ERR "class_register failed for uio\n");
 776                goto err_class_register;
 777        }
 778        return 0;
 779
 780err_class_register:
 781        uio_major_cleanup();
 782exit:
 783        return ret;
 784}
 785
 786static void release_uio_class(void)
 787{
 788        class_unregister(&uio_class);
 789        uio_major_cleanup();
 790}
 791
 792/**
 793 * uio_register_device - register a new userspace IO device
 794 * @owner:      module that creates the new device
 795 * @parent:     parent device
 796 * @info:       UIO device capabilities
 797 *
 798 * returns zero on success or a negative error code.
 799 */
 800int __uio_register_device(struct module *owner,
 801                          struct device *parent,
 802                          struct uio_info *info)
 803{
 804        struct uio_device *idev;
 805        int ret = 0;
 806
 807        if (!parent || !info || !info->name || !info->version)
 808                return -EINVAL;
 809
 810        info->uio_dev = NULL;
 811
 812        idev = kzalloc(sizeof(*idev), GFP_KERNEL);
 813        if (!idev) {
 814                ret = -ENOMEM;
 815                goto err_kzalloc;
 816        }
 817
 818        idev->owner = owner;
 819        idev->info = info;
 820        init_waitqueue_head(&idev->wait);
 821        atomic_set(&idev->event, 0);
 822
 823        ret = uio_get_minor(idev);
 824        if (ret)
 825                goto err_get_minor;
 826
 827        idev->dev = device_create(&uio_class, parent,
 828                                  MKDEV(uio_major, idev->minor), idev,
 829                                  "uio%d", idev->minor);
 830        if (IS_ERR(idev->dev)) {
 831                printk(KERN_ERR "UIO: device register failed\n");
 832                ret = PTR_ERR(idev->dev);
 833                goto err_device_create;
 834        }
 835
 836        ret = uio_dev_add_attributes(idev);
 837        if (ret)
 838                goto err_uio_dev_add_attributes;
 839
 840        info->uio_dev = idev;
 841
 842        if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
 843                ret = request_irq(info->irq, uio_interrupt,
 844                                  info->irq_flags, info->name, idev);
 845                if (ret)
 846                        goto err_request_irq;
 847        }
 848
 849        return 0;
 850
 851err_request_irq:
 852        uio_dev_del_attributes(idev);
 853err_uio_dev_add_attributes:
 854        device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
 855err_device_create:
 856        uio_free_minor(idev);
 857err_get_minor:
 858        kfree(idev);
 859err_kzalloc:
 860        return ret;
 861}
 862EXPORT_SYMBOL_GPL(__uio_register_device);
 863
 864/**
 865 * uio_unregister_device - unregister a industrial IO device
 866 * @info:       UIO device capabilities
 867 *
 868 */
 869void uio_unregister_device(struct uio_info *info)
 870{
 871        struct uio_device *idev;
 872
 873        if (!info || !info->uio_dev)
 874                return;
 875
 876        idev = info->uio_dev;
 877
 878        uio_free_minor(idev);
 879
 880        if (info->irq && (info->irq != UIO_IRQ_CUSTOM))
 881                free_irq(info->irq, idev);
 882
 883        uio_dev_del_attributes(idev);
 884
 885        device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
 886        kfree(idev);
 887
 888        return;
 889}
 890EXPORT_SYMBOL_GPL(uio_unregister_device);
 891
 892static int __init uio_init(void)
 893{
 894        return init_uio_class();
 895}
 896
 897static void __exit uio_exit(void)
 898{
 899        release_uio_class();
 900}
 901
 902module_init(uio_init)
 903module_exit(uio_exit)
 904MODULE_LICENSE("GPL v2");
 905
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.