// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   ALSA sequencer Ports
 *   Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
 *                         Jaroslav Kysela <perex@perex.cz>
 */

#include <sound/core.h>
#include <linux/slab.h>
#include <linux/module.h>
#include "seq_system.h"
#include "seq_ports.h"
#include "seq_clientmgr.h"

/*

   registration of client ports

 */


/* 

NOTE: the current implementation of the port structure as a linked list is
not optimal for clients that have many ports. For sending messages to all
subscribers of a port we first need to find the address of the port
structure, which means we have to traverse the list. A direct access table
(array) would be better, but big preallocated arrays waste memory.

Possible actions:

1) leave it this way, a client does normaly does not have more than a few
ports

2) replace the linked list of ports by a array of pointers which is
dynamicly kmalloced. When a port is added or deleted we can simply allocate
a new array, copy the corresponding pointers, and delete the old one. We
then only need a pointer to this array, and an integer that tells us how
much elements are in array.

*/

/* return pointer to port structure - port is locked if found */
struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client,
						 int num)
{
	struct snd_seq_client_port *port;

	if (client == NULL)
		return NULL;
	read_lock(&client->ports_lock);
	list_for_each_entry(port, &client->ports_list_head, list) {
		if (port->addr.port == num) {
			if (port->closing)
				break; /* deleting now */
			snd_use_lock_use(&port->use_lock);
			read_unlock(&client->ports_lock);
			return port;
		}
	}
	read_unlock(&client->ports_lock);
	return NULL;		/* not found */
}


/* search for the next port - port is locked if found */
struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *client,
						       struct snd_seq_port_info *pinfo)
{
	int num;
	struct snd_seq_client_port *port, *found;
	bool check_inactive = (pinfo->capability & SNDRV_SEQ_PORT_CAP_INACTIVE);

	num = pinfo->addr.port;
	found = NULL;
	read_lock(&client->ports_lock);
	list_for_each_entry(port, &client->ports_list_head, list) {
		if ((port->capability & SNDRV_SEQ_PORT_CAP_INACTIVE) &&
		    !check_inactive)
			continue; /* skip inactive ports */
		if (port->addr.port < num)
			continue;
		if (port->addr.port == num) {
			found = port;
			break;
		}
		if (found == NULL || port->addr.port < found->addr.port)
			found = port;
	}
	if (found) {
		if (found->closing)
			found = NULL;
		else
			snd_use_lock_use(&found->use_lock);
	}
	read_unlock(&client->ports_lock);
	return found;
}


/* initialize snd_seq_port_subs_info */
static void port_subs_info_init(struct snd_seq_port_subs_info *grp)
{
	INIT_LIST_HEAD(&grp->list_head);
	grp->count = 0;
	grp->exclusive = 0;
	rwlock_init(&grp->list_lock);
	init_rwsem(&grp->list_mutex);
	grp->open = NULL;
	grp->close = NULL;
}


/* create a port, port number or a negative error code is returned
 * the caller needs to unref the port via snd_seq_port_unlock() appropriately
 */
int snd_seq_create_port(struct snd_seq_client *client, int port,
			struct snd_seq_client_port **port_ret)
{
	struct snd_seq_client_port *new_port, *p;
	int num;
	
	*port_ret = NULL;

	/* sanity check */
	if (snd_BUG_ON(!client))
		return -EINVAL;

	if (client->num_ports >= SNDRV_SEQ_MAX_PORTS) {
		pr_warn("ALSA: seq: too many ports for client %d\n", client->number);
		return -EINVAL;
	}

	/* create a new port */
	new_port = kzalloc(sizeof(*new_port), GFP_KERNEL);
	if (!new_port)
		return -ENOMEM;	/* failure, out of memory */
	/* init port data */
	new_port->addr.client = client->number;
	new_port->addr.port = -1;
	new_port->owner = THIS_MODULE;
	snd_use_lock_init(&new_port->use_lock);
	port_subs_info_init(&new_port->c_src);
	port_subs_info_init(&new_port->c_dest);
	snd_use_lock_use(&new_port->use_lock);

	num = max(port, 0);
	mutex_lock(&client->ports_mutex);
	write_lock_irq(&client->ports_lock);
	list_for_each_entry(p, &client->ports_list_head, list) {
		if (p->addr.port == port) {
			kfree(new_port);
			num = -EBUSY;
			goto unlock;
		}
		if (p->addr.port > num)
			break;
		if (port < 0) /* auto-probe mode */
			num = p->addr.port + 1;
	}
	/* insert the new port */
	list_add_tail(&new_port->list, &p->list);
	client->num_ports++;
	new_port->addr.port = num;	/* store the port number in the port */
	sprintf(new_port->name, "port-%d", num);
	*port_ret = new_port;
 unlock:
	write_unlock_irq(&client->ports_lock);
	mutex_unlock(&client->ports_mutex);

	return num;
}

/* */
static int subscribe_port(struct snd_seq_client *client,
			  struct snd_seq_client_port *port,
			  struct snd_seq_port_subs_info *grp,
			  struct snd_seq_port_subscribe *info, int send_ack);
static int unsubscribe_port(struct snd_seq_client *client,
			    struct snd_seq_client_port *port,
			    struct snd_seq_port_subs_info *grp,
			    struct snd_seq_port_subscribe *info, int send_ack);


static struct snd_seq_client_port *get_client_port(struct snd_seq_addr *addr,
						   struct snd_seq_client **cp)
{
	struct snd_seq_client_port *p;
	*cp = snd_seq_client_use_ptr(addr->client);
	if (*cp) {
		p = snd_seq_port_use_ptr(*cp, addr->port);
		if (! p) {
			snd_seq_client_unlock(*cp);
			*cp = NULL;
		}
		return p;
	}
	return NULL;
}

static void delete_and_unsubscribe_port(struct snd_seq_client *client,
					struct snd_seq_client_port *port,
					struct snd_seq_subscribers *subs,
					bool is_src, bool ack);

static inline struct snd_seq_subscribers *
get_subscriber(struct list_head *p, bool is_src)
{
	if (is_src)
		return list_entry(p, struct snd_seq_subscribers, src_list);
	else
		return list_entry(p, struct snd_seq_subscribers, dest_list);
}

/*
 * remove all subscribers on the list
 * this is called from port_delete, for each src and dest list.
 */
static void clear_subscriber_list(struct snd_seq_client *client,
				  struct snd_seq_client_port *port,
				  struct snd_seq_port_subs_info *grp,
				  int is_src)
{
	struct list_head *p, *n;

	list_for_each_safe(p, n, &grp->list_head) {
		struct snd_seq_subscribers *subs;
		struct snd_seq_client *c;
		struct snd_seq_client_port *aport;

		subs = get_subscriber(p, is_src);
		if (is_src)
			aport = get_client_port(&subs->info.dest, &c);
		else
			aport = get_client_port(&subs->info.sender, &c);
		delete_and_unsubscribe_port(client, port, subs, is_src, false);

		if (!aport) {
			/* looks like the connected port is being deleted.
			 * we decrease the counter, and when both ports are deleted
			 * remove the subscriber info
			 */
			if (atomic_dec_and_test(&subs->ref_count))
				kfree(subs);
			continue;
		}

		/* ok we got the connected port */
		delete_and_unsubscribe_port(c, aport, subs, !is_src, true);
		kfree(subs);
		snd_seq_port_unlock(aport);
		snd_seq_client_unlock(c);
	}
}

/* delete port data */
static int port_delete(struct snd_seq_client *client,
		       struct snd_seq_client_port *port)
{
	/* set closing flag and wait for all port access are gone */
	port->closing = 1;
	snd_use_lock_sync(&port->use_lock); 

	/* clear subscribers info */
	clear_subscriber_list(client, port, &port->c_src, true);
	clear_subscriber_list(client, port, &port->c_dest, false);

	if (port->private_free)
		port->private_free(port->private_data);

	snd_BUG_ON(port->c_src.count != 0);
	snd_BUG_ON(port->c_dest.count != 0);

	kfree(port);
	return 0;
}


/* delete a port with the given port id */
int snd_seq_delete_port(struct snd_seq_client *client, int port)
{
	struct snd_seq_client_port *found = NULL, *p;

	mutex_lock(&client->ports_mutex);
	write_lock_irq(&client->ports_lock);
	list_for_each_entry(p, &client->ports_list_head, list) {
		if (p->addr.port == port) {
			/* ok found.  delete from the list at first */
			list_del(&p->list);
			client->num_ports--;
			found = p;
			break;
		}
	}
	write_unlock_irq(&client->ports_lock);
	mutex_unlock(&client->ports_mutex);
	if (found)
		return port_delete(client, found);
	else
		return -ENOENT;
}

/* delete the all ports belonging to the given client */
int snd_seq_delete_all_ports(struct snd_seq_client *client)
{
	struct list_head deleted_list;
	struct snd_seq_client_port *port, *tmp;
	
	/* move the port list to deleted_list, and
	 * clear the port list in the client data.
	 */
	mutex_lock(&client->ports_mutex);
	write_lock_irq(&client->ports_lock);
	if (! list_empty(&client->ports_list_head)) {
		list_add(&deleted_list, &client->ports_list_head);
		list_del_init(&client->ports_list_head);
	} else {
		INIT_LIST_HEAD(&deleted_list);
	}
	client->num_ports = 0;
	write_unlock_irq(&client->ports_lock);

	/* remove each port in deleted_list */
	list_for_each_entry_safe(port, tmp, &deleted_list, list) {
		list_del(&port->list);
		snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port);
		port_delete(client, port);
	}
	mutex_unlock(&client->ports_mutex);
	return 0;
}

/* set port info fields */
int snd_seq_set_port_info(struct snd_seq_client_port * port,
			  struct snd_seq_port_info * info)
{
	if (snd_BUG_ON(!port || !info))
		return -EINVAL;

	/* set port name */
	if (info->name[0])
		strscpy(port->name, info->name, sizeof(port->name));
	
	/* set capabilities */
	port->capability = info->capability;
	
	/* get port type */
	port->type = info->type;

	/* information about supported channels/voices */
	port->midi_channels = info->midi_channels;
	port->midi_voices = info->midi_voices;
	port->synth_voices = info->synth_voices;

	/* timestamping */
	port->timestamping = (info->flags & SNDRV_SEQ_PORT_FLG_TIMESTAMP) ? 1 : 0;
	port->time_real = (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0;
	port->time_queue = info->time_queue;

	/* UMP direction and group */
	port->direction = info->direction;
	port->ump_group = info->ump_group;
	if (port->ump_group > SNDRV_UMP_MAX_GROUPS)
		port->ump_group = 0;

	/* fill default port direction */
	if (!port->direction) {
		if (info->capability & SNDRV_SEQ_PORT_CAP_READ)
			port->direction |= SNDRV_SEQ_PORT_DIR_INPUT;
		if (info->capability & SNDRV_SEQ_PORT_CAP_WRITE)
			port->direction |= SNDRV_SEQ_PORT_DIR_OUTPUT;
	}

	return 0;
}

/* get port info fields */
int snd_seq_get_port_info(struct snd_seq_client_port * port,
			  struct snd_seq_port_info * info)
{
	if (snd_BUG_ON(!port || !info))
		return -EINVAL;

	/* get port name */
	strscpy(info->name, port->name, sizeof(info->name));
	
	/* get capabilities */
	info->capability = port->capability;

	/* get port type */
	info->type = port->type;

	/* information about supported channels/voices */
	info->midi_channels = port->midi_channels;
	info->midi_voices = port->midi_voices;
	info->synth_voices = port->synth_voices;

	/* get subscriber counts */
	info->read_use = port->c_src.count;
	info->write_use = port->c_dest.count;
	
	/* timestamping */
	info->flags = 0;
	if (port->timestamping) {
		info->flags |= SNDRV_SEQ_PORT_FLG_TIMESTAMP;
		if (port->time_real)
			info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL;
		info->time_queue = port->time_queue;
	}

	/* UMP direction and group */
	info->direction = port->direction;
	info->ump_group = port->ump_group;

	return 0;
}



/*
 * call callback functions (if any):
 * the callbacks are invoked only when the first (for connection) or
 * the last subscription (for disconnection) is done.  Second or later
 * subscription results in increment of counter, but no callback is
 * invoked.
 * This feature is useful if these callbacks are associated with
 * initialization or termination of devices (see seq_midi.c).
 */

static int subscribe_port(struct snd_seq_client *client,
			  struct snd_seq_client_port *port,
			  struct snd_seq_port_subs_info *grp,
			  struct snd_seq_port_subscribe *info,
			  int send_ack)
{
	int err = 0;

	if (!try_module_get(port->owner))
		return -EFAULT;
	grp->count++;
	if (grp->open && grp->count == 1) {
		err = grp->open(port->private_data, info);
		if (err < 0) {
			module_put(port->owner);
			grp->count--;
		}
	}
	if (err >= 0 && send_ack && client->type == USER_CLIENT)
		snd_seq_client_notify_subscription(port->addr.client, port->addr.port,
						   info, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED);

	return err;
}

static int unsubscribe_port(struct snd_seq_client *client,
			    struct snd_seq_client_port *port,
			    struct snd_seq_port_subs_info *grp,
			    struct snd_seq_port_subscribe *info,
			    int send_ack)
{
	int err = 0;

	if (! grp->count)
		return -EINVAL;
	grp->count--;
	if (grp->close && grp->count == 0)
		err = grp->close(port->private_data, info);
	if (send_ack && client->type == USER_CLIENT)
		snd_seq_client_notify_subscription(port->addr.client, port->addr.port,
						   info, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED);
	module_put(port->owner);
	return err;
}



/* check if both addresses are identical */
static inline int addr_match(struct snd_seq_addr *r, struct snd_seq_addr *s)
{
	return (r->client == s->client) && (r->port == s->port);
}

/* check the two subscribe info match */
/* if flags is zero, checks only sender and destination addresses */
static int match_subs_info(struct snd_seq_port_subscribe *r,
			   struct snd_seq_port_subscribe *s)
{
	if (addr_match(&r->sender, &s->sender) &&
	    addr_match(&r->dest, &s->dest)) {
		if (r->flags && r->flags == s->flags)
			return r->queue == s->queue;
		else if (! r->flags)
			return 1;
	}
	return 0;
}

static int check_and_subscribe_port(struct snd_seq_client *client,
				    struct snd_seq_client_port *port,
				    struct snd_seq_subscribers *subs,
				    bool is_src, bool exclusive, bool ack)
{
	struct snd_seq_port_subs_info *grp;
	struct list_head *p;
	struct snd_seq_subscribers *s;
	int err;

	grp = is_src ? &port->c_src : &port->c_dest;
	err = -EBUSY;
	down_write(&grp->list_mutex);
	if (exclusive) {
		if (!list_empty(&grp->list_head))
			goto __error;
	} else {
		if (grp->exclusive)
			goto __error;
		/* check whether already exists */
		list_for_each(p, &grp->list_head) {
			s = get_subscriber(p, is_src);
			if (match_subs_info(&subs->info, &s->info))
				goto __error;
		}
	}

	err = subscribe_port(client, port, grp, &subs->info, ack);
	if (err < 0) {
		grp->exclusive = 0;
		goto __error;
	}

	/* add to list */
	write_lock_irq(&grp->list_lock);
	if (is_src)
		list_add_tail(&subs->src_list, &grp->list_head);
	else
		list_add_tail(&subs->dest_list, &grp->list_head);
	grp->exclusive = exclusive;
	atomic_inc(&subs->ref_count);
	write_unlock_irq(&grp->list_lock);
	err = 0;

 __error:
	up_write(&grp->list_mutex);
	return err;
}

/* called with grp->list_mutex held */
static void __delete_and_unsubscribe_port(struct snd_seq_client *client,
					  struct snd_seq_client_port *port,
					  struct snd_seq_subscribers *subs,
					  bool is_src, bool ack)
{
	struct snd_seq_port_subs_info *grp;
	struct list_head *list;
	bool empty;

	grp = is_src ? &port->c_src : &port->c_dest;
	list = is_src ? &subs->src_list : &subs->dest_list;
	write_lock_irq(&grp->list_lock);
	empty = list_empty(list);
	if (!empty)
		list_del_init(list);
	grp->exclusive = 0;
	write_unlock_irq(&grp->list_lock);

	if (!empty)
		unsubscribe_port(client, port, grp, &subs->info, ack);
}

static void delete_and_unsubscribe_port(struct snd_seq_client *client,
					struct snd_seq_client_port *port,
					struct snd_seq_subscribers *subs,
					bool is_src, bool ack)
{
	struct snd_seq_port_subs_info *grp;

	grp = is_src ? &port->c_src : &port->c_dest;
	down_write(&grp->list_mutex);
	__delete_and_unsubscribe_port(client, port, subs, is_src, ack);
	up_write(&grp->list_mutex);
}

/* connect two ports */
int snd_seq_port_connect(struct snd_seq_client *connector,
			 struct snd_seq_client *src_client,
			 struct snd_seq_client_port *src_port,
			 struct snd_seq_client *dest_client,
			 struct snd_seq_client_port *dest_port,
			 struct snd_seq_port_subscribe *info)
{
	struct snd_seq_subscribers *subs;
	bool exclusive;
	int err;

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

	subs->info = *info;
	atomic_set(&subs->ref_count, 0);
	INIT_LIST_HEAD(&subs->src_list);
	INIT_LIST_HEAD(&subs->dest_list);

	exclusive = !!(info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE);

	err = check_and_subscribe_port(src_client, src_port, subs, true,
				       exclusive,
				       connector->number != src_client->number);
	if (err < 0)
		goto error;
	err = check_and_subscribe_port(dest_client, dest_port, subs, false,
				       exclusive,
				       connector->number != dest_client->number);
	if (err < 0)
		goto error_dest;

	return 0;

 error_dest:
	delete_and_unsubscribe_port(src_client, src_port, subs, true,
				    connector->number != src_client->number);
 error:
	kfree(subs);
	return err;
}

/* remove the connection */
int snd_seq_port_disconnect(struct snd_seq_client *connector,
			    struct snd_seq_client *src_client,
			    struct snd_seq_client_port *src_port,
			    struct snd_seq_client *dest_client,
			    struct snd_seq_client_port *dest_port,
			    struct snd_seq_port_subscribe *info)
{
	struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
	struct snd_seq_subscribers *subs;
	int err = -ENOENT;

	/* always start from deleting the dest port for avoiding concurrent
	 * deletions
	 */
	down_write(&dest->list_mutex);
	/* look for the connection */
	list_for_each_entry(subs, &dest->list_head, dest_list) {
		if (match_subs_info(info, &subs->info)) {
			__delete_and_unsubscribe_port(dest_client, dest_port,
						      subs, false,
						      connector->number != dest_client->number);
			err = 0;
			break;
		}
	}
	up_write(&dest->list_mutex);
	if (err < 0)
		return err;

	delete_and_unsubscribe_port(src_client, src_port, subs, true,
				    connector->number != src_client->number);
	kfree(subs);
	return 0;
}


/* get matched subscriber */
int snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
				  struct snd_seq_addr *dest_addr,
				  struct snd_seq_port_subscribe *subs)
{
	struct snd_seq_subscribers *s;
	int err = -ENOENT;

	down_read(&src_grp->list_mutex);
	list_for_each_entry(s, &src_grp->list_head, src_list) {
		if (addr_match(dest_addr, &s->info.dest)) {
			*subs = s->info;
			err = 0;
			break;
		}
	}
	up_read(&src_grp->list_mutex);
	return err;
}

/*
 * Attach a device driver that wants to receive events from the
 * sequencer.  Returns the new port number on success.
 * A driver that wants to receive the events converted to midi, will
 * use snd_seq_midisynth_register_port().
 */
/* exported */
int snd_seq_event_port_attach(int client,
			      struct snd_seq_port_callback *pcbp,
			      int cap, int type, int midi_channels,
			      int midi_voices, char *portname)
{
	struct snd_seq_port_info portinfo;
	int  ret;

	/* Set up the port */
	memset(&portinfo, 0, sizeof(portinfo));
	portinfo.addr.client = client;
	strscpy(portinfo.name, portname ? portname : "Unnamed port",
		sizeof(portinfo.name));

	portinfo.capability = cap;
	portinfo.type = type;
	portinfo.kernel = pcbp;
	portinfo.midi_channels = midi_channels;
	portinfo.midi_voices = midi_voices;

	/* Create it */
	ret = snd_seq_kernel_client_ctl(client,
					SNDRV_SEQ_IOCTL_CREATE_PORT,
					&portinfo);

	if (ret >= 0)
		ret = portinfo.addr.port;

	return ret;
}
EXPORT_SYMBOL(snd_seq_event_port_attach);

/*
 * Detach the driver from a port.
 */
/* exported */
int snd_seq_event_port_detach(int client, int port)
{
	struct snd_seq_port_info portinfo;
	int  err;

	memset(&portinfo, 0, sizeof(portinfo));
	portinfo.addr.client = client;
	portinfo.addr.port   = port;
	err = snd_seq_kernel_client_ctl(client,
					SNDRV_SEQ_IOCTL_DELETE_PORT,
					&portinfo);

	return err;
}
EXPORT_SYMBOL(snd_seq_event_port_detach);
