linux/sound/drivers/opl4/opl4_proc.c
<<
>>
Prefs
   1/*
   2 * Functions for the OPL4 proc file
   3 * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18 */
  19
  20#include "opl4_local.h"
  21#include <linux/vmalloc.h>
  22#include <linux/export.h>
  23#include <sound/info.h>
  24
  25#ifdef CONFIG_PROC_FS
  26
  27static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
  28                                  unsigned short mode, void **file_private_data)
  29{
  30        struct snd_opl4 *opl4 = entry->private_data;
  31
  32        mutex_lock(&opl4->access_mutex);
  33        if (opl4->memory_access) {
  34                mutex_unlock(&opl4->access_mutex);
  35                return -EBUSY;
  36        }
  37        opl4->memory_access++;
  38        mutex_unlock(&opl4->access_mutex);
  39        return 0;
  40}
  41
  42static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
  43                                     unsigned short mode, void *file_private_data)
  44{
  45        struct snd_opl4 *opl4 = entry->private_data;
  46
  47        mutex_lock(&opl4->access_mutex);
  48        opl4->memory_access--;
  49        mutex_unlock(&opl4->access_mutex);
  50        return 0;
  51}
  52
  53static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry,
  54                                      void *file_private_data,
  55                                      struct file *file, char __user *_buf,
  56                                      size_t count, loff_t pos)
  57{
  58        struct snd_opl4 *opl4 = entry->private_data;
  59        char* buf;
  60
  61        buf = vmalloc(count);
  62        if (!buf)
  63                return -ENOMEM;
  64        snd_opl4_read_memory(opl4, buf, pos, count);
  65        if (copy_to_user(_buf, buf, count)) {
  66                vfree(buf);
  67                return -EFAULT;
  68        }
  69        vfree(buf);
  70        return count;
  71}
  72
  73static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
  74                                       void *file_private_data,
  75                                       struct file *file,
  76                                       const char __user *_buf,
  77                                       size_t count, loff_t pos)
  78{
  79        struct snd_opl4 *opl4 = entry->private_data;
  80        char *buf;
  81
  82        buf = vmalloc(count);
  83        if (!buf)
  84                return -ENOMEM;
  85        if (copy_from_user(buf, _buf, count)) {
  86                vfree(buf);
  87                return -EFAULT;
  88        }
  89        snd_opl4_write_memory(opl4, buf, pos, count);
  90        vfree(buf);
  91        return count;
  92}
  93
  94static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
  95        .open = snd_opl4_mem_proc_open,
  96        .release = snd_opl4_mem_proc_release,
  97        .read = snd_opl4_mem_proc_read,
  98        .write = snd_opl4_mem_proc_write,
  99};
 100
 101int snd_opl4_create_proc(struct snd_opl4 *opl4)
 102{
 103        struct snd_info_entry *entry;
 104
 105        entry = snd_info_create_card_entry(opl4->card, "opl4-mem", opl4->card->proc_root);
 106        if (entry) {
 107                if (opl4->hardware < OPL3_HW_OPL4_ML) {
 108                        /* OPL4 can access 4 MB external ROM/SRAM */
 109                        entry->mode |= S_IWUSR;
 110                        entry->size = 4 * 1024 * 1024;
 111                } else {
 112                        /* OPL4-ML has 1 MB internal ROM */
 113                        entry->size = 1 * 1024 * 1024;
 114                }
 115                entry->content = SNDRV_INFO_CONTENT_DATA;
 116                entry->c.ops = &snd_opl4_mem_proc_ops;
 117                entry->module = THIS_MODULE;
 118                entry->private_data = opl4;
 119                if (snd_info_register(entry) < 0) {
 120                        snd_info_free_entry(entry);
 121                        entry = NULL;
 122                }
 123        }
 124        opl4->proc_entry = entry;
 125        return 0;
 126}
 127
 128void snd_opl4_free_proc(struct snd_opl4 *opl4)
 129{
 130        snd_info_free_entry(opl4->proc_entry);
 131}
 132
 133#endif /* CONFIG_PROC_FS */
 134