~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/hda/hda_hwdep.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * HWDEP Interface for HD-audio codec
  4  *
  5  * Copyright (c) 2007 Takashi Iwai <tiwai@suse.de>
  6  */
  7 
  8 #include <linux/init.h>
  9 #include <linux/slab.h>
 10 #include <linux/compat.h>
 11 #include <linux/nospec.h>
 12 #include <sound/core.h>
 13 #include <sound/hda_codec.h>
 14 #include "hda_local.h"
 15 #include <sound/hda_hwdep.h>
 16 #include <sound/minors.h>
 17 
 18 /*
 19  * write/read an out-of-bound verb
 20  */
 21 static int verb_write_ioctl(struct hda_codec *codec,
 22                             struct hda_verb_ioctl __user *arg)
 23 {
 24         u32 verb, res;
 25 
 26         if (get_user(verb, &arg->verb))
 27                 return -EFAULT;
 28         res = snd_hda_codec_read(codec, verb >> 24, 0,
 29                                  (verb >> 8) & 0xffff, verb & 0xff);
 30         if (put_user(res, &arg->res))
 31                 return -EFAULT;
 32         return 0;
 33 }
 34 
 35 static int get_wcap_ioctl(struct hda_codec *codec,
 36                           struct hda_verb_ioctl __user *arg)
 37 {
 38         u32 verb, res;
 39         
 40         if (get_user(verb, &arg->verb))
 41                 return -EFAULT;
 42         /* open-code get_wcaps(verb>>24) with nospec */
 43         verb >>= 24;
 44         if (verb < codec->core.start_nid ||
 45             verb >= codec->core.start_nid + codec->core.num_nodes) {
 46                 res = 0;
 47         } else {
 48                 verb -= codec->core.start_nid;
 49                 verb = array_index_nospec(verb, codec->core.num_nodes);
 50                 res = codec->wcaps[verb];
 51         }
 52         if (put_user(res, &arg->res))
 53                 return -EFAULT;
 54         return 0;
 55 }
 56 
 57 
 58 /*
 59  */
 60 static int hda_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
 61                            unsigned int cmd, unsigned long arg)
 62 {
 63         struct hda_codec *codec = hw->private_data;
 64         void __user *argp = (void __user *)arg;
 65 
 66         switch (cmd) {
 67         case HDA_IOCTL_PVERSION:
 68                 return put_user(HDA_HWDEP_VERSION, (int __user *)argp);
 69         case HDA_IOCTL_VERB_WRITE:
 70                 return verb_write_ioctl(codec, argp);
 71         case HDA_IOCTL_GET_WCAP:
 72                 return get_wcap_ioctl(codec, argp);
 73         }
 74         return -ENOIOCTLCMD;
 75 }
 76 
 77 #ifdef CONFIG_COMPAT
 78 static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
 79                                   unsigned int cmd, unsigned long arg)
 80 {
 81         return hda_hwdep_ioctl(hw, file, cmd, (unsigned long)compat_ptr(arg));
 82 }
 83 #endif
 84 
 85 static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
 86 {
 87 #ifndef CONFIG_SND_DEBUG_VERBOSE
 88         if (!capable(CAP_SYS_RAWIO))
 89                 return -EACCES;
 90 #endif
 91         return 0;
 92 }
 93 
 94 int snd_hda_create_hwdep(struct hda_codec *codec)
 95 {
 96         char hwname[16];
 97         struct snd_hwdep *hwdep;
 98         int err;
 99 
100         sprintf(hwname, "HDA Codec %d", codec->addr);
101         err = snd_hwdep_new(codec->card, hwname, codec->addr, &hwdep);
102         if (err < 0)
103                 return err;
104         codec->hwdep = hwdep;
105         sprintf(hwdep->name, "HDA Codec %d", codec->addr);
106         hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
107         hwdep->private_data = codec;
108         hwdep->exclusive = 1;
109 
110         hwdep->ops.open = hda_hwdep_open;
111         hwdep->ops.ioctl = hda_hwdep_ioctl;
112 #ifdef CONFIG_COMPAT
113         hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat;
114 #endif
115 
116         /* for sysfs */
117         hwdep->dev->groups = snd_hda_dev_attr_groups;
118         dev_set_drvdata(hwdep->dev, codec);
119 
120         return 0;
121 }
122 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php