diff --git a/Module.mk b/Module.mk index eb6f897..4522190 100644 --- a/Module.mk +++ b/Module.mk @@ -78,6 +78,7 @@ imps += avs avs-ea3 include src/main/aciodrv/Module.mk include src/main/acioemu/Module.mk +include src/main/aciomgr/Module.mk include src/main/aciotest/Module.mk include src/main/asio/Module.mk include src/main/bio2drv/Module.mk @@ -378,6 +379,7 @@ $(zipdir)/iidx-27.zip: \ $(V)zip -j $@ $^ $(zipdir)/iidx-hwio-x86.zip: \ + build/bin/indep-32/aciomgr.dll \ build/bin/indep-32/eamio-icca.dll \ build/bin/indep-32/iidxio-bio2.dll \ build/bin/indep-32/iidxio-ezusb.dll \ @@ -390,6 +392,7 @@ $(zipdir)/iidx-hwio-x86.zip: \ $(V)zip -j $@ $^ $(zipdir)/iidx-hwio-x64.zip: \ + build/bin/indep-64/aciomgr.dll \ build/bin/indep-64/eamio-icca.dll \ build/bin/indep-64/iidxio-bio2.dll \ build/bin/indep-64/iidxio-ezusb.dll \ @@ -483,6 +486,8 @@ $(zipdir)/sdvx-05-cn.zip: \ $(V)zip -j $@ $^ $(zipdir)/sdvx-hwio-x86.zip: \ + build/bin/indep-32/aciomgr.dll \ + build/bin/indep-32/eamio-icca.dll \ build/bin/indep-32/sdvxio-kfca.dll \ build/bin/indep-32/sdvxio-bio2.dll \ build/bin/indep-32/vigem-sdvxio.exe \ @@ -491,6 +496,8 @@ $(zipdir)/sdvx-hwio-x86.zip: \ $(V)zip -j $@ $^ $(zipdir)/sdvx-hwio-x64.zip: \ + build/bin/indep-64/aciomgr.dll \ + build/bin/indep-64/eamio-icca.dll \ build/bin/indep-64/sdvxio-kfca.dll \ build/bin/indep-64/sdvxio-bio2.dll \ build/bin/indep-64/vigem-sdvxio.exe \ diff --git a/src/main/aciodrv/device.c b/src/main/aciodrv/device.c index 686e98f..650131b 100644 --- a/src/main/aciodrv/device.c +++ b/src/main/aciodrv/device.c @@ -291,7 +291,13 @@ static bool aciodrv_device_start_node(struct aciodrv_device_ctx *device, uint8_t return true; } +// deprecated name struct aciodrv_device_ctx *aciodrv_device_open(const char *port_path, int baud) +{ + return aciodrv_device_open_path(port_path, baud); +} + +struct aciodrv_device_ctx *aciodrv_device_open_path(const char *port_path, int baud) { HANDLE port = aciodrv_port_open(port_path, baud); diff --git a/src/main/aciodrv/device.h b/src/main/aciodrv/device.h index 4e7adb3..ba48b26 100644 --- a/src/main/aciodrv/device.h +++ b/src/main/aciodrv/device.h @@ -18,7 +18,13 @@ struct aciodrv_device_ctx; * @param baud Baud rate for communication (e.g. 57600 for ICCA) * @return opened device context, NULL on error */ -struct aciodrv_device_ctx *aciodrv_device_open(const char *port_path, int baud); +struct aciodrv_device_ctx *aciodrv_device_open(const char *port_path, int baud) +#ifdef __GNUC__ +__attribute__((deprecated("Use aciomgr instead if device is shareable, else aciodrv_device_open_path"))) +#endif +; + +struct aciodrv_device_ctx *aciodrv_device_open_path(const char *port_path, int baud); /** * Get the node count on the opened device. diff --git a/src/main/aciomgr/Module.mk b/src/main/aciomgr/Module.mk new file mode 100644 index 0000000..5bc35f8 --- /dev/null +++ b/src/main/aciomgr/Module.mk @@ -0,0 +1,8 @@ +dlls += aciomgr + +libs_aciomgr := \ + aciodrv \ + util \ + +src_aciomgr := \ + manager.c \ diff --git a/src/main/aciomgr/aciomgr.def b/src/main/aciomgr/aciomgr.def new file mode 100644 index 0000000..06bc21f --- /dev/null +++ b/src/main/aciomgr/aciomgr.def @@ -0,0 +1,12 @@ +LIBRARY aciomgr + +EXPORTS + aciomgr_set_loggers + aciomgr_port_init + aciomgr_port_fini + aciomgr_get_node_count + aciomgr_get_node_product_ident + aciomgr_port_submit_packet + aciomgr_port_checkout + aciomgr_port_checkin + DllMain@12 @1 NONAME diff --git a/src/main/aciomgr/manager.c b/src/main/aciomgr/manager.c new file mode 100644 index 0000000..3cc022a --- /dev/null +++ b/src/main/aciomgr/manager.c @@ -0,0 +1,201 @@ +#define LOG_MODULE "aciomgr-manager" + +#include + +#include + +#include "manager.h" + +#include "aciodrv/device.h" +#include "util/array.h" +#include "util/log.h" + +#define MAX_PORT_PATH_LENGTH 256 + +struct aciomgr_port_dispatcher { + CRITICAL_SECTION cs; + size_t references; + struct aciodrv_device_ctx *device; + char path[MAX_PORT_PATH_LENGTH]; + int baud; +}; + +static void _aciomgr_setup_port_dispatcher( + struct aciomgr_port_dispatcher *dispatcher, const char *path, int baud); +static void _aciomgr_destroy_port_dispatcher( + struct aciomgr_port_dispatcher *dispatcher); +static void _aciomgr_init(); +static void _aciomgr_fini(); + +// DLL-globals +static atomic_bool running; +static CRITICAL_SECTION mgr_cs; +static struct array active_ports; + +static void _aciomgr_setup_port_dispatcher( + struct aciomgr_port_dispatcher *dispatcher, const char *path, int baud) +{ + InitializeCriticalSection(&dispatcher->cs); + + strcpy(dispatcher->path, path); + dispatcher->baud = baud; + + dispatcher->device = aciodrv_device_open_path(path, baud); + dispatcher->references = 0; +} + +static void _aciomgr_destroy_port_dispatcher( + struct aciomgr_port_dispatcher *dispatcher) +{ + aciodrv_device_close(dispatcher->device); + DeleteCriticalSection(&dispatcher->cs); +} + +static void _aciomgr_init() +{ + if (running) { + // warn + _aciomgr_fini(); + } + InitializeCriticalSection(&mgr_cs); + array_init(&active_ports); + + running = true; +} + +static void _aciomgr_fini() +{ + if (!running) { + // warn + } + running = false; + DeleteCriticalSection(&mgr_cs); + array_fini(&active_ports); +} + +void aciomgr_set_loggers( + log_formatter_t misc, + log_formatter_t info, + log_formatter_t warning, + log_formatter_t fatal) +{ + log_to_external(misc, info, warning, fatal); +} + +struct aciomgr_port_dispatcher *aciomgr_port_init(const char *path, int baud) +{ + if (!running) { + // warn + return NULL; + } + + if (strlen(path) >= MAX_PORT_PATH_LENGTH) { + // warn + return NULL; + } + + + struct aciomgr_port_dispatcher* entry; + + EnterCriticalSection(&mgr_cs); + + for (size_t i = 0; i < active_ports.nitems; i++) { + entry = array_item(struct aciomgr_port_dispatcher, &active_ports, i); + + if (strcmp(entry->path, path) == 0) { + // found + if (entry->baud != baud) { + log_warning( + "Device at %s opened with baud of %d, but requested %d", + path, + entry->baud, + baud); + } + goto done; + } + } + + entry = array_append(struct aciomgr_port_dispatcher, &active_ports); + _aciomgr_setup_port_dispatcher(entry, path, baud); + +done: + entry->references++; + LeaveCriticalSection(&mgr_cs); + + return entry; +} + +void aciomgr_port_fini(struct aciomgr_port_dispatcher *dispatcher) +{ + if (!running) { + // warn + return; + } + + EnterCriticalSection(&mgr_cs); + dispatcher->references--; + LeaveCriticalSection(&mgr_cs); + + if (dispatcher->references == 0) { + _aciomgr_destroy_port_dispatcher(dispatcher); + } +} + +// this function don't require the lock +uint8_t aciomgr_get_node_count(struct aciomgr_port_dispatcher *dispatcher) { + return aciodrv_device_get_node_count(dispatcher->device); +} + +// this function don't require the lock +bool aciomgr_get_node_product_ident( + struct aciomgr_port_dispatcher *dispatcher, + uint8_t node_id, + char product[4]) +{ + return aciodrv_device_get_node_product_ident(dispatcher->device, node_id, product); +} + +bool aciomgr_port_submit_packet( + struct aciomgr_port_dispatcher *dispatcher, + struct ac_io_message *msg, + int max_resp_size) +{ + // CS's although lightweight, may still be a burden, short circuit + if (dispatcher->references > 1) { + EnterCriticalSection(&dispatcher->cs); + bool response = aciodrv_send_and_recv(dispatcher->device, msg, max_resp_size); + LeaveCriticalSection(&dispatcher->cs); + return response; + } + + return aciodrv_send_and_recv(dispatcher->device, msg, max_resp_size); +} + +struct aciodrv_device_ctx *aciomgr_port_checkout( + struct aciomgr_port_dispatcher *dispatcher) +{ + if (dispatcher->references > 1) { + EnterCriticalSection(&dispatcher->cs); + } + + return dispatcher->device; +} + +void aciomgr_port_checkin(struct aciomgr_port_dispatcher *dispatcher) { + if (dispatcher->references > 1) { + LeaveCriticalSection(&dispatcher->cs); + } +} + +BOOL WINAPI DllMain(HMODULE self, DWORD reason, void *ctx) +{ + if (reason == DLL_PROCESS_ATTACH) { + _aciomgr_init(); + } + + if (reason == DLL_PROCESS_DETACH) { + _aciomgr_fini(); + } + + return TRUE; +} diff --git a/src/main/aciomgr/manager.h b/src/main/aciomgr/manager.h new file mode 100644 index 0000000..00f52ce --- /dev/null +++ b/src/main/aciomgr/manager.h @@ -0,0 +1,82 @@ +#ifndef ACIOMGR_MANAGER_H +#define ACIOMGR_MANAGER_H + +#include + +#include "acio/acio.h" + +#include "bemanitools/glue.h" + +struct aciodrv_device_ctx; +struct aciomgr_port_dispatcher; + +/** + * The first function that will be called on your DLL. You will be supplied + * with four function pointers that may be used to log messages to the game's + * log file. See comments in glue.h for further information. + */ +void aciomgr_set_loggers( + log_formatter_t misc, + log_formatter_t info, + log_formatter_t warning, + log_formatter_t fatal); + +/** + * Init and open, or return the existing handle to an acio port + * + * @param path Port the device is connected to (e.g. "COM1") + * @return opened port dispatcher context, NULL on error + */ +struct aciomgr_port_dispatcher *aciomgr_port_init(const char *path, int baud); + +void aciomgr_port_fini(struct aciomgr_port_dispatcher *dispatcher); + +/** + * Get the node count on the opened device. + * + * @param dispatcher dispatcher context from aciomgr_port_init + * @return Total num of nodes enumerated on the ACIO device. + */ +uint8_t aciomgr_get_node_count(struct aciomgr_port_dispatcher *dispatcher); + +/** + * Get the product identifier of an enumerated node. + * + * @param dispatcher dispatcher context from aciomgr_port_init + * @param node_id Id of the node. Needs to be in range of the total node count. + * @param product Buffer to return the product id to. + * @return True on success, false on error. If True the variable product + * contains the identifier of the queried node. + */ +bool aciomgr_get_node_product_ident(struct aciomgr_port_dispatcher *dispatcher, uint8_t node_id, char product[4]); + +/** + * Submit and wait for the response of the specified packet + * + * @param dispatcher dispatcher context from aciomgr_port_init + * @param msg pointer to the message buffer to read from / write to + * @param max_resp_size pointer to the max size response we expect + * @return false on error + */ +bool aciomgr_port_submit_packet( + struct aciomgr_port_dispatcher *dispatcher, + struct ac_io_message *msg, + int max_resp_size); + +/** + * Checkout the device handler for this port dispatcher on this thread + * + * @param dispatcher dispatcher context from aciomgr_port_init + * @return the device context + */ +struct aciodrv_device_ctx *aciomgr_port_checkout( + struct aciomgr_port_dispatcher *dispatcher); + +/** + * Checkin the device handler that this thread holds + * + * @param dispatcher dispatcher context from aciomgr_port_init + */ +void aciomgr_port_checkin(struct aciomgr_port_dispatcher *dispatcher); + +#endif \ No newline at end of file diff --git a/src/main/aciotest/main.c b/src/main/aciotest/main.c index 9ed271f..010f6f3 100644 --- a/src/main/aciotest/main.c +++ b/src/main/aciotest/main.c @@ -71,7 +71,7 @@ int main(int argc, char **argv) log_to_writer(log_writer_stdout, NULL); - struct aciodrv_device_ctx *device = aciodrv_device_open(argv[1], atoi(argv[2])); + struct aciodrv_device_ctx *device = aciodrv_device_open_path(argv[1], atoi(argv[2])); if (!device) { printf("Opening acio device failed\n"); diff --git a/src/main/bio2drv/bi2a-iidx.c b/src/main/bio2drv/bi2a-iidx.c index 29713a0..839a16d 100644 --- a/src/main/bio2drv/bi2a-iidx.c +++ b/src/main/bio2drv/bi2a-iidx.c @@ -110,7 +110,7 @@ bool bio2drv_bi2a_iidx_poll( device, &msg, offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) { - log_warning("[%x] Polling of node %d failed", node_id + 1); + log_warning("Polling of node %d failed", node_id + 1); return false; } diff --git a/src/main/eamio-icca/Module.mk b/src/main/eamio-icca/Module.mk index 1199b2a..3403aa7 100644 --- a/src/main/eamio-icca/Module.mk +++ b/src/main/eamio-icca/Module.mk @@ -3,6 +3,7 @@ dlls += \ libs_eamio-icca := \ aciodrv \ + aciomgr \ util \ src_eamio-icca := \ diff --git a/src/main/eamio-icca/eamio-icca.c b/src/main/eamio-icca/eamio-icca.c index d14a216..0c073f1 100644 --- a/src/main/eamio-icca/eamio-icca.c +++ b/src/main/eamio-icca/eamio-icca.c @@ -8,13 +8,15 @@ #include #include -#include "aciodrv/device.h" +#include "aciomgr/manager.h" #include "aciodrv/icca.h" #include "bemanitools/eamio.h" #include "util/log.h" +#define NUMBER_OF_EMULATED_READERS 2 + static const uint8_t eam_io_keypad_mappings[16] = {EAM_IO_KEYPAD_DECIMAL, EAM_IO_KEYPAD_3, EAM_IO_KEYPAD_6, @@ -32,9 +34,11 @@ static const uint8_t eam_io_keypad_mappings[16] = {EAM_IO_KEYPAD_DECIMAL, EAM_IO_KEYPAD_5, EAM_IO_KEYPAD_8}; -static struct ac_io_icca_state eam_io_icca_state[2]; +static struct ac_io_icca_state eam_io_icca_state[NUMBER_OF_EMULATED_READERS]; -static struct aciodrv_device_ctx *acio_device_ctx; +static struct aciomgr_port_dispatcher *acio_manager_ctx; + +static int32_t icca_node_id[NUMBER_OF_EMULATED_READERS]; void eam_io_set_loggers( log_formatter_t misc, @@ -42,32 +46,83 @@ void eam_io_set_loggers( log_formatter_t warning, log_formatter_t fatal) { + /* Pass logger functions on to aciomgr so that it has somewhere to write + its own log output. */ + aciomgr_set_loggers(misc, info, warning, fatal); + log_to_external(misc, info, warning, fatal); } +static bool check_if_icca(int node_id) { + char product[4]; + aciomgr_get_node_product_ident(acio_manager_ctx, node_id, product); + + if (!memcmp(product, "ICCA", 4)) { + return true; + } + if (!memcmp(product, "ICCB", 4)) { + return true; + } + if (!memcmp(product, "ICCC", 4)) { + return true; + } + + return false; +} + bool eam_io_init( thread_create_t create, thread_join_t join, thread_destroy_t destroy) { - acio_device_ctx = aciodrv_device_open("COM1", 57600); + acio_manager_ctx = aciomgr_port_init("COM1", 57600); - if (acio_device_ctx == NULL) { + if (acio_manager_ctx == NULL) { log_warning("Opening acio device on COM1 failed"); return false; } - for (uint8_t i = 0; i < 2; i++) { - if (!aciodrv_icca_init(acio_device_ctx, i)) { - log_warning("Initializing icca %d failed", i); - return false; + struct aciodrv_device_ctx *device = aciomgr_port_checkout(acio_manager_ctx); + for (uint8_t i = 0; i < NUMBER_OF_EMULATED_READERS; i++) { + icca_node_id[i] = -1; + + for (uint8_t nid = 0; nid < aciomgr_get_node_count(acio_manager_ctx); ++nid) { + if (check_if_icca(nid)) { + bool existing_reader = false; + for (uint8_t j = 0; j < i; j++) { + if (nid == icca_node_id[j]) { + existing_reader = true; + break; + } + } + + if (existing_reader) { + continue; + } + + icca_node_id[i] = nid; + + if (!aciodrv_icca_init(device, icca_node_id[i])) { + log_warning("Initializing icca %d failed", i); + + // if we have at least 1 valid reader, don't fail + // (ex: for games that expect only 1 reader) + if (i > 0) { + aciomgr_port_checkin(acio_manager_ctx); + return false; + } + } + + break; + } } } + aciomgr_port_checkin(acio_manager_ctx); return true; } void eam_io_fini(void) { - aciodrv_device_close(acio_device_ctx); + aciomgr_port_fini(acio_manager_ctx); } uint16_t eam_io_get_keypad_state(uint8_t unit_no) @@ -113,35 +168,54 @@ uint8_t eam_io_read_card(uint8_t unit_no, uint8_t *card_id, uint8_t nbytes) bool eam_io_card_slot_cmd(uint8_t unit_no, uint8_t cmd) { + // this node is not setup, just return "success"" + if (icca_node_id[unit_no] == -1) { + return true; + } + + struct aciodrv_device_ctx *device = aciomgr_port_checkout(acio_manager_ctx); + + bool response = false; switch (cmd) { case EAM_IO_CARD_SLOT_CMD_CLOSE: - return aciodrv_icca_set_state( - acio_device_ctx, unit_no, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL); + response = aciodrv_icca_set_state( + device, unit_no, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL); case EAM_IO_CARD_SLOT_CMD_OPEN: - return aciodrv_icca_set_state( - acio_device_ctx, unit_no, AC_IO_ICCA_SLOT_STATE_OPEN, NULL); + response = aciodrv_icca_set_state( + device, unit_no, AC_IO_ICCA_SLOT_STATE_OPEN, NULL); case EAM_IO_CARD_SLOT_CMD_EJECT: - return aciodrv_icca_set_state( - acio_device_ctx, unit_no, AC_IO_ICCA_SLOT_STATE_EJECT, NULL); + response = aciodrv_icca_set_state( + device, unit_no, AC_IO_ICCA_SLOT_STATE_EJECT, NULL); case EAM_IO_CARD_SLOT_CMD_READ: - return aciodrv_icca_read_card(acio_device_ctx, unit_no, NULL) && + response = aciodrv_icca_read_card(device, unit_no, NULL) && aciodrv_icca_get_state( - acio_device_ctx, unit_no, &eam_io_icca_state[unit_no]); + device, unit_no, &eam_io_icca_state[unit_no]); default: break; } + aciomgr_port_checkin(acio_manager_ctx); - return false; + return response; } bool eam_io_poll(uint8_t unit_no) { - return aciodrv_icca_get_state( - acio_device_ctx, unit_no, &eam_io_icca_state[unit_no]); + // this node is not setup, just return "success"" + if (icca_node_id[unit_no] == -1) { + return true; + } + + bool response = aciodrv_icca_get_state( + aciomgr_port_checkout(acio_manager_ctx), + unit_no, + &eam_io_icca_state[unit_no]); + aciomgr_port_checkin(acio_manager_ctx); + + return response; } const struct eam_io_config_api *eam_io_get_config_api(void) diff --git a/src/main/iidxio-bio2/iidxio.c b/src/main/iidxio-bio2/iidxio.c index 189b763..6014c17 100644 --- a/src/main/iidxio-bio2/iidxio.c +++ b/src/main/iidxio-bio2/iidxio.c @@ -116,7 +116,8 @@ bool iidx_io_init( } } - bio2_device_ctx = aciodrv_device_open(selected_port, config_bio2.baud); + // BIO2's cannot share a bus with anything else, so use device directly + bio2_device_ctx = aciodrv_device_open_path(selected_port, config_bio2.baud); if (bio2_device_ctx == NULL) { log_info("Opening BIO2 device on [%s] failed", selected_port); diff --git a/src/main/sdvxio-bio2/sdvxio.c b/src/main/sdvxio-bio2/sdvxio.c index 4207e8a..5d3de59 100644 --- a/src/main/sdvxio-bio2/sdvxio.c +++ b/src/main/sdvxio-bio2/sdvxio.c @@ -101,7 +101,8 @@ bool sdvx_io_init( } } - bio2_device_ctx = aciodrv_device_open(selected_port, config_bio2.baud); + // BIO2's cannot share a bus with anything else, so use device directly + bio2_device_ctx = aciodrv_device_open_path(selected_port, config_bio2.baud); if (bio2_device_ctx == NULL) { log_info("Opening BIO2 device on [%s] failed", selected_port); diff --git a/src/main/sdvxio-kfca/Module.mk b/src/main/sdvxio-kfca/Module.mk index 257d071..cb10b22 100644 --- a/src/main/sdvxio-kfca/Module.mk +++ b/src/main/sdvxio-kfca/Module.mk @@ -3,6 +3,7 @@ dlls += sdvxio-kfca libs_sdvxio-kfca := \ geninput \ aciodrv \ + aciomgr \ cconfig \ util \ diff --git a/src/main/sdvxio-kfca/sdvxio.c b/src/main/sdvxio-kfca/sdvxio.c index 0d06737..4ae1af5 100644 --- a/src/main/sdvxio-kfca/sdvxio.c +++ b/src/main/sdvxio-kfca/sdvxio.c @@ -9,7 +9,7 @@ #include "cconfig/cconfig-main.h" -#include "aciodrv/device.h" +#include "aciomgr/manager.h" #include "aciodrv/kfca.h" #include "sdvxio-kfca/config-kfca.h" @@ -37,7 +37,7 @@ static int16_t kfca_node_id; struct ac_io_kfca_poll_out pout_staging; struct ac_io_kfca_poll_out pout_ready; -static struct aciodrv_device_ctx *acio_device_ctx; +static struct aciomgr_port_dispatcher *acio_manager_ctx; void sdvx_io_set_loggers( log_formatter_t misc, @@ -45,6 +45,10 @@ void sdvx_io_set_loggers( log_formatter_t warning, log_formatter_t fatal) { + /* Pass logger functions on to aciomgr so that it has somewhere to write + its own log output. */ + aciomgr_set_loggers(misc, info, warning, fatal); + sdvx_io_log_misc = misc; sdvx_io_log_info = info; sdvx_io_log_warning = warning; @@ -80,23 +84,23 @@ bool sdvx_io_init( cconfig_finit(config); - acio_device_ctx = aciodrv_device_open(config_kfca.port, config_kfca.baud); + acio_manager_ctx = aciomgr_port_init(config_kfca.port, config_kfca.baud); - if (acio_device_ctx == NULL) { + if (acio_manager_ctx == NULL) { log_info("Opening acio device on [%s] failed", config_kfca.port); return 0; } log_info("Opening acio device successful"); - uint8_t node_count = aciodrv_device_get_node_count(acio_device_ctx); + uint8_t node_count = aciomgr_get_node_count(acio_manager_ctx); log_info("Enumerated %d nodes", node_count); kfca_node_id = -1; for (uint8_t i = 0; i < node_count; i++) { char product[4]; - aciodrv_device_get_node_product_ident(acio_device_ctx, i, product); + aciomgr_get_node_product_ident(acio_manager_ctx, i, product); log_info( "> %d: %c%c%c%c\n", i, @@ -116,7 +120,12 @@ bool sdvx_io_init( if (kfca_node_id != -1) { log_warning("Using KFCA on node: %d", kfca_node_id); - if (!aciodrv_kfca_init(acio_device_ctx, kfca_node_id)) { + bool init_result = aciodrv_kfca_init( + aciomgr_port_checkout(acio_manager_ctx), + kfca_node_id); + aciomgr_port_checkin(acio_manager_ctx); + + if (!init_result) { log_warning("Unable to start KFCA on node: %d", kfca_node_id); return false; } @@ -167,7 +176,14 @@ bool sdvx_io_read_input(void) } processing_io = true; - if (!aciodrv_kfca_poll(acio_device_ctx, kfca_node_id, &pout_ready, &pin)) { + bool poll_result = aciodrv_kfca_poll( + aciomgr_port_checkout(acio_manager_ctx), + kfca_node_id, + &pout_ready, + &pin); + aciomgr_port_checkin(acio_manager_ctx); + + if (!poll_result) { return false; } @@ -221,10 +237,13 @@ bool sdvx_io_set_amp_volume( return false; } - if (!aciodrv_kfca_amp( - acio_device_ctx, - kfca_node_id, - primary, 96, headphone, subwoofer)) { + bool amp_result = aciodrv_kfca_amp( + aciomgr_port_checkout(acio_manager_ctx), + kfca_node_id, + primary, 96, headphone, subwoofer); + aciomgr_port_checkin(acio_manager_ctx); + + if (!amp_result) { return false; }