root/drivers/staging/speakup/devsynth.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. speakup_file_write
  2. speakup_file_read
  3. speakup_file_open
  4. speakup_file_release
  5. speakup_register_devsynth
  6. speakup_unregister_devsynth

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <linux/errno.h>
   3 #include <linux/miscdevice.h>   /* for misc_register, and SYNTH_MINOR */
   4 #include <linux/types.h>
   5 #include <linux/uaccess.h>
   6 
   7 #include "speakup.h"
   8 #include "spk_priv.h"
   9 
  10 #ifndef SYNTH_MINOR
  11 #define SYNTH_MINOR 25
  12 #endif
  13 
  14 static int misc_registered;
  15 static int dev_opened;
  16 
  17 static ssize_t speakup_file_write(struct file *fp, const char __user *buffer,
  18                                   size_t nbytes, loff_t *ppos)
  19 {
  20         size_t count = nbytes;
  21         const char __user *ptr = buffer;
  22         size_t bytes;
  23         unsigned long flags;
  24         u_char buf[256];
  25 
  26         if (!synth)
  27                 return -ENODEV;
  28         while (count > 0) {
  29                 bytes = min(count, sizeof(buf));
  30                 if (copy_from_user(buf, ptr, bytes))
  31                         return -EFAULT;
  32                 count -= bytes;
  33                 ptr += bytes;
  34                 spin_lock_irqsave(&speakup_info.spinlock, flags);
  35                 synth_write(buf, bytes);
  36                 spin_unlock_irqrestore(&speakup_info.spinlock, flags);
  37         }
  38         return (ssize_t)nbytes;
  39 }
  40 
  41 static ssize_t speakup_file_read(struct file *fp, char __user *buf,
  42                                  size_t nbytes, loff_t *ppos)
  43 {
  44         return 0;
  45 }
  46 
  47 static int speakup_file_open(struct inode *ip, struct file *fp)
  48 {
  49         if (!synth)
  50                 return -ENODEV;
  51         if (xchg(&dev_opened, 1))
  52                 return -EBUSY;
  53         return 0;
  54 }
  55 
  56 static int speakup_file_release(struct inode *ip, struct file *fp)
  57 {
  58         dev_opened = 0;
  59         return 0;
  60 }
  61 
  62 static const struct file_operations synth_fops = {
  63         .read = speakup_file_read,
  64         .write = speakup_file_write,
  65         .open = speakup_file_open,
  66         .release = speakup_file_release,
  67 };
  68 
  69 static struct miscdevice synth_device = {
  70         .minor = SYNTH_MINOR,
  71         .name = "synth",
  72         .fops = &synth_fops,
  73 };
  74 
  75 void speakup_register_devsynth(void)
  76 {
  77         if (misc_registered != 0)
  78                 return;
  79 /* zero it so if register fails, deregister will not ref invalid ptrs */
  80         if (misc_register(&synth_device)) {
  81                 pr_warn("Couldn't initialize miscdevice /dev/synth.\n");
  82         } else {
  83                 pr_info("initialized device: /dev/synth, node (MAJOR %d, MINOR %d)\n",
  84                         MISC_MAJOR, SYNTH_MINOR);
  85                 misc_registered = 1;
  86         }
  87 }
  88 
  89 void speakup_unregister_devsynth(void)
  90 {
  91         if (!misc_registered)
  92                 return;
  93         pr_info("speakup: unregistering synth device /dev/synth\n");
  94         misc_deregister(&synth_device);
  95         misc_registered = 0;
  96 }

/* [<][>][^][v][top][bottom][index][help] */