LCOV - code coverage report
Current view: top level - drivers/uio - uio.c (source / functions) Hit Total Coverage
Test: Real Lines: 23 363 6.3 %
Date: 2020-10-17 15:46:16 Functions: 0 38 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

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

Generated by: LCOV version 1.14