#include <sys/fm/protocol.h>
#include <fm/topo_mod.h>
#include <fm/topo_list.h>
#include <fm/topo_method.h>
static const topo_pgroup_info_t transceiver_pgroup = {
TOPO_PGROUP_TRANSCEIVER,
TOPO_STABILITY_PRIVATE,
TOPO_STABILITY_PRIVATE,
1
};
static const topo_pgroup_info_t sff_transceiver_pgroup = {
TOPO_PGROUP_SFF_TRANSCEIVER,
TOPO_STABILITY_PRIVATE,
TOPO_STABILITY_PRIVATE,
1
};
int
transceiver_range_create(topo_mod_t *mod, tnode_t *pnode, topo_instance_t min,
topo_instance_t max)
{
return (topo_node_range_create(mod, pnode, TRANSCEIVER, min, max));
}
static tnode_t *
transceiver_create_common(topo_mod_t *mod, tnode_t *pnode, topo_instance_t inst,
const char *type, boolean_t usable, const char *part, const char *rev,
const char *serial)
{
int err;
tnode_t *tn = NULL;
nvlist_t *fmri = NULL, *auth = NULL;
if (type == NULL) {
topo_mod_dprintf(mod, "transceiver_create_common missing type "
"argument");
goto error;
}
if ((auth = topo_mod_auth(mod, pnode)) == NULL) {
topo_mod_dprintf(mod, "topo_mod_auth() failed: %s\n",
topo_mod_errmsg(mod));
goto error;
}
if ((fmri = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION,
TRANSCEIVER, inst, NULL, auth, part, rev, serial)) == NULL) {
topo_mod_dprintf(mod, "topo_mod_hcfmri() failed: %s\n",
topo_mod_errmsg(mod));
goto error;
}
if ((tn = topo_node_bind(mod, pnode, TRANSCEIVER, inst, fmri)) ==
NULL) {
topo_mod_dprintf(mod, "topo_node_bind() failed: %s\n",
topo_mod_errmsg(mod));
goto error;
}
if (topo_node_fru_set(tn, fmri, 0, &err) != 0) {
topo_mod_dprintf(mod, "topo_node_fru_set() failed: %s\n",
topo_strerror(err));
goto error;
}
if (topo_pgroup_create(tn, &transceiver_pgroup, &err) != 0) {
topo_mod_dprintf(mod, "failed to create property group %s: "
"%s\n", TOPO_PGROUP_TRANSCEIVER, topo_strerror(err));
goto error;
}
if (topo_prop_set_string(tn, TOPO_PGROUP_TRANSCEIVER,
TOPO_PROP_TRANSCEIVER_TYPE, TOPO_PROP_IMMUTABLE, type,
&err) != 0) {
topo_mod_dprintf(mod, "failed to set %s property: %s\n",
TOPO_PROP_TRANSCEIVER_TYPE, topo_strerror(err));
goto error;
}
if (topo_prop_set_string(tn, TOPO_PGROUP_TRANSCEIVER,
TOPO_PROP_TRANSCEIVER_USABLE, TOPO_PROP_IMMUTABLE,
usable ? "true" : "false", &err) != 0) {
topo_mod_dprintf(mod, "failed to set %s property: %s\n",
TOPO_PROP_TRANSCEIVER_USABLE, topo_strerror(err));
goto error;
}
nvlist_free(fmri);
nvlist_free(auth);
return (tn);
error:
topo_node_unbind(tn);
nvlist_free(fmri);
nvlist_free(auth);
return (NULL);
}
int
transceiver_create_sff(topo_mod_t *mod, tnode_t *pnode, topo_instance_t inst,
boolean_t useable, const char *vendor, const char *part, const char *rev,
const char *serial, tnode_t **nodep)
{
int err;
tnode_t *tn = NULL;
if ((tn = transceiver_create_common(mod, pnode, inst,
TOPO_PROP_PORT_TYPE_SFF, useable, part, rev, serial)) == NULL) {
return (-1);
}
if (topo_pgroup_create(tn, &sff_transceiver_pgroup, &err) != 0) {
topo_mod_dprintf(mod, "failed to create property group %s: "
"%s\n", TOPO_PGROUP_SFF_TRANSCEIVER, topo_strerror(err));
goto error;
}
if (vendor != NULL && topo_prop_set_string(tn,
TOPO_PGROUP_SFF_TRANSCEIVER, TOPO_PORT_SFF_TRANSCEIVER_VENDOR,
TOPO_PROP_IMMUTABLE, vendor, &err) != 0) {
topo_mod_dprintf(mod, "failed to set %s property: %s\n",
TOPO_PORT_SFF_TRANSCEIVER_VENDOR, topo_strerror(err));
goto error;
}
if (part != NULL && topo_prop_set_string(tn,
TOPO_PGROUP_SFF_TRANSCEIVER, TOPO_PORT_SFF_TRANSCEIVER_PN,
TOPO_PROP_IMMUTABLE, part, &err) != 0) {
topo_mod_dprintf(mod, "failed to set %s property: %s\n",
TOPO_PORT_SFF_TRANSCEIVER_PN, topo_strerror(err));
goto error;
}
if (rev != NULL && topo_prop_set_string(tn,
TOPO_PGROUP_SFF_TRANSCEIVER, TOPO_PORT_SFF_TRANSCEIVER_REV,
TOPO_PROP_IMMUTABLE, rev, &err) != 0) {
topo_mod_dprintf(mod, "failed to set %s property: %s\n",
TOPO_PORT_SFF_TRANSCEIVER_REV, topo_strerror(err));
goto error;
}
if (serial != NULL && topo_prop_set_string(tn,
TOPO_PGROUP_SFF_TRANSCEIVER, TOPO_PORT_SFF_TRANSCEIVER_SN,
TOPO_PROP_IMMUTABLE, serial, &err) != 0) {
topo_mod_dprintf(mod, "failed to set %s property: %s\n",
TOPO_PORT_SFF_TRANSCEIVER_SN, topo_strerror(err));
goto error;
}
if (nodep != NULL)
*nodep = tn;
return (0);
error:
topo_node_unbind(tn);
return (-1);
}