0001
0002
0003
0004
0005
0006
0007 #include "opl4_local.h"
0008 #include <linux/vmalloc.h>
0009 #include <linux/export.h>
0010 #include <sound/info.h>
0011
0012 static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
0013 unsigned short mode, void **file_private_data)
0014 {
0015 struct snd_opl4 *opl4 = entry->private_data;
0016
0017 mutex_lock(&opl4->access_mutex);
0018 if (opl4->memory_access) {
0019 mutex_unlock(&opl4->access_mutex);
0020 return -EBUSY;
0021 }
0022 opl4->memory_access++;
0023 mutex_unlock(&opl4->access_mutex);
0024 return 0;
0025 }
0026
0027 static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
0028 unsigned short mode, void *file_private_data)
0029 {
0030 struct snd_opl4 *opl4 = entry->private_data;
0031
0032 mutex_lock(&opl4->access_mutex);
0033 opl4->memory_access--;
0034 mutex_unlock(&opl4->access_mutex);
0035 return 0;
0036 }
0037
0038 static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry,
0039 void *file_private_data,
0040 struct file *file, char __user *_buf,
0041 size_t count, loff_t pos)
0042 {
0043 struct snd_opl4 *opl4 = entry->private_data;
0044 char* buf;
0045
0046 buf = vmalloc(count);
0047 if (!buf)
0048 return -ENOMEM;
0049 snd_opl4_read_memory(opl4, buf, pos, count);
0050 if (copy_to_user(_buf, buf, count)) {
0051 vfree(buf);
0052 return -EFAULT;
0053 }
0054 vfree(buf);
0055 return count;
0056 }
0057
0058 static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
0059 void *file_private_data,
0060 struct file *file,
0061 const char __user *_buf,
0062 size_t count, loff_t pos)
0063 {
0064 struct snd_opl4 *opl4 = entry->private_data;
0065 char *buf;
0066
0067 buf = vmalloc(count);
0068 if (!buf)
0069 return -ENOMEM;
0070 if (copy_from_user(buf, _buf, count)) {
0071 vfree(buf);
0072 return -EFAULT;
0073 }
0074 snd_opl4_write_memory(opl4, buf, pos, count);
0075 vfree(buf);
0076 return count;
0077 }
0078
0079 static const struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
0080 .open = snd_opl4_mem_proc_open,
0081 .release = snd_opl4_mem_proc_release,
0082 .read = snd_opl4_mem_proc_read,
0083 .write = snd_opl4_mem_proc_write,
0084 };
0085
0086 int snd_opl4_create_proc(struct snd_opl4 *opl4)
0087 {
0088 struct snd_info_entry *entry;
0089
0090 entry = snd_info_create_card_entry(opl4->card, "opl4-mem", opl4->card->proc_root);
0091 if (entry) {
0092 if (opl4->hardware < OPL3_HW_OPL4_ML) {
0093
0094 entry->mode |= 0200;
0095 entry->size = 4 * 1024 * 1024;
0096 } else {
0097
0098 entry->size = 1 * 1024 * 1024;
0099 }
0100 entry->content = SNDRV_INFO_CONTENT_DATA;
0101 entry->c.ops = &snd_opl4_mem_proc_ops;
0102 entry->module = THIS_MODULE;
0103 entry->private_data = opl4;
0104 }
0105 opl4->proc_entry = entry;
0106 return 0;
0107 }
0108
0109 void snd_opl4_free_proc(struct snd_opl4 *opl4)
0110 {
0111 snd_info_free_entry(opl4->proc_entry);
0112 }