xref: /linux/sound/drivers/opl4/opl4_proc.c (revision 8dd06ef34b6e2f41b29fbf5fc1663780f2524285)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * Functions for the OPL4 proc file
41da177e4SLinus Torvalds  * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
51da177e4SLinus Torvalds  */
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds #include "opl4_local.h"
81da177e4SLinus Torvalds #include <linux/vmalloc.h>
9d81a6d71SPaul Gortmaker #include <linux/export.h>
101da177e4SLinus Torvalds #include <sound/info.h>
111da177e4SLinus Torvalds 
snd_opl4_mem_proc_open(struct snd_info_entry * entry,unsigned short mode,void ** file_private_data)12a42dd420STakashi Iwai static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
131da177e4SLinus Torvalds 				  unsigned short mode, void **file_private_data)
141da177e4SLinus Torvalds {
15a42dd420STakashi Iwai 	struct snd_opl4 *opl4 = entry->private_data;
161da177e4SLinus Torvalds 
17ef9f0a42SIngo Molnar 	mutex_lock(&opl4->access_mutex);
181da177e4SLinus Torvalds 	if (opl4->memory_access) {
19ef9f0a42SIngo Molnar 		mutex_unlock(&opl4->access_mutex);
201da177e4SLinus Torvalds 		return -EBUSY;
211da177e4SLinus Torvalds 	}
221da177e4SLinus Torvalds 	opl4->memory_access++;
23ef9f0a42SIngo Molnar 	mutex_unlock(&opl4->access_mutex);
241da177e4SLinus Torvalds 	return 0;
251da177e4SLinus Torvalds }
261da177e4SLinus Torvalds 
snd_opl4_mem_proc_release(struct snd_info_entry * entry,unsigned short mode,void * file_private_data)27a42dd420STakashi Iwai static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
281da177e4SLinus Torvalds 				     unsigned short mode, void *file_private_data)
291da177e4SLinus Torvalds {
30a42dd420STakashi Iwai 	struct snd_opl4 *opl4 = entry->private_data;
311da177e4SLinus Torvalds 
32ef9f0a42SIngo Molnar 	mutex_lock(&opl4->access_mutex);
331da177e4SLinus Torvalds 	opl4->memory_access--;
34ef9f0a42SIngo Molnar 	mutex_unlock(&opl4->access_mutex);
351da177e4SLinus Torvalds 	return 0;
361da177e4SLinus Torvalds }
371da177e4SLinus Torvalds 
snd_opl4_mem_proc_read(struct snd_info_entry * entry,void * file_private_data,struct file * file,char __user * _buf,size_t count,loff_t pos)3824e4a121STakashi Iwai static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry,
3924e4a121STakashi Iwai 				      void *file_private_data,
401da177e4SLinus Torvalds 				      struct file *file, char __user *_buf,
4124e4a121STakashi Iwai 				      size_t count, loff_t pos)
421da177e4SLinus Torvalds {
43a42dd420STakashi Iwai 	struct snd_opl4 *opl4 = entry->private_data;
441da177e4SLinus Torvalds 	char* buf;
451da177e4SLinus Torvalds 
46d97e1b78STakashi Iwai 	buf = vmalloc(count);
471da177e4SLinus Torvalds 	if (!buf)
481da177e4SLinus Torvalds 		return -ENOMEM;
49d97e1b78STakashi Iwai 	snd_opl4_read_memory(opl4, buf, pos, count);
50d97e1b78STakashi Iwai 	if (copy_to_user(_buf, buf, count)) {
511da177e4SLinus Torvalds 		vfree(buf);
521da177e4SLinus Torvalds 		return -EFAULT;
531da177e4SLinus Torvalds 	}
541da177e4SLinus Torvalds 	vfree(buf);
55d97e1b78STakashi Iwai 	return count;
561da177e4SLinus Torvalds }
571da177e4SLinus Torvalds 
snd_opl4_mem_proc_write(struct snd_info_entry * entry,void * file_private_data,struct file * file,const char __user * _buf,size_t count,loff_t pos)5824e4a121STakashi Iwai static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
5924e4a121STakashi Iwai 				       void *file_private_data,
6024e4a121STakashi Iwai 				       struct file *file,
6124e4a121STakashi Iwai 				       const char __user *_buf,
62670ff6abSTakashi Iwai 				       size_t count, loff_t pos)
631da177e4SLinus Torvalds {
64a42dd420STakashi Iwai 	struct snd_opl4 *opl4 = entry->private_data;
651da177e4SLinus Torvalds 	char *buf;
661da177e4SLinus Torvalds 
67d97e1b78STakashi Iwai 	buf = vmalloc(count);
681da177e4SLinus Torvalds 	if (!buf)
691da177e4SLinus Torvalds 		return -ENOMEM;
70d97e1b78STakashi Iwai 	if (copy_from_user(buf, _buf, count)) {
711da177e4SLinus Torvalds 		vfree(buf);
721da177e4SLinus Torvalds 		return -EFAULT;
731da177e4SLinus Torvalds 	}
74d97e1b78STakashi Iwai 	snd_opl4_write_memory(opl4, buf, pos, count);
751da177e4SLinus Torvalds 	vfree(buf);
76d97e1b78STakashi Iwai 	return count;
771da177e4SLinus Torvalds }
781da177e4SLinus Torvalds 
79*d25ff268STakashi Iwai static const struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
801da177e4SLinus Torvalds 	.open = snd_opl4_mem_proc_open,
811da177e4SLinus Torvalds 	.release = snd_opl4_mem_proc_release,
821da177e4SLinus Torvalds 	.read = snd_opl4_mem_proc_read,
831da177e4SLinus Torvalds 	.write = snd_opl4_mem_proc_write,
841da177e4SLinus Torvalds };
851da177e4SLinus Torvalds 
snd_opl4_create_proc(struct snd_opl4 * opl4)86a42dd420STakashi Iwai int snd_opl4_create_proc(struct snd_opl4 *opl4)
871da177e4SLinus Torvalds {
88a42dd420STakashi Iwai 	struct snd_info_entry *entry;
891da177e4SLinus Torvalds 
901da177e4SLinus Torvalds 	entry = snd_info_create_card_entry(opl4->card, "opl4-mem", opl4->card->proc_root);
911da177e4SLinus Torvalds 	if (entry) {
921da177e4SLinus Torvalds 		if (opl4->hardware < OPL3_HW_OPL4_ML) {
931da177e4SLinus Torvalds 			/* OPL4 can access 4 MB external ROM/SRAM */
946a73cf46SJoe Perches 			entry->mode |= 0200;
951da177e4SLinus Torvalds 			entry->size = 4 * 1024 * 1024;
961da177e4SLinus Torvalds 		} else {
971da177e4SLinus Torvalds 			/* OPL4-ML has 1 MB internal ROM */
981da177e4SLinus Torvalds 			entry->size = 1 * 1024 * 1024;
991da177e4SLinus Torvalds 		}
1001da177e4SLinus Torvalds 		entry->content = SNDRV_INFO_CONTENT_DATA;
1011da177e4SLinus Torvalds 		entry->c.ops = &snd_opl4_mem_proc_ops;
1021da177e4SLinus Torvalds 		entry->module = THIS_MODULE;
1031da177e4SLinus Torvalds 		entry->private_data = opl4;
1041da177e4SLinus Torvalds 	}
1051da177e4SLinus Torvalds 	opl4->proc_entry = entry;
1061da177e4SLinus Torvalds 	return 0;
1071da177e4SLinus Torvalds }
1081da177e4SLinus Torvalds 
snd_opl4_free_proc(struct snd_opl4 * opl4)109a42dd420STakashi Iwai void snd_opl4_free_proc(struct snd_opl4 *opl4)
1101da177e4SLinus Torvalds {
111746d4a02STakashi Iwai 	snd_info_free_entry(opl4->proc_entry);
1121da177e4SLinus Torvalds }
113