// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Universal MIDI Packet (UMP) support
 */

#include <linux/list.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/mm.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include <sound/ump.h>
#include <sound/ump_convert.h>

#define ump_err(ump, fmt, args...)	dev_err((ump)->core.dev, fmt, ##args)
#define ump_warn(ump, fmt, args...)	dev_warn((ump)->core.dev, fmt, ##args)
#define ump_info(ump, fmt, args...)	dev_info((ump)->core.dev, fmt, ##args)
#define ump_dbg(ump, fmt, args...)	dev_dbg((ump)->core.dev, fmt, ##args)

static int snd_ump_dev_register(struct snd_rawmidi *rmidi);
static int snd_ump_dev_unregister(struct snd_rawmidi *rmidi);
static long snd_ump_ioctl(struct snd_rawmidi *rmidi, unsigned int cmd,
			  void __user *argp);
static void snd_ump_proc_read(struct snd_info_entry *entry,
			      struct snd_info_buffer *buffer);
static int snd_ump_rawmidi_open(struct snd_rawmidi_substream *substream);
static int snd_ump_rawmidi_close(struct snd_rawmidi_substream *substream);
static void snd_ump_rawmidi_trigger(struct snd_rawmidi_substream *substream,
				    int up);
static void snd_ump_rawmidi_drain(struct snd_rawmidi_substream *substream);

static void ump_handle_stream_msg(struct snd_ump_endpoint *ump,
				  const u32 *buf, int size);
#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
static int process_legacy_output(struct snd_ump_endpoint *ump,
				 u32 *buffer, int count);
static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src,
				 int words);
#else
static inline int process_legacy_output(struct snd_ump_endpoint *ump,
					u32 *buffer, int count)
{
	return 0;
}
static inline void process_legacy_input(struct snd_ump_endpoint *ump,
					const u32 *src, int words)
{
}
#endif

static const struct snd_rawmidi_global_ops snd_ump_rawmidi_ops = {
	.dev_register = snd_ump_dev_register,
	.dev_unregister = snd_ump_dev_unregister,
	.ioctl = snd_ump_ioctl,
	.proc_read = snd_ump_proc_read,
};

static const struct snd_rawmidi_ops snd_ump_rawmidi_input_ops = {
	.open = snd_ump_rawmidi_open,
	.close = snd_ump_rawmidi_close,
	.trigger = snd_ump_rawmidi_trigger,
};

static const struct snd_rawmidi_ops snd_ump_rawmidi_output_ops = {
	.open = snd_ump_rawmidi_open,
	.close = snd_ump_rawmidi_close,
	.trigger = snd_ump_rawmidi_trigger,
	.drain = snd_ump_rawmidi_drain,
};

static void snd_ump_endpoint_free(struct snd_rawmidi *rmidi)
{
	struct snd_ump_endpoint *ump = rawmidi_to_ump(rmidi);
	struct snd_ump_block *fb;

	while (!list_empty(&ump->block_list)) {
		fb = list_first_entry(&ump->block_list, struct snd_ump_block,
				      list);
		list_del(&fb->list);
		if (fb->private_free)
			fb->private_free(fb);
		kfree(fb);
	}

	if (ump->private_free)
		ump->private_free(ump);

#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
	kfree(ump->out_cvts);
#endif
}

/**
 * snd_ump_endpoint_new - create a UMP Endpoint object
 * @card: the card instance
 * @id: the id string for rawmidi
 * @device: the device index for rawmidi
 * @output: 1 for enabling output
 * @input: 1 for enabling input
 * @ump_ret: the pointer to store the new UMP instance
 *
 * Creates a new UMP Endpoint object. A UMP Endpoint is tied with one rawmidi
 * instance with one input and/or one output rawmidi stream (either uni-
 * or bi-directional). A UMP Endpoint may contain one or multiple UMP Blocks
 * that consist of one or multiple UMP Groups.
 *
 * Use snd_rawmidi_set_ops() to set the operators to the new instance.
 * Unlike snd_rawmidi_new(), this function sets up the info_flags by itself
 * depending on the given @output and @input.
 *
 * The device has SNDRV_RAWMIDI_INFO_UMP flag set and a different device
 * file ("umpCxDx") than a standard MIDI 1.x device ("midiCxDx") is
 * created.
 *
 * Return: Zero if successful, or a negative error code on failure.
 */
int snd_ump_endpoint_new(struct snd_card *card, char *id, int device,
			 int output, int input,
			 struct snd_ump_endpoint **ump_ret)
{
	unsigned int info_flags = SNDRV_RAWMIDI_INFO_UMP;
	struct snd_ump_endpoint *ump;
	int err;

	if (input)
		info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
	if (output)
		info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
	if (input && output)
		info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;

	ump = kzalloc(sizeof(*ump), GFP_KERNEL);
	if (!ump)
		return -ENOMEM;
	INIT_LIST_HEAD(&ump->block_list);
	mutex_init(&ump->open_mutex);
	init_waitqueue_head(&ump->stream_wait);
#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
	spin_lock_init(&ump->legacy_locks[0]);
	spin_lock_init(&ump->legacy_locks[1]);
#endif
	err = snd_rawmidi_init(&ump->core, card, id, device,
			       output, input, info_flags);
	if (err < 0) {
		snd_rawmidi_free(&ump->core);
		return err;
	}

	ump->info.card = card->number;
	ump->info.device = device;

	ump->core.private_free = snd_ump_endpoint_free;
	ump->core.ops = &snd_ump_rawmidi_ops;
	if (input)
		snd_rawmidi_set_ops(&ump->core, SNDRV_RAWMIDI_STREAM_INPUT,
				    &snd_ump_rawmidi_input_ops);
	if (output)
		snd_rawmidi_set_ops(&ump->core, SNDRV_RAWMIDI_STREAM_OUTPUT,
				    &snd_ump_rawmidi_output_ops);

	ump_dbg(ump, "Created a UMP EP #%d (%s)\n", device, id);
	*ump_ret = ump;
	return 0;
}
EXPORT_SYMBOL_GPL(snd_ump_endpoint_new);

/*
 * Device register / unregister hooks;
 *  do nothing, placeholders for avoiding the default rawmidi handling
 */

#if IS_ENABLED(CONFIG_SND_SEQUENCER)
static void snd_ump_dev_seq_free(struct snd_seq_device *device)
{
	struct snd_ump_endpoint *ump = device->private_data;

	ump->seq_dev = NULL;
}
#endif

static int snd_ump_dev_register(struct snd_rawmidi *rmidi)
{
#if IS_ENABLED(CONFIG_SND_SEQUENCER)
	struct snd_ump_endpoint *ump = rawmidi_to_ump(rmidi);
	int err;

	err = snd_seq_device_new(ump->core.card, ump->core.device,
				 SNDRV_SEQ_DEV_ID_UMP, 0, &ump->seq_dev);
	if (err < 0)
		return err;
	ump->seq_dev->private_data = ump;
	ump->seq_dev->private_free = snd_ump_dev_seq_free;
	snd_device_register(ump->core.card, ump->seq_dev);
#endif
	return 0;
}

static int snd_ump_dev_unregister(struct snd_rawmidi *rmidi)
{
	return 0;
}

static struct snd_ump_block *
snd_ump_get_block(struct snd_ump_endpoint *ump, unsigned char id)
{
	struct snd_ump_block *fb;

	list_for_each_entry(fb, &ump->block_list, list) {
		if (fb->info.block_id == id)
			return fb;
	}
	return NULL;
}

/*
 * rawmidi ops for UMP endpoint
 */
static int snd_ump_rawmidi_open(struct snd_rawmidi_substream *substream)
{
	struct snd_ump_endpoint *ump = rawmidi_to_ump(substream->rmidi);
	int dir = substream->stream;
	int err;

	if (ump->substreams[dir])
		return -EBUSY;
	err = ump->ops->open(ump, dir);
	if (err < 0)
		return err;
	ump->substreams[dir] = substream;
	return 0;
}

static int snd_ump_rawmidi_close(struct snd_rawmidi_substream *substream)
{
	struct snd_ump_endpoint *ump = rawmidi_to_ump(substream->rmidi);
	int dir = substream->stream;

	ump->substreams[dir] = NULL;
	ump->ops->close(ump, dir);
	return 0;
}

static void snd_ump_rawmidi_trigger(struct snd_rawmidi_substream *substream,
				    int up)
{
	struct snd_ump_endpoint *ump = rawmidi_to_ump(substream->rmidi);
	int dir = substream->stream;

	ump->ops->trigger(ump, dir, up);
}

static void snd_ump_rawmidi_drain(struct snd_rawmidi_substream *substream)
{
	struct snd_ump_endpoint *ump = rawmidi_to_ump(substream->rmidi);

	if (ump->ops->drain)
		ump->ops->drain(ump, SNDRV_RAWMIDI_STREAM_OUTPUT);
}

/* number of 32bit words per message type */
static unsigned char ump_packet_words[0x10] = {
	1, 1, 1, 2, 2, 4, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4
};

/**
 * snd_ump_receive_ump_val - parse the UMP packet data
 * @ump: UMP endpoint
 * @val: UMP packet data
 *
 * The data is copied onto ump->input_buf[].
 * When a full packet is completed, returns the number of words (from 1 to 4).
 * OTOH, if the packet is incomplete, returns 0.
 */
int snd_ump_receive_ump_val(struct snd_ump_endpoint *ump, u32 val)
{
	int words;

	if (!ump->input_pending)
		ump->input_pending = ump_packet_words[ump_message_type(val)];

	ump->input_buf[ump->input_buf_head++] = val;
	ump->input_pending--;
	if (!ump->input_pending) {
		words = ump->input_buf_head;
		ump->input_buf_head = 0;
		return words;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(snd_ump_receive_ump_val);

/**
 * snd_ump_receive - transfer UMP packets from the device
 * @ump: the UMP endpoint
 * @buffer: the buffer pointer to transfer
 * @count: byte size to transfer
 *
 * Called from the driver to submit the received UMP packets from the device
 * to user-space.  It's essentially a wrapper of rawmidi_receive().
 * The data to receive is in CPU-native endianness.
 */
int snd_ump_receive(struct snd_ump_endpoint *ump, const u32 *buffer, int count)
{
	struct snd_rawmidi_substream *substream;
	const u32 *p = buffer;
	int n, words = count >> 2;

	while (words--) {
		n = snd_ump_receive_ump_val(ump, *p++);
		if (!n)
			continue;
		ump_handle_stream_msg(ump, ump->input_buf, n);
#if IS_ENABLED(CONFIG_SND_SEQUENCER)
		if (ump->seq_ops)
			ump->seq_ops->input_receive(ump, ump->input_buf, n);
#endif
		process_legacy_input(ump, ump->input_buf, n);
	}

	substream = ump->substreams[SNDRV_RAWMIDI_STREAM_INPUT];
	if (!substream)
		return 0;
	return snd_rawmidi_receive(substream, (const char *)buffer, count);
}
EXPORT_SYMBOL_GPL(snd_ump_receive);

/**
 * snd_ump_transmit - transmit UMP packets
 * @ump: the UMP endpoint
 * @buffer: the buffer pointer to transfer
 * @count: byte size to transfer
 *
 * Called from the driver to obtain the UMP packets from user-space to the
 * device.  It's essentially a wrapper of rawmidi_transmit().
 * The data to transmit is in CPU-native endianness.
 */
int snd_ump_transmit(struct snd_ump_endpoint *ump, u32 *buffer, int count)
{
	struct snd_rawmidi_substream *substream =
		ump->substreams[SNDRV_RAWMIDI_STREAM_OUTPUT];
	int err;

	if (!substream)
		return -ENODEV;
	err = snd_rawmidi_transmit(substream, (char *)buffer, count);
	/* received either data or an error? */
	if (err)
		return err;
	return process_legacy_output(ump, buffer, count);
}
EXPORT_SYMBOL_GPL(snd_ump_transmit);

/**
 * snd_ump_block_new - Create a UMP block
 * @ump: UMP object
 * @blk: block ID number to create
 * @direction: direction (in/out/bidirection)
 * @first_group: the first group ID (0-based)
 * @num_groups: the number of groups in this block
 * @blk_ret: the pointer to store the resultant block object
 */
int snd_ump_block_new(struct snd_ump_endpoint *ump, unsigned int blk,
		      unsigned int direction, unsigned int first_group,
		      unsigned int num_groups, struct snd_ump_block **blk_ret)
{
	struct snd_ump_block *fb, *p;

	if (blk < 0 || blk >= SNDRV_UMP_MAX_BLOCKS)
		return -EINVAL;

	if (snd_ump_get_block(ump, blk))
		return -EBUSY;

	fb = kzalloc(sizeof(*fb), GFP_KERNEL);
	if (!fb)
		return -ENOMEM;

	fb->ump = ump;
	fb->info.card = ump->info.card;
	fb->info.device = ump->info.device;
	fb->info.block_id = blk;
	if (blk >= ump->info.num_blocks)
		ump->info.num_blocks = blk + 1;
	fb->info.direction = direction;
	fb->info.active = 1;
	fb->info.first_group = first_group;
	fb->info.num_groups = num_groups;
	/* fill the default name, may be overwritten to a better name */
	snprintf(fb->info.name, sizeof(fb->info.name), "Group %d-%d",
		 first_group + 1, first_group + num_groups);

	/* put the entry in the ordered list */
	list_for_each_entry(p, &ump->block_list, list) {
		if (p->info.block_id > blk) {
			list_add_tail(&fb->list, &p->list);
			goto added;
		}
	}
	list_add_tail(&fb->list, &ump->block_list);

 added:
	ump_dbg(ump, "Created a UMP Block #%d (%s)\n", blk, fb->info.name);
	*blk_ret = fb;
	return 0;
}
EXPORT_SYMBOL_GPL(snd_ump_block_new);

static int snd_ump_ioctl_block(struct snd_ump_endpoint *ump,
			       struct snd_ump_block_info __user *argp)
{
	struct snd_ump_block *fb;
	unsigned char id;

	if (get_user(id, &argp->block_id))
		return -EFAULT;
	fb = snd_ump_get_block(ump, id);
	if (!fb)
		return -ENOENT;
	if (copy_to_user(argp, &fb->info, sizeof(fb->info)))
		return -EFAULT;
	return 0;
}

/*
 * Handle UMP-specific ioctls; called from snd_rawmidi_ioctl()
 */
static long snd_ump_ioctl(struct snd_rawmidi *rmidi, unsigned int cmd,
			  void __user *argp)
{
	struct snd_ump_endpoint *ump = rawmidi_to_ump(rmidi);

	switch (cmd) {
	case SNDRV_UMP_IOCTL_ENDPOINT_INFO:
		if (copy_to_user(argp, &ump->info, sizeof(ump->info)))
			return -EFAULT;
		return 0;
	case SNDRV_UMP_IOCTL_BLOCK_INFO:
		return snd_ump_ioctl_block(ump, argp);
	default:
		ump_dbg(ump, "rawmidi: unknown command = 0x%x\n", cmd);
		return -ENOTTY;
	}
}

static const char *ump_direction_string(int dir)
{
	switch (dir) {
	case SNDRV_UMP_DIR_INPUT:
		return "input";
	case SNDRV_UMP_DIR_OUTPUT:
		return "output";
	case SNDRV_UMP_DIR_BIDIRECTION:
		return "bidirection";
	default:
		return "unknown";
	}
}

static const char *ump_ui_hint_string(int dir)
{
	switch (dir) {
	case  SNDRV_UMP_BLOCK_UI_HINT_RECEIVER:
		return "receiver";
	case SNDRV_UMP_BLOCK_UI_HINT_SENDER:
		return "sender";
	case SNDRV_UMP_BLOCK_UI_HINT_BOTH:
		return "both";
	default:
		return "unknown";
	}
}

/* Additional proc file output */
static void snd_ump_proc_read(struct snd_info_entry *entry,
			      struct snd_info_buffer *buffer)
{
	struct snd_rawmidi *rmidi = entry->private_data;
	struct snd_ump_endpoint *ump = rawmidi_to_ump(rmidi);
	struct snd_ump_block *fb;

	snd_iprintf(buffer, "EP Name: %s\n", ump->info.name);
	snd_iprintf(buffer, "EP Product ID: %s\n", ump->info.product_id);
	snd_iprintf(buffer, "UMP Version: 0x%04x\n", ump->info.version);
	snd_iprintf(buffer, "Protocol Caps: 0x%08x\n", ump->info.protocol_caps);
	snd_iprintf(buffer, "Protocol: 0x%08x\n", ump->info.protocol);
	if (ump->info.version) {
		snd_iprintf(buffer, "Manufacturer ID: 0x%08x\n",
			    ump->info.manufacturer_id);
		snd_iprintf(buffer, "Family ID: 0x%04x\n", ump->info.family_id);
		snd_iprintf(buffer, "Model ID: 0x%04x\n", ump->info.model_id);
		snd_iprintf(buffer, "SW Revision: 0x%02x%02x%02x%02x\n",
			    ump->info.sw_revision[0],
			    ump->info.sw_revision[1],
			    ump->info.sw_revision[2],
			    ump->info.sw_revision[3]);
	}
	snd_iprintf(buffer, "Static Blocks: %s\n",
		    (ump->info.flags & SNDRV_UMP_EP_INFO_STATIC_BLOCKS) ? "Yes" : "No");
	snd_iprintf(buffer, "Num Blocks: %d\n\n", ump->info.num_blocks);

	list_for_each_entry(fb, &ump->block_list, list) {
		snd_iprintf(buffer, "Block %d (%s)\n", fb->info.block_id,
			    fb->info.name);
		snd_iprintf(buffer, "  Direction: %s\n",
			    ump_direction_string(fb->info.direction));
		snd_iprintf(buffer, "  Active: %s\n",
			    fb->info.active ? "Yes" : "No");
		snd_iprintf(buffer, "  Groups: %d-%d\n",
			    fb->info.first_group + 1,
			    fb->info.first_group + fb->info.num_groups);
		snd_iprintf(buffer, "  Is MIDI1: %s%s\n",
			    (fb->info.flags & SNDRV_UMP_BLOCK_IS_MIDI1) ? "Yes" : "No",
			    (fb->info.flags & SNDRV_UMP_BLOCK_IS_LOWSPEED) ? " (Low Speed)" : "");
		if (ump->info.version) {
			snd_iprintf(buffer, "  MIDI-CI Version: %d\n",
				    fb->info.midi_ci_version);
			snd_iprintf(buffer, "  Sysex8 Streams: %d\n",
				    fb->info.sysex8_streams);
			snd_iprintf(buffer, "  UI Hint: %s\n",
				    ump_ui_hint_string(fb->info.ui_hint));
		}
		snd_iprintf(buffer, "\n");
	}
}

/*
 * UMP endpoint and function block handling
 */

/* open / close UMP streams for the internal stream msg communication */
static int ump_request_open(struct snd_ump_endpoint *ump)
{
	return snd_rawmidi_kernel_open(&ump->core, 0,
				       SNDRV_RAWMIDI_LFLG_OUTPUT,
				       &ump->stream_rfile);
}

static void ump_request_close(struct snd_ump_endpoint *ump)
{
	snd_rawmidi_kernel_release(&ump->stream_rfile);
}

/* request a command and wait for the given response;
 * @req1 and @req2 are u32 commands
 * @reply is the expected UMP stream status
 */
static int ump_req_msg(struct snd_ump_endpoint *ump, u32 req1, u32 req2,
		       u32 reply)
{
	u32 buf[4];

	ump_dbg(ump, "%s: request %08x %08x, wait-for %08x\n",
		__func__, req1, req2, reply);
	memset(buf, 0, sizeof(buf));
	buf[0] = req1;
	buf[1] = req2;
	ump->stream_finished = 0;
	ump->stream_wait_for = reply;
	snd_rawmidi_kernel_write(ump->stream_rfile.output,
				 (unsigned char *)&buf, 16);
	wait_event_timeout(ump->stream_wait, ump->stream_finished,
			   msecs_to_jiffies(500));
	if (!READ_ONCE(ump->stream_finished)) {
		ump_dbg(ump, "%s: request timed out\n", __func__);
		return -ETIMEDOUT;
	}
	ump->stream_finished = 0;
	ump_dbg(ump, "%s: reply: %08x %08x %08x %08x\n",
		__func__, buf[0], buf[1], buf[2], buf[3]);
	return 0;
}

/* append the received letters via UMP packet to the given string buffer;
 * return 1 if the full string is received or 0 to continue
 */
static int ump_append_string(struct snd_ump_endpoint *ump, char *dest,
			     int maxsize, const u32 *buf, int offset)
{
	unsigned char format;
	int c;

	format = ump_stream_message_format(buf[0]);
	if (format == UMP_STREAM_MSG_FORMAT_SINGLE ||
	    format == UMP_STREAM_MSG_FORMAT_START) {
		c = 0;
	} else {
		c = strlen(dest);
		if (c >= maxsize - 1)
			return 1;
	}

	for (; offset < 16; offset++) {
		dest[c] = buf[offset / 4] >> (3 - (offset % 4)) * 8;
		if (!dest[c])
			break;
		if (++c >= maxsize - 1)
			break;
	}
	dest[c] = 0;
	return (format == UMP_STREAM_MSG_FORMAT_SINGLE ||
		format == UMP_STREAM_MSG_FORMAT_END);
}

/* handle EP info stream message; update the UMP attributes */
static int ump_handle_ep_info_msg(struct snd_ump_endpoint *ump,
				  const union snd_ump_stream_msg *buf)
{
	ump->info.version = (buf->ep_info.ump_version_major << 8) |
		buf->ep_info.ump_version_minor;
	ump->info.num_blocks = buf->ep_info.num_function_blocks;
	if (ump->info.num_blocks > SNDRV_UMP_MAX_BLOCKS) {
		ump_info(ump, "Invalid function blocks %d, fallback to 1\n",
			 ump->info.num_blocks);
		ump->info.num_blocks = 1;
	}

	if (buf->ep_info.static_function_block)
		ump->info.flags |= SNDRV_UMP_EP_INFO_STATIC_BLOCKS;

	ump->info.protocol_caps = (buf->ep_info.protocol << 8) |
		buf->ep_info.jrts;

	ump_dbg(ump, "EP info: version=%x, num_blocks=%x, proto_caps=%x\n",
		ump->info.version, ump->info.num_blocks, ump->info.protocol_caps);
	return 1; /* finished */
}

/* handle EP device info stream message; update the UMP attributes */
static int ump_handle_device_info_msg(struct snd_ump_endpoint *ump,
				      const union snd_ump_stream_msg *buf)
{
	ump->info.manufacturer_id = buf->device_info.manufacture_id & 0x7f7f7f;
	ump->info.family_id = (buf->device_info.family_msb << 8) |
		buf->device_info.family_lsb;
	ump->info.model_id = (buf->device_info.model_msb << 8) |
		buf->device_info.model_lsb;
	ump->info.sw_revision[0] = (buf->device_info.sw_revision >> 24) & 0x7f;
	ump->info.sw_revision[1] = (buf->device_info.sw_revision >> 16) & 0x7f;
	ump->info.sw_revision[2] = (buf->device_info.sw_revision >> 8) & 0x7f;
	ump->info.sw_revision[3] = buf->device_info.sw_revision & 0x7f;
	ump_dbg(ump, "EP devinfo: manid=%08x, family=%04x, model=%04x, sw=%02x%02x%02x%02x\n",
		ump->info.manufacturer_id,
		ump->info.family_id,
		ump->info.model_id,
		ump->info.sw_revision[0],
		ump->info.sw_revision[1],
		ump->info.sw_revision[2],
		ump->info.sw_revision[3]);
	return 1; /* finished */
}

/* handle EP name stream message; update the UMP name string */
static int ump_handle_ep_name_msg(struct snd_ump_endpoint *ump,
				  const union snd_ump_stream_msg *buf)
{
	return ump_append_string(ump, ump->info.name, sizeof(ump->info.name),
				 buf->raw, 2);
}

/* handle EP product id stream message; update the UMP product_id string */
static int ump_handle_product_id_msg(struct snd_ump_endpoint *ump,
				     const union snd_ump_stream_msg *buf)
{
	return ump_append_string(ump, ump->info.product_id,
				 sizeof(ump->info.product_id),
				 buf->raw, 2);
}

/* notify the protocol change to sequencer */
static void seq_notify_protocol(struct snd_ump_endpoint *ump)
{
#if IS_ENABLED(CONFIG_SND_SEQUENCER)
	if (ump->seq_ops && ump->seq_ops->switch_protocol)
		ump->seq_ops->switch_protocol(ump);
#endif /* CONFIG_SND_SEQUENCER */
}

/**
 * snd_ump_switch_protocol - switch MIDI protocol
 * @ump: UMP endpoint
 * @protocol: protocol to switch to
 *
 * Returns 1 if the protocol is actually switched, 0 if unchanged
 */
int snd_ump_switch_protocol(struct snd_ump_endpoint *ump, unsigned int protocol)
{
	protocol &= ump->info.protocol_caps;
	if (protocol == ump->info.protocol)
		return 0;

	ump->info.protocol = protocol;
	ump_dbg(ump, "New protocol = %x (caps = %x)\n",
		protocol, ump->info.protocol_caps);
	seq_notify_protocol(ump);
	return 1;
}
EXPORT_SYMBOL_GPL(snd_ump_switch_protocol);

/* handle EP stream config message; update the UMP protocol */
static int ump_handle_stream_cfg_msg(struct snd_ump_endpoint *ump,
				     const union snd_ump_stream_msg *buf)
{
	unsigned int protocol =
		(buf->stream_cfg.protocol << 8) | buf->stream_cfg.jrts;

	snd_ump_switch_protocol(ump, protocol);
	return 1; /* finished */
}

/* Extract Function Block info from UMP packet */
static void fill_fb_info(struct snd_ump_endpoint *ump,
			 struct snd_ump_block_info *info,
			 const union snd_ump_stream_msg *buf)
{
	info->direction = buf->fb_info.direction;
	info->ui_hint = buf->fb_info.ui_hint;
	info->first_group = buf->fb_info.first_group;
	info->num_groups = buf->fb_info.num_groups;
	info->flags = buf->fb_info.midi_10;
	info->active = buf->fb_info.active;
	info->midi_ci_version = buf->fb_info.midi_ci_version;
	info->sysex8_streams = buf->fb_info.sysex8_streams;

	ump_dbg(ump, "FB %d: dir=%d, active=%d, first_gp=%d, num_gp=%d, midici=%d, sysex8=%d, flags=0x%x\n",
		info->block_id, info->direction, info->active,
		info->first_group, info->num_groups, info->midi_ci_version,
		info->sysex8_streams, info->flags);
}

/* check whether the FB info gets updated by the current message */
static bool is_fb_info_updated(struct snd_ump_endpoint *ump,
			       struct snd_ump_block *fb,
			       const union snd_ump_stream_msg *buf)
{
	char tmpbuf[offsetof(struct snd_ump_block_info, name)];

	if (ump->info.flags & SNDRV_UMP_EP_INFO_STATIC_BLOCKS) {
		ump_info(ump, "Skipping static FB info update (blk#%d)\n",
			 fb->info.block_id);
		return 0;
	}

	memcpy(tmpbuf, &fb->info, sizeof(tmpbuf));
	fill_fb_info(ump, (struct snd_ump_block_info *)tmpbuf, buf);
	return memcmp(&fb->info, tmpbuf, sizeof(tmpbuf)) != 0;
}

/* notify the FB info/name change to sequencer */
static void seq_notify_fb_change(struct snd_ump_endpoint *ump,
				 struct snd_ump_block *fb)
{
#if IS_ENABLED(CONFIG_SND_SEQUENCER)
	if (ump->seq_ops && ump->seq_ops->notify_fb_change)
		ump->seq_ops->notify_fb_change(ump, fb);
#endif
}

/* handle FB info message; update FB info if the block is present */
static int ump_handle_fb_info_msg(struct snd_ump_endpoint *ump,
				  const union snd_ump_stream_msg *buf)
{
	unsigned char blk;
	struct snd_ump_block *fb;

	blk = buf->fb_info.function_block_id;
	fb = snd_ump_get_block(ump, blk);

	/* complain only if updated after parsing */
	if (!fb && ump->parsed) {
		ump_info(ump, "Function Block Info Update for non-existing block %d\n",
			 blk);
		return -ENODEV;
	}

	/* When updated after the initial parse, check the FB info update */
	if (ump->parsed && !is_fb_info_updated(ump, fb, buf))
		return 1; /* no content change */

	if (fb) {
		fill_fb_info(ump, &fb->info, buf);
		if (ump->parsed)
			seq_notify_fb_change(ump, fb);
	}

	return 1; /* finished */
}

/* handle FB name message; update the FB name string */
static int ump_handle_fb_name_msg(struct snd_ump_endpoint *ump,
				  const union snd_ump_stream_msg *buf)
{
	unsigned char blk;
	struct snd_ump_block *fb;
	int ret;

	blk = buf->fb_name.function_block_id;
	fb = snd_ump_get_block(ump, blk);
	if (!fb)
		return -ENODEV;

	ret = ump_append_string(ump, fb->info.name, sizeof(fb->info.name),
				buf->raw, 3);
	/* notify the FB name update to sequencer, too */
	if (ret > 0 && ump->parsed)
		seq_notify_fb_change(ump, fb);
	return ret;
}

static int create_block_from_fb_info(struct snd_ump_endpoint *ump, int blk)
{
	struct snd_ump_block *fb;
	unsigned char direction, first_group, num_groups;
	const union snd_ump_stream_msg *buf =
		(const union snd_ump_stream_msg *)ump->input_buf;
	u32 msg;
	int err;

	/* query the FB info once */
	msg = ump_stream_compose(UMP_STREAM_MSG_STATUS_FB_DISCOVERY, 0) |
		(blk << 8) | UMP_STREAM_MSG_REQUEST_FB_INFO;
	err = ump_req_msg(ump, msg, 0, UMP_STREAM_MSG_STATUS_FB_INFO);
	if (err < 0) {
		ump_dbg(ump, "Unable to get FB info for block %d\n", blk);
		return err;
	}

	/* the last input must be the FB info */
	if (buf->fb_info.status != UMP_STREAM_MSG_STATUS_FB_INFO) {
		ump_dbg(ump, "Inconsistent input: 0x%x\n", *buf->raw);
		return -EINVAL;
	}

	direction = buf->fb_info.direction;
	first_group = buf->fb_info.first_group;
	num_groups = buf->fb_info.num_groups;

	err = snd_ump_block_new(ump, blk, direction, first_group, num_groups,
				&fb);
	if (err < 0)
		return err;

	fill_fb_info(ump, &fb->info, buf);

	msg = ump_stream_compose(UMP_STREAM_MSG_STATUS_FB_DISCOVERY, 0) |
		(blk << 8) | UMP_STREAM_MSG_REQUEST_FB_NAME;
	err = ump_req_msg(ump, msg, 0, UMP_STREAM_MSG_STATUS_FB_NAME);
	if (err)
		ump_dbg(ump, "Unable to get UMP FB name string #%d\n", blk);

	return 0;
}

/* handle stream messages, called from snd_ump_receive() */
static void ump_handle_stream_msg(struct snd_ump_endpoint *ump,
				  const u32 *buf, int size)
{
	const union snd_ump_stream_msg *msg;
	unsigned int status;
	int ret;

	/* UMP stream message suppressed (for gadget UMP)? */
	if (ump->no_process_stream)
		return;

	BUILD_BUG_ON(sizeof(*msg) != 16);
	ump_dbg(ump, "Stream msg: %08x %08x %08x %08x\n",
		buf[0], buf[1], buf[2], buf[3]);

	if (size != 4 || ump_message_type(*buf) != UMP_MSG_TYPE_STREAM)
		return;

	msg = (const union snd_ump_stream_msg *)buf;
	status = ump_stream_message_status(*buf);
	switch (status) {
	case UMP_STREAM_MSG_STATUS_EP_INFO:
		ret = ump_handle_ep_info_msg(ump, msg);
		break;
	case UMP_STREAM_MSG_STATUS_DEVICE_INFO:
		ret = ump_handle_device_info_msg(ump, msg);
		break;
	case UMP_STREAM_MSG_STATUS_EP_NAME:
		ret = ump_handle_ep_name_msg(ump, msg);
		break;
	case UMP_STREAM_MSG_STATUS_PRODUCT_ID:
		ret = ump_handle_product_id_msg(ump, msg);
		break;
	case UMP_STREAM_MSG_STATUS_STREAM_CFG:
		ret = ump_handle_stream_cfg_msg(ump, msg);
		break;
	case UMP_STREAM_MSG_STATUS_FB_INFO:
		ret = ump_handle_fb_info_msg(ump, msg);
		break;
	case UMP_STREAM_MSG_STATUS_FB_NAME:
		ret = ump_handle_fb_name_msg(ump, msg);
		break;
	default:
		return;
	}

	/* when the message has been processed fully, wake up */
	if (ret > 0 && ump->stream_wait_for == status) {
		WRITE_ONCE(ump->stream_finished, 1);
		wake_up(&ump->stream_wait);
	}
}

/**
 * snd_ump_parse_endpoint - parse endpoint and create function blocks
 * @ump: UMP object
 *
 * Returns 0 for successful parse, -ENODEV if device doesn't respond
 * (or the query is unsupported), or other error code for serious errors.
 */
int snd_ump_parse_endpoint(struct snd_ump_endpoint *ump)
{
	int blk, err;
	u32 msg;

	if (!(ump->core.info_flags & SNDRV_RAWMIDI_INFO_DUPLEX))
		return -ENODEV;

	err = ump_request_open(ump);
	if (err < 0) {
		ump_dbg(ump, "Unable to open rawmidi device: %d\n", err);
		return err;
	}

	/* Check Endpoint Information */
	msg = ump_stream_compose(UMP_STREAM_MSG_STATUS_EP_DISCOVERY, 0) |
		0x0101; /* UMP version 1.1 */
	err = ump_req_msg(ump, msg, UMP_STREAM_MSG_REQUEST_EP_INFO,
			  UMP_STREAM_MSG_STATUS_EP_INFO);
	if (err < 0) {
		ump_dbg(ump, "Unable to get UMP EP info\n");
		goto error;
	}

	/* Request Endpoint Device Info */
	err = ump_req_msg(ump, msg, UMP_STREAM_MSG_REQUEST_DEVICE_INFO,
			  UMP_STREAM_MSG_STATUS_DEVICE_INFO);
	if (err < 0)
		ump_dbg(ump, "Unable to get UMP EP device info\n");

	/* Request Endpoint Name */
	err = ump_req_msg(ump, msg, UMP_STREAM_MSG_REQUEST_EP_NAME,
			  UMP_STREAM_MSG_STATUS_EP_NAME);
	if (err < 0)
		ump_dbg(ump, "Unable to get UMP EP name string\n");

	/* Request Endpoint Product ID */
	err = ump_req_msg(ump, msg, UMP_STREAM_MSG_REQUEST_PRODUCT_ID,
			  UMP_STREAM_MSG_STATUS_PRODUCT_ID);
	if (err < 0)
		ump_dbg(ump, "Unable to get UMP EP product ID string\n");

	/* Get the current stream configuration */
	err = ump_req_msg(ump, msg, UMP_STREAM_MSG_REQUEST_STREAM_CFG,
			  UMP_STREAM_MSG_STATUS_STREAM_CFG);
	if (err < 0)
		ump_dbg(ump, "Unable to get UMP EP stream config\n");

	/* Query and create blocks from Function Blocks */
	for (blk = 0; blk < ump->info.num_blocks; blk++) {
		err = create_block_from_fb_info(ump, blk);
		if (err < 0)
			continue;
	}

 error:
	ump->parsed = true;
	ump_request_close(ump);
	if (err == -ETIMEDOUT)
		err = -ENODEV;
	return err;
}
EXPORT_SYMBOL_GPL(snd_ump_parse_endpoint);

#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
/*
 * Legacy rawmidi support
 */
static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream)
{
	struct snd_ump_endpoint *ump = substream->rmidi->private_data;
	int dir = substream->stream;
	int group = ump->legacy_mapping[substream->number];
	int err;

	guard(mutex)(&ump->open_mutex);
	if (ump->legacy_substreams[dir][group])
		return -EBUSY;
	if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) {
		if (!ump->legacy_out_opens) {
			err = snd_rawmidi_kernel_open(&ump->core, 0,
						      SNDRV_RAWMIDI_LFLG_OUTPUT |
						      SNDRV_RAWMIDI_LFLG_APPEND,
						      &ump->legacy_out_rfile);
			if (err < 0)
				return err;
		}
		ump->legacy_out_opens++;
		snd_ump_convert_reset(&ump->out_cvts[group]);
	}
	guard(spinlock_irq)(&ump->legacy_locks[dir]);
	ump->legacy_substreams[dir][group] = substream;
	return 0;
}

static int snd_ump_legacy_close(struct snd_rawmidi_substream *substream)
{
	struct snd_ump_endpoint *ump = substream->rmidi->private_data;
	int dir = substream->stream;
	int group = ump->legacy_mapping[substream->number];

	guard(mutex)(&ump->open_mutex);
	scoped_guard(spinlock_irq, &ump->legacy_locks[dir])
		ump->legacy_substreams[dir][group] = NULL;
	if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) {
		if (!--ump->legacy_out_opens)
			snd_rawmidi_kernel_release(&ump->legacy_out_rfile);
	}
	return 0;
}

static void snd_ump_legacy_trigger(struct snd_rawmidi_substream *substream,
				   int up)
{
	struct snd_ump_endpoint *ump = substream->rmidi->private_data;
	int dir = substream->stream;

	ump->ops->trigger(ump, dir, up);
}

static void snd_ump_legacy_drain(struct snd_rawmidi_substream *substream)
{
	struct snd_ump_endpoint *ump = substream->rmidi->private_data;

	if (ump->ops->drain)
		ump->ops->drain(ump, SNDRV_RAWMIDI_STREAM_OUTPUT);
}

static int snd_ump_legacy_dev_register(struct snd_rawmidi *rmidi)
{
	/* dummy, just for avoiding create superfluous seq clients */
	return 0;
}

static const struct snd_rawmidi_ops snd_ump_legacy_input_ops = {
	.open = snd_ump_legacy_open,
	.close = snd_ump_legacy_close,
	.trigger = snd_ump_legacy_trigger,
};

static const struct snd_rawmidi_ops snd_ump_legacy_output_ops = {
	.open = snd_ump_legacy_open,
	.close = snd_ump_legacy_close,
	.trigger = snd_ump_legacy_trigger,
	.drain = snd_ump_legacy_drain,
};

static const struct snd_rawmidi_global_ops snd_ump_legacy_ops = {
	.dev_register = snd_ump_legacy_dev_register,
};

static int process_legacy_output(struct snd_ump_endpoint *ump,
				 u32 *buffer, int count)
{
	struct snd_rawmidi_substream *substream;
	struct ump_cvt_to_ump *ctx;
	const int dir = SNDRV_RAWMIDI_STREAM_OUTPUT;
	unsigned char c;
	int group, size = 0;

	if (!ump->out_cvts || !ump->legacy_out_opens)
		return 0;

	guard(spinlock_irqsave)(&ump->legacy_locks[dir]);
	for (group = 0; group < SNDRV_UMP_MAX_GROUPS; group++) {
		substream = ump->legacy_substreams[dir][group];
		if (!substream)
			continue;
		ctx = &ump->out_cvts[group];
		while (!ctx->ump_bytes &&
		       snd_rawmidi_transmit(substream, &c, 1) > 0)
			snd_ump_convert_to_ump(ctx, group, ump->info.protocol, c);
		if (ctx->ump_bytes && ctx->ump_bytes <= count) {
			size = ctx->ump_bytes;
			memcpy(buffer, ctx->ump, size);
			ctx->ump_bytes = 0;
			break;
		}
	}
	return size;
}

static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src,
				 int words)
{
	struct snd_rawmidi_substream *substream;
	unsigned char buf[16];
	unsigned char group;
	const int dir = SNDRV_RAWMIDI_STREAM_INPUT;
	int size;

	size = snd_ump_convert_from_ump(src, buf, &group);
	if (size <= 0)
		return;
	guard(spinlock_irqsave)(&ump->legacy_locks[dir]);
	substream = ump->legacy_substreams[dir][group];
	if (substream)
		snd_rawmidi_receive(substream, buf, size);
}

/* Fill ump->legacy_mapping[] for groups to be used for legacy rawmidi */
static int fill_legacy_mapping(struct snd_ump_endpoint *ump)
{
	struct snd_ump_block *fb;
	unsigned int group_maps = 0;
	int i, num;

	if (ump->info.flags & SNDRV_UMP_EP_INFO_STATIC_BLOCKS) {
		list_for_each_entry(fb, &ump->block_list, list) {
			for (i = 0; i < fb->info.num_groups; i++)
				group_maps |= 1U << (fb->info.first_group + i);
		}
		if (!group_maps)
			ump_info(ump, "No UMP Group is found in FB\n");
	}

	/* use all groups for non-static case */
	if (!group_maps)
		group_maps = (1U << SNDRV_UMP_MAX_GROUPS) - 1;

	num = 0;
	for (i = 0; i < SNDRV_UMP_MAX_GROUPS; i++)
		if (group_maps & (1U << i))
			ump->legacy_mapping[num++] = i;

	return num;
}

static void fill_substream_names(struct snd_ump_endpoint *ump,
				 struct snd_rawmidi *rmidi, int dir)
{
	struct snd_rawmidi_substream *s;

	list_for_each_entry(s, &rmidi->streams[dir].substreams, list)
		snprintf(s->name, sizeof(s->name), "Group %d (%.16s)",
			 ump->legacy_mapping[s->number] + 1, ump->info.name);
}

int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,
				  char *id, int device)
{
	struct snd_rawmidi *rmidi;
	bool input, output;
	int err, num;

	ump->out_cvts = kcalloc(SNDRV_UMP_MAX_GROUPS,
				sizeof(*ump->out_cvts), GFP_KERNEL);
	if (!ump->out_cvts)
		return -ENOMEM;

	num = fill_legacy_mapping(ump);

	input = ump->core.info_flags & SNDRV_RAWMIDI_INFO_INPUT;
	output = ump->core.info_flags & SNDRV_RAWMIDI_INFO_OUTPUT;
	err = snd_rawmidi_new(ump->core.card, id, device,
			      output ? num : 0, input ? num : 0,
			      &rmidi);
	if (err < 0) {
		kfree(ump->out_cvts);
		return err;
	}

	if (input)
		snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
				    &snd_ump_legacy_input_ops);
	if (output)
		snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
				    &snd_ump_legacy_output_ops);
	snprintf(rmidi->name, sizeof(rmidi->name), "%.68s (MIDI 1.0)",
		 ump->info.name);
	rmidi->info_flags = ump->core.info_flags & ~SNDRV_RAWMIDI_INFO_UMP;
	rmidi->ops = &snd_ump_legacy_ops;
	rmidi->private_data = ump;
	ump->legacy_rmidi = rmidi;
	if (input)
		fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT);
	if (output)
		fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT);

	ump_dbg(ump, "Created a legacy rawmidi #%d (%s)\n", device, id);
	return 0;
}
EXPORT_SYMBOL_GPL(snd_ump_attach_legacy_rawmidi);
#endif /* CONFIG_SND_UMP_LEGACY_RAWMIDI */

MODULE_DESCRIPTION("Universal MIDI Packet (UMP) Core Driver");
MODULE_LICENSE("GPL");
