// Copyright(c) 2018-2020, 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. #ifdef HAVE_CONFIG_H #include #endif /* HAVE_CONFIG_H */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif // _GNU_SOURCE #include #include #include #include #include "props.h" struct _fpga_properties *opae_properties_create(void) { struct _fpga_properties *props; pthread_mutexattr_t mattr; int err; props = (struct _fpga_properties *)calloc( 1, sizeof(struct _fpga_properties)); if (!props) return NULL; props->magic = FPGA_PROPERTY_MAGIC; if (pthread_mutexattr_init(&mattr)) { OPAE_ERR("pthread_mutexattr_init() failed"); goto out_free; } if (pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE)) { OPAE_ERR("pthread_mutexattr_settype() failed"); goto out_destroy_attr; } if (pthread_mutex_init(&props->lock, &mattr)) { OPAE_ERR("pthread_mutex_init() failed"); goto out_destroy_attr; } pthread_mutexattr_destroy(&mattr); return props; out_destroy_attr: err = pthread_mutexattr_destroy(&mattr); if (err) OPAE_ERR("pthread_mutexattr_destroy() failed: %s", strerror(err)); out_free: free(props); return NULL; } fpga_result __OPAE_API__ fpgaDestroyProperties(fpga_properties *prop) { struct _fpga_properties *p; int err; ASSERT_NOT_NULL(prop); p = opae_validate_and_lock_properties(*prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_PARENT) && (p->flags & OPAE_PROPERTIES_FLAG_PARENT_ALLOC)) { // The parent token has a wrapper that we allocated. // Free it. opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(p->parent); if (wrapped_token) opae_destroy_wrapped_token(wrapped_token); } p->magic = 0; opae_mutex_unlock(err, &p->lock); err = pthread_mutex_destroy(&p->lock); if (err) OPAE_ERR("pthread_mutex_destroy() failed: %s", strerror(err)); free(p); *prop = NULL; return FPGA_OK; } fpga_result __OPAE_API__ fpgaCloneProperties(fpga_properties src, fpga_properties *dst) { int err; struct _fpga_properties *clone; pthread_mutex_t save_lock; struct _fpga_properties *p; ASSERT_NOT_NULL(dst); p = opae_validate_and_lock_properties(src); ASSERT_NOT_NULL(p); clone = opae_properties_create(); if (!clone) { opae_mutex_unlock(err, &p->lock); return FPGA_EXCEPTION; } save_lock = clone->lock; *clone = *p; clone->lock = save_lock; *dst = clone; opae_mutex_unlock(err, &p->lock); return FPGA_OK; } fpga_result __OPAE_API__ fpgaClearProperties(fpga_properties props) { int err; struct _fpga_properties *p = opae_validate_and_lock_properties(props); ASSERT_NOT_NULL(p); p->valid_fields = 0; opae_mutex_unlock(err, &p->lock); return FPGA_OK; } fpga_result __OPAE_API__ fpgaPropertiesGetParent(const fpga_properties prop, fpga_token *parent) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(parent); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_PARENT)) { res = fpgaCloneToken(p->parent, parent); if (res != FPGA_OK) OPAE_ERR("cloning token from property"); } else { OPAE_MSG("No parent"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetParent(fpga_properties prop, fpga_token parent) { int err; struct _fpga_properties *p; ASSERT_NOT_NULL(parent); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_PARENT) && (p->flags & OPAE_PROPERTIES_FLAG_PARENT_ALLOC)) { // We have a wrapped parent token that we allocated. // Free it. opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(p->parent); if (wrapped_token) opae_destroy_wrapped_token(wrapped_token); } // When explicitly setting a parent token, // the caller assumes responsibility for freeing // that token. p->flags &= ~OPAE_PROPERTIES_FLAG_PARENT_ALLOC; p->parent = parent; SET_FIELD_VALID(p, FPGA_PROPERTY_PARENT); opae_mutex_unlock(err, &p->lock); return FPGA_OK; } fpga_result __OPAE_API__ fpgaPropertiesGetObjectType( const fpga_properties prop, fpga_objtype *objtype) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(objtype); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE)) { *objtype = p->objtype; } else { OPAE_MSG("No object type"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetObjectType(fpga_properties prop, fpga_objtype objtype) { int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); p->objtype = objtype; SET_FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE); opae_mutex_unlock(err, &p->lock); return FPGA_OK; } fpga_result __OPAE_API__ fpgaPropertiesGetSegment(const fpga_properties prop, uint16_t *segment) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(segment); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_SEGMENT)) { *segment = p->segment; } else { OPAE_MSG("No segment"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetSegment(fpga_properties prop, uint16_t segment) { int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_SEGMENT); p->segment = segment; opae_mutex_unlock(err, &p->lock); return FPGA_OK; } fpga_result __OPAE_API__ fpgaPropertiesGetBus(const fpga_properties prop, uint8_t *bus) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(bus); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_BUS)) { *bus = p->bus; } else { OPAE_MSG("No bus"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetBus(fpga_properties prop, uint8_t bus) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_BUS); p->bus = bus; opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetDevice(const fpga_properties prop, uint8_t *device) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(device); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_DEVICE)) { *device = p->device; } else { OPAE_MSG("No device"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetDevice(fpga_properties prop, uint8_t device) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_DEVICE); p->device = device; opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetFunction(const fpga_properties prop, uint8_t *function) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(function); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_FUNCTION)) { *function = p->function; } else { OPAE_MSG("No function"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetFunction(fpga_properties prop, uint8_t function) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; // PCIe supports 8 functions per device. if (function > 7) { OPAE_MSG("Invalid function number"); return FPGA_INVALID_PARAM; } p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_FUNCTION); p->function = function; opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetSocketID(const fpga_properties prop, uint8_t *socket_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(socket_id); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_SOCKETID)) { *socket_id = p->socket_id; } else { OPAE_MSG("No socket ID"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetSocketID(fpga_properties prop, uint8_t socket_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_SOCKETID); p->socket_id = socket_id; opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetDeviceID(const fpga_properties prop, uint16_t *device_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(device_id); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_DEVICEID)) { *device_id = p->device_id; } else { OPAE_MSG("No device ID"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetDeviceID(fpga_properties prop, uint16_t device_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_DEVICEID); p->device_id = device_id; opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetNumSlots(const fpga_properties prop, uint32_t *num_slots) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(num_slots); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_DEVICE == p->objtype) { if (FIELD_VALID(p, FPGA_PROPERTY_NUM_SLOTS)) { *num_slots = p->u.fpga.num_slots; } else { OPAE_MSG("No number of slots"); res = FPGA_NOT_FOUND; } } else { OPAE_ERR( "Attempting to get num_slots from invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetNumSlots(fpga_properties prop, uint32_t num_slots) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_DEVICE == p->objtype) { SET_FIELD_VALID(p, FPGA_PROPERTY_NUM_SLOTS); p->u.fpga.num_slots = num_slots; } else { OPAE_ERR( "Attempting to set num slots on invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetBBSID(const fpga_properties prop, uint64_t *bbs_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(bbs_id); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_DEVICE == p->objtype) { if (FIELD_VALID(p, FPGA_PROPERTY_BBSID)) { *bbs_id = p->u.fpga.bbs_id; } else { OPAE_MSG("No BBS ID"); res = FPGA_NOT_FOUND; } } else { OPAE_ERR( "Attempting to get BBS ID from invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetBBSID(fpga_properties prop, uint64_t bbs_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_DEVICE == p->objtype) { SET_FIELD_VALID(p, FPGA_PROPERTY_BBSID); p->u.fpga.bbs_id = bbs_id; } else { OPAE_ERR("Attempting to set BBS ID on invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetBBSVersion(const fpga_properties prop, fpga_version *bbs_version) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(bbs_version); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_DEVICE == p->objtype) { if (FIELD_VALID(p, FPGA_PROPERTY_BBSVERSION)) { *bbs_version = p->u.fpga.bbs_version; } else { OPAE_MSG("No BBS version"); res = FPGA_NOT_FOUND; } } else { OPAE_ERR( "Attempting to get BBS version from invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetBBSVersion(fpga_properties prop, fpga_version bbs_version) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_DEVICE == p->objtype) { SET_FIELD_VALID(p, FPGA_PROPERTY_BBSVERSION); p->u.fpga.bbs_version = bbs_version; } else { OPAE_ERR( "Attempting to set BBS version on invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetVendorID(const fpga_properties prop, uint16_t *vendor_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(vendor_id); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_VENDORID)) { *vendor_id = p->vendor_id; } else { OPAE_MSG("No vendor ID"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetVendorID(fpga_properties prop, uint16_t vendor_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_VENDORID); p->vendor_id = vendor_id; opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetModel(const fpga_properties prop, char *model) { UNUSED_PARAM(prop); UNUSED_PARAM(model); OPAE_MSG("Model not supported"); return FPGA_NOT_SUPPORTED; } fpga_result __OPAE_API__ fpgaPropertiesSetModel(fpga_properties prop, char *model) { UNUSED_PARAM(prop); UNUSED_PARAM(model); OPAE_MSG("Model not supported"); return FPGA_NOT_SUPPORTED; } fpga_result __OPAE_API__ fpgaPropertiesGetLocalMemorySize( const fpga_properties prop, uint64_t *local_memory_size) { UNUSED_PARAM(prop); UNUSED_PARAM(local_memory_size); OPAE_MSG("Local memory not supported"); return FPGA_NOT_SUPPORTED; } fpga_result __OPAE_API__ fpgaPropertiesSetLocalMemorySize(fpga_properties prop, uint64_t local_memory_size) { UNUSED_PARAM(prop); UNUSED_PARAM(local_memory_size); OPAE_MSG("Local memory not supported"); return FPGA_NOT_SUPPORTED; } fpga_result __OPAE_API__ fpgaPropertiesGetCapabilities( const fpga_properties prop, uint64_t *capabilities) { UNUSED_PARAM(prop); UNUSED_PARAM(capabilities); OPAE_MSG("Capabilities not supported"); return FPGA_NOT_SUPPORTED; } fpga_result __OPAE_API__ fpgaPropertiesSetCapabilities(fpga_properties prop, uint64_t capabilities) { UNUSED_PARAM(prop); UNUSED_PARAM(capabilities); OPAE_MSG("Capabilities not supported"); return FPGA_NOT_SUPPORTED; } fpga_result __OPAE_API__ fpgaPropertiesGetGUID(const fpga_properties prop, fpga_guid *guid) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(guid); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_GUID)) { memcpy(*guid, p->guid, sizeof(fpga_guid)); } else { OPAE_MSG("No GUID"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetGUID(fpga_properties prop, fpga_guid guid) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_GUID); memcpy(p->guid, guid, sizeof(fpga_guid)); opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetNumMMIO(const fpga_properties prop, uint32_t *mmio_spaces) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(mmio_spaces); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_ACCELERATOR == p->objtype) { if (FIELD_VALID(p, FPGA_PROPERTY_NUM_MMIO)) { *mmio_spaces = p->u.accelerator.num_mmio; } else { OPAE_MSG("No MMIO spaces"); res = FPGA_NOT_FOUND; } } else { OPAE_ERR( "Attempting to get number of MMIO spaces from invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetNumMMIO(fpga_properties prop, uint32_t mmio_spaces) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_ACCELERATOR == p->objtype) { SET_FIELD_VALID(p, FPGA_PROPERTY_NUM_MMIO); p->u.accelerator.num_mmio = mmio_spaces; } else { OPAE_ERR( "Attempting to set number of MMIO spaces on invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetNumInterrupts( const fpga_properties prop, uint32_t *num_interrupts) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(num_interrupts); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_ACCELERATOR == p->objtype) { if (FIELD_VALID(p, FPGA_PROPERTY_NUM_INTERRUPTS)) { *num_interrupts = p->u.accelerator.num_interrupts; } else { OPAE_MSG("No interrupts"); res = FPGA_NOT_FOUND; } } else { OPAE_ERR( "Attempting to get number of interrupts from invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetNumInterrupts(fpga_properties prop, uint32_t num_interrupts) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_ACCELERATOR == p->objtype) { SET_FIELD_VALID(p, FPGA_PROPERTY_NUM_INTERRUPTS); p->u.accelerator.num_interrupts = num_interrupts; } else { OPAE_ERR( "Attempting to set number of interrupts on invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetAcceleratorState( const fpga_properties prop, fpga_accelerator_state *state) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(state); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_ACCELERATOR == p->objtype) { if (FIELD_VALID(p, FPGA_PROPERTY_ACCELERATOR_STATE)) { *state = p->u.accelerator.state; } else { OPAE_MSG("No accelerator state"); res = FPGA_NOT_FOUND; } } else { OPAE_ERR("Attempting to get state from invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetAcceleratorState( fpga_properties prop, fpga_accelerator_state state) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJTYPE) && FPGA_ACCELERATOR == p->objtype) { SET_FIELD_VALID(p, FPGA_PROPERTY_ACCELERATOR_STATE); p->u.accelerator.state = state; } else { OPAE_ERR("Attempting to set state from invalid object type: %d", p->objtype); res = FPGA_INVALID_PARAM; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetObjectID(const fpga_properties prop, uint64_t *object_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(object_id); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_OBJECTID)) { *object_id = p->object_id; } else { OPAE_MSG("No object ID"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetObjectID(fpga_properties prop, uint64_t object_id) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_OBJECTID); p->object_id = object_id; opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesGetNumErrors(const fpga_properties prop, uint32_t *num_errors) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p; ASSERT_NOT_NULL(num_errors); p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_NUM_ERRORS)) { *num_errors = p->num_errors; } else { OPAE_MSG("No num errors"); res = FPGA_NOT_FOUND; } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaPropertiesSetNumErrors(const fpga_properties prop, uint32_t num_errors) { fpga_result res = FPGA_OK; int err; struct _fpga_properties *p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); SET_FIELD_VALID(p, FPGA_PROPERTY_NUM_ERRORS); p->num_errors = num_errors; opae_mutex_unlock(err, &p->lock); return res; }