1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte /* 27*fcf3ce44SJohn Forte * Media independent RPC-like comms 28*fcf3ce44SJohn Forte */ 29*fcf3ce44SJohn Forte 30*fcf3ce44SJohn Forte #include <sys/types.h> 31*fcf3ce44SJohn Forte #include <sys/conf.h> 32*fcf3ce44SJohn Forte #include <sys/stat.h> 33*fcf3ce44SJohn Forte #include <sys/errno.h> 34*fcf3ce44SJohn Forte #include <sys/cmn_err.h> 35*fcf3ce44SJohn Forte #include <sys/ksynch.h> 36*fcf3ce44SJohn Forte #include <sys/kmem.h> 37*fcf3ce44SJohn Forte #include <sys/modctl.h> 38*fcf3ce44SJohn Forte #include <sys/ddi.h> 39*fcf3ce44SJohn Forte #include <sys/sunddi.h> 40*fcf3ce44SJohn Forte 41*fcf3ce44SJohn Forte #include <sys/varargs.h> 42*fcf3ce44SJohn Forte #ifdef DS_DDICT 43*fcf3ce44SJohn Forte #include <sys/nsctl/contract.h> 44*fcf3ce44SJohn Forte #endif 45*fcf3ce44SJohn Forte #include "ncall.h" 46*fcf3ce44SJohn Forte #include "ncall_module.h" 47*fcf3ce44SJohn Forte 48*fcf3ce44SJohn Forte #include <sys/nsctl/nsvers.h> 49*fcf3ce44SJohn Forte 50*fcf3ce44SJohn Forte /* 51*fcf3ce44SJohn Forte * cb_ops functions. 52*fcf3ce44SJohn Forte */ 53*fcf3ce44SJohn Forte 54*fcf3ce44SJohn Forte static int ncallioctl(dev_t, int, intptr_t, int, cred_t *, int *); 55*fcf3ce44SJohn Forte static int ncallprint(dev_t, char *); 56*fcf3ce44SJohn Forte 57*fcf3ce44SJohn Forte 58*fcf3ce44SJohn Forte static struct cb_ops ncall_cb_ops = { 59*fcf3ce44SJohn Forte nulldev, /* open */ 60*fcf3ce44SJohn Forte nulldev, /* close */ 61*fcf3ce44SJohn Forte nulldev, /* strategy */ 62*fcf3ce44SJohn Forte ncallprint, 63*fcf3ce44SJohn Forte nodev, /* dump */ 64*fcf3ce44SJohn Forte nodev, /* read */ 65*fcf3ce44SJohn Forte nodev, /* write */ 66*fcf3ce44SJohn Forte ncallioctl, 67*fcf3ce44SJohn Forte nodev, /* devmap */ 68*fcf3ce44SJohn Forte nodev, /* mmap */ 69*fcf3ce44SJohn Forte nodev, /* segmap */ 70*fcf3ce44SJohn Forte nochpoll, /* poll */ 71*fcf3ce44SJohn Forte ddi_prop_op, 72*fcf3ce44SJohn Forte NULL, /* NOT a stream */ 73*fcf3ce44SJohn Forte D_NEW | D_MP | D_64BIT, 74*fcf3ce44SJohn Forte CB_REV, 75*fcf3ce44SJohn Forte nodev, /* aread */ 76*fcf3ce44SJohn Forte nodev, /* awrite */ 77*fcf3ce44SJohn Forte }; 78*fcf3ce44SJohn Forte 79*fcf3ce44SJohn Forte 80*fcf3ce44SJohn Forte /* 81*fcf3ce44SJohn Forte * dev_ops functions. 82*fcf3ce44SJohn Forte */ 83*fcf3ce44SJohn Forte 84*fcf3ce44SJohn Forte static int ncall_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 85*fcf3ce44SJohn Forte static int ncall_attach(dev_info_t *, ddi_attach_cmd_t); 86*fcf3ce44SJohn Forte static int ncall_detach(dev_info_t *, ddi_detach_cmd_t); 87*fcf3ce44SJohn Forte 88*fcf3ce44SJohn Forte static struct dev_ops ncall_ops = { 89*fcf3ce44SJohn Forte DEVO_REV, 90*fcf3ce44SJohn Forte 0, 91*fcf3ce44SJohn Forte ncall_getinfo, 92*fcf3ce44SJohn Forte nulldev, /* identify */ 93*fcf3ce44SJohn Forte nulldev, /* probe */ 94*fcf3ce44SJohn Forte ncall_attach, 95*fcf3ce44SJohn Forte ncall_detach, 96*fcf3ce44SJohn Forte nodev, /* reset */ 97*fcf3ce44SJohn Forte &ncall_cb_ops, 98*fcf3ce44SJohn Forte (struct bus_ops *)0, 99*fcf3ce44SJohn Forte NULL /* power */ 100*fcf3ce44SJohn Forte }; 101*fcf3ce44SJohn Forte 102*fcf3ce44SJohn Forte /* 103*fcf3ce44SJohn Forte * Module linkage. 104*fcf3ce44SJohn Forte */ 105*fcf3ce44SJohn Forte 106*fcf3ce44SJohn Forte extern struct mod_ops mod_driverops; 107*fcf3ce44SJohn Forte 108*fcf3ce44SJohn Forte static struct modldrv modldrv = { 109*fcf3ce44SJohn Forte &mod_driverops, 110*fcf3ce44SJohn Forte "nws:Kernel Call:" ISS_VERSION_STR, 111*fcf3ce44SJohn Forte &ncall_ops 112*fcf3ce44SJohn Forte }; 113*fcf3ce44SJohn Forte 114*fcf3ce44SJohn Forte static struct modlinkage modlinkage = { 115*fcf3ce44SJohn Forte MODREV_1, 116*fcf3ce44SJohn Forte &modldrv, 117*fcf3ce44SJohn Forte 0 118*fcf3ce44SJohn Forte }; 119*fcf3ce44SJohn Forte 120*fcf3ce44SJohn Forte typedef struct ncall_modinfo_s { 121*fcf3ce44SJohn Forte struct ncall_modinfo_s *next; 122*fcf3ce44SJohn Forte ncall_module_t *module; 123*fcf3ce44SJohn Forte } ncall_modinfo_t; 124*fcf3ce44SJohn Forte 125*fcf3ce44SJohn Forte static dev_info_t *ncall_dip; /* Single DIP for driver */ 126*fcf3ce44SJohn Forte static kmutex_t ncall_mutex; 127*fcf3ce44SJohn Forte 128*fcf3ce44SJohn Forte static ncall_modinfo_t *ncall_modules; 129*fcf3ce44SJohn Forte static int ncall_active; 130*fcf3ce44SJohn Forte 131*fcf3ce44SJohn Forte static ncall_node_t ncall_nodeinfo; 132*fcf3ce44SJohn Forte 133*fcf3ce44SJohn Forte static int ncallgetnodes(intptr_t, int, int *); 134*fcf3ce44SJohn Forte extern void ncall_init_stub(void); 135*fcf3ce44SJohn Forte 136*fcf3ce44SJohn Forte int 137*fcf3ce44SJohn Forte _init(void) 138*fcf3ce44SJohn Forte { 139*fcf3ce44SJohn Forte int error; 140*fcf3ce44SJohn Forte 141*fcf3ce44SJohn Forte mutex_init(&ncall_mutex, NULL, MUTEX_DRIVER, NULL); 142*fcf3ce44SJohn Forte 143*fcf3ce44SJohn Forte if ((error = mod_install(&modlinkage)) != 0) { 144*fcf3ce44SJohn Forte mutex_destroy(&ncall_mutex); 145*fcf3ce44SJohn Forte return (error); 146*fcf3ce44SJohn Forte } 147*fcf3ce44SJohn Forte 148*fcf3ce44SJohn Forte return (0); 149*fcf3ce44SJohn Forte } 150*fcf3ce44SJohn Forte 151*fcf3ce44SJohn Forte 152*fcf3ce44SJohn Forte int 153*fcf3ce44SJohn Forte _fini(void) 154*fcf3ce44SJohn Forte { 155*fcf3ce44SJohn Forte int error; 156*fcf3ce44SJohn Forte 157*fcf3ce44SJohn Forte if ((error = mod_remove(&modlinkage)) != 0) 158*fcf3ce44SJohn Forte return (error); 159*fcf3ce44SJohn Forte 160*fcf3ce44SJohn Forte mutex_destroy(&ncall_mutex); 161*fcf3ce44SJohn Forte return (error); 162*fcf3ce44SJohn Forte } 163*fcf3ce44SJohn Forte 164*fcf3ce44SJohn Forte 165*fcf3ce44SJohn Forte int 166*fcf3ce44SJohn Forte _info(struct modinfo *modinfop) 167*fcf3ce44SJohn Forte { 168*fcf3ce44SJohn Forte return (mod_info(&modlinkage, modinfop)); 169*fcf3ce44SJohn Forte } 170*fcf3ce44SJohn Forte 171*fcf3ce44SJohn Forte static int 172*fcf3ce44SJohn Forte ncall_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 173*fcf3ce44SJohn Forte { 174*fcf3ce44SJohn Forte switch (cmd) { 175*fcf3ce44SJohn Forte 176*fcf3ce44SJohn Forte case DDI_ATTACH: 177*fcf3ce44SJohn Forte ncall_dip = dip; 178*fcf3ce44SJohn Forte 179*fcf3ce44SJohn Forte if (ddi_create_minor_node(dip, "c,ncall", S_IFCHR, 180*fcf3ce44SJohn Forte 0, DDI_PSEUDO, 0) != DDI_SUCCESS) 181*fcf3ce44SJohn Forte goto failed; 182*fcf3ce44SJohn Forte 183*fcf3ce44SJohn Forte ddi_report_dev(dip); 184*fcf3ce44SJohn Forte 185*fcf3ce44SJohn Forte return (DDI_SUCCESS); 186*fcf3ce44SJohn Forte 187*fcf3ce44SJohn Forte default: 188*fcf3ce44SJohn Forte return (DDI_FAILURE); 189*fcf3ce44SJohn Forte } 190*fcf3ce44SJohn Forte 191*fcf3ce44SJohn Forte failed: 192*fcf3ce44SJohn Forte (void) ncall_detach(dip, DDI_DETACH); 193*fcf3ce44SJohn Forte return (DDI_FAILURE); 194*fcf3ce44SJohn Forte } 195*fcf3ce44SJohn Forte 196*fcf3ce44SJohn Forte 197*fcf3ce44SJohn Forte static int 198*fcf3ce44SJohn Forte ncall_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 199*fcf3ce44SJohn Forte { 200*fcf3ce44SJohn Forte switch (cmd) { 201*fcf3ce44SJohn Forte 202*fcf3ce44SJohn Forte case DDI_DETACH: 203*fcf3ce44SJohn Forte 204*fcf3ce44SJohn Forte /* 205*fcf3ce44SJohn Forte * If still active, then refuse to detach. 206*fcf3ce44SJohn Forte */ 207*fcf3ce44SJohn Forte 208*fcf3ce44SJohn Forte if (ncall_modules != NULL || ncall_active) 209*fcf3ce44SJohn Forte return (DDI_FAILURE); 210*fcf3ce44SJohn Forte 211*fcf3ce44SJohn Forte /* 212*fcf3ce44SJohn Forte * Remove all minor nodes. 213*fcf3ce44SJohn Forte */ 214*fcf3ce44SJohn Forte 215*fcf3ce44SJohn Forte ddi_remove_minor_node(dip, NULL); 216*fcf3ce44SJohn Forte ncall_dip = NULL; 217*fcf3ce44SJohn Forte 218*fcf3ce44SJohn Forte return (DDI_SUCCESS); 219*fcf3ce44SJohn Forte 220*fcf3ce44SJohn Forte default: 221*fcf3ce44SJohn Forte return (DDI_FAILURE); 222*fcf3ce44SJohn Forte } 223*fcf3ce44SJohn Forte } 224*fcf3ce44SJohn Forte 225*fcf3ce44SJohn Forte 226*fcf3ce44SJohn Forte /* ARGSUSED */ 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte static int 229*fcf3ce44SJohn Forte ncall_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 230*fcf3ce44SJohn Forte { 231*fcf3ce44SJohn Forte int rc = DDI_FAILURE; 232*fcf3ce44SJohn Forte 233*fcf3ce44SJohn Forte switch (infocmd) { 234*fcf3ce44SJohn Forte 235*fcf3ce44SJohn Forte case DDI_INFO_DEVT2DEVINFO: 236*fcf3ce44SJohn Forte *result = ncall_dip; 237*fcf3ce44SJohn Forte rc = DDI_SUCCESS; 238*fcf3ce44SJohn Forte break; 239*fcf3ce44SJohn Forte 240*fcf3ce44SJohn Forte case DDI_INFO_DEVT2INSTANCE: 241*fcf3ce44SJohn Forte /* 242*fcf3ce44SJohn Forte * We only have a single instance. 243*fcf3ce44SJohn Forte */ 244*fcf3ce44SJohn Forte *result = 0; 245*fcf3ce44SJohn Forte rc = DDI_SUCCESS; 246*fcf3ce44SJohn Forte break; 247*fcf3ce44SJohn Forte 248*fcf3ce44SJohn Forte default: 249*fcf3ce44SJohn Forte break; 250*fcf3ce44SJohn Forte } 251*fcf3ce44SJohn Forte 252*fcf3ce44SJohn Forte return (rc); 253*fcf3ce44SJohn Forte } 254*fcf3ce44SJohn Forte 255*fcf3ce44SJohn Forte 256*fcf3ce44SJohn Forte /* ARGSUSED */ 257*fcf3ce44SJohn Forte static int 258*fcf3ce44SJohn Forte ncallprint(dev_t dev, char *str) 259*fcf3ce44SJohn Forte { 260*fcf3ce44SJohn Forte cmn_err(CE_WARN, "%s%d: %s", ddi_get_name(ncall_dip), 261*fcf3ce44SJohn Forte ddi_get_instance(ncall_dip), str); 262*fcf3ce44SJohn Forte 263*fcf3ce44SJohn Forte return (0); 264*fcf3ce44SJohn Forte } 265*fcf3ce44SJohn Forte 266*fcf3ce44SJohn Forte 267*fcf3ce44SJohn Forte int 268*fcf3ce44SJohn Forte ncall_register_module(ncall_module_t *mp, ncall_node_t *nodep) 269*fcf3ce44SJohn Forte { 270*fcf3ce44SJohn Forte ncall_modinfo_t *new; 271*fcf3ce44SJohn Forte int rc = 0; 272*fcf3ce44SJohn Forte 273*fcf3ce44SJohn Forte if (mp == NULL || mp->ncall_version != NCALL_MODULE_VER) 274*fcf3ce44SJohn Forte return (EINVAL); 275*fcf3ce44SJohn Forte 276*fcf3ce44SJohn Forte new = kmem_alloc(sizeof (*new), KM_SLEEP); 277*fcf3ce44SJohn Forte 278*fcf3ce44SJohn Forte if (new != NULL) { 279*fcf3ce44SJohn Forte new->module = mp; 280*fcf3ce44SJohn Forte 281*fcf3ce44SJohn Forte mutex_enter(&ncall_mutex); 282*fcf3ce44SJohn Forte 283*fcf3ce44SJohn Forte new->next = ncall_modules; 284*fcf3ce44SJohn Forte ncall_modules = new; 285*fcf3ce44SJohn Forte 286*fcf3ce44SJohn Forte mutex_exit(&ncall_mutex); 287*fcf3ce44SJohn Forte } else { 288*fcf3ce44SJohn Forte rc = ENOMEM; 289*fcf3ce44SJohn Forte } 290*fcf3ce44SJohn Forte 291*fcf3ce44SJohn Forte *nodep = ncall_nodeinfo; /* structure copy */ 292*fcf3ce44SJohn Forte return (rc); 293*fcf3ce44SJohn Forte } 294*fcf3ce44SJohn Forte 295*fcf3ce44SJohn Forte 296*fcf3ce44SJohn Forte int 297*fcf3ce44SJohn Forte ncall_unregister_module(ncall_module_t *mod) 298*fcf3ce44SJohn Forte { 299*fcf3ce44SJohn Forte ncall_modinfo_t **mpp; 300*fcf3ce44SJohn Forte int rc = ESRCH; 301*fcf3ce44SJohn Forte 302*fcf3ce44SJohn Forte mutex_enter(&ncall_mutex); 303*fcf3ce44SJohn Forte 304*fcf3ce44SJohn Forte for (mpp = &ncall_modules; *mpp != NULL; mpp = &((*mpp)->next)) { 305*fcf3ce44SJohn Forte if ((*mpp)->module == mod) { 306*fcf3ce44SJohn Forte *mpp = (*mpp)->next; 307*fcf3ce44SJohn Forte rc = 0; 308*fcf3ce44SJohn Forte break; 309*fcf3ce44SJohn Forte } 310*fcf3ce44SJohn Forte } 311*fcf3ce44SJohn Forte 312*fcf3ce44SJohn Forte mutex_exit(&ncall_mutex); 313*fcf3ce44SJohn Forte 314*fcf3ce44SJohn Forte return (rc); 315*fcf3ce44SJohn Forte } 316*fcf3ce44SJohn Forte 317*fcf3ce44SJohn Forte 318*fcf3ce44SJohn Forte static int 319*fcf3ce44SJohn Forte ncall_stop(void) 320*fcf3ce44SJohn Forte { 321*fcf3ce44SJohn Forte ncall_modinfo_t *mod; 322*fcf3ce44SJohn Forte int rc = 0; 323*fcf3ce44SJohn Forte 324*fcf3ce44SJohn Forte mutex_enter(&ncall_mutex); 325*fcf3ce44SJohn Forte 326*fcf3ce44SJohn Forte while ((rc == 0) && ((mod = ncall_modules) != NULL)) { 327*fcf3ce44SJohn Forte mutex_exit(&ncall_mutex); 328*fcf3ce44SJohn Forte 329*fcf3ce44SJohn Forte rc = (*mod->module->ncall_stop)(); 330*fcf3ce44SJohn Forte 331*fcf3ce44SJohn Forte mutex_enter(&ncall_mutex); 332*fcf3ce44SJohn Forte } 333*fcf3ce44SJohn Forte 334*fcf3ce44SJohn Forte mutex_exit(&ncall_mutex); 335*fcf3ce44SJohn Forte 336*fcf3ce44SJohn Forte return (rc); 337*fcf3ce44SJohn Forte } 338*fcf3ce44SJohn Forte 339*fcf3ce44SJohn Forte 340*fcf3ce44SJohn Forte /* ARGSUSED */ 341*fcf3ce44SJohn Forte static int ncallioctl(dev_t dev, int cmd, intptr_t arg, int mode, 342*fcf3ce44SJohn Forte cred_t *crp, int *rvalp) 343*fcf3ce44SJohn Forte { 344*fcf3ce44SJohn Forte ncall_node_t node = { 0, }; 345*fcf3ce44SJohn Forte int mirror; 346*fcf3ce44SJohn Forte int rc = 0; 347*fcf3ce44SJohn Forte 348*fcf3ce44SJohn Forte *rvalp = 0; 349*fcf3ce44SJohn Forte 350*fcf3ce44SJohn Forte if ((rc = drv_priv(crp)) != 0) 351*fcf3ce44SJohn Forte return (rc); 352*fcf3ce44SJohn Forte 353*fcf3ce44SJohn Forte switch (cmd) { 354*fcf3ce44SJohn Forte 355*fcf3ce44SJohn Forte case NC_IOC_START: 356*fcf3ce44SJohn Forte if (ncall_active) { 357*fcf3ce44SJohn Forte rc = EALREADY; 358*fcf3ce44SJohn Forte break; 359*fcf3ce44SJohn Forte } 360*fcf3ce44SJohn Forte 361*fcf3ce44SJohn Forte if (ddi_copyin((void *)arg, &node, sizeof (node), mode) < 0) 362*fcf3ce44SJohn Forte return (EFAULT); 363*fcf3ce44SJohn Forte 364*fcf3ce44SJohn Forte bcopy(&node, &ncall_nodeinfo, sizeof (ncall_nodeinfo)); 365*fcf3ce44SJohn Forte ncall_init_stub(); 366*fcf3ce44SJohn Forte ncall_active = 1; 367*fcf3ce44SJohn Forte break; 368*fcf3ce44SJohn Forte 369*fcf3ce44SJohn Forte case NC_IOC_STOP: 370*fcf3ce44SJohn Forte ncall_active = 0; 371*fcf3ce44SJohn Forte rc = ncall_stop(); 372*fcf3ce44SJohn Forte break; 373*fcf3ce44SJohn Forte 374*fcf3ce44SJohn Forte case NC_IOC_GETNODE: 375*fcf3ce44SJohn Forte if (!ncall_active) { 376*fcf3ce44SJohn Forte rc = ENONET; 377*fcf3ce44SJohn Forte break; 378*fcf3ce44SJohn Forte } 379*fcf3ce44SJohn Forte if (ddi_copyout(&ncall_nodeinfo, (void *)arg, 380*fcf3ce44SJohn Forte sizeof (ncall_nodeinfo), mode) < 0) { 381*fcf3ce44SJohn Forte rc = EFAULT; 382*fcf3ce44SJohn Forte break; 383*fcf3ce44SJohn Forte } 384*fcf3ce44SJohn Forte mirror = ncall_mirror(ncall_nodeinfo.nc_nodeid); 385*fcf3ce44SJohn Forte /* 386*fcf3ce44SJohn Forte * can't return -1, as this will mask the ioctl 387*fcf3ce44SJohn Forte * failure, so return 0. 388*fcf3ce44SJohn Forte */ 389*fcf3ce44SJohn Forte if (mirror == -1) 390*fcf3ce44SJohn Forte mirror = 0; 391*fcf3ce44SJohn Forte *rvalp = mirror; 392*fcf3ce44SJohn Forte break; 393*fcf3ce44SJohn Forte 394*fcf3ce44SJohn Forte case NC_IOC_GETNETNODES: 395*fcf3ce44SJohn Forte rc = ncallgetnodes(arg, mode, rvalp); 396*fcf3ce44SJohn Forte break; 397*fcf3ce44SJohn Forte 398*fcf3ce44SJohn Forte case NC_IOC_PING: 399*fcf3ce44SJohn Forte if (!ncall_active) { 400*fcf3ce44SJohn Forte rc = ENONET; 401*fcf3ce44SJohn Forte break; 402*fcf3ce44SJohn Forte } 403*fcf3ce44SJohn Forte 404*fcf3ce44SJohn Forte if (ddi_copyin((void *)arg, &node, sizeof (node), mode) < 0) { 405*fcf3ce44SJohn Forte rc = EFAULT; 406*fcf3ce44SJohn Forte break; 407*fcf3ce44SJohn Forte } 408*fcf3ce44SJohn Forte 409*fcf3ce44SJohn Forte node.nc_nodename[sizeof (node.nc_nodename)-1] = '\0'; 410*fcf3ce44SJohn Forte rc = ncall_ping(node.nc_nodename, rvalp); 411*fcf3ce44SJohn Forte break; 412*fcf3ce44SJohn Forte 413*fcf3ce44SJohn Forte default: 414*fcf3ce44SJohn Forte rc = EINVAL; 415*fcf3ce44SJohn Forte break; 416*fcf3ce44SJohn Forte } 417*fcf3ce44SJohn Forte 418*fcf3ce44SJohn Forte return (rc); 419*fcf3ce44SJohn Forte } 420*fcf3ce44SJohn Forte 421*fcf3ce44SJohn Forte 422*fcf3ce44SJohn Forte void 423*fcf3ce44SJohn Forte ncall_register_svc(int svc_id, void (*func)(ncall_t *, int *)) 424*fcf3ce44SJohn Forte { 425*fcf3ce44SJohn Forte if (ncall_modules) 426*fcf3ce44SJohn Forte (*ncall_modules->module->ncall_register_svc)(svc_id, func); 427*fcf3ce44SJohn Forte } 428*fcf3ce44SJohn Forte 429*fcf3ce44SJohn Forte 430*fcf3ce44SJohn Forte void 431*fcf3ce44SJohn Forte ncall_unregister_svc(int svc_id) 432*fcf3ce44SJohn Forte { 433*fcf3ce44SJohn Forte if (ncall_modules) 434*fcf3ce44SJohn Forte (*ncall_modules->module->ncall_unregister_svc)(svc_id); 435*fcf3ce44SJohn Forte } 436*fcf3ce44SJohn Forte 437*fcf3ce44SJohn Forte 438*fcf3ce44SJohn Forte int 439*fcf3ce44SJohn Forte ncall_nodeid(char *nodename) 440*fcf3ce44SJohn Forte { 441*fcf3ce44SJohn Forte if (ncall_modules) 442*fcf3ce44SJohn Forte return ((ncall_modules->module->ncall_nodeid)(nodename)); 443*fcf3ce44SJohn Forte else 444*fcf3ce44SJohn Forte return (0); 445*fcf3ce44SJohn Forte } 446*fcf3ce44SJohn Forte 447*fcf3ce44SJohn Forte 448*fcf3ce44SJohn Forte char * 449*fcf3ce44SJohn Forte ncall_nodename(int nodeid) 450*fcf3ce44SJohn Forte { 451*fcf3ce44SJohn Forte if (ncall_modules) 452*fcf3ce44SJohn Forte return ((*ncall_modules->module->ncall_nodename)(nodeid)); 453*fcf3ce44SJohn Forte else 454*fcf3ce44SJohn Forte return ("unknown"); 455*fcf3ce44SJohn Forte } 456*fcf3ce44SJohn Forte 457*fcf3ce44SJohn Forte 458*fcf3ce44SJohn Forte int 459*fcf3ce44SJohn Forte ncall_mirror(int nodeid) 460*fcf3ce44SJohn Forte { 461*fcf3ce44SJohn Forte if (ncall_modules) 462*fcf3ce44SJohn Forte return ((*ncall_modules->module->ncall_mirror)(nodeid)); 463*fcf3ce44SJohn Forte else 464*fcf3ce44SJohn Forte return (-1); 465*fcf3ce44SJohn Forte } 466*fcf3ce44SJohn Forte 467*fcf3ce44SJohn Forte 468*fcf3ce44SJohn Forte int 469*fcf3ce44SJohn Forte ncall_self(void) 470*fcf3ce44SJohn Forte { 471*fcf3ce44SJohn Forte if (ncall_modules) 472*fcf3ce44SJohn Forte return ((*ncall_modules->module->ncall_self)()); 473*fcf3ce44SJohn Forte else 474*fcf3ce44SJohn Forte return (-1); 475*fcf3ce44SJohn Forte } 476*fcf3ce44SJohn Forte 477*fcf3ce44SJohn Forte 478*fcf3ce44SJohn Forte int 479*fcf3ce44SJohn Forte ncall_alloc(int host_id, int flags, int net, ncall_t **ncall_p) 480*fcf3ce44SJohn Forte { 481*fcf3ce44SJohn Forte int rc = ENOLINK; 482*fcf3ce44SJohn Forte 483*fcf3ce44SJohn Forte if (ncall_modules) 484*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_alloc)(host_id, 485*fcf3ce44SJohn Forte flags, net, ncall_p); 486*fcf3ce44SJohn Forte 487*fcf3ce44SJohn Forte return (rc); 488*fcf3ce44SJohn Forte } 489*fcf3ce44SJohn Forte 490*fcf3ce44SJohn Forte 491*fcf3ce44SJohn Forte int 492*fcf3ce44SJohn Forte ncall_timedsend(ncall_t *ncall, int flags, int svc_id, 493*fcf3ce44SJohn Forte struct timeval *t, ...) 494*fcf3ce44SJohn Forte { 495*fcf3ce44SJohn Forte va_list ap; 496*fcf3ce44SJohn Forte int rc = ENOLINK; 497*fcf3ce44SJohn Forte 498*fcf3ce44SJohn Forte va_start(ap, t); 499*fcf3ce44SJohn Forte 500*fcf3ce44SJohn Forte if (ncall_modules) 501*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_timedsend)(ncall, flags, 502*fcf3ce44SJohn Forte svc_id, t, ap); 503*fcf3ce44SJohn Forte 504*fcf3ce44SJohn Forte va_end(ap); 505*fcf3ce44SJohn Forte 506*fcf3ce44SJohn Forte return (rc); 507*fcf3ce44SJohn Forte } 508*fcf3ce44SJohn Forte 509*fcf3ce44SJohn Forte int 510*fcf3ce44SJohn Forte ncall_timedsendnotify(ncall_t *ncall, int flags, int svc_id, 511*fcf3ce44SJohn Forte struct timeval *t, void (*ncall_callback)(ncall_t *, void *), 512*fcf3ce44SJohn Forte void *vptr, ...) 513*fcf3ce44SJohn Forte { 514*fcf3ce44SJohn Forte va_list ap; 515*fcf3ce44SJohn Forte int rc = ENOLINK; 516*fcf3ce44SJohn Forte 517*fcf3ce44SJohn Forte va_start(ap, vptr); 518*fcf3ce44SJohn Forte 519*fcf3ce44SJohn Forte if (ncall_modules) 520*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_timedsendnotify)(ncall, 521*fcf3ce44SJohn Forte flags, svc_id, t, ncall_callback, vptr, ap); 522*fcf3ce44SJohn Forte va_end(ap); 523*fcf3ce44SJohn Forte 524*fcf3ce44SJohn Forte return (rc); 525*fcf3ce44SJohn Forte } 526*fcf3ce44SJohn Forte 527*fcf3ce44SJohn Forte int 528*fcf3ce44SJohn Forte ncall_broadcast(ncall_t *ncall, int flags, int svc_id, 529*fcf3ce44SJohn Forte struct timeval *t, ...) 530*fcf3ce44SJohn Forte { 531*fcf3ce44SJohn Forte va_list ap; 532*fcf3ce44SJohn Forte int rc = ENOLINK; 533*fcf3ce44SJohn Forte 534*fcf3ce44SJohn Forte va_start(ap, t); 535*fcf3ce44SJohn Forte 536*fcf3ce44SJohn Forte if (ncall_modules) 537*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_broadcast)(ncall, flags, 538*fcf3ce44SJohn Forte svc_id, t, ap); 539*fcf3ce44SJohn Forte va_end(ap); 540*fcf3ce44SJohn Forte 541*fcf3ce44SJohn Forte return (rc); 542*fcf3ce44SJohn Forte } 543*fcf3ce44SJohn Forte 544*fcf3ce44SJohn Forte 545*fcf3ce44SJohn Forte int 546*fcf3ce44SJohn Forte ncall_send(ncall_t *ncall, int flags, int svc_id, ...) 547*fcf3ce44SJohn Forte { 548*fcf3ce44SJohn Forte va_list ap; 549*fcf3ce44SJohn Forte int rc = ENOLINK; 550*fcf3ce44SJohn Forte 551*fcf3ce44SJohn Forte va_start(ap, svc_id); 552*fcf3ce44SJohn Forte 553*fcf3ce44SJohn Forte if (ncall_modules) 554*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_timedsend)(ncall, flags, 555*fcf3ce44SJohn Forte svc_id, NULL, ap); 556*fcf3ce44SJohn Forte 557*fcf3ce44SJohn Forte va_end(ap); 558*fcf3ce44SJohn Forte 559*fcf3ce44SJohn Forte return (rc); 560*fcf3ce44SJohn Forte } 561*fcf3ce44SJohn Forte 562*fcf3ce44SJohn Forte 563*fcf3ce44SJohn Forte int 564*fcf3ce44SJohn Forte ncall_read_reply(ncall_t *ncall, int n, ...) 565*fcf3ce44SJohn Forte { 566*fcf3ce44SJohn Forte va_list ap; 567*fcf3ce44SJohn Forte int rc = ENOLINK; 568*fcf3ce44SJohn Forte 569*fcf3ce44SJohn Forte va_start(ap, n); 570*fcf3ce44SJohn Forte 571*fcf3ce44SJohn Forte if (ncall_modules) 572*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_read_reply)(ncall, n, ap); 573*fcf3ce44SJohn Forte 574*fcf3ce44SJohn Forte va_end(ap); 575*fcf3ce44SJohn Forte 576*fcf3ce44SJohn Forte return (rc); 577*fcf3ce44SJohn Forte } 578*fcf3ce44SJohn Forte 579*fcf3ce44SJohn Forte 580*fcf3ce44SJohn Forte void 581*fcf3ce44SJohn Forte ncall_reset(ncall_t *ncall) 582*fcf3ce44SJohn Forte { 583*fcf3ce44SJohn Forte if (ncall_modules) 584*fcf3ce44SJohn Forte (*ncall_modules->module->ncall_reset)(ncall); 585*fcf3ce44SJohn Forte } 586*fcf3ce44SJohn Forte 587*fcf3ce44SJohn Forte 588*fcf3ce44SJohn Forte void 589*fcf3ce44SJohn Forte ncall_free(ncall_t *ncall) 590*fcf3ce44SJohn Forte { 591*fcf3ce44SJohn Forte if (ncall_modules) 592*fcf3ce44SJohn Forte (*ncall_modules->module->ncall_free)(ncall); 593*fcf3ce44SJohn Forte } 594*fcf3ce44SJohn Forte 595*fcf3ce44SJohn Forte 596*fcf3ce44SJohn Forte int 597*fcf3ce44SJohn Forte ncall_put_data(ncall_t *ncall, void *data, int len) 598*fcf3ce44SJohn Forte { 599*fcf3ce44SJohn Forte int rc = ENOLINK; 600*fcf3ce44SJohn Forte 601*fcf3ce44SJohn Forte if (ncall_modules) 602*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_put_data)(ncall, data, len); 603*fcf3ce44SJohn Forte 604*fcf3ce44SJohn Forte return (rc); 605*fcf3ce44SJohn Forte } 606*fcf3ce44SJohn Forte 607*fcf3ce44SJohn Forte 608*fcf3ce44SJohn Forte int 609*fcf3ce44SJohn Forte ncall_get_data(ncall_t *ncall, void *data, int len) 610*fcf3ce44SJohn Forte { 611*fcf3ce44SJohn Forte int rc = ENOLINK; 612*fcf3ce44SJohn Forte 613*fcf3ce44SJohn Forte if (ncall_modules) 614*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_get_data)(ncall, data, len); 615*fcf3ce44SJohn Forte 616*fcf3ce44SJohn Forte return (rc); 617*fcf3ce44SJohn Forte } 618*fcf3ce44SJohn Forte 619*fcf3ce44SJohn Forte 620*fcf3ce44SJohn Forte int 621*fcf3ce44SJohn Forte ncall_sender(ncall_t *ncall) 622*fcf3ce44SJohn Forte { 623*fcf3ce44SJohn Forte int rc = -1; 624*fcf3ce44SJohn Forte 625*fcf3ce44SJohn Forte if (ncall_modules) 626*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_sender)(ncall); 627*fcf3ce44SJohn Forte 628*fcf3ce44SJohn Forte return (rc); 629*fcf3ce44SJohn Forte } 630*fcf3ce44SJohn Forte 631*fcf3ce44SJohn Forte 632*fcf3ce44SJohn Forte void 633*fcf3ce44SJohn Forte ncall_reply(ncall_t *ncall, ...) 634*fcf3ce44SJohn Forte { 635*fcf3ce44SJohn Forte va_list ap; 636*fcf3ce44SJohn Forte 637*fcf3ce44SJohn Forte if (ncall_modules) { 638*fcf3ce44SJohn Forte va_start(ap, ncall); 639*fcf3ce44SJohn Forte 640*fcf3ce44SJohn Forte (*ncall_modules->module->ncall_reply)(ncall, ap); 641*fcf3ce44SJohn Forte 642*fcf3ce44SJohn Forte va_end(ap); 643*fcf3ce44SJohn Forte } 644*fcf3ce44SJohn Forte } 645*fcf3ce44SJohn Forte 646*fcf3ce44SJohn Forte 647*fcf3ce44SJohn Forte void 648*fcf3ce44SJohn Forte ncall_pend(ncall_t *ncall) 649*fcf3ce44SJohn Forte { 650*fcf3ce44SJohn Forte if (ncall_modules) 651*fcf3ce44SJohn Forte (*ncall_modules->module->ncall_pend)(ncall); 652*fcf3ce44SJohn Forte } 653*fcf3ce44SJohn Forte 654*fcf3ce44SJohn Forte 655*fcf3ce44SJohn Forte void 656*fcf3ce44SJohn Forte ncall_done(ncall_t *ncall) 657*fcf3ce44SJohn Forte { 658*fcf3ce44SJohn Forte if (ncall_modules) 659*fcf3ce44SJohn Forte (*ncall_modules->module->ncall_done)(ncall); 660*fcf3ce44SJohn Forte } 661*fcf3ce44SJohn Forte 662*fcf3ce44SJohn Forte int 663*fcf3ce44SJohn Forte ncall_ping(char *nodename, int *up) 664*fcf3ce44SJohn Forte { 665*fcf3ce44SJohn Forte int rc = ENOLINK; 666*fcf3ce44SJohn Forte if (ncall_modules) 667*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_ping)(nodename, up); 668*fcf3ce44SJohn Forte return (rc); 669*fcf3ce44SJohn Forte } 670*fcf3ce44SJohn Forte 671*fcf3ce44SJohn Forte int 672*fcf3ce44SJohn Forte ncall_maxnodes() 673*fcf3ce44SJohn Forte { 674*fcf3ce44SJohn Forte int rc = 0; 675*fcf3ce44SJohn Forte 676*fcf3ce44SJohn Forte if (ncall_modules) 677*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_maxnodes)(); 678*fcf3ce44SJohn Forte 679*fcf3ce44SJohn Forte return (rc); 680*fcf3ce44SJohn Forte } 681*fcf3ce44SJohn Forte 682*fcf3ce44SJohn Forte int 683*fcf3ce44SJohn Forte ncall_nextnode(void **vptr) 684*fcf3ce44SJohn Forte { 685*fcf3ce44SJohn Forte int rc = 0; 686*fcf3ce44SJohn Forte 687*fcf3ce44SJohn Forte if (ncall_modules) 688*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_nextnode)(vptr); 689*fcf3ce44SJohn Forte 690*fcf3ce44SJohn Forte return (rc); 691*fcf3ce44SJohn Forte } 692*fcf3ce44SJohn Forte 693*fcf3ce44SJohn Forte int 694*fcf3ce44SJohn Forte ncall_errcode(ncall_t *ncall, int *result) 695*fcf3ce44SJohn Forte { 696*fcf3ce44SJohn Forte int rc = ENOLINK; 697*fcf3ce44SJohn Forte if (ncall_modules) 698*fcf3ce44SJohn Forte rc = (*ncall_modules->module->ncall_errcode)(ncall, result); 699*fcf3ce44SJohn Forte 700*fcf3ce44SJohn Forte return (rc); 701*fcf3ce44SJohn Forte } 702*fcf3ce44SJohn Forte 703*fcf3ce44SJohn Forte static int 704*fcf3ce44SJohn Forte ncallgetnodes(intptr_t uaddr, int mode, int *rvalp) 705*fcf3ce44SJohn Forte { 706*fcf3ce44SJohn Forte ncall_node_t *nodelist; 707*fcf3ce44SJohn Forte int slot; 708*fcf3ce44SJohn Forte int rc; 709*fcf3ce44SJohn Forte int nodecnt; 710*fcf3ce44SJohn Forte int nodeid; 711*fcf3ce44SJohn Forte void *sequence; 712*fcf3ce44SJohn Forte char *nodename; 713*fcf3ce44SJohn Forte 714*fcf3ce44SJohn Forte rc = 0; 715*fcf3ce44SJohn Forte 716*fcf3ce44SJohn Forte nodecnt = ncall_maxnodes(); 717*fcf3ce44SJohn Forte if (nodecnt <= 0) { 718*fcf3ce44SJohn Forte return (ENONET); 719*fcf3ce44SJohn Forte } 720*fcf3ce44SJohn Forte 721*fcf3ce44SJohn Forte /* 722*fcf3ce44SJohn Forte * If the user passes up a null address argument, then 723*fcf3ce44SJohn Forte * he/she doesn't want the actual nodes, but the configured 724*fcf3ce44SJohn Forte * maximum, so space can be correctly allocated. 725*fcf3ce44SJohn Forte */ 726*fcf3ce44SJohn Forte 727*fcf3ce44SJohn Forte if (uaddr == NULL) { 728*fcf3ce44SJohn Forte *rvalp = nodecnt; 729*fcf3ce44SJohn Forte return (0); 730*fcf3ce44SJohn Forte } 731*fcf3ce44SJohn Forte nodelist = kmem_zalloc(sizeof (*nodelist) * nodecnt, KM_SLEEP); 732*fcf3ce44SJohn Forte 733*fcf3ce44SJohn Forte slot = 0; 734*fcf3ce44SJohn Forte sequence = NULL; 735*fcf3ce44SJohn Forte while ((nodeid = ncall_nextnode(&sequence)) > 0) { 736*fcf3ce44SJohn Forte nodename = ncall_nodename(nodeid); 737*fcf3ce44SJohn Forte /* 738*fcf3ce44SJohn Forte * There is a small window where nextnode can 739*fcf3ce44SJohn Forte * return a valid nodeid, and it being disabled 740*fcf3ce44SJohn Forte * which will get nodename to return "". 741*fcf3ce44SJohn Forte * Discard the nodeid if this happens. 742*fcf3ce44SJohn Forte */ 743*fcf3ce44SJohn Forte if (strlen(nodename) > 0) { 744*fcf3ce44SJohn Forte int size = sizeof (nodelist[slot].nc_nodename) - 1; 745*fcf3ce44SJohn Forte ASSERT(slot < nodecnt); 746*fcf3ce44SJohn Forte /* 747*fcf3ce44SJohn Forte * make sure its null terminated when it 748*fcf3ce44SJohn Forte * gets to userland. 749*fcf3ce44SJohn Forte */ 750*fcf3ce44SJohn Forte nodelist[slot].nc_nodename[size] = 0; 751*fcf3ce44SJohn Forte (void) strncpy(nodelist[slot].nc_nodename, nodename, 752*fcf3ce44SJohn Forte size); 753*fcf3ce44SJohn Forte nodelist[slot].nc_nodeid = nodeid; 754*fcf3ce44SJohn Forte slot++; 755*fcf3ce44SJohn Forte } 756*fcf3ce44SJohn Forte } 757*fcf3ce44SJohn Forte if (ddi_copyout(nodelist, (void *)uaddr, sizeof (*nodelist) * slot, 758*fcf3ce44SJohn Forte mode) < 0) { 759*fcf3ce44SJohn Forte rc = EFAULT; 760*fcf3ce44SJohn Forte } else { 761*fcf3ce44SJohn Forte /* 762*fcf3ce44SJohn Forte * tell them how many have come back. 763*fcf3ce44SJohn Forte */ 764*fcf3ce44SJohn Forte *rvalp = slot; 765*fcf3ce44SJohn Forte } 766*fcf3ce44SJohn Forte kmem_free(nodelist, sizeof (*nodelist) * nodecnt); 767*fcf3ce44SJohn Forte return (rc); 768*fcf3ce44SJohn Forte } 769