LCOV - code coverage report
Current view: top level - drivers/media/rc - lirc_dev.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_qemu_modules_combined.info Lines: 5 327 1.5 %
Date: 2020-09-30 20:25:01 Functions: 1 16 6.2 %
Branches: 2 312 0.6 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  * LIRC base driver
       4                 :            :  *
       5                 :            :  * by Artur Lipowski <alipowski@interia.pl>
       6                 :            :  */
       7                 :            : 
       8                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
       9                 :            : 
      10                 :            : #include <linux/module.h>
      11                 :            : #include <linux/mutex.h>
      12                 :            : #include <linux/device.h>
      13                 :            : #include <linux/file.h>
      14                 :            : #include <linux/idr.h>
      15                 :            : #include <linux/poll.h>
      16                 :            : #include <linux/sched.h>
      17                 :            : #include <linux/wait.h>
      18                 :            : 
      19                 :            : #include "rc-core-priv.h"
      20                 :            : #include <uapi/linux/lirc.h>
      21                 :            : 
      22                 :            : #define LIRCBUF_SIZE    1024
      23                 :            : 
      24                 :            : static dev_t lirc_base_dev;
      25                 :            : 
      26                 :            : /* Used to keep track of allocated lirc devices */
      27                 :            : static DEFINE_IDA(lirc_ida);
      28                 :            : 
      29                 :            : /* Only used for sysfs but defined to void otherwise */
      30                 :            : static struct class *lirc_class;
      31                 :            : 
      32                 :            : /**
      33                 :            :  * ir_lirc_raw_event() - Send raw IR data to lirc to be relayed to userspace
      34                 :            :  *
      35                 :            :  * @dev:        the struct rc_dev descriptor of the device
      36                 :            :  * @ev:         the struct ir_raw_event descriptor of the pulse/space
      37                 :            :  */
      38                 :          0 : void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
      39                 :            : {
      40                 :            :         unsigned long flags;
      41                 :            :         struct lirc_fh *fh;
      42                 :            :         int sample;
      43                 :            : 
      44                 :            :         /* Packet start */
      45         [ #  # ]:          0 :         if (ev.reset) {
      46                 :            :                 /*
      47                 :            :                  * Userspace expects a long space event before the start of
      48                 :            :                  * the signal to use as a sync.  This may be done with repeat
      49                 :            :                  * packets and normal samples.  But if a reset has been sent
      50                 :            :                  * then we assume that a long time has passed, so we send a
      51                 :            :                  * space with the maximum time value.
      52                 :            :                  */
      53                 :            :                 sample = LIRC_SPACE(LIRC_VALUE_MASK);
      54                 :            :                 dev_dbg(&dev->dev, "delivering reset sync space to lirc_dev\n");
      55                 :            : 
      56                 :            :         /* Carrier reports */
      57         [ #  # ]:          0 :         } else if (ev.carrier_report) {
      58                 :          0 :                 sample = LIRC_FREQUENCY(ev.carrier);
      59                 :            :                 dev_dbg(&dev->dev, "carrier report (freq: %d)\n", sample);
      60                 :            : 
      61                 :            :         /* Packet end */
      62         [ #  # ]:          0 :         } else if (ev.timeout) {
      63         [ #  # ]:          0 :                 if (dev->gap)
      64                 :          0 :                         return;
      65                 :            : 
      66                 :          0 :                 dev->gap_start = ktime_get();
      67                 :          0 :                 dev->gap = true;
      68                 :          0 :                 dev->gap_duration = ev.duration;
      69                 :            : 
      70                 :          0 :                 sample = LIRC_TIMEOUT(ev.duration / 1000);
      71                 :            :                 dev_dbg(&dev->dev, "timeout report (duration: %d)\n", sample);
      72                 :            : 
      73                 :            :         /* Normal sample */
      74                 :            :         } else {
      75         [ #  # ]:          0 :                 if (dev->gap) {
      76                 :          0 :                         dev->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
      77                 :            :                                                          dev->gap_start));
      78                 :            : 
      79                 :            :                         /* Convert to ms and cap by LIRC_VALUE_MASK */
      80                 :          0 :                         do_div(dev->gap_duration, 1000);
      81                 :          0 :                         dev->gap_duration = min_t(u64, dev->gap_duration,
      82                 :            :                                                   LIRC_VALUE_MASK);
      83                 :            : 
      84                 :          0 :                         spin_lock_irqsave(&dev->lirc_fh_lock, flags);
      85         [ #  # ]:          0 :                         list_for_each_entry(fh, &dev->lirc_fh, list)
      86         [ #  # ]:          0 :                                 kfifo_put(&fh->rawir,
      87                 :            :                                           LIRC_SPACE(dev->gap_duration));
      88                 :            :                         spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
      89                 :          0 :                         dev->gap = false;
      90                 :            :                 }
      91                 :            : 
      92         [ #  # ]:          0 :                 sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
      93                 :          0 :                                         LIRC_SPACE(ev.duration / 1000);
      94                 :            :                 dev_dbg(&dev->dev, "delivering %uus %s to lirc_dev\n",
      95                 :            :                         TO_US(ev.duration), TO_STR(ev.pulse));
      96                 :            :         }
      97                 :            : 
      98                 :            :         /*
      99                 :            :          * bpf does not care about the gap generated above; that exists
     100                 :            :          * for backwards compatibility
     101                 :            :          */
     102                 :          0 :         lirc_bpf_run(dev, sample);
     103                 :            : 
     104                 :          0 :         spin_lock_irqsave(&dev->lirc_fh_lock, flags);
     105         [ #  # ]:          0 :         list_for_each_entry(fh, &dev->lirc_fh, list) {
     106   [ #  #  #  # ]:          0 :                 if (LIRC_IS_TIMEOUT(sample) && !fh->send_timeout_reports)
     107                 :          0 :                         continue;
     108   [ #  #  #  # ]:          0 :                 if (kfifo_put(&fh->rawir, sample))
     109                 :          0 :                         wake_up_poll(&fh->wait_poll, EPOLLIN | EPOLLRDNORM);
     110                 :            :         }
     111                 :            :         spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
     112                 :            : }
     113                 :            : 
     114                 :            : /**
     115                 :            :  * ir_lirc_scancode_event() - Send scancode data to lirc to be relayed to
     116                 :            :  *              userspace. This can be called in atomic context.
     117                 :            :  * @dev:        the struct rc_dev descriptor of the device
     118                 :            :  * @lsc:        the struct lirc_scancode describing the decoded scancode
     119                 :            :  */
     120                 :          0 : void ir_lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc)
     121                 :            : {
     122                 :            :         unsigned long flags;
     123                 :            :         struct lirc_fh *fh;
     124                 :            : 
     125                 :          0 :         lsc->timestamp = ktime_get_ns();
     126                 :            : 
     127                 :          0 :         spin_lock_irqsave(&dev->lirc_fh_lock, flags);
     128         [ #  # ]:          0 :         list_for_each_entry(fh, &dev->lirc_fh, list) {
     129   [ #  #  #  # ]:          0 :                 if (kfifo_put(&fh->scancodes, *lsc))
     130                 :          0 :                         wake_up_poll(&fh->wait_poll, EPOLLIN | EPOLLRDNORM);
     131                 :            :         }
     132                 :            :         spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
     133                 :          0 : }
     134                 :            : EXPORT_SYMBOL_GPL(ir_lirc_scancode_event);
     135                 :            : 
     136                 :          0 : static int ir_lirc_open(struct inode *inode, struct file *file)
     137                 :            : {
     138                 :          0 :         struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev,
     139                 :            :                                           lirc_cdev);
     140                 :          0 :         struct lirc_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
     141                 :            :         unsigned long flags;
     142                 :            :         int retval;
     143                 :            : 
     144         [ #  # ]:          0 :         if (!fh)
     145                 :            :                 return -ENOMEM;
     146                 :            : 
     147                 :          0 :         get_device(&dev->dev);
     148                 :            : 
     149         [ #  # ]:          0 :         if (!dev->registered) {
     150                 :            :                 retval = -ENODEV;
     151                 :            :                 goto out_fh;
     152                 :            :         }
     153                 :            : 
     154         [ #  # ]:          0 :         if (dev->driver_type == RC_DRIVER_IR_RAW) {
     155         [ #  # ]:          0 :                 if (kfifo_alloc(&fh->rawir, MAX_IR_EVENT_SIZE, GFP_KERNEL)) {
     156                 :            :                         retval = -ENOMEM;
     157                 :            :                         goto out_fh;
     158                 :            :                 }
     159                 :            :         }
     160                 :            : 
     161         [ #  # ]:          0 :         if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
     162         [ #  # ]:          0 :                 if (kfifo_alloc(&fh->scancodes, 32, GFP_KERNEL)) {
     163                 :            :                         retval = -ENOMEM;
     164                 :            :                         goto out_rawir;
     165                 :            :                 }
     166                 :            :         }
     167                 :            : 
     168                 :          0 :         fh->send_mode = LIRC_MODE_PULSE;
     169                 :          0 :         fh->rc = dev;
     170                 :          0 :         fh->send_timeout_reports = true;
     171                 :            : 
     172         [ #  # ]:          0 :         if (dev->driver_type == RC_DRIVER_SCANCODE)
     173                 :          0 :                 fh->rec_mode = LIRC_MODE_SCANCODE;
     174                 :            :         else
     175                 :          0 :                 fh->rec_mode = LIRC_MODE_MODE2;
     176                 :            : 
     177                 :          0 :         retval = rc_open(dev);
     178         [ #  # ]:          0 :         if (retval)
     179                 :            :                 goto out_kfifo;
     180                 :            : 
     181                 :          0 :         init_waitqueue_head(&fh->wait_poll);
     182                 :            : 
     183                 :          0 :         file->private_data = fh;
     184                 :          0 :         spin_lock_irqsave(&dev->lirc_fh_lock, flags);
     185                 :          0 :         list_add(&fh->list, &dev->lirc_fh);
     186                 :            :         spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
     187                 :            : 
     188                 :          0 :         stream_open(inode, file);
     189                 :            : 
     190                 :          0 :         return 0;
     191                 :            : out_kfifo:
     192         [ #  # ]:          0 :         if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
     193                 :          0 :                 kfifo_free(&fh->scancodes);
     194                 :            : out_rawir:
     195         [ #  # ]:          0 :         if (dev->driver_type == RC_DRIVER_IR_RAW)
     196                 :          0 :                 kfifo_free(&fh->rawir);
     197                 :            : out_fh:
     198                 :          0 :         kfree(fh);
     199                 :          0 :         put_device(&dev->dev);
     200                 :            : 
     201                 :          0 :         return retval;
     202                 :            : }
     203                 :            : 
     204                 :          0 : static int ir_lirc_close(struct inode *inode, struct file *file)
     205                 :            : {
     206                 :          0 :         struct lirc_fh *fh = file->private_data;
     207                 :          0 :         struct rc_dev *dev = fh->rc;
     208                 :            :         unsigned long flags;
     209                 :            : 
     210                 :          0 :         spin_lock_irqsave(&dev->lirc_fh_lock, flags);
     211                 :            :         list_del(&fh->list);
     212                 :            :         spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
     213                 :            : 
     214         [ #  # ]:          0 :         if (dev->driver_type == RC_DRIVER_IR_RAW)
     215                 :          0 :                 kfifo_free(&fh->rawir);
     216         [ #  # ]:          0 :         if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
     217                 :          0 :                 kfifo_free(&fh->scancodes);
     218                 :          0 :         kfree(fh);
     219                 :            : 
     220                 :          0 :         rc_close(dev);
     221                 :          0 :         put_device(&dev->dev);
     222                 :            : 
     223                 :          0 :         return 0;
     224                 :            : }
     225                 :            : 
     226                 :          0 : static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
     227                 :            :                                    size_t n, loff_t *ppos)
     228                 :            : {
     229                 :          0 :         struct lirc_fh *fh = file->private_data;
     230                 :          0 :         struct rc_dev *dev = fh->rc;
     231                 :            :         unsigned int *txbuf;
     232                 :            :         struct ir_raw_event *raw = NULL;
     233                 :            :         ssize_t ret;
     234                 :            :         size_t count;
     235                 :            :         ktime_t start;
     236                 :            :         s64 towait;
     237                 :            :         unsigned int duration = 0; /* signal duration in us */
     238                 :            :         int i;
     239                 :            : 
     240                 :          0 :         ret = mutex_lock_interruptible(&dev->lock);
     241         [ #  # ]:          0 :         if (ret)
     242                 :            :                 return ret;
     243                 :            : 
     244         [ #  # ]:          0 :         if (!dev->registered) {
     245                 :            :                 ret = -ENODEV;
     246                 :            :                 goto out_unlock;
     247                 :            :         }
     248                 :            : 
     249         [ #  # ]:          0 :         if (!dev->tx_ir) {
     250                 :            :                 ret = -EINVAL;
     251                 :            :                 goto out_unlock;
     252                 :            :         }
     253                 :            : 
     254         [ #  # ]:          0 :         if (fh->send_mode == LIRC_MODE_SCANCODE) {
     255                 :            :                 struct lirc_scancode scan;
     256                 :            : 
     257         [ #  # ]:          0 :                 if (n != sizeof(scan)) {
     258                 :            :                         ret = -EINVAL;
     259                 :          0 :                         goto out_unlock;
     260                 :            :                 }
     261                 :            : 
     262         [ #  # ]:          0 :                 if (copy_from_user(&scan, buf, sizeof(scan))) {
     263                 :            :                         ret = -EFAULT;
     264                 :            :                         goto out_unlock;
     265                 :            :                 }
     266                 :            : 
     267   [ #  #  #  #  :          0 :                 if (scan.flags || scan.keycode || scan.timestamp) {
                   #  # ]
     268                 :            :                         ret = -EINVAL;
     269                 :            :                         goto out_unlock;
     270                 :            :                 }
     271                 :            : 
     272                 :            :                 /*
     273                 :            :                  * The scancode field in lirc_scancode is 64-bit simply
     274                 :            :                  * to future-proof it, since there are IR protocols encode
     275                 :            :                  * use more than 32 bits. For now only 32-bit protocols
     276                 :            :                  * are supported.
     277                 :            :                  */
     278   [ #  #  #  # ]:          0 :                 if (scan.scancode > U32_MAX ||
     279                 :          0 :                     !rc_validate_scancode(scan.rc_proto, scan.scancode)) {
     280                 :            :                         ret = -EINVAL;
     281                 :            :                         goto out_unlock;
     282                 :            :                 }
     283                 :            : 
     284                 :          0 :                 raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL);
     285         [ #  # ]:          0 :                 if (!raw) {
     286                 :            :                         ret = -ENOMEM;
     287                 :            :                         goto out_unlock;
     288                 :            :                 }
     289                 :            : 
     290                 :          0 :                 ret = ir_raw_encode_scancode(scan.rc_proto, scan.scancode,
     291                 :            :                                              raw, LIRCBUF_SIZE);
     292         [ #  # ]:          0 :                 if (ret < 0)
     293                 :            :                         goto out_kfree_raw;
     294                 :            : 
     295                 :          0 :                 count = ret;
     296                 :            : 
     297                 :          0 :                 txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL);
     298         [ #  # ]:          0 :                 if (!txbuf) {
     299                 :            :                         ret = -ENOMEM;
     300                 :            :                         goto out_kfree_raw;
     301                 :            :                 }
     302                 :            : 
     303         [ #  # ]:          0 :                 for (i = 0; i < count; i++)
     304                 :            :                         /* Convert from NS to US */
     305                 :          0 :                         txbuf[i] = DIV_ROUND_UP(raw[i].duration, 1000);
     306                 :            : 
     307         [ #  # ]:          0 :                 if (dev->s_tx_carrier) {
     308                 :          0 :                         int carrier = ir_raw_encode_carrier(scan.rc_proto);
     309                 :            : 
     310         [ #  # ]:          0 :                         if (carrier > 0)
     311                 :          0 :                                 dev->s_tx_carrier(dev, carrier);
     312                 :            :                 }
     313                 :            :         } else {
     314   [ #  #  #  # ]:          0 :                 if (n < sizeof(unsigned int) || n % sizeof(unsigned int)) {
     315                 :            :                         ret = -EINVAL;
     316                 :            :                         goto out_unlock;
     317                 :            :                 }
     318                 :            : 
     319                 :          0 :                 count = n / sizeof(unsigned int);
     320   [ #  #  #  # ]:          0 :                 if (count > LIRCBUF_SIZE || count % 2 == 0) {
     321                 :            :                         ret = -EINVAL;
     322                 :            :                         goto out_unlock;
     323                 :            :                 }
     324                 :            : 
     325                 :          0 :                 txbuf = memdup_user(buf, n);
     326         [ #  # ]:          0 :                 if (IS_ERR(txbuf)) {
     327                 :            :                         ret = PTR_ERR(txbuf);
     328                 :          0 :                         goto out_unlock;
     329                 :            :                 }
     330                 :            :         }
     331                 :            : 
     332         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     333   [ #  #  #  # ]:          0 :                 if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) {
     334                 :            :                         ret = -EINVAL;
     335                 :            :                         goto out_kfree;
     336                 :            :                 }
     337                 :            : 
     338                 :          0 :                 duration += txbuf[i];
     339                 :            :         }
     340                 :            : 
     341                 :          0 :         start = ktime_get();
     342                 :            : 
     343                 :          0 :         ret = dev->tx_ir(dev, txbuf, count);
     344         [ #  # ]:          0 :         if (ret < 0)
     345                 :            :                 goto out_kfree;
     346                 :            : 
     347                 :          0 :         kfree(txbuf);
     348                 :          0 :         kfree(raw);
     349                 :          0 :         mutex_unlock(&dev->lock);
     350                 :            : 
     351                 :            :         /*
     352                 :            :          * The lircd gap calculation expects the write function to
     353                 :            :          * wait for the actual IR signal to be transmitted before
     354                 :            :          * returning.
     355                 :            :          */
     356                 :          0 :         towait = ktime_us_delta(ktime_add_us(start, duration),
     357                 :            :                                 ktime_get());
     358         [ #  # ]:          0 :         if (towait > 0) {
     359                 :          0 :                 set_current_state(TASK_INTERRUPTIBLE);
     360                 :          0 :                 schedule_timeout(usecs_to_jiffies(towait));
     361                 :            :         }
     362                 :            : 
     363                 :          0 :         return n;
     364                 :            : out_kfree:
     365                 :          0 :         kfree(txbuf);
     366                 :            : out_kfree_raw:
     367                 :          0 :         kfree(raw);
     368                 :            : out_unlock:
     369                 :          0 :         mutex_unlock(&dev->lock);
     370                 :          0 :         return ret;
     371                 :            : }
     372                 :            : 
     373                 :          0 : static long ir_lirc_ioctl(struct file *file, unsigned int cmd,
     374                 :            :                           unsigned long arg)
     375                 :            : {
     376                 :          0 :         struct lirc_fh *fh = file->private_data;
     377                 :          0 :         struct rc_dev *dev = fh->rc;
     378                 :          0 :         u32 __user *argp = (u32 __user *)(arg);
     379                 :            :         u32 val = 0;
     380                 :            :         int ret;
     381                 :            : 
     382         [ #  # ]:          0 :         if (_IOC_DIR(cmd) & _IOC_WRITE) {
     383                 :          0 :                 ret = get_user(val, argp);
     384         [ #  # ]:          0 :                 if (ret)
     385                 :            :                         return ret;
     386                 :            :         }
     387                 :            : 
     388                 :          0 :         ret = mutex_lock_interruptible(&dev->lock);
     389         [ #  # ]:          0 :         if (ret)
     390                 :            :                 return ret;
     391                 :            : 
     392         [ #  # ]:          0 :         if (!dev->registered) {
     393                 :            :                 ret = -ENODEV;
     394                 :            :                 goto out;
     395                 :            :         }
     396                 :            : 
     397   [ #  #  #  #  :          0 :         switch (cmd) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     398                 :            :         case LIRC_GET_FEATURES:
     399         [ #  # ]:          0 :                 if (dev->driver_type == RC_DRIVER_SCANCODE)
     400                 :          0 :                         val |= LIRC_CAN_REC_SCANCODE;
     401                 :            : 
     402         [ #  # ]:          0 :                 if (dev->driver_type == RC_DRIVER_IR_RAW) {
     403                 :          0 :                         val |= LIRC_CAN_REC_MODE2;
     404         [ #  # ]:          0 :                         if (dev->rx_resolution)
     405                 :          0 :                                 val |= LIRC_CAN_GET_REC_RESOLUTION;
     406                 :            :                 }
     407                 :            : 
     408         [ #  # ]:          0 :                 if (dev->tx_ir) {
     409                 :          0 :                         val |= LIRC_CAN_SEND_PULSE;
     410         [ #  # ]:          0 :                         if (dev->s_tx_mask)
     411                 :          0 :                                 val |= LIRC_CAN_SET_TRANSMITTER_MASK;
     412         [ #  # ]:          0 :                         if (dev->s_tx_carrier)
     413                 :          0 :                                 val |= LIRC_CAN_SET_SEND_CARRIER;
     414         [ #  # ]:          0 :                         if (dev->s_tx_duty_cycle)
     415                 :          0 :                                 val |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
     416                 :            :                 }
     417                 :            : 
     418         [ #  # ]:          0 :                 if (dev->s_rx_carrier_range)
     419                 :          0 :                         val |= LIRC_CAN_SET_REC_CARRIER |
     420                 :            :                                 LIRC_CAN_SET_REC_CARRIER_RANGE;
     421                 :            : 
     422         [ #  # ]:          0 :                 if (dev->s_learning_mode)
     423                 :          0 :                         val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
     424                 :            : 
     425         [ #  # ]:          0 :                 if (dev->s_carrier_report)
     426                 :          0 :                         val |= LIRC_CAN_MEASURE_CARRIER;
     427                 :            : 
     428         [ #  # ]:          0 :                 if (dev->max_timeout)
     429                 :          0 :                         val |= LIRC_CAN_SET_REC_TIMEOUT;
     430                 :            : 
     431                 :            :                 break;
     432                 :            : 
     433                 :            :         /* mode support */
     434                 :            :         case LIRC_GET_REC_MODE:
     435         [ #  # ]:          0 :                 if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
     436                 :            :                         ret = -ENOTTY;
     437                 :            :                 else
     438                 :          0 :                         val = fh->rec_mode;
     439                 :            :                 break;
     440                 :            : 
     441                 :            :         case LIRC_SET_REC_MODE:
     442   [ #  #  #  # ]:          0 :                 switch (dev->driver_type) {
     443                 :            :                 case RC_DRIVER_IR_RAW_TX:
     444                 :            :                         ret = -ENOTTY;
     445                 :          0 :                         break;
     446                 :            :                 case RC_DRIVER_SCANCODE:
     447         [ #  # ]:          0 :                         if (val != LIRC_MODE_SCANCODE)
     448                 :            :                                 ret = -EINVAL;
     449                 :            :                         break;
     450                 :            :                 case RC_DRIVER_IR_RAW:
     451         [ #  # ]:          0 :                         if (!(val == LIRC_MODE_MODE2 ||
     452                 :          0 :                               val == LIRC_MODE_SCANCODE))
     453                 :            :                                 ret = -EINVAL;
     454                 :            :                         break;
     455                 :            :                 }
     456                 :            : 
     457         [ #  # ]:          0 :                 if (!ret)
     458                 :          0 :                         fh->rec_mode = val;
     459                 :            :                 break;
     460                 :            : 
     461                 :            :         case LIRC_GET_SEND_MODE:
     462         [ #  # ]:          0 :                 if (!dev->tx_ir)
     463                 :            :                         ret = -ENOTTY;
     464                 :            :                 else
     465                 :          0 :                         val = fh->send_mode;
     466                 :            :                 break;
     467                 :            : 
     468                 :            :         case LIRC_SET_SEND_MODE:
     469         [ #  # ]:          0 :                 if (!dev->tx_ir)
     470                 :            :                         ret = -ENOTTY;
     471         [ #  # ]:          0 :                 else if (!(val == LIRC_MODE_PULSE || val == LIRC_MODE_SCANCODE))
     472                 :            :                         ret = -EINVAL;
     473                 :            :                 else
     474                 :          0 :                         fh->send_mode = val;
     475                 :            :                 break;
     476                 :            : 
     477                 :            :         /* TX settings */
     478                 :            :         case LIRC_SET_TRANSMITTER_MASK:
     479         [ #  # ]:          0 :                 if (!dev->s_tx_mask)
     480                 :            :                         ret = -ENOTTY;
     481                 :            :                 else
     482                 :          0 :                         ret = dev->s_tx_mask(dev, val);
     483                 :            :                 break;
     484                 :            : 
     485                 :            :         case LIRC_SET_SEND_CARRIER:
     486         [ #  # ]:          0 :                 if (!dev->s_tx_carrier)
     487                 :            :                         ret = -ENOTTY;
     488                 :            :                 else
     489                 :          0 :                         ret = dev->s_tx_carrier(dev, val);
     490                 :            :                 break;
     491                 :            : 
     492                 :            :         case LIRC_SET_SEND_DUTY_CYCLE:
     493         [ #  # ]:          0 :                 if (!dev->s_tx_duty_cycle)
     494                 :            :                         ret = -ENOTTY;
     495         [ #  # ]:          0 :                 else if (val <= 0 || val >= 100)
     496                 :            :                         ret = -EINVAL;
     497                 :            :                 else
     498                 :          0 :                         ret = dev->s_tx_duty_cycle(dev, val);
     499                 :            :                 break;
     500                 :            : 
     501                 :            :         /* RX settings */
     502                 :            :         case LIRC_SET_REC_CARRIER:
     503         [ #  # ]:          0 :                 if (!dev->s_rx_carrier_range)
     504                 :            :                         ret = -ENOTTY;
     505         [ #  # ]:          0 :                 else if (val <= 0)
     506                 :            :                         ret = -EINVAL;
     507                 :            :                 else
     508                 :          0 :                         ret = dev->s_rx_carrier_range(dev, fh->carrier_low,
     509                 :            :                                                       val);
     510                 :            :                 break;
     511                 :            : 
     512                 :            :         case LIRC_SET_REC_CARRIER_RANGE:
     513         [ #  # ]:          0 :                 if (!dev->s_rx_carrier_range)
     514                 :            :                         ret = -ENOTTY;
     515         [ #  # ]:          0 :                 else if (val <= 0)
     516                 :            :                         ret = -EINVAL;
     517                 :            :                 else
     518                 :          0 :                         fh->carrier_low = val;
     519                 :            :                 break;
     520                 :            : 
     521                 :            :         case LIRC_GET_REC_RESOLUTION:
     522         [ #  # ]:          0 :                 if (!dev->rx_resolution)
     523                 :            :                         ret = -ENOTTY;
     524                 :            :                 else
     525                 :          0 :                         val = dev->rx_resolution / 1000;
     526                 :            :                 break;
     527                 :            : 
     528                 :            :         case LIRC_SET_WIDEBAND_RECEIVER:
     529         [ #  # ]:          0 :                 if (!dev->s_learning_mode)
     530                 :            :                         ret = -ENOTTY;
     531                 :            :                 else
     532                 :          0 :                         ret = dev->s_learning_mode(dev, !!val);
     533                 :            :                 break;
     534                 :            : 
     535                 :            :         case LIRC_SET_MEASURE_CARRIER_MODE:
     536         [ #  # ]:          0 :                 if (!dev->s_carrier_report)
     537                 :            :                         ret = -ENOTTY;
     538                 :            :                 else
     539                 :          0 :                         ret = dev->s_carrier_report(dev, !!val);
     540                 :            :                 break;
     541                 :            : 
     542                 :            :         /* Generic timeout support */
     543                 :            :         case LIRC_GET_MIN_TIMEOUT:
     544         [ #  # ]:          0 :                 if (!dev->max_timeout)
     545                 :            :                         ret = -ENOTTY;
     546                 :            :                 else
     547                 :          0 :                         val = DIV_ROUND_UP(dev->min_timeout, 1000);
     548                 :            :                 break;
     549                 :            : 
     550                 :            :         case LIRC_GET_MAX_TIMEOUT:
     551         [ #  # ]:          0 :                 if (!dev->max_timeout)
     552                 :            :                         ret = -ENOTTY;
     553                 :            :                 else
     554                 :          0 :                         val = dev->max_timeout / 1000;
     555                 :            :                 break;
     556                 :            : 
     557                 :            :         case LIRC_SET_REC_TIMEOUT:
     558         [ #  # ]:          0 :                 if (!dev->max_timeout) {
     559                 :            :                         ret = -ENOTTY;
     560         [ #  # ]:          0 :                 } else if (val > U32_MAX / 1000) {
     561                 :            :                         /* Check for multiply overflow */
     562                 :            :                         ret = -EINVAL;
     563                 :            :                 } else {
     564                 :          0 :                         u32 tmp = val * 1000;
     565                 :            : 
     566   [ #  #  #  # ]:          0 :                         if (tmp < dev->min_timeout || tmp > dev->max_timeout)
     567                 :            :                                 ret = -EINVAL;
     568         [ #  # ]:          0 :                         else if (dev->s_timeout)
     569                 :          0 :                                 ret = dev->s_timeout(dev, tmp);
     570                 :            :                         else
     571                 :          0 :                                 dev->timeout = tmp;
     572                 :            :                 }
     573                 :            :                 break;
     574                 :            : 
     575                 :            :         case LIRC_GET_REC_TIMEOUT:
     576         [ #  # ]:          0 :                 if (!dev->timeout)
     577                 :            :                         ret = -ENOTTY;
     578                 :            :                 else
     579                 :          0 :                         val = DIV_ROUND_UP(dev->timeout, 1000);
     580                 :            :                 break;
     581                 :            : 
     582                 :            :         case LIRC_SET_REC_TIMEOUT_REPORTS:
     583         [ #  # ]:          0 :                 if (dev->driver_type != RC_DRIVER_IR_RAW)
     584                 :            :                         ret = -ENOTTY;
     585                 :            :                 else
     586                 :          0 :                         fh->send_timeout_reports = !!val;
     587                 :            :                 break;
     588                 :            : 
     589                 :            :         default:
     590                 :            :                 ret = -ENOTTY;
     591                 :            :         }
     592                 :            : 
     593         [ #  # ]:          0 :         if (!ret && _IOC_DIR(cmd) & _IOC_READ)
     594                 :          0 :                 ret = put_user(val, argp);
     595                 :            : 
     596                 :            : out:
     597                 :          0 :         mutex_unlock(&dev->lock);
     598                 :          0 :         return ret;
     599                 :            : }
     600                 :            : 
     601                 :          0 : static __poll_t ir_lirc_poll(struct file *file, struct poll_table_struct *wait)
     602                 :            : {
     603                 :          0 :         struct lirc_fh *fh = file->private_data;
     604                 :          0 :         struct rc_dev *rcdev = fh->rc;
     605                 :            :         __poll_t events = 0;
     606                 :            : 
     607                 :          0 :         poll_wait(file, &fh->wait_poll, wait);
     608                 :            : 
     609         [ #  # ]:          0 :         if (!rcdev->registered) {
     610                 :            :                 events = EPOLLHUP | EPOLLERR;
     611         [ #  # ]:          0 :         } else if (rcdev->driver_type != RC_DRIVER_IR_RAW_TX) {
     612   [ #  #  #  # ]:          0 :                 if (fh->rec_mode == LIRC_MODE_SCANCODE &&
     613                 :          0 :                     !kfifo_is_empty(&fh->scancodes))
     614                 :            :                         events = EPOLLIN | EPOLLRDNORM;
     615                 :            : 
     616   [ #  #  #  # ]:          0 :                 if (fh->rec_mode == LIRC_MODE_MODE2 &&
     617                 :          0 :                     !kfifo_is_empty(&fh->rawir))
     618                 :            :                         events = EPOLLIN | EPOLLRDNORM;
     619                 :            :         }
     620                 :            : 
     621                 :          0 :         return events;
     622                 :            : }
     623                 :            : 
     624                 :          0 : static ssize_t ir_lirc_read_mode2(struct file *file, char __user *buffer,
     625                 :            :                                   size_t length)
     626                 :            : {
     627                 :          0 :         struct lirc_fh *fh = file->private_data;
     628                 :          0 :         struct rc_dev *rcdev = fh->rc;
     629                 :            :         unsigned int copied;
     630                 :            :         int ret;
     631                 :            : 
     632   [ #  #  #  # ]:          0 :         if (length < sizeof(unsigned int) || length % sizeof(unsigned int))
     633                 :            :                 return -EINVAL;
     634                 :            : 
     635                 :            :         do {
     636         [ #  # ]:          0 :                 if (kfifo_is_empty(&fh->rawir)) {
     637         [ #  # ]:          0 :                         if (file->f_flags & O_NONBLOCK)
     638                 :            :                                 return -EAGAIN;
     639                 :            : 
     640   [ #  #  #  #  :          0 :                         ret = wait_event_interruptible(fh->wait_poll,
          #  #  #  #  #  
                      # ]
     641                 :            :                                         !kfifo_is_empty(&fh->rawir) ||
     642                 :            :                                         !rcdev->registered);
     643         [ #  # ]:          0 :                         if (ret)
     644                 :          0 :                                 return ret;
     645                 :            :                 }
     646                 :            : 
     647         [ #  # ]:          0 :                 if (!rcdev->registered)
     648                 :            :                         return -ENODEV;
     649                 :            : 
     650                 :          0 :                 ret = mutex_lock_interruptible(&rcdev->lock);
     651         [ #  # ]:          0 :                 if (ret)
     652                 :          0 :                         return ret;
     653                 :          0 :                 ret = kfifo_to_user(&fh->rawir, buffer, length, &copied);
     654                 :          0 :                 mutex_unlock(&rcdev->lock);
     655         [ #  # ]:          0 :                 if (ret)
     656                 :          0 :                         return ret;
     657         [ #  # ]:          0 :         } while (copied == 0);
     658                 :            : 
     659                 :          0 :         return copied;
     660                 :            : }
     661                 :            : 
     662                 :          0 : static ssize_t ir_lirc_read_scancode(struct file *file, char __user *buffer,
     663                 :            :                                      size_t length)
     664                 :            : {
     665                 :          0 :         struct lirc_fh *fh = file->private_data;
     666                 :          0 :         struct rc_dev *rcdev = fh->rc;
     667                 :            :         unsigned int copied;
     668                 :            :         int ret;
     669                 :            : 
     670   [ #  #  #  # ]:          0 :         if (length < sizeof(struct lirc_scancode) ||
     671                 :          0 :             length % sizeof(struct lirc_scancode))
     672                 :            :                 return -EINVAL;
     673                 :            : 
     674                 :            :         do {
     675         [ #  # ]:          0 :                 if (kfifo_is_empty(&fh->scancodes)) {
     676         [ #  # ]:          0 :                         if (file->f_flags & O_NONBLOCK)
     677                 :            :                                 return -EAGAIN;
     678                 :            : 
     679   [ #  #  #  #  :          0 :                         ret = wait_event_interruptible(fh->wait_poll,
          #  #  #  #  #  
                      # ]
     680                 :            :                                         !kfifo_is_empty(&fh->scancodes) ||
     681                 :            :                                         !rcdev->registered);
     682         [ #  # ]:          0 :                         if (ret)
     683                 :          0 :                                 return ret;
     684                 :            :                 }
     685                 :            : 
     686         [ #  # ]:          0 :                 if (!rcdev->registered)
     687                 :            :                         return -ENODEV;
     688                 :            : 
     689                 :          0 :                 ret = mutex_lock_interruptible(&rcdev->lock);
     690         [ #  # ]:          0 :                 if (ret)
     691                 :          0 :                         return ret;
     692                 :          0 :                 ret = kfifo_to_user(&fh->scancodes, buffer, length, &copied);
     693                 :          0 :                 mutex_unlock(&rcdev->lock);
     694         [ #  # ]:          0 :                 if (ret)
     695                 :          0 :                         return ret;
     696         [ #  # ]:          0 :         } while (copied == 0);
     697                 :            : 
     698                 :          0 :         return copied;
     699                 :            : }
     700                 :            : 
     701                 :          0 : static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
     702                 :            :                             size_t length, loff_t *ppos)
     703                 :            : {
     704                 :          0 :         struct lirc_fh *fh = file->private_data;
     705                 :          0 :         struct rc_dev *rcdev = fh->rc;
     706                 :            : 
     707         [ #  # ]:          0 :         if (rcdev->driver_type == RC_DRIVER_IR_RAW_TX)
     708                 :            :                 return -EINVAL;
     709                 :            : 
     710         [ #  # ]:          0 :         if (!rcdev->registered)
     711                 :            :                 return -ENODEV;
     712                 :            : 
     713         [ #  # ]:          0 :         if (fh->rec_mode == LIRC_MODE_MODE2)
     714                 :          0 :                 return ir_lirc_read_mode2(file, buffer, length);
     715                 :            :         else /* LIRC_MODE_SCANCODE */
     716                 :          0 :                 return ir_lirc_read_scancode(file, buffer, length);
     717                 :            : }
     718                 :            : 
     719                 :            : static const struct file_operations lirc_fops = {
     720                 :            :         .owner          = THIS_MODULE,
     721                 :            :         .write          = ir_lirc_transmit_ir,
     722                 :            :         .unlocked_ioctl = ir_lirc_ioctl,
     723                 :            : #ifdef CONFIG_COMPAT
     724                 :            :         .compat_ioctl   = ir_lirc_ioctl,
     725                 :            : #endif
     726                 :            :         .read           = ir_lirc_read,
     727                 :            :         .poll           = ir_lirc_poll,
     728                 :            :         .open           = ir_lirc_open,
     729                 :            :         .release        = ir_lirc_close,
     730                 :            :         .llseek         = no_llseek,
     731                 :            : };
     732                 :            : 
     733                 :          0 : static void lirc_release_device(struct device *ld)
     734                 :            : {
     735                 :            :         struct rc_dev *rcdev = container_of(ld, struct rc_dev, lirc_dev);
     736                 :            : 
     737                 :          0 :         put_device(&rcdev->dev);
     738                 :          0 : }
     739                 :            : 
     740                 :          0 : int ir_lirc_register(struct rc_dev *dev)
     741                 :            : {
     742                 :            :         const char *rx_type, *tx_type;
     743                 :            :         int err, minor;
     744                 :            : 
     745                 :          0 :         minor = ida_simple_get(&lirc_ida, 0, RC_DEV_MAX, GFP_KERNEL);
     746         [ #  # ]:          0 :         if (minor < 0)
     747                 :            :                 return minor;
     748                 :            : 
     749                 :          0 :         device_initialize(&dev->lirc_dev);
     750                 :          0 :         dev->lirc_dev.class = lirc_class;
     751                 :          0 :         dev->lirc_dev.parent = &dev->dev;
     752                 :          0 :         dev->lirc_dev.release = lirc_release_device;
     753                 :          0 :         dev->lirc_dev.devt = MKDEV(MAJOR(lirc_base_dev), minor);
     754                 :          0 :         dev_set_name(&dev->lirc_dev, "lirc%d", minor);
     755                 :            : 
     756                 :          0 :         INIT_LIST_HEAD(&dev->lirc_fh);
     757                 :          0 :         spin_lock_init(&dev->lirc_fh_lock);
     758                 :            : 
     759                 :          0 :         cdev_init(&dev->lirc_cdev, &lirc_fops);
     760                 :            : 
     761                 :          0 :         err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev);
     762         [ #  # ]:          0 :         if (err)
     763                 :            :                 goto out_ida;
     764                 :            : 
     765                 :          0 :         get_device(&dev->dev);
     766                 :            : 
     767      [ #  #  # ]:          0 :         switch (dev->driver_type) {
     768                 :            :         case RC_DRIVER_SCANCODE:
     769                 :            :                 rx_type = "scancode";
     770                 :            :                 break;
     771                 :            :         case RC_DRIVER_IR_RAW:
     772                 :            :                 rx_type = "raw IR";
     773                 :          0 :                 break;
     774                 :            :         default:
     775                 :            :                 rx_type = "no";
     776                 :          0 :                 break;
     777                 :            :         }
     778                 :            : 
     779         [ #  # ]:          0 :         if (dev->tx_ir)
     780                 :            :                 tx_type = "raw IR";
     781                 :            :         else
     782                 :            :                 tx_type = "no";
     783                 :            : 
     784                 :          0 :         dev_info(&dev->dev, "lirc_dev: driver %s registered at minor = %d, %s receiver, %s transmitter",
     785                 :            :                  dev->driver_name, minor, rx_type, tx_type);
     786                 :            : 
     787                 :          0 :         return 0;
     788                 :            : 
     789                 :            : out_ida:
     790                 :          0 :         ida_simple_remove(&lirc_ida, minor);
     791                 :          0 :         return err;
     792                 :            : }
     793                 :            : 
     794                 :          0 : void ir_lirc_unregister(struct rc_dev *dev)
     795                 :            : {
     796                 :            :         unsigned long flags;
     797                 :            :         struct lirc_fh *fh;
     798                 :            : 
     799                 :            :         dev_dbg(&dev->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
     800                 :            :                 dev->driver_name, MINOR(dev->lirc_dev.devt));
     801                 :            : 
     802                 :          0 :         spin_lock_irqsave(&dev->lirc_fh_lock, flags);
     803         [ #  # ]:          0 :         list_for_each_entry(fh, &dev->lirc_fh, list)
     804                 :          0 :                 wake_up_poll(&fh->wait_poll, EPOLLHUP | EPOLLERR);
     805                 :            :         spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
     806                 :            : 
     807                 :          0 :         cdev_device_del(&dev->lirc_cdev, &dev->lirc_dev);
     808                 :          0 :         ida_simple_remove(&lirc_ida, MINOR(dev->lirc_dev.devt));
     809                 :          0 : }
     810                 :            : 
     811                 :        404 : int __init lirc_dev_init(void)
     812                 :            : {
     813                 :            :         int retval;
     814                 :            : 
     815                 :        404 :         lirc_class = class_create(THIS_MODULE, "lirc");
     816         [ -  + ]:        404 :         if (IS_ERR(lirc_class)) {
     817                 :          0 :                 pr_err("class_create failed\n");
     818                 :          0 :                 return PTR_ERR(lirc_class);
     819                 :            :         }
     820                 :            : 
     821                 :        404 :         retval = alloc_chrdev_region(&lirc_base_dev, 0, RC_DEV_MAX,
     822                 :            :                                      "BaseRemoteCtl");
     823         [ -  + ]:        404 :         if (retval) {
     824                 :          0 :                 class_destroy(lirc_class);
     825                 :          0 :                 pr_err("alloc_chrdev_region failed\n");
     826                 :          0 :                 return retval;
     827                 :            :         }
     828                 :            : 
     829                 :            :         pr_debug("IR Remote Control driver registered, major %d\n",
     830                 :            :                  MAJOR(lirc_base_dev));
     831                 :            : 
     832                 :            :         return 0;
     833                 :            : }
     834                 :            : 
     835                 :          0 : void __exit lirc_dev_exit(void)
     836                 :            : {
     837                 :          0 :         class_destroy(lirc_class);
     838                 :          0 :         unregister_chrdev_region(lirc_base_dev, RC_DEV_MAX);
     839                 :          0 : }
     840                 :            : 
     841                 :          0 : struct rc_dev *rc_dev_get_from_fd(int fd)
     842                 :            : {
     843                 :          0 :         struct fd f = fdget(fd);
     844                 :            :         struct lirc_fh *fh;
     845                 :            :         struct rc_dev *dev;
     846                 :            : 
     847         [ #  # ]:          0 :         if (!f.file)
     848                 :            :                 return ERR_PTR(-EBADF);
     849                 :            : 
     850         [ #  # ]:          0 :         if (f.file->f_op != &lirc_fops) {
     851                 :            :                 fdput(f);
     852                 :            :                 return ERR_PTR(-EINVAL);
     853                 :            :         }
     854                 :            : 
     855                 :          0 :         fh = f.file->private_data;
     856                 :          0 :         dev = fh->rc;
     857                 :            : 
     858                 :          0 :         get_device(&dev->dev);
     859                 :            :         fdput(f);
     860                 :            : 
     861                 :          0 :         return dev;
     862                 :            : }
     863                 :            : 
     864                 :            : MODULE_ALIAS("lirc_dev");

Generated by: LCOV version 1.14