10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
54411Svikram * Common Development and Distribution License (the "License").
64411Svikram * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*12163SRamaswamy.Tummala@Sun.COM * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate * This file contains support required for IB cfgadm plugin.
270Sstevel@tonic-gate */
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <sys/conf.h>
300Sstevel@tonic-gate #include <sys/stat.h>
310Sstevel@tonic-gate #include <sys/modctl.h>
320Sstevel@tonic-gate #include <sys/ib/mgt/ibdm/ibdm_impl.h>
330Sstevel@tonic-gate #include <sys/ib/ibnex/ibnex.h>
340Sstevel@tonic-gate #include <sys/ib/ibnex/ibnex_devctl.h>
350Sstevel@tonic-gate #include <sys/ib/ibtl/impl/ibtl_ibnex.h>
369879SRamaswamy.Tummala@Sun.COM #include <sys/ib/ibtl/impl/ibtl.h>
370Sstevel@tonic-gate #include <sys/file.h>
380Sstevel@tonic-gate #include <sys/sunndi.h>
390Sstevel@tonic-gate #include <sys/fs/dv_node.h>
400Sstevel@tonic-gate #include <sys/mdi_impldefs.h>
410Sstevel@tonic-gate #include <sys/sunmdi.h>
420Sstevel@tonic-gate
439879SRamaswamy.Tummala@Sun.COM /* return the minimum value of (x) and (y) */
449879SRamaswamy.Tummala@Sun.COM #define MIN(x, y) ((x) < (y) ? (x) : (y))
459879SRamaswamy.Tummala@Sun.COM
460Sstevel@tonic-gate /*
470Sstevel@tonic-gate * function prototypes
480Sstevel@tonic-gate */
490Sstevel@tonic-gate int ibnex_open(dev_t *, int, int, cred_t *);
500Sstevel@tonic-gate int ibnex_close(dev_t, int, int, cred_t *);
510Sstevel@tonic-gate int ibnex_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
520Sstevel@tonic-gate int ibnex_offline_childdip(dev_info_t *);
530Sstevel@tonic-gate static int ibnex_get_num_devices(void);
540Sstevel@tonic-gate static int ibnex_get_snapshot(char **, size_t *, int);
550Sstevel@tonic-gate static int ibnex_get_commsvcnode_snapshot(nvlist_t **, ib_guid_t,
560Sstevel@tonic-gate ib_guid_t, int, ib_pkey_t, ibnex_node_type_t);
570Sstevel@tonic-gate static int ibnex_fill_ioc_tmp(nvlist_t **, ibdm_ioc_info_t *);
580Sstevel@tonic-gate static int ibnex_fill_nodeinfo(nvlist_t **, ibnex_node_data_t *,
590Sstevel@tonic-gate void *);
60*12163SRamaswamy.Tummala@Sun.COM static void ibnex_figure_ap_devstate(ibnex_node_data_t *,
610Sstevel@tonic-gate devctl_ap_state_t *);
620Sstevel@tonic-gate static void ibnex_figure_ib_apid_devstate(devctl_ap_state_t *);
630Sstevel@tonic-gate static char *ibnex_get_apid(struct devctl_iocdata *);
640Sstevel@tonic-gate static int ibnex_get_dip_from_apid(char *, dev_info_t **,
650Sstevel@tonic-gate ibnex_node_data_t **);
66*12163SRamaswamy.Tummala@Sun.COM extern int ibnex_get_node_and_dip_from_guid(ib_guid_t, int,
67*12163SRamaswamy.Tummala@Sun.COM ib_pkey_t, ibnex_node_data_t **, dev_info_t **);
680Sstevel@tonic-gate static ibnex_rval_t ibnex_handle_pseudo_configure(char *);
690Sstevel@tonic-gate static ibnex_rval_t ibnex_handle_ioc_configure(char *);
700Sstevel@tonic-gate static ibnex_rval_t ibnex_handle_commsvcnode_configure(char *);
710Sstevel@tonic-gate static void ibnex_return_apid(dev_info_t *, char **);
720Sstevel@tonic-gate static void ibnex_port_conf_entry_add(char *);
730Sstevel@tonic-gate static void ibnex_vppa_conf_entry_add(char *);
740Sstevel@tonic-gate static void ibnex_hcasvc_conf_entry_add(char *);
750Sstevel@tonic-gate static int ibnex_port_conf_entry_delete(char *, char *);
760Sstevel@tonic-gate static int ibnex_vppa_conf_entry_delete(char *, char *);
770Sstevel@tonic-gate static int ibnex_hcasvc_conf_entry_delete(char *, char *);
780Sstevel@tonic-gate
790Sstevel@tonic-gate static ibnex_rval_t ibnex_ioc_fininode(dev_info_t *, ibnex_ioc_node_t *);
800Sstevel@tonic-gate static ibnex_rval_t ibnex_commsvc_fininode(dev_info_t *);
810Sstevel@tonic-gate static ibnex_rval_t ibnex_pseudo_fininode(dev_info_t *);
820Sstevel@tonic-gate
839879SRamaswamy.Tummala@Sun.COM static int ibnex_devctl(dev_t, int, intptr_t, int,
849879SRamaswamy.Tummala@Sun.COM cred_t *, int *);
859879SRamaswamy.Tummala@Sun.COM static int ibnex_ctl_get_api_ver(dev_t, int, intptr_t, int,
869879SRamaswamy.Tummala@Sun.COM cred_t *, int *);
879879SRamaswamy.Tummala@Sun.COM static int ibnex_ctl_get_hca_list(dev_t, int, intptr_t, int,
889879SRamaswamy.Tummala@Sun.COM cred_t *, int *);
899879SRamaswamy.Tummala@Sun.COM static int ibnex_ctl_query_hca(dev_t, int, intptr_t, int,
909879SRamaswamy.Tummala@Sun.COM cred_t *, int *);
919879SRamaswamy.Tummala@Sun.COM static int ibnex_ctl_query_hca_port(dev_t, int, intptr_t, int,
929879SRamaswamy.Tummala@Sun.COM cred_t *, int *);
939879SRamaswamy.Tummala@Sun.COM
940Sstevel@tonic-gate extern uint64_t ibnex_str2hex(char *, int, int *);
958082SRamaswamy.Tummala@Sun.COM extern int ibnex_ioc_initnode_all_pi(ibdm_ioc_info_t *);
960Sstevel@tonic-gate extern dev_info_t *ibnex_commsvc_initnode(dev_info_t *,
970Sstevel@tonic-gate ibdm_port_attr_t *, int, int, ib_pkey_t, int *,
980Sstevel@tonic-gate int);
990Sstevel@tonic-gate extern int ibnex_get_dip_from_guid(ib_guid_t, int,
1000Sstevel@tonic-gate ib_pkey_t, dev_info_t **);
1010Sstevel@tonic-gate extern void ibnex_reprobe_ioc_dev(void *arg);
1020Sstevel@tonic-gate extern void ibnex_reprobe_ioc_all();
1038082SRamaswamy.Tummala@Sun.COM extern int ibnex_pseudo_create_all_pi(ibnex_node_data_t *);
1040Sstevel@tonic-gate extern void ibnex_pseudo_initnodes(void);
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate extern ibnex_t ibnex;
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate /*
1090Sstevel@tonic-gate * ibnex_open()
1100Sstevel@tonic-gate */
1110Sstevel@tonic-gate /* ARGSUSED */
1120Sstevel@tonic-gate int
ibnex_open(dev_t * dev,int flag,int otyp,cred_t * credp)1130Sstevel@tonic-gate ibnex_open(dev_t *dev, int flag, int otyp, cred_t *credp)
1140Sstevel@tonic-gate {
1150Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\topen");
1160Sstevel@tonic-gate return (0);
1170Sstevel@tonic-gate }
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate /*
1210Sstevel@tonic-gate * ibnex_close()
1220Sstevel@tonic-gate */
1230Sstevel@tonic-gate /* ARGSUSED */
1240Sstevel@tonic-gate int
ibnex_close(dev_t dev,int flag,int otyp,cred_t * credp)1250Sstevel@tonic-gate ibnex_close(dev_t dev, int flag, int otyp, cred_t *credp)
1260Sstevel@tonic-gate {
1270Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tclose");
1280Sstevel@tonic-gate return (0);
1290Sstevel@tonic-gate }
1300Sstevel@tonic-gate
1319879SRamaswamy.Tummala@Sun.COM int
ibnex_ioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)1329879SRamaswamy.Tummala@Sun.COM ibnex_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
1339879SRamaswamy.Tummala@Sun.COM int *rvalp)
1349879SRamaswamy.Tummala@Sun.COM {
1359879SRamaswamy.Tummala@Sun.COM /*
1369879SRamaswamy.Tummala@Sun.COM * For all generic devctl ioctls (such as DEVCTL_AP_CONFIGURE),
1379879SRamaswamy.Tummala@Sun.COM * call ibnex_devctl().
1389879SRamaswamy.Tummala@Sun.COM */
1399879SRamaswamy.Tummala@Sun.COM if (IS_DEVCTL(cmd))
1409879SRamaswamy.Tummala@Sun.COM return (ibnex_devctl(dev, cmd, arg, mode, credp, rvalp));
1419879SRamaswamy.Tummala@Sun.COM
1429879SRamaswamy.Tummala@Sun.COM /*
1439879SRamaswamy.Tummala@Sun.COM * The rest are ibnex specific ioctls.
1449879SRamaswamy.Tummala@Sun.COM */
1459879SRamaswamy.Tummala@Sun.COM
1469879SRamaswamy.Tummala@Sun.COM switch (cmd) {
1479879SRamaswamy.Tummala@Sun.COM case IBNEX_CTL_GET_API_VER:
1489879SRamaswamy.Tummala@Sun.COM return (ibnex_ctl_get_api_ver(dev, cmd, arg, mode,
1499879SRamaswamy.Tummala@Sun.COM credp, rvalp));
1509879SRamaswamy.Tummala@Sun.COM
1519879SRamaswamy.Tummala@Sun.COM case IBNEX_CTL_GET_HCA_LIST:
1529879SRamaswamy.Tummala@Sun.COM return (ibnex_ctl_get_hca_list(dev, cmd, arg, mode,
1539879SRamaswamy.Tummala@Sun.COM credp, rvalp));
1549879SRamaswamy.Tummala@Sun.COM
1559879SRamaswamy.Tummala@Sun.COM case IBNEX_CTL_QUERY_HCA:
1569879SRamaswamy.Tummala@Sun.COM return (ibnex_ctl_query_hca(dev, cmd, arg, mode,
1579879SRamaswamy.Tummala@Sun.COM credp, rvalp));
1589879SRamaswamy.Tummala@Sun.COM
1599879SRamaswamy.Tummala@Sun.COM case IBNEX_CTL_QUERY_HCA_PORT:
1609879SRamaswamy.Tummala@Sun.COM return (ibnex_ctl_query_hca_port(dev, cmd, arg, mode,
1619879SRamaswamy.Tummala@Sun.COM credp, rvalp));
1629879SRamaswamy.Tummala@Sun.COM
1639879SRamaswamy.Tummala@Sun.COM default:
1649879SRamaswamy.Tummala@Sun.COM return (EINVAL);
1659879SRamaswamy.Tummala@Sun.COM }
1669879SRamaswamy.Tummala@Sun.COM }
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate /*
1690Sstevel@tonic-gate * ibnex_ioctl()
1700Sstevel@tonic-gate * Ioctl routine for cfgadm controls
1710Sstevel@tonic-gate * DEVCTL_AP_GETSTATE: returns attachment point state
1720Sstevel@tonic-gate * DEVCTL_AP_CONTROL: Does "ibnex" specific ioctls listed below
1730Sstevel@tonic-gate * IBNEX_NUM_DEVICE_NODES Gives how many device nodes exist?
1740Sstevel@tonic-gate * IBNEX_NUM_HCA_NODES Gives how many HCAs exist in the fabric
1750Sstevel@tonic-gate * IBNEX_UPDATE_PKEY_TBLS "-x update_pkey_tbls"
1760Sstevel@tonic-gate * IBNEX_GET_SNAPSHOT Gets the "snapshot" back to user-land
1770Sstevel@tonic-gate * IBNEX_SNAPSHOT_SIZE What is "snapshot" size
1780Sstevel@tonic-gate * IBNEX_DEVICE_PATH_SZ What is device-path size
1790Sstevel@tonic-gate * IBNEX_GET_DEVICE_PATH Gets the device path for Dynamic ap
1800Sstevel@tonic-gate * IBNEX_HCA_LIST_SZ "-x list" option size for the HCA ap_id
1810Sstevel@tonic-gate * IBNEX_HCA_LIST_INFO "-x list" option info for the HCA ap_id
1820Sstevel@tonic-gate * IBNEX_UNCFG_CLNTS_SZ "-x unconfig_client option size"
1830Sstevel@tonic-gate * IBNEX_UNCFG_CLNTS_INFO "-x unconfig_client data"
1840Sstevel@tonic-gate * IBNEX_CONF_ENTRY_ADD: "-x add_service"
1850Sstevel@tonic-gate * IBNEX_CONF_ENTRY_DEL: "-x delete_service"
1860Sstevel@tonic-gate * IBNEX_HCA_VERBOSE_SZ: "-alv hca_apid data size"
1870Sstevel@tonic-gate * IBNEX_HCA_VERBOSE_INFO: "-alv hca_apid actual data"
1880Sstevel@tonic-gate * IBNEX_UPDATE_IOC_CONF "-x update_ioc_conf"
1890Sstevel@tonic-gate * DEVCTL_AP_CONFIGURE: "configure" the attachment point
1900Sstevel@tonic-gate * DEVCTL_AP_UNCONFIGURE: "unconfigure" the attachment point
1910Sstevel@tonic-gate */
1920Sstevel@tonic-gate /* ARGSUSED */
1939879SRamaswamy.Tummala@Sun.COM static int
ibnex_devctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)1949879SRamaswamy.Tummala@Sun.COM ibnex_devctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
1950Sstevel@tonic-gate int *rvalp)
1960Sstevel@tonic-gate {
1970Sstevel@tonic-gate int ret, rv = 0, ioc_reprobe_pending = 0;
1980Sstevel@tonic-gate int circ;
1990Sstevel@tonic-gate char *snapshot = NULL;
2000Sstevel@tonic-gate char *apid_n = NULL;
2010Sstevel@tonic-gate char *service = NULL;
2020Sstevel@tonic-gate char *devnm = NULL;
2030Sstevel@tonic-gate char *msg;
2040Sstevel@tonic-gate char *guid_str;
2050Sstevel@tonic-gate uint_t num_hcas = 0;
2060Sstevel@tonic-gate size_t snapshot_sz = 0;
2070Sstevel@tonic-gate uint32_t ssiz;
2080Sstevel@tonic-gate uint32_t apid_len;
2090Sstevel@tonic-gate ib_guid_t hca_guid;
2100Sstevel@tonic-gate boolean_t apid_alloced = B_FALSE;
2110Sstevel@tonic-gate dev_info_t *apid_dip = NULL;
2120Sstevel@tonic-gate dev_info_t *pdip;
2130Sstevel@tonic-gate ibnex_rval_t ret_val;
2140Sstevel@tonic-gate ib_service_type_t svc_type = IB_NONE;
2150Sstevel@tonic-gate devctl_ap_state_t ap_state;
216*12163SRamaswamy.Tummala@Sun.COM ibnex_node_data_t *nodep = NULL;
217*12163SRamaswamy.Tummala@Sun.COM ibnex_node_data_t *scanp;
2180Sstevel@tonic-gate struct devctl_iocdata *dcp = NULL;
2190Sstevel@tonic-gate
2209879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L4("ibnex", "\tdevctl: cmd=%x, arg=%p, mode=%x, cred=%p, "
2210Sstevel@tonic-gate "\t\trval=%p dev=0x%x", cmd, arg, mode, credp, rvalp, dev);
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate /* read devctl ioctl data */
2240Sstevel@tonic-gate if ((cmd != DEVCTL_AP_CONTROL) &&
2250Sstevel@tonic-gate (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)) {
2260Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex",
2279879SRamaswamy.Tummala@Sun.COM "\tdevctl: ndi_dc_allochdl failed\n");
2280Sstevel@tonic-gate return (EFAULT);
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
2320Sstevel@tonic-gate switch (cmd) {
2330Sstevel@tonic-gate case DEVCTL_AP_GETSTATE:
2349879SRamaswamy.Tummala@Sun.COM msg = "\tdevctl: DEVCTL_AP_GETSTATE";
2350Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s:", msg);
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate apid_n = ibnex_get_apid(dcp);
2380Sstevel@tonic-gate if (*apid_n == '\0') {
2390Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
2400Sstevel@tonic-gate "%s: ibnex_get_apid failed", msg);
2410Sstevel@tonic-gate rv = EIO;
2420Sstevel@tonic-gate break;
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate
2450Sstevel@tonic-gate if (strncmp(apid_n, IBNEX_FABRIC, strlen(IBNEX_FABRIC)) == 0) {
2460Sstevel@tonic-gate ibnex_figure_ib_apid_devstate(&ap_state);
2470Sstevel@tonic-gate apid_dip = ibnex.ibnex_dip;
2480Sstevel@tonic-gate } else {
2490Sstevel@tonic-gate /* if this apid is already seen by IBNEX, get the dip */
2500Sstevel@tonic-gate rv = ibnex_get_dip_from_apid(apid_n, &apid_dip, &nodep);
2510Sstevel@tonic-gate if (rv != IBNEX_DYN_APID) {
2520Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
2530Sstevel@tonic-gate "%s: ibnex_get_dip_from_apid failed", msg);
2540Sstevel@tonic-gate rv = EIO;
2550Sstevel@tonic-gate break;
2560Sstevel@tonic-gate }
2570Sstevel@tonic-gate if (apid_dip)
2580Sstevel@tonic-gate ndi_rele_devi(apid_dip);
2590Sstevel@tonic-gate /* rv could be something undesirable, so reset it */
2600Sstevel@tonic-gate rv = 0;
2610Sstevel@tonic-gate
262*12163SRamaswamy.Tummala@Sun.COM ibnex_figure_ap_devstate(nodep, &ap_state);
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate /* copy the return-AP-state information to the user space */
2660Sstevel@tonic-gate if (ndi_dc_return_ap_state(&ap_state, dcp) != NDI_SUCCESS) {
2670Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
2680Sstevel@tonic-gate "%s: ndi_dc_return_ap_state failed", msg);
2690Sstevel@tonic-gate rv = EFAULT;
2700Sstevel@tonic-gate }
2710Sstevel@tonic-gate break;
2720Sstevel@tonic-gate
2730Sstevel@tonic-gate case DEVCTL_AP_CONTROL:
2740Sstevel@tonic-gate {
2750Sstevel@tonic-gate int num_nodes = 0;
2760Sstevel@tonic-gate ibnex_ioctl_data_t ioc; /* for 64-bit copies only */
2770Sstevel@tonic-gate
2789879SRamaswamy.Tummala@Sun.COM msg = "\tdevctl: DEVCTL_AP_CONTROL";
2790Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL
2800Sstevel@tonic-gate if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
2810Sstevel@tonic-gate ibnex_ioctl_data_32_t ioc32;
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate if (ddi_copyin((void *)arg, &ioc32,
2840Sstevel@tonic-gate sizeof (ioc32), mode) != 0) {
2850Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
2860Sstevel@tonic-gate "%s: ddi_copyin err 1", msg);
2870Sstevel@tonic-gate rv = EFAULT;
2880Sstevel@tonic-gate break;
2890Sstevel@tonic-gate }
2900Sstevel@tonic-gate ioc.cmd = (uint_t)ioc32.cmd;
2910Sstevel@tonic-gate ioc.buf = (caddr_t)(uintptr_t)ioc32.buf;
2920Sstevel@tonic-gate ioc.bufsiz = (uint_t)ioc32.bufsiz;
2930Sstevel@tonic-gate ioc.ap_id = (caddr_t)(uintptr_t)ioc32.ap_id;
2940Sstevel@tonic-gate ioc.ap_id_len = (uint_t)ioc32.ap_id_len;
2950Sstevel@tonic-gate ioc.misc_arg = (uint_t)ioc32.misc_arg;
2960Sstevel@tonic-gate }
2970Sstevel@tonic-gate #else
2980Sstevel@tonic-gate if (ddi_copyin((void *)arg, &ioc, sizeof (ioc),
2990Sstevel@tonic-gate mode) != 0) {
3000Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
3010Sstevel@tonic-gate "%s: ddi_copyin 2 failed", msg);
3020Sstevel@tonic-gate rv = EFAULT;
3030Sstevel@tonic-gate break;
3040Sstevel@tonic-gate }
3050Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: \n\tioc: cmd=%x buf=%p, "
3080Sstevel@tonic-gate "bufsiz=%d", msg, ioc.cmd, ioc.buf, ioc.bufsiz);
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate /*
3110Sstevel@tonic-gate * figure out ap_id name as passed from user-land
3120Sstevel@tonic-gate * NOTE: We don't need to figure out ap_id for these
3130Sstevel@tonic-gate * two sub-commands:-
3140Sstevel@tonic-gate * IBNEX_NUM_DEVICE_NODES, IBNEX_NUM_HCA_NODES
3150Sstevel@tonic-gate *
3160Sstevel@tonic-gate * Hence, In user-land, these two ioctls force "ap_id_len" to 0.
3170Sstevel@tonic-gate */
3180Sstevel@tonic-gate if (ioc.ap_id_len > 0) {
3190Sstevel@tonic-gate apid_alloced = B_TRUE;
3200Sstevel@tonic-gate apid_len = ioc.ap_id_len + 1;
3210Sstevel@tonic-gate apid_n = kmem_zalloc(apid_len, KM_SLEEP);
3220Sstevel@tonic-gate if (ddi_copyin((void *)ioc.ap_id, apid_n,
3230Sstevel@tonic-gate ioc.ap_id_len, mode) != 0) {
3240Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
3250Sstevel@tonic-gate "%s: ddi_copyin err 3", msg);
3260Sstevel@tonic-gate rv = EFAULT;
3270Sstevel@tonic-gate break;
3280Sstevel@tonic-gate }
3290Sstevel@tonic-gate
3300Sstevel@tonic-gate IBTF_DPRINTF_L3("ibnex", "%s: apid_n= %s", msg, apid_n);
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate /* process sub-commands */
3350Sstevel@tonic-gate switch (ioc.cmd) {
3360Sstevel@tonic-gate case IBNEX_NUM_DEVICE_NODES:
3379879SRamaswamy.Tummala@Sun.COM msg = "\tdevctl: DEVCTL_AP_CONTROL: NUM_DEVICE_NODES";
3380Sstevel@tonic-gate
3390Sstevel@tonic-gate /*
3400Sstevel@tonic-gate * figure out how many IOC, VPPA,
3410Sstevel@tonic-gate * Pseudo and Port nodes are present
3420Sstevel@tonic-gate */
3430Sstevel@tonic-gate num_nodes = ibnex_get_num_devices();
3440Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: num_nodes = %d",
3450Sstevel@tonic-gate msg, num_nodes);
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate if (ddi_copyout(&num_nodes, ioc.buf,
3480Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
3490Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: copyout", msg);
3500Sstevel@tonic-gate rv = EIO;
3510Sstevel@tonic-gate }
3520Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
3530Sstevel@tonic-gate return (rv);
3540Sstevel@tonic-gate
3550Sstevel@tonic-gate case IBNEX_NUM_HCA_NODES:
3569879SRamaswamy.Tummala@Sun.COM msg = "\tdevctl: DEVCTL_AP_CONTROL: NUM_HCA_NODES";
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate /* figure out how many HCAs are present in the host */
3590Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
3600Sstevel@tonic-gate num_hcas = ibt_get_hca_list(NULL);
3610Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: num %d", msg, num_hcas);
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate if (ddi_copyout(&num_hcas, ioc.buf,
3640Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
3650Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: copyout", msg);
3660Sstevel@tonic-gate rv = EIO;
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate return (rv);
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate case IBNEX_UPDATE_PKEY_TBLS:
3719879SRamaswamy.Tummala@Sun.COM msg = "\tdevctl: DEVCTL_AP_CONTROL: UPDATE_PKEY_TBLS";
3720Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s", msg);
3730Sstevel@tonic-gate
3740Sstevel@tonic-gate /*
3750Sstevel@tonic-gate * update P_Key tables:
3760Sstevel@tonic-gate * ibdm_ibnex_update_pkey_tbls() calls
3770Sstevel@tonic-gate * ibt_query_hca_ports_byguids() for all the
3780Sstevel@tonic-gate * HCAs that the IBDM has "seen" in the system.
3790Sstevel@tonic-gate * This ends up updating the IBTL P_Key database.
3800Sstevel@tonic-gate * NOTE: Changes in this area will break this
3810Sstevel@tonic-gate * assumption. Initially the plan was to call
3820Sstevel@tonic-gate * ibt_query_hca_ports_byguids() in IBTL but
3830Sstevel@tonic-gate * IBDM needs to call it as well. So, eliminating
3840Sstevel@tonic-gate * the first invocation.
3850Sstevel@tonic-gate *
3860Sstevel@tonic-gate * It next updates the DM P_Key database.
3870Sstevel@tonic-gate * Note that the DM P_Key database updating
3880Sstevel@tonic-gate * will always be driven through cfgadm.
3890Sstevel@tonic-gate */
3900Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
3910Sstevel@tonic-gate ibdm_ibnex_update_pkey_tbls();
3920Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
3930Sstevel@tonic-gate break;
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate case IBNEX_GET_SNAPSHOT:
3960Sstevel@tonic-gate case IBNEX_SNAPSHOT_SIZE:
3970Sstevel@tonic-gate msg = (ioc.cmd == IBNEX_SNAPSHOT_SIZE) ?
3989879SRamaswamy.Tummala@Sun.COM "\tdevctl: DEVCTL_AP_CONTROL: IBNEX_SNAPSHOT_SIZE" :
3999879SRamaswamy.Tummala@Sun.COM "\tdevctl: DEVCTL_AP_CONTROL: IBNEX_GET_SNAPSHOT";
4000Sstevel@tonic-gate
4010Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s:", msg);
4020Sstevel@tonic-gate
4030Sstevel@tonic-gate if (ibnex_get_snapshot(&snapshot, &snapshot_sz,
4040Sstevel@tonic-gate ioc.misc_arg) != 0) {
4050Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
4060Sstevel@tonic-gate "%s:\n\tibnex_get_snapshot failed", msg);
4070Sstevel@tonic-gate rv = EIO;
4080Sstevel@tonic-gate break;
4090Sstevel@tonic-gate }
4100Sstevel@tonic-gate
4110Sstevel@tonic-gate /* ssiz needs to be reinitialized again */
4120Sstevel@tonic-gate ssiz = snapshot_sz;
4130Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex",
4140Sstevel@tonic-gate "%s:\n\tsize =%x", msg, snapshot_sz);
4150Sstevel@tonic-gate
4160Sstevel@tonic-gate if (ioc.cmd == IBNEX_SNAPSHOT_SIZE) {
4170Sstevel@tonic-gate if (ddi_copyout(&ssiz, ioc.buf,
4180Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
4190Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
4200Sstevel@tonic-gate "%s:\n\tddi_copyout 2 failed", msg);
4210Sstevel@tonic-gate rv = EFAULT;
4220Sstevel@tonic-gate }
4230Sstevel@tonic-gate
4240Sstevel@tonic-gate } else {
4250Sstevel@tonic-gate if (ioc.bufsiz != snapshot_sz) {
4260Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
4270Sstevel@tonic-gate "%s:\n\tinvalid buffer size (%x %x)"
4280Sstevel@tonic-gate " ", msg, ioc.bufsiz, snapshot_sz);
4290Sstevel@tonic-gate rv = EINVAL;
4300Sstevel@tonic-gate
4310Sstevel@tonic-gate } else if (ddi_copyout(snapshot, ioc.buf,
4320Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
4330Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
4340Sstevel@tonic-gate "%s:\n\tddi_copyout 3 failed", msg);
4350Sstevel@tonic-gate rv = EFAULT;
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate
4390Sstevel@tonic-gate kmem_free(snapshot, snapshot_sz);
4400Sstevel@tonic-gate break;
4410Sstevel@tonic-gate
4420Sstevel@tonic-gate case IBNEX_DEVICE_PATH_SZ:
4430Sstevel@tonic-gate case IBNEX_GET_DEVICE_PATH:
4440Sstevel@tonic-gate {
4450Sstevel@tonic-gate char path[MAXPATHLEN];
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate msg = (ioc.cmd == IBNEX_DEVICE_PATH_SZ) ?
4489879SRamaswamy.Tummala@Sun.COM "\tdevctl:DEVCTL_AP_CONTROL: IBNEX_DEVICE_PATH_SZ" :
4499879SRamaswamy.Tummala@Sun.COM "\tdevctl:DEVCTL_AP_CONTROL: IBNEX_GET_DEVICE_PATH";
4500Sstevel@tonic-gate
4510Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: apid = %s", msg, apid_n);
4520Sstevel@tonic-gate
4530Sstevel@tonic-gate /* if this apid is already seen by IBNEX, get the dip */
4540Sstevel@tonic-gate rv = ibnex_get_dip_from_apid(apid_n, &apid_dip, &nodep);
4550Sstevel@tonic-gate if (rv != IBNEX_DYN_APID || apid_dip == NULL) {
4560Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
4570Sstevel@tonic-gate "%s:\n\tget_dip_from_apid failed", msg);
4580Sstevel@tonic-gate rv = EIO;
4590Sstevel@tonic-gate break;
4600Sstevel@tonic-gate }
4610Sstevel@tonic-gate ndi_rele_devi(apid_dip);
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate /* ddi_pathname doesn't supply /devices, so we do. */
4640Sstevel@tonic-gate (void) strcpy(path, "/devices");
4650Sstevel@tonic-gate (void) ddi_pathname(apid_dip, path + strlen(path));
4660Sstevel@tonic-gate ssiz = (uint32_t)strlen(path) + 1;
4670Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex",
4680Sstevel@tonic-gate "%s: len = %x\n\tpath = %s", msg, ssiz, path);
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate /* rv could be something undesirable, so reset it */
4710Sstevel@tonic-gate rv = 0;
4720Sstevel@tonic-gate
4730Sstevel@tonic-gate if (ioc.cmd == IBNEX_DEVICE_PATH_SZ) {
4740Sstevel@tonic-gate if (ddi_copyout(&ssiz, ioc.buf,
4750Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
4760Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
4770Sstevel@tonic-gate "%s: ddi_copyout 4 failed", msg);
4780Sstevel@tonic-gate rv = EFAULT;
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate } else {
4820Sstevel@tonic-gate if (ioc.bufsiz != ssiz) {
4830Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
4840Sstevel@tonic-gate "%s: invalid size (%x, %x)",
4850Sstevel@tonic-gate msg, ioc.bufsiz, ssiz);
4860Sstevel@tonic-gate rv = EINVAL;
4870Sstevel@tonic-gate } else if (ddi_copyout(&path, ioc.buf,
4880Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
4890Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s "
4900Sstevel@tonic-gate "ddi_copyout 5 failed", msg);
4910Sstevel@tonic-gate rv = EFAULT;
4920Sstevel@tonic-gate }
4930Sstevel@tonic-gate }
4940Sstevel@tonic-gate break;
4950Sstevel@tonic-gate }
4960Sstevel@tonic-gate
4970Sstevel@tonic-gate case IBNEX_HCA_LIST_SZ:
4980Sstevel@tonic-gate case IBNEX_HCA_LIST_INFO:
4990Sstevel@tonic-gate msg = (ioc.cmd == IBNEX_HCA_LIST_SZ) ?
5000Sstevel@tonic-gate "DEVCTL_AP_CONTROL: IBNEX_HCA_LIST_SZ" :
5010Sstevel@tonic-gate "DEVCTL_AP_CONTROL: IBNEX_HCA_LIST_INFO";
5020Sstevel@tonic-gate
5030Sstevel@tonic-gate guid_str = strrchr(apid_n, ':') + 1;
5040Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s, input apid = %s, "
5050Sstevel@tonic-gate "guid = %s", msg, apid_n, guid_str);
5060Sstevel@tonic-gate
5070Sstevel@tonic-gate if (guid_str == NULL) {
5080Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid input "
5090Sstevel@tonic-gate "GUID passed %s", msg, guid_str);
5100Sstevel@tonic-gate rv = EFAULT;
5110Sstevel@tonic-gate break;
5120Sstevel@tonic-gate }
5130Sstevel@tonic-gate
5140Sstevel@tonic-gate /* Get the GUID(hex value) from apid_n */
5150Sstevel@tonic-gate hca_guid = ibnex_str2hex(guid_str, strlen(guid_str),
5160Sstevel@tonic-gate &ret);
5170Sstevel@tonic-gate if (ret != IBNEX_SUCCESS) {
5180Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: Invalid HCA "
5190Sstevel@tonic-gate "GUID string", msg);
5200Sstevel@tonic-gate rv = EIO;
5210Sstevel@tonic-gate break;
5220Sstevel@tonic-gate }
5230Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s HCA GUID = %llX",
5240Sstevel@tonic-gate msg, hca_guid);
5250Sstevel@tonic-gate if (ibtl_ibnex_get_hca_info(hca_guid,
5260Sstevel@tonic-gate IBTL_IBNEX_LIST_CLNTS_FLAG, &snapshot, &snapshot_sz,
5270Sstevel@tonic-gate ibnex_return_apid) != IBT_SUCCESS) {
5280Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
5290Sstevel@tonic-gate "%s: get HCA consumers failed", msg);
5300Sstevel@tonic-gate rv = EIO;
5310Sstevel@tonic-gate break;
5320Sstevel@tonic-gate }
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate ssiz = snapshot_sz;
5350Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: size =%x", msg, ssiz);
5360Sstevel@tonic-gate
5370Sstevel@tonic-gate if (ioc.cmd == IBNEX_HCA_LIST_SZ) {
5380Sstevel@tonic-gate if (ddi_copyout(&ssiz, ioc.buf,
5390Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
5400Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
5410Sstevel@tonic-gate "%s: ddi_copyout 6 failed", msg);
5420Sstevel@tonic-gate rv = EFAULT;
5430Sstevel@tonic-gate }
5440Sstevel@tonic-gate } else {
5450Sstevel@tonic-gate if (ioc.bufsiz != ssiz) {
5460Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid "
5470Sstevel@tonic-gate "size (%x, %x)", msg, ioc.bufsiz,
5480Sstevel@tonic-gate ssiz);
5490Sstevel@tonic-gate rv = EINVAL;
5500Sstevel@tonic-gate } else if (ddi_copyout(snapshot, ioc.buf,
5510Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
5520Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s "
5530Sstevel@tonic-gate "ddi_copyout 7 failed", msg);
5540Sstevel@tonic-gate rv = EFAULT;
5550Sstevel@tonic-gate }
5560Sstevel@tonic-gate }
5570Sstevel@tonic-gate
5580Sstevel@tonic-gate kmem_free(snapshot, snapshot_sz);
5590Sstevel@tonic-gate break;
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate case IBNEX_UNCFG_CLNTS_SZ:
5620Sstevel@tonic-gate case IBNEX_UNCFG_CLNTS_INFO:
5630Sstevel@tonic-gate msg = (ioc.cmd == IBNEX_UNCFG_CLNTS_SZ) ?
5649879SRamaswamy.Tummala@Sun.COM "\tdevctl:DEVCTL_AP_CONTROL: IBNEX_UNCFG_CLNTS_SZ" :
5659879SRamaswamy.Tummala@Sun.COM "\tdevctl:DEVCTL_AP_CONTROL: "
5669879SRamaswamy.Tummala@Sun.COM "IBNEX_UNCFG_CLNTS_INFO";
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate guid_str = strrchr(apid_n, ':') + 1;
5690Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s, apid = %s, guid = %s",
5700Sstevel@tonic-gate msg, apid_n, guid_str);
5710Sstevel@tonic-gate
5720Sstevel@tonic-gate if (guid_str == NULL) {
5730Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid input "
5740Sstevel@tonic-gate "GUID %s", msg, guid_str);
5750Sstevel@tonic-gate rv = EFAULT;
5760Sstevel@tonic-gate break;
5770Sstevel@tonic-gate }
5780Sstevel@tonic-gate
5790Sstevel@tonic-gate /* Get the GUID(hex value) from apid_n */
5800Sstevel@tonic-gate hca_guid = ibnex_str2hex(guid_str, strlen(guid_str),
5810Sstevel@tonic-gate &ret);
5820Sstevel@tonic-gate if (ret != IBNEX_SUCCESS) {
5830Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: Invalid HCA "
5840Sstevel@tonic-gate "GUID string passed", msg);
5850Sstevel@tonic-gate rv = EIO;
5860Sstevel@tonic-gate break;
5870Sstevel@tonic-gate }
5880Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s G = %llX", msg, hca_guid);
5890Sstevel@tonic-gate if (ibtl_ibnex_get_hca_info(hca_guid,
5900Sstevel@tonic-gate IBTL_IBNEX_UNCFG_CLNTS_FLAG, &snapshot,
5910Sstevel@tonic-gate &snapshot_sz, ibnex_return_apid) != IBT_SUCCESS) {
5920Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
5930Sstevel@tonic-gate "%s: get HCA consumers failed", msg);
5940Sstevel@tonic-gate rv = EIO;
5950Sstevel@tonic-gate break;
5960Sstevel@tonic-gate }
5970Sstevel@tonic-gate /* ssiz needs to be reinitialized again */
5980Sstevel@tonic-gate ssiz = snapshot_sz;
5990Sstevel@tonic-gate
6000Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: size =%x", msg, ssiz);
6010Sstevel@tonic-gate
6020Sstevel@tonic-gate if (ioc.cmd == IBNEX_UNCFG_CLNTS_SZ) {
6030Sstevel@tonic-gate if (ddi_copyout(&ssiz, ioc.buf,
6040Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
6050Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
6060Sstevel@tonic-gate "%s: ddi_copyout 9 failed", msg);
6070Sstevel@tonic-gate rv = EFAULT;
6080Sstevel@tonic-gate }
6090Sstevel@tonic-gate
6100Sstevel@tonic-gate } else {
6110Sstevel@tonic-gate if (ioc.bufsiz != ssiz) {
6120Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
6130Sstevel@tonic-gate "%s: invalid size (%x, %x)",
6140Sstevel@tonic-gate msg, ioc.bufsiz, ssiz);
6150Sstevel@tonic-gate rv = EINVAL;
6160Sstevel@tonic-gate } else if (ddi_copyout(snapshot, ioc.buf,
6170Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
6180Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s "
6190Sstevel@tonic-gate "ddi_copyout 10 failed", msg);
6200Sstevel@tonic-gate rv = EFAULT;
6210Sstevel@tonic-gate }
6220Sstevel@tonic-gate }
6230Sstevel@tonic-gate
6240Sstevel@tonic-gate kmem_free(snapshot, snapshot_sz);
6250Sstevel@tonic-gate break;
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate case IBNEX_CONF_ENTRY_ADD:
6289879SRamaswamy.Tummala@Sun.COM msg = "\tdevctl: IBNEX_CONF_ENTRY_ADD: ";
6290Sstevel@tonic-gate service = kmem_zalloc(ioc.bufsiz + 1, KM_SLEEP);
6300Sstevel@tonic-gate /* read in the "service" name */
6310Sstevel@tonic-gate if (ddi_copyin(ioc.buf, service,
6320Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
6330Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: ddi_copyin err 6",
6340Sstevel@tonic-gate msg);
6350Sstevel@tonic-gate rv = EFAULT;
6360Sstevel@tonic-gate break;
6370Sstevel@tonic-gate }
6380Sstevel@tonic-gate
6390Sstevel@tonic-gate /* read in the "service type" */
6400Sstevel@tonic-gate svc_type = ioc.misc_arg;
6410Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: service = %s, type = %d",
6420Sstevel@tonic-gate msg, service, svc_type);
6430Sstevel@tonic-gate
6440Sstevel@tonic-gate if (svc_type == IB_PORT_SERVICE) {
6450Sstevel@tonic-gate ibnex_port_conf_entry_add(service);
6460Sstevel@tonic-gate } else if (svc_type == IB_VPPA_SERVICE) {
6470Sstevel@tonic-gate ibnex_vppa_conf_entry_add(service);
6480Sstevel@tonic-gate } else if (svc_type == IB_HCASVC_SERVICE) {
6490Sstevel@tonic-gate ibnex_hcasvc_conf_entry_add(service);
6500Sstevel@tonic-gate }
6510Sstevel@tonic-gate kmem_free(service, ioc.bufsiz + 1);
6520Sstevel@tonic-gate break;
6530Sstevel@tonic-gate
6540Sstevel@tonic-gate case IBNEX_CONF_ENTRY_DEL:
6559879SRamaswamy.Tummala@Sun.COM msg = "\tdevctl:IBNEX_CONF_ENTRY_DEL: ";
6560Sstevel@tonic-gate service = kmem_zalloc(ioc.bufsiz + 1, KM_SLEEP);
6570Sstevel@tonic-gate /* read in the "service" name */
6580Sstevel@tonic-gate if (ddi_copyin(ioc.buf, service,
6590Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
6600Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: ddi_copyin err 7",
6610Sstevel@tonic-gate msg);
6620Sstevel@tonic-gate rv = EFAULT;
6630Sstevel@tonic-gate break;
6640Sstevel@tonic-gate }
6650Sstevel@tonic-gate
6660Sstevel@tonic-gate /* read in the "service type" */
6670Sstevel@tonic-gate svc_type = ioc.misc_arg;
6680Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: service = %s, type = %d",
6690Sstevel@tonic-gate msg, service, svc_type);
6700Sstevel@tonic-gate
6710Sstevel@tonic-gate if (svc_type == IB_PORT_SERVICE) {
6720Sstevel@tonic-gate rv = ibnex_port_conf_entry_delete(msg, service);
6730Sstevel@tonic-gate } else if (svc_type == IB_VPPA_SERVICE) {
6740Sstevel@tonic-gate rv = ibnex_vppa_conf_entry_delete(msg, service);
6750Sstevel@tonic-gate } else if (svc_type == IB_HCASVC_SERVICE) {
6760Sstevel@tonic-gate rv = ibnex_hcasvc_conf_entry_delete(msg,
6770Sstevel@tonic-gate service);
6780Sstevel@tonic-gate }
6790Sstevel@tonic-gate kmem_free(service, ioc.bufsiz + 1);
6800Sstevel@tonic-gate break;
6810Sstevel@tonic-gate
6820Sstevel@tonic-gate case IBNEX_HCA_VERBOSE_SZ:
6830Sstevel@tonic-gate case IBNEX_HCA_VERBOSE_INFO:
6840Sstevel@tonic-gate msg = (ioc.cmd == IBNEX_HCA_VERBOSE_SZ) ?
6850Sstevel@tonic-gate "DEVCTL_AP_CONTROL: IBNEX_HCA_VERBOSE_SZ" :
6860Sstevel@tonic-gate "DEVCTL_AP_CONTROL: IBNEX_HCA_VERBOSE_INFO";
6870Sstevel@tonic-gate
6880Sstevel@tonic-gate guid_str = strrchr(apid_n, ':') + 1;
6890Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s, apid = %s, guid = %s",
6900Sstevel@tonic-gate msg, apid_n, guid_str);
6910Sstevel@tonic-gate
6920Sstevel@tonic-gate if (guid_str == NULL) {
6930Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid GUID %s",
6940Sstevel@tonic-gate msg, guid_str);
6950Sstevel@tonic-gate rv = EFAULT;
6960Sstevel@tonic-gate break;
6970Sstevel@tonic-gate }
6980Sstevel@tonic-gate
6990Sstevel@tonic-gate /* Get the GUID(hex value) from apid_n */
7000Sstevel@tonic-gate hca_guid = ibnex_str2hex(guid_str, strlen(guid_str),
7010Sstevel@tonic-gate &ret);
7020Sstevel@tonic-gate if (ret != IBNEX_SUCCESS) {
7030Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: Invalid HCA GUID "
7040Sstevel@tonic-gate "string", msg);
7050Sstevel@tonic-gate rv = EIO;
7060Sstevel@tonic-gate break;
7070Sstevel@tonic-gate }
7080Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s HCA GUID = 0x%llX",
7090Sstevel@tonic-gate msg, hca_guid);
7100Sstevel@tonic-gate
7110Sstevel@tonic-gate if (ibtl_ibnex_get_hca_verbose_data(hca_guid, &snapshot,
7120Sstevel@tonic-gate &snapshot_sz) != IBT_SUCCESS) {
7130Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: get HCA verbose "
7140Sstevel@tonic-gate "data failed", msg);
7150Sstevel@tonic-gate rv = EIO;
7160Sstevel@tonic-gate break;
7170Sstevel@tonic-gate }
7180Sstevel@tonic-gate
7190Sstevel@tonic-gate ssiz = snapshot_sz;
7200Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: size =%x", msg, ssiz);
7210Sstevel@tonic-gate
7220Sstevel@tonic-gate if (ioc.cmd == IBNEX_HCA_VERBOSE_SZ) {
7230Sstevel@tonic-gate if (ddi_copyout(&ssiz, ioc.buf,
7240Sstevel@tonic-gate ioc.bufsiz, mode) != 0) {
7250Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
7260Sstevel@tonic-gate "%s: ddi_copyout 11 failed", msg);
7270Sstevel@tonic-gate rv = EFAULT;
7280Sstevel@tonic-gate }
7290Sstevel@tonic-gate } else {
7300Sstevel@tonic-gate if (ioc.bufsiz != ssiz) {
7310Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
7320Sstevel@tonic-gate "%s: invalid size (%x, %x)",
7330Sstevel@tonic-gate msg, ioc.bufsiz, ssiz);
7340Sstevel@tonic-gate rv = EINVAL;
7350Sstevel@tonic-gate } else if (ddi_copyout(snapshot,
7360Sstevel@tonic-gate ioc.buf, ioc.bufsiz, mode) != 0) {
7370Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s "
7380Sstevel@tonic-gate "ddi_copyout 12 failed", msg);
7390Sstevel@tonic-gate rv = EFAULT;
7400Sstevel@tonic-gate }
7410Sstevel@tonic-gate }
7420Sstevel@tonic-gate
7430Sstevel@tonic-gate kmem_free(snapshot, snapshot_sz);
7440Sstevel@tonic-gate break;
7450Sstevel@tonic-gate
7460Sstevel@tonic-gate case IBNEX_UPDATE_IOC_CONF :
7479879SRamaswamy.Tummala@Sun.COM msg = "\tdevctl:IBNEX_UPDATE_IOC_CONF: ";
7480Sstevel@tonic-gate
7490Sstevel@tonic-gate /*
7500Sstevel@tonic-gate * If IB fabric APID, call ibnex_update_all
7510Sstevel@tonic-gate * If IOC APID, get the apid dip and call
7520Sstevel@tonic-gate * ibnex_update_ioc
7530Sstevel@tonic-gate */
7540Sstevel@tonic-gate if (ioc.misc_arg == IBNEX_BASE_APID) {
7550Sstevel@tonic-gate /*
7560Sstevel@tonic-gate * If reprobe is in progress or another reprobe
7570Sstevel@tonic-gate * is already waiting, wait.
7580Sstevel@tonic-gate */
7590Sstevel@tonic-gate if (ibnex.ibnex_reprobe_state != 0) {
7600Sstevel@tonic-gate if (ibnex.ibnex_reprobe_state ==
7610Sstevel@tonic-gate IBNEX_REPROBE_ALL_PROGRESS)
7620Sstevel@tonic-gate ibnex.ibnex_reprobe_state =
7630Sstevel@tonic-gate IBNEX_REPROBE_ALL_WAIT;
7640Sstevel@tonic-gate while (ibnex.ibnex_reprobe_state) {
7650Sstevel@tonic-gate cv_wait(&ibnex.ibnex_reprobe_cv,
7660Sstevel@tonic-gate &ibnex.ibnex_mutex);
7670Sstevel@tonic-gate }
7680Sstevel@tonic-gate
7690Sstevel@tonic-gate /*
7700Sstevel@tonic-gate * Pending reprobe all completed, return
7710Sstevel@tonic-gate */
7720Sstevel@tonic-gate break;
7730Sstevel@tonic-gate }
7740Sstevel@tonic-gate
7750Sstevel@tonic-gate /* Check if reprobe for any IOC is pending */
7760Sstevel@tonic-gate /* CONSTCOND */
7770Sstevel@tonic-gate while (1) {
7780Sstevel@tonic-gate ioc_reprobe_pending = 0;
7790Sstevel@tonic-gate for (scanp = ibnex.ibnex_ioc_node_head;
7800Sstevel@tonic-gate scanp;
7810Sstevel@tonic-gate scanp = scanp->node_next) {
7820Sstevel@tonic-gate if (scanp->node_reprobe_state
7830Sstevel@tonic-gate != 0) {
7840Sstevel@tonic-gate ioc_reprobe_pending =
7850Sstevel@tonic-gate 1;
7860Sstevel@tonic-gate break;
7870Sstevel@tonic-gate }
7880Sstevel@tonic-gate }
7890Sstevel@tonic-gate if (ioc_reprobe_pending == 0) {
7900Sstevel@tonic-gate ibnex.ibnex_reprobe_state &=
7910Sstevel@tonic-gate ~IBNEX_REPROBE_IOC_WAIT;
7920Sstevel@tonic-gate break;
7930Sstevel@tonic-gate }
7940Sstevel@tonic-gate
7950Sstevel@tonic-gate ibnex.ibnex_reprobe_state =
7960Sstevel@tonic-gate IBNEX_REPROBE_IOC_WAIT;
7970Sstevel@tonic-gate cv_wait(&ibnex.ibnex_reprobe_cv,
7980Sstevel@tonic-gate &ibnex.ibnex_mutex);
7990Sstevel@tonic-gate }
8000Sstevel@tonic-gate
8010Sstevel@tonic-gate /*
8020Sstevel@tonic-gate * Set the REPROBE_ALL_PROGRESS state &
8030Sstevel@tonic-gate * start reprobe
8040Sstevel@tonic-gate */
8050Sstevel@tonic-gate ibnex.ibnex_reprobe_state =
8060Sstevel@tonic-gate IBNEX_REPROBE_ALL_PROGRESS;
8070Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
8080Sstevel@tonic-gate ibnex_reprobe_ioc_all();
8090Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
8100Sstevel@tonic-gate } else if (ioc.misc_arg == IBNEX_DYN_APID) {
8110Sstevel@tonic-gate rv = ibnex_get_dip_from_apid(apid_n, &apid_dip,
8120Sstevel@tonic-gate &nodep);
8130Sstevel@tonic-gate ASSERT(rv == IBNEX_DYN_APID);
8140Sstevel@tonic-gate
8150Sstevel@tonic-gate /* Device unconfigured: return */
8160Sstevel@tonic-gate if (apid_dip == NULL)
8170Sstevel@tonic-gate break;
8180Sstevel@tonic-gate
8190Sstevel@tonic-gate ndi_rele_devi(apid_dip);
8200Sstevel@tonic-gate /* Reset return value back to 0 */
8210Sstevel@tonic-gate rv = 0;
8220Sstevel@tonic-gate if (ibnex.ibnex_reprobe_state != 0 ||
8230Sstevel@tonic-gate nodep->node_reprobe_state != 0) {
8240Sstevel@tonic-gate while (ibnex.ibnex_reprobe_state != 0 &&
8250Sstevel@tonic-gate nodep->node_reprobe_state != 0) {
8260Sstevel@tonic-gate cv_wait(&ibnex.ibnex_reprobe_cv,
8270Sstevel@tonic-gate &ibnex.ibnex_mutex);
8280Sstevel@tonic-gate }
8290Sstevel@tonic-gate /* Pending reprobe completed, return */
8300Sstevel@tonic-gate break;
8310Sstevel@tonic-gate }
8320Sstevel@tonic-gate
8330Sstevel@tonic-gate /* Set node_reprobe_state and start reprobe */
8340Sstevel@tonic-gate nodep->node_reprobe_state =
8350Sstevel@tonic-gate IBNEX_NODE_REPROBE_NOTIFY_ON_UPDATE;
8360Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
8370Sstevel@tonic-gate ibnex_reprobe_ioc_dev((void *)apid_dip);
8380Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
8390Sstevel@tonic-gate } else {
8400Sstevel@tonic-gate rv = EINVAL;
8410Sstevel@tonic-gate }
8420Sstevel@tonic-gate
8430Sstevel@tonic-gate break;
8440Sstevel@tonic-gate
8450Sstevel@tonic-gate default:
8460Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
8470Sstevel@tonic-gate "DEVCTL_AP_CONTROL: ioc:unknown cmd = %x", ioc.cmd);
8480Sstevel@tonic-gate break;
8490Sstevel@tonic-gate }
8500Sstevel@tonic-gate }
8510Sstevel@tonic-gate break;
8520Sstevel@tonic-gate
8530Sstevel@tonic-gate case DEVCTL_AP_UNCONFIGURE:
8540Sstevel@tonic-gate msg = "DEVCTL_AP_UNCONFIGURE";
8550Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s", msg);
8560Sstevel@tonic-gate
8570Sstevel@tonic-gate /* Check for write permissions */
8580Sstevel@tonic-gate if (!(mode & FWRITE)) {
8590Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid mode %x",
8600Sstevel@tonic-gate msg, mode);
8610Sstevel@tonic-gate rv = EPERM;
8620Sstevel@tonic-gate break;
8630Sstevel@tonic-gate }
8640Sstevel@tonic-gate
8650Sstevel@tonic-gate if ((apid_n = ibnex_get_apid(dcp)) == '\0') {
8660Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
8670Sstevel@tonic-gate "%s: ibnex_get_apid failed", msg);
8680Sstevel@tonic-gate rv = EIO;
8690Sstevel@tonic-gate break;
8700Sstevel@tonic-gate }
8710Sstevel@tonic-gate
8720Sstevel@tonic-gate /*
8730Sstevel@tonic-gate * If this apid is already seen by IBNEX, get the dip
8740Sstevel@tonic-gate * NOTE: ibnex_get_dip_from_apid() finds a valid dip
8750Sstevel@tonic-gate * and also does a ndi_devi_hold() on the child.
8760Sstevel@tonic-gate */
8770Sstevel@tonic-gate rv = ibnex_get_dip_from_apid(apid_n, &apid_dip, &nodep);
8780Sstevel@tonic-gate if ((rv != IBNEX_DYN_APID) || (apid_dip == NULL)) {
8790Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: get_dip_from_apid "
8800Sstevel@tonic-gate "failed with 0x%x", msg, rv);
8810Sstevel@tonic-gate rv = EIO;
8820Sstevel@tonic-gate break;
8830Sstevel@tonic-gate }
8840Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s: DIP = %p", msg, apid_dip);
8850Sstevel@tonic-gate
8860Sstevel@tonic-gate /* Check if it is a valid node type? */
8870Sstevel@tonic-gate if (!IBNEX_VALID_NODE_TYPE(nodep)) {
8880Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid IB node", msg);
8890Sstevel@tonic-gate rv = ENODEV;
8900Sstevel@tonic-gate ndi_rele_devi(apid_dip);
8910Sstevel@tonic-gate break;
8920Sstevel@tonic-gate }
8930Sstevel@tonic-gate
8940Sstevel@tonic-gate /*
8950Sstevel@tonic-gate * continue unconfigure operation, only if device node
8960Sstevel@tonic-gate * is already configured. Return EBUSY if another
8970Sstevel@tonic-gate * configure/unconfigure operation is in progress.
8980Sstevel@tonic-gate */
8990Sstevel@tonic-gate if (nodep->node_state == IBNEX_CFGADM_CONFIGURING ||
9000Sstevel@tonic-gate nodep->node_state == IBNEX_CFGADM_UNCONFIGURING) {
9010Sstevel@tonic-gate rv = EBUSY;
9020Sstevel@tonic-gate ndi_rele_devi(apid_dip);
9030Sstevel@tonic-gate break;
9040Sstevel@tonic-gate }
9050Sstevel@tonic-gate
9060Sstevel@tonic-gate /* do this before to avoid races */
9070Sstevel@tonic-gate nodep->node_dip = NULL;
9080Sstevel@tonic-gate nodep->node_state = IBNEX_CFGADM_UNCONFIGURING;
9090Sstevel@tonic-gate
9100Sstevel@tonic-gate /*
9110Sstevel@tonic-gate * Call devfs_clean first
9120Sstevel@tonic-gate * NOTE: The code so far is protected by holding ibnex_mutex
9130Sstevel@tonic-gate * and by doing a ndi_devi_hold() on the child.
9140Sstevel@tonic-gate */
9150Sstevel@tonic-gate pdip = ddi_get_parent(apid_dip);
9160Sstevel@tonic-gate if (i_ddi_node_state(apid_dip) >= DS_INITIALIZED) {
9170Sstevel@tonic-gate devnm = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
9180Sstevel@tonic-gate (void) ddi_deviname(apid_dip, devnm);
9190Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
9204411Svikram (void) devfs_clean(pdip, devnm + 1, DV_CLEAN_FORCE);
9210Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
9220Sstevel@tonic-gate kmem_free(devnm, MAXNAMELEN + 1);
9230Sstevel@tonic-gate }
9240Sstevel@tonic-gate
9250Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
9260Sstevel@tonic-gate ndi_devi_enter(pdip, &circ);
9270Sstevel@tonic-gate ndi_rele_devi(apid_dip);
9280Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
9290Sstevel@tonic-gate
9300Sstevel@tonic-gate /* unconfigure the Port/VPPA/HCA_SVC node */
9310Sstevel@tonic-gate if (IBNEX_COMMSVC_NODE_TYPE(nodep)) {
9320Sstevel@tonic-gate ret_val = ibnex_commsvc_fininode(apid_dip);
9330Sstevel@tonic-gate } else if (nodep->node_type == IBNEX_IOC_NODE) {
9340Sstevel@tonic-gate /* unconfigure the IOC node */
9350Sstevel@tonic-gate ret_val = ibnex_ioc_fininode(apid_dip,
9360Sstevel@tonic-gate &nodep->node_data.ioc_node);
9370Sstevel@tonic-gate } else if (nodep->node_type == IBNEX_PSEUDO_NODE) {
9380Sstevel@tonic-gate /* unconfigure the pseudo node */
9390Sstevel@tonic-gate ret_val = ibnex_pseudo_fininode(apid_dip);
9400Sstevel@tonic-gate }
9410Sstevel@tonic-gate
9420Sstevel@tonic-gate /* reset upon failure */
9430Sstevel@tonic-gate if (ret_val != IBNEX_SUCCESS) {
9440Sstevel@tonic-gate nodep->node_dip = apid_dip;
9450Sstevel@tonic-gate nodep->node_state = IBNEX_CFGADM_CONFIGURED;
9468082SRamaswamy.Tummala@Sun.COM } else {
9470Sstevel@tonic-gate nodep->node_state = IBNEX_CFGADM_UNCONFIGURED;
9488082SRamaswamy.Tummala@Sun.COM nodep->node_ap_state = IBNEX_NODE_AP_UNCONFIGURED;
9498082SRamaswamy.Tummala@Sun.COM }
9500Sstevel@tonic-gate
9510Sstevel@tonic-gate rv = (ret_val != IBNEX_SUCCESS) ? EIO : 0;
9520Sstevel@tonic-gate ndi_devi_exit(pdip, circ);
9530Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: DONE !! It %s", msg,
9540Sstevel@tonic-gate rv ? "failed" : "succeeded");
9550Sstevel@tonic-gate break;
9560Sstevel@tonic-gate
9570Sstevel@tonic-gate case DEVCTL_AP_CONFIGURE:
9580Sstevel@tonic-gate msg = "DEVCTL_AP_CONFIGURE";
9590Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "%s", msg);
9600Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
9610Sstevel@tonic-gate ndi_devi_enter(ibnex.ibnex_dip, &circ);
9620Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
9630Sstevel@tonic-gate
9640Sstevel@tonic-gate /* Check for write permissions */
9650Sstevel@tonic-gate if (!(mode & FWRITE)) {
9660Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid mode %x",
9670Sstevel@tonic-gate msg, mode);
9680Sstevel@tonic-gate rv = EPERM;
9690Sstevel@tonic-gate ndi_devi_exit(ibnex.ibnex_dip, circ);
9700Sstevel@tonic-gate break;
9710Sstevel@tonic-gate }
9720Sstevel@tonic-gate
9730Sstevel@tonic-gate if ((apid_n = ibnex_get_apid(dcp)) == '\0') {
9740Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
9750Sstevel@tonic-gate "%s: ibnex_get_apid failed", msg);
9760Sstevel@tonic-gate rv = EIO;
9770Sstevel@tonic-gate ndi_devi_exit(ibnex.ibnex_dip, circ);
9780Sstevel@tonic-gate break;
9790Sstevel@tonic-gate }
9800Sstevel@tonic-gate
9810Sstevel@tonic-gate /*
9828082SRamaswamy.Tummala@Sun.COM * Let's get the node if it already exists.
9838082SRamaswamy.Tummala@Sun.COM * NOTE: ibnex_get_dip_from_apid() finds a valid dip
9848082SRamaswamy.Tummala@Sun.COM * and also does a ndi_devi_hold() on the child.
9858082SRamaswamy.Tummala@Sun.COM */
9868082SRamaswamy.Tummala@Sun.COM nodep = NULL;
9878082SRamaswamy.Tummala@Sun.COM ret_val = ibnex_get_dip_from_apid(apid_n, &apid_dip, &nodep);
9888082SRamaswamy.Tummala@Sun.COM /*
9898082SRamaswamy.Tummala@Sun.COM * We need the node_data but not the dip. If we get a dip for
9908082SRamaswamy.Tummala@Sun.COM * this apid, it means it's already configured. We need to
9918082SRamaswamy.Tummala@Sun.COM * return.
9928082SRamaswamy.Tummala@Sun.COM */
9938082SRamaswamy.Tummala@Sun.COM if (apid_dip != NULL) {
9948082SRamaswamy.Tummala@Sun.COM ndi_rele_devi(apid_dip);
9958082SRamaswamy.Tummala@Sun.COM ndi_devi_exit(ibnex.ibnex_dip, circ);
9968082SRamaswamy.Tummala@Sun.COM rv = 0;
9978082SRamaswamy.Tummala@Sun.COM break;
9988082SRamaswamy.Tummala@Sun.COM }
9998082SRamaswamy.Tummala@Sun.COM
10008082SRamaswamy.Tummala@Sun.COM /*
10018082SRamaswamy.Tummala@Sun.COM * A node exits for this apid but not a dip. So we must have
10028082SRamaswamy.Tummala@Sun.COM * unconfigured it earlier. Set the node_ap_state to configuring
10038082SRamaswamy.Tummala@Sun.COM * to allow configure operation.
10048082SRamaswamy.Tummala@Sun.COM */
10058082SRamaswamy.Tummala@Sun.COM if (nodep != NULL) {
10068082SRamaswamy.Tummala@Sun.COM nodep->node_ap_state = IBNEX_NODE_AP_CONFIGURING;
10078082SRamaswamy.Tummala@Sun.COM }
10088082SRamaswamy.Tummala@Sun.COM
10098082SRamaswamy.Tummala@Sun.COM
10108082SRamaswamy.Tummala@Sun.COM /*
10110Sstevel@tonic-gate * Five types of APIDs are supported:
10120Sstevel@tonic-gate * o HCA_GUID,0,service-name (HCA-SVC device)
10130Sstevel@tonic-gate * o IOC_GUID (IOC device)
10140Sstevel@tonic-gate * o PORT_GUID,0,service-name (Port device)
10150Sstevel@tonic-gate * o pseudo_name,unit-address, (Pseudo device)
10160Sstevel@tonic-gate * o PORT_GUID,P_Key,service-name (VPPA device)
10170Sstevel@tonic-gate * If the apid doesn't have "," then treat it as an IOC
10180Sstevel@tonic-gate * If the apid has one "," then it is Pseudo device
10190Sstevel@tonic-gate * If the apid has 2 ","s then it is one of the
10200Sstevel@tonic-gate * Port,VPPA,HCA_SVC devices
10210Sstevel@tonic-gate */
10220Sstevel@tonic-gate if (strrchr(apid_n, ',') == NULL) {
10230Sstevel@tonic-gate ret_val = ibnex_handle_ioc_configure(apid_n);
10240Sstevel@tonic-gate } else {
10250Sstevel@tonic-gate char *first = strchr(apid_n, ',');
10260Sstevel@tonic-gate char *second;
10270Sstevel@tonic-gate
10280Sstevel@tonic-gate second = first ? strchr(first + 1, ',') : NULL;
10290Sstevel@tonic-gate if (first != NULL && second == NULL) {
10300Sstevel@tonic-gate ret_val = ibnex_handle_pseudo_configure(apid_n);
10310Sstevel@tonic-gate } else if (first != NULL && second != NULL) {
10320Sstevel@tonic-gate ret_val = ibnex_handle_commsvcnode_configure(
10330Sstevel@tonic-gate apid_n);
10340Sstevel@tonic-gate }
10350Sstevel@tonic-gate } /* end of else */
10360Sstevel@tonic-gate
10378082SRamaswamy.Tummala@Sun.COM if (ret_val != IBNEX_SUCCESS) {
10380Sstevel@tonic-gate rv = (ret_val == IBNEX_BUSY) ? EBUSY : EIO;
10398082SRamaswamy.Tummala@Sun.COM } else {
10408082SRamaswamy.Tummala@Sun.COM /*
10418082SRamaswamy.Tummala@Sun.COM * Get the newly created node and set the state to
10428082SRamaswamy.Tummala@Sun.COM * IBNEX_NODE_AP_CONFIGURED.
10438082SRamaswamy.Tummala@Sun.COM * NOTE: ibnex_get_dip_from_apid() finds a valid dip
10448082SRamaswamy.Tummala@Sun.COM * and also does a ndi_devi_hold() on the child.
10458082SRamaswamy.Tummala@Sun.COM */
10468082SRamaswamy.Tummala@Sun.COM if (!nodep)
10478082SRamaswamy.Tummala@Sun.COM ret_val = ibnex_get_dip_from_apid(apid_n,
10488082SRamaswamy.Tummala@Sun.COM &apid_dip, &nodep);
10498082SRamaswamy.Tummala@Sun.COM if (nodep != NULL) {
10508082SRamaswamy.Tummala@Sun.COM nodep->node_ap_state = IBNEX_NODE_AP_CONFIGURED;
10518082SRamaswamy.Tummala@Sun.COM }
10528082SRamaswamy.Tummala@Sun.COM if (apid_dip != NULL) {
10538082SRamaswamy.Tummala@Sun.COM ndi_rele_devi(apid_dip);
10548082SRamaswamy.Tummala@Sun.COM }
10558082SRamaswamy.Tummala@Sun.COM }
10560Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: DONE !! It %s", msg,
10570Sstevel@tonic-gate rv ? "failed" : "succeeded");
10580Sstevel@tonic-gate ndi_devi_exit(ibnex.ibnex_dip, circ);
10590Sstevel@tonic-gate break;
10600Sstevel@tonic-gate
10610Sstevel@tonic-gate default:
10620Sstevel@tonic-gate rv = EIO;
10630Sstevel@tonic-gate break;
10640Sstevel@tonic-gate }
10650Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
10660Sstevel@tonic-gate
10670Sstevel@tonic-gate if ((apid_alloced == B_TRUE) && (apid_n != NULL)) {
10680Sstevel@tonic-gate kmem_free(apid_n, apid_len);
10690Sstevel@tonic-gate }
10700Sstevel@tonic-gate
10710Sstevel@tonic-gate if (dcp) {
10720Sstevel@tonic-gate ndi_dc_freehdl(dcp);
10730Sstevel@tonic-gate }
10740Sstevel@tonic-gate return (rv);
10750Sstevel@tonic-gate }
10760Sstevel@tonic-gate
10770Sstevel@tonic-gate
10780Sstevel@tonic-gate /*
10790Sstevel@tonic-gate * ibnex_get_num_devices()
10800Sstevel@tonic-gate * Figure out how many IOC, VPPA, Pseudo, HCA_SVC and Port devices exist
10810Sstevel@tonic-gate */
10820Sstevel@tonic-gate static int
ibnex_get_num_devices(void)10830Sstevel@tonic-gate ibnex_get_num_devices(void)
10840Sstevel@tonic-gate {
10850Sstevel@tonic-gate int j, k, l, hca_count;
10860Sstevel@tonic-gate int num_nodes = 0;
10870Sstevel@tonic-gate ibdm_hca_list_t *hca_list, *hcap;
10880Sstevel@tonic-gate ibdm_port_attr_t *pattr;
10890Sstevel@tonic-gate ibnex_node_data_t *nodep;
10900Sstevel@tonic-gate
10910Sstevel@tonic-gate ASSERT(mutex_owned(&ibnex.ibnex_mutex));
10920Sstevel@tonic-gate
10930Sstevel@tonic-gate /* Get a count of HCAs, first. */
10940Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
10950Sstevel@tonic-gate ibdm_ibnex_get_hca_list(&hca_list, &hca_count);
10960Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
10970Sstevel@tonic-gate for (hcap = hca_list; hca_list != NULL; hca_list = hca_list->hl_next) {
10980Sstevel@tonic-gate for (j = 0; j < ibnex.ibnex_nhcasvc_comm_svcs; j++)
10990Sstevel@tonic-gate num_nodes++;
11000Sstevel@tonic-gate for (j = 0; j < hca_list->hl_nports; j++) {
11010Sstevel@tonic-gate for (k = 0; k < ibnex.ibnex_num_comm_svcs; k++)
11020Sstevel@tonic-gate num_nodes++;
11030Sstevel@tonic-gate
11040Sstevel@tonic-gate pattr = &hca_list->hl_port_attr[j];
11050Sstevel@tonic-gate for (k = 0; k < pattr->pa_npkeys; k++) {
11060Sstevel@tonic-gate if (IBNEX_INVALID_PKEY(pattr->pa_pkey_tbl[k].
11070Sstevel@tonic-gate pt_pkey))
11080Sstevel@tonic-gate continue;
11090Sstevel@tonic-gate
11100Sstevel@tonic-gate for (l = 0; l < ibnex.ibnex_nvppa_comm_svcs;
11118082SRamaswamy.Tummala@Sun.COM l++, ++num_nodes)
11128082SRamaswamy.Tummala@Sun.COM ;
11130Sstevel@tonic-gate } /* end of pa_npkeys */
11140Sstevel@tonic-gate } /* end of hl_nports */
11150Sstevel@tonic-gate } /* end of hca_list != NULL */
11160Sstevel@tonic-gate if (hcap)
11170Sstevel@tonic-gate ibdm_ibnex_free_hca_list(hcap);
11180Sstevel@tonic-gate
11190Sstevel@tonic-gate /*
11200Sstevel@tonic-gate * Now figure out how many IOC nodes are present.
11210Sstevel@tonic-gate * Add count of configured "diconnected" IOCs
11220Sstevel@tonic-gate */
11230Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
11240Sstevel@tonic-gate num_nodes += ibdm_ibnex_get_ioc_count();
11250Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
11260Sstevel@tonic-gate num_nodes += ibnex.ibnex_num_disconnect_iocs;
11270Sstevel@tonic-gate
11280Sstevel@tonic-gate /* Last: figure out how many Pseudo nodes are present. */
11290Sstevel@tonic-gate for (nodep = ibnex.ibnex_pseudo_node_head; nodep;
11301093Shiremath nodep = nodep->node_next) {
11311093Shiremath if (nodep->node_data.pseudo_node.pseudo_merge_node == 1)
11321093Shiremath continue;
11331093Shiremath
11341093Shiremath num_nodes++;
11351093Shiremath }
11360Sstevel@tonic-gate return (num_nodes);
11370Sstevel@tonic-gate }
11380Sstevel@tonic-gate
11390Sstevel@tonic-gate
11400Sstevel@tonic-gate /*
11410Sstevel@tonic-gate * ibnex_get_snapshot()
11420Sstevel@tonic-gate * Get a snapshot of all Port/IOC/VPPA/HCA_SVC/Pseudo nodes
11430Sstevel@tonic-gate * Snapshot includes IBNEX_NODE_INFO_NVL, IBNEX_NODE_TYPE_NVL,
11440Sstevel@tonic-gate * IBNEX_NODE_RSTATE_NVL, IBNEX_NODE_OSTATE_NVL and
11450Sstevel@tonic-gate * IBNEX_NODE_COND_NVL
11460Sstevel@tonic-gate */
11470Sstevel@tonic-gate static int
ibnex_get_snapshot(char ** buf,size_t * sz,int allow_probe)11480Sstevel@tonic-gate ibnex_get_snapshot(char **buf, size_t *sz, int allow_probe)
11490Sstevel@tonic-gate {
11500Sstevel@tonic-gate int i, j, k, l, hca_count;
11510Sstevel@tonic-gate nvlist_t *nvl;
11520Sstevel@tonic-gate ib_pkey_t pkey;
11530Sstevel@tonic-gate boolean_t found;
11540Sstevel@tonic-gate ibdm_ioc_info_t *ioc_listp;
11550Sstevel@tonic-gate ibdm_ioc_info_t *iocp;
11560Sstevel@tonic-gate ibdm_hca_list_t *hca_list, *hcap;
11570Sstevel@tonic-gate ibdm_port_attr_t *port_attr;
11580Sstevel@tonic-gate ibnex_node_data_t *nodep;
11590Sstevel@tonic-gate
11600Sstevel@tonic-gate ASSERT(mutex_owned(&ibnex.ibnex_mutex));
11610Sstevel@tonic-gate
11620Sstevel@tonic-gate *buf = NULL;
11630Sstevel@tonic-gate *sz = 0;
11640Sstevel@tonic-gate
11650Sstevel@tonic-gate if (!ibnex.ibnex_pseudo_inited) {
11660Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
11670Sstevel@tonic-gate ibnex_pseudo_initnodes();
11680Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
11690Sstevel@tonic-gate ibnex.ibnex_pseudo_inited = 1;
11700Sstevel@tonic-gate }
11710Sstevel@tonic-gate
11720Sstevel@tonic-gate /* First, Port/VPPA/HCA_SVC nodes */
11730Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
11740Sstevel@tonic-gate ibdm_ibnex_get_hca_list(&hca_list, &hca_count);
11750Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
11760Sstevel@tonic-gate
11770Sstevel@tonic-gate (void) nvlist_alloc(&nvl, 0, KM_SLEEP);
11780Sstevel@tonic-gate
11790Sstevel@tonic-gate /* Go thru all the ports of all the HCAs and all the port-svc indices */
11800Sstevel@tonic-gate for (hcap = hca_list, i = 0; i < hca_count;
11810Sstevel@tonic-gate hca_list = hca_list->hl_next, i++) {
11820Sstevel@tonic-gate
11830Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_get_snapshot: "
11840Sstevel@tonic-gate "fill in COMM service HCA_SVC nodes");
11850Sstevel@tonic-gate port_attr = hca_list->hl_hca_port_attr;
11860Sstevel@tonic-gate for (j = 0; j < ibnex.ibnex_nhcasvc_comm_svcs; j++) {
11870Sstevel@tonic-gate if (ibnex_get_commsvcnode_snapshot(&nvl,
11880Sstevel@tonic-gate port_attr->pa_hca_guid,
11890Sstevel@tonic-gate port_attr->pa_hca_guid, j, (ib_pkey_t)0,
11900Sstevel@tonic-gate IBNEX_HCASVC_COMMSVC_NODE) != 0) {
11910Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
11920Sstevel@tonic-gate "ibnex_get_snapshot: failed to fill"
11930Sstevel@tonic-gate " HCA_SVC device (%x %x)", i, j);
11940Sstevel@tonic-gate ibdm_ibnex_free_hca_list(hcap);
11950Sstevel@tonic-gate nvlist_free(nvl);
11960Sstevel@tonic-gate return (-1);
11970Sstevel@tonic-gate }
11980Sstevel@tonic-gate
11990Sstevel@tonic-gate }
12000Sstevel@tonic-gate
12010Sstevel@tonic-gate for (j = 0; j < hca_list->hl_nports; j++) {
12020Sstevel@tonic-gate port_attr = &hca_list->hl_port_attr[j];
12030Sstevel@tonic-gate
12040Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_get_snapshot: "
12050Sstevel@tonic-gate "fill in COMM service Port nodes");
12060Sstevel@tonic-gate for (k = 0; k < ibnex.ibnex_num_comm_svcs; k++) {
12070Sstevel@tonic-gate
12080Sstevel@tonic-gate if (ibnex_get_commsvcnode_snapshot(&nvl,
12090Sstevel@tonic-gate port_attr->pa_hca_guid,
12100Sstevel@tonic-gate port_attr->pa_port_guid, k, (ib_pkey_t)0,
12110Sstevel@tonic-gate IBNEX_PORT_COMMSVC_NODE) != 0) {
12120Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
12130Sstevel@tonic-gate "ibnex_get_snapshot: failed to fill"
12140Sstevel@tonic-gate " Port device (%x %x %x)", i, j, k);
12150Sstevel@tonic-gate ibdm_ibnex_free_hca_list(hcap);
12160Sstevel@tonic-gate nvlist_free(nvl);
12170Sstevel@tonic-gate return (-1);
12180Sstevel@tonic-gate }
12190Sstevel@tonic-gate
12200Sstevel@tonic-gate } /* end of num_comm_svcs for loop */
12210Sstevel@tonic-gate
12220Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_get_snapshot: "
12230Sstevel@tonic-gate "fill in VPPA service port nodes");
12240Sstevel@tonic-gate for (l = 0; l < port_attr->pa_npkeys; l++) {
12250Sstevel@tonic-gate pkey = port_attr->pa_pkey_tbl[l].pt_pkey;
12260Sstevel@tonic-gate if (IBNEX_INVALID_PKEY(pkey))
12270Sstevel@tonic-gate continue;
12280Sstevel@tonic-gate
12290Sstevel@tonic-gate for (k = 0; k < ibnex.ibnex_nvppa_comm_svcs;
12300Sstevel@tonic-gate k++) {
12310Sstevel@tonic-gate
12320Sstevel@tonic-gate if (ibnex_get_commsvcnode_snapshot(&nvl,
12330Sstevel@tonic-gate port_attr->pa_hca_guid,
12340Sstevel@tonic-gate port_attr->pa_port_guid, k, pkey,
12350Sstevel@tonic-gate IBNEX_VPPA_COMMSVC_NODE) != 0) {
12360Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
12370Sstevel@tonic-gate "ibnex_get_snapshot: "
12380Sstevel@tonic-gate "failed to fill VPPA "
12390Sstevel@tonic-gate "device (%x %x %x % x)",
12400Sstevel@tonic-gate i, j, k, l);
12410Sstevel@tonic-gate ibdm_ibnex_free_hca_list(hcap);
12420Sstevel@tonic-gate nvlist_free(nvl);
12430Sstevel@tonic-gate return (-1);
12440Sstevel@tonic-gate }
12450Sstevel@tonic-gate } /* end of ibnex_nvppa_comm_svcs loop */
12460Sstevel@tonic-gate
12470Sstevel@tonic-gate } /* end of pa_npkeys for loop */
12480Sstevel@tonic-gate
12490Sstevel@tonic-gate } /* end of hl_nports for loop */
12500Sstevel@tonic-gate
12510Sstevel@tonic-gate } /* end of hca_count for loop */
12520Sstevel@tonic-gate
12530Sstevel@tonic-gate if (hcap)
12540Sstevel@tonic-gate ibdm_ibnex_free_hca_list(hcap);
12550Sstevel@tonic-gate
12560Sstevel@tonic-gate /* save it to free up the entire list */
12570Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
12580Sstevel@tonic-gate iocp = ioc_listp = ibdm_ibnex_get_ioc_list(allow_probe);
12590Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
12600Sstevel@tonic-gate for (; ioc_listp != NULL; ioc_listp = ioc_listp->ioc_next) {
12610Sstevel@tonic-gate
12620Sstevel@tonic-gate /*
12630Sstevel@tonic-gate * Say we have N IOCs and all were deleted from ibnex
12640Sstevel@tonic-gate * but not from IBDM
12650Sstevel@tonic-gate */
12660Sstevel@tonic-gate if (ibnex.ibnex_ioc_node_head == NULL) {
12670Sstevel@tonic-gate if (ibnex_fill_ioc_tmp(&nvl, ioc_listp) != 0) {
12680Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_get_snapshot: "
12690Sstevel@tonic-gate "filling NVL data failed");
12700Sstevel@tonic-gate ibdm_ibnex_free_ioc_list(iocp);
12710Sstevel@tonic-gate nvlist_free(nvl);
12720Sstevel@tonic-gate return (-1);
12730Sstevel@tonic-gate }
12740Sstevel@tonic-gate continue;
12750Sstevel@tonic-gate
12760Sstevel@tonic-gate } else {
12770Sstevel@tonic-gate found = B_FALSE;
12780Sstevel@tonic-gate
12790Sstevel@tonic-gate /* Check first, if we have already seen this IOC? */
12800Sstevel@tonic-gate for (nodep = ibnex.ibnex_ioc_node_head; nodep != NULL;
12810Sstevel@tonic-gate nodep = nodep->node_next) {
12820Sstevel@tonic-gate if (ioc_listp->ioc_profile.ioc_guid ==
12830Sstevel@tonic-gate nodep->node_data.ioc_node.ioc_guid) {
12840Sstevel@tonic-gate found = B_TRUE;
12850Sstevel@tonic-gate break;
12860Sstevel@tonic-gate }
12870Sstevel@tonic-gate }
12880Sstevel@tonic-gate
12890Sstevel@tonic-gate
12900Sstevel@tonic-gate /* have we seen this IOC before? */
12910Sstevel@tonic-gate if (found == B_TRUE) {
12920Sstevel@tonic-gate if (ibnex_fill_nodeinfo(&nvl, nodep,
12930Sstevel@tonic-gate &ioc_listp->ioc_profile) != 0) {
12940Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
12950Sstevel@tonic-gate "ibnex_get_snapshot: filling NVL "
12960Sstevel@tonic-gate "for IOC node %p failed", nodep);
12970Sstevel@tonic-gate ibdm_ibnex_free_ioc_list(iocp);
12980Sstevel@tonic-gate nvlist_free(nvl);
12990Sstevel@tonic-gate return (-1);
13000Sstevel@tonic-gate }
13010Sstevel@tonic-gate
13020Sstevel@tonic-gate } else {
13030Sstevel@tonic-gate
13040Sstevel@tonic-gate if (ibnex_fill_ioc_tmp(&nvl, ioc_listp) != 0) {
13050Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
13060Sstevel@tonic-gate "ibnex_get_snapshot: filling NVL "
13070Sstevel@tonic-gate "tmp for IOC node %p failed",
13080Sstevel@tonic-gate ioc_listp);
13090Sstevel@tonic-gate ibdm_ibnex_free_ioc_list(iocp);
13100Sstevel@tonic-gate nvlist_free(nvl);
13110Sstevel@tonic-gate return (-1);
13120Sstevel@tonic-gate }
13130Sstevel@tonic-gate }
13140Sstevel@tonic-gate
13150Sstevel@tonic-gate } /* end of else ibnex_ioc_node_head == NULL */
13160Sstevel@tonic-gate } /* end of external for */
13170Sstevel@tonic-gate
13180Sstevel@tonic-gate ibdm_ibnex_free_ioc_list(iocp);
13190Sstevel@tonic-gate
13200Sstevel@tonic-gate /*
13210Sstevel@tonic-gate * Add list of "disconnected" IOCs, not unconfigured.
13220Sstevel@tonic-gate */
13230Sstevel@tonic-gate for (nodep = ibnex.ibnex_ioc_node_head; nodep != NULL;
13240Sstevel@tonic-gate nodep = nodep->node_next) {
13250Sstevel@tonic-gate if (nodep->node_data.ioc_node.ioc_ngids == 0 &&
13260Sstevel@tonic-gate nodep->node_data.ioc_node.ioc_profile != NULL &&
13270Sstevel@tonic-gate nodep->node_state != IBNEX_CFGADM_UNCONFIGURED) {
13280Sstevel@tonic-gate if (ibnex_fill_nodeinfo(&nvl, nodep,
13290Sstevel@tonic-gate nodep->node_data.ioc_node.ioc_profile) != 0) {
13300Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
13310Sstevel@tonic-gate "ibnex_get_snapshot: filling NVL "
13320Sstevel@tonic-gate "for disconnected IOC node %p "
13330Sstevel@tonic-gate "failed", nodep);
13340Sstevel@tonic-gate nvlist_free(nvl);
13350Sstevel@tonic-gate return (-1);
13360Sstevel@tonic-gate }
13370Sstevel@tonic-gate }
13380Sstevel@tonic-gate }
13390Sstevel@tonic-gate
13400Sstevel@tonic-gate /* lastly; pseudo nodes */
13410Sstevel@tonic-gate for (nodep = ibnex.ibnex_pseudo_node_head; nodep;
13420Sstevel@tonic-gate nodep = nodep->node_next) {
13431093Shiremath if (nodep->node_data.pseudo_node.pseudo_merge_node == 1)
13441093Shiremath continue;
13450Sstevel@tonic-gate if (ibnex_fill_nodeinfo(&nvl, nodep, NULL) != 0) {
13460Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_get_snapshot: "
13470Sstevel@tonic-gate "filling NVL data for Pseudo %p failed", nodep);
13480Sstevel@tonic-gate nvlist_free(nvl);
13490Sstevel@tonic-gate return (-1);
13500Sstevel@tonic-gate }
13510Sstevel@tonic-gate }
13520Sstevel@tonic-gate
13530Sstevel@tonic-gate /* pack the data into the buffer */
13540Sstevel@tonic-gate if (nvlist_pack(nvl, buf, sz, NV_ENCODE_NATIVE, KM_SLEEP)) {
13550Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
13560Sstevel@tonic-gate "ibnex_get_snapshot: nvlist_pack failed");
13570Sstevel@tonic-gate nvlist_free(nvl);
13580Sstevel@tonic-gate return (-1);
13590Sstevel@tonic-gate }
13600Sstevel@tonic-gate
13610Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_get_snapshot: size = 0x%x", *sz);
13620Sstevel@tonic-gate nvlist_free(nvl);
13630Sstevel@tonic-gate return (0);
13640Sstevel@tonic-gate }
13650Sstevel@tonic-gate
13660Sstevel@tonic-gate
13670Sstevel@tonic-gate /*
13680Sstevel@tonic-gate * ibnex_get_commsvcnode_snapshot()
13690Sstevel@tonic-gate * A utility function to fill in a "dummy" Port/VPPA/HCA_SVC
13700Sstevel@tonic-gate * information. Cfgadm plugin will display all Port/VPPA/
13710Sstevel@tonic-gate * HCA_SVCs seen even if they are not all configured by IBNEX.
13720Sstevel@tonic-gate *
13730Sstevel@tonic-gate * This function uses information from IBDM to fill up Port/VPPA/
13740Sstevel@tonic-gate * HCA_SVC snapshot. If none exists then it makes up a "temporary"
13750Sstevel@tonic-gate * node which will be displayed as "connected/unconfigured/unknown".
13760Sstevel@tonic-gate *
13770Sstevel@tonic-gate * For HCA_SVC node port_guid will be same as hca_guid.
13780Sstevel@tonic-gate */
13790Sstevel@tonic-gate static int
ibnex_get_commsvcnode_snapshot(nvlist_t ** nvlpp,ib_guid_t hca_guid,ib_guid_t port_guid,int svc_index,ib_pkey_t p_key,ibnex_node_type_t node_type)13800Sstevel@tonic-gate ibnex_get_commsvcnode_snapshot(nvlist_t **nvlpp, ib_guid_t hca_guid,
13810Sstevel@tonic-gate ib_guid_t port_guid, int svc_index, ib_pkey_t p_key,
13820Sstevel@tonic-gate ibnex_node_type_t node_type)
13830Sstevel@tonic-gate {
13840Sstevel@tonic-gate int rval;
13850Sstevel@tonic-gate dev_info_t *dip = NULL;
13860Sstevel@tonic-gate ibnex_node_data_t *nodep;
13870Sstevel@tonic-gate ibnex_node_data_t dummy;
13880Sstevel@tonic-gate ibnex_node_data_t *tmp = &dummy;
13890Sstevel@tonic-gate
13900Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_get_commsvcnode_snapshot: "
13910Sstevel@tonic-gate "HCA GUID: %llX Port GUID: %llX svc_index = %x pkey = %x "
13920Sstevel@tonic-gate "node_type = %x", hca_guid, port_guid, svc_index, p_key, node_type);
13930Sstevel@tonic-gate
13940Sstevel@tonic-gate /* check if this node was seen before? */
1395*12163SRamaswamy.Tummala@Sun.COM rval = ibnex_get_node_and_dip_from_guid(port_guid, svc_index, p_key,
1396*12163SRamaswamy.Tummala@Sun.COM &nodep, &dip);
1397*12163SRamaswamy.Tummala@Sun.COM if (rval == IBNEX_SUCCESS && nodep != NULL) {
13980Sstevel@tonic-gate
13990Sstevel@tonic-gate if (ibnex_fill_nodeinfo(nvlpp, nodep, NULL) != 0) {
14000Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
14010Sstevel@tonic-gate "ibnex_get_commsvcnode_snapshot: failed to fill "
14020Sstevel@tonic-gate "Port/VPPA device node %p NVL data", nodep);
14030Sstevel@tonic-gate return (-1);
14040Sstevel@tonic-gate }
14050Sstevel@tonic-gate
14060Sstevel@tonic-gate } else {
14070Sstevel@tonic-gate /* Fake up a Port/VPPA/HCA_SVC node */
14080Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_get_commsvcnode_snapshot: "
14090Sstevel@tonic-gate "VPPA/Port/HCA_SVC not seen by ibnex");
14100Sstevel@tonic-gate bzero(tmp, sizeof (ibnex_node_data_t));
14110Sstevel@tonic-gate tmp->node_type = node_type;
14120Sstevel@tonic-gate tmp->node_data.port_node.port_guid = port_guid;
14130Sstevel@tonic-gate tmp->node_data.port_node.port_hcaguid = hca_guid;
14140Sstevel@tonic-gate tmp->node_data.port_node.port_commsvc_idx = svc_index;
14150Sstevel@tonic-gate /* Fill P_Key only for VPPA nodes */
14160Sstevel@tonic-gate if (node_type == IBNEX_VPPA_COMMSVC_NODE) {
14170Sstevel@tonic-gate tmp->node_data.port_node.port_pkey = p_key;
14180Sstevel@tonic-gate }
14190Sstevel@tonic-gate
14200Sstevel@tonic-gate if (ibnex_fill_nodeinfo(nvlpp, tmp, NULL) != 0) {
14210Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
14220Sstevel@tonic-gate "ibnex_get_commsvcnode_snapshot: failed to fill "
14230Sstevel@tonic-gate "tmp Port/VPPA device node %p NVL data", tmp);
14240Sstevel@tonic-gate return (-1);
14250Sstevel@tonic-gate }
14260Sstevel@tonic-gate }
14270Sstevel@tonic-gate
14280Sstevel@tonic-gate return (0);
14290Sstevel@tonic-gate }
14300Sstevel@tonic-gate
14310Sstevel@tonic-gate
14320Sstevel@tonic-gate /*
14330Sstevel@tonic-gate * ibnex_fill_ioc_tmp()
14340Sstevel@tonic-gate * A utility function to fill in a "dummy" IOC information.
14350Sstevel@tonic-gate * Cfgadm plugin will display all IOCs seen by IBDM even if they
14360Sstevel@tonic-gate * are configured or not by IBNEX.
14370Sstevel@tonic-gate *
14380Sstevel@tonic-gate * This function uses information from IBDM to fill up a
14390Sstevel@tonic-gate * dummy IOC information. It will be displayed as
14400Sstevel@tonic-gate * "connected/unconfigured/unknown".
14410Sstevel@tonic-gate */
14420Sstevel@tonic-gate static int
ibnex_fill_ioc_tmp(nvlist_t ** nvlpp,ibdm_ioc_info_t * ioc_listp)14430Sstevel@tonic-gate ibnex_fill_ioc_tmp(nvlist_t **nvlpp, ibdm_ioc_info_t *ioc_listp)
14440Sstevel@tonic-gate {
14450Sstevel@tonic-gate ibnex_node_data_t dummy;
14460Sstevel@tonic-gate ibnex_node_data_t *nodep = &dummy;
14470Sstevel@tonic-gate
14480Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_fill_ioc_tmp:");
14490Sstevel@tonic-gate
14500Sstevel@tonic-gate bzero(nodep, sizeof (ibnex_node_data_t));
14510Sstevel@tonic-gate nodep->node_type = IBNEX_IOC_NODE;
14520Sstevel@tonic-gate nodep->node_data.ioc_node.ioc_guid = ioc_listp->ioc_profile.ioc_guid;
14530Sstevel@tonic-gate nodep->node_data.ioc_node.iou_guid = ioc_listp->ioc_iou_guid;
14540Sstevel@tonic-gate (void) strncpy(nodep->node_data.ioc_node.ioc_id_string,
14550Sstevel@tonic-gate (char *)ioc_listp->ioc_profile.ioc_id_string,
14560Sstevel@tonic-gate IB_DM_IOC_ID_STRING_LEN);
14570Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_fill_ioc_tmp: %s",
14580Sstevel@tonic-gate nodep->node_data.ioc_node.ioc_id_string);
14590Sstevel@tonic-gate
14600Sstevel@tonic-gate if (ibnex_fill_nodeinfo(nvlpp, nodep, &ioc_listp->ioc_profile) != 0) {
14610Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "\tibnex_fill_ioc_tmp: filling NVL "
14620Sstevel@tonic-gate "data for IOC node %p failed", nodep);
14630Sstevel@tonic-gate return (-1);
14640Sstevel@tonic-gate }
14650Sstevel@tonic-gate
14660Sstevel@tonic-gate return (0);
14670Sstevel@tonic-gate }
14680Sstevel@tonic-gate
14690Sstevel@tonic-gate
14700Sstevel@tonic-gate /*
14710Sstevel@tonic-gate * ibnex_fill_nodeinfo()
14720Sstevel@tonic-gate * A utility function to fill in to the NVLIST information about
14730Sstevel@tonic-gate * a Port/IOC/VPPA/HCA_SVC/Pseudo driver that is then passed over
14740Sstevel@tonic-gate * to cfgadm utility for display. This information is used only
14750Sstevel@tonic-gate * for cfgadm -ll displays.
14760Sstevel@tonic-gate *
14770Sstevel@tonic-gate * Information that is filled in here is:-
14780Sstevel@tonic-gate * AP_ID_NAME
14790Sstevel@tonic-gate * AP_ID_INFO
14800Sstevel@tonic-gate * AP_ID_TYPE
14810Sstevel@tonic-gate * AP_ID_OCCUPANT_STATE
14820Sstevel@tonic-gate * AP_ID_RECEPTACLE_STATE
14830Sstevel@tonic-gate * AP_ID_CONDITION
14840Sstevel@tonic-gate */
14850Sstevel@tonic-gate static int
ibnex_fill_nodeinfo(nvlist_t ** nvlpp,ibnex_node_data_t * node_datap,void * tmp)14860Sstevel@tonic-gate ibnex_fill_nodeinfo(nvlist_t **nvlpp, ibnex_node_data_t *node_datap, void *tmp)
14870Sstevel@tonic-gate {
14880Sstevel@tonic-gate char *svcname;
14890Sstevel@tonic-gate char *node_name;
14900Sstevel@tonic-gate char apid[IBTL_IBNEX_APID_LEN];
14910Sstevel@tonic-gate char info_data[MAXNAMELEN];
14920Sstevel@tonic-gate ib_dm_ioc_ctrl_profile_t *profilep;
14930Sstevel@tonic-gate devctl_ap_state_t state;
14940Sstevel@tonic-gate
14950Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: 0x%x addr is %p",
14960Sstevel@tonic-gate node_datap->node_type, node_datap);
14970Sstevel@tonic-gate
14980Sstevel@tonic-gate if (node_datap->node_type == IBNEX_PORT_COMMSVC_NODE) {
14990Sstevel@tonic-gate svcname = ibnex.ibnex_comm_svc_names[node_datap->node_data.
15000Sstevel@tonic-gate port_node.port_commsvc_idx];
15010Sstevel@tonic-gate (void) snprintf(apid, IBTL_IBNEX_APID_LEN, "%llX,0,%s",
15020Sstevel@tonic-gate (longlong_t)node_datap->node_data.port_node.port_guid,
15030Sstevel@tonic-gate svcname);
15040Sstevel@tonic-gate
15050Sstevel@tonic-gate /* Node APID */
15060Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_APID_NVL, apid)) {
15070Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
15080Sstevel@tonic-gate "failed to fill %s", IBNEX_NODE_APID_NVL);
15090Sstevel@tonic-gate return (-1);
15100Sstevel@tonic-gate }
15110Sstevel@tonic-gate
15120Sstevel@tonic-gate /* Node Info */
15130Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_INFO_NVL, svcname)) {
15140Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
15150Sstevel@tonic-gate "failed to fill Port %s", IBNEX_NODE_INFO_NVL);
15160Sstevel@tonic-gate return (-1);
15170Sstevel@tonic-gate }
15180Sstevel@tonic-gate
15190Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: "
15200Sstevel@tonic-gate "Port %s = %s, %s = %s",
15210Sstevel@tonic-gate IBNEX_NODE_INFO_NVL, apid, IBNEX_NODE_APID_NVL, svcname);
15220Sstevel@tonic-gate
15230Sstevel@tonic-gate } else if (node_datap->node_type == IBNEX_VPPA_COMMSVC_NODE) {
15240Sstevel@tonic-gate svcname = ibnex.ibnex_vppa_comm_svc_names[node_datap->node_data.
15250Sstevel@tonic-gate port_node.port_commsvc_idx];
15260Sstevel@tonic-gate (void) snprintf(apid, IBTL_IBNEX_APID_LEN, "%llX,%x,%s",
15270Sstevel@tonic-gate (longlong_t)node_datap->node_data.port_node.port_guid,
15280Sstevel@tonic-gate node_datap->node_data.port_node.port_pkey, svcname);
15290Sstevel@tonic-gate
15300Sstevel@tonic-gate /* Node APID */
15310Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_APID_NVL, apid)) {
15320Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
15330Sstevel@tonic-gate "failed to fill %s", IBNEX_NODE_APID_NVL);
15340Sstevel@tonic-gate return (-1);
15350Sstevel@tonic-gate }
15360Sstevel@tonic-gate
15370Sstevel@tonic-gate /* Node Info */
15380Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_INFO_NVL, svcname)) {
15390Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
15400Sstevel@tonic-gate "failed to fill VPPA %s", IBNEX_NODE_INFO_NVL);
15410Sstevel@tonic-gate return (-1);
15420Sstevel@tonic-gate }
15430Sstevel@tonic-gate
15440Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: "
15450Sstevel@tonic-gate "VPPA %s = %s, %s = %s",
15460Sstevel@tonic-gate IBNEX_NODE_APID_NVL, apid, IBNEX_NODE_INFO_NVL, svcname);
15470Sstevel@tonic-gate
15480Sstevel@tonic-gate } else if (node_datap->node_type == IBNEX_HCASVC_COMMSVC_NODE) {
15490Sstevel@tonic-gate svcname = ibnex.ibnex_hcasvc_comm_svc_names[node_datap->
15500Sstevel@tonic-gate node_data.port_node.port_commsvc_idx];
15510Sstevel@tonic-gate (void) snprintf(apid, IBTL_IBNEX_APID_LEN, "%llX,0,%s",
15520Sstevel@tonic-gate (longlong_t)node_datap->node_data.port_node.port_guid,
15530Sstevel@tonic-gate svcname);
15540Sstevel@tonic-gate
15550Sstevel@tonic-gate /* Node APID */
15560Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_APID_NVL, apid)) {
15570Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
15580Sstevel@tonic-gate "failed to fill %s", IBNEX_NODE_APID_NVL);
15590Sstevel@tonic-gate return (-1);
15600Sstevel@tonic-gate }
15610Sstevel@tonic-gate
15620Sstevel@tonic-gate /* Node Info */
15630Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_INFO_NVL, svcname)) {
15640Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
15650Sstevel@tonic-gate "failed to fill Port %s", IBNEX_NODE_INFO_NVL);
15660Sstevel@tonic-gate return (-1);
15670Sstevel@tonic-gate }
15680Sstevel@tonic-gate
15690Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: "
15700Sstevel@tonic-gate "Port %s = %s, %s = %s",
15710Sstevel@tonic-gate IBNEX_NODE_INFO_NVL, apid, IBNEX_NODE_APID_NVL, svcname);
15720Sstevel@tonic-gate
15730Sstevel@tonic-gate } else if (node_datap->node_type == IBNEX_IOC_NODE) {
15740Sstevel@tonic-gate
15750Sstevel@tonic-gate /*
15760Sstevel@tonic-gate * get the IOC profile pointer from the args
15770Sstevel@tonic-gate */
15780Sstevel@tonic-gate profilep = (ib_dm_ioc_ctrl_profile_t *)tmp;
15790Sstevel@tonic-gate IBNEX_FORM_GUID(apid, IBTL_IBNEX_APID_LEN, profilep->ioc_guid);
15800Sstevel@tonic-gate
15810Sstevel@tonic-gate /* Node APID */
15820Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_APID_NVL, apid)) {
15830Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
15840Sstevel@tonic-gate "failed to fill in %s", IBNEX_NODE_APID_NVL);
15850Sstevel@tonic-gate return (-1);
15860Sstevel@tonic-gate }
15870Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: %s %s",
15880Sstevel@tonic-gate IBNEX_NODE_APID_NVL, apid);
15890Sstevel@tonic-gate
15900Sstevel@tonic-gate /*
15910Sstevel@tonic-gate * IOC "info" filed will display the following fields
15920Sstevel@tonic-gate * VendorID, IOCDeviceID, DeviceVersion, SubsystemVendorID,
15930Sstevel@tonic-gate * SubsystemID, Class, Subclass, Protocol, ProtocolVersion
15940Sstevel@tonic-gate */
15950Sstevel@tonic-gate (void) snprintf(info_data, MAXNAMELEN,
15960Sstevel@tonic-gate "VID: 0x%x DEVID: 0x%x VER: 0x%x SUBSYS_VID: 0x%x "
15970Sstevel@tonic-gate "SUBSYS_ID: 0x%x CLASS: 0x%x SUBCLASS: 0x%x PROTO: 0x%x "
15980Sstevel@tonic-gate "PROTOVER: 0x%x ID_STRING: %s", profilep->ioc_vendorid,
15990Sstevel@tonic-gate profilep->ioc_deviceid, profilep->ioc_device_ver,
16000Sstevel@tonic-gate profilep->ioc_subsys_vendorid, profilep->ioc_subsys_id,
16010Sstevel@tonic-gate profilep->ioc_io_class, profilep->ioc_io_subclass,
16020Sstevel@tonic-gate profilep->ioc_protocol, profilep->ioc_protocol_ver,
16030Sstevel@tonic-gate (char *)profilep->ioc_id_string);
16040Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: %s", info_data);
16050Sstevel@tonic-gate
16060Sstevel@tonic-gate /* Node Info */
16070Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_INFO_NVL, info_data)) {
16080Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
16090Sstevel@tonic-gate "failed to fill IOC %s", IBNEX_NODE_INFO_NVL);
16100Sstevel@tonic-gate return (-1);
16110Sstevel@tonic-gate }
16120Sstevel@tonic-gate
16130Sstevel@tonic-gate } else if (node_datap->node_type == IBNEX_PSEUDO_NODE) {
16140Sstevel@tonic-gate (void) snprintf(apid, IBTL_IBNEX_APID_LEN, "%s",
16150Sstevel@tonic-gate node_datap->node_data.pseudo_node.pseudo_node_addr);
16160Sstevel@tonic-gate
16170Sstevel@tonic-gate /* Node APID */
16180Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_APID_NVL, apid)) {
16190Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
16200Sstevel@tonic-gate "failed to fill in %s", IBNEX_NODE_APID_NVL);
16210Sstevel@tonic-gate return (-1);
16220Sstevel@tonic-gate }
16230Sstevel@tonic-gate
16240Sstevel@tonic-gate /* Node Info */
16250Sstevel@tonic-gate node_name = node_datap->node_data.pseudo_node.pseudo_devi_name;
16260Sstevel@tonic-gate (void) snprintf(info_data, MAXNAMELEN,
16270Sstevel@tonic-gate "Pseudo Driver = \"%s\", Unit-address = \"%s\"",
16280Sstevel@tonic-gate node_name, apid + strlen(node_name) + 1);
16290Sstevel@tonic-gate if (nvlist_add_string(*nvlpp, IBNEX_NODE_INFO_NVL, info_data)) {
16300Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
16310Sstevel@tonic-gate "failed to fill Pseudo %s", IBNEX_NODE_INFO_NVL);
16320Sstevel@tonic-gate return (-1);
16330Sstevel@tonic-gate }
16340Sstevel@tonic-gate
16350Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: Pseudo %s = %s,"
16360Sstevel@tonic-gate "%s = %s", IBNEX_NODE_APID_NVL, apid, IBNEX_NODE_INFO_NVL,
16370Sstevel@tonic-gate info_data);
16380Sstevel@tonic-gate }
16390Sstevel@tonic-gate
16400Sstevel@tonic-gate /* Node type */
16410Sstevel@tonic-gate if (nvlist_add_int32(*nvlpp, IBNEX_NODE_TYPE_NVL,
16420Sstevel@tonic-gate node_datap->node_type)) {
16430Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
16440Sstevel@tonic-gate "failed to fill in %s", IBNEX_NODE_TYPE_NVL);
16450Sstevel@tonic-gate return (-1);
16460Sstevel@tonic-gate }
16470Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: %s %d",
16480Sstevel@tonic-gate IBNEX_NODE_TYPE_NVL, node_datap->node_type);
16490Sstevel@tonic-gate
16500Sstevel@tonic-gate /* figure out "ostate", "rstate" and "condition" */
1651*12163SRamaswamy.Tummala@Sun.COM ibnex_figure_ap_devstate(node_datap, &state);
16520Sstevel@tonic-gate
16530Sstevel@tonic-gate if (nvlist_add_int32(*nvlpp, IBNEX_NODE_RSTATE_NVL, state.ap_rstate)) {
16540Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
16550Sstevel@tonic-gate "failed to fill in %s", IBNEX_NODE_RSTATE_NVL);
16560Sstevel@tonic-gate return (-1);
16570Sstevel@tonic-gate }
16580Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: %s %d",
16590Sstevel@tonic-gate IBNEX_NODE_RSTATE_NVL, state.ap_rstate);
16600Sstevel@tonic-gate
16610Sstevel@tonic-gate if (nvlist_add_int32(*nvlpp, IBNEX_NODE_OSTATE_NVL, state.ap_ostate)) {
16620Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
16630Sstevel@tonic-gate "failed to fill in %s", IBNEX_NODE_OSTATE_NVL);
16640Sstevel@tonic-gate return (-1);
16650Sstevel@tonic-gate }
16660Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: %s %d",
16670Sstevel@tonic-gate IBNEX_NODE_OSTATE_NVL, state.ap_ostate);
16680Sstevel@tonic-gate
16690Sstevel@tonic-gate if (nvlist_add_int32(*nvlpp, IBNEX_NODE_COND_NVL, state.ap_condition)) {
16700Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "ibnex_fill_nodeinfo: "
16710Sstevel@tonic-gate "failed to fill in %s", IBNEX_NODE_COND_NVL);
16720Sstevel@tonic-gate return (-1);
16730Sstevel@tonic-gate }
16740Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "ibnex_fill_nodeinfo: %s %d",
16750Sstevel@tonic-gate IBNEX_NODE_COND_NVL, state.ap_condition);
16760Sstevel@tonic-gate
16770Sstevel@tonic-gate return (0);
16780Sstevel@tonic-gate }
16790Sstevel@tonic-gate
16800Sstevel@tonic-gate
16810Sstevel@tonic-gate /*
16820Sstevel@tonic-gate * ibnex_figure_ap_devstate()
16830Sstevel@tonic-gate * Fills the "devctl_ap_state_t" for a given ap_id
16840Sstevel@tonic-gate *
16850Sstevel@tonic-gate * currently it assumes that we don't support "error_code" and
16860Sstevel@tonic-gate * "last_change" value.
16870Sstevel@tonic-gate */
16880Sstevel@tonic-gate static void
ibnex_figure_ap_devstate(ibnex_node_data_t * nodep,devctl_ap_state_t * ap_state)1689*12163SRamaswamy.Tummala@Sun.COM ibnex_figure_ap_devstate(ibnex_node_data_t *nodep, devctl_ap_state_t *ap_state)
16900Sstevel@tonic-gate {
1691*12163SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L5("ibnex", "ibnex_figure_ap_devstate: nodep = %p", nodep);
16920Sstevel@tonic-gate
16930Sstevel@tonic-gate ap_state->ap_rstate = AP_RSTATE_CONNECTED;
1694*12163SRamaswamy.Tummala@Sun.COM if (nodep == NULL) { /* for nodes not seen by IBNEX yet */
16950Sstevel@tonic-gate ap_state->ap_ostate = AP_OSTATE_UNCONFIGURED;
16960Sstevel@tonic-gate ap_state->ap_condition = AP_COND_UNKNOWN;
16970Sstevel@tonic-gate } else {
1698*12163SRamaswamy.Tummala@Sun.COM /*
1699*12163SRamaswamy.Tummala@Sun.COM * IBNEX_NODE_AP_UNCONFIGURED & IBNEX_NODE_AP_CONFIGURING.
1700*12163SRamaswamy.Tummala@Sun.COM */
1701*12163SRamaswamy.Tummala@Sun.COM if (nodep->node_ap_state >= IBNEX_NODE_AP_UNCONFIGURED) {
17020Sstevel@tonic-gate ap_state->ap_ostate = AP_OSTATE_UNCONFIGURED;
17030Sstevel@tonic-gate ap_state->ap_condition = AP_COND_UNKNOWN;
17040Sstevel@tonic-gate } else {
17050Sstevel@tonic-gate ap_state->ap_ostate = AP_OSTATE_CONFIGURED;
17060Sstevel@tonic-gate ap_state->ap_condition = AP_COND_OK;
17070Sstevel@tonic-gate }
17080Sstevel@tonic-gate }
17090Sstevel@tonic-gate ap_state->ap_last_change = (time_t)-1;
17100Sstevel@tonic-gate ap_state->ap_error_code = 0;
17110Sstevel@tonic-gate ap_state->ap_in_transition = 0;
17120Sstevel@tonic-gate }
17130Sstevel@tonic-gate
17140Sstevel@tonic-gate
17150Sstevel@tonic-gate /*
17160Sstevel@tonic-gate * ibnex_figure_ib_apid_devstate()
17170Sstevel@tonic-gate * Fills the "devctl_ap_state_t" for a IB static ap_id
17180Sstevel@tonic-gate */
17190Sstevel@tonic-gate static void
ibnex_figure_ib_apid_devstate(devctl_ap_state_t * ap_state)17200Sstevel@tonic-gate ibnex_figure_ib_apid_devstate(devctl_ap_state_t *ap_state)
17210Sstevel@tonic-gate {
17220Sstevel@tonic-gate ap_state->ap_rstate = AP_RSTATE_CONNECTED;
17230Sstevel@tonic-gate ap_state->ap_condition = AP_COND_OK;
17240Sstevel@tonic-gate ap_state->ap_ostate = (ibt_get_hca_list(NULL) == 0) ?
17250Sstevel@tonic-gate AP_OSTATE_UNCONFIGURED : AP_OSTATE_CONFIGURED;
17260Sstevel@tonic-gate ap_state->ap_last_change = (time_t)-1;
17270Sstevel@tonic-gate ap_state->ap_error_code = 0;
17280Sstevel@tonic-gate ap_state->ap_in_transition = 0;
17290Sstevel@tonic-gate }
17300Sstevel@tonic-gate
17310Sstevel@tonic-gate
17320Sstevel@tonic-gate /*
17330Sstevel@tonic-gate * ibnex_get_apid()
17340Sstevel@tonic-gate * Reads in the ap_id passed as an nvlist_string from user-land
17350Sstevel@tonic-gate */
17360Sstevel@tonic-gate static char *
ibnex_get_apid(struct devctl_iocdata * dcp)17370Sstevel@tonic-gate ibnex_get_apid(struct devctl_iocdata *dcp)
17380Sstevel@tonic-gate {
17390Sstevel@tonic-gate char *ap_id;
17400Sstevel@tonic-gate
17410Sstevel@tonic-gate ASSERT(mutex_owned(&ibnex.ibnex_mutex));
17420Sstevel@tonic-gate
17430Sstevel@tonic-gate /* Get which ap_id to operate on. */
17440Sstevel@tonic-gate if (nvlist_lookup_string(ndi_dc_get_ap_data(dcp), "apid",
17450Sstevel@tonic-gate &ap_id) != 0) {
17460Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_get_apid: ap_id lookup failed");
17470Sstevel@tonic-gate ap_id = NULL;
17480Sstevel@tonic-gate }
17490Sstevel@tonic-gate
17500Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_get_apid: ap_id=%s", ap_id);
17510Sstevel@tonic-gate return (ap_id);
17520Sstevel@tonic-gate }
17530Sstevel@tonic-gate
17540Sstevel@tonic-gate
17550Sstevel@tonic-gate /*
17560Sstevel@tonic-gate * ibnex_get_dip_from_apid()
17570Sstevel@tonic-gate * Figures out the dip/node_data from an ap_id given that this ap_id
17580Sstevel@tonic-gate * exists as a "name" in the "ibnex" list
17590Sstevel@tonic-gate *
17600Sstevel@tonic-gate * NOTE: ap_id was on stack earlier and gets manipulated here. Since this
17610Sstevel@tonic-gate * function may be called twice; it is better to make a local copy of
17620Sstevel@tonic-gate * ap_id; if the ap_id were to be reused.
17630Sstevel@tonic-gate */
17640Sstevel@tonic-gate static int
ibnex_get_dip_from_apid(char * apid,dev_info_t ** ret_dip,ibnex_node_data_t ** ret_node_datap)17650Sstevel@tonic-gate ibnex_get_dip_from_apid(char *apid, dev_info_t **ret_dip,
17660Sstevel@tonic-gate ibnex_node_data_t **ret_node_datap)
17670Sstevel@tonic-gate {
17680Sstevel@tonic-gate int rv, ret;
17690Sstevel@tonic-gate int index;
17700Sstevel@tonic-gate int len = strlen((char *)apid) + 1;
17710Sstevel@tonic-gate char *dyn;
17720Sstevel@tonic-gate char *ap_id;
17730Sstevel@tonic-gate char *first;
17740Sstevel@tonic-gate char *second = NULL;
17750Sstevel@tonic-gate char *node_addr;
17760Sstevel@tonic-gate char name[100];
17770Sstevel@tonic-gate ibnex_node_data_t *nodep = NULL;
17780Sstevel@tonic-gate
17790Sstevel@tonic-gate ap_id = i_ddi_strdup(apid, KM_SLEEP);
17800Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_get_dip_from_apid: %s", ap_id);
17810Sstevel@tonic-gate ASSERT(mutex_owned(&ibnex.ibnex_mutex));
17820Sstevel@tonic-gate
17830Sstevel@tonic-gate if ((dyn = GET_DYN(ap_id)) != NULL) {
17840Sstevel@tonic-gate rv = IBNEX_DYN_APID;
17850Sstevel@tonic-gate } else { /* either static, hca or unknown */
17860Sstevel@tonic-gate *ret_dip = NULL;
17870Sstevel@tonic-gate if (strstr(ap_id, "hca") != 0) {
17880Sstevel@tonic-gate rv = IBNEX_HCA_APID;
17890Sstevel@tonic-gate } else if (strstr(ap_id, IBNEX_FABRIC) != 0) {
17900Sstevel@tonic-gate rv = IBNEX_BASE_APID;
17910Sstevel@tonic-gate } else {
17920Sstevel@tonic-gate rv = IBNEX_UNKNOWN_APID;
17930Sstevel@tonic-gate }
17940Sstevel@tonic-gate kmem_free(ap_id, len);
17950Sstevel@tonic-gate return (rv);
17960Sstevel@tonic-gate }
17970Sstevel@tonic-gate
17980Sstevel@tonic-gate dyn += strlen(DYN_SEP);
17990Sstevel@tonic-gate if (*dyn == '\0') {
18000Sstevel@tonic-gate *ret_dip = NULL;
18010Sstevel@tonic-gate kmem_free(ap_id, len);
18020Sstevel@tonic-gate return (IBNEX_UNKNOWN_APID);
18030Sstevel@tonic-gate }
18040Sstevel@tonic-gate
18050Sstevel@tonic-gate /* APID */
18060Sstevel@tonic-gate first = strchr(dyn, ',');
18070Sstevel@tonic-gate if (first != NULL)
18080Sstevel@tonic-gate second = strchr(first+1, ',');
18090Sstevel@tonic-gate
18100Sstevel@tonic-gate /* Implies Port or VPPA or HCA_SVC Driver ap_id */
18110Sstevel@tonic-gate if (first != NULL && second != NULL) {
18120Sstevel@tonic-gate int str_len;
18130Sstevel@tonic-gate int pkey_val = 0;
18140Sstevel@tonic-gate char *pkey_str = strchr(ap_id, ',');
18150Sstevel@tonic-gate char *svc_str = strrchr(pkey_str, ',');
18160Sstevel@tonic-gate
18170Sstevel@tonic-gate /* dyn contains ,GUID,p_key,svc_name. Change it to GUID */
18180Sstevel@tonic-gate str_len = strlen(dyn) - strlen(pkey_str);
18190Sstevel@tonic-gate dyn[str_len] = '\0';
18200Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_get_dip_from_apid: "
18210Sstevel@tonic-gate "Port / Node Guid %s", dyn);
18220Sstevel@tonic-gate
18230Sstevel@tonic-gate /* figure out comm or vppa. figure out pkey */
18240Sstevel@tonic-gate ++pkey_str; /* pkey_str used to point to ",p_key,svc_name" */
18250Sstevel@tonic-gate
18260Sstevel@tonic-gate /* pkey_str contains p_key,svc_name. Change it to p_key */
18270Sstevel@tonic-gate str_len = strlen(pkey_str) - strlen(svc_str);
18280Sstevel@tonic-gate pkey_str[str_len] = '\0';
18290Sstevel@tonic-gate
18300Sstevel@tonic-gate /* convert the string P_KEY to hex value */
18310Sstevel@tonic-gate pkey_val = ibnex_str2hex(pkey_str, strlen(pkey_str), &ret);
18320Sstevel@tonic-gate if (ret != IBNEX_SUCCESS) {
18330Sstevel@tonic-gate *ret_dip = NULL;
18340Sstevel@tonic-gate kmem_free(ap_id, len);
18350Sstevel@tonic-gate return (IBNEX_UNKNOWN_APID);
18360Sstevel@tonic-gate }
18370Sstevel@tonic-gate
18380Sstevel@tonic-gate ++svc_str; /* svc_str used to point to ",svc_name" */
18390Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "\tibnex_get_dip_from_apid: pkey %s"
18400Sstevel@tonic-gate ":%x service name = %s", pkey_str, pkey_val, svc_str);
18410Sstevel@tonic-gate
18420Sstevel@tonic-gate for (nodep = ibnex.ibnex_port_node_head;
18430Sstevel@tonic-gate nodep != NULL; nodep = nodep->node_next) {
18440Sstevel@tonic-gate index = nodep->node_data.port_node.port_commsvc_idx;
18450Sstevel@tonic-gate IBNEX_FORM_GUID(name, IBTL_IBNEX_APID_LEN,
18460Sstevel@tonic-gate nodep->node_data.port_node.port_guid);
18470Sstevel@tonic-gate
18480Sstevel@tonic-gate /*
18490Sstevel@tonic-gate * Match P_Key, name string & service string:
18500Sstevel@tonic-gate * For COMM / HCA_SVC services these should be true:
18510Sstevel@tonic-gate * P_Key matches to 0, svc_str in comm_svc_names[]
18520Sstevel@tonic-gate * and name matches the dynamic part of the ap_id
18530Sstevel@tonic-gate * For VPPA services this should be true:
18540Sstevel@tonic-gate * P_Key != 0 & matches, svc_str in
18550Sstevel@tonic-gate * vppa_comm_svc_names[] and the name matches the
18560Sstevel@tonic-gate * dynamic part of the ap_id.
18570Sstevel@tonic-gate */
18580Sstevel@tonic-gate if ((pkey_val == nodep->node_data.port_node.
18590Sstevel@tonic-gate port_pkey) && (strstr(dyn, name) != NULL)) {
18600Sstevel@tonic-gate
18610Sstevel@tonic-gate /* pkey != 0, COMM / HCA_SVC service */
18620Sstevel@tonic-gate if (((pkey_val == 0) && (
18630Sstevel@tonic-gate /* Port Service */
18640Sstevel@tonic-gate ((ibnex.ibnex_comm_svc_names != NULL) &&
18650Sstevel@tonic-gate (index < ibnex.ibnex_num_comm_svcs) &&
18660Sstevel@tonic-gate (strstr(svc_str, ibnex.
18670Sstevel@tonic-gate ibnex_comm_svc_names[index]) != NULL)) ||
18680Sstevel@tonic-gate /* HCA_SVC service */
18690Sstevel@tonic-gate ((ibnex.ibnex_hcasvc_comm_svc_names !=
18700Sstevel@tonic-gate NULL) && (index <
18710Sstevel@tonic-gate ibnex.ibnex_nhcasvc_comm_svcs) &&
18720Sstevel@tonic-gate (strstr(svc_str, ibnex.
18730Sstevel@tonic-gate ibnex_hcasvc_comm_svc_names[index])
18748082SRamaswamy.Tummala@Sun.COM != NULL)))) ||
18750Sstevel@tonic-gate /* next the VPPA strings */
18760Sstevel@tonic-gate ((pkey_val != 0) && (strstr(svc_str, ibnex.
18770Sstevel@tonic-gate ibnex_vppa_comm_svc_names[index]) !=
18780Sstevel@tonic-gate NULL))) {
18790Sstevel@tonic-gate if (nodep->node_dip)
18800Sstevel@tonic-gate ndi_hold_devi(nodep->node_dip);
18810Sstevel@tonic-gate *ret_node_datap = nodep;
18820Sstevel@tonic-gate *ret_dip = nodep->node_dip;
18830Sstevel@tonic-gate kmem_free(ap_id, len);
18840Sstevel@tonic-gate return (rv);
18850Sstevel@tonic-gate }
18860Sstevel@tonic-gate }
18870Sstevel@tonic-gate
18880Sstevel@tonic-gate } /* end of for */
18890Sstevel@tonic-gate
18900Sstevel@tonic-gate } else if (first != NULL && second == NULL) {
18910Sstevel@tonic-gate /* pseudo ap_id */
18920Sstevel@tonic-gate for (nodep = ibnex.ibnex_pseudo_node_head; nodep;
18930Sstevel@tonic-gate nodep = nodep->node_next) {
18941093Shiremath if (nodep->node_data.pseudo_node.pseudo_merge_node
18951093Shiremath == 1)
18961093Shiremath continue;
18970Sstevel@tonic-gate node_addr = nodep->node_data.pseudo_node.
18980Sstevel@tonic-gate pseudo_node_addr;
18990Sstevel@tonic-gate if (strncmp(dyn, node_addr, strlen(node_addr)) == 0) {
19000Sstevel@tonic-gate if (nodep->node_dip)
19010Sstevel@tonic-gate ndi_hold_devi(nodep->node_dip);
19020Sstevel@tonic-gate *ret_node_datap = nodep;
19030Sstevel@tonic-gate *ret_dip = nodep->node_dip;
19040Sstevel@tonic-gate kmem_free(ap_id, len);
19050Sstevel@tonic-gate return (rv);
19060Sstevel@tonic-gate }
19070Sstevel@tonic-gate }
19080Sstevel@tonic-gate
19090Sstevel@tonic-gate } else if (first == NULL && second == NULL) {
19100Sstevel@tonic-gate /* This is an IOC ap_id */
19110Sstevel@tonic-gate for (nodep = ibnex.ibnex_ioc_node_head; nodep != NULL;
19120Sstevel@tonic-gate nodep = nodep->node_next) {
19130Sstevel@tonic-gate IBNEX_FORM_GUID(name, IBTL_IBNEX_APID_LEN,
19140Sstevel@tonic-gate nodep->node_data.ioc_node.ioc_guid);
19150Sstevel@tonic-gate if (strstr(dyn, name) != NULL) {
19160Sstevel@tonic-gate if (nodep->node_dip)
19170Sstevel@tonic-gate ndi_hold_devi(nodep->node_dip);
19180Sstevel@tonic-gate *ret_node_datap = nodep;
19190Sstevel@tonic-gate *ret_dip = nodep->node_dip;
19200Sstevel@tonic-gate kmem_free(ap_id, len);
19210Sstevel@tonic-gate return (rv);
19220Sstevel@tonic-gate }
19230Sstevel@tonic-gate }
19240Sstevel@tonic-gate }
19250Sstevel@tonic-gate
19260Sstevel@tonic-gate /* Could not find a matching IB device */
19270Sstevel@tonic-gate *ret_dip = (nodep) ? nodep->node_dip : NULL;
19280Sstevel@tonic-gate kmem_free(ap_id, len);
19290Sstevel@tonic-gate return (rv);
19300Sstevel@tonic-gate }
19310Sstevel@tonic-gate
19320Sstevel@tonic-gate
19330Sstevel@tonic-gate /*
19340Sstevel@tonic-gate * ibnex_handle_pseudo_configure()
19350Sstevel@tonic-gate * Do DEVCTL_AP_CONNECT processing for Pseudo devices only.
19360Sstevel@tonic-gate * The code also checks if the given ap_id is valid or not.
19370Sstevel@tonic-gate */
19380Sstevel@tonic-gate static ibnex_rval_t
ibnex_handle_pseudo_configure(char * apid)19390Sstevel@tonic-gate ibnex_handle_pseudo_configure(char *apid)
19400Sstevel@tonic-gate {
19410Sstevel@tonic-gate char *node_addr;
19420Sstevel@tonic-gate char *last = strrchr(apid, ':') + 1;
19430Sstevel@tonic-gate ibnex_rval_t retval = IBNEX_FAILURE;
19440Sstevel@tonic-gate ibnex_node_data_t *nodep;
19450Sstevel@tonic-gate
19460Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_handle_pseudo_configure: "
19470Sstevel@tonic-gate "last = %s\n\t\tapid = %s", last, apid);
19480Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
19490Sstevel@tonic-gate
19500Sstevel@tonic-gate /* Check if the APID is valid first */
19510Sstevel@tonic-gate if (apid == NULL || last == NULL) {
19520Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_handle_pseudo_configure: "
19530Sstevel@tonic-gate "invalid apid %s", apid);
19540Sstevel@tonic-gate return (retval);
19550Sstevel@tonic-gate }
19560Sstevel@tonic-gate
19570Sstevel@tonic-gate /* find the matching entry and configure it */
19580Sstevel@tonic-gate for (nodep = ibnex.ibnex_pseudo_node_head; nodep != NULL;
19590Sstevel@tonic-gate nodep = nodep->node_next) {
19601093Shiremath if (nodep->node_data.pseudo_node.pseudo_merge_node == 1)
19611093Shiremath continue;
19620Sstevel@tonic-gate node_addr = nodep->node_data.pseudo_node.pseudo_node_addr;
19630Sstevel@tonic-gate if (strncmp(node_addr, last, strlen(last)))
19640Sstevel@tonic-gate continue;
19650Sstevel@tonic-gate
19660Sstevel@tonic-gate if (nodep->node_dip != NULL) {
19670Sstevel@tonic-gate /*
19680Sstevel@tonic-gate * Return BUSY if another configure
19690Sstevel@tonic-gate * operation is in progress
19700Sstevel@tonic-gate */
19710Sstevel@tonic-gate if (nodep->node_state ==
19720Sstevel@tonic-gate IBNEX_CFGADM_CONFIGURING)
19730Sstevel@tonic-gate return (IBNEX_BUSY);
19740Sstevel@tonic-gate else
19750Sstevel@tonic-gate return (IBNEX_SUCCESS);
19760Sstevel@tonic-gate }
19770Sstevel@tonic-gate
19780Sstevel@tonic-gate /*
19790Sstevel@tonic-gate * Return BUSY if another unconfigure operation is
19800Sstevel@tonic-gate * in progress
19810Sstevel@tonic-gate */
19820Sstevel@tonic-gate if (nodep->node_state == IBNEX_CFGADM_UNCONFIGURING)
19830Sstevel@tonic-gate return (IBNEX_BUSY);
19840Sstevel@tonic-gate
19850Sstevel@tonic-gate ASSERT(nodep->node_state != IBNEX_CFGADM_CONFIGURED);
19860Sstevel@tonic-gate nodep->node_state = IBNEX_CFGADM_CONFIGURING;
19870Sstevel@tonic-gate
19880Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
19898082SRamaswamy.Tummala@Sun.COM retval = ibnex_pseudo_create_all_pi(nodep);
19900Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
19910Sstevel@tonic-gate if (retval == NDI_SUCCESS) {
19920Sstevel@tonic-gate nodep->node_state = IBNEX_CFGADM_CONFIGURED;
19930Sstevel@tonic-gate return (IBNEX_SUCCESS);
19940Sstevel@tonic-gate } else {
19950Sstevel@tonic-gate nodep->node_state = IBNEX_CFGADM_UNCONFIGURED;
19960Sstevel@tonic-gate return (IBNEX_FAILURE);
19970Sstevel@tonic-gate }
19980Sstevel@tonic-gate }
19990Sstevel@tonic-gate
20000Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\thandle_pseudo_configure: retval=%d",
20010Sstevel@tonic-gate retval);
20020Sstevel@tonic-gate return (retval);
20030Sstevel@tonic-gate }
20040Sstevel@tonic-gate
20050Sstevel@tonic-gate
20060Sstevel@tonic-gate /*
20070Sstevel@tonic-gate * ibnex_handle_ioc_configure()
20080Sstevel@tonic-gate * Do DEVCTL_AP_CONNECT processing for IOCs only.
20090Sstevel@tonic-gate * The code also checks if the given ap_id is valid or not.
20100Sstevel@tonic-gate */
20110Sstevel@tonic-gate static ibnex_rval_t
ibnex_handle_ioc_configure(char * apid)20120Sstevel@tonic-gate ibnex_handle_ioc_configure(char *apid)
20130Sstevel@tonic-gate {
20140Sstevel@tonic-gate int ret;
20150Sstevel@tonic-gate char *guid_str = strrchr(apid, ':') + 1;
20160Sstevel@tonic-gate ib_guid_t ioc_guid;
20170Sstevel@tonic-gate ibnex_rval_t retval = IBNEX_FAILURE;
20180Sstevel@tonic-gate ibdm_ioc_info_t *ioc_info;
20190Sstevel@tonic-gate
20200Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
20210Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_handle_ioc_configure: %s", apid);
20220Sstevel@tonic-gate
20230Sstevel@tonic-gate /* Check if the APID is valid first */
20240Sstevel@tonic-gate if (guid_str == NULL) {
20250Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex",
20260Sstevel@tonic-gate "\tibnex_handle_ioc_configure: invalid apid %s", apid);
20270Sstevel@tonic-gate return (retval);
20280Sstevel@tonic-gate }
20290Sstevel@tonic-gate
20300Sstevel@tonic-gate /*
20310Sstevel@tonic-gate * Call into IBDM to get IOC information
20320Sstevel@tonic-gate */
20330Sstevel@tonic-gate ioc_guid = ibnex_str2hex(guid_str, strlen(guid_str), &ret);
20340Sstevel@tonic-gate if (ret != IBNEX_SUCCESS)
20350Sstevel@tonic-gate return (ret);
20360Sstevel@tonic-gate
20370Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex",
20380Sstevel@tonic-gate "\tibnex_handle_ioc_configure: IOC GUID = %llX", ioc_guid);
20390Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
20400Sstevel@tonic-gate ioc_info = ibdm_ibnex_get_ioc_info(ioc_guid);
20410Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
20420Sstevel@tonic-gate if (ioc_info == NULL) {
20430Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
20440Sstevel@tonic-gate "\tibnex_handle_ioc_configure: probe_iocguid failed");
20450Sstevel@tonic-gate return (retval);
20460Sstevel@tonic-gate }
20470Sstevel@tonic-gate
20488082SRamaswamy.Tummala@Sun.COM retval = ibnex_ioc_initnode_all_pi(ioc_info);
20490Sstevel@tonic-gate ibdm_ibnex_free_ioc_list(ioc_info);
20500Sstevel@tonic-gate
20510Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_handle_ioc_configure: "
20520Sstevel@tonic-gate "done retval = %d", retval);
20530Sstevel@tonic-gate return (retval);
20540Sstevel@tonic-gate }
20550Sstevel@tonic-gate
20560Sstevel@tonic-gate
20570Sstevel@tonic-gate /*
20580Sstevel@tonic-gate * ibnex_handle_commsvcnode_configure()
20590Sstevel@tonic-gate * Do DEVCTL_AP_CONNECT processing
20600Sstevel@tonic-gate * This is done for Port/VPPA/HCA_SVC drivers Only.
20610Sstevel@tonic-gate * The code also checks if the given ap_id is valid or not.
20620Sstevel@tonic-gate */
20630Sstevel@tonic-gate static ibnex_rval_t
ibnex_handle_commsvcnode_configure(char * apid)20640Sstevel@tonic-gate ibnex_handle_commsvcnode_configure(char *apid)
20650Sstevel@tonic-gate {
20668082SRamaswamy.Tummala@Sun.COM int ret, str_len, circ;
20670Sstevel@tonic-gate int sndx;
20680Sstevel@tonic-gate int port_pkey = 0;
20690Sstevel@tonic-gate char *pkey_str = strchr(apid, ',');
20700Sstevel@tonic-gate char *guid_str = strrchr(apid, ':') + 1;
20710Sstevel@tonic-gate char *svc_str = strrchr(pkey_str, ',');
20720Sstevel@tonic-gate boolean_t found = B_FALSE;
20730Sstevel@tonic-gate boolean_t is_hcasvc_node = B_FALSE;
20740Sstevel@tonic-gate ib_guid_t guid; /* Port / Node GUID */
20750Sstevel@tonic-gate dev_info_t *parent;
20760Sstevel@tonic-gate ibnex_rval_t retval = IBNEX_FAILURE;
20770Sstevel@tonic-gate ibdm_port_attr_t *port_attr;
20780Sstevel@tonic-gate int node_type;
20790Sstevel@tonic-gate ibdm_hca_list_t *hca_list;
20800Sstevel@tonic-gate
20810Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
20820Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_handle_commsvcnode_configure: %s",
20830Sstevel@tonic-gate apid);
20840Sstevel@tonic-gate
20850Sstevel@tonic-gate /* Check if the APID is valid first */
20860Sstevel@tonic-gate if (guid_str == NULL || ((guid_str != NULL) &&
20870Sstevel@tonic-gate (pkey_str == NULL || svc_str == NULL))) {
20880Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex",
20890Sstevel@tonic-gate "\tibnex_handle_commsvcnode_configure: "
20900Sstevel@tonic-gate "invalid apid %s", apid);
20910Sstevel@tonic-gate return (retval);
20920Sstevel@tonic-gate }
20930Sstevel@tonic-gate
20940Sstevel@tonic-gate /* guid_str contains GUID,p_key,svc_name. Change it to GUID */
20950Sstevel@tonic-gate str_len = strlen(guid_str) - strlen(pkey_str);
20960Sstevel@tonic-gate guid_str[str_len] = '\0';
20970Sstevel@tonic-gate
20980Sstevel@tonic-gate /* convert the string GUID to hex value */
20990Sstevel@tonic-gate guid = ibnex_str2hex(guid_str, strlen(guid_str), &ret);
21000Sstevel@tonic-gate if (ret == IBNEX_FAILURE)
21010Sstevel@tonic-gate return (ret);
21020Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_handle_commsvcnode_configure: "
21030Sstevel@tonic-gate "Port / Node Guid %llX", guid);
21040Sstevel@tonic-gate
21050Sstevel@tonic-gate /* figure out Port/HCA_SVC or VPPA. Also figure out the P_Key. */
21060Sstevel@tonic-gate ++pkey_str; /* pkey_str used to point to ",p_key,svc_name" */
21070Sstevel@tonic-gate
21080Sstevel@tonic-gate /* pkey_str contains p_key,svc_name. Change it to P_Key */
21090Sstevel@tonic-gate str_len = strlen(pkey_str) - strlen(svc_str);
21100Sstevel@tonic-gate pkey_str[str_len] = '\0';
21110Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "\tibnex_handle_commsvcnode_configure: "
21120Sstevel@tonic-gate "p_key %s", pkey_str);
21130Sstevel@tonic-gate
21140Sstevel@tonic-gate /* convert the string P_Key to a hexadecimal value */
21150Sstevel@tonic-gate port_pkey = ibnex_str2hex(pkey_str, strlen(pkey_str), &ret);
21160Sstevel@tonic-gate IBTF_DPRINTF_L5("ibnex", "\tibnex_handle_commsvcnode_configure: "
21170Sstevel@tonic-gate "PKEY num %x", port_pkey);
21180Sstevel@tonic-gate if (ret == IBNEX_FAILURE)
21190Sstevel@tonic-gate return (ret);
21200Sstevel@tonic-gate
21210Sstevel@tonic-gate ++svc_str; /* svc_str used to point to ",svc_name" */
21220Sstevel@tonic-gate
21230Sstevel@tonic-gate /* find the service index */
21240Sstevel@tonic-gate if (port_pkey == 0) {
21250Sstevel@tonic-gate /* PORT Devices */
21260Sstevel@tonic-gate for (sndx = 0; sndx < ibnex.ibnex_num_comm_svcs; sndx++) {
21270Sstevel@tonic-gate if (strncmp(ibnex.ibnex_comm_svc_names[sndx],
21280Sstevel@tonic-gate svc_str, strlen(svc_str)) == 0) {
21290Sstevel@tonic-gate found = B_TRUE;
21300Sstevel@tonic-gate break;
21310Sstevel@tonic-gate }
21320Sstevel@tonic-gate }
21330Sstevel@tonic-gate
21340Sstevel@tonic-gate /* HCA_SVC Devices */
21350Sstevel@tonic-gate if (found == B_FALSE) {
21360Sstevel@tonic-gate for (sndx = 0; sndx < ibnex.ibnex_nhcasvc_comm_svcs;
21370Sstevel@tonic-gate sndx++) {
21380Sstevel@tonic-gate if (strncmp(ibnex.ibnex_hcasvc_comm_svc_names
21390Sstevel@tonic-gate [sndx], svc_str, strlen(svc_str)) == 0) {
21400Sstevel@tonic-gate found = B_TRUE;
21410Sstevel@tonic-gate is_hcasvc_node = B_TRUE;
21420Sstevel@tonic-gate break;
21430Sstevel@tonic-gate }
21440Sstevel@tonic-gate }
21450Sstevel@tonic-gate }
21460Sstevel@tonic-gate
21470Sstevel@tonic-gate } else {
21480Sstevel@tonic-gate for (sndx = 0; sndx < ibnex.ibnex_nvppa_comm_svcs; sndx++) {
21490Sstevel@tonic-gate if (strncmp(ibnex.ibnex_vppa_comm_svc_names[sndx],
21500Sstevel@tonic-gate svc_str, strlen(svc_str)) == 0) {
21510Sstevel@tonic-gate found = B_TRUE;
21520Sstevel@tonic-gate break;
21530Sstevel@tonic-gate }
21540Sstevel@tonic-gate }
21550Sstevel@tonic-gate }
21560Sstevel@tonic-gate
21570Sstevel@tonic-gate if (found == B_FALSE) {
21580Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
21590Sstevel@tonic-gate "\tibnex_handle_commsvcnode_configure: "
21600Sstevel@tonic-gate "invalid service %s", svc_str);
21610Sstevel@tonic-gate return (retval);
21620Sstevel@tonic-gate }
21630Sstevel@tonic-gate
21640Sstevel@tonic-gate /* get Port attributes structure */
21650Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
21660Sstevel@tonic-gate if (is_hcasvc_node == B_FALSE) {
21670Sstevel@tonic-gate port_attr = ibdm_ibnex_get_port_attrs(guid);
21680Sstevel@tonic-gate if (port_attr == NULL) {
21690Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
21700Sstevel@tonic-gate "\tibnex_handle_commsvcnode_configure: "
21710Sstevel@tonic-gate "ibdm_ibnex_get_port_attrs failed");
21720Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
21730Sstevel@tonic-gate return (retval);
21740Sstevel@tonic-gate }
21750Sstevel@tonic-gate } else {
21760Sstevel@tonic-gate hca_list = ibdm_ibnex_get_hca_info_by_guid(guid);
21770Sstevel@tonic-gate if (hca_list == NULL) {
21780Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
21790Sstevel@tonic-gate "\tibnex_handle_commsvcnode_configure: "
21800Sstevel@tonic-gate "ibdm_ibnex_get_hca_info_by_guid failed");
21810Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
21820Sstevel@tonic-gate return (retval);
21830Sstevel@tonic-gate }
21840Sstevel@tonic-gate port_attr = hca_list->hl_hca_port_attr;
21850Sstevel@tonic-gate }
21860Sstevel@tonic-gate
21870Sstevel@tonic-gate /* get HCA's dip */
21880Sstevel@tonic-gate parent = ibtl_ibnex_hcaguid2dip(port_attr->pa_hca_guid);
21890Sstevel@tonic-gate
21900Sstevel@tonic-gate if (parent == NULL) {
21910Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex",
21920Sstevel@tonic-gate "\tibnex_handle_commsvcnode_configure: "
21930Sstevel@tonic-gate "no HCA present");
21940Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
21950Sstevel@tonic-gate if (is_hcasvc_node == B_FALSE)
21960Sstevel@tonic-gate ibdm_ibnex_free_port_attr(port_attr);
21970Sstevel@tonic-gate else
21980Sstevel@tonic-gate ibdm_ibnex_free_hca_list(hca_list);
21990Sstevel@tonic-gate return (retval);
22000Sstevel@tonic-gate }
22010Sstevel@tonic-gate
22020Sstevel@tonic-gate if (port_pkey == 0)
22030Sstevel@tonic-gate node_type = (is_hcasvc_node == B_FALSE) ?
22040Sstevel@tonic-gate IBNEX_PORT_COMMSVC_NODE : IBNEX_HCASVC_COMMSVC_NODE;
22050Sstevel@tonic-gate else
22060Sstevel@tonic-gate node_type = IBNEX_VPPA_COMMSVC_NODE;
22070Sstevel@tonic-gate
22080Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
22098082SRamaswamy.Tummala@Sun.COM ndi_devi_enter(parent, &circ);
22100Sstevel@tonic-gate if (ibnex_commsvc_initnode(parent, port_attr, sndx, node_type,
22110Sstevel@tonic-gate port_pkey, &ret, IBNEX_CFGADM_ENUMERATE) != NULL) {
22120Sstevel@tonic-gate retval = IBNEX_SUCCESS;
22130Sstevel@tonic-gate } else {
22140Sstevel@tonic-gate retval = (ret == IBNEX_BUSY) ? IBNEX_BUSY : IBNEX_FAILURE;
22150Sstevel@tonic-gate }
22168082SRamaswamy.Tummala@Sun.COM ndi_devi_exit(parent, circ);
22170Sstevel@tonic-gate
22180Sstevel@tonic-gate if (is_hcasvc_node == B_FALSE)
22190Sstevel@tonic-gate ibdm_ibnex_free_port_attr(port_attr);
22200Sstevel@tonic-gate else
22210Sstevel@tonic-gate ibdm_ibnex_free_hca_list(hca_list);
22220Sstevel@tonic-gate
22230Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tibnex_handle_commsvcnode_configure: "
22240Sstevel@tonic-gate "done retval = %d", retval);
22250Sstevel@tonic-gate
22260Sstevel@tonic-gate return (retval);
22270Sstevel@tonic-gate }
22280Sstevel@tonic-gate
22290Sstevel@tonic-gate
22300Sstevel@tonic-gate /*
22310Sstevel@tonic-gate * ibnex_return_apid()
22320Sstevel@tonic-gate * Construct the ap_id of a given IBTF client in kernel
22330Sstevel@tonic-gate */
22340Sstevel@tonic-gate static void
ibnex_return_apid(dev_info_t * childp,char ** ret_apid)22350Sstevel@tonic-gate ibnex_return_apid(dev_info_t *childp, char **ret_apid)
22360Sstevel@tonic-gate {
22370Sstevel@tonic-gate ibnex_node_data_t *nodep;
22380Sstevel@tonic-gate
22390Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_return_apid:");
22400Sstevel@tonic-gate
22410Sstevel@tonic-gate ASSERT(childp != NULL);
22420Sstevel@tonic-gate nodep = ddi_get_parent_data(childp);
22430Sstevel@tonic-gate
22440Sstevel@tonic-gate if (nodep->node_type == IBNEX_PORT_COMMSVC_NODE) {
22450Sstevel@tonic-gate (void) snprintf(*ret_apid, IBTL_IBNEX_APID_LEN,
22460Sstevel@tonic-gate "ib%s%llX,0,%s", DYN_SEP,
22470Sstevel@tonic-gate (longlong_t)nodep->node_data.port_node.port_guid,
22480Sstevel@tonic-gate ibnex.ibnex_comm_svc_names[nodep->node_data.port_node.
22490Sstevel@tonic-gate port_commsvc_idx]);
22500Sstevel@tonic-gate
22510Sstevel@tonic-gate } else if (nodep->node_type == IBNEX_HCASVC_COMMSVC_NODE) {
22520Sstevel@tonic-gate (void) snprintf(*ret_apid, IBTL_IBNEX_APID_LEN,
22530Sstevel@tonic-gate "ib%s%llX,0,%s", DYN_SEP,
22540Sstevel@tonic-gate (longlong_t)nodep->node_data.port_node.port_guid, ibnex.
22550Sstevel@tonic-gate ibnex_hcasvc_comm_svc_names[nodep->node_data.port_node.
22560Sstevel@tonic-gate port_commsvc_idx]);
22570Sstevel@tonic-gate
22580Sstevel@tonic-gate } else if (nodep->node_type == IBNEX_VPPA_COMMSVC_NODE) {
22590Sstevel@tonic-gate (void) snprintf(*ret_apid, IBTL_IBNEX_APID_LEN,
22600Sstevel@tonic-gate "ib%s%llX,%x,%s", DYN_SEP,
22610Sstevel@tonic-gate (longlong_t)nodep->node_data.port_node.port_guid,
22620Sstevel@tonic-gate nodep->node_data.port_node.port_pkey,
22630Sstevel@tonic-gate ibnex.ibnex_vppa_comm_svc_names[nodep->node_data.port_node.
22640Sstevel@tonic-gate port_commsvc_idx]);
22650Sstevel@tonic-gate
22660Sstevel@tonic-gate } else if (nodep->node_type == IBNEX_IOC_NODE) {
22670Sstevel@tonic-gate (void) snprintf(*ret_apid, IBTL_IBNEX_APID_LEN,
22680Sstevel@tonic-gate "ib%s%llX", DYN_SEP,
22690Sstevel@tonic-gate (longlong_t)nodep->node_data.ioc_node.ioc_guid);
22700Sstevel@tonic-gate
22710Sstevel@tonic-gate } else if (nodep->node_type == IBNEX_PSEUDO_NODE) {
22720Sstevel@tonic-gate (void) snprintf(*ret_apid, IBTL_IBNEX_APID_LEN, "ib%s%s",
22730Sstevel@tonic-gate DYN_SEP, nodep->node_data.pseudo_node.pseudo_node_addr);
22740Sstevel@tonic-gate
22750Sstevel@tonic-gate } else {
22760Sstevel@tonic-gate (void) snprintf(*ret_apid, IBTL_IBNEX_APID_LEN, "%s", "-");
22770Sstevel@tonic-gate }
22780Sstevel@tonic-gate
22790Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "ibnex_return_apid: %x %s",
22800Sstevel@tonic-gate nodep->node_type, ret_apid);
22810Sstevel@tonic-gate }
22820Sstevel@tonic-gate
22830Sstevel@tonic-gate
22840Sstevel@tonic-gate /*
22850Sstevel@tonic-gate * ibnex_vppa_conf_entry_add()
22860Sstevel@tonic-gate * Add a new service to the ibnex data base of VPPA communication
22870Sstevel@tonic-gate * services.
22880Sstevel@tonic-gate */
22890Sstevel@tonic-gate static void
ibnex_vppa_conf_entry_add(char * service)22900Sstevel@tonic-gate ibnex_vppa_conf_entry_add(char *service)
22910Sstevel@tonic-gate {
22920Sstevel@tonic-gate int i, nsvcs;
22930Sstevel@tonic-gate char **service_name;
22940Sstevel@tonic-gate
22950Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
22960Sstevel@tonic-gate nsvcs = ibnex.ibnex_nvppa_comm_svcs;
22970Sstevel@tonic-gate
22980Sstevel@tonic-gate /* Allocate space for new "ibnex.ibnex_nvppa_comm_svcs + 1" */
22990Sstevel@tonic-gate service_name = kmem_alloc((nsvcs + 1) * sizeof (char *), KM_SLEEP);
23000Sstevel@tonic-gate /*
23010Sstevel@tonic-gate * Copy over the existing "ibnex.ibnex_vppa_comm_svc_names"
23020Sstevel@tonic-gate * array. Add the new service at the end.
23030Sstevel@tonic-gate */
23040Sstevel@tonic-gate for (i = 0; i < nsvcs; i++)
23050Sstevel@tonic-gate service_name[i] = ibnex.ibnex_vppa_comm_svc_names[i];
23060Sstevel@tonic-gate service_name[i] = kmem_alloc(strlen(service) + 1, KM_SLEEP);
23070Sstevel@tonic-gate (void) snprintf(service_name[i], 5, "%s", service);
23080Sstevel@tonic-gate
23090Sstevel@tonic-gate /* Replace existing pointer to VPPA services w/ newly allocated one */
23100Sstevel@tonic-gate if (ibnex.ibnex_vppa_comm_svc_names) {
23110Sstevel@tonic-gate kmem_free(ibnex.ibnex_vppa_comm_svc_names, nsvcs *
23120Sstevel@tonic-gate sizeof (char *));
23130Sstevel@tonic-gate }
23140Sstevel@tonic-gate ibnex.ibnex_nvppa_comm_svcs++;
23150Sstevel@tonic-gate ibnex.ibnex_vppa_comm_svc_names = service_name;
23160Sstevel@tonic-gate }
23170Sstevel@tonic-gate
23180Sstevel@tonic-gate /*
23190Sstevel@tonic-gate * ibnex_port_conf_entry_add()
23200Sstevel@tonic-gate * Add a new service to the ibnex data base of Port communication
23210Sstevel@tonic-gate * services.
23220Sstevel@tonic-gate */
23230Sstevel@tonic-gate static void
ibnex_port_conf_entry_add(char * service)23240Sstevel@tonic-gate ibnex_port_conf_entry_add(char *service)
23250Sstevel@tonic-gate {
23260Sstevel@tonic-gate int i, nsvcs;
23270Sstevel@tonic-gate char **service_name;
23280Sstevel@tonic-gate
23290Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
23300Sstevel@tonic-gate nsvcs = ibnex.ibnex_num_comm_svcs;
23310Sstevel@tonic-gate
23320Sstevel@tonic-gate /* Allocate space for new "ibnex.ibnex_num_comm_svcs + 1" */
23330Sstevel@tonic-gate service_name = kmem_alloc((nsvcs + 1) * sizeof (char *), KM_SLEEP);
23340Sstevel@tonic-gate /*
23350Sstevel@tonic-gate * Copy over the existing "ibnex.ibnex_comm_svc_names" array.
23360Sstevel@tonic-gate * Add the new service to the end.
23370Sstevel@tonic-gate */
23380Sstevel@tonic-gate for (i = 0; i < nsvcs; i++)
23390Sstevel@tonic-gate service_name[i] = ibnex.ibnex_comm_svc_names[i];
23400Sstevel@tonic-gate service_name[i] = kmem_alloc(strlen(service) + 1, KM_SLEEP);
23410Sstevel@tonic-gate (void) snprintf(service_name[i], 5, "%s", service);
23420Sstevel@tonic-gate
23430Sstevel@tonic-gate /* Replace existing pointer to Port services w/ newly allocated one */
23440Sstevel@tonic-gate if (ibnex.ibnex_comm_svc_names) {
23450Sstevel@tonic-gate kmem_free(ibnex.ibnex_comm_svc_names, nsvcs * sizeof (char *));
23460Sstevel@tonic-gate }
23470Sstevel@tonic-gate ibnex.ibnex_num_comm_svcs++;
23480Sstevel@tonic-gate ibnex.ibnex_comm_svc_names = service_name;
23490Sstevel@tonic-gate }
23500Sstevel@tonic-gate
23510Sstevel@tonic-gate /*
23520Sstevel@tonic-gate * ibnex_hcasvc_conf_entry_add()
23530Sstevel@tonic-gate * Add a new service to the ibnex data base of HCA_SVC communication
23540Sstevel@tonic-gate * services.
23550Sstevel@tonic-gate */
23560Sstevel@tonic-gate static void
ibnex_hcasvc_conf_entry_add(char * service)23570Sstevel@tonic-gate ibnex_hcasvc_conf_entry_add(char *service)
23580Sstevel@tonic-gate {
23590Sstevel@tonic-gate int i, nsvcs;
23600Sstevel@tonic-gate char **service_name;
23610Sstevel@tonic-gate
23620Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
23630Sstevel@tonic-gate nsvcs = ibnex.ibnex_nhcasvc_comm_svcs;
23640Sstevel@tonic-gate
23650Sstevel@tonic-gate /* Allocate space for new "ibnex.ibnex_nvppa_comm_svcs + 1" */
23660Sstevel@tonic-gate service_name = kmem_alloc((nsvcs + 1) * sizeof (char *), KM_SLEEP);
23670Sstevel@tonic-gate /*
23680Sstevel@tonic-gate * Copy over the existing "ibnex.ibnex_hcasvc_comm_svc_names"
23690Sstevel@tonic-gate * array. Add the new service at the end.
23700Sstevel@tonic-gate */
23710Sstevel@tonic-gate for (i = 0; i < nsvcs; i++)
23720Sstevel@tonic-gate service_name[i] = ibnex.ibnex_hcasvc_comm_svc_names[i];
23730Sstevel@tonic-gate service_name[i] = kmem_alloc(strlen(service) + 1, KM_SLEEP);
23740Sstevel@tonic-gate (void) snprintf(service_name[i], 5, "%s", service);
23750Sstevel@tonic-gate
23760Sstevel@tonic-gate /*
23770Sstevel@tonic-gate * Replace existing pointer to HCA_SVC services w/ newly
23780Sstevel@tonic-gate * allocated one
23790Sstevel@tonic-gate */
23800Sstevel@tonic-gate if (ibnex.ibnex_hcasvc_comm_svc_names) {
23810Sstevel@tonic-gate kmem_free(ibnex.ibnex_hcasvc_comm_svc_names, nsvcs *
23820Sstevel@tonic-gate sizeof (char *));
23830Sstevel@tonic-gate }
23840Sstevel@tonic-gate ibnex.ibnex_nhcasvc_comm_svcs++;
23850Sstevel@tonic-gate ibnex.ibnex_hcasvc_comm_svc_names = service_name;
23860Sstevel@tonic-gate }
23870Sstevel@tonic-gate
23880Sstevel@tonic-gate
23890Sstevel@tonic-gate /*
23900Sstevel@tonic-gate * ibnex_vppa_conf_entry_delete()
23910Sstevel@tonic-gate * Delete an existing service entry from ibnex data base of
23920Sstevel@tonic-gate * VPPA communication services.
23930Sstevel@tonic-gate */
23940Sstevel@tonic-gate static int
ibnex_vppa_conf_entry_delete(char * msg,char * service)23950Sstevel@tonic-gate ibnex_vppa_conf_entry_delete(char *msg, char *service)
23960Sstevel@tonic-gate {
23970Sstevel@tonic-gate int i, j, nsvcs;
23980Sstevel@tonic-gate int len;
23990Sstevel@tonic-gate int match_ndx;
24000Sstevel@tonic-gate char **service_name;
24010Sstevel@tonic-gate boolean_t found = B_FALSE;
24020Sstevel@tonic-gate ibnex_node_data_t *node_datap = ibnex.ibnex_port_node_head;
24030Sstevel@tonic-gate
24040Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tvppa_conf_entry_delete: %s", service);
24050Sstevel@tonic-gate
24060Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
24070Sstevel@tonic-gate nsvcs = ibnex.ibnex_nvppa_comm_svcs;
24080Sstevel@tonic-gate
24090Sstevel@tonic-gate /* find matching index */
24100Sstevel@tonic-gate for (i = 0; i < nsvcs; i++) {
24119713SBill.Taylor@Sun.COM if (strcmp(ibnex.ibnex_vppa_comm_svc_names[i], service))
24120Sstevel@tonic-gate continue;
24130Sstevel@tonic-gate found = B_TRUE;
24140Sstevel@tonic-gate match_ndx = i;
24150Sstevel@tonic-gate break;
24160Sstevel@tonic-gate }
24170Sstevel@tonic-gate
24180Sstevel@tonic-gate /* check for valid "nsvcs" */
24190Sstevel@tonic-gate if (found == B_FALSE || nsvcs == 0) {
24200Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid vppa services %x",
24210Sstevel@tonic-gate msg, nsvcs);
24220Sstevel@tonic-gate return (EIO);
24230Sstevel@tonic-gate }
24240Sstevel@tonic-gate
24250Sstevel@tonic-gate /* Check if service is in use; return failure if so */
24260Sstevel@tonic-gate for (; node_datap; node_datap = node_datap->node_next) {
24270Sstevel@tonic-gate if ((node_datap->node_data.port_node.port_commsvc_idx == i) &&
24280Sstevel@tonic-gate node_datap->node_type == IBNEX_VPPA_COMMSVC_NODE &&
24290Sstevel@tonic-gate node_datap->node_dip) {
24300Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: service %s is in use",
24310Sstevel@tonic-gate msg, service);
24320Sstevel@tonic-gate return (EIO);
24330Sstevel@tonic-gate }
24340Sstevel@tonic-gate }
24350Sstevel@tonic-gate
24360Sstevel@tonic-gate /* if nsvcs == 1, bailout early */
24370Sstevel@tonic-gate if (nsvcs == 1) {
24380Sstevel@tonic-gate /* free up that single entry */
24390Sstevel@tonic-gate len = strlen(ibnex.ibnex_vppa_comm_svc_names[0]) + 1;
24400Sstevel@tonic-gate kmem_free(ibnex.ibnex_vppa_comm_svc_names[0], len);
24410Sstevel@tonic-gate kmem_free(ibnex.ibnex_vppa_comm_svc_names, sizeof (char *));
24420Sstevel@tonic-gate ibnex.ibnex_vppa_comm_svc_names = NULL;
24430Sstevel@tonic-gate ibnex.ibnex_nvppa_comm_svcs = 0;
24440Sstevel@tonic-gate return (0);
24450Sstevel@tonic-gate }
24460Sstevel@tonic-gate
24470Sstevel@tonic-gate /* Allocate space for new "ibnex.ibnex_nvppa_comm_svcs - 1" */
24480Sstevel@tonic-gate service_name = kmem_alloc((nsvcs - 1) * sizeof (char *), KM_SLEEP);
24490Sstevel@tonic-gate /*
24500Sstevel@tonic-gate * Copy over the existing "ibnex.ibnex_vppa_comm_svc_names"
24510Sstevel@tonic-gate * array. Do not copy over the matching service.
24520Sstevel@tonic-gate */
24530Sstevel@tonic-gate for (i = 0, j = 0; i < nsvcs; i++) {
24540Sstevel@tonic-gate if (i == match_ndx) {
24550Sstevel@tonic-gate /* free up that entry */
24560Sstevel@tonic-gate len = strlen(ibnex.ibnex_vppa_comm_svc_names[i]) + 1;
24570Sstevel@tonic-gate kmem_free(ibnex.ibnex_vppa_comm_svc_names[i], len);
24580Sstevel@tonic-gate continue;
24590Sstevel@tonic-gate }
24600Sstevel@tonic-gate service_name[j++] = ibnex.ibnex_vppa_comm_svc_names[i];
24610Sstevel@tonic-gate }
24620Sstevel@tonic-gate
24630Sstevel@tonic-gate /* Replace existing pointer to VPPA services w/ newly adjusted one */
24640Sstevel@tonic-gate if (ibnex.ibnex_vppa_comm_svc_names) {
24650Sstevel@tonic-gate kmem_free(ibnex.ibnex_vppa_comm_svc_names, nsvcs *
24660Sstevel@tonic-gate sizeof (char *));
24670Sstevel@tonic-gate ibnex.ibnex_nvppa_comm_svcs--;
24680Sstevel@tonic-gate ibnex.ibnex_vppa_comm_svc_names = service_name;
24690Sstevel@tonic-gate }
24700Sstevel@tonic-gate return (0);
24710Sstevel@tonic-gate }
24720Sstevel@tonic-gate
24730Sstevel@tonic-gate
24740Sstevel@tonic-gate /*
24750Sstevel@tonic-gate * ibnex_port_conf_entry_delete()
24760Sstevel@tonic-gate * Delete an existing service entry from ibnex data base of
24770Sstevel@tonic-gate * Port communication services.
24780Sstevel@tonic-gate */
24790Sstevel@tonic-gate static int
ibnex_port_conf_entry_delete(char * msg,char * service)24800Sstevel@tonic-gate ibnex_port_conf_entry_delete(char *msg, char *service)
24810Sstevel@tonic-gate {
24820Sstevel@tonic-gate int i, j, nsvcs;
24830Sstevel@tonic-gate int match_ndx;
24840Sstevel@tonic-gate int len;
24850Sstevel@tonic-gate char **service_name;
24860Sstevel@tonic-gate boolean_t found = B_FALSE;
24870Sstevel@tonic-gate ibnex_node_data_t *node_datap = ibnex.ibnex_port_node_head;
24880Sstevel@tonic-gate
24890Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tport_conf_entry_delete: %s", service);
24900Sstevel@tonic-gate
24910Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
24920Sstevel@tonic-gate nsvcs = ibnex.ibnex_num_comm_svcs;
24930Sstevel@tonic-gate
24940Sstevel@tonic-gate /* find matching index */
24950Sstevel@tonic-gate for (i = 0; i < nsvcs; i++) {
24969713SBill.Taylor@Sun.COM if (strcmp(ibnex.ibnex_comm_svc_names[i], service))
24970Sstevel@tonic-gate continue;
24980Sstevel@tonic-gate found = B_TRUE;
24990Sstevel@tonic-gate match_ndx = i;
25000Sstevel@tonic-gate break;
25010Sstevel@tonic-gate }
25020Sstevel@tonic-gate
25030Sstevel@tonic-gate /* check for valid "nsvcs" */
25040Sstevel@tonic-gate if (found == B_FALSE || nsvcs == 0) {
25050Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid services %x", msg, nsvcs);
25060Sstevel@tonic-gate return (EIO);
25070Sstevel@tonic-gate }
25080Sstevel@tonic-gate
25090Sstevel@tonic-gate /* Check if service is in use; return failure if so */
25100Sstevel@tonic-gate for (; node_datap; node_datap = node_datap->node_next) {
25110Sstevel@tonic-gate if ((node_datap->node_data.port_node.port_commsvc_idx == i) &&
25120Sstevel@tonic-gate node_datap->node_type == IBNEX_PORT_COMMSVC_NODE &&
25130Sstevel@tonic-gate node_datap->node_dip)
25140Sstevel@tonic-gate return (EIO);
25150Sstevel@tonic-gate }
25160Sstevel@tonic-gate
25170Sstevel@tonic-gate /* if nsvcs == 1, bailout early */
25180Sstevel@tonic-gate if (nsvcs == 1) {
25190Sstevel@tonic-gate /* free up that single entry */
25200Sstevel@tonic-gate len = strlen(ibnex.ibnex_comm_svc_names[0]) + 1;
25210Sstevel@tonic-gate kmem_free(ibnex.ibnex_comm_svc_names[0], len);
25220Sstevel@tonic-gate kmem_free(ibnex.ibnex_comm_svc_names, sizeof (char *));
25230Sstevel@tonic-gate ibnex.ibnex_comm_svc_names = NULL;
25240Sstevel@tonic-gate ibnex.ibnex_num_comm_svcs = 0;
25250Sstevel@tonic-gate return (0);
25260Sstevel@tonic-gate }
25270Sstevel@tonic-gate
25280Sstevel@tonic-gate /* Allocate space for new "ibnex.ibnex_num_comm_svcs - 1" */
25290Sstevel@tonic-gate service_name = kmem_alloc((nsvcs - 1) * sizeof (char *), KM_SLEEP);
25300Sstevel@tonic-gate /*
25310Sstevel@tonic-gate * Copy over the existing "ibnex.ibnex_comm_svc_names" array.
25320Sstevel@tonic-gate * Skip the matching service.
25330Sstevel@tonic-gate */
25340Sstevel@tonic-gate for (i = 0, j = 0; i < nsvcs; i++) {
25350Sstevel@tonic-gate if (i == match_ndx) {
25360Sstevel@tonic-gate /* free up that entry */
25370Sstevel@tonic-gate len = strlen(ibnex.ibnex_comm_svc_names[i]) + 1;
25380Sstevel@tonic-gate kmem_free(ibnex.ibnex_comm_svc_names[i], len);
25390Sstevel@tonic-gate continue;
25400Sstevel@tonic-gate }
25410Sstevel@tonic-gate service_name[j++] = ibnex.ibnex_comm_svc_names[i];
25420Sstevel@tonic-gate }
25430Sstevel@tonic-gate
25440Sstevel@tonic-gate /* Replace existing pointer to Port services w/ newly adjusted one */
25450Sstevel@tonic-gate if (ibnex.ibnex_comm_svc_names) {
25460Sstevel@tonic-gate kmem_free(ibnex.ibnex_comm_svc_names, nsvcs * sizeof (char *));
25470Sstevel@tonic-gate ibnex.ibnex_num_comm_svcs--;
25480Sstevel@tonic-gate ibnex.ibnex_comm_svc_names = service_name;
25490Sstevel@tonic-gate }
25500Sstevel@tonic-gate return (0);
25510Sstevel@tonic-gate }
25520Sstevel@tonic-gate
25530Sstevel@tonic-gate /*
25540Sstevel@tonic-gate * ibnex_hcasvc_conf_entry_delete()
25550Sstevel@tonic-gate * Delete an existing service entry from ibnex data base of
25560Sstevel@tonic-gate * HCA_SVC communication services.
25570Sstevel@tonic-gate */
25580Sstevel@tonic-gate static int
ibnex_hcasvc_conf_entry_delete(char * msg,char * service)25590Sstevel@tonic-gate ibnex_hcasvc_conf_entry_delete(char *msg, char *service)
25600Sstevel@tonic-gate {
25610Sstevel@tonic-gate int i, j, nsvcs;
25620Sstevel@tonic-gate int len;
25630Sstevel@tonic-gate int match_ndx;
25640Sstevel@tonic-gate char **service_name;
25650Sstevel@tonic-gate boolean_t found = B_FALSE;
25660Sstevel@tonic-gate ibnex_node_data_t *node_datap = ibnex.ibnex_port_node_head;
25670Sstevel@tonic-gate
25680Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\thcasvc_conf_entry_delete: %s", service);
25690Sstevel@tonic-gate
25700Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
25710Sstevel@tonic-gate nsvcs = ibnex.ibnex_nhcasvc_comm_svcs;
25720Sstevel@tonic-gate
25730Sstevel@tonic-gate /* find matching index */
25740Sstevel@tonic-gate for (i = 0; i < nsvcs; i++) {
25759713SBill.Taylor@Sun.COM if (strcmp(ibnex.ibnex_hcasvc_comm_svc_names[i], service))
25760Sstevel@tonic-gate continue;
25770Sstevel@tonic-gate found = B_TRUE;
25780Sstevel@tonic-gate match_ndx = i;
25790Sstevel@tonic-gate break;
25800Sstevel@tonic-gate }
25810Sstevel@tonic-gate
25820Sstevel@tonic-gate /* check for valid "nsvcs" */
25830Sstevel@tonic-gate if (found == B_FALSE || nsvcs == 0) {
25840Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: invalid hca_svc services %x",
25850Sstevel@tonic-gate msg, nsvcs);
25860Sstevel@tonic-gate return (EIO);
25870Sstevel@tonic-gate }
25880Sstevel@tonic-gate
25890Sstevel@tonic-gate /* Check if service is in use; return failure if so */
25900Sstevel@tonic-gate for (; node_datap; node_datap = node_datap->node_next) {
25910Sstevel@tonic-gate if ((node_datap->node_data.port_node.port_commsvc_idx == i) &&
25920Sstevel@tonic-gate node_datap->node_type == IBNEX_HCASVC_COMMSVC_NODE &&
25930Sstevel@tonic-gate node_datap->node_dip) {
25940Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "%s: service %s is in use",
25950Sstevel@tonic-gate msg, service);
25960Sstevel@tonic-gate return (EIO);
25970Sstevel@tonic-gate }
25980Sstevel@tonic-gate }
25990Sstevel@tonic-gate
26000Sstevel@tonic-gate /* if nsvcs == 1, bailout early */
26010Sstevel@tonic-gate if (nsvcs == 1) {
26020Sstevel@tonic-gate /* free up that single entry */
26030Sstevel@tonic-gate len = strlen(ibnex.ibnex_hcasvc_comm_svc_names[0]) + 1;
26040Sstevel@tonic-gate kmem_free(ibnex.ibnex_hcasvc_comm_svc_names[0], len);
26050Sstevel@tonic-gate kmem_free(ibnex.ibnex_hcasvc_comm_svc_names, sizeof (char *));
26060Sstevel@tonic-gate ibnex.ibnex_hcasvc_comm_svc_names = NULL;
26070Sstevel@tonic-gate ibnex.ibnex_nhcasvc_comm_svcs = 0;
26080Sstevel@tonic-gate return (0);
26090Sstevel@tonic-gate }
26100Sstevel@tonic-gate
26110Sstevel@tonic-gate /* Allocate space for new "ibnex.ibnex_nhcasvc_comm_svcs - 1" */
26120Sstevel@tonic-gate service_name = kmem_alloc((nsvcs - 1) * sizeof (char *), KM_SLEEP);
26130Sstevel@tonic-gate /*
26140Sstevel@tonic-gate * Copy over the existing "ibnex.ibnex_hcasvc_comm_svc_names"
26150Sstevel@tonic-gate * array. Do not copy over the matching service.
26160Sstevel@tonic-gate */
26170Sstevel@tonic-gate for (i = 0, j = 0; i < nsvcs; i++) {
26180Sstevel@tonic-gate if (i == match_ndx) {
26190Sstevel@tonic-gate /* free up that entry */
26200Sstevel@tonic-gate len = strlen(ibnex.ibnex_hcasvc_comm_svc_names[i]) + 1;
26210Sstevel@tonic-gate kmem_free(ibnex.ibnex_hcasvc_comm_svc_names[i], len);
26220Sstevel@tonic-gate continue;
26230Sstevel@tonic-gate }
26240Sstevel@tonic-gate service_name[j++] = ibnex.ibnex_hcasvc_comm_svc_names[i];
26250Sstevel@tonic-gate }
26260Sstevel@tonic-gate
26270Sstevel@tonic-gate /* Replace existing pointer to VPPA services w/ newly adjusted one */
26280Sstevel@tonic-gate if (ibnex.ibnex_hcasvc_comm_svc_names) {
26290Sstevel@tonic-gate kmem_free(ibnex.ibnex_hcasvc_comm_svc_names, nsvcs *
26300Sstevel@tonic-gate sizeof (char *));
26310Sstevel@tonic-gate ibnex.ibnex_nhcasvc_comm_svcs--;
26320Sstevel@tonic-gate ibnex.ibnex_hcasvc_comm_svc_names = service_name;
26330Sstevel@tonic-gate }
26340Sstevel@tonic-gate return (0);
26350Sstevel@tonic-gate }
26360Sstevel@tonic-gate
26370Sstevel@tonic-gate
26380Sstevel@tonic-gate /*
26390Sstevel@tonic-gate * ibnex_ioc_fininode()
26400Sstevel@tonic-gate * Un-initialize a child device node for IOC device node
26410Sstevel@tonic-gate * Returns IBNEX_SUCCESS/IBNEX_FAILURE
26420Sstevel@tonic-gate */
26430Sstevel@tonic-gate static ibnex_rval_t
ibnex_ioc_fininode(dev_info_t * dip,ibnex_ioc_node_t * ioc_nodep)26440Sstevel@tonic-gate ibnex_ioc_fininode(dev_info_t *dip, ibnex_ioc_node_t *ioc_nodep)
26450Sstevel@tonic-gate {
26460Sstevel@tonic-gate int rval = MDI_SUCCESS;
26470Sstevel@tonic-gate
26480Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
26490Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tioc_fininode");
26500Sstevel@tonic-gate
26510Sstevel@tonic-gate /*
26520Sstevel@tonic-gate * For a dis-connected IOC,
26530Sstevel@tonic-gate * Free the ioc_profile &&
26540Sstevel@tonic-gate * decrement ibnex_num_disconnect_iocs
26550Sstevel@tonic-gate */
26560Sstevel@tonic-gate if (ioc_nodep->ioc_ngids == 0 && ioc_nodep->ioc_profile) {
26570Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tioc_fininode: unconfigure "
26580Sstevel@tonic-gate "disconnected IOC: GUID %lX", ioc_nodep->ioc_guid);
26590Sstevel@tonic-gate ibnex.ibnex_num_disconnect_iocs--;
26600Sstevel@tonic-gate kmem_free(ioc_nodep->ioc_profile,
26610Sstevel@tonic-gate sizeof (ib_dm_ioc_ctrl_profile_t));
26620Sstevel@tonic-gate ioc_nodep->ioc_profile = NULL;
26630Sstevel@tonic-gate }
26640Sstevel@tonic-gate
26650Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
26660Sstevel@tonic-gate ASSERT(i_ddi_node_state(dip) >= DS_BOUND);
26670Sstevel@tonic-gate
26680Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tioc_fininode: offlining the IOC");
26690Sstevel@tonic-gate rval = ibnex_offline_childdip(dip);
26700Sstevel@tonic-gate
26710Sstevel@tonic-gate if (rval != MDI_SUCCESS) {
26720Sstevel@tonic-gate rval = NDI_FAILURE;
26730Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "\toffline failed for IOC "
26740Sstevel@tonic-gate "dip %p with 0x%x", dip, rval);
26750Sstevel@tonic-gate }
26760Sstevel@tonic-gate
26770Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
26780Sstevel@tonic-gate return (rval == MDI_SUCCESS ? IBNEX_SUCCESS : IBNEX_OFFLINE_FAILED);
26790Sstevel@tonic-gate }
26800Sstevel@tonic-gate
26810Sstevel@tonic-gate
26820Sstevel@tonic-gate int
ibnex_offline_childdip(dev_info_t * dip)26830Sstevel@tonic-gate ibnex_offline_childdip(dev_info_t *dip)
26840Sstevel@tonic-gate {
26859778SEiji.Ota@Sun.COM int rval = MDI_SUCCESS, rval2;
26860Sstevel@tonic-gate mdi_pathinfo_t *path = NULL, *temp;
26870Sstevel@tonic-gate
26880Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\toffline_childdip; begin");
26890Sstevel@tonic-gate if (dip == NULL) {
26900Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "\toffline_childdip; NULL dip");
26910Sstevel@tonic-gate return (MDI_FAILURE);
26920Sstevel@tonic-gate }
26930Sstevel@tonic-gate
26940Sstevel@tonic-gate for (path = mdi_get_next_phci_path(dip, path); path; ) {
26950Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\toffline_childdip: "
26960Sstevel@tonic-gate "offling path %p", path);
26979778SEiji.Ota@Sun.COM rval2 = MDI_SUCCESS;
26989778SEiji.Ota@Sun.COM if (MDI_PI_IS_ONLINE(path)) {
26999778SEiji.Ota@Sun.COM rval2 = mdi_pi_offline(path, NDI_UNCONFIG);
27009778SEiji.Ota@Sun.COM /* If it cannot be offlined, log this path and error */
27019778SEiji.Ota@Sun.COM if (rval2 != MDI_SUCCESS) {
27029778SEiji.Ota@Sun.COM rval = rval2;
27039778SEiji.Ota@Sun.COM cmn_err(CE_WARN,
27049778SEiji.Ota@Sun.COM "!ibnex\toffline_childdip (0x%p): "
27059778SEiji.Ota@Sun.COM "mdi_pi_offline path (0x%p) failed with %d",
27069778SEiji.Ota@Sun.COM (void *)dip, (void *)path, rval2);
27079778SEiji.Ota@Sun.COM }
27080Sstevel@tonic-gate }
27099778SEiji.Ota@Sun.COM /* prepare the next path */
27100Sstevel@tonic-gate temp = path;
27110Sstevel@tonic-gate path = mdi_get_next_phci_path(dip, path);
27129778SEiji.Ota@Sun.COM /* free the offline path */
27139778SEiji.Ota@Sun.COM if (rval2 == MDI_SUCCESS) {
27149778SEiji.Ota@Sun.COM (void) mdi_pi_free(temp, 0);
27159778SEiji.Ota@Sun.COM }
27160Sstevel@tonic-gate }
27170Sstevel@tonic-gate return (rval);
27180Sstevel@tonic-gate }
27190Sstevel@tonic-gate
27200Sstevel@tonic-gate
27210Sstevel@tonic-gate /*
27220Sstevel@tonic-gate * ibnex_commsvc_fininode()
27230Sstevel@tonic-gate *
27240Sstevel@tonic-gate * Un-initialize a child device node for HCA port / node GUID
27250Sstevel@tonic-gate * for a communication service.
27260Sstevel@tonic-gate * Returns IBNEX_SUCCESS/IBNEX_FAILURE
27270Sstevel@tonic-gate */
27280Sstevel@tonic-gate static ibnex_rval_t
ibnex_commsvc_fininode(dev_info_t * dip)27290Sstevel@tonic-gate ibnex_commsvc_fininode(dev_info_t *dip)
27300Sstevel@tonic-gate {
27310Sstevel@tonic-gate int rval = NDI_SUCCESS;
27320Sstevel@tonic-gate
27330Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
27340Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tcommsvc_fininode");
27350Sstevel@tonic-gate
27360Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
27370Sstevel@tonic-gate if (i_ddi_node_state(dip) < DS_BOUND) {
27380Sstevel@tonic-gate /*
27390Sstevel@tonic-gate * if the child hasn't been bound yet, we can
27400Sstevel@tonic-gate * just free the dip. This path is currently
27410Sstevel@tonic-gate * untested.
27420Sstevel@tonic-gate */
27430Sstevel@tonic-gate (void) ddi_remove_child(dip, 0);
27440Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex",
27450Sstevel@tonic-gate "\tcommsvc_fininode: ddi_remove_child");
27460Sstevel@tonic-gate } else {
27470Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tcommsvc_fininode: offlining the "
27480Sstevel@tonic-gate "Commsvc node");
27490Sstevel@tonic-gate
27500Sstevel@tonic-gate rval = ndi_devi_offline(dip, NDI_DEVI_REMOVE | NDI_UNCONFIG);
27510Sstevel@tonic-gate if (rval != NDI_SUCCESS)
27520Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "\toffline failed for Commsvc "
27530Sstevel@tonic-gate "dip %p with 0x%x", dip, rval);
27540Sstevel@tonic-gate }
27550Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
27560Sstevel@tonic-gate return (rval == NDI_SUCCESS ? IBNEX_SUCCESS : IBNEX_OFFLINE_FAILED);
27570Sstevel@tonic-gate }
27580Sstevel@tonic-gate
27590Sstevel@tonic-gate
27600Sstevel@tonic-gate /*
27610Sstevel@tonic-gate * ibnex_pseudo_fininode()
27620Sstevel@tonic-gate * Un-initialize a child pseudo device node
27630Sstevel@tonic-gate * Returns IBNEX_SUCCESS/IBNEX_FAILURE
27640Sstevel@tonic-gate */
27650Sstevel@tonic-gate static ibnex_rval_t
ibnex_pseudo_fininode(dev_info_t * dip)27660Sstevel@tonic-gate ibnex_pseudo_fininode(dev_info_t *dip)
27670Sstevel@tonic-gate {
27680Sstevel@tonic-gate int rval = MDI_SUCCESS;
27690Sstevel@tonic-gate
27700Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibnex.ibnex_mutex));
27710Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tpseudo_fininode: dip = %p", dip);
27720Sstevel@tonic-gate
27730Sstevel@tonic-gate mutex_exit(&ibnex.ibnex_mutex);
27740Sstevel@tonic-gate ASSERT(i_ddi_node_state(dip) >= DS_BOUND);
27750Sstevel@tonic-gate
27760Sstevel@tonic-gate IBTF_DPRINTF_L4("ibnex", "\tpseudo_fininode: offlining the "
27770Sstevel@tonic-gate "pseudo device");
27780Sstevel@tonic-gate rval = ibnex_offline_childdip(dip);
27790Sstevel@tonic-gate if (rval != MDI_SUCCESS) {
27800Sstevel@tonic-gate rval = NDI_FAILURE;
27810Sstevel@tonic-gate IBTF_DPRINTF_L2("ibnex", "\tpseudo offline failed for "
27820Sstevel@tonic-gate "dip %p with 0x%x", dip, rval);
27830Sstevel@tonic-gate }
27840Sstevel@tonic-gate
27850Sstevel@tonic-gate mutex_enter(&ibnex.ibnex_mutex);
27860Sstevel@tonic-gate return (rval == MDI_SUCCESS ? IBNEX_SUCCESS : IBNEX_OFFLINE_FAILED);
27870Sstevel@tonic-gate }
27889879SRamaswamy.Tummala@Sun.COM
27899879SRamaswamy.Tummala@Sun.COM /*
27909879SRamaswamy.Tummala@Sun.COM * IOCTL implementation to get api version number.
27919879SRamaswamy.Tummala@Sun.COM */
27929879SRamaswamy.Tummala@Sun.COM static int
ibnex_ctl_get_api_ver(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)27939879SRamaswamy.Tummala@Sun.COM ibnex_ctl_get_api_ver(dev_t dev, int cmd, intptr_t arg, int mode,
27949879SRamaswamy.Tummala@Sun.COM cred_t *credp, int *rvalp)
27959879SRamaswamy.Tummala@Sun.COM {
27969879SRamaswamy.Tummala@Sun.COM ibnex_ctl_api_ver_t api_ver;
27979879SRamaswamy.Tummala@Sun.COM
27989879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L4("ibnex", "\tctl_get_api_ver: cmd=%x, arg=%p, "
27999879SRamaswamy.Tummala@Sun.COM "mode=%x, cred=%p, rval=%p, dev=0x%x", cmd, arg, mode, credp,
28009879SRamaswamy.Tummala@Sun.COM rvalp, dev);
28019879SRamaswamy.Tummala@Sun.COM
28029879SRamaswamy.Tummala@Sun.COM api_ver.api_ver_num = IBNEX_CTL_API_VERSION;
28039879SRamaswamy.Tummala@Sun.COM
28049879SRamaswamy.Tummala@Sun.COM if (ddi_copyout(&api_ver, (void *)arg, sizeof (ibnex_ctl_api_ver_t),
28059879SRamaswamy.Tummala@Sun.COM mode) != 0) {
28069879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
28079879SRamaswamy.Tummala@Sun.COM "\tctl_get_api_ver: ddi_copyout err");
28089879SRamaswamy.Tummala@Sun.COM return (EFAULT);
28099879SRamaswamy.Tummala@Sun.COM }
28109879SRamaswamy.Tummala@Sun.COM
28119879SRamaswamy.Tummala@Sun.COM return (0);
28129879SRamaswamy.Tummala@Sun.COM }
28139879SRamaswamy.Tummala@Sun.COM
28149879SRamaswamy.Tummala@Sun.COM /*
28159879SRamaswamy.Tummala@Sun.COM * IOCTL implementation to get the list of HCAs
28169879SRamaswamy.Tummala@Sun.COM */
28179879SRamaswamy.Tummala@Sun.COM static int
ibnex_ctl_get_hca_list(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)28189879SRamaswamy.Tummala@Sun.COM ibnex_ctl_get_hca_list(dev_t dev, int cmd, intptr_t arg, int mode,
28199879SRamaswamy.Tummala@Sun.COM cred_t *credp, int *rvalp)
28209879SRamaswamy.Tummala@Sun.COM {
28219879SRamaswamy.Tummala@Sun.COM ibnex_ctl_get_hca_list_t hca_list;
28229879SRamaswamy.Tummala@Sun.COM int rv = 0;
28239879SRamaswamy.Tummala@Sun.COM uint_t *in_nhcasp;
28249879SRamaswamy.Tummala@Sun.COM uint_t nhcas, n;
28259879SRamaswamy.Tummala@Sun.COM ib_guid_t *hca_guids;
28269879SRamaswamy.Tummala@Sun.COM
28279879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L4("ibnex", "\tctl_get_hca_list: cmd=%x, arg=%p, "
28289879SRamaswamy.Tummala@Sun.COM "mode=%x, cred=%p, rval=%p, dev=0x%x", cmd, arg, mode, credp,
28299879SRamaswamy.Tummala@Sun.COM rvalp, dev);
28309879SRamaswamy.Tummala@Sun.COM
28319879SRamaswamy.Tummala@Sun.COM #ifdef _MULTI_DATAMODEL
28329879SRamaswamy.Tummala@Sun.COM if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
28339879SRamaswamy.Tummala@Sun.COM ibnex_ctl_get_hca_list_32_t hca_list_32;
28349879SRamaswamy.Tummala@Sun.COM
28359879SRamaswamy.Tummala@Sun.COM if (ddi_copyin((void *)arg, &hca_list_32,
28369879SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_get_hca_list_32_t), mode) != 0) {
28379879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
28389879SRamaswamy.Tummala@Sun.COM "\tctl_get_hca_list: ddi_copyin err 1");
28399879SRamaswamy.Tummala@Sun.COM return (EFAULT);
28409879SRamaswamy.Tummala@Sun.COM }
28419879SRamaswamy.Tummala@Sun.COM
28429879SRamaswamy.Tummala@Sun.COM hca_list.hca_guids_alloc_sz = hca_list_32.hca_guids_alloc_sz;
28439879SRamaswamy.Tummala@Sun.COM hca_list.hca_guids =
28449879SRamaswamy.Tummala@Sun.COM (ib_guid_t *)(uintptr_t)hca_list_32.hca_guids;
28459879SRamaswamy.Tummala@Sun.COM in_nhcasp = &((ibnex_ctl_get_hca_list_32_t *)arg)->nhcas;
28469879SRamaswamy.Tummala@Sun.COM } else
28479879SRamaswamy.Tummala@Sun.COM #endif
28489879SRamaswamy.Tummala@Sun.COM {
28499879SRamaswamy.Tummala@Sun.COM if (ddi_copyin((void *)arg, &hca_list,
28509879SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_get_hca_list_t), mode) != 0) {
28519879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
28529879SRamaswamy.Tummala@Sun.COM "\tctl_get_hca_list: ddi_copyin err 2");
28539879SRamaswamy.Tummala@Sun.COM return (EFAULT);
28549879SRamaswamy.Tummala@Sun.COM }
28559879SRamaswamy.Tummala@Sun.COM
28569879SRamaswamy.Tummala@Sun.COM in_nhcasp = &((ibnex_ctl_get_hca_list_t *)arg)->nhcas;
28579879SRamaswamy.Tummala@Sun.COM }
28589879SRamaswamy.Tummala@Sun.COM
28599879SRamaswamy.Tummala@Sun.COM nhcas = ibt_get_hca_list(&hca_guids);
28609879SRamaswamy.Tummala@Sun.COM
28619879SRamaswamy.Tummala@Sun.COM /* copy number of hcas to user space */
28629879SRamaswamy.Tummala@Sun.COM if (ddi_copyout(&nhcas, in_nhcasp, sizeof (uint_t), mode) != 0) {
28639879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
28649879SRamaswamy.Tummala@Sun.COM "\tctl_get_hca_list: ddi_copyout err 1");
28659879SRamaswamy.Tummala@Sun.COM rv = EFAULT;
28669879SRamaswamy.Tummala@Sun.COM goto out;
28679879SRamaswamy.Tummala@Sun.COM }
28689879SRamaswamy.Tummala@Sun.COM
28699879SRamaswamy.Tummala@Sun.COM n = MIN(nhcas, hca_list.hca_guids_alloc_sz);
28709879SRamaswamy.Tummala@Sun.COM if (n == 0)
28719879SRamaswamy.Tummala@Sun.COM goto out;
28729879SRamaswamy.Tummala@Sun.COM
28739879SRamaswamy.Tummala@Sun.COM /* copy HCA guids to user space */
28749879SRamaswamy.Tummala@Sun.COM if (ddi_copyout(hca_guids, hca_list.hca_guids,
28759879SRamaswamy.Tummala@Sun.COM n * sizeof (ib_guid_t), mode) != 0) {
28769879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
28779879SRamaswamy.Tummala@Sun.COM "\tctl_get_hca_list: ddi_copyout err 2");
28789879SRamaswamy.Tummala@Sun.COM rv = EFAULT;
28799879SRamaswamy.Tummala@Sun.COM }
28809879SRamaswamy.Tummala@Sun.COM
28819879SRamaswamy.Tummala@Sun.COM out:
28829879SRamaswamy.Tummala@Sun.COM if (nhcas > 0)
28839879SRamaswamy.Tummala@Sun.COM ibt_free_hca_list(hca_guids, nhcas);
28849879SRamaswamy.Tummala@Sun.COM
28859879SRamaswamy.Tummala@Sun.COM return (rv);
28869879SRamaswamy.Tummala@Sun.COM }
28879879SRamaswamy.Tummala@Sun.COM
288810094SRamaswamy.Tummala@Sun.COM #define IBNEX_CTL_CP_HCA_INFO(x, y, driver_name, instance, device_path, \
288910094SRamaswamy.Tummala@Sun.COM device_path_alloc_sz, device_path_len) \
289010094SRamaswamy.Tummala@Sun.COM { \
289110094SRamaswamy.Tummala@Sun.COM (x)->hca_node_guid = (y)->hca_node_guid; \
289210094SRamaswamy.Tummala@Sun.COM (x)->hca_si_guid = (y)->hca_si_guid; \
289310094SRamaswamy.Tummala@Sun.COM (x)->hca_nports = (y)->hca_nports; \
289410094SRamaswamy.Tummala@Sun.COM (x)->hca_flags = (y)->hca_flags; \
289510094SRamaswamy.Tummala@Sun.COM (x)->hca_flags2 = (y)->hca_flags2; \
289610094SRamaswamy.Tummala@Sun.COM (x)->hca_vendor_id = (y)->hca_vendor_id; \
289710094SRamaswamy.Tummala@Sun.COM (x)->hca_device_id = (y)->hca_device_id; \
289810094SRamaswamy.Tummala@Sun.COM (x)->hca_version_id = (y)->hca_version_id; \
289910094SRamaswamy.Tummala@Sun.COM (x)->hca_max_chans = (y)->hca_max_chans; \
290010094SRamaswamy.Tummala@Sun.COM (x)->hca_max_chan_sz = (y)->hca_max_chan_sz; \
290110094SRamaswamy.Tummala@Sun.COM (x)->hca_max_sgl = (y)->hca_max_sgl; \
290210094SRamaswamy.Tummala@Sun.COM (x)->hca_max_cq = (y)->hca_max_cq; \
290310094SRamaswamy.Tummala@Sun.COM (x)->hca_max_cq_sz = (y)->hca_max_cq_sz; \
290410094SRamaswamy.Tummala@Sun.COM (x)->hca_page_sz = (y)->hca_page_sz; \
290510094SRamaswamy.Tummala@Sun.COM (x)->hca_max_memr = (y)->hca_max_memr; \
290610094SRamaswamy.Tummala@Sun.COM (x)->hca_max_memr_len = (y)->hca_max_memr_len; \
290710094SRamaswamy.Tummala@Sun.COM (x)->hca_max_mem_win = (y)->hca_max_mem_win; \
290810094SRamaswamy.Tummala@Sun.COM (x)->hca_max_rsc = (y)->hca_max_rsc; \
290910094SRamaswamy.Tummala@Sun.COM (x)->hca_max_rdma_in_chan = (y)->hca_max_rdma_in_chan; \
291010094SRamaswamy.Tummala@Sun.COM (x)->hca_max_rdma_out_chan = (y)->hca_max_rdma_out_chan; \
291110094SRamaswamy.Tummala@Sun.COM (x)->hca_max_ipv6_chan = (y)->hca_max_ipv6_chan; \
291210094SRamaswamy.Tummala@Sun.COM (x)->hca_max_ether_chan = (y)->hca_max_ether_chan; \
291310094SRamaswamy.Tummala@Sun.COM (x)->hca_max_mcg_chans = (y)->hca_max_mcg_chans; \
291410094SRamaswamy.Tummala@Sun.COM (x)->hca_max_mcg = (y)->hca_max_mcg; \
291510094SRamaswamy.Tummala@Sun.COM (x)->hca_max_chan_per_mcg = (y)->hca_max_chan_per_mcg; \
291610094SRamaswamy.Tummala@Sun.COM (x)->hca_max_partitions = (y)->hca_max_partitions; \
291710094SRamaswamy.Tummala@Sun.COM (x)->hca_local_ack_delay = (y)->hca_local_ack_delay; \
291810094SRamaswamy.Tummala@Sun.COM (x)->hca_max_port_sgid_tbl_sz = (y)->hca_max_port_sgid_tbl_sz; \
291910094SRamaswamy.Tummala@Sun.COM (x)->hca_max_port_pkey_tbl_sz = (y)->hca_max_port_pkey_tbl_sz; \
292010094SRamaswamy.Tummala@Sun.COM (x)->hca_max_pd = (y)->hca_max_pd; \
292110094SRamaswamy.Tummala@Sun.COM (x)->hca_max_ud_dest = (y)->hca_max_ud_dest; \
292210094SRamaswamy.Tummala@Sun.COM (x)->hca_max_srqs = (y)->hca_max_srqs; \
292310094SRamaswamy.Tummala@Sun.COM (x)->hca_max_srqs_sz = (y)->hca_max_srqs_sz; \
292410094SRamaswamy.Tummala@Sun.COM (x)->hca_max_srq_sgl = (y)->hca_max_srq_sgl; \
292510094SRamaswamy.Tummala@Sun.COM (x)->hca_max_cq_handlers = (y)->hca_max_cq_handlers; \
292610094SRamaswamy.Tummala@Sun.COM (x)->hca_reserved_lkey = (y)->hca_reserved_lkey; \
292710094SRamaswamy.Tummala@Sun.COM (x)->hca_max_fmrs = (y)->hca_max_fmrs; \
292810094SRamaswamy.Tummala@Sun.COM (x)->hca_max_lso_size = (y)->hca_max_lso_size; \
292910094SRamaswamy.Tummala@Sun.COM (x)->hca_max_lso_hdr_size = (y)->hca_max_lso_hdr_size; \
293010094SRamaswamy.Tummala@Sun.COM (x)->hca_max_inline_size = (y)->hca_max_inline_size; \
293110094SRamaswamy.Tummala@Sun.COM (x)->hca_max_cq_mod_count = (y)->hca_max_cq_mod_count; \
293210094SRamaswamy.Tummala@Sun.COM (x)->hca_max_cq_mod_usec = (y)->hca_max_cq_mod_usec; \
293310094SRamaswamy.Tummala@Sun.COM (x)->hca_fw_major_version = (y)->hca_fw_major_version; \
293410094SRamaswamy.Tummala@Sun.COM (x)->hca_fw_minor_version = (y)->hca_fw_minor_version; \
293510094SRamaswamy.Tummala@Sun.COM (x)->hca_fw_micro_version = (y)->hca_fw_micro_version; \
293610094SRamaswamy.Tummala@Sun.COM (x)->hca_ud_send_inline_sz = (y)->hca_ud_send_inline_sz; \
293710094SRamaswamy.Tummala@Sun.COM (x)->hca_conn_send_inline_sz = (y)->hca_conn_send_inline_sz; \
293810094SRamaswamy.Tummala@Sun.COM (x)->hca_conn_rdmaw_inline_overhead = \
293910094SRamaswamy.Tummala@Sun.COM (y)->hca_conn_rdmaw_inline_overhead; \
294010094SRamaswamy.Tummala@Sun.COM (x)->hca_recv_sgl_sz = (y)->hca_recv_sgl_sz; \
294110094SRamaswamy.Tummala@Sun.COM (x)->hca_ud_send_sgl_sz = (y)->hca_ud_send_sgl_sz; \
294210094SRamaswamy.Tummala@Sun.COM (x)->hca_conn_send_sgl_sz = (y)->hca_conn_send_sgl_sz; \
294310094SRamaswamy.Tummala@Sun.COM (x)->hca_conn_rdma_sgl_overhead = (y)->hca_conn_rdma_sgl_overhead; \
294410094SRamaswamy.Tummala@Sun.COM \
294510094SRamaswamy.Tummala@Sun.COM (void) strlcpy((x)->hca_driver_name, (driver_name), \
294610094SRamaswamy.Tummala@Sun.COM MAX_HCA_DRVNAME_LEN); \
294710094SRamaswamy.Tummala@Sun.COM (x)->hca_driver_instance = (instance); \
294810094SRamaswamy.Tummala@Sun.COM \
294910094SRamaswamy.Tummala@Sun.COM (x)->hca_device_path = ((device_path_alloc_sz) >= (device_path_len)) \
295010094SRamaswamy.Tummala@Sun.COM ? (device_path) : NULL; \
295110094SRamaswamy.Tummala@Sun.COM (x)->hca_device_path_len = (device_path_len); \
295210094SRamaswamy.Tummala@Sun.COM }
295310094SRamaswamy.Tummala@Sun.COM
29549879SRamaswamy.Tummala@Sun.COM /*
29559879SRamaswamy.Tummala@Sun.COM * IOCTL implementation to query HCA attributes
29569879SRamaswamy.Tummala@Sun.COM */
29579879SRamaswamy.Tummala@Sun.COM static int
ibnex_ctl_query_hca(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)29589879SRamaswamy.Tummala@Sun.COM ibnex_ctl_query_hca(dev_t dev, int cmd, intptr_t arg, int mode,
29599879SRamaswamy.Tummala@Sun.COM cred_t *credp, int *rvalp)
29609879SRamaswamy.Tummala@Sun.COM {
29619879SRamaswamy.Tummala@Sun.COM int rv = 0;
296210094SRamaswamy.Tummala@Sun.COM ibnex_ctl_query_hca_t *query_hca = NULL;
296310094SRamaswamy.Tummala@Sun.COM ibnex_ctl_query_hca_32_t *query_hca_32 = NULL;
296410094SRamaswamy.Tummala@Sun.COM ibt_hca_attr_t *hca_attr = NULL;
29659879SRamaswamy.Tummala@Sun.COM char driver_name[MAX_HCA_DRVNAME_LEN];
29669879SRamaswamy.Tummala@Sun.COM int instance;
296710094SRamaswamy.Tummala@Sun.COM ib_guid_t hca_guid;
296810094SRamaswamy.Tummala@Sun.COM char *device_path;
296910094SRamaswamy.Tummala@Sun.COM uint_t device_path_alloc_sz, hca_device_path_len;
297010094SRamaswamy.Tummala@Sun.COM char *hca_device_path = NULL;
29719879SRamaswamy.Tummala@Sun.COM
29729879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L4("ibnex", "\tctl_query_hca: cmd=%x, arg=%p, "
29739879SRamaswamy.Tummala@Sun.COM "mode=%x, cred=%p, rval=%p, dev=0x%x", cmd, arg, mode, credp,
29749879SRamaswamy.Tummala@Sun.COM rvalp, dev);
29759879SRamaswamy.Tummala@Sun.COM
297610094SRamaswamy.Tummala@Sun.COM #ifdef _MULTI_DATAMODEL
297710094SRamaswamy.Tummala@Sun.COM if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
297810094SRamaswamy.Tummala@Sun.COM query_hca_32 = kmem_zalloc(
297910094SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_query_hca_32_t), KM_SLEEP);
298010094SRamaswamy.Tummala@Sun.COM
298110094SRamaswamy.Tummala@Sun.COM if (ddi_copyin((void *)arg, query_hca_32,
298210094SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_query_hca_32_t), mode) != 0) {
298310094SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
298410094SRamaswamy.Tummala@Sun.COM "\tctl_query_hca: ddi_copyin err 1");
298510094SRamaswamy.Tummala@Sun.COM rv = EFAULT;
298610094SRamaswamy.Tummala@Sun.COM goto out;
298710094SRamaswamy.Tummala@Sun.COM }
298810094SRamaswamy.Tummala@Sun.COM
298910094SRamaswamy.Tummala@Sun.COM hca_guid = query_hca_32->hca_guid;
299010094SRamaswamy.Tummala@Sun.COM device_path = (char *)(uintptr_t)query_hca_32->hca_device_path;
299110094SRamaswamy.Tummala@Sun.COM device_path_alloc_sz = query_hca_32->hca_device_path_alloc_sz;
299210094SRamaswamy.Tummala@Sun.COM } else
299310094SRamaswamy.Tummala@Sun.COM #endif
299410094SRamaswamy.Tummala@Sun.COM {
299510094SRamaswamy.Tummala@Sun.COM query_hca = kmem_zalloc(sizeof (ibnex_ctl_query_hca_t),
299610094SRamaswamy.Tummala@Sun.COM KM_SLEEP);
299710094SRamaswamy.Tummala@Sun.COM
299810094SRamaswamy.Tummala@Sun.COM if (ddi_copyin((void *)arg, query_hca,
299910094SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_query_hca_t), mode) != 0) {
300010094SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
300110094SRamaswamy.Tummala@Sun.COM "\tctl_query_hca: ddi_copyin err 2");
300210094SRamaswamy.Tummala@Sun.COM rv = EFAULT;
300310094SRamaswamy.Tummala@Sun.COM goto out;
300410094SRamaswamy.Tummala@Sun.COM }
300510094SRamaswamy.Tummala@Sun.COM
300610094SRamaswamy.Tummala@Sun.COM hca_guid = query_hca->hca_guid;
300710094SRamaswamy.Tummala@Sun.COM device_path = query_hca->hca_device_path;
300810094SRamaswamy.Tummala@Sun.COM device_path_alloc_sz = query_hca->hca_device_path_alloc_sz;
300910094SRamaswamy.Tummala@Sun.COM }
301010094SRamaswamy.Tummala@Sun.COM
30119879SRamaswamy.Tummala@Sun.COM hca_attr = kmem_zalloc(sizeof (ibt_hca_attr_t), KM_SLEEP);
301210094SRamaswamy.Tummala@Sun.COM hca_device_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
301310094SRamaswamy.Tummala@Sun.COM
301410094SRamaswamy.Tummala@Sun.COM if (ibtl_ibnex_query_hca_byguid(hca_guid, hca_attr,
301510094SRamaswamy.Tummala@Sun.COM driver_name, sizeof (driver_name), &instance, hca_device_path)
301610094SRamaswamy.Tummala@Sun.COM != IBT_SUCCESS) {
30179879SRamaswamy.Tummala@Sun.COM rv = ENXIO;
30189879SRamaswamy.Tummala@Sun.COM goto out;
30199879SRamaswamy.Tummala@Sun.COM }
30209879SRamaswamy.Tummala@Sun.COM
302110094SRamaswamy.Tummala@Sun.COM hca_device_path_len = strlen(hca_device_path) + 1;
302210094SRamaswamy.Tummala@Sun.COM
302310094SRamaswamy.Tummala@Sun.COM #ifdef _MULTI_DATAMODEL
302410094SRamaswamy.Tummala@Sun.COM if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
302510094SRamaswamy.Tummala@Sun.COM
302610094SRamaswamy.Tummala@Sun.COM IBNEX_CTL_CP_HCA_INFO(&query_hca_32->hca_info, hca_attr,
302710094SRamaswamy.Tummala@Sun.COM driver_name, instance, query_hca_32->hca_device_path,
302810094SRamaswamy.Tummala@Sun.COM device_path_alloc_sz, hca_device_path_len);
302910094SRamaswamy.Tummala@Sun.COM
303010094SRamaswamy.Tummala@Sun.COM /* copy hca information to the user space */
303110094SRamaswamy.Tummala@Sun.COM if (ddi_copyout(&query_hca_32->hca_info,
303210094SRamaswamy.Tummala@Sun.COM &((ibnex_ctl_query_hca_32_t *)arg)->hca_info,
303310094SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_hca_info_32_t), mode) != 0) {
303410094SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
303510094SRamaswamy.Tummala@Sun.COM "\tctl_query_hca: ddi_copyout err 1");
303610094SRamaswamy.Tummala@Sun.COM rv = EFAULT;
303710094SRamaswamy.Tummala@Sun.COM goto out;
303810094SRamaswamy.Tummala@Sun.COM }
303910094SRamaswamy.Tummala@Sun.COM } else
304010094SRamaswamy.Tummala@Sun.COM #endif
304110094SRamaswamy.Tummala@Sun.COM {
304210094SRamaswamy.Tummala@Sun.COM IBNEX_CTL_CP_HCA_INFO(&query_hca->hca_info, hca_attr,
304310094SRamaswamy.Tummala@Sun.COM driver_name, instance, device_path,
304410094SRamaswamy.Tummala@Sun.COM device_path_alloc_sz, hca_device_path_len);
304510094SRamaswamy.Tummala@Sun.COM
304610094SRamaswamy.Tummala@Sun.COM /* copy hca information to the user space */
304710094SRamaswamy.Tummala@Sun.COM if (ddi_copyout(&query_hca->hca_info,
304810094SRamaswamy.Tummala@Sun.COM &((ibnex_ctl_query_hca_t *)arg)->hca_info,
304910094SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_hca_info_t), mode) != 0) {
305010094SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
305110094SRamaswamy.Tummala@Sun.COM "\tctl_query_hca: ddi_copyout err 2");
305210094SRamaswamy.Tummala@Sun.COM rv = EFAULT;
305310094SRamaswamy.Tummala@Sun.COM goto out;
305410094SRamaswamy.Tummala@Sun.COM }
305510094SRamaswamy.Tummala@Sun.COM }
305610094SRamaswamy.Tummala@Sun.COM
305710094SRamaswamy.Tummala@Sun.COM if (device_path_alloc_sz >= hca_device_path_len) {
305810094SRamaswamy.Tummala@Sun.COM if (ddi_copyout(hca_device_path,
305910094SRamaswamy.Tummala@Sun.COM device_path,
306010094SRamaswamy.Tummala@Sun.COM hca_device_path_len, mode) != 0) {
306110094SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex", "\tctl_query_hca: "
306210094SRamaswamy.Tummala@Sun.COM "ddi_copyout err copying device path");
306310094SRamaswamy.Tummala@Sun.COM rv = EFAULT;
306410094SRamaswamy.Tummala@Sun.COM }
30659879SRamaswamy.Tummala@Sun.COM }
30669879SRamaswamy.Tummala@Sun.COM
30679879SRamaswamy.Tummala@Sun.COM out:
306810094SRamaswamy.Tummala@Sun.COM if (query_hca)
306910094SRamaswamy.Tummala@Sun.COM kmem_free(query_hca, sizeof (ibnex_ctl_query_hca_t));
307010094SRamaswamy.Tummala@Sun.COM if (query_hca_32)
307110094SRamaswamy.Tummala@Sun.COM kmem_free(query_hca_32, sizeof (ibnex_ctl_query_hca_32_t));
307210094SRamaswamy.Tummala@Sun.COM if (hca_attr)
307310094SRamaswamy.Tummala@Sun.COM kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
307410094SRamaswamy.Tummala@Sun.COM if (hca_device_path)
307510094SRamaswamy.Tummala@Sun.COM kmem_free(hca_device_path, MAXPATHLEN);
307610094SRamaswamy.Tummala@Sun.COM
30779879SRamaswamy.Tummala@Sun.COM return (rv);
30789879SRamaswamy.Tummala@Sun.COM }
30799879SRamaswamy.Tummala@Sun.COM
30809879SRamaswamy.Tummala@Sun.COM #define IBNEX_CTL_CP_PORT_INFO(x, y, sgid_tbl, pkey_tbl) \
30819879SRamaswamy.Tummala@Sun.COM { \
30829879SRamaswamy.Tummala@Sun.COM (x)->p_lid = (y)->p_opaque1; \
30839879SRamaswamy.Tummala@Sun.COM (x)->p_qkey_violations = (y)->p_qkey_violations; \
30849879SRamaswamy.Tummala@Sun.COM (x)->p_pkey_violations = (y)->p_pkey_violations; \
30859879SRamaswamy.Tummala@Sun.COM (x)->p_sm_sl = (y)->p_sm_sl; \
30869879SRamaswamy.Tummala@Sun.COM (x)->p_phys_state = (y)->p_phys_state; \
30879879SRamaswamy.Tummala@Sun.COM (x)->p_sm_lid = (y)->p_sm_lid; \
30889879SRamaswamy.Tummala@Sun.COM (x)->p_linkstate = (y)->p_linkstate; \
30899879SRamaswamy.Tummala@Sun.COM (x)->p_port_num = (y)->p_port_num; \
30909879SRamaswamy.Tummala@Sun.COM (x)->p_width_supported = (y)->p_width_supported; \
30919879SRamaswamy.Tummala@Sun.COM (x)->p_width_enabled = (y)->p_width_enabled; \
30929879SRamaswamy.Tummala@Sun.COM (x)->p_width_active = (y)->p_width_active; \
30939879SRamaswamy.Tummala@Sun.COM (x)->p_mtu = (y)->p_mtu; \
30949879SRamaswamy.Tummala@Sun.COM (x)->p_lmc = (y)->p_lmc; \
30959879SRamaswamy.Tummala@Sun.COM (x)->p_speed_supported = (y)->p_speed_supported; \
30969879SRamaswamy.Tummala@Sun.COM (x)->p_speed_enabled = (y)->p_speed_enabled; \
30979879SRamaswamy.Tummala@Sun.COM (x)->p_speed_active = (y)->p_speed_active; \
30989879SRamaswamy.Tummala@Sun.COM (x)->p_sgid_tbl = (sgid_tbl); \
30999879SRamaswamy.Tummala@Sun.COM (x)->p_sgid_tbl_sz = (y)->p_sgid_tbl_sz; \
31009879SRamaswamy.Tummala@Sun.COM (x)->p_pkey_tbl = (pkey_tbl); \
31019879SRamaswamy.Tummala@Sun.COM (x)->p_pkey_tbl_sz = (y)->p_pkey_tbl_sz; \
31029879SRamaswamy.Tummala@Sun.COM (x)->p_def_pkey_ix = (y)->p_def_pkey_ix; \
31039879SRamaswamy.Tummala@Sun.COM (x)->p_max_vl = (y)->p_max_vl; \
31049879SRamaswamy.Tummala@Sun.COM (x)->p_init_type_reply = (y)->p_init_type_reply; \
31059879SRamaswamy.Tummala@Sun.COM (x)->p_subnet_timeout = (y)->p_subnet_timeout; \
31069879SRamaswamy.Tummala@Sun.COM (x)->p_capabilities = (y)->p_capabilities; \
31079879SRamaswamy.Tummala@Sun.COM (x)->p_msg_sz = (y)->p_msg_sz; \
31089879SRamaswamy.Tummala@Sun.COM }
31099879SRamaswamy.Tummala@Sun.COM
31109879SRamaswamy.Tummala@Sun.COM /*
31119879SRamaswamy.Tummala@Sun.COM * IOCTL implementation to query HCA port attributes
31129879SRamaswamy.Tummala@Sun.COM */
31139879SRamaswamy.Tummala@Sun.COM static int
ibnex_ctl_query_hca_port(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)31149879SRamaswamy.Tummala@Sun.COM ibnex_ctl_query_hca_port(dev_t dev, int cmd, intptr_t arg, int mode,
31159879SRamaswamy.Tummala@Sun.COM cred_t *credp, int *rvalp)
31169879SRamaswamy.Tummala@Sun.COM {
31179879SRamaswamy.Tummala@Sun.COM ibt_hca_portinfo_t *ibt_pi;
31189879SRamaswamy.Tummala@Sun.COM uint_t nports;
31199879SRamaswamy.Tummala@Sun.COM uint_t size = 0;
31209879SRamaswamy.Tummala@Sun.COM int rv = 0;
31219879SRamaswamy.Tummala@Sun.COM ibnex_ctl_query_hca_port_t *query_hca_port = NULL;
31229879SRamaswamy.Tummala@Sun.COM ibnex_ctl_query_hca_port_32_t *query_hca_port_32 = NULL;
31239879SRamaswamy.Tummala@Sun.COM uint_t sgid_tbl_sz;
31249879SRamaswamy.Tummala@Sun.COM uint16_t pkey_tbl_sz;
312510183SRamaswamy.Tummala@Sun.COM ibt_hca_attr_t hca_attr;
31269879SRamaswamy.Tummala@Sun.COM
31279879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L4("ibnex", "\tctl_query_hca_port: cmd=%x, arg=%p, "
31289879SRamaswamy.Tummala@Sun.COM "mode=%x, cred=%p, rval=%p, dev=0x%x", cmd, arg, mode, credp,
31299879SRamaswamy.Tummala@Sun.COM rvalp, dev);
31309879SRamaswamy.Tummala@Sun.COM
31319879SRamaswamy.Tummala@Sun.COM query_hca_port = kmem_zalloc(sizeof (ibnex_ctl_query_hca_port_t),
31329879SRamaswamy.Tummala@Sun.COM KM_SLEEP);
31339879SRamaswamy.Tummala@Sun.COM
31349879SRamaswamy.Tummala@Sun.COM #ifdef _MULTI_DATAMODEL
31359879SRamaswamy.Tummala@Sun.COM if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
31369879SRamaswamy.Tummala@Sun.COM query_hca_port_32 = kmem_zalloc(
31379879SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_query_hca_port_32_t), KM_SLEEP);
31389879SRamaswamy.Tummala@Sun.COM
31399879SRamaswamy.Tummala@Sun.COM if (ddi_copyin((void *)arg, query_hca_port_32,
31409879SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_query_hca_port_32_t), mode) != 0) {
31419879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
314210094SRamaswamy.Tummala@Sun.COM "\tctl_query_hca_port: ddi_copyin err 1");
31439879SRamaswamy.Tummala@Sun.COM rv = EFAULT;
31449879SRamaswamy.Tummala@Sun.COM goto out;
31459879SRamaswamy.Tummala@Sun.COM }
31469879SRamaswamy.Tummala@Sun.COM
31479879SRamaswamy.Tummala@Sun.COM query_hca_port->hca_guid = query_hca_port_32->hca_guid;
31489879SRamaswamy.Tummala@Sun.COM query_hca_port->port_num = query_hca_port_32->port_num;
31499879SRamaswamy.Tummala@Sun.COM
31509879SRamaswamy.Tummala@Sun.COM query_hca_port->sgid_tbl =
31519879SRamaswamy.Tummala@Sun.COM (ib_gid_t *)(uintptr_t)query_hca_port_32->sgid_tbl;
31529879SRamaswamy.Tummala@Sun.COM query_hca_port->sgid_tbl_alloc_sz =
31539879SRamaswamy.Tummala@Sun.COM query_hca_port_32->sgid_tbl_alloc_sz;
31549879SRamaswamy.Tummala@Sun.COM
31559879SRamaswamy.Tummala@Sun.COM query_hca_port->pkey_tbl =
31569879SRamaswamy.Tummala@Sun.COM (ib_pkey_t *)(uintptr_t)query_hca_port_32->pkey_tbl;
31579879SRamaswamy.Tummala@Sun.COM query_hca_port->pkey_tbl_alloc_sz =
31589879SRamaswamy.Tummala@Sun.COM query_hca_port_32->pkey_tbl_alloc_sz;
31599879SRamaswamy.Tummala@Sun.COM
31609879SRamaswamy.Tummala@Sun.COM } else
31619879SRamaswamy.Tummala@Sun.COM #endif
31629879SRamaswamy.Tummala@Sun.COM {
31639879SRamaswamy.Tummala@Sun.COM if (ddi_copyin((void *)arg, query_hca_port,
31649879SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_query_hca_port_t), mode) != 0) {
31659879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
31669879SRamaswamy.Tummala@Sun.COM "\tctl_query_hca_port: ddi_copyin err 2");
31679879SRamaswamy.Tummala@Sun.COM rv = EFAULT;
31689879SRamaswamy.Tummala@Sun.COM goto out;
31699879SRamaswamy.Tummala@Sun.COM }
31709879SRamaswamy.Tummala@Sun.COM }
31719879SRamaswamy.Tummala@Sun.COM
317210183SRamaswamy.Tummala@Sun.COM if (ibt_query_hca_byguid(query_hca_port->hca_guid, &hca_attr) !=
317310183SRamaswamy.Tummala@Sun.COM IBT_SUCCESS) {
317410183SRamaswamy.Tummala@Sun.COM rv = ENXIO;
317510183SRamaswamy.Tummala@Sun.COM goto out;
317610183SRamaswamy.Tummala@Sun.COM }
317710183SRamaswamy.Tummala@Sun.COM
317810183SRamaswamy.Tummala@Sun.COM if (query_hca_port->port_num == 0 ||
317910183SRamaswamy.Tummala@Sun.COM query_hca_port->port_num > hca_attr.hca_nports) {
318010183SRamaswamy.Tummala@Sun.COM rv = ENOENT;
31819879SRamaswamy.Tummala@Sun.COM goto out;
31829879SRamaswamy.Tummala@Sun.COM }
31839879SRamaswamy.Tummala@Sun.COM
31849879SRamaswamy.Tummala@Sun.COM /*
31859879SRamaswamy.Tummala@Sun.COM * Query hca port attributes and copy them to the user space.
31869879SRamaswamy.Tummala@Sun.COM */
31879879SRamaswamy.Tummala@Sun.COM
31889879SRamaswamy.Tummala@Sun.COM if (ibt_query_hca_ports_byguid(query_hca_port->hca_guid,
31899879SRamaswamy.Tummala@Sun.COM query_hca_port->port_num, &ibt_pi, &nports, &size) != IBT_SUCCESS) {
319010183SRamaswamy.Tummala@Sun.COM rv = ENXIO;
31919879SRamaswamy.Tummala@Sun.COM goto out;
31929879SRamaswamy.Tummala@Sun.COM }
31939879SRamaswamy.Tummala@Sun.COM
31949879SRamaswamy.Tummala@Sun.COM sgid_tbl_sz = MIN(query_hca_port->sgid_tbl_alloc_sz,
31959879SRamaswamy.Tummala@Sun.COM ibt_pi->p_sgid_tbl_sz);
31969879SRamaswamy.Tummala@Sun.COM
31979879SRamaswamy.Tummala@Sun.COM pkey_tbl_sz = MIN(query_hca_port->pkey_tbl_alloc_sz,
31989879SRamaswamy.Tummala@Sun.COM ibt_pi->p_pkey_tbl_sz);
31999879SRamaswamy.Tummala@Sun.COM
32009879SRamaswamy.Tummala@Sun.COM #ifdef _MULTI_DATAMODEL
32019879SRamaswamy.Tummala@Sun.COM if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
32029879SRamaswamy.Tummala@Sun.COM IBNEX_CTL_CP_PORT_INFO(
32039879SRamaswamy.Tummala@Sun.COM &query_hca_port_32->port_info, ibt_pi,
32049879SRamaswamy.Tummala@Sun.COM query_hca_port_32->sgid_tbl, query_hca_port_32->pkey_tbl);
32059879SRamaswamy.Tummala@Sun.COM
32069879SRamaswamy.Tummala@Sun.COM if (ddi_copyout(&query_hca_port_32->port_info,
32079879SRamaswamy.Tummala@Sun.COM &((ibnex_ctl_query_hca_port_32_t *)arg)->port_info,
32089879SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_hca_port_info_32_t), mode) != 0 ||
32099879SRamaswamy.Tummala@Sun.COM
32109879SRamaswamy.Tummala@Sun.COM ddi_copyout(ibt_pi->p_sgid_tbl,
32119879SRamaswamy.Tummala@Sun.COM query_hca_port->sgid_tbl,
32129879SRamaswamy.Tummala@Sun.COM sgid_tbl_sz * sizeof (ib_gid_t), mode) != 0 ||
32139879SRamaswamy.Tummala@Sun.COM
32149879SRamaswamy.Tummala@Sun.COM ddi_copyout(ibt_pi->p_pkey_tbl,
32159879SRamaswamy.Tummala@Sun.COM query_hca_port->pkey_tbl,
32169879SRamaswamy.Tummala@Sun.COM pkey_tbl_sz * sizeof (ib_pkey_t), mode) != 0) {
32179879SRamaswamy.Tummala@Sun.COM
32189879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
32199879SRamaswamy.Tummala@Sun.COM "\tctl_query_hca_port: ddi_copyout err 2");
32209879SRamaswamy.Tummala@Sun.COM rv = EFAULT;
32219879SRamaswamy.Tummala@Sun.COM goto out;
32229879SRamaswamy.Tummala@Sun.COM }
32239879SRamaswamy.Tummala@Sun.COM } else
32249879SRamaswamy.Tummala@Sun.COM #endif
32259879SRamaswamy.Tummala@Sun.COM {
32269879SRamaswamy.Tummala@Sun.COM IBNEX_CTL_CP_PORT_INFO(
32279879SRamaswamy.Tummala@Sun.COM &query_hca_port->port_info, ibt_pi,
32289879SRamaswamy.Tummala@Sun.COM query_hca_port->sgid_tbl, query_hca_port->pkey_tbl);
32299879SRamaswamy.Tummala@Sun.COM
32309879SRamaswamy.Tummala@Sun.COM if (ddi_copyout(&query_hca_port->port_info,
32319879SRamaswamy.Tummala@Sun.COM &((ibnex_ctl_query_hca_port_t *)arg)->port_info,
32329879SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_hca_port_info_t), mode) != 0 ||
32339879SRamaswamy.Tummala@Sun.COM
32349879SRamaswamy.Tummala@Sun.COM ddi_copyout(ibt_pi->p_sgid_tbl,
32359879SRamaswamy.Tummala@Sun.COM query_hca_port->sgid_tbl,
32369879SRamaswamy.Tummala@Sun.COM sgid_tbl_sz * sizeof (ib_gid_t), mode) != 0 ||
32379879SRamaswamy.Tummala@Sun.COM
32389879SRamaswamy.Tummala@Sun.COM ddi_copyout(ibt_pi->p_pkey_tbl,
32399879SRamaswamy.Tummala@Sun.COM query_hca_port->pkey_tbl,
32409879SRamaswamy.Tummala@Sun.COM pkey_tbl_sz * sizeof (ib_pkey_t), mode) != 0) {
32419879SRamaswamy.Tummala@Sun.COM
32429879SRamaswamy.Tummala@Sun.COM IBTF_DPRINTF_L2("ibnex",
32439879SRamaswamy.Tummala@Sun.COM "\tctl_query_hca_port: ddi_copyout err 2");
32449879SRamaswamy.Tummala@Sun.COM rv = EFAULT;
32459879SRamaswamy.Tummala@Sun.COM goto out;
32469879SRamaswamy.Tummala@Sun.COM }
32479879SRamaswamy.Tummala@Sun.COM }
32489879SRamaswamy.Tummala@Sun.COM
32499879SRamaswamy.Tummala@Sun.COM out:
32509879SRamaswamy.Tummala@Sun.COM if (size > 0)
32519879SRamaswamy.Tummala@Sun.COM ibt_free_portinfo(ibt_pi, size);
32529879SRamaswamy.Tummala@Sun.COM
32539879SRamaswamy.Tummala@Sun.COM if (query_hca_port)
32549879SRamaswamy.Tummala@Sun.COM kmem_free(query_hca_port, sizeof (ibnex_ctl_query_hca_port_t));
32559879SRamaswamy.Tummala@Sun.COM
32569879SRamaswamy.Tummala@Sun.COM if (query_hca_port_32)
32579879SRamaswamy.Tummala@Sun.COM kmem_free(query_hca_port_32,
32589879SRamaswamy.Tummala@Sun.COM sizeof (ibnex_ctl_query_hca_port_32_t));
32599879SRamaswamy.Tummala@Sun.COM return (rv);
32609879SRamaswamy.Tummala@Sun.COM }
3261