// 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)
{
	unsigned int type;

	protocol &= ump->info.protocol_caps;
	if (protocol == ump->info.protocol)
		return 0;

	type = protocol & SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK;
	if (type != SNDRV_UMP_EP_INFO_PROTO_MIDI1 &&
	    type != SNDRV_UMP_EP_INFO_PROTO_MIDI2)
		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");

	/* If no protocol is set by some reason, assume the valid one */
	if (!(ump->info.protocol & SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK)) {
		if (ump->info.protocol_caps & SNDRV_UMP_EP_INFO_PROTO_MIDI2)
			ump->info.protocol |= SNDRV_UMP_EP_INFO_PROTO_MIDI2;
		else if (ump->info.protocol_caps & SNDRV_UMP_EP_INFO_PROTO_MIDI1)
			ump->info.protocol |= SNDRV_UMP_EP_INFO_PROTO_MIDI1;
	}

	/* 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");
