/*
 * Copyright 2012, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *    * Neither the name of Google Inc. nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * pci.c: Quick PCI access, requires linux /proc/bus/pci or
 * directory that has same structure
 *
 * FIXME: does not handle extended configuration space (>256B)
 */

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <inttypes.h>
#include <dirent.h>

#include "mosys/platform.h"
#include "mosys/globals.h"
#include "mosys/log.h"

#include "lib/string.h"

#include "intf/pci.h"

/* default PCI root directory */
#define PCI_PROC_DIR	"/proc/bus/pci"

/* used throughout this file */
static char *pci_proc_dir;

static int pci_setup(struct platform_intf *intf)
{
	pci_proc_dir = format_string("%s/%s", mosys_get_root_prefix(),
	                             PCI_PROC_DIR);
	return 0;
}

static void pci_destroy(struct platform_intf *intf)
{
	free(pci_proc_dir);
}

/*
 * pci_open_file  -  Open PCI dev file based on bus/dev/func under given root
 *
 * @bus:	pci bus number
 * @dev:	pci device id
 * @func:	pci function id
 * @rw:         read=0, write=1
 *
 * returns valid file descriptor on success
 * returns <0 on failure
 */
static int pci_open_file(int bus, int dev, int func, int rw)
{
	char pcif[1024];

	snprintf(pcif, sizeof(pcif), "%s/%02x/%02x.%x",
	         pci_proc_dir, bus, dev, func);

	return open(pcif, rw);
}

/*
 * pci_read_file  -  Read from pci configuration space
 *
 * @intf:       platform interface
 * @bus:        pci bus
 * @dev:        pci device
 * @func:       pci function
 * @reg:        configuration register
 * @length:     number of bytes to read
 * @data:       buffer to read data into
 *
 * returns number of bytes read
 * returns <0 to indicate failure
 */
static int pci_read_file(struct platform_intf *intf, int bus,
                         int dev, int func, int reg, int length, void *data)
{
	int fd, rlen;

	lprintf(LOG_DEBUG,
	        "pci_read_file: reading %02x:%02x.%x at %02x (%d bytes)\n", bus,
	        dev, func, reg, length);

	if (length < 1 || length > 255)
		return -1;

	fd = pci_open_file(bus, dev, func, O_RDONLY);
	if (fd < 0) {
		lprintf(LOG_DEBUG,
		        "Unable to open PCI %02x:%02x.%1x for reading\n", bus,
		        dev, func);
		return -1;
	}

	/* seek to starting register */
	if (lseek(fd, reg, SEEK_SET) == (off_t) - 1) {
		lperror(LOG_DEBUG,
		        "Unable to read from PCI %02x:%02x.%1x at 0x%x", bus,
		        dev, func, reg);
		close(fd);
		return -1;
	}

	/* read the data */
	rlen = read(fd, data, length);

	if (rlen != length)
		lperror(LOG_DEBUG, "Unable to read %d bytes from PCI"
		        " %02x:%02x.%1x at 0x%x", length, bus, dev, func, reg);

	close(fd);

	return rlen;
}

/*
 * pci_write_file  -  Write to pci configuration space
 *
 * @intf:	platform interface
 * @bus:	pci bus
 * @dev:	pci device
 * @func:	pci function
 * @reg:	configuration register
 * @size:	number of bytes to read
 * @data:       buffer to write from
 *
 * returns number of bytes written
 * returns <0 to indicate failure
 */
static int pci_write_file(struct platform_intf *intf, int bus, int dev,
                          int func, int reg, int length, const void *data)
{
	int fd, wlen;

	lprintf(LOG_DEBUG,
	        "pci_write_file: writing %02x:%02x.%x at %02x (%d bytes)\n",
	        bus, dev, func, reg, length);

	if (length < 1 || length > 256)
		return -1;

	fd = pci_open_file(bus, dev, func, O_WRONLY);
	if (fd < 0) {
		lprintf(LOG_DEBUG,
		        "Unable to open PCI %02x:%02x.%1x for writing\n", bus,
		        dev, func);
		return -1;
	}

	/* seek to starting register */
	if (lseek(fd, reg, SEEK_SET) == (off_t) - 1) {
		lperror(LOG_DEBUG, "Unable to write to PCI %02x:%02x.%1x at 0x%x",
		        bus, dev, func, reg);
		close(fd);
		return -1;
	}

	/* write the data */
	wlen = write(fd, data, length);

	if (wlen != length)
		lperror(LOG_DEBUG, "Unable to write %d bytes to PCI"
		        " %02x:%02x.%1x at 0x%x", length, bus, dev, func, reg);

	close(fd);

	return wlen;
}

/*
 * pci_do_foreach_in_bus  -  Execute function on all PCI devices on a given bus
 *
 * @intf:	platform interface
 * @bus:	target pci bus
 * @cb:		pci callback
 * @data:	data supplied to callback
 *
 * Supplied PCI callback will cause bus enumeration to stop if
 * it returns non-zero value.
 *
 * returns 0 to indicate success, failure otherwise.
 */
static int pci_do_foreach_in_bus(struct platform_intf *intf, int bus,
                                 pci_callback_t cb, void *data)
{
	struct dirent *d;
	char path[1024];
	DIR *dp;
	int dev = 0, func = 0;
	int ret = 0;

	if (cb == NULL)
		return -1;

	/* directory is a bus number */
	snprintf(path, sizeof(path), "%s/%02x/",
		 pci_proc_dir, bus);

	if (!(dp = opendir(path))) {
		lprintf(LOG_DEBUG, "Failed to open %s\n", path);
		return -1;
	}

	while ((d = readdir(dp))) {
		if (d->d_type != DT_REG)
			continue;

		/* file is a pci device.function */
		if (sscanf(d->d_name, "%02x.%01x", &dev, &func) != 2) {
			lprintf(LOG_DEBUG, "Invalid PCI file name: %s/%s\n",
			        path, d->d_name);
			continue;
		}

		/* now exec callback, non-zero return means stop */
		lprintf(LOG_DEBUG,
		        "Executing callback for device %02x:%02x.%01x\n",
		        bus, dev, func);

		ret = cb(intf, bus, dev, func, data);
		if (ret != 0) {
			break;
		}
	}
	closedir(dp);
	return ret;
}

/*
 * pci_do_foreach  -  Execute function on all PCI devices
 *
 * @intf:	platform interface
 * @cb:		pci callback
 * @data:	data supplied to callback
 *
 * Supplied PCI callback will cause bus enumeration to stop if
 * it returns non-zero value.
 *
 * returns 0 to indicate success, failure otherwise.
 */
static int pci_do_foreach(struct platform_intf *intf,
                          pci_callback_t cb, void *data)
{
	struct dirent *topd;
	DIR *topdp;
	int ret = 0;

	if (!(topdp = opendir(pci_proc_dir))) {
		lprintf(LOG_DEBUG, "Failed to open %s\n", pci_proc_dir);
		return -1;
	}

	while ((topd = readdir(topdp))) {
		if (topd->d_type != DT_DIR)
			continue;

		/* Ignore driectories with '.' in the first part of the name. */
		if (topd->d_name[0] == '.')
			continue;

		ret = pci_foreach_in_bus(intf,
		                         strtol(topd->d_name, NULL, 16), cb, data);

		if (ret != 0) {
			closedir(topdp);
			return ret;
		}
	}

	if (topdp)
		closedir(topdp);

	return ret;
}

/* PCI operations based on /proc directory */
struct pci_intf pci_file_intf = {
	.setup		= pci_setup,
	.destroy	= pci_destroy,
	.read		= pci_read_file,
	.write		= pci_write_file,
	.foreach	= pci_do_foreach,
	.foreach_in_bus	= pci_do_foreach_in_bus,
};
