Jack-release/cmd_encoder.c

762 lines
18 KiB
C

/* SPDX-License-Identifier: Apache-2.0 */
/**
* @file jack.c
*
* @brief Code file for FM API over TCP CLI
*
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
*
* @date Jan 2024
* @author Barrett Edwards <code@jrlabs.io>
*
*/
/* INCLUDES ==================================================================*/
/* gettid()
*/
#define _GNU_SOURCE
#include <unistd.h>
/* printf()
*/
#include <stdio.h>
/* memset()
*/
#include <string.h>
#include <stdlib.h>
/* autl_prnt_buf()
*/
#include <arrayutils.h>
#include <ptrqueue.h>
#include <fmapi.h>
#include <emapi.h>
/* mctp_init()
* mctp_set_mh()
* mctp_run()
*/
#include <mctp.h>
#include "cmd_encoder.h"
#include "options.h"
/* MACROS ====================================================================*/
#ifdef JACK_VERBOSE
#define INIT unsigned step = 0;
#define ENTER if (opts[CLOP_VERBOSITY].u64 & MCTP_VERBOSE_THREADS) printf("%d:%s Enter\n", gettid(), __FUNCTION__);
#define STEP step++; if (opts[CLOP_VERBOSITY].u64 & MCTP_VERBOSE_STEPS) printf("%d:%s STEP: %u\n", gettid(), __FUNCTION__, step);
#define HEX32(k, i) if (opts[CLOP_VERBOSITY].u64 & MCTP_VERBOSE_STEPS) printf("%d:%s STEP: %u %s: 0x%x\n", gettid(), __FUNCTION__, step, k, i);
#define INT32(k, i) if (opts[CLOP_VERBOSITY].u64 & MCTP_VERBOSE_STEPS) printf("%d:%s STEP: %u %s: %d\n", gettid(), __FUNCTION__, step, k, i);
#define ERR32(k, i) if (opts[CLOP_VERBOSITY].u64 & MCTP_VERBOSE_ERROR) printf("%d:%s STEP: %u ERR: %s: %d\n", gettid(), __FUNCTION__, step, k, i);
#define EXIT(rc) if (opts[CLOP_VERBOSITY].u64 & MCTP_VERBOSE_THREADS) printf("%d:%s Exit: %d\n", gettid(), __FUNCTION__,rc);
#else
#define INIT
#define ENTER
#define STEP
#define HEX32(k, i)
#define INT32(k, i)
#define ERR32(k, i)
#define EXIT(rc)
#endif
#define JKLN_CMD_TIMEOUT_SEC 10
#define JKLN_CMD_TIMEOUT_NSEC 0
/* ENUMERATIONS ==============================================================*/
/* STRUCTS ===================================================================*/
/* PROTOTYPES ================================================================*/
/* GLOBAL VARIABLES ==========================================================*/
/* FUNCTIONS =================================================================*/
struct mctp_action *submit_ctrl(
struct mctp *m,
struct mctp_ctrl_msg *msg,
int retry,
void *user_data,
void (*fn_submitted)(struct mctp *m, struct mctp_action *a),
void (*fn_completed)(struct mctp *m, struct mctp_action *a),
void (*fn_failed)(struct mctp *m, struct mctp_action *a)
)
{
struct timespec delta;
// Initialize variables
delta.tv_sec = JKLN_CMD_TIMEOUT_SEC;
delta.tv_nsec = JKLN_CMD_TIMEOUT_NSEC;
// Set MCTP Control Header fields
msg->hdr.req = 1;
msg->hdr.datagram = 0;
msg->hdr.inst = 0;
msg->len = mctp_len_ctrl((__u8*)&msg->hdr);
// Submit to MCTP library
return mctp_submit(
m, // struct mctp*
MCMT_CONTROL, // [MCMT]
msg, // void* to mctp payload
msg->len+MCLN_CTRL, // Length of mctp payload
retry, // Retry attempts
&delta,
user_data, // To keep with mctp_action
fn_submitted, // fn_submitted
fn_completed, // fn_completed
fn_failed // fn_failed
);
}
struct mctp_action *submit_emapi(
struct mctp *m,
struct emapi_msg *msg,
int retry,
void *user_data,
void (*fn_submitted)(struct mctp *m, struct mctp_action *a),
void (*fn_completed)(struct mctp *m, struct mctp_action *a),
void (*fn_failed)(struct mctp *m, struct mctp_action *a)
)
{
int len;
struct emapi_buf buf;
struct timespec delta;
// Initialize variables
delta.tv_sec = JKLN_CMD_TIMEOUT_SEC;
delta.tv_nsec = JKLN_CMD_TIMEOUT_NSEC;
// Serialize payload
len = emapi_serialize((__u8*)&buf.payload, &msg->obj, emapi_emob_req(msg->hdr.opcode), NULL);
// Set EM API message category as a request
emapi_fill_hdr(&msg->hdr, EMMT_REQ, 0, 0, msg->hdr.opcode, len, msg->hdr.a, msg->hdr.b);
// Serialize EM API Header into buffer
emapi_serialize((__u8*)&buf.hdr, &msg->hdr, EMOB_HDR, NULL);
// Submit to MCTP library
return mctp_submit(
m, // struct mctp*
MCMT_CSE, // [MCMT]
&buf, // void* to mctp payload
msg->hdr.len + EMLN_HDR,// Length of mctp payload
retry, // Retry attempts
&delta,
user_data, // To keep with mctp_action
fn_submitted, // fn_submitted
fn_completed, // fn_completed
fn_failed // fn_failed
);
}
struct mctp_action *submit_fmapi(
struct mctp *m,
struct fmapi_msg *msg,
int retry,
void *user_data,
void (*fn_submitted)(struct mctp *m, struct mctp_action *a),
void (*fn_completed)(struct mctp *m, struct mctp_action *a),
void (*fn_failed)(struct mctp *m, struct mctp_action *a)
)
{
int len;
struct fmapi_buf buf;
struct timespec delta;
// Initialize variables
delta.tv_sec = JKLN_CMD_TIMEOUT_SEC;
delta.tv_nsec = JKLN_CMD_TIMEOUT_NSEC;
// Serialize Object
len = fmapi_serialize((__u8*)&buf.payload, &msg->obj, fmapi_fmob_req(msg->hdr.opcode));
// Fill Header
fmapi_fill_hdr(&msg->hdr, FMMT_REQ, 0, msg->hdr.opcode, 0, len, 0, 0);
// Serialize Header
fmapi_serialize((__u8*)&buf.hdr, &msg->hdr, FMOB_HDR);
// Submit to MCTP library
return mctp_submit(
m, // struct mctp*
MCMT_CXLFMAPI, // [MCMT]
&buf, // void* to mctp payload
msg->hdr.len + FMLN_HDR,// Length of mctp payload
retry, // Retry attempts
&delta,
user_data, // To keep with mctp_action
fn_submitted, // fn_submitted
fn_completed, // fn_completed
fn_failed // fn_failed
);
}
/**
* Prepare an MCTP Message Request from CLI Options
*
* @param mm struct mctp_msg* this is the message to store the request in
* @return 0 upon success, non-zero otherwise
*
* STEPS
* 1: Set buffer pointers
* 3: Command switch
*/
struct mctp_action *submit_cli_request(struct mctp *m, void *user_data)
{
INIT
struct mctp_action *ma;
struct fmapi_msg msg, sub;
struct emapi_msg em;
struct mctp_ctrl_msg mc;
ENTER
// Initialize Variables
ma = NULL;
STEP // 1: Set buffer pointers
STEP // 2: Handle Command
switch (opts[CLOP_CMD].val)
{
case CLCM_NULL:
goto end;
case CLCM_AER:
{
int vcsid, vppbid;
vcsid = 0;
vppbid = 0;
if (opts[CLOP_VCSID].set)
vcsid = opts[CLOP_VCSID].u8; //!< Virtual CXL Switch ID
if (opts[CLOP_VPPBID].set)
vppbid = opts[CLOP_VPPBID].u8; //!< Virtual Pcie-to-PCIe Bridge ID <u8>
if (!opts[CLOP_AER_ERROR].set)
goto end;
if (!opts[CLOP_AER_HEADER].set) //!< TLP Header to place in AER registers, as defined in the PCIe specification
goto end;
fmapi_fill_vsc_aer(&msg, vcsid, vppbid, opts[CLOP_AER_ERROR].u32, opts[CLOP_AER_HEADER].buf);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_PORT_BIND:
{
int vcsid, vppbid, ppid, ldid;
vcsid = 0;
vppbid = 0;
ppid = 0;
ldid = 0xFFFF;
if (opts[CLOP_VCSID].set)
vcsid = opts[CLOP_VCSID].u8; //!< Virtual CXL Switch ID
if (opts[CLOP_PPID].set)
ppid = opts[CLOP_PPID].u8; //!< Physical Port ID <u8>
if (opts[CLOP_VPPBID].set)
vppbid = opts[CLOP_VPPBID].u8; //!< Virtual Pcie-to-PCIe Bridge ID <u8>
if (opts[CLOP_LDID].set)
ldid = opts[CLOP_LDID].u16; //!< Logical Device ID <u16>
fmapi_fill_vsc_bind(&msg, vcsid, vppbid, ppid, ldid);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_PORT_CONFIG:
{
int ppid, reg, ext, fdbe, type;
ppid = 0;
reg = 0;
ext = 0;
fdbe = 0;
type = 0;
if (opts[CLOP_PPID].set)
ppid = opts[CLOP_PPID].u8; //!< PPB ID: Target PPB physical port
if (opts[CLOP_REGISTER].set)
reg = opts[CLOP_REGISTER].u8; //!< Register Number as defined in PCIe spec
if (opts[CLOP_EXT_REGISTER].set)
ext = opts[CLOP_EXT_REGISTER].u8; //!< Extended Register Number as defined in PCIe spec
if (opts[CLOP_FDBE].set)
fdbe = opts[CLOP_FDBE].u8; //!< First DWord Byte Enable as defined in PCIe spec
else
fdbe = 0x1; //!< First DWord Byte Enable as defined in PCIe spec
if (opts[CLOP_WRITE].set)
type = FMCT_WRITE; //!< Transation type [FMCT]
fmapi_fill_psc_cfg(&msg, ppid, reg, ext, fdbe, type, (__u8*)&opts[CLOP_DATA].u32);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_PORT_CONN:
{
emapi_fill_conn(&em, opts[CLOP_PPID].u8, opts[CLOP_DEVICE].u8);
ma = submit_emapi(m, &em, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_PORT_DISCONN:
{
emapi_fill_disconn(&em, opts[CLOP_PPID].u8, opts[CLOP_ALL].set);
ma = submit_emapi(m, &em, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_PORT_CTRL:
{
int ppid, opcode;
ppid = 0;
opcode = 0;
if (opts[CLOP_PPID].set)
ppid = opts[CLOP_PPID].u8;
switch (opts[CLOP_PORT_CONTROL].val)
{
case CLPC_ASSERT: opcode = FMPO_ASSERT_PERST; break;
case CLPC_DEASSERT: opcode = FMPO_DEASSERT_PERST; break;
case CLPC_RESET: opcode = FMPO_RESET_PPB; break;
default: goto end;
}
fmapi_fill_psc_port_ctrl(&msg, ppid, opcode);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_PORT_UNBIND:
{
int vcsid, vppbid, option;
vcsid = 0;
option = 0;
vppbid = 0xFFFF;
// Prepare Object
if (opts[CLOP_VCSID].set)
vcsid = opts[CLOP_VCSID].u8; //!< Virtual CXL Switch ID
if (opts[CLOP_VPPBID].set)
vppbid = opts[CLOP_VPPBID].u8; //!< Virtual Pcie-to-PCIe Bridge ID <u8>
if (opts[CLOP_UNBIND_MODE].set)
{ //!< Unbind Option [FMUB]
switch(opts[CLOP_UNBIND_MODE].val)
{
case CLPU_WAIT: option = FMUB_WAIT; break;
case CLPU_MANAGED: option = FMUB_MANAGED_HOT_REMOVE; break;
case CLPU_SURPRISE: option = FMUB_SURPRISE_HOT_REMOVE; break;
default: goto end;
}
}
fmapi_fill_vsc_unbind(&msg, vcsid, vppbid, option);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_LD_CONFIG:
{
int ppid, ldid, reg, ext, fdbe, type;
ppid = 0;
ldid = 0;
reg = 0;
ext = 0;
fdbe = 1;
type = FMCT_READ;
// Prepare Object
if (opts[CLOP_PPID].set)
ppid = opts[CLOP_PPID].u8; //!< PPB ID: Target PPB physical port
if (opts[CLOP_REGISTER].set)
reg = opts[CLOP_REGISTER].u8; //!< Register Number as defined in PCIe spec
if (opts[CLOP_EXT_REGISTER].set)
ext = opts[CLOP_EXT_REGISTER].u8; //!< Extended Register Number as defined in PCIe spec
if (opts[CLOP_FDBE].set)
fdbe = opts[CLOP_FDBE].u8; //!< First DWord Byte Enable as defined in PCIe spec
if (opts[CLOP_WRITE].set)
type = FMCT_WRITE; //!< Transation type [FMCT]
if (opts[CLOP_LDID].set)
ldid = opts[CLOP_LDID].u16; //!< Logical Device ID <u16>
fmapi_fill_mpc_cfg(&msg, ppid, ldid, reg, ext, fdbe, type, (__u8*)&opts[CLOP_DATA].u32);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_LD_MEM:
{
int ppid, ldid, len, fdbe, ldbe, type;
__u64 offset;
__u8 *data;
ppid = 0;
ldid = 0;
offset = 0;
len = 0;
fdbe = 0xF; //!< First DWord Byte Enable as defined in PCIe spec
ldbe = 0xF; //!< First DWord Byte Enable as defined in PCIe spec
type = FMCT_READ;
// Prepare Object
if (opts[CLOP_PPID].set)
ppid = opts[CLOP_PPID].u8; //!< PPB ID: Target PPB physical port
if (opts[CLOP_FDBE].set)
fdbe = opts[CLOP_FDBE].u8; //!< First DWord Byte Enable as defined in PCIe spec
if (opts[CLOP_LDBE].set)
ldbe = opts[CLOP_LDBE].u8; //!< Last DWord Byte Enable as defined in PCIe spec
if (opts[CLOP_WRITE].set)
type = FMCT_WRITE; //!< Transation type [FMCT]
if (opts[CLOP_LDID].set)
ldid = opts[CLOP_LDID].u16; //!< Logical Device ID <u16>
if (opts[CLOP_LEN].set)
len = opts[CLOP_LEN].len; //!< Transaction Length in bytes, max of 4 kB
if (opts[CLOP_OFFSET].set)
offset = opts[CLOP_OFFSET].u64; //!< Transaction Offset into target device mem space
data = (__u8*)&opts[CLOP_DATA].u32; //!< Transaction Data: Write data. Only valid for write transactions
if (opts[CLOP_INFILE].set)
data = opts[CLOP_INFILE].buf; //!< Transaction Data: Write data. Only valid for write transactions
fmapi_fill_mpc_mem(&msg, ppid, ldid, offset, len, fdbe, ldbe, type, data);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_MCTP:
break;
case CLCM_MCTP_GET_EID:
{
mctp_ctrl_fill_get_eid(&mc);
ma = submit_ctrl(m, &mc, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_MCTP_GET_TYPE:
{
mctp_ctrl_fill_get_type(&mc);
ma = submit_ctrl(m, &mc, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_MCTP_GET_UUID:
{
mctp_ctrl_fill_get_uuid(&mc);
ma = submit_ctrl(m, &mc, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_MCTP_GET_VER:
{
mctp_ctrl_fill_get_ver(&mc, opts[CLOP_MCTP_TYPE].u8);
ma = submit_ctrl(m, &mc, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_MCTP_SET_EID:
{
mctp_ctrl_fill_set_eid(&mc, opts[CLOP_MCTP_EID].u8);
ma = submit_ctrl(m, &mc, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SET_MSG_LIMIT:
{
fmapi_fill_isc_set_msg_limit(&msg, opts[CLOP_LIMIT].u8);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SET_LD_ALLOCATIONS:
{
int start, num;
start = 0;
num = opts[CLOP_LD_RNG1].num;
if (opts[CLOP_LDID].set)
start = opts[CLOP_LDID].u16;
fmapi_fill_mcc_set_alloc(&sub, start, num, (__u64*)opts[CLOP_LD_RNG1].buf, (__u64*)opts[CLOP_LD_RNG2].buf);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SET_QOS_ALLOCATED:
{
int start, num;
num = opts[CLOP_QOS_ALLOCATED].num;
start = 0;
if (opts[CLOP_LDID].set)
start = opts[CLOP_LDID].u16;
if (!opts[CLOP_QOS_ALLOCATED].set)
goto end;
fmapi_fill_mcc_set_qos_alloc(&sub, start, num, opts[CLOP_QOS_ALLOCATED].buf);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SET_QOS_CONTROL:
{
int epc, ttr, mod, sev, si, rcb, ci;
epc = 0;
ttr = 0;
mod = 0;
sev = 0;
si = 0;
rcb = 0;
ci = 0;
if (opts[CLOP_CONGEST_ENABLE].set)
epc = 1;
if (opts[CLOP_TEMP_THROTTLE].set)
ttr = 1;
if (opts[CLOP_EGRESS_MOD_PCNT].set)
mod = opts[CLOP_EGRESS_MOD_PCNT].u8;
if (opts[CLOP_EGRESS_SEV_PCNT].set)
sev = opts[CLOP_EGRESS_SEV_PCNT].u8;
if (opts[CLOP_BP_SAMPLE_INTVL].set)
si = opts[CLOP_BP_SAMPLE_INTVL].u8;
if (opts[CLOP_REQCMPBASIS].set)
rcb = opts[CLOP_REQCMPBASIS].u16;
if (opts[CLOP_CCINTERVAL].set)
ci = opts[CLOP_CCINTERVAL].u8;
fmapi_fill_mcc_set_qos_ctrl(&sub, epc, ttr, mod, sev, si, rcb, ci);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SET_QOS_LIMIT:
{
int start, num;
num = opts[CLOP_QOS_LIMIT].num;
start = 0;
if (opts[CLOP_LDID].set)
start = opts[CLOP_LDID].u16;
if (!opts[CLOP_QOS_LIMIT].set)
goto end;
fmapi_fill_mcc_set_qos_limit(&sub, start, num, opts[CLOP_QOS_LIMIT].buf);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_BOS:
{
fmapi_fill_isc_bos(&msg);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_IDENTITY:
{
fmapi_fill_isc_id(&msg);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_MSG_LIMIT:
{
fmapi_fill_isc_get_msg_limit(&msg);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_PORT:
{
if (opts[CLOP_PPID].set)
{
if (opts[CLOP_PPID].num > 0)
fmapi_fill_psc_get_ports(&msg, opts[CLOP_PPID].num, opts[CLOP_PPID].buf);
else
fmapi_fill_psc_get_port(&msg, opts[CLOP_PPID].u8);
}
else if (opts[CLOP_ALL].set)
fmapi_fill_psc_get_all_ports(&msg);
else
goto end;
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_LD_ALLOCATIONS:
{
fmapi_fill_mcc_get_alloc(&sub, 0, 0);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_LD_INFO:
{
fmapi_fill_mcc_get_info(&sub);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_QOS_ALLOCATED:
{
__u8 num, start;
num = 255;
start = 0;
if (opts[CLOP_NUM].set)
num = opts[CLOP_NUM].u8;
if (opts[CLOP_LDID].set)
start = opts[CLOP_LDID].u16;
fmapi_fill_mcc_get_qos_alloc(&sub, start, num);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_QOS_CONTROL:
{
fmapi_fill_mcc_get_qos_ctrl(&sub);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_QOS_LIMIT:
{
__u8 num, start;
num = 255;
start = 0;
if (opts[CLOP_NUM].set)
num = opts[CLOP_NUM].u8;
if (opts[CLOP_LDID].set)
start = opts[CLOP_LDID].u16;
fmapi_fill_mcc_get_qos_limit(&sub, start, num);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_QOS_STATUS:
{
fmapi_fill_mcc_get_qos_status(&sub);
fmapi_fill_mpc_tmc(&msg, opts[CLOP_PPID].u8, MCMT_CXLCCI, &sub);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_SWITCH:
{
fmapi_fill_psc_id(&msg);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_DEV:
{
int a = 0;
int b = 0;
if (opts[CLOP_DEVICE].set) {
a = 1;
b = opts[CLOP_DEVICE].u8;
}
if (opts[CLOP_ALL].set) {
a = 0;
}
emapi_fill_listdev(&em, a, b);
ma = submit_emapi(m, &em, 0, user_data, NULL, NULL, NULL);
}
break;
case CLCM_SHOW_VCS:
{
int vcsid = 0;
if (opts[CLOP_VCSID].set)
vcsid = opts[CLOP_VCSID].u8;
fmapi_fill_vsc_get_vcs(&msg, vcsid, 0, 255);
ma = submit_fmapi(m, &msg, 0, user_data, NULL, NULL, NULL);
}
break;
default:
goto end;
}
end:
EXIT(0);
return ma;
}