/*
 * sound/oss/sb_midi.c
 *
 * The low level driver for the Sound Blaster DS chips.
 *
 *
 * Copyright (C) by Hannu Savolainen 1993-1997
 *
 * OSS/Free 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.
 */

#include <linux/spinlock.h>
#include <linux/slab.h>

#include "sound_config.h"

#include "sb.h"
#undef SB_TEST_IRQ

/*
 * 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.
 */


static int sb_midi_open(int dev, int mode,
	     void            (*input) (int dev, unsigned char data),
	     void            (*output) (int dev)
)
{
	sb_devc *devc = midi_devs[dev]->devc;
	unsigned long flags;

	if (devc == NULL)
		return -ENXIO;

	spin_lock_irqsave(&devc->lock, flags);
	if (devc->opened)
	{
		spin_unlock_irqrestore(&devc->lock, flags);
		return -EBUSY;
	}
	devc->opened = 1;
	spin_unlock_irqrestore(&devc->lock, flags);

	devc->irq_mode = IMODE_MIDI;
	devc->midi_broken = 0;

	sb_dsp_reset(devc);

	if (!sb_dsp_command(devc, 0x35))	/* Start MIDI UART mode */
	{
		  devc->opened = 0;
		  return -EIO;
	}
	devc->intr_active = 1;

	if (mode & OPEN_READ)
	{
		devc->input_opened = 1;
		devc->midi_input_intr = input;
	}
	return 0;
}

static void sb_midi_close(int dev)
{
	sb_devc *devc = midi_devs[dev]->devc;
	unsigned long flags;

	if (devc == NULL)
		return;

	spin_lock_irqsave(&devc->lock, flags);
	sb_dsp_reset(devc);
	devc->intr_active = 0;
	devc->input_opened = 0;
	devc->opened = 0;
	spin_unlock_irqrestore(&devc->lock, flags);
}

static int sb_midi_out(int dev, unsigned char midi_byte)
{
	sb_devc *devc = midi_devs[dev]->devc;

	if (devc == NULL)
		return 1;

	if (devc->midi_broken)
		return 1;

	if (!sb_dsp_command(devc, midi_byte))
	{
		devc->midi_broken = 1;
		return 1;
	}
	return 1;
}

static int sb_midi_start_read(int dev)
{
	return 0;
}

static int sb_midi_end_read(int dev)
{
	sb_devc *devc = midi_devs[dev]->devc;

	if (devc == NULL)
		return -ENXIO;

	sb_dsp_reset(devc);
	devc->intr_active = 0;
	return 0;
}

static int sb_midi_ioctl(int dev, unsigned cmd, void __user *arg)
{
        return -EINVAL;
}

void sb_midi_interrupt(sb_devc * devc)
{
	unsigned long   flags;
	unsigned char   data;

	if (devc == NULL)
		return;

	spin_lock_irqsave(&devc->lock, flags);

	data = inb(DSP_READ);
	if (devc->input_opened)
		devc->midi_input_intr(devc->my_mididev, data);

	spin_unlock_irqrestore(&devc->lock, flags);
}

#define MIDI_SYNTH_NAME	"Sound Blaster Midi"
#define MIDI_SYNTH_CAPS	0
#include "midi_synth.h"

static struct midi_operations sb_midi_operations =
{
	.owner		= THIS_MODULE,
	.info		= {"Sound Blaster", 0, 0, SNDCARD_SB},
	.converter	= &std_midi_synth,
	.in_info	= {0},
	.open		= sb_midi_open,
	.close		= sb_midi_close,
	.ioctl		= sb_midi_ioctl,
	.outputc	= sb_midi_out,
	.start_read	= sb_midi_start_read,
	.end_read	= sb_midi_end_read,
};

void sb_dsp_midi_init(sb_devc * devc, struct module *owner)
{
	int dev;

	if (devc->model < 2)	/* No MIDI support for SB 1.x */
		return;

	dev = sound_alloc_mididev();

	if (dev == -1)
	{
		printk(KERN_ERR "sb_midi: too many MIDI devices detected\n");
		return;
	}
	std_midi_synth.midi_dev = devc->my_mididev = dev;
	midi_devs[dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
	if (midi_devs[dev] == NULL)
	{
		printk(KERN_WARNING "Sound Blaster:  failed to allocate MIDI memory.\n");
		sound_unload_mididev(dev);
		return;
	}
	memcpy((char *) midi_devs[dev], (char *) &sb_midi_operations,
	       sizeof(struct midi_operations));

	if (owner)
		midi_devs[dev]->owner = owner;

	midi_devs[dev]->devc = devc;


	midi_devs[dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
	if (midi_devs[dev]->converter == NULL)
	{
		  printk(KERN_WARNING "Sound Blaster:  failed to allocate MIDI memory.\n");
		  kfree(midi_devs[dev]);
		  sound_unload_mididev(dev);
		  return;
	}
	memcpy((char *) midi_devs[dev]->converter, (char *) &std_midi_synth,
	       sizeof(struct synth_operations));

	midi_devs[dev]->converter->id = "SBMIDI";
	sequencer_init();
}
='35'>35</option><option value='40'>40</option></select></td></tr><tr><td class='label'>space:</td><td class='ctrl'><select name='ignorews' onchange='this.form.submit();'><option value='0' selected='selected'>include</option><option value='1'>ignore</option></select></td></tr><tr><td class='label'>mode:</td><td class='ctrl'><select name='dt' onchange='this.form.submit();'><option value='0' selected='selected'>unified</option><option value='1'>ssdiff</option><option value='2'>stat only</option></select></td></tr><tr><td/><td class='ctrl'><noscript><input type='submit' value='reload'/></noscript></td></tr></table></form></div><table summary='commit info' class='commit-info'>
<tr><th>author</th><td>Bhumika Goyal &lt;bhumirks@gmail.com&gt;</td><td class='right'>2017-01-25 00:54:07 +0530</td></tr>
<tr><th>committer</th><td>Dan Williams &lt;dan.j.williams@intel.com&gt;</td><td class='right'>2017-01-31 18:16:30 -0800</td></tr>
<tr><th>commit</th><td colspan='2' class='oid'><a href='/cgit.cgi/linux/net-next.git/commit/tools/perf/pmu-events/arch/x86/skylake?id=970d14e3989160ee9e97c7d75ecbc893fd29dab9'>970d14e3989160ee9e97c7d75ecbc893fd29dab9</a> (<a href='/cgit.cgi/linux/net-next.git/patch/tools/perf/pmu-events/arch/x86/skylake?id=970d14e3989160ee9e97c7d75ecbc893fd29dab9'>patch</a>)</td></tr>
<tr><th>tree</th><td colspan='2' class='oid'><a href='/cgit.cgi/linux/net-next.git/tree/?id=970d14e3989160ee9e97c7d75ecbc893fd29dab9'>4a731cac4efedb17f86a912ec56c151d26792abe</a> /<a href='/cgit.cgi/linux/net-next.git/tree/tools/perf/pmu-events/arch/x86/skylake?id=970d14e3989160ee9e97c7d75ecbc893fd29dab9'>tools/perf/pmu-events/arch/x86/skylake</a></td></tr>
<tr><th>parent</th><td colspan='2' class='oid'><a href='/cgit.cgi/linux/net-next.git/commit/tools/perf/pmu-events/arch/x86/skylake?id=7a308bb3016f57e5be11a677d15b821536419d36'>7a308bb3016f57e5be11a677d15b821536419d36</a> (<a href='/cgit.cgi/linux/net-next.git/diff/tools/perf/pmu-events/arch/x86/skylake?id=970d14e3989160ee9e97c7d75ecbc893fd29dab9&amp;id2=7a308bb3016f57e5be11a677d15b821536419d36'>diff</a>)</td></tr></table>
<div class='commit-subject'>nvdimm: constify device_type structures</div><div class='commit-msg'>Declare device_type structure as const as it is only stored in the
type field of a device structure. This field is of type const, so add
const to declaration of device_type structure.

File size before:
  text	   data	    bss	    dec	    hex	filename
  19278	   3199	     16	  22493	   57dd	nvdimm/namespace_devs.o

File size after:
  text	   data	    bss	    dec	    hex	filename
  19929	   3160	     16	  23105	   5a41	nvdimm/namespace_devs.o

Signed-off-by: Bhumika Goyal &lt;bhumirks@gmail.com&gt;
Signed-off-by: Dan Williams &lt;dan.j.williams@intel.com&gt;
</div><div class='diffstat-header'><a href='/cgit.cgi/linux/net-next.git/diff/?id=970d14e3989160ee9e97c7d75ecbc893fd29dab9'>Diffstat</a> (limited to 'tools/perf/pmu-events/arch/x86/skylake')</div><table summary='diffstat' class='diffstat'>