|
Packit |
6639f8 |
// Copyright(c) 2018-2019, Intel Corporation
|
|
Packit |
6639f8 |
//
|
|
Packit |
6639f8 |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
6639f8 |
// modification, are permitted provided that the following conditions are met:
|
|
Packit |
6639f8 |
//
|
|
Packit |
6639f8 |
// * Redistributions of source code must retain the above copyright notice,
|
|
Packit |
6639f8 |
// this list of conditions and the following disclaimer.
|
|
Packit |
6639f8 |
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
Packit |
6639f8 |
// this list of conditions and the following disclaimer in the documentation
|
|
Packit |
6639f8 |
// and/or other materials provided with the distribution.
|
|
Packit |
6639f8 |
// * Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
6639f8 |
// may be used to endorse or promote products derived from this software
|
|
Packit |
6639f8 |
// without specific prior written permission.
|
|
Packit |
6639f8 |
//
|
|
Packit |
6639f8 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
6639f8 |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
6639f8 |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
6639f8 |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
Packit |
6639f8 |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
Packit |
6639f8 |
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
Packit |
6639f8 |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
6639f8 |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
Packit |
6639f8 |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
6639f8 |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
Packit |
6639f8 |
// POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
6639f8 |
#include <config.h>
|
|
Packit |
6639f8 |
#endif // HAVE_CONFIG_H
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#include <inttypes.h>
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#include "opae_events_api.h"
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#ifdef LOG
|
|
Packit |
6639f8 |
#undef LOG
|
|
Packit |
6639f8 |
#endif
|
|
Packit |
6639f8 |
#define LOG(format, ...) \
|
|
Packit |
6639f8 |
log_printf("opae_events_api: " format, ##__VA_ARGS__)
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC pthread_mutex_t list_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
|
Packit |
6639f8 |
STATIC api_client_event_registry *event_registry_list;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
int opae_api_register_event(int conn_socket,
|
|
Packit |
6639f8 |
int fd,
|
|
Packit |
6639f8 |
fpga_event_type e,
|
|
Packit |
6639f8 |
uint64_t object_id)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
api_client_event_registry *r =
|
|
Packit |
6639f8 |
(api_client_event_registry *) malloc(sizeof(*r));
|
|
Packit |
6639f8 |
int err;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!r)
|
|
Packit |
6639f8 |
return ENOMEM;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
r->conn_socket = conn_socket;
|
|
Packit |
6639f8 |
r->fd = fd;
|
|
Packit |
6639f8 |
r->data = 1;
|
|
Packit |
6639f8 |
r->event = e;
|
|
Packit |
6639f8 |
r->object_id = object_id;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_mutex_lock(err, &list_lock);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
r->next = event_registry_list;
|
|
Packit |
6639f8 |
event_registry_list = r;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_mutex_unlock(err, &list_lock);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
return 0;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC void release_event_registry(api_client_event_registry *r)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
close(r->fd);
|
|
Packit |
6639f8 |
free(r);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
int opae_api_unregister_event(int conn_socket,
|
|
Packit |
6639f8 |
fpga_event_type e,
|
|
Packit |
6639f8 |
uint64_t object_id)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
api_client_event_registry *trash;
|
|
Packit |
6639f8 |
api_client_event_registry *save;
|
|
Packit |
6639f8 |
int err;
|
|
Packit |
6639f8 |
int res = 0;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_mutex_lock(err, &list_lock);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
trash = event_registry_list;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!trash) { // empty list
|
|
Packit |
6639f8 |
res = 1;
|
|
Packit |
6639f8 |
goto out_unlock;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if ((conn_socket == trash->conn_socket) &&
|
|
Packit |
6639f8 |
(e == trash->event) &&
|
|
Packit |
6639f8 |
(object_id == trash->object_id)) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// found at head of list
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
event_registry_list = event_registry_list->next;
|
|
Packit |
6639f8 |
release_event_registry(trash);
|
|
Packit |
6639f8 |
goto out_unlock;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
save = trash;
|
|
Packit |
6639f8 |
trash = trash->next;
|
|
Packit |
6639f8 |
while (trash) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if ((conn_socket == trash->conn_socket) &&
|
|
Packit |
6639f8 |
(e == trash->event) &&
|
|
Packit |
6639f8 |
(object_id == trash->object_id))
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
save = trash;
|
|
Packit |
6639f8 |
trash = trash->next;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!trash) { // not found
|
|
Packit |
6639f8 |
res = 1;
|
|
Packit |
6639f8 |
goto out_unlock;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// found at trash
|
|
Packit |
6639f8 |
save->next = trash->next;
|
|
Packit |
6639f8 |
release_event_registry(trash);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
out_unlock:
|
|
Packit |
6639f8 |
fpgad_mutex_unlock(err, &list_lock);
|
|
Packit |
6639f8 |
return res;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC api_client_event_registry *
|
|
Packit |
6639f8 |
find_event_for(int conn_socket)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
api_client_event_registry *r;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (r = event_registry_list ; r ; r = r->next)
|
|
Packit |
6639f8 |
if (conn_socket == r->conn_socket)
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
return r;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
void opae_api_unregister_all_events_for(int conn_socket)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
api_client_event_registry *r;
|
|
Packit |
6639f8 |
int err;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_mutex_lock(err, &list_lock);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
r = find_event_for(conn_socket);
|
|
Packit |
6639f8 |
while (r) {
|
|
Packit |
6639f8 |
opae_api_unregister_event(conn_socket, r->event, r->object_id);
|
|
Packit |
6639f8 |
r = find_event_for(conn_socket);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_mutex_unlock(err, &list_lock);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
void opae_api_unregister_all_events(void)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
api_client_event_registry *r;
|
|
Packit |
6639f8 |
int err;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_mutex_lock(err, &list_lock);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (r = event_registry_list ; r != NULL ; ) {
|
|
Packit |
6639f8 |
api_client_event_registry *trash;
|
|
Packit |
6639f8 |
trash = r;
|
|
Packit |
6639f8 |
r = r->next;
|
|
Packit |
6639f8 |
release_event_registry(trash);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
event_registry_list = NULL;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_mutex_unlock(err, &list_lock);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
void opae_api_for_each_registered_event
|
|
Packit |
6639f8 |
(void (*cb)(api_client_event_registry *r, void *context),
|
|
Packit |
6639f8 |
void *context)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
api_client_event_registry *r;
|
|
Packit |
6639f8 |
int err;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_mutex_lock(err, &list_lock);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (r = event_registry_list; r != NULL; r = r->next) {
|
|
Packit |
6639f8 |
cb(r, context);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_mutex_unlock(err, &list_lock);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC void check_and_send_EVENT_ERROR(api_client_event_registry *r,
|
|
Packit |
6639f8 |
void *context)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
fpgad_monitored_device *d =
|
|
Packit |
6639f8 |
(fpgad_monitored_device *)context;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if ((r->event == FPGA_EVENT_ERROR) &&
|
|
Packit |
6639f8 |
(r->object_id == d->object_id)) {
|
|
Packit |
6639f8 |
LOG("object_id: 0x%" PRIx64 " event: FPGA_EVENT_ERROR\n",
|
|
Packit |
6639f8 |
d->object_id);
|
|
Packit |
6639f8 |
if (write(r->fd, &r->data, sizeof(r->data)) < 0)
|
|
Packit |
6639f8 |
LOG("write failed: %s\n", strerror(errno));
|
|
Packit |
6639f8 |
r->data++;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
void opae_api_send_EVENT_ERROR(fpgad_monitored_device *d)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
opae_api_for_each_registered_event(check_and_send_EVENT_ERROR,
|
|
Packit |
6639f8 |
d);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC void check_and_send_EVENT_POWER_THERMAL(api_client_event_registry *r,
|
|
Packit |
6639f8 |
void *context)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
fpgad_monitored_device *d =
|
|
Packit |
6639f8 |
(fpgad_monitored_device *)context;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if ((r->event == FPGA_EVENT_POWER_THERMAL) &&
|
|
Packit |
6639f8 |
(r->object_id == d->object_id)) {
|
|
Packit |
6639f8 |
LOG("object_id: 0x%" PRIx64 " event: FPGA_EVENT_POWER_THERMAL\n",
|
|
Packit |
6639f8 |
d->object_id);
|
|
Packit |
6639f8 |
if (write(r->fd, &r->data, sizeof(r->data)) < 0)
|
|
Packit |
6639f8 |
LOG("write failed: %s\n", strerror(errno));
|
|
Packit |
6639f8 |
r->data++;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
void opae_api_send_EVENT_POWER_THERMAL(fpgad_monitored_device *d)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
opae_api_for_each_registered_event(check_and_send_EVENT_POWER_THERMAL,
|
|
Packit |
6639f8 |
d);
|
|
Packit |
6639f8 |
}
|