// Copyright(c) 2017, Intel Corporation
//
// 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 Intel Corporation  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.

/**
 * @file enum.h
 * @brief APIs for resource enumeration and managing tokens
 *
 * These APIs are the first step for any application using OPAE to discover
 * resources that are present on the system. They allow selective enumeration
 * (i.e. getting a list of resources that match a given list of criteria) and
 * methods to manage the lifecycle of tokens generated by fpgaEnumerate().
 */

#ifndef __FPGA_ENUM_H__
#define __FPGA_ENUM_H__

#include <opae/types.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Enumerate FPGA resources present in the system
 *
 * This call allows the user to query the system for FPGA resources that match
 * a certain set of criteria, e.g. all accelerators that are assigned to a host
 * interface and available, all FPGAs of a specific type, etc.
 *
 * fpgaEnumerate() will create a number of `fpga_token`s to represent the
 * matching resources and populate the array `tokens` with these tokens. The
 * `max_tokens` argument can be used to limit the number of tokens
 * allocated/returned by fpgaEnumerate(); i.e., the number of tokens in the
 * returned `tokens` array will be either `max_tokens` or `num_matches` (the
 * number of resources matching the filter), whichever is smaller. Use
 * fpgaDestroyToken() to destroy tokens that are no longer needed.
 *
 * To query the number of matches for a particular set of filters (e.g. to
 * allocate a `tokens` array of the appropriate size), call fpgaEnumerate()
 * with the parameter `tokens` set to NULL; this will only return the number of
 * matches in `num_matches`.
 *
 * @note fpgaEnumerate() will allocate memory for the created tokens returned
 * in `tokens`. It is the responsibility of the using application to free this
 * memory after use by calling fpgaDestroyToken() for each of the returned
 * tokens.
 *
 * @param[in] filters      Array of `fpga_properties` objects describing the
 *                         properties of the objects that should be returned. A
 *                         resource is considered matching if its properties
 *                         match any one of the supplied filters. To match all
 *                         FPGA resources, pass an empty filters object (one
 *                         without any filter criteria set) or pass a NULL
 *                         filters parameter with num_filters set to 0.
 * @param[in] num_filters  Number of entries in the `filters` array, or 0 to
 *                         match all FPGA resources when `filters` is NULL.
 * @param[out] tokens      Pointer to an array of fpga_token variables to be
 *                         populated.  If NULL is supplied, fpgaEnumerate() will
 *                         not create any tokens, but it will return the
 *                         number of possible matches in `num_match`.
 * @param[in] max_tokens   Maximum number of tokens that fpgaEnumerate() shall
 *                         return (length of `tokens` array). There may be more
 *                         or fewer matches than this number; `num_matches` is
 *                         set to the number of actual matches.
 * @param[out] num_matches Number of resources matching the `filter` criteria.
 *                         This number can be higher than the number of tokens
 *                         returned in the `tokens` array (depending on the
 *                         value of `max_tokens`).
 * @returns                FPGA_OK on success.
 *                         FPGA_INVALID_PARAM if invalid pointers or objects
 *                         are passed into the function.
 *                         FPGA_NO_DRIVER if OPAE can't find the respective
 *                         enumeration data structures usually provided by the
 *                         driver.
 *                         FPGA_NO_MEMORY if there was not enough memory to
 *                         create tokens.
 */
fpga_result fpgaEnumerate(const fpga_properties *filters,
			  uint32_t num_filters, fpga_token *tokens,
			  uint32_t max_tokens, uint32_t *num_matches);

/**
 * Clone a fpga_token object
 *
 * Creates a copy of an fpga_token object.
 *
 * @note This call creates a new token object and allocates memory for it. It
 * is the responsibility of the using application to free this memory after use
 * by calling fpgaDestroyToken() for the cloned token.
 *
 * @param[in]  src        fpga_token object to copy
 * @param[out] dst        New fpga_token object cloned from 'src'
 * @returns               FPGA_OK on success
 */
fpga_result fpgaCloneToken(fpga_token src, fpga_token *dst);

/**
 * Destroy a Token
 *
 * This function destroys a token created by fpgaEnumerate() and frees the
 * associated memory.
 *
 * @note fpgaDestroyToken() requires the address of an fpga_token as
 * previously created by fpgaEnumerate() or fpgaCloneToken(). Passing
 * any other value results in undefined behavior.
 *
 * @param[in] token      fpga_token to destroy
 * @returns              FPGA_OK on success
 */
fpga_result fpgaDestroyToken(fpga_token *token);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

#endif // __FPGA_ENUM_H__

