1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte /* 22d9d73587SMark J Musante * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23fcf3ce44SJohn Forte * Use is subject to license terms. 24*b97d6ca7SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27fcf3ce44SJohn Forte #include <sys/types.h> 28fcf3ce44SJohn Forte #include <sys/ksynch.h> 29fcf3ce44SJohn Forte #include <sys/kmem.h> 30fcf3ce44SJohn Forte #include <sys/file.h> 31fcf3ce44SJohn Forte #include <sys/errno.h> 32fcf3ce44SJohn Forte #include <sys/open.h> 33fcf3ce44SJohn Forte #include <sys/cred.h> 34fcf3ce44SJohn Forte #include <sys/conf.h> 35fcf3ce44SJohn Forte #include <sys/uio.h> 36fcf3ce44SJohn Forte #include <sys/cmn_err.h> 37fcf3ce44SJohn Forte #include <sys/modctl.h> 38fcf3ce44SJohn Forte #include <sys/ddi.h> 39fcf3ce44SJohn Forte 40fcf3ce44SJohn Forte #define __NSC_GEN__ 41fcf3ce44SJohn Forte #include <sys/nsctl/nsc_dev.h> 42fcf3ce44SJohn Forte #include <sys/nsctl/nsc_gen.h> 43fcf3ce44SJohn Forte #include <sys/nsctl/nsc_ioctl.h> 44fcf3ce44SJohn Forte #include <sys/nsctl/nsc_power.h> 45fcf3ce44SJohn Forte #include <sys/nsctl/nsc_mem.h> 46fcf3ce44SJohn Forte #include "../nsctl.h" 47fcf3ce44SJohn Forte 48fcf3ce44SJohn Forte #include <sys/nsctl/nsvers.h> 49fcf3ce44SJohn Forte 50fcf3ce44SJohn Forte #ifdef DS_DDICT 51fcf3ce44SJohn Forte #include "../contract.h" 52fcf3ce44SJohn Forte #endif 53fcf3ce44SJohn Forte 54fcf3ce44SJohn Forte extern void nscsetup(); 55*b97d6ca7SMilan Jurik extern int _nsc_init_raw(int); 56fcf3ce44SJohn Forte extern void _nsc_deinit_raw(); 57fcf3ce44SJohn Forte extern void _nsc_init_start(); 58fcf3ce44SJohn Forte extern void _nsc_init_os(), _nsc_deinit_os(); 59fcf3ce44SJohn Forte extern void _nsc_init_dev(), _nsc_init_mem(); 60fcf3ce44SJohn Forte extern void _nsc_init_gen(), _nsc_init_rmlock(); 61fcf3ce44SJohn Forte extern void _nsc_init_resv(), _nsc_deinit_resv(); 62fcf3ce44SJohn Forte extern void _nsc_init_frz(), _nsc_deinit_frz(); 63fcf3ce44SJohn Forte extern void _nsc_init_ncio(), _nsc_deinit_ncio(); 64fcf3ce44SJohn Forte extern void _nsc_deinit_mem(), _nsc_deinit_rmlock(); 65fcf3ce44SJohn Forte extern void _nsc_deinit_dev(); 66fcf3ce44SJohn Forte 67*b97d6ca7SMilan Jurik extern int _nsc_frz_start(char *, int *); 68*b97d6ca7SMilan Jurik extern int _nsc_frz_stop(char *, int *); 69*b97d6ca7SMilan Jurik extern int _nsc_frz_isfrozen(char *, int *); 70fcf3ce44SJohn Forte 71fcf3ce44SJohn Forte extern nsc_mem_t *_nsc_local_mem; 72fcf3ce44SJohn Forte extern nsc_rmhdr_t *_nsc_rmhdr_ptr; 73fcf3ce44SJohn Forte extern nsc_def_t _nsc_raw_def[]; 74fcf3ce44SJohn Forte extern int _nsc_raw_flags; 75fcf3ce44SJohn Forte 76fcf3ce44SJohn Forte int nsc_devflag = D_MP; 77fcf3ce44SJohn Forte 78fcf3ce44SJohn Forte int _nsc_init_done = 0; 79fcf3ce44SJohn Forte 80fcf3ce44SJohn Forte kmutex_t _nsc_drv_lock; 81fcf3ce44SJohn Forte nsc_io_t *_nsc_file_io; 82fcf3ce44SJohn Forte nsc_io_t *_nsc_vchr_io; 83fcf3ce44SJohn Forte nsc_io_t *_nsc_raw_io; 84fcf3ce44SJohn Forte 85fcf3ce44SJohn Forte nsc_fd_t **_nsc_minor_fd; 86fcf3ce44SJohn Forte kmutex_t **_nsc_minor_slp; 87fcf3ce44SJohn Forte 88fcf3ce44SJohn Forte 89fcf3ce44SJohn Forte /* Maximum number of devices - tunable in nsctl.conf */ 90fcf3ce44SJohn Forte static int _nsc_max_devices; 91fcf3ce44SJohn Forte 92fcf3ce44SJohn Forte /* Internal version of _nsc_max_devices */ 93fcf3ce44SJohn Forte int _nsc_maxdev; 94fcf3ce44SJohn Forte 95fcf3ce44SJohn Forte extern void _nsc_global_setup(void); 96fcf3ce44SJohn Forte 97fcf3ce44SJohn Forte static int nsc_load(), nsc_unload(); 98d9d73587SMark J Musante static void nscteardown(); 99fcf3ce44SJohn Forte 100fcf3ce44SJohn Forte /* 101fcf3ce44SJohn Forte * Solaris specific driver module interface code. 102fcf3ce44SJohn Forte */ 103fcf3ce44SJohn Forte 104fcf3ce44SJohn Forte extern int nscopen(dev_t *, int, int, cred_t *); 105fcf3ce44SJohn Forte extern int nscioctl(dev_t, int, intptr_t, int, cred_t *, int *); 106fcf3ce44SJohn Forte extern int nscclose(dev_t, int, int, cred_t *); 107fcf3ce44SJohn Forte extern int nscread(dev_t, uio_t *, cred_t *); 108fcf3ce44SJohn Forte extern int nscwrite(dev_t, uio_t *, cred_t *); 109fcf3ce44SJohn Forte 110fcf3ce44SJohn Forte static dev_info_t *nsctl_dip; /* Single DIP for driver */ 111fcf3ce44SJohn Forte 112fcf3ce44SJohn Forte static int _nsctl_print(dev_t, char *); 113fcf3ce44SJohn Forte 114fcf3ce44SJohn Forte static struct cb_ops nsctl_cb_ops = { 115fcf3ce44SJohn Forte nscopen, /* open */ 116fcf3ce44SJohn Forte nscclose, /* close */ 117fcf3ce44SJohn Forte nodev, /* not a block driver, strategy not an entry point */ 118fcf3ce44SJohn Forte _nsctl_print, /* no print routine */ 119fcf3ce44SJohn Forte nodev, /* no dump routine */ 120fcf3ce44SJohn Forte nscread, /* read */ 121fcf3ce44SJohn Forte nscwrite, /* write */ 122fcf3ce44SJohn Forte (int (*)()) nscioctl, /* ioctl */ 123fcf3ce44SJohn Forte nodev, /* no devmap routine */ 124fcf3ce44SJohn Forte nodev, /* no mmap routine */ 125fcf3ce44SJohn Forte nodev, /* no segmap routine */ 126fcf3ce44SJohn Forte nochpoll, /* no chpoll routine */ 127fcf3ce44SJohn Forte ddi_prop_op, 128fcf3ce44SJohn Forte 0, /* not a STREAMS driver, no cb_str routine */ 129fcf3ce44SJohn Forte D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */ 130fcf3ce44SJohn Forte CB_REV, 131fcf3ce44SJohn Forte nodev, /* aread */ 132fcf3ce44SJohn Forte nodev, /* awrite */ 133fcf3ce44SJohn Forte }; 134fcf3ce44SJohn Forte 135fcf3ce44SJohn Forte static int _nsctl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 136fcf3ce44SJohn Forte static int _nsctl_attach(dev_info_t *, ddi_attach_cmd_t); 137fcf3ce44SJohn Forte static int _nsctl_detach(dev_info_t *, ddi_detach_cmd_t); 138fcf3ce44SJohn Forte 139fcf3ce44SJohn Forte static struct dev_ops nsctl_ops = { 140fcf3ce44SJohn Forte DEVO_REV, /* Driver build version */ 141fcf3ce44SJohn Forte 0, /* device reference count */ 142fcf3ce44SJohn Forte _nsctl_getinfo, 143fcf3ce44SJohn Forte nulldev, /* Identify */ 144fcf3ce44SJohn Forte nulldev, /* Probe */ 145fcf3ce44SJohn Forte _nsctl_attach, 146fcf3ce44SJohn Forte _nsctl_detach, 147fcf3ce44SJohn Forte nodev, /* Reset */ 148fcf3ce44SJohn Forte &nsctl_cb_ops, 149fcf3ce44SJohn Forte (struct bus_ops *)0 150fcf3ce44SJohn Forte }; 151fcf3ce44SJohn Forte 152fcf3ce44SJohn Forte static struct modldrv nsctl_ldrv = { 153fcf3ce44SJohn Forte &mod_driverops, 154fcf3ce44SJohn Forte "nws:Control:" ISS_VERSION_STR, 155fcf3ce44SJohn Forte &nsctl_ops 156fcf3ce44SJohn Forte }; 157fcf3ce44SJohn Forte 158fcf3ce44SJohn Forte static struct modlinkage nsctl_modlinkage = { 159fcf3ce44SJohn Forte MODREV_1, 160fcf3ce44SJohn Forte &nsctl_ldrv, 161fcf3ce44SJohn Forte NULL 162fcf3ce44SJohn Forte }; 163fcf3ce44SJohn Forte 164fcf3ce44SJohn Forte /* 165fcf3ce44SJohn Forte * Solaris module load time code 166fcf3ce44SJohn Forte */ 167fcf3ce44SJohn Forte 168fcf3ce44SJohn Forte int nsc_min_nodeid; 169fcf3ce44SJohn Forte int nsc_max_nodeid; 170fcf3ce44SJohn Forte 171fcf3ce44SJohn Forte int 172fcf3ce44SJohn Forte _init(void) 173fcf3ce44SJohn Forte { 174fcf3ce44SJohn Forte int err; 175fcf3ce44SJohn Forte 176fcf3ce44SJohn Forte err = nsc_load(); 177fcf3ce44SJohn Forte 178fcf3ce44SJohn Forte if (!err) 179fcf3ce44SJohn Forte err = mod_install(&nsctl_modlinkage); 180fcf3ce44SJohn Forte 181fcf3ce44SJohn Forte if (err) { 182fcf3ce44SJohn Forte (void) nsc_unload(); 1833270659fSSrikanth, Ramana cmn_err(CE_NOTE, "!nsctl_init: err %d", err); 184fcf3ce44SJohn Forte } 185fcf3ce44SJohn Forte 186fcf3ce44SJohn Forte return (err); 187fcf3ce44SJohn Forte 188fcf3ce44SJohn Forte } 189fcf3ce44SJohn Forte 190fcf3ce44SJohn Forte /* 191fcf3ce44SJohn Forte * Solaris module unload time code 192fcf3ce44SJohn Forte */ 193fcf3ce44SJohn Forte 194fcf3ce44SJohn Forte int 195fcf3ce44SJohn Forte _fini(void) 196fcf3ce44SJohn Forte { 197fcf3ce44SJohn Forte int err; 198fcf3ce44SJohn Forte 199fcf3ce44SJohn Forte if ((err = mod_remove(&nsctl_modlinkage)) == 0) { 200fcf3ce44SJohn Forte err = nsc_unload(); 201fcf3ce44SJohn Forte } 202fcf3ce44SJohn Forte return (err); 203fcf3ce44SJohn Forte } 204fcf3ce44SJohn Forte 205fcf3ce44SJohn Forte /* 206fcf3ce44SJohn Forte * Solaris module info code 207fcf3ce44SJohn Forte */ 208fcf3ce44SJohn Forte int 209fcf3ce44SJohn Forte _info(struct modinfo *modinfop) 210fcf3ce44SJohn Forte { 211fcf3ce44SJohn Forte return (mod_info(&nsctl_modlinkage, modinfop)); 212fcf3ce44SJohn Forte } 213fcf3ce44SJohn Forte 214fcf3ce44SJohn Forte /* 215fcf3ce44SJohn Forte * Attach an instance of the device. This happens before an open 216fcf3ce44SJohn Forte * can succeed. 217fcf3ce44SJohn Forte */ 218fcf3ce44SJohn Forte static int 219fcf3ce44SJohn Forte _nsctl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 220fcf3ce44SJohn Forte { 221fcf3ce44SJohn Forte int rc; 222fcf3ce44SJohn Forte 223fcf3ce44SJohn Forte if (cmd == DDI_ATTACH) { 224fcf3ce44SJohn Forte nsctl_dip = dip; 225fcf3ce44SJohn Forte 226fcf3ce44SJohn Forte /* Announce presence of the device */ 227fcf3ce44SJohn Forte ddi_report_dev(dip); 228fcf3ce44SJohn Forte 229fcf3ce44SJohn Forte /* 230fcf3ce44SJohn Forte * Get the node parameters now that we can look up. 231fcf3ce44SJohn Forte */ 232fcf3ce44SJohn Forte nsc_min_nodeid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 233fcf3ce44SJohn Forte DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 234fcf3ce44SJohn Forte "nsc_min_nodeid", 0); 235fcf3ce44SJohn Forte 236fcf3ce44SJohn Forte nsc_max_nodeid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 237fcf3ce44SJohn Forte DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 238fcf3ce44SJohn Forte "nsc_max_nodeid", 5); 239fcf3ce44SJohn Forte 240fcf3ce44SJohn Forte _nsc_max_devices = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 241fcf3ce44SJohn Forte DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 242fcf3ce44SJohn Forte "nsc_max_devices", 128); 243fcf3ce44SJohn Forte 244fcf3ce44SJohn Forte _nsc_maxdev = _nsc_max_devices; 245fcf3ce44SJohn Forte nscsetup(); 246fcf3ce44SJohn Forte 247fcf3ce44SJohn Forte /* 248fcf3ce44SJohn Forte * Init raw requires the _nsc_max_devices value and so 249fcf3ce44SJohn Forte * cannot be done before the nsc_max_devices property has 250fcf3ce44SJohn Forte * been read which can only be done after the module is 251fcf3ce44SJohn Forte * attached and we have a dip. 252fcf3ce44SJohn Forte */ 253fcf3ce44SJohn Forte 254fcf3ce44SJohn Forte if ((rc = _nsc_init_raw(_nsc_max_devices)) != 0) { 255fcf3ce44SJohn Forte cmn_err(CE_WARN, 2563270659fSSrikanth, Ramana "!nsctl: unable to initialize raw io provider: %d", 257fcf3ce44SJohn Forte rc); 258fcf3ce44SJohn Forte return (DDI_FAILURE); 259fcf3ce44SJohn Forte } 260fcf3ce44SJohn Forte 261fcf3ce44SJohn Forte /* 262fcf3ce44SJohn Forte * Init rest of soft state structure 263fcf3ce44SJohn Forte */ 264fcf3ce44SJohn Forte 265fcf3ce44SJohn Forte rc = ddi_create_minor_node(dip, "c,nsctl", S_IFCHR, 0, 266fcf3ce44SJohn Forte DDI_PSEUDO, 0); 267fcf3ce44SJohn Forte if (rc != DDI_SUCCESS) { 268fcf3ce44SJohn Forte /* free anything we allocated here */ 269fcf3ce44SJohn Forte cmn_err(CE_WARN, 2703270659fSSrikanth, Ramana "!_nsctl_attach: ddi_create_minor_node failed %d", 271fcf3ce44SJohn Forte rc); 272fcf3ce44SJohn Forte return (DDI_FAILURE); 273fcf3ce44SJohn Forte } 274fcf3ce44SJohn Forte 275fcf3ce44SJohn Forte /* Announce presence of the device */ 276fcf3ce44SJohn Forte ddi_report_dev(dip); 277fcf3ce44SJohn Forte 278fcf3ce44SJohn Forte /* mark the device as attached, opens may proceed */ 279fcf3ce44SJohn Forte return (DDI_SUCCESS); 280fcf3ce44SJohn Forte } else 281fcf3ce44SJohn Forte return (DDI_FAILURE); 282fcf3ce44SJohn Forte } 283fcf3ce44SJohn Forte 284fcf3ce44SJohn Forte static int 285fcf3ce44SJohn Forte _nsctl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 286fcf3ce44SJohn Forte { 287fcf3ce44SJohn Forte if (cmd == DDI_DETACH) { 288d9d73587SMark J Musante nscteardown(); 289fcf3ce44SJohn Forte _nsc_deinit_raw(); 290fcf3ce44SJohn Forte 291fcf3ce44SJohn Forte ddi_remove_minor_node(dip, NULL); 292fcf3ce44SJohn Forte nsctl_dip = NULL; 293fcf3ce44SJohn Forte 294fcf3ce44SJohn Forte return (DDI_SUCCESS); 295fcf3ce44SJohn Forte } 296fcf3ce44SJohn Forte else 297fcf3ce44SJohn Forte return (DDI_FAILURE); 298fcf3ce44SJohn Forte } 299fcf3ce44SJohn Forte 300fcf3ce44SJohn Forte 301fcf3ce44SJohn Forte /* ARGSUSED */ 302fcf3ce44SJohn Forte static int 303fcf3ce44SJohn Forte _nsctl_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 304fcf3ce44SJohn Forte { 305fcf3ce44SJohn Forte dev_t dev; 306fcf3ce44SJohn Forte int rc; 307fcf3ce44SJohn Forte 308fcf3ce44SJohn Forte switch (cmd) { 309fcf3ce44SJohn Forte case DDI_INFO_DEVT2INSTANCE: 310fcf3ce44SJohn Forte /* The "instance" number is the minor number */ 311fcf3ce44SJohn Forte dev = (dev_t)arg; 312fcf3ce44SJohn Forte *result = (void *)(unsigned long)getminor(dev); 313fcf3ce44SJohn Forte rc = DDI_SUCCESS; 314fcf3ce44SJohn Forte break; 315fcf3ce44SJohn Forte 316fcf3ce44SJohn Forte case DDI_INFO_DEVT2DEVINFO: 317fcf3ce44SJohn Forte *result = nsctl_dip; 318fcf3ce44SJohn Forte rc = DDI_SUCCESS; 319fcf3ce44SJohn Forte break; 320fcf3ce44SJohn Forte 321fcf3ce44SJohn Forte default: 322fcf3ce44SJohn Forte rc = DDI_FAILURE; 323fcf3ce44SJohn Forte break; 324fcf3ce44SJohn Forte } 325fcf3ce44SJohn Forte 326fcf3ce44SJohn Forte return (rc); 327fcf3ce44SJohn Forte } 328fcf3ce44SJohn Forte 329fcf3ce44SJohn Forte 330fcf3ce44SJohn Forte /* ARGSUSED */ 331fcf3ce44SJohn Forte static int 332fcf3ce44SJohn Forte _nsctl_print(dev_t dev, char *s) 333fcf3ce44SJohn Forte { 3343270659fSSrikanth, Ramana cmn_err(CE_WARN, "!nsctl:%s", s); 335fcf3ce44SJohn Forte return (0); 336fcf3ce44SJohn Forte } 337fcf3ce44SJohn Forte 338fcf3ce44SJohn Forte 339fcf3ce44SJohn Forte void 340fcf3ce44SJohn Forte nsc_init() 341fcf3ce44SJohn Forte { 342fcf3ce44SJohn Forte if (_nsc_init_done) 343fcf3ce44SJohn Forte return; 344fcf3ce44SJohn Forte 345fcf3ce44SJohn Forte _nsc_init_start(); 346fcf3ce44SJohn Forte _nsc_init_gen(); 347fcf3ce44SJohn Forte _nsc_init_svc(); 348fcf3ce44SJohn Forte _nsc_init_mem(); 349fcf3ce44SJohn Forte _nsc_init_dev(); 350fcf3ce44SJohn Forte _nsc_init_rmlock(); 351fcf3ce44SJohn Forte _nsc_init_resv(); 352fcf3ce44SJohn Forte _nsc_init_os(); 353fcf3ce44SJohn Forte (void) _nsc_init_power(); 354fcf3ce44SJohn Forte 355fcf3ce44SJohn Forte /* 356fcf3ce44SJohn Forte * When using mc, nscsetup is done through mc callback to global_init. 357fcf3ce44SJohn Forte */ 358fcf3ce44SJohn Forte nscsetup(); 359fcf3ce44SJohn Forte 360fcf3ce44SJohn Forte mutex_init(&_nsc_drv_lock, NULL, MUTEX_DRIVER, NULL); 361fcf3ce44SJohn Forte 362fcf3ce44SJohn Forte _nsc_raw_io = nsc_register_io("raw", 363fcf3ce44SJohn Forte NSC_RAW_ID | _nsc_raw_flags, _nsc_raw_def); 364fcf3ce44SJohn Forte 365fcf3ce44SJohn Forte if (!_nsc_raw_io) 3663270659fSSrikanth, Ramana cmn_err(CE_WARN, "!_nsc_init: register io failed - raw"); 367fcf3ce44SJohn Forte 368fcf3ce44SJohn Forte _nsc_init_ncio(); 369fcf3ce44SJohn Forte _nsc_init_frz(); 370fcf3ce44SJohn Forte 371fcf3ce44SJohn Forte _nsc_init_done = 1; 372fcf3ce44SJohn Forte } 373fcf3ce44SJohn Forte 374fcf3ce44SJohn Forte 375fcf3ce44SJohn Forte /* 376fcf3ce44SJohn Forte * Called after the mc refresh is complete (SEG_INIT callbacks have 377fcf3ce44SJohn Forte * been received) and module _attach() is done. Only does any real 378fcf3ce44SJohn Forte * work when all of the above conditions have been met. 379fcf3ce44SJohn Forte */ 380fcf3ce44SJohn Forte void 381fcf3ce44SJohn Forte nscsetup() 382fcf3ce44SJohn Forte { 383d9d73587SMark J Musante if (nsc_max_devices() == 0 || _nsc_minor_fd != NULL) 384fcf3ce44SJohn Forte return; 385fcf3ce44SJohn Forte 386fcf3ce44SJohn Forte _nsc_minor_fd = nsc_kmem_zalloc(sizeof (nsc_fd_t *)*_nsc_maxdev, 387fcf3ce44SJohn Forte 0, _nsc_local_mem); 388fcf3ce44SJohn Forte 389d9d73587SMark J Musante if (!_nsc_minor_fd) { 3903270659fSSrikanth, Ramana cmn_err(CE_WARN, "!nscsetup - alloc failed"); 391d9d73587SMark J Musante return; 392d9d73587SMark J Musante } 393d9d73587SMark J Musante 394fcf3ce44SJohn Forte _nsc_minor_slp = nsc_kmem_zalloc(sizeof (kmutex_t *)*_nsc_maxdev, 395fcf3ce44SJohn Forte 0, _nsc_local_mem); 396fcf3ce44SJohn Forte 397d9d73587SMark J Musante if (!_nsc_minor_slp) { 3983270659fSSrikanth, Ramana cmn_err(CE_WARN, "!nscsetup - alloc failed"); 399d9d73587SMark J Musante nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev); 400d9d73587SMark J Musante _nsc_minor_fd = (nsc_fd_t **)NULL; 401d9d73587SMark J Musante } 402fcf3ce44SJohn Forte } 403fcf3ce44SJohn Forte 404d9d73587SMark J Musante static void 405d9d73587SMark J Musante nscteardown() 406d9d73587SMark J Musante { 407d9d73587SMark J Musante int i; 408d9d73587SMark J Musante 409d9d73587SMark J Musante if (_nsc_minor_fd == NULL) 410d9d73587SMark J Musante return; 411d9d73587SMark J Musante 412d9d73587SMark J Musante #ifdef DEBUG 413d9d73587SMark J Musante /* Check all devices were closed. Index 0 is the prototype dev. */ 414d9d73587SMark J Musante for (i = 1; i < _nsc_maxdev; i++) { 415d9d73587SMark J Musante ASSERT(_nsc_minor_slp[i] == NULL); 416d9d73587SMark J Musante ASSERT(_nsc_minor_fd[i] == NULL); 417d9d73587SMark J Musante } 418d9d73587SMark J Musante #endif /* DEBUG */ 419d9d73587SMark J Musante 420d9d73587SMark J Musante nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev); 421d9d73587SMark J Musante nsc_kmem_free(_nsc_minor_slp, sizeof (kmutex_t *) * _nsc_maxdev); 422d9d73587SMark J Musante 423d9d73587SMark J Musante _nsc_minor_fd = (nsc_fd_t **)NULL; 424d9d73587SMark J Musante _nsc_minor_slp = (kmutex_t **)NULL; 425d9d73587SMark J Musante } 426fcf3ce44SJohn Forte 427fcf3ce44SJohn Forte int 428fcf3ce44SJohn Forte nsc_load() 429fcf3ce44SJohn Forte { 430fcf3ce44SJohn Forte nsc_init(); 431fcf3ce44SJohn Forte return (0); 432fcf3ce44SJohn Forte } 433fcf3ce44SJohn Forte 434fcf3ce44SJohn Forte 435fcf3ce44SJohn Forte int 436fcf3ce44SJohn Forte nsc_unload() 437fcf3ce44SJohn Forte { 438fcf3ce44SJohn Forte if (!_nsc_init_done) { 439fcf3ce44SJohn Forte return (0); 440fcf3ce44SJohn Forte } 441fcf3ce44SJohn Forte 442d9d73587SMark J Musante nscteardown(); 443d9d73587SMark J Musante 444fcf3ce44SJohn Forte (void) _nsc_deinit_power(); 445fcf3ce44SJohn Forte _nsc_deinit_resv(); 446fcf3ce44SJohn Forte _nsc_deinit_mem(); 447fcf3ce44SJohn Forte _nsc_deinit_rmlock(); 448fcf3ce44SJohn Forte _nsc_deinit_svc(); 449fcf3ce44SJohn Forte _nsc_deinit_frz(); 450fcf3ce44SJohn Forte _nsc_deinit_ncio(); 451fcf3ce44SJohn Forte 452fcf3ce44SJohn Forte if (_nsc_vchr_io) 453fcf3ce44SJohn Forte (void) nsc_unregister_io(_nsc_vchr_io, 0); 454fcf3ce44SJohn Forte 455fcf3ce44SJohn Forte if (_nsc_file_io) 456fcf3ce44SJohn Forte (void) nsc_unregister_io(_nsc_file_io, 0); 457fcf3ce44SJohn Forte 458fcf3ce44SJohn Forte _nsc_vchr_io = NULL; 459fcf3ce44SJohn Forte _nsc_file_io = NULL; 460fcf3ce44SJohn Forte 461fcf3ce44SJohn Forte if (_nsc_raw_io) 462fcf3ce44SJohn Forte (void) nsc_unregister_io(_nsc_raw_io, 0); 463fcf3ce44SJohn Forte 464fcf3ce44SJohn Forte _nsc_raw_io = NULL; 465fcf3ce44SJohn Forte 466fcf3ce44SJohn Forte _nsc_deinit_dev(); 467fcf3ce44SJohn Forte _nsc_deinit_os(); 468fcf3ce44SJohn Forte 469fcf3ce44SJohn Forte _nsc_init_done = 0; 470fcf3ce44SJohn Forte return (0); 471fcf3ce44SJohn Forte } 472fcf3ce44SJohn Forte 473fcf3ce44SJohn Forte 474fcf3ce44SJohn Forte /* ARGSUSED */ 475fcf3ce44SJohn Forte 476fcf3ce44SJohn Forte int 477fcf3ce44SJohn Forte nscopen(dev_t *devp, int flag, int otyp, cred_t *crp) 478fcf3ce44SJohn Forte { 479fcf3ce44SJohn Forte kmutex_t *slp; 480fcf3ce44SJohn Forte int i, error; 481fcf3ce44SJohn Forte 482fcf3ce44SJohn Forte if (error = drv_priv(crp)) 483fcf3ce44SJohn Forte return (error); 484fcf3ce44SJohn Forte 485fcf3ce44SJohn Forte if (!_nsc_minor_fd || !_nsc_minor_slp) 486fcf3ce44SJohn Forte return (ENXIO); 487fcf3ce44SJohn Forte 488fcf3ce44SJohn Forte if (getminor(*devp) != 0) 489fcf3ce44SJohn Forte return (ENXIO); 490fcf3ce44SJohn Forte 491fcf3ce44SJohn Forte slp = nsc_kmem_alloc(sizeof (kmutex_t), 0, _nsc_local_mem); 492fcf3ce44SJohn Forte mutex_init(slp, NULL, MUTEX_DRIVER, NULL); 493fcf3ce44SJohn Forte 494fcf3ce44SJohn Forte mutex_enter(&_nsc_drv_lock); 495fcf3ce44SJohn Forte 496fcf3ce44SJohn Forte for (i = 1; i < _nsc_maxdev; i++) { 497fcf3ce44SJohn Forte if (_nsc_minor_slp[i] == NULL) { 498fcf3ce44SJohn Forte _nsc_minor_slp[i] = slp; 499fcf3ce44SJohn Forte break; 500fcf3ce44SJohn Forte } 501fcf3ce44SJohn Forte } 502fcf3ce44SJohn Forte 503fcf3ce44SJohn Forte mutex_exit(&_nsc_drv_lock); 504fcf3ce44SJohn Forte 505fcf3ce44SJohn Forte if (i >= _nsc_maxdev) { 506fcf3ce44SJohn Forte mutex_destroy(slp); 507fcf3ce44SJohn Forte nsc_kmem_free(slp, sizeof (kmutex_t)); 508fcf3ce44SJohn Forte return (EAGAIN); 509fcf3ce44SJohn Forte } 510fcf3ce44SJohn Forte 511fcf3ce44SJohn Forte *devp = makedevice(getmajor(*devp), i); 512fcf3ce44SJohn Forte 513fcf3ce44SJohn Forte return (0); 514fcf3ce44SJohn Forte } 515fcf3ce44SJohn Forte 516fcf3ce44SJohn Forte 517fcf3ce44SJohn Forte int 518fcf3ce44SJohn Forte _nscopen(dev_t dev, intptr_t arg, int mode, int *rvp) 519fcf3ce44SJohn Forte { 520fcf3ce44SJohn Forte minor_t mindev = getminor(dev); 521fcf3ce44SJohn Forte struct nscioc_open *op; 522fcf3ce44SJohn Forte nsc_fd_t *fd; 523fcf3ce44SJohn Forte int rc; 524fcf3ce44SJohn Forte 525fcf3ce44SJohn Forte op = nsc_kmem_alloc(sizeof (*op), KM_SLEEP, _nsc_local_mem); 526fcf3ce44SJohn Forte if (op == NULL) { 527fcf3ce44SJohn Forte return (ENOMEM); 528fcf3ce44SJohn Forte } 529fcf3ce44SJohn Forte 530fcf3ce44SJohn Forte if (ddi_copyin((void *)arg, op, sizeof (*op), mode) < 0) { 531fcf3ce44SJohn Forte nsc_kmem_free(op, sizeof (*op)); 532fcf3ce44SJohn Forte return (EFAULT); 533fcf3ce44SJohn Forte } 534fcf3ce44SJohn Forte 535fcf3ce44SJohn Forte mutex_enter(_nsc_minor_slp[mindev]); 536fcf3ce44SJohn Forte 537fcf3ce44SJohn Forte if (_nsc_minor_fd[mindev]) { 538fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 539fcf3ce44SJohn Forte nsc_kmem_free(op, sizeof (*op)); 540fcf3ce44SJohn Forte return (EBUSY); 541fcf3ce44SJohn Forte } 542fcf3ce44SJohn Forte 543fcf3ce44SJohn Forte op->path[sizeof (op->path)-1] = 0; 544fcf3ce44SJohn Forte 545fcf3ce44SJohn Forte fd = nsc_open(op->path, (op->flag & NSC_TYPES), 0, 0, &rc); 546fcf3ce44SJohn Forte 547fcf3ce44SJohn Forte if (fd == NULL) { 548fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 549fcf3ce44SJohn Forte nsc_kmem_free(op, sizeof (*op)); 550fcf3ce44SJohn Forte return (rc); 551fcf3ce44SJohn Forte } 552fcf3ce44SJohn Forte 553fcf3ce44SJohn Forte mode |= (op->mode - FOPEN); 554fcf3ce44SJohn Forte 555fcf3ce44SJohn Forte if (mode & (FWRITE|FEXCL)) { 556fcf3ce44SJohn Forte if ((rc = nsc_reserve(fd, NSC_PCATCH)) != 0) { 557fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 558fcf3ce44SJohn Forte (void) nsc_close(fd); 559fcf3ce44SJohn Forte nsc_kmem_free(op, sizeof (*op)); 560fcf3ce44SJohn Forte return (rc); 561fcf3ce44SJohn Forte } 562fcf3ce44SJohn Forte } 563fcf3ce44SJohn Forte 564fcf3ce44SJohn Forte *rvp = 0; 565fcf3ce44SJohn Forte _nsc_minor_fd[mindev] = fd; 566fcf3ce44SJohn Forte 567fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 568fcf3ce44SJohn Forte nsc_kmem_free(op, sizeof (*op)); 569fcf3ce44SJohn Forte return (0); 570fcf3ce44SJohn Forte } 571fcf3ce44SJohn Forte 572fcf3ce44SJohn Forte 573fcf3ce44SJohn Forte /* ARGSUSED */ 574fcf3ce44SJohn Forte 575fcf3ce44SJohn Forte int 576fcf3ce44SJohn Forte nscclose(dev_t dev, int flag, int otyp, cred_t *crp) 577fcf3ce44SJohn Forte { 578fcf3ce44SJohn Forte minor_t mindev = getminor(dev); 579fcf3ce44SJohn Forte kmutex_t *slp; 580fcf3ce44SJohn Forte nsc_fd_t *fd; 581fcf3ce44SJohn Forte 582fcf3ce44SJohn Forte if (!_nsc_minor_fd || !_nsc_minor_slp) 583fcf3ce44SJohn Forte return (0); 584fcf3ce44SJohn Forte 585fcf3ce44SJohn Forte if ((slp = _nsc_minor_slp[mindev]) == 0) 586fcf3ce44SJohn Forte return (0); 587fcf3ce44SJohn Forte 588fcf3ce44SJohn Forte if ((fd = _nsc_minor_fd[mindev]) != NULL) 589fcf3ce44SJohn Forte (void) nsc_close(fd); 590fcf3ce44SJohn Forte 591fcf3ce44SJohn Forte _nsc_minor_fd[mindev] = NULL; 592fcf3ce44SJohn Forte _nsc_minor_slp[mindev] = NULL; 593fcf3ce44SJohn Forte 594fcf3ce44SJohn Forte mutex_destroy(slp); 595fcf3ce44SJohn Forte nsc_kmem_free(slp, sizeof (kmutex_t)); 596fcf3ce44SJohn Forte return (0); 597fcf3ce44SJohn Forte } 598fcf3ce44SJohn Forte 599fcf3ce44SJohn Forte 600fcf3ce44SJohn Forte /* ARGSUSED */ 601fcf3ce44SJohn Forte 602fcf3ce44SJohn Forte int 603fcf3ce44SJohn Forte nscread(dev_t dev, uio_t *uiop, cred_t *crp) 604fcf3ce44SJohn Forte { 605fcf3ce44SJohn Forte minor_t mindev = getminor(dev); 606fcf3ce44SJohn Forte int rc, resv; 607fcf3ce44SJohn Forte nsc_fd_t *fd; 608fcf3ce44SJohn Forte 609fcf3ce44SJohn Forte if ((fd = _nsc_minor_fd[mindev]) == 0) 610fcf3ce44SJohn Forte return (EIO); 611fcf3ce44SJohn Forte 612fcf3ce44SJohn Forte mutex_enter(_nsc_minor_slp[mindev]); 613fcf3ce44SJohn Forte 614fcf3ce44SJohn Forte resv = (nsc_held(fd) == 0); 615fcf3ce44SJohn Forte 616fcf3ce44SJohn Forte if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) { 617fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 618fcf3ce44SJohn Forte return (rc); 619fcf3ce44SJohn Forte } 620fcf3ce44SJohn Forte 621fcf3ce44SJohn Forte rc = nsc_uread(fd, uiop, crp); 622fcf3ce44SJohn Forte 623fcf3ce44SJohn Forte if (resv) 624fcf3ce44SJohn Forte nsc_release(fd); 625fcf3ce44SJohn Forte 626fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 627fcf3ce44SJohn Forte return (rc); 628fcf3ce44SJohn Forte } 629fcf3ce44SJohn Forte 630fcf3ce44SJohn Forte 631fcf3ce44SJohn Forte /* ARGSUSED */ 632fcf3ce44SJohn Forte 633fcf3ce44SJohn Forte int 634fcf3ce44SJohn Forte nscwrite(dev_t dev, uio_t *uiop, cred_t *crp) 635fcf3ce44SJohn Forte { 636fcf3ce44SJohn Forte minor_t mindev = getminor(dev); 637fcf3ce44SJohn Forte int rc, resv; 638fcf3ce44SJohn Forte nsc_fd_t *fd; 639fcf3ce44SJohn Forte 640fcf3ce44SJohn Forte if ((fd = _nsc_minor_fd[mindev]) == 0) 641fcf3ce44SJohn Forte return (EIO); 642fcf3ce44SJohn Forte 643fcf3ce44SJohn Forte mutex_enter(_nsc_minor_slp[mindev]); 644fcf3ce44SJohn Forte 645fcf3ce44SJohn Forte resv = (nsc_held(fd) == 0); 646fcf3ce44SJohn Forte 647fcf3ce44SJohn Forte if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) { 648fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 649fcf3ce44SJohn Forte return (rc); 650fcf3ce44SJohn Forte } 651fcf3ce44SJohn Forte 652fcf3ce44SJohn Forte rc = nsc_uwrite(fd, uiop, crp); 653fcf3ce44SJohn Forte 654fcf3ce44SJohn Forte if (resv) 655fcf3ce44SJohn Forte nsc_release(fd); 656fcf3ce44SJohn Forte 657fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 658fcf3ce44SJohn Forte return (rc); 659fcf3ce44SJohn Forte } 660fcf3ce44SJohn Forte 661fcf3ce44SJohn Forte 662fcf3ce44SJohn Forte int 663fcf3ce44SJohn Forte _nscreserve(dev_t dev, int *rvp) 664fcf3ce44SJohn Forte { 665fcf3ce44SJohn Forte minor_t mindev = getminor(dev); 666fcf3ce44SJohn Forte nsc_fd_t *fd; 667fcf3ce44SJohn Forte int rc; 668fcf3ce44SJohn Forte 669fcf3ce44SJohn Forte if ((fd = _nsc_minor_fd[mindev]) == 0) 670fcf3ce44SJohn Forte return (EIO); 671fcf3ce44SJohn Forte 672fcf3ce44SJohn Forte mutex_enter(_nsc_minor_slp[mindev]); 673fcf3ce44SJohn Forte 674fcf3ce44SJohn Forte if (nsc_held(fd)) { 675fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 676fcf3ce44SJohn Forte return (EBUSY); 677fcf3ce44SJohn Forte } 678fcf3ce44SJohn Forte 679fcf3ce44SJohn Forte if ((rc = nsc_reserve(fd, NSC_PCATCH)) != 0) { 680fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 681fcf3ce44SJohn Forte return (rc); 682fcf3ce44SJohn Forte } 683fcf3ce44SJohn Forte 684fcf3ce44SJohn Forte *rvp = 0; 685fcf3ce44SJohn Forte 686fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 687fcf3ce44SJohn Forte return (0); 688fcf3ce44SJohn Forte } 689fcf3ce44SJohn Forte 690fcf3ce44SJohn Forte 691fcf3ce44SJohn Forte int 692fcf3ce44SJohn Forte _nscrelease(dev_t dev, int *rvp) 693fcf3ce44SJohn Forte { 694fcf3ce44SJohn Forte minor_t mindev = getminor(dev); 695fcf3ce44SJohn Forte nsc_fd_t *fd; 696fcf3ce44SJohn Forte 697fcf3ce44SJohn Forte if ((fd = _nsc_minor_fd[mindev]) == 0) 698fcf3ce44SJohn Forte return (EIO); 699fcf3ce44SJohn Forte 700fcf3ce44SJohn Forte mutex_enter(_nsc_minor_slp[mindev]); 701fcf3ce44SJohn Forte 702fcf3ce44SJohn Forte if (!nsc_held(fd)) { 703fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 704fcf3ce44SJohn Forte return (EINVAL); 705fcf3ce44SJohn Forte } 706fcf3ce44SJohn Forte 707fcf3ce44SJohn Forte nsc_release(fd); 708fcf3ce44SJohn Forte 709fcf3ce44SJohn Forte *rvp = 0; 710fcf3ce44SJohn Forte 711fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 712fcf3ce44SJohn Forte return (0); 713fcf3ce44SJohn Forte } 714fcf3ce44SJohn Forte 715fcf3ce44SJohn Forte 716fcf3ce44SJohn Forte int 717fcf3ce44SJohn Forte _nscpartsize(dev_t dev, intptr_t arg, int mode) 718fcf3ce44SJohn Forte { 719fcf3ce44SJohn Forte struct nscioc_partsize partsize; 720fcf3ce44SJohn Forte minor_t mindev = getminor(dev); 721fcf3ce44SJohn Forte nsc_size_t size; 722fcf3ce44SJohn Forte int rc, resv; 723fcf3ce44SJohn Forte nsc_fd_t *fd; 724fcf3ce44SJohn Forte 725fcf3ce44SJohn Forte if ((fd = _nsc_minor_fd[mindev]) == 0) 726fcf3ce44SJohn Forte return (EIO); 727fcf3ce44SJohn Forte 728fcf3ce44SJohn Forte mutex_enter(_nsc_minor_slp[mindev]); 729fcf3ce44SJohn Forte 730fcf3ce44SJohn Forte resv = (nsc_held(fd) == 0); 731fcf3ce44SJohn Forte 732fcf3ce44SJohn Forte if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) { 733fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 734fcf3ce44SJohn Forte return (rc); 735fcf3ce44SJohn Forte } 736fcf3ce44SJohn Forte 737fcf3ce44SJohn Forte rc = nsc_partsize(fd, &size); 738fcf3ce44SJohn Forte partsize.partsize = (uint64_t)size; 739fcf3ce44SJohn Forte 740fcf3ce44SJohn Forte if (resv) 741fcf3ce44SJohn Forte nsc_release(fd); 742fcf3ce44SJohn Forte 743fcf3ce44SJohn Forte mutex_exit(_nsc_minor_slp[mindev]); 744fcf3ce44SJohn Forte 745fcf3ce44SJohn Forte if (ddi_copyout((void *)&partsize, (void *)arg, 746fcf3ce44SJohn Forte sizeof (partsize), mode) < 0) { 747fcf3ce44SJohn Forte return (EFAULT); 748fcf3ce44SJohn Forte } 749fcf3ce44SJohn Forte 750fcf3ce44SJohn Forte return (rc); 751fcf3ce44SJohn Forte } 752fcf3ce44SJohn Forte 753fcf3ce44SJohn Forte 754fcf3ce44SJohn Forte /* ARGSUSED */ 755fcf3ce44SJohn Forte 756fcf3ce44SJohn Forte int 757fcf3ce44SJohn Forte nscioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp) 758fcf3ce44SJohn Forte { 759fcf3ce44SJohn Forte struct nscioc_bsize *bsize = NULL; 760fcf3ce44SJohn Forte char *path = NULL; 761fcf3ce44SJohn Forte int rc = 0; 762fcf3ce44SJohn Forte 763fcf3ce44SJohn Forte *rvp = 0; 764fcf3ce44SJohn Forte 765fcf3ce44SJohn Forte switch (cmd) { 766fcf3ce44SJohn Forte case NSCIOC_OPEN: 767fcf3ce44SJohn Forte rc = _nscopen(dev, arg, mode, rvp); 768fcf3ce44SJohn Forte break; 769fcf3ce44SJohn Forte 770fcf3ce44SJohn Forte case NSCIOC_RESERVE: 771fcf3ce44SJohn Forte rc = _nscreserve(dev, rvp); 772fcf3ce44SJohn Forte break; 773fcf3ce44SJohn Forte 774fcf3ce44SJohn Forte case NSCIOC_RELEASE: 775fcf3ce44SJohn Forte rc = _nscrelease(dev, rvp); 776fcf3ce44SJohn Forte break; 777fcf3ce44SJohn Forte 778fcf3ce44SJohn Forte case NSCIOC_PARTSIZE: 779fcf3ce44SJohn Forte rc = _nscpartsize(dev, arg, mode); 780fcf3ce44SJohn Forte break; 781fcf3ce44SJohn Forte 782fcf3ce44SJohn Forte case NSCIOC_FREEZE: 783fcf3ce44SJohn Forte path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem); 784fcf3ce44SJohn Forte if (path == NULL) { 785fcf3ce44SJohn Forte rc = ENOMEM; 786fcf3ce44SJohn Forte break; 787fcf3ce44SJohn Forte } 788fcf3ce44SJohn Forte if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0) 789fcf3ce44SJohn Forte rc = EFAULT; 790fcf3ce44SJohn Forte else { 791fcf3ce44SJohn Forte path[NSC_MAXPATH-1] = 0; 792fcf3ce44SJohn Forte rc = _nsc_frz_start(path, rvp); 793fcf3ce44SJohn Forte } 794fcf3ce44SJohn Forte break; 795fcf3ce44SJohn Forte 796fcf3ce44SJohn Forte case NSCIOC_UNFREEZE: 797fcf3ce44SJohn Forte path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem); 798fcf3ce44SJohn Forte if (path == NULL) { 799fcf3ce44SJohn Forte rc = ENOMEM; 800fcf3ce44SJohn Forte break; 801fcf3ce44SJohn Forte } 802fcf3ce44SJohn Forte if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0) 803fcf3ce44SJohn Forte rc = EFAULT; 804fcf3ce44SJohn Forte else { 805fcf3ce44SJohn Forte path[NSC_MAXPATH-1] = 0; 806fcf3ce44SJohn Forte rc = _nsc_frz_stop(path, rvp); 807fcf3ce44SJohn Forte } 808fcf3ce44SJohn Forte break; 809fcf3ce44SJohn Forte 810fcf3ce44SJohn Forte case NSCIOC_ISFROZEN: 811fcf3ce44SJohn Forte path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem); 812fcf3ce44SJohn Forte if (path == NULL) { 813fcf3ce44SJohn Forte rc = ENOMEM; 814fcf3ce44SJohn Forte break; 815fcf3ce44SJohn Forte } 816fcf3ce44SJohn Forte if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0) 817fcf3ce44SJohn Forte rc = EFAULT; 818fcf3ce44SJohn Forte else { 819fcf3ce44SJohn Forte path[NSC_MAXPATH-1] = 0; 820fcf3ce44SJohn Forte rc = _nsc_frz_isfrozen(path, rvp); 821fcf3ce44SJohn Forte } 822fcf3ce44SJohn Forte break; 823fcf3ce44SJohn Forte 824fcf3ce44SJohn Forte #ifdef ENABLE_POWER_MSG 825fcf3ce44SJohn Forte case NSCIOC_POWERMSG: 826fcf3ce44SJohn Forte rc = _nsc_power((void *)arg, rvp); 827fcf3ce44SJohn Forte break; 828fcf3ce44SJohn Forte #endif 829fcf3ce44SJohn Forte 830fcf3ce44SJohn Forte case NSCIOC_NSKERND: 831fcf3ce44SJohn Forte rc = nskernd_command(arg, mode, rvp); 832fcf3ce44SJohn Forte break; 833fcf3ce44SJohn Forte 834fcf3ce44SJohn Forte /* return sizes of global memory segments */ 835fcf3ce44SJohn Forte case NSCIOC_GLOBAL_SIZES: 836fcf3ce44SJohn Forte if (!_nsc_init_done) { 837fcf3ce44SJohn Forte rc = EINVAL; 838fcf3ce44SJohn Forte break; 839fcf3ce44SJohn Forte } 840fcf3ce44SJohn Forte 841fcf3ce44SJohn Forte rc = _nsc_get_global_sizes((void *)arg, rvp); 842fcf3ce44SJohn Forte 843fcf3ce44SJohn Forte break; 844fcf3ce44SJohn Forte 845fcf3ce44SJohn Forte /* return contents of global segments */ 846fcf3ce44SJohn Forte case NSCIOC_GLOBAL_DATA: 847fcf3ce44SJohn Forte if (!_nsc_init_done) { 848fcf3ce44SJohn Forte rc = EINVAL; 849fcf3ce44SJohn Forte break; 850fcf3ce44SJohn Forte } 851fcf3ce44SJohn Forte 852fcf3ce44SJohn Forte rc = _nsc_get_global_data((void *)arg, rvp); 853fcf3ce44SJohn Forte break; 854fcf3ce44SJohn Forte 855fcf3ce44SJohn Forte /* 856fcf3ce44SJohn Forte * nvmem systems: 857fcf3ce44SJohn Forte * clear the hdr dirty bit to prevent loading from nvme on reboot 858fcf3ce44SJohn Forte */ 859fcf3ce44SJohn Forte case NSCIOC_NVMEM_CLEANF: 860fcf3ce44SJohn Forte rc = _nsc_clear_dirty(1); /* dont be nice about it */ 861fcf3ce44SJohn Forte break; 862fcf3ce44SJohn Forte case NSCIOC_NVMEM_CLEAN: 863fcf3ce44SJohn Forte rc = _nsc_clear_dirty(0); 864fcf3ce44SJohn Forte break; 865fcf3ce44SJohn Forte 866fcf3ce44SJohn Forte case NSCIOC_BSIZE: 867fcf3ce44SJohn Forte bsize = nsc_kmem_alloc(sizeof (*bsize), KM_SLEEP, 868fcf3ce44SJohn Forte _nsc_local_mem); 869fcf3ce44SJohn Forte if (bsize == NULL) { 870fcf3ce44SJohn Forte rc = ENOMEM; 871fcf3ce44SJohn Forte break; 872fcf3ce44SJohn Forte } 873fcf3ce44SJohn Forte 874fcf3ce44SJohn Forte if (ddi_copyin((void *)arg, bsize, sizeof (*bsize), mode) < 0) { 875fcf3ce44SJohn Forte rc = EFAULT; 876fcf3ce44SJohn Forte break; 877fcf3ce44SJohn Forte } 878fcf3ce44SJohn Forte 879fcf3ce44SJohn Forte rc = nskern_bsize(bsize, rvp); 880fcf3ce44SJohn Forte if (rc == 0) { 881fcf3ce44SJohn Forte if (ddi_copyout(bsize, (void *)arg, 882fcf3ce44SJohn Forte sizeof (*bsize), mode) < 0) { 883fcf3ce44SJohn Forte rc = EFAULT; 884fcf3ce44SJohn Forte break; 885fcf3ce44SJohn Forte } 886fcf3ce44SJohn Forte } 887fcf3ce44SJohn Forte 888fcf3ce44SJohn Forte break; 889fcf3ce44SJohn Forte 890fcf3ce44SJohn Forte default: 891fcf3ce44SJohn Forte return (ENOTTY); 892fcf3ce44SJohn Forte } 893fcf3ce44SJohn Forte 894fcf3ce44SJohn Forte if (bsize != NULL) { 895fcf3ce44SJohn Forte nsc_kmem_free(bsize, sizeof (*bsize)); 896fcf3ce44SJohn Forte bsize = NULL; 897fcf3ce44SJohn Forte } 898fcf3ce44SJohn Forte if (path != NULL) { 899fcf3ce44SJohn Forte nsc_kmem_free(path, NSC_MAXPATH); 900fcf3ce44SJohn Forte path = NULL; 901fcf3ce44SJohn Forte } 902fcf3ce44SJohn Forte return (rc); 903fcf3ce44SJohn Forte } 904fcf3ce44SJohn Forte 905fcf3ce44SJohn Forte 906fcf3ce44SJohn Forte int 907fcf3ce44SJohn Forte nsc_max_devices(void) 908fcf3ce44SJohn Forte { 909fcf3ce44SJohn Forte return (_nsc_max_devices); 910fcf3ce44SJohn Forte } 911fcf3ce44SJohn Forte 912fcf3ce44SJohn Forte 913fcf3ce44SJohn Forte /* 914fcf3ce44SJohn Forte * Used by _nsc_global_setup() in case nvram is dirty and has saved a different 915fcf3ce44SJohn Forte * value for nsc_max_devices. We need to use the saved value, not the new 916fcf3ce44SJohn Forte * one configured by the user. 917fcf3ce44SJohn Forte */ 918fcf3ce44SJohn Forte void 919fcf3ce44SJohn Forte _nsc_set_max_devices(int maxdev) 920fcf3ce44SJohn Forte { 921fcf3ce44SJohn Forte _nsc_max_devices = maxdev; 922fcf3ce44SJohn Forte _nsc_maxdev = _nsc_max_devices; 923fcf3ce44SJohn Forte } 924