// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2017 - Cambridge Greys Ltd
 * Copyright (C) 2011 - 2014 Cisco Systems Inc
 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 */

#include <stdlib.h>
#include <errno.h>
#include <sys/epoll.h>
#include <signal.h>
#include <string.h>
#include <irq_user.h>
#include <os.h>
#include <um_malloc.h>

/* Epoll support */

static int epollfd = -1;

#define MAX_EPOLL_EVENTS 64

static struct epoll_event epoll_events[MAX_EPOLL_EVENTS];

/* Helper to return an Epoll data pointer from an epoll event structure.
 * We need to keep this one on the userspace side to keep includes separate
 */

void *os_epoll_get_data_pointer(int index)
{
	return epoll_events[index].data.ptr;
}

/* Helper to compare events versus the events in the epoll structure.
 * Same as above - needs to be on the userspace side
 */


int os_epoll_triggered(int index, int events)
{
	return epoll_events[index].events & events;
}
/* Helper to set the event mask.
 * The event mask is opaque to the kernel side, because it does not have
 * access to the right includes/defines for EPOLL constants.
 */

int os_event_mask(int irq_type)
{
	if (irq_type == IRQ_READ)
		return EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLRDHUP;
	if (irq_type == IRQ_WRITE)
		return EPOLLOUT;
	return 0;
}

/*
 * Initial Epoll Setup
 */
int os_setup_epoll(void)
{
	epollfd = epoll_create(MAX_EPOLL_EVENTS);
	return epollfd;
}

/*
 * Helper to run the actual epoll_wait
 */
int os_waiting_for_events_epoll(void)
{
	int n, err;

	n = epoll_wait(epollfd,
		(struct epoll_event *) &epoll_events, MAX_EPOLL_EVENTS, 0);
	if (n < 0) {
		err = -errno;
		if (errno != EINTR)
			printk(
				UM_KERN_ERR "os_waiting_for_events:"
				" epoll returned %d, error = %s\n", n,
				strerror(errno)
			);
		return err;
	}
	return n;
}


/*
 * Helper to add a fd to epoll
 */
int os_add_epoll_fd(int events, int fd, void *data)
{
	struct epoll_event event;
	int result;

	event.data.ptr = data;
	event.events = events | EPOLLET;
	result = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event);
	if ((result) && (errno == EEXIST))
		result = os_mod_epoll_fd(events, fd, data);
	if (result)
		printk("epollctl add err fd %d, %s\n", fd, strerror(errno));
	return result;
}

/*
 * Helper to mod the fd event mask and/or data backreference
 */
int os_mod_epoll_fd(int events, int fd, void *data)
{
	struct epoll_event event;
	int result;

	event.data.ptr = data;
	event.events = events;
	result = epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event);
	if (result)
		printk(UM_KERN_ERR
			"epollctl mod err fd %d, %s\n", fd, strerror(errno));
	return result;
}

/*
 * Helper to delete the epoll fd
 */
int os_del_epoll_fd(int fd)
{
	struct epoll_event event;
	int result;
	/* This is quiet as we use this as IO ON/OFF - so it is often
	 * invoked on a non-existent fd
	 */
	result = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &event);
	return result;
}

void os_set_ioignore(void)
{
	signal(SIGIO, SIG_IGN);
}

void os_close_epoll_fd(void)
{
	/* Needed so we do not leak an fd when rebooting */
	os_close_file(epollfd);
}
