/*
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * pci.c: Linux user space PCI bus management.
 *
 * Copyright (c) 2008 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <vppinfra/linux/sysfs.h>

#include <vlib/vlib.h>
#include <vlib/pci/pci.h>
#include <vlib/unix/unix.h>
#include <vlib/linux/vfio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>
#include <linux/vfio.h>
#include <sys/eventfd.h>

#define SYSFS_DEVICES_PCI "/sys/devices/pci"
static const char *sysfs_pci_dev_path = "/sys/bus/pci/devices";
static const char *sysfs_pci_drv_path = "/sys/bus/pci/drivers";
static char *sysfs_mod_vfio_noiommu =
  "/sys/module/vfio/parameters/enable_unsafe_noiommu_mode";

#define pci_log_debug(vm, dev, f, ...) \
  vlib_log(VLIB_LOG_LEVEL_DEBUG, pci_main.log_default, "%U: " f, \
           format_vlib_pci_addr, vlib_pci_get_addr(vm, dev->handle), ## __VA_ARGS__)
#define pci_log_err(vm, dev, f, ...) \
  vlib_log(VLIB_LOG_LEVEL_ERR, pci_main.log_default, "%U: " f, \
           format_vlib_pci_addr, vlib_pci_get_addr(vm, dev->handle), ## __VA_ARGS__)

typedef struct
{
  int fd;
  void *addr;
  size_t size;
} linux_pci_region_t;

typedef struct
{
  int fd;
  u32 clib_file_index;
  union
  {
    pci_intx_handler_function_t *intx_handler;
    pci_msix_handler_function_t *msix_handler;
  };
} linux_pci_irq_t;

typedef enum
{
  LINUX_PCI_DEVICE_TYPE_UNKNOWN,
  LINUX_PCI_DEVICE_TYPE_UIO,
  LINUX_PCI_DEVICE_TYPE_VFIO,
} linux_pci_device_type_t;

typedef struct
{
  linux_pci_device_type_t type;
  vlib_pci_dev_handle_t handle;
  vlib_pci_addr_t addr;
  u32 numa_node;

  /* Resource file descriptors. */
  linux_pci_region_t *regions;

  /* File descriptor for config space read/write. */
  int config_fd;
  u64 config_offset;

  /* Device File descriptor */
  int fd;

  /* read/write file descriptor for io bar */
  int io_fd;
  u64 io_offset;

  /* Minor device for uio device. */
  u32 uio_minor;

  /* Interrupt handlers */
  linux_pci_irq_t intx_irq;
  linux_pci_irq_t *msix_irqs;

  /* private data */
  uword private_data;

  u8 supports_va_dma;

} linux_pci_device_t;

/* Pool of PCI devices. */
typedef struct
{
  vlib_main_t *vlib_main;
  linux_pci_device_t *linux_pci_devices;

} linux_pci_main_t;

extern linux_pci_main_t linux_pci_main;

static linux_pci_device_t *
linux_pci_get_device (vlib_pci_dev_handle_t h)
{
  linux_pci_main_t *lpm = &linux_pci_main;
  return pool_elt_at_index (lpm->linux_pci_devices, h);
}

uword
vlib_pci_get_private_data (vlib_main_t * vm, vlib_pci_dev_handle_t h)
{
  linux_pci_device_t *d = linux_pci_get_device (h);
  return d->private_data;
}

void
vlib_pci_set_private_data (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			   uword private_data)
{
  linux_pci_device_t *d = linux_pci_get_device (h);
  d->private_data = private_data;
}

vlib_pci_addr_t *
vlib_pci_get_addr (vlib_main_t * vm, vlib_pci_dev_handle_t h)
{
  linux_pci_device_t *d = linux_pci_get_device (h);
  return &d->addr;
}

u32
vlib_pci_get_numa_node (vlib_main_t * vm, vlib_pci_dev_handle_t h)
{
  linux_pci_device_t *d = linux_pci_get_device (h);
  return d->numa_node;
}

u32
vlib_pci_get_num_msix_interrupts (vlib_main_t * vm, vlib_pci_dev_handle_t h)
{
  linux_pci_device_t *d = linux_pci_get_device (h);

  if (d->type == LINUX_PCI_DEVICE_TYPE_VFIO)
    {
      struct vfio_irq_info ii = { 0 };

      ii.argsz = sizeof (struct vfio_irq_info);
      ii.index = VFIO_PCI_MSIX_IRQ_INDEX;
      if (ioctl (d->fd, VFIO_DEVICE_GET_IRQ_INFO, &ii) < 0)
	return 0;
      return ii.count;
    }
  return 0;
}

/* Call to allocate/initialize the pci subsystem.
   This is not an init function so that users can explicitly enable
   pci only when it's needed. */
clib_error_t *pci_bus_init (vlib_main_t * vm);

linux_pci_main_t linux_pci_main;

vlib_pci_device_info_t *
vlib_pci_get_device_info (vlib_main_t * vm, vlib_pci_addr_t * addr,
			  clib_error_t ** error)
{
  clib_error_t *err;
  vlib_pci_device_info_t *di;
  u8 *f = 0;
  u32 tmp;
  int fd;
  u8 *tmpstr;
  clib_bitmap_t *bmp = 0;

  di = clib_mem_alloc (sizeof (vlib_pci_device_info_t));
  clib_memset (di, 0, sizeof (vlib_pci_device_info_t));
  di->addr.as_u32 = addr->as_u32;

  u8 *dev_dir_name = format (0, "%s/%U", sysfs_pci_dev_path,
			     format_vlib_pci_addr, addr);

  f = format (0, "%v/config%c", dev_dir_name, 0);
  fd = open ((char *) f, O_RDWR);

  /* Try read-only access if write fails. */
  if (fd < 0)
    fd = open ((char *) f, O_RDONLY);

  if (fd < 0)
    {
      err = clib_error_return_unix (0, "open `%s'", f);
      goto error;
    }

  /* You can only read more that 64 bytes of config space as root; so we try to
     read the full space but fall back to just the first 64 bytes. */
  if (read (fd, &di->config_data, sizeof (di->config_data)) <
      sizeof (di->config0))
    {
      err = clib_error_return_unix (0, "read `%s'", f);
      close (fd);
      goto error;
    }

  {
    static pci_config_header_t all_ones;
    if (all_ones.vendor_id == 0)
      clib_memset (&all_ones, ~0, sizeof (all_ones));

    if (!memcmp (&di->config0.header, &all_ones, sizeof (all_ones)))
      {
	err = clib_error_return (0, "invalid PCI config for `%s'", f);
	close (fd);
	goto error;
      }
  }

  if (di->config0.header.header_type == 0)
    pci_config_type0_little_to_host (&di->config0);
  else
    pci_config_type1_little_to_host (&di->config1);

  di->numa_node = -1;
  vec_reset_length (f);
  f = format (f, "%v/numa_node%c", dev_dir_name, 0);
  err = clib_sysfs_read ((char *) f, "%d", &di->numa_node);
  if (err)
    {
      di->numa_node = -1;
      clib_error_free (err);
    }
  if (di->numa_node == -1)
    {
      /* if '/sys/bus/pci/devices/<device id>/numa_node' returns -1 and
         it is a SMP system, set numa_node to 0. */
      if ((err = clib_sysfs_read ("/sys/devices/system/node/online", "%U",
				  unformat_bitmap_list, &bmp)))
	clib_error_free (err);
      if (clib_bitmap_count_set_bits (bmp) == 1)
	di->numa_node = 0;
    }

  vec_reset_length (f);
  f = format (f, "%v/class%c", dev_dir_name, 0);
  err = clib_sysfs_read ((char *) f, "0x%x", &tmp);
  if (err)
    goto error;
  di->device_class = tmp >> 8;

  vec_reset_length (f);
  f = format (f, "%v/vendor%c", dev_dir_name, 0);
  err = clib_sysfs_read ((char *) f, "0x%x", &tmp);
  if (err)
    goto error;
  di->vendor_id = tmp;

  vec_reset_length (f);
  f = format (f, "%v/device%c", dev_dir_name, 0);
  err = clib_sysfs_read ((char *) f, "0x%x", &tmp);
  if (err)
    goto error;
  di->device_id = tmp;

  vec_reset_length (f);
  f = format (f, "%v/driver%c", dev_dir_name, 0);
  di->driver_name = clib_sysfs_link_to_name ((char *) f);
  if (!di->driver_name)
    di->driver_name = format (0, "<NONE>%c", 0);

  di->iommu_group = -1;
  vec_reset_length (f);
  f = format (f, "%v/iommu_group%c", dev_dir_name, 0);
  tmpstr = clib_sysfs_link_to_name ((char *) f);
  if (tmpstr)
    {
      di->iommu_group = atoi ((char *) tmpstr);
      vec_free (tmpstr);
    }

  vec_reset_length (f);
  f = format (f, "%v/iommu_group/name%c", dev_dir_name, 0);
  err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
  if (err == 0)
    {
      if (strncmp ((char *) tmpstr, "vfio-noiommu", 12) == 0)
	di->flags |= VLIB_PCI_DEVICE_INFO_F_NOIOMMU;
      vec_free (tmpstr);
    }
  else
    clib_error_free (err);

  close (fd);

  vec_reset_length (f);
  f = format (f, "%v/vpd%c", dev_dir_name, 0);
  fd = open ((char *) f, O_RDONLY);
  if (fd >= 0)
    {
      while (1)
	{
	  u8 tag[3];
	  u8 *data = 0;
	  uword len;

	  if (read (fd, &tag, 3) != 3)
	    break;

	  if (tag[0] != 0x82 && tag[0] != 0x90 && tag[0] != 0x91)
	    break;

	  len = (tag[2] << 8) | tag[1];
	  vec_validate (data, len - 1);

	  if (read (fd, data, len) != len)
	    {
	      vec_free (data);
	      break;
	    }
	  if (tag[0] == 0x82)
	    di->product_name = data;
	  else if (tag[0] == 0x90)
	    di->vpd_r = data;
	  else if (tag[0] == 0x91)
	    di->vpd_w = data;

	  data = 0;
	}
      close (fd);
    }

  goto done;

error:
  vlib_pci_free_device_info (di);
  di = 0;

done:
  vec_free (bmp);
  vec_free (f);
  vec_free (dev_dir_name);
  if (error)
    *error = err;
  else
    clib_error_free (err);
  return di;
}

clib_error_t *__attribute__ ((weak))
vlib_pci_get_device_root_bus (vlib_pci_addr_t *addr, vlib_pci_addr_t *root_bus)
{
  u8 *rel_path = 0, *abs_path = 0, *link_path = 0;
  unformat_input_t input;
  int fd = open (sysfs_pci_dev_path, O_RDONLY);
  ssize_t size = 0;
  u32 domain = 0, bus;
  clib_error_t *err = NULL;

  if (fd < 0)
    return clib_error_return_unix (0, "failed to open %s", sysfs_pci_dev_path);

  vec_alloc (rel_path, PATH_MAX);
  vec_alloc (abs_path, PATH_MAX);

  link_path =
    format (0, "%s/%U", sysfs_pci_dev_path, format_vlib_pci_addr, addr);
  size = readlinkat (fd, (char *) link_path, (char *) rel_path, PATH_MAX);
  if (size < 0)
    {
      err = clib_error_return_unix (0, "failed to read %s", rel_path);
      goto done;
    }

  rel_path[size] = '\0';
  vec_free (link_path);

  link_path = format (0, "%s/%s", sysfs_pci_dev_path, rel_path);
  if (!realpath ((char *) link_path, (char *) abs_path))
    {
      err = clib_error_return_unix (0, "failed to resolve %s", link_path);
      goto done;
    }

  unformat_init_string (&input, (char *) abs_path,
			clib_strnlen ((char *) abs_path, PATH_MAX));

  if (!unformat (&input, SYSFS_DEVICES_PCI "%x:%x/%s", &domain, &bus,
		 link_path))
    {
      err = clib_error_return (0, "unknown input '%U'", format_unformat_error,
			       input);
      goto done;
    }

  root_bus->domain = domain;
  root_bus->bus = bus;

done:
  vec_free (abs_path);
  vec_free (link_path);
  vec_free (rel_path);
  close (fd);

  return err;
}

static int
directory_exists (char *path)
{
  struct stat s = { 0 };
  if (stat (path, &s) == -1)
    return 0;

  return S_ISDIR (s.st_mode);
}

clib_error_t *
vlib_pci_bind_to_uio (vlib_main_t *vm, vlib_pci_addr_t *addr,
		      char *uio_drv_name, int force)
{
  clib_error_t *error = 0;
  u8 *s = 0, *driver_name = 0;
  DIR *dir = 0;
  struct dirent *e;
  vlib_pci_device_info_t *di;
  int fd, clear_driver_override = 0;
  u8 *dev_dir_name = format (0, "%s/%U", sysfs_pci_dev_path,
			     format_vlib_pci_addr, addr);

  di = vlib_pci_get_device_info (vm, addr, &error);

  if (error)
    return error;

  if (strncmp ("auto", uio_drv_name, 5) == 0)
    {
      int vfio_pci_loaded = 0;

      if (directory_exists ("/sys/module/vfio_pci"))
	vfio_pci_loaded = 1;

      if (di->iommu_group != -1)
	{
	  /* device is bound to IOMMU group */
	  if (!vfio_pci_loaded)
	    {
	      error = clib_error_return (0, "Skipping PCI device %U: device "
					 "is bound to IOMMU group and "
					 "vfio-pci driver is not loaded",
					 format_vlib_pci_addr, addr);
	      goto err0;
	    }
	  else
	    uio_drv_name = "vfio-pci";
	}
      else
	{
	  /* device is not bound to IOMMU group so we have multiple options */
	  if (vfio_pci_loaded &&
	      (error = clib_sysfs_write (sysfs_mod_vfio_noiommu, "Y")) == 0)
	    uio_drv_name = "vfio-pci";
	  else if (directory_exists ("/sys/module/uio_pci_generic"))
	    uio_drv_name = "uio_pci_generic";
	  else if (directory_exists ("/sys/module/igb_uio"))
	    uio_drv_name = "igb_uio";
	  else
	    {
	      clib_error_free (error);
	      error = clib_error_return (0, "Skipping PCI device %U: missing "
					 "kernel VFIO or UIO driver",
					 format_vlib_pci_addr, addr);
	      goto err0;
	    }
	  clib_error_free (error);
	}
    }

  s = format (s, "%v/driver%c", dev_dir_name, 0);
  driver_name = clib_sysfs_link_to_name ((char *) s);
  vec_reset_length (s);

  if (driver_name &&
      ((strcmp ("vfio-pci", (char *) driver_name) == 0) ||
       (strcmp ("uio_pci_generic", (char *) driver_name) == 0) ||
       (strcmp ("igb_uio", (char *) driver_name) == 0)))
    goto err0;

  if (!force)
    {
      /* walk trough all linux interfaces and if interface belonging to
	 this device is found check if interface is admin up  */
      dir = opendir ("/sys/class/net");
      s = format (s, "%U%c", format_vlib_pci_addr, addr, 0);

      if (!dir)
	{
	  error = clib_error_return (0,
				     "Skipping PCI device %U: failed to "
				     "read /sys/class/net",
				     format_vlib_pci_addr, addr);
	  goto err0;
	}

      fd = socket (PF_INET, SOCK_DGRAM, 0);
      if (fd < 0)
	{
	  error = clib_error_return_unix (0, "socket");
	  goto err1;
	}

      while ((e = readdir (dir)))
	{
	  struct ifreq ifr;
	  struct ethtool_drvinfo drvinfo;

	  if (e->d_name[0] == '.') /* skip . and .. */
	    continue;

	  clib_memset (&ifr, 0, sizeof ifr);
	  clib_memset (&drvinfo, 0, sizeof drvinfo);
	  ifr.ifr_data = (char *) &drvinfo;
	  clib_strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name) - 1);

	  drvinfo.cmd = ETHTOOL_GDRVINFO;
	  if (ioctl (fd, SIOCETHTOOL, &ifr) < 0)
	    {
	      /* Some interfaces (eg "lo") don't support this ioctl */
	      if ((errno != ENOTSUP) && (errno != ENODEV))
		clib_unix_warning ("ioctl fetch intf %s bus info error",
				   e->d_name);
	      continue;
	    }

	  if (strcmp ((char *) s, drvinfo.bus_info))
	    continue;

	  clib_memset (&ifr, 0, sizeof (ifr));
	  clib_strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name) - 1);

	  if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0)
	    {
	      error = clib_error_return_unix (0, "ioctl fetch intf %s flags",
					      e->d_name);
	      close (fd);
	      goto err1;
	    }

	  if (ifr.ifr_flags & IFF_UP)
	    {
	      vlib_log (VLIB_LOG_LEVEL_WARNING, pci_main.log_default,
			"Skipping PCI device %U as host "
			"interface %s is up",
			format_vlib_pci_addr, addr, e->d_name);
	      close (fd);
	      goto err1;
	    }
	}

      close (fd);
      vec_reset_length (s);
    }

  s = format (s, "%v/driver/unbind%c", dev_dir_name, 0);
  clib_sysfs_write ((char *) s, "%U", format_vlib_pci_addr, addr);
  vec_reset_length (s);

  s = format (s, "%v/driver_override%c", dev_dir_name, 0);
  if (access ((char *) s, F_OK) == 0)
    {
      clib_sysfs_write ((char *) s, "%s", uio_drv_name);
      clear_driver_override = 1;
    }
  else
    {
      vec_reset_length (s);
      s = format (s, "%s/%s/new_id%c", sysfs_pci_drv_path, uio_drv_name, 0);
      clib_sysfs_write ((char *) s, "0x%04x 0x%04x", di->vendor_id,
			di->device_id);
    }
  vec_reset_length (s);

  s = format (s, "%s/%s/bind%c", sysfs_pci_drv_path, uio_drv_name, 0);
  clib_sysfs_write ((char *) s, "%U", format_vlib_pci_addr, addr);
  vec_reset_length (s);

  if (clear_driver_override)
    {
      s = format (s, "%v/driver_override%c", dev_dir_name, 0);
      clib_sysfs_write ((char *) s, "%c", 0);
      vec_reset_length (s);
    }

err1:
  closedir (dir);
err0:
  vec_free (s);
  vec_free (dev_dir_name);
  vec_free (driver_name);
  return error;
}


static clib_error_t *
scan_uio_dir (void *arg, u8 * path_name, u8 * file_name)
{
  linux_pci_device_t *l = arg;
  unformat_input_t input;

  unformat_init_string (&input, (char *) file_name, vec_len (file_name));

  if (!unformat (&input, "uio%d", &l->uio_minor))
    abort ();

  unformat_free (&input);
  return 0;
}

static clib_error_t *
vfio_set_irqs (vlib_main_t * vm, linux_pci_device_t * p, u32 index, u32 start,
	       u32 count, u32 flags, int *efds)
{
  int data_len = efds ? count * sizeof (int) : 0;
  u8 buf[sizeof (struct vfio_irq_set) + data_len];
  struct vfio_irq_info ii = { 0 };
  struct vfio_irq_set *irq_set = (struct vfio_irq_set *) buf;


  ii.argsz = sizeof (struct vfio_irq_info);
  ii.index = index;

  if (ioctl (p->fd, VFIO_DEVICE_GET_IRQ_INFO, &ii) < 0)
    return clib_error_return_unix (0, "ioctl(VFIO_DEVICE_GET_IRQ_INFO) "
				   "'%U'", format_vlib_pci_addr, &p->addr);

  pci_log_debug (vm, p, "%s index:%u count:%u flags: %s%s%s%s(0x%x)",
		 __func__, ii.index, ii.count,
		 ii.flags & VFIO_IRQ_INFO_EVENTFD ? "eventfd " : "",
		 ii.flags & VFIO_IRQ_INFO_MASKABLE ? "maskable " : "",
		 ii.flags & VFIO_IRQ_INFO_AUTOMASKED ? "automasked " : "",
		 ii.flags & VFIO_IRQ_INFO_NORESIZE ? "noresize " : "",
		 ii.flags);

  if (ii.count < start + count)
    return clib_error_return_unix (0, "vfio_set_irq: unexistng interrupt on "
				   "'%U'", format_vlib_pci_addr, &p->addr);


  if (efds)
    {
      flags |= VFIO_IRQ_SET_DATA_EVENTFD;
      clib_memcpy_fast (&irq_set->data, efds, data_len);
    }
  else
    flags |= VFIO_IRQ_SET_DATA_NONE;

  ASSERT ((flags & (VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_DATA_EVENTFD)) !=
	  (VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_DATA_EVENTFD));

  irq_set->argsz = sizeof (struct vfio_irq_set) + data_len;
  irq_set->index = index;
  irq_set->start = start;
  irq_set->count = count;
  irq_set->flags = flags;

  if (ioctl (p->fd, VFIO_DEVICE_SET_IRQS, irq_set) < 0)
    return clib_error_return_unix (0, "%U:ioctl(VFIO_DEVICE_SET_IRQS) "
				   "[index = %u, start = %u, count = %u, "
				   "flags = 0x%x]",
				   format_vlib_pci_addr, &p->addr,
				   index, start, count, flags);
  return 0;
}

static clib_error_t *
linux_pci_uio_read_ready (clib_file_t * uf)
{
  vlib_main_t *vm = vlib_get_main ();
  int __attribute__ ((unused)) rv;
  vlib_pci_dev_handle_t h = uf->private_data;
  linux_pci_device_t *p = linux_pci_get_device (h);
  linux_pci_irq_t *irq = &p->intx_irq;

  u32 icount;
  rv = read (uf->file_descriptor, &icount, 4);

  if (irq->intx_handler)
    irq->intx_handler (vm, h);

  vlib_pci_intr_enable (vm, h);

  return /* no error */ 0;
}

static clib_error_t *
linux_pci_vfio_unmask_intx (vlib_main_t * vm, linux_pci_device_t * d)
{
  return vfio_set_irqs (vm, d, VFIO_PCI_INTX_IRQ_INDEX, 0, 1,
			VFIO_IRQ_SET_ACTION_UNMASK, 0);
}

static clib_error_t *
linux_pci_uio_error_ready (clib_file_t * uf)
{
  u32 error_index = (u32) uf->private_data;

  return clib_error_return (0, "pci device %d: error", error_index);
}

static clib_error_t *
linux_pci_vfio_msix_read_ready (clib_file_t * uf)
{
  vlib_main_t *vm = vlib_get_main ();
  int __attribute__ ((unused)) rv;
  vlib_pci_dev_handle_t h = uf->private_data >> 16;
  u16 line = uf->private_data & 0xffff;
  linux_pci_device_t *p = linux_pci_get_device (h);
  linux_pci_irq_t *irq = vec_elt_at_index (p->msix_irqs, line);

  u64 icount;
  rv = read (uf->file_descriptor, &icount, sizeof (icount));

  if (irq->msix_handler)
    irq->msix_handler (vm, h, line);

  return /* no error */ 0;
}

static clib_error_t *
linux_pci_vfio_intx_read_ready (clib_file_t * uf)
{
  vlib_main_t *vm = vlib_get_main ();
  int __attribute__ ((unused)) rv;
  vlib_pci_dev_handle_t h = uf->private_data;
  linux_pci_device_t *p = linux_pci_get_device (h);
  linux_pci_irq_t *irq = &p->intx_irq;

  u64 icount;
  rv = read (uf->file_descriptor, &icount, sizeof (icount));

  if (irq->intx_handler)
    irq->intx_handler (vm, h);

  linux_pci_vfio_unmask_intx (vm, p);

  return /* no error */ 0;
}

static clib_error_t *
linux_pci_vfio_error_ready (clib_file_t * uf)
{
  u32 error_index = (u32) uf->private_data;

  return clib_error_return (0, "pci device %d: error", error_index);
}

static clib_error_t *
add_device_uio (vlib_main_t * vm, linux_pci_device_t * p,
		vlib_pci_device_info_t * di, pci_device_registration_t * r)
{
  linux_pci_main_t *lpm = &linux_pci_main;
  clib_error_t *err = 0;
  u8 *s = 0;

  p->fd = -1;
  p->type = LINUX_PCI_DEVICE_TYPE_UIO;

  s = format (s, "%s/%U/config%c", sysfs_pci_dev_path,
	      format_vlib_pci_addr, &di->addr, 0);

  p->config_fd = open ((char *) s, O_RDWR);
  p->config_offset = 0;
  vec_reset_length (s);

  if (p->config_fd == -1)
    {
      err = clib_error_return_unix (0, "open '%s'", s);
      goto error;
    }

  s = format (0, "%s/%U/uio%c", sysfs_pci_dev_path,
	      format_vlib_pci_addr, &di->addr, 0);
  foreach_directory_file ((char *) s, scan_uio_dir, p,	/* scan_dirs */
			  1);
  vec_reset_length (s);

  s = format (s, "/dev/uio%d%c", p->uio_minor, 0);
  p->fd = open ((char *) s, O_RDWR);
  if (p->fd < 0)
    {
      err = clib_error_return_unix (0, "open '%s'", s);
      goto error;
    }

  if (r && r->interrupt_handler)
    vlib_pci_register_intx_handler (vm, p->handle, r->interrupt_handler);

  if (r && r->init_function)
    err = r->init_function (lpm->vlib_main, p->handle);

error:
  vec_free (s);
  if (err)
    {
      if (p->config_fd != -1)
	close (p->config_fd);
      if (p->fd != -1)
	close (p->fd);
    }
  return err;
}

clib_error_t *
vlib_pci_register_intx_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
				pci_intx_handler_function_t * intx_handler)
{
  linux_pci_device_t *p = linux_pci_get_device (h);
  clib_file_t t = { 0 };
  linux_pci_irq_t *irq = &p->intx_irq;
  ASSERT (irq->fd == -1);

  if (p->type == LINUX_PCI_DEVICE_TYPE_VFIO)
    {
      struct vfio_irq_info ii = { 0 };
      ii.argsz = sizeof (struct vfio_irq_info);
      ii.index = VFIO_PCI_INTX_IRQ_INDEX;
      if (ioctl (p->fd, VFIO_DEVICE_GET_IRQ_INFO, &ii) < 0)
	return clib_error_return_unix (0, "ioctl(VFIO_DEVICE_GET_IRQ_INFO) '"
				       "%U'", format_vlib_pci_addr, &p->addr);
      pci_log_debug (vm, p, "%s index:%u count:%u flags: %s%s%s%s(0x%x)",
		     __func__, ii.index, ii.count,
		     ii.flags & VFIO_IRQ_INFO_EVENTFD ? "eventfd " : "",
		     ii.flags & VFIO_IRQ_INFO_MASKABLE ? "maskable " : "",
		     ii.flags & VFIO_IRQ_INFO_AUTOMASKED ? "automasked " : "",
		     ii.flags & VFIO_IRQ_INFO_NORESIZE ? "noresize " : "",
		     ii.flags);
      if (ii.count != 1)
	return clib_error_return (0, "INTx interrupt does not exist on device"
				  "'%U'", format_vlib_pci_addr, &p->addr);

      irq->fd = eventfd (0, EFD_NONBLOCK);
      if (irq->fd == -1)
	return clib_error_return_unix (0, "eventfd");

      t.file_descriptor = irq->fd;
      t.read_function = linux_pci_vfio_intx_read_ready;
    }
  else if (p->type == LINUX_PCI_DEVICE_TYPE_UIO)
    {
      t.file_descriptor = p->fd;
      t.read_function = linux_pci_uio_read_ready;
    }
  else
    return 0;

  t.error_function = linux_pci_uio_error_ready;
  t.private_data = p->handle;
  t.description = format (0, "PCI %U INTx", format_vlib_pci_addr, &p->addr);
  irq->clib_file_index = clib_file_add (&file_main, &t);
  irq->intx_handler = intx_handler;
  return 0;
}

clib_error_t *
vlib_pci_register_msix_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
				u32 start, u32 count,
				pci_msix_handler_function_t * msix_handler)
{
  clib_error_t *err = 0;
  linux_pci_device_t *p = linux_pci_get_device (h);
  u32 i;

  if (p->type != LINUX_PCI_DEVICE_TYPE_VFIO)
    return clib_error_return (0, "vfio driver is needed for MSI-X interrupt "
			      "support");

  /* *INDENT-OFF* */
  vec_validate_init_empty (p->msix_irqs, start + count - 1, (linux_pci_irq_t)
			   { .fd = -1});
  /* *INDENT-ON* */

  for (i = start; i < start + count; i++)
    {
      clib_file_t t = { 0 };
      linux_pci_irq_t *irq = vec_elt_at_index (p->msix_irqs, i);
      ASSERT (irq->fd == -1);

      irq->fd = eventfd (0, EFD_NONBLOCK);
      if (irq->fd == -1)
	{
	  err = clib_error_return_unix (0, "eventfd");
	  goto error;
	}

      t.read_function = linux_pci_vfio_msix_read_ready;
      t.file_descriptor = irq->fd;
      t.error_function = linux_pci_vfio_error_ready;
      t.private_data = p->handle << 16 | i;
      t.description = format (0, "PCI %U MSI-X #%u", format_vlib_pci_addr,
			      &p->addr, i);
      irq->clib_file_index = clib_file_add (&file_main, &t);
      irq->msix_handler = msix_handler;
    }

  return 0;

error:
  while (i-- > start)
    {
      linux_pci_irq_t *irq = vec_elt_at_index (p->msix_irqs, i);
      if (irq->fd != -1)
	{
	  clib_file_del_by_index (&file_main, irq->clib_file_index);
	  close (irq->fd);
	  irq->fd = -1;
	}
    }
  return err;
}

clib_error_t *
vlib_pci_enable_msix_irq (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			  u16 start, u16 count)
{
  linux_pci_device_t *p = linux_pci_get_device (h);
  int fds[count];
  int i;

  if (p->type != LINUX_PCI_DEVICE_TYPE_VFIO)
    return clib_error_return (0, "vfio driver is needed for MSI-X interrupt "
			      "support");

  for (i = start; i < start + count; i++)
    {
      linux_pci_irq_t *irq = vec_elt_at_index (p->msix_irqs, i);
      fds[i] = irq->fd;
    }

  return vfio_set_irqs (vm, p, VFIO_PCI_MSIX_IRQ_INDEX, start, count,
			VFIO_IRQ_SET_ACTION_TRIGGER, fds);
}

uword
vlib_pci_get_msix_file_index (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			      u16 index)
{
  linux_pci_device_t *p = linux_pci_get_device (h);
  linux_pci_irq_t *irq = vec_elt_at_index (p->msix_irqs, index);
  if (irq->fd == -1)
    return ~0;
  return irq->clib_file_index;
}

clib_error_t *
vlib_pci_disable_msix_irq (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			   u16 start, u16 count)
{
  linux_pci_device_t *p = linux_pci_get_device (h);
  int i, fds[count];

  if (p->type != LINUX_PCI_DEVICE_TYPE_VFIO)
    return clib_error_return (0, "vfio driver is needed for MSI-X interrupt "
			      "support");

  for (i = start; i < start + count; i++)
    fds[i] = -1;

  return vfio_set_irqs (vm, p, VFIO_PCI_MSIX_IRQ_INDEX, start, count,
			VFIO_IRQ_SET_ACTION_TRIGGER, fds);
}

static clib_error_t *
add_device_vfio (vlib_main_t * vm, linux_pci_device_t * p,
		 vlib_pci_device_info_t * di, pci_device_registration_t * r)
{
  linux_pci_main_t *lpm = &linux_pci_main;
  struct vfio_device_info device_info = { 0 };
  struct vfio_region_info reg = { 0 };
  clib_error_t *err = 0;
  u8 *s = 0;
  int is_noiommu;

  p->type = LINUX_PCI_DEVICE_TYPE_VFIO;

  if ((err = linux_vfio_group_get_device_fd (&p->addr, &p->fd, &is_noiommu)))
    return err;

  if (is_noiommu == 0)
    p->supports_va_dma = 1;

  device_info.argsz = sizeof (device_info);
  if (ioctl (p->fd, VFIO_DEVICE_GET_INFO, &device_info) < 0)
    {
      err = clib_error_return_unix (0, "ioctl(VFIO_DEVICE_GET_INFO) '%U'",
				    format_vlib_pci_addr, &di->addr);
      goto error;
    }

  reg.argsz = sizeof (struct vfio_region_info);
  reg.index = VFIO_PCI_CONFIG_REGION_INDEX;
  if (ioctl (p->fd, VFIO_DEVICE_GET_REGION_INFO, &reg) < 0)
    {
      err = clib_error_return_unix (0, "ioctl(VFIO_DEVICE_GET_INFO) '%U'",
				    format_vlib_pci_addr, &di->addr);
      goto error;
    }

  pci_log_debug (vm, p, "%s %U", __func__, format_vfio_region_info, &reg);

  p->config_offset = reg.offset;
  p->config_fd = p->fd;

  /* reset if device supports it */
  if (device_info.flags & VFIO_DEVICE_FLAGS_RESET)
    if (ioctl (p->fd, VFIO_DEVICE_RESET) < 0)
      {
	err = clib_error_return_unix (0, "ioctl(VFIO_DEVICE_RESET) '%U'",
				      format_vlib_pci_addr, &di->addr);
	goto error;
      }

  if (r && r->interrupt_handler)
    {
      vlib_pci_register_intx_handler (vm, p->handle, r->interrupt_handler);
      linux_pci_vfio_unmask_intx (vm, p);
    }

  if (p->supports_va_dma)
    {
      vlib_buffer_pool_t *bp;
      /* *INDENT-OFF* */
      vec_foreach (bp, vm->buffer_main->buffer_pools)
	{
	  u32 i;
	  vlib_physmem_map_t *pm;
	  pm = vlib_physmem_get_map (vm, bp->physmem_map_index);
	  for (i = 0; i < pm->n_pages; i++)
	    vfio_map_physmem_page (vm, pm->base + (i << pm->log2_page_size));
	}
      /* *INDENT-ON* */
    }

  if (r && r->init_function)
    err = r->init_function (lpm->vlib_main, p->handle);

error:
  vec_free (s);
  if (err)
    {
      if (p->fd != -1)
	close (p->fd);
      if (p->config_fd != -1 && p->config_fd != p->fd)
	close (p->config_fd);
      p->config_fd = p->fd = -1;
    }
  return err;
}

/* Configuration space read/write. */
clib_error_t *
vlib_pci_read_write_config (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			    vlib_read_or_write_t read_or_write,
			    uword address, void *data, u32 n_bytes)
{
  linux_pci_device_t *p = linux_pci_get_device (h);
  int n;

  if (read_or_write == VLIB_READ)
    n = pread (p->config_fd, data, n_bytes, p->config_offset + address);
  else
    n = pwrite (p->config_fd, data, n_bytes, p->config_offset + address);

  if (n != n_bytes)
    return clib_error_return_unix (0, "%s",
				   read_or_write == VLIB_READ
				   ? "read" : "write");

  return 0;
}

static clib_error_t *
vlib_pci_region (vlib_main_t * vm, vlib_pci_dev_handle_t h, u32 bar, int *fd,
		 u64 * size, u64 * offset)
{
  linux_pci_device_t *p = linux_pci_get_device (h);
  clib_error_t *error = 0;
  int _fd = -1;
  u64 _size = 0, _offset = 0;

  ASSERT (bar <= 5);

  error = 0;

  if (p->type == LINUX_PCI_DEVICE_TYPE_UIO)
    {
      u8 *file_name;
      struct stat stat_buf;
      file_name = format (0, "%s/%U/resource%d%c", sysfs_pci_dev_path,
			  format_vlib_pci_addr, &p->addr, bar, 0);

      _fd = open ((char *) file_name, O_RDWR);
      if (_fd < 0)
	{
	  error = clib_error_return_unix (0, "open `%s'", file_name);
	  vec_free (file_name);
	  return error;
	}

      if (fstat (_fd, &stat_buf) < 0)
	{
	  error = clib_error_return_unix (0, "fstat `%s'", file_name);
	  vec_free (file_name);
	  close (_fd);
	  return error;
	}

      vec_free (file_name);
      _size = stat_buf.st_size;
      _offset = 0;
    }
  else if (p->type == LINUX_PCI_DEVICE_TYPE_VFIO)
    {
      struct vfio_region_info *r;
      u32 sz = sizeof (struct vfio_region_info);
    again:
      r = clib_mem_alloc (sz);
      clib_memset (r, 0, sz);
      r->argsz = sz;
      r->index = bar;
      if (ioctl (p->fd, VFIO_DEVICE_GET_REGION_INFO, r) < 0)
	return clib_error_return_unix (0, "ioctl(VFIO_DEVICE_GET_INFO) "
				       "'%U'", format_vlib_pci_addr,
				       &p->addr);
      if (sz != r->argsz)
	{
	  sz = r->argsz;
	  clib_mem_free (r);
	  goto again;
	}
      _fd = p->fd;
      _size = r->size;
      _offset = r->offset;
      pci_log_debug (vm, p, "%s %U", __func__, format_vfio_region_info, r);
      clib_mem_free (r);
    }
  else
    ASSERT (0);

  *fd = _fd;
  *size = _size;
  *offset = _offset;

  return error;
}

static clib_error_t *
vlib_pci_map_region_int (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			 u32 bar, u8 * addr, void **result)
{
  linux_pci_device_t *p = linux_pci_get_device (h);
  int fd = -1;
  clib_error_t *error;
  u64 size = 0, offset = 0;
  u16 command;

  pci_log_debug (vm, p, "map region %u to va %p", bar, addr);

  if ((error = vlib_pci_read_config_u16 (vm, h, 4, &command)))
    return error;

  if (!(command & PCI_COMMAND_MEMORY))
    {
      pci_log_debug (vm, p, "setting memory enable bit");
      command |= PCI_COMMAND_MEMORY;
      if ((error = vlib_pci_write_config_u16 (vm, h, 4, &command)))
	return error;
    }

  if ((error = vlib_pci_region (vm, h, bar, &fd, &size, &offset)))
    return error;

  *result = clib_mem_vm_map_shared (addr, size, fd, offset,
				    "PCIe %U region %u", format_vlib_pci_addr,
				    vlib_pci_get_addr (vm, h), bar);
  if (*result == CLIB_MEM_VM_MAP_FAILED)
    {
      error = clib_error_return_unix (0, "mmap `BAR%u'", bar);
      if (p->type == LINUX_PCI_DEVICE_TYPE_UIO && (fd != -1))
	close (fd);
      return error;
    }

  /* *INDENT-OFF* */
  vec_validate_init_empty (p->regions, bar,
			   (linux_pci_region_t) { .fd = -1});
  /* *INDENT-ON* */
  if (p->type == LINUX_PCI_DEVICE_TYPE_UIO)
    p->regions[bar].fd = fd;
  p->regions[bar].addr = *result;
  p->regions[bar].size = size;
  return 0;
}

clib_error_t *
vlib_pci_map_region (vlib_main_t * vm, vlib_pci_dev_handle_t h, u32 resource,
		     void **result)
{
  return (vlib_pci_map_region_int (vm, h, resource, 0 /* addr */ , result));
}

clib_error_t *
vlib_pci_map_region_fixed (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			   u32 resource, u8 * addr, void **result)
{
  return (vlib_pci_map_region_int (vm, h, resource, addr, result));
}

clib_error_t *
vlib_pci_io_region (vlib_main_t * vm, vlib_pci_dev_handle_t h, u32 resource)
{
  linux_pci_device_t *p = linux_pci_get_device (h);
  clib_error_t *error = 0;
  int fd = -1;
  u64 size = 0, offset = 0;

  if ((error = vlib_pci_region (vm, h, resource, &fd, &size, &offset)))
    return error;

  p->io_fd = fd;
  p->io_offset = offset;
  return error;
}

clib_error_t *
vlib_pci_read_write_io (vlib_main_t * vm, vlib_pci_dev_handle_t h,
			vlib_read_or_write_t read_or_write,
			uword offset, void *data, u32 length)
{
  linux_pci_device_t *p = linux_pci_get_device (h);
  int n = 0;

  if (read_or_write == VLIB_READ)
    n = pread (p->io_fd, data, length, p->io_offset + offset);
  else
    n = pwrite (p->io_fd, data, length, p->io_offset + offset);

  if (n != length)
    return clib_error_return_unix (0, "%s",
				   read_or_write == VLIB_READ
				   ? "read" : "write");
  return 0;
}

clib_error_t *
vlib_pci_map_dma (vlib_main_t * vm, vlib_pci_dev_handle_t h, void *ptr)
{
  linux_pci_device_t *p = linux_pci_get_device (h);

  if (!p->supports_va_dma)
    return 0;

  return vfio_map_physmem_page (vm, ptr);
}

int
vlib_pci_supports_virtual_addr_dma (vlib_main_t * vm, vlib_pci_dev_handle_t h)
{
  linux_pci_device_t *p = linux_pci_get_device (h);

  return p->supports_va_dma != 0;
}

clib_error_t *
vlib_pci_device_open (vlib_main_t * vm, vlib_pci_addr_t * addr,
		      pci_device_id_t ids[], vlib_pci_dev_handle_t * handle)
{
  linux_pci_main_t *lpm = &linux_pci_main;
  vlib_pci_device_info_t *di;
  linux_pci_device_t *p;
  clib_error_t *err = 0;
  pci_device_id_t *i;

  di = vlib_pci_get_device_info (vm, addr, &err);

  if (err)
    return err;
  for (i = ids; i->vendor_id != 0; i++)
    if (i->vendor_id == di->vendor_id && i->device_id == di->device_id)
      break;

  if (i->vendor_id == 0)
    return clib_error_return (0, "Wrong vendor or device id");

  pool_get (lpm->linux_pci_devices, p);
  p->handle = p - lpm->linux_pci_devices;
  p->addr.as_u32 = di->addr.as_u32;
  p->intx_irq.fd = -1;
  p->intx_irq.clib_file_index = -1;
  p->numa_node = di->numa_node;
  /*
   * pci io bar read/write fd
   */
  p->io_fd = -1;

  pci_log_debug (vm, p, "open vid:0x%04x did:0x%04x driver:%s iommu_group:%d",
		 di->vendor_id, di->device_id, di->driver_name,
		 di->iommu_group);

  if (clib_strncmp ("vfio-pci", (char *) di->driver_name, 8) == 0)
    err = add_device_vfio (vm, p, di, 0);
  else if (clib_strncmp ("uio_pci_generic", (char *) di->driver_name, 8) == 0)
    err = add_device_uio (vm, p, di, 0);
  else
    err = clib_error_create ("device not bound to 'vfio-pci' or "
			     "'uio_pci_generic' kernel module");
  if (err)
    goto error;

  *handle = p->handle;

error:
  vlib_pci_free_device_info (di);
  if (err)
    {
      pci_log_err (vm, p, "%U", format_clib_error, err);
      clib_memset (p, 0, sizeof (linux_pci_device_t));
      pool_put (lpm->linux_pci_devices, p);
    }

  return err;
}

void
vlib_pci_device_close (vlib_main_t * vm, vlib_pci_dev_handle_t h)
{
  linux_pci_main_t *lpm = &linux_pci_main;
  linux_pci_device_t *p = linux_pci_get_device (h);
  linux_pci_irq_t *irq;
  linux_pci_region_t *res;
  clib_error_t *err = 0;

  if (p->type == LINUX_PCI_DEVICE_TYPE_UIO)
    {
      irq = &p->intx_irq;
      if (irq->clib_file_index != -1)
	clib_file_del_by_index (&file_main, irq->clib_file_index);
      close (p->config_fd);
      if (p->io_fd != -1)
	close (p->io_fd);
    }
  else if (p->type == LINUX_PCI_DEVICE_TYPE_VFIO)
    {
      irq = &p->intx_irq;
      /* close INTx irqs */
      if (irq->fd != -1)
	{
	  err = vfio_set_irqs (vm, p, VFIO_PCI_INTX_IRQ_INDEX, 0, 0,
			       VFIO_IRQ_SET_ACTION_TRIGGER, 0);
	  clib_error_free (err);
	  if (irq->clib_file_index != -1)
	    clib_file_del_by_index (&file_main, irq->clib_file_index);
	  close (irq->fd);
	}

      /* close MSI-X irqs */
      if (vec_len (p->msix_irqs))
	{
	  err = vfio_set_irqs (vm, p, VFIO_PCI_MSIX_IRQ_INDEX, 0, 0,
			       VFIO_IRQ_SET_ACTION_TRIGGER, 0);
	  clib_error_free (err);
          /* *INDENT-OFF* */
	  vec_foreach (irq, p->msix_irqs)
	    {
	      if (irq->fd == -1)
		continue;
	      clib_file_del_by_index (&file_main, irq->clib_file_index);
	      close (irq->fd);
	    }
          /* *INDENT-ON* */
	  vec_free (p->msix_irqs);
	}
    }

  /* *INDENT-OFF* */
  vec_foreach (res, p->regions)
    {
      if (res->size == 0)
	continue;
      clib_mem_vm_unmap (res->addr);
      if (res->fd != -1)
        close (res->fd);
    }
  /* *INDENT-ON* */
  vec_free (p->regions);

  close (p->fd);
  clib_memset (p, 0, sizeof (linux_pci_device_t));
  pool_put (lpm->linux_pci_devices, p);
}

void
init_device_from_registered (vlib_main_t * vm, vlib_pci_device_info_t * di)
{
  vlib_pci_main_t *pm = &pci_main;
  linux_pci_main_t *lpm = &linux_pci_main;
  pci_device_registration_t *r;
  pci_device_id_t *i;
  clib_error_t *err = 0;
  linux_pci_device_t *p;

  pool_get (lpm->linux_pci_devices, p);
  p->handle = p - lpm->linux_pci_devices;
  p->intx_irq.fd = -1;

  r = pm->pci_device_registrations;

  while (r)
    {
      for (i = r->supported_devices; i->vendor_id != 0; i++)
	if (i->vendor_id == di->vendor_id && i->device_id == di->device_id)
	  {
	    if (di->iommu_group != -1)
	      err = add_device_vfio (vm, p, di, r);
	    else
	      err = add_device_uio (vm, p, di, r);

	    if (err)
	      clib_error_report (err);
	    else
	      return;
	  }
      r = r->next_registration;
    }

  /* No driver, close the PCI config-space FD */
  clib_memset (p, 0, sizeof (linux_pci_device_t));
  pool_put (lpm->linux_pci_devices, p);
}

static clib_error_t *
scan_pci_addr (void *arg, u8 * dev_dir_name, u8 * ignored)
{
  vlib_pci_addr_t addr, **addrv = arg;
  unformat_input_t input;
  clib_error_t *err = 0;

  unformat_init_string (&input, (char *) dev_dir_name,
			vec_len (dev_dir_name));

  if (!unformat (&input, "/sys/bus/pci/devices/%U",
		 unformat_vlib_pci_addr, &addr))
    err = clib_error_return (0, "unformat error `%v`", dev_dir_name);

  unformat_free (&input);

  if (err)
    return err;

  vec_add1 (*addrv, addr);
  return 0;
}

static int
pci_addr_cmp (void *v1, void *v2)
{
  vlib_pci_addr_t *a1 = v1;
  vlib_pci_addr_t *a2 = v2;

  if (a1->domain > a2->domain)
    return 1;
  if (a1->domain < a2->domain)
    return -1;
  if (a1->bus > a2->bus)
    return 1;
  if (a1->bus < a2->bus)
    return -1;
  if (a1->slot > a2->slot)
    return 1;
  if (a1->slot < a2->slot)
    return -1;
  if (a1->function > a2->function)
    return 1;
  if (a1->function < a2->function)
    return -1;
  return 0;
}

vlib_pci_addr_t *
vlib_pci_get_all_dev_addrs ()
{
  vlib_pci_addr_t *addrs = 0;
  clib_error_t *err;
  err = foreach_directory_file ((char *) sysfs_pci_dev_path, scan_pci_addr,
				&addrs, /* scan_dirs */ 0);
  if (err)
    {
      vec_free (addrs);
      return 0;
    }

  vec_sort_with_function (addrs, pci_addr_cmp);

  return addrs;
}

clib_error_t *
linux_pci_init (vlib_main_t * vm)
{
  vlib_pci_main_t *pm = &pci_main;
  vlib_pci_addr_t *addr = 0, *addrs;

  pm->vlib_main = vm;

  ASSERT (sizeof (vlib_pci_addr_t) == sizeof (u32));

  addrs = vlib_pci_get_all_dev_addrs ();
  /* *INDENT-OFF* */
  vec_foreach (addr, addrs)
    {
      vlib_pci_device_info_t *d;
      if ((d = vlib_pci_get_device_info (vm, addr, 0)))
	{
	  init_device_from_registered (vm, d);
	  vlib_pci_free_device_info (d);
	}
    }
  /* *INDENT-ON* */

  return 0;
}

/* *INDENT-OFF* */
VLIB_INIT_FUNCTION (linux_pci_init) =
{
  .runs_after = VLIB_INITS("unix_input_init"),
};
/* *INDENT-ON* */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
