cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

opl4_proc.c (2723B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Functions for the OPL4 proc file
      4 * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
      5 */
      6
      7#include "opl4_local.h"
      8#include <linux/vmalloc.h>
      9#include <linux/export.h>
     10#include <sound/info.h>
     11
     12static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
     13				  unsigned short mode, void **file_private_data)
     14{
     15	struct snd_opl4 *opl4 = entry->private_data;
     16
     17	mutex_lock(&opl4->access_mutex);
     18	if (opl4->memory_access) {
     19		mutex_unlock(&opl4->access_mutex);
     20		return -EBUSY;
     21	}
     22	opl4->memory_access++;
     23	mutex_unlock(&opl4->access_mutex);
     24	return 0;
     25}
     26
     27static int snd_opl4_mem_proc_release(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	opl4->memory_access--;
     34	mutex_unlock(&opl4->access_mutex);
     35	return 0;
     36}
     37
     38static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry,
     39				      void *file_private_data,
     40				      struct file *file, char __user *_buf,
     41				      size_t count, loff_t pos)
     42{
     43	struct snd_opl4 *opl4 = entry->private_data;
     44	char* buf;
     45
     46	buf = vmalloc(count);
     47	if (!buf)
     48		return -ENOMEM;
     49	snd_opl4_read_memory(opl4, buf, pos, count);
     50	if (copy_to_user(_buf, buf, count)) {
     51		vfree(buf);
     52		return -EFAULT;
     53	}
     54	vfree(buf);
     55	return count;
     56}
     57
     58static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
     59				       void *file_private_data,
     60				       struct file *file,
     61				       const char __user *_buf,
     62				       size_t count, loff_t pos)
     63{
     64	struct snd_opl4 *opl4 = entry->private_data;
     65	char *buf;
     66
     67	buf = vmalloc(count);
     68	if (!buf)
     69		return -ENOMEM;
     70	if (copy_from_user(buf, _buf, count)) {
     71		vfree(buf);
     72		return -EFAULT;
     73	}
     74	snd_opl4_write_memory(opl4, buf, pos, count);
     75	vfree(buf);
     76	return count;
     77}
     78
     79static const struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
     80	.open = snd_opl4_mem_proc_open,
     81	.release = snd_opl4_mem_proc_release,
     82	.read = snd_opl4_mem_proc_read,
     83	.write = snd_opl4_mem_proc_write,
     84};
     85
     86int snd_opl4_create_proc(struct snd_opl4 *opl4)
     87{
     88	struct snd_info_entry *entry;
     89
     90	entry = snd_info_create_card_entry(opl4->card, "opl4-mem", opl4->card->proc_root);
     91	if (entry) {
     92		if (opl4->hardware < OPL3_HW_OPL4_ML) {
     93			/* OPL4 can access 4 MB external ROM/SRAM */
     94			entry->mode |= 0200;
     95			entry->size = 4 * 1024 * 1024;
     96		} else {
     97			/* OPL4-ML has 1 MB internal ROM */
     98			entry->size = 1 * 1024 * 1024;
     99		}
    100		entry->content = SNDRV_INFO_CONTENT_DATA;
    101		entry->c.ops = &snd_opl4_mem_proc_ops;
    102		entry->module = THIS_MODULE;
    103		entry->private_data = opl4;
    104	}
    105	opl4->proc_entry = entry;
    106	return 0;
    107}
    108
    109void snd_opl4_free_proc(struct snd_opl4 *opl4)
    110{
    111	snd_info_free_entry(opl4->proc_entry);
    112}