⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 v_midi.c

📁 讲述linux的初始化过程
💻 C
字号:
/* * sound/v_midi.c * * The low level driver for the Sound Blaster DS chips. * * * Copyright (C) by Hannu Savolainen 1993-1996 * * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. * ?? * * Changes *	Alan Cox		Modularisation, changed memory allocations *	Christoph Hellwig	Adapted to module_init/module_exit * * Status *	Untested */#include <linux/init.h>#include <linux/module.h>#include "sound_config.h"#include "v_midi.h"static vmidi_devc *v_devc[2] = { NULL, NULL};static int midi1,midi2;static void *midi_mem = NULL;/* * The DSP channel can be used either for input or output. Variable * 'sb_irq_mode' will be set when the program calls read or write first time * after open. Current version doesn't support mode changes without closing * and reopening the device. Support for this feature may be implemented in a * future version of this driver. */void            (*midi_input_intr) (int dev, unsigned char data);static int v_midi_open (int dev, int mode,	      void            (*input) (int dev, unsigned char data),	      void            (*output) (int dev)){	vmidi_devc *devc = midi_devs[dev]->devc;	unsigned long flags;	if (devc == NULL)		return -(ENXIO);	save_flags (flags);	cli();	if (devc->opened)	{		restore_flags (flags);		return -(EBUSY);	}	devc->opened = 1;	restore_flags (flags);	devc->intr_active = 1;	if (mode & OPEN_READ)	{		devc->input_opened = 1;		devc->midi_input_intr = input;	}	return 0;}static void v_midi_close (int dev){	vmidi_devc *devc = midi_devs[dev]->devc;	unsigned long flags;	if (devc == NULL)		return;	save_flags (flags);	cli ();	devc->intr_active = 0;	devc->input_opened = 0;	devc->opened = 0;	restore_flags (flags);}static int v_midi_out (int dev, unsigned char midi_byte){	vmidi_devc *devc = midi_devs[dev]->devc;	vmidi_devc *pdevc = midi_devs[devc->pair_mididev]->devc;	if (devc == NULL)		return -(ENXIO);	if (pdevc->input_opened > 0){		if (MIDIbuf_avail(pdevc->my_mididev) > 500)			return 0;		pdevc->midi_input_intr (pdevc->my_mididev, midi_byte);	}	return 1;}static inline int v_midi_start_read (int dev){	return 0;}static int v_midi_end_read (int dev){	vmidi_devc *devc = midi_devs[dev]->devc;	if (devc == NULL)		return -ENXIO;	devc->intr_active = 0;	return 0;}/* why -EPERM and not -EINVAL?? */static inline int v_midi_ioctl (int dev, unsigned cmd, caddr_t arg){	return -EPERM;}#define MIDI_SYNTH_NAME	"Loopback MIDI"#define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT#include "midi_synth.h"static struct midi_operations v_midi_operations ={	owner:		THIS_MODULE,	info:		{"Loopback MIDI Port 1", 0, 0, SNDCARD_VMIDI},	converter:	&std_midi_synth,	in_info:	{0},	open:		v_midi_open,	close:		v_midi_close,	ioctl:		v_midi_ioctl,	outputc:	v_midi_out,	start_read:	v_midi_start_read,	end_read:	v_midi_end_read,};static struct midi_operations v_midi_operations2 ={	owner:		THIS_MODULE,	info:		{"Loopback MIDI Port 2", 0, 0, SNDCARD_VMIDI},	converter:	&std_midi_synth,	in_info:	{0},	open:		v_midi_open,	close:		v_midi_close,	ioctl:		v_midi_ioctl,	outputc:	v_midi_out,	start_read:	v_midi_start_read,	end_read:	v_midi_end_read,};/* *	We kmalloc just one of these - it makes life simpler and the code *	cleaner and the memory handling far more efficient */ struct vmidi_memory{	/* Must be first */	struct midi_operations m_ops[2];	struct synth_operations s_ops[2];	struct vmidi_devc v_ops[2];};static void __init attach_v_midi (struct address_info *hw_config){	struct vmidi_memory *m;	/* printk("Attaching v_midi device.....\n"); */	midi1 = sound_alloc_mididev();	if (midi1 == -1)	{		printk(KERN_ERR "v_midi: Too many midi devices detected\n");		return;	}		m=(struct vmidi_memory *)kmalloc(sizeof(struct vmidi_memory), GFP_KERNEL);	if (m == NULL)	{		printk(KERN_WARNING "Loopback MIDI: Failed to allocate memory\n");		sound_unload_mididev(midi1);		return;	}		midi_mem = m;		midi_devs[midi1] = &m->m_ops[0];		midi2 = sound_alloc_mididev();	if (midi2 == -1)	{		printk (KERN_ERR "v_midi: Too many midi devices detected\n");		kfree(m);		sound_unload_mididev(midi1);		return;	}	midi_devs[midi2] = &m->m_ops[1];	/* printk("VMIDI1: %d   VMIDI2: %d\n",midi1,midi2); */	/* for MIDI-1 */	v_devc[0] = &m->v_ops[0];	memcpy ((char *) midi_devs[midi1], (char *) &v_midi_operations,		sizeof (struct midi_operations));	v_devc[0]->my_mididev = midi1;	v_devc[0]->pair_mididev = midi2;	v_devc[0]->opened = v_devc[0]->input_opened = 0;	v_devc[0]->intr_active = 0;	v_devc[0]->midi_input_intr = NULL;	midi_devs[midi1]->devc = v_devc[0];	midi_devs[midi1]->converter = &m->s_ops[0];	std_midi_synth.midi_dev = midi1;	memcpy ((char *) midi_devs[midi1]->converter, (char *) &std_midi_synth,		sizeof (struct synth_operations));	midi_devs[midi1]->converter->id = "V_MIDI 1";	/* for MIDI-2 */	v_devc[1] = &m->v_ops[1];	memcpy ((char *) midi_devs[midi2], (char *) &v_midi_operations2,		sizeof (struct midi_operations));	v_devc[1]->my_mididev = midi2;	v_devc[1]->pair_mididev = midi1;	v_devc[1]->opened = v_devc[1]->input_opened = 0;	v_devc[1]->intr_active = 0;	v_devc[1]->midi_input_intr = NULL;	midi_devs[midi2]->devc = v_devc[1];	midi_devs[midi2]->converter = &m->s_ops[1];	std_midi_synth.midi_dev = midi2;	memcpy ((char *) midi_devs[midi2]->converter, (char *) &std_midi_synth,		sizeof (struct synth_operations));	midi_devs[midi2]->converter->id = "V_MIDI 2";	sequencer_init();	/* printk("Attached v_midi device\n"); */}static inline int __init probe_v_midi(struct address_info *hw_config){	return(1);	/* always OK */}static void __exit unload_v_midi(struct address_info *hw_config){	sound_unload_mididev(midi1);	sound_unload_mididev(midi2);	kfree(midi_mem);}static struct address_info cfg; /* dummy */static int __init init_vmidi(void){	printk("MIDI Loopback device driver\n");	if (!probe_v_midi(&cfg))		return -ENODEV;	attach_v_midi(&cfg);	return 0;}static void __exit cleanup_vmidi(void){	unload_v_midi(&cfg);}module_init(init_vmidi);module_exit(cleanup_vmidi);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -