/*
 *	The PCI Library -- Device Filtering
 *
 *	Copyright (c) 1998--2014 Martin Mares <mj@ucw.cz>
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#include <stdlib.h>
#include <string.h>

#include "internal.h"

void pci_filter_init_v33(struct pci_access *a UNUSED, struct pci_filter *f) VERSIONED_ABI;
char *pci_filter_parse_slot_v33(struct pci_filter *f, char *str) VERSIONED_ABI;
char *pci_filter_parse_id_v33(struct pci_filter *f, char *str) VERSIONED_ABI;
int pci_filter_match_v33(struct pci_filter *f, struct pci_dev *d) VERSIONED_ABI;

void
pci_filter_init_v33(struct pci_access *a UNUSED, struct pci_filter *f)
{
  f->domain = f->bus = f->slot = f->func = -1;
  f->vendor = f->device = f->device_class = -1;
}

/* Slot filter syntax: [[[domain]:][bus]:][slot][.[func]] */

char *
pci_filter_parse_slot_v33(struct pci_filter *f, char *str)
{
  char *colon = strrchr(str, ':');
  char *dot = strchr((colon ? colon + 1 : str), '.');
  char *mid = str;
  char *e, *bus, *colon2;

  if (colon)
    {
      *colon++ = 0;
      mid = colon;
      colon2 = strchr(str, ':');
      if (colon2)
	{
	  *colon2++ = 0;
	  bus = colon2;
	  if (str[0] && strcmp(str, "*"))
	    {
	      long int x = strtol(str, &e, 16);
	      if ((e && *e) || (x < 0 || x > 0x7fffffff))
		return "Invalid domain number";
	      f->domain = x;
	    }
	}
      else
	bus = str;
      if (bus[0] && strcmp(bus, "*"))
	{
	  long int x = strtol(bus, &e, 16);
	  if ((e && *e) || (x < 0 || x > 0xff))
	    return "Invalid bus number";
	  f->bus = x;
	}
    }
  if (dot)
    *dot++ = 0;
  if (mid[0] && strcmp(mid, "*"))
    {
      long int x = strtol(mid, &e, 16);
      if ((e && *e) || (x < 0 || x > 0x1f))
	return "Invalid slot number";
      f->slot = x;
    }
  if (dot && dot[0] && strcmp(dot, "*"))
    {
      long int x = strtol(dot, &e, 16);
      if ((e && *e) || (x < 0 || x > 7))
	return "Invalid function number";
      f->func = x;
    }
  return NULL;
}

/* ID filter syntax: [vendor]:[device][:class] */

char *
pci_filter_parse_id_v33(struct pci_filter *f, char *str)
{
  char *s, *c, *e;

  if (!*str)
    return NULL;
  s = strchr(str, ':');
  if (!s)
    return "':' expected";
  *s++ = 0;
  if (str[0] && strcmp(str, "*"))
    {
      long int x = strtol(str, &e, 16);
      if ((e && *e) || (x < 0 || x > 0xffff))
	return "Invalid vendor ID";
      f->vendor = x;
    }
  c = strchr(s, ':');
  if (c)
    *c++ = 0;
  if (s[0] && strcmp(s, "*"))
    {
      long int x = strtol(s, &e, 16);
      if ((e && *e) || (x < 0 || x > 0xffff))
	return "Invalid device ID";
      f->device = x;
    }
  if (c && c[0] && strcmp(s, "*"))
    {
      long int x = strtol(c, &e, 16);
      if ((e && *e) || (x < 0 || x > 0xffff))
	return "Invalid class code";
      f->device_class = x;
    }
  return NULL;
}

int
pci_filter_match_v33(struct pci_filter *f, struct pci_dev *d)
{
  if ((f->domain >= 0 && f->domain != d->domain) ||
      (f->bus >= 0 && f->bus != d->bus) ||
      (f->slot >= 0 && f->slot != d->dev) ||
      (f->func >= 0 && f->func != d->func))
    return 0;
  if (f->device >= 0 || f->vendor >= 0)
    {
      pci_fill_info_v35(d, PCI_FILL_IDENT);
      if ((f->device >= 0 && f->device != d->device_id) ||
	  (f->vendor >= 0 && f->vendor != d->vendor_id))
	return 0;
    }
  if (f->device_class >= 0)
    {
      pci_fill_info(d, PCI_FILL_CLASS);
      if (f->device_class != d->device_class)
	return 0;
    }
  return 1;
}

/*
 * Before pciutils v3.3, struct pci_filter had fewer fields,
 * so we have to provide compatibility wrappers.
 */

struct pci_filter_v30 {
  int domain, bus, slot, func;			/* -1 = ANY */
  int vendor, device;
};

void pci_filter_init_v30(struct pci_access *a, struct pci_filter_v30 *f) VERSIONED_ABI;
char *pci_filter_parse_slot_v30(struct pci_filter_v30 *f, char *str) VERSIONED_ABI;
char *pci_filter_parse_id_v30(struct pci_filter_v30 *f, char *str) VERSIONED_ABI;
int pci_filter_match_v30(struct pci_filter_v30 *f, struct pci_dev *d) VERSIONED_ABI;

static void
pci_filter_import_v30(struct pci_filter_v30 *old, struct pci_filter *new)
{
  new->domain = old->domain;
  new->bus = old->bus;
  new->slot = old->slot;
  new->func = old->func;
  new->vendor = old->vendor;
  new->device = old->device;
  new->device_class = -1;
}

static void
pci_filter_export_v30(struct pci_filter *new, struct pci_filter_v30 *old)
{
  old->domain = new->domain;
  old->bus = new->bus;
  old->slot = new->slot;
  old->func = new->func;
  old->vendor = new->vendor;
  old->device = new->device;
}

void
pci_filter_init_v30(struct pci_access *a, struct pci_filter_v30 *f)
{
  struct pci_filter new;
  pci_filter_init_v33(a, &new);
  pci_filter_export_v30(&new, f);
}

char *
pci_filter_parse_slot_v30(struct pci_filter_v30 *f, char *str)
{
  struct pci_filter new;
  char *err;
  pci_filter_import_v30(f, &new);
  if (err = pci_filter_parse_slot_v33(&new, str))
    return err;
  pci_filter_export_v30(&new, f);
  return NULL;
}

char *
pci_filter_parse_id_v30(struct pci_filter_v30 *f, char *str)
{
  struct pci_filter new;
  char *err;
  pci_filter_import_v30(f, &new);
  if (err = pci_filter_parse_id_v33(&new, str))
    return err;
  if (new.device_class >= 0)
    return "Filtering by class not supported in this program";
  pci_filter_export_v30(&new, f);
  return NULL;
}

int
pci_filter_match_v30(struct pci_filter_v30 *f, struct pci_dev *d)
{
  struct pci_filter new;
  pci_filter_import_v30(f, &new);
  return pci_filter_match_v33(&new, d);
}

STATIC_ALIAS(void pci_filter_init(struct pci_access *a, struct pci_filter *f), pci_filter_init_v33(a, f));
SYMBOL_VERSION(pci_filter_init_v30, pci_filter_init@LIBPCI_3.0);
SYMBOL_VERSION(pci_filter_init_v33, pci_filter_init@@LIBPCI_3.3);

STATIC_ALIAS(char *pci_filter_parse_slot(struct pci_filter *f, char *str), pci_filter_parse_slot_v33(f, str));
SYMBOL_VERSION(pci_filter_parse_slot_v30, pci_filter_parse_slot@LIBPCI_3.0);
SYMBOL_VERSION(pci_filter_parse_slot_v33, pci_filter_parse_slot@@LIBPCI_3.3);

STATIC_ALIAS(char *pci_filter_parse_id(struct pci_filter *f, char *str), pci_filter_parse_id_v33(f, str));
SYMBOL_VERSION(pci_filter_parse_id_v30, pci_filter_parse_id@LIBPCI_3.0);
SYMBOL_VERSION(pci_filter_parse_id_v33, pci_filter_parse_id@@LIBPCI_3.3);

STATIC_ALIAS(int pci_filter_match(struct pci_filter *f, struct pci_dev *d), pci_filter_match_v33(f, d));
SYMBOL_VERSION(pci_filter_match_v30, pci_filter_match@LIBPCI_3.0);
SYMBOL_VERSION(pci_filter_match_v33, pci_filter_match@@LIBPCI_3.3);
