4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER START
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * The contents of this file are subject to the terms of the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Common Development and Distribution License (the "License").
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * You may not use this file except in compliance with the License.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * or http://www.opensolaris.org/os/licensing.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * See the License for the specific language governing permissions
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * and limitations under the License.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * When distributing Covered Code, include this CDDL HEADER in each
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * If applicable, add the following below this CDDL HEADER, with the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * fields enclosed by brackets "[]" replaced with your own identifying
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * information: Portions Copyright [yyyy] [name of copyright owner]
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER END
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
616875b414de63a60e3f732e0d9b5345f07f9221David Hollister * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Use is subject to license terms.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Copyright 2012 Milan Jurik. All rights reserved.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/types.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/ksynch.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/kmem.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/file.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/errno.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/open.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/cred.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/conf.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/uio.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/cmn_err.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/modctl.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/ddi.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#define __NSC_GEN__
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/nsctl/nsc_dev.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/nsctl/nsc_gen.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/nsctl/nsc_ioctl.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/nsctl/nsc_power.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/nsctl/nsc_mem.h>
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne#include "../nsctl.h"
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/nsctl/nsvers.h>
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#ifdef DS_DDICT
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne#include "../contract.h"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#endif
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void nscsetup();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int _nsc_init_raw(int);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_deinit_raw();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_init_start();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_init_os(), _nsc_deinit_os();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_init_dev(), _nsc_init_mem();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_init_gen(), _nsc_init_rmlock();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_init_resv(), _nsc_deinit_resv();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_init_frz(), _nsc_deinit_frz();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_init_ncio(), _nsc_deinit_ncio();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_deinit_mem(), _nsc_deinit_rmlock();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_deinit_dev();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int _nsc_frz_start(char *, int *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int _nsc_frz_stop(char *, int *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int _nsc_frz_isfrozen(char *, int *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern nsc_mem_t *_nsc_local_mem;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern nsc_rmhdr_t *_nsc_rmhdr_ptr;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern nsc_def_t _nsc_raw_def[];
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int _nsc_raw_flags;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint nsc_devflag = D_MP;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint _nsc_init_done = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhkmutex_t _nsc_drv_lock;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnsc_io_t *_nsc_file_io;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnsc_io_t *_nsc_vchr_io;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnsc_io_t *_nsc_raw_io;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnsc_fd_t **_nsc_minor_fd;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhkmutex_t **_nsc_minor_slp;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh/* Maximum number of devices - tunable in nsctl.conf */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic int _nsc_max_devices;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* Internal version of _nsc_max_devices */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint _nsc_maxdev;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_global_setup(void);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic int nsc_load(), nsc_unload();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void nscteardown();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Solaris specific driver module interface code.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int nscopen(dev_t *, int, int, cred_t *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int nscioctl(dev_t, int, intptr_t, int, cred_t *, int *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int nscclose(dev_t, int, int, cred_t *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int nscread(dev_t, uio_t *, cred_t *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int nscwrite(dev_t, uio_t *, cred_t *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic dev_info_t *nsctl_dip; /* Single DIP for driver */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic int _nsctl_print(dev_t, char *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic struct cb_ops nsctl_cb_ops = {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nscopen, /* open */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nscclose, /* close */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nodev, /* not a block driver, strategy not an entry point */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh _nsctl_print, /* no print routine */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh nodev, /* no dump routine */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nscread, /* read */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nscwrite, /* write */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (int (*)()) nscioctl, /* ioctl */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nodev, /* no devmap routine */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nodev, /* no mmap routine */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nodev, /* no segmap routine */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nochpoll, /* no chpoll routine */
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne ddi_prop_op,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh 0, /* not a STREAMS driver, no cb_str routine */
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne CB_REV,
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne nodev, /* aread */
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne nodev, /* awrite */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh};
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdhstatic int _nsctl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Hornestatic int _nsctl_attach(dev_info_t *, ddi_attach_cmd_t);
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Hornestatic int _nsctl_detach(dev_info_t *, ddi_detach_cmd_t);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic struct dev_ops nsctl_ops = {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh DEVO_REV, /* Driver build version */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh 0, /* device reference count */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsctl_getinfo,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nulldev, /* Identify */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nulldev, /* Probe */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsctl_attach,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsctl_detach,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nodev, /* Reset */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh &nsctl_cb_ops,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (struct bus_ops *)0
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh};
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic struct modldrv nsctl_ldrv = {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh &mod_driverops,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "nws:Control:" ISS_VERSION_STR,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh &nsctl_ops
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh};
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic struct modlinkage nsctl_modlinkage = {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh MODREV_1,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh &nsctl_ldrv,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh NULL
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh};
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Solaris module load time code
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint nsc_min_nodeid;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint nsc_max_nodeid;
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_init(void)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int err;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh err = nsc_load();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed if (!err)
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed err = mod_install(&nsctl_modlinkage);
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed if (err) {
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed (void) nsc_unload();
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed cmn_err(CE_NOTE, "!nsctl_init: err %d", err);
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed }
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed return (err);
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed}
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Solaris module unload time code
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_fini(void)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh int err;
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((err = mod_remove(&nsctl_modlinkage)) == 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh err = nsc_unload();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (err);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Solaris module info code
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh_info(struct modinfo *modinfop)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (mod_info(&nsctl_modlinkage, modinfop));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Attach an instance of the device. This happens before an open
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * can succeed.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic int
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_nsctl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int rc;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (cmd == DDI_ATTACH) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsctl_dip = dip;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Announce presence of the device */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ddi_report_dev(dip);
5c45adf04db8ffdcb5dd969bb5203ff9b17677dbJesse Butler
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Get the node parameters now that we can look up.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_min_nodeid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "nsc_min_nodeid", 0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_max_nodeid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "nsc_max_nodeid", 5);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed _nsc_max_devices = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "nsc_max_devices", 128);
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_maxdev = _nsc_max_devices;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nscsetup();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh /*
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * Init raw requires the _nsc_max_devices value and so
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * cannot be done before the nsc_max_devices property has
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * been read which can only be done after the module is
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * attached and we have a dip.
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((rc = _nsc_init_raw(_nsc_max_devices)) != 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh cmn_err(CE_WARN,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "!nsctl: unable to initialize raw io provider: %d",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (DDI_FAILURE);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Init rest of soft state structure
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh rc = ddi_create_minor_node(dip, "c,nsctl", S_IFCHR, 0,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh DDI_PSEUDO, 0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (rc != DDI_SUCCESS) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* free anything we allocated here */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh cmn_err(CE_WARN,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "!_nsctl_attach: ddi_create_minor_node failed %d",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (DDI_FAILURE);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Announce presence of the device */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ddi_report_dev(dip);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh /* mark the device as attached, opens may proceed */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (DDI_SUCCESS);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh } else
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (DDI_FAILURE);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic int
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh_nsctl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (cmd == DDI_DETACH) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nscteardown();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_deinit_raw();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ddi_remove_minor_node(dip, NULL);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsctl_dip = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (DDI_SUCCESS);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh else
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (DDI_FAILURE);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic int
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_nsctl_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dev_t dev;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int rc;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh switch (cmd) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case DDI_INFO_DEVT2INSTANCE:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* The "instance" number is the minor number */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dev = (dev_t)arg;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *result = (void *)(unsigned long)getminor(dev);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = DDI_SUCCESS;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh case DDI_INFO_DEVT2DEVINFO:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *result = nsctl_dip;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = DDI_SUCCESS;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh default:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = DDI_FAILURE;
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister break;
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdhstatic int
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_nsctl_print(dev_t dev, char *s)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh cmn_err(CE_WARN, "!nsctl:%s", s);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhvoid
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnsc_init()
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (_nsc_init_done)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_start();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_gen();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_svc();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_mem();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_dev();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_rmlock();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_resv();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_os();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (void) _nsc_init_power();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * When using mc, nscsetup is done through mc callback to global_init.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nscsetup();
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister mutex_init(&_nsc_drv_lock, NULL, MUTEX_DRIVER, NULL);
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister _nsc_raw_io = nsc_register_io("raw",
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister NSC_RAW_ID | _nsc_raw_flags, _nsc_raw_def);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (!_nsc_raw_io)
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister cmn_err(CE_WARN, "!_nsc_init: register io failed - raw");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_ncio();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_frz();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_done = 1;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
616875b414de63a60e3f732e0d9b5345f07f9221David Hollister
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Called after the mc refresh is complete (SEG_INIT callbacks have
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * been received) and module _attach() is done. Only does any real
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister * work when all of the above conditions have been met.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhvoid
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnscsetup()
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (nsc_max_devices() == 0 || _nsc_minor_fd != NULL)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_fd = nsc_kmem_zalloc(sizeof (nsc_fd_t *)*_nsc_maxdev,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh 0, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (!_nsc_minor_fd) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh cmn_err(CE_WARN, "!nscsetup - alloc failed");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_slp = nsc_kmem_zalloc(sizeof (kmutex_t *)*_nsc_maxdev,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh 0, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (!_nsc_minor_slp) {
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed cmn_err(CE_WARN, "!nscsetup - alloc failed");
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev);
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed _nsc_minor_fd = (nsc_fd_t **)NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnscteardown()
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int i;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (_nsc_minor_fd == NULL)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#ifdef DEBUG
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Check all devices were closed. Index 0 is the prototype dev. */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh for (i = 1; i < _nsc_maxdev; i++) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ASSERT(_nsc_minor_slp[i] == NULL);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ASSERT(_nsc_minor_fd[i] == NULL);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#endif /* DEBUG */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh nsc_kmem_free(_nsc_minor_slp, sizeof (kmutex_t *) * _nsc_maxdev);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_fd = (nsc_fd_t **)NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_slp = (kmutex_t **)NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnsc_load()
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_init();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnsc_unload()
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (!_nsc_init_done) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister }
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister nscteardown();
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister (void) _nsc_deinit_power();
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana _nsc_deinit_resv();
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana _nsc_deinit_mem();
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana _nsc_deinit_rmlock();
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana _nsc_deinit_svc();
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana _nsc_deinit_frz();
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana _nsc_deinit_ncio();
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana if (_nsc_vchr_io)
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana (void) nsc_unregister_io(_nsc_vchr_io, 0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (_nsc_file_io)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (void) nsc_unregister_io(_nsc_file_io, 0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_vchr_io = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_file_io = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (_nsc_raw_io)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (void) nsc_unregister_io(_nsc_raw_io, 0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_raw_io = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_deinit_dev();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_deinit_os();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_init_done = 0;
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnscopen(dev_t *devp, int flag, int otyp, cred_t *crp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh kmutex_t *slp;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int i, error;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (error = drv_priv(crp))
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (error);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (!_nsc_minor_fd || !_nsc_minor_slp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (ENXIO);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (getminor(*devp) != 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (ENXIO);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh slp = nsc_kmem_alloc(sizeof (kmutex_t), 0, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_init(slp, NULL, MUTEX_DRIVER, NULL);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_enter(&_nsc_drv_lock);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh for (i = 1; i < _nsc_maxdev; i++) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (_nsc_minor_slp[i] == NULL) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_slp[i] = slp;
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh break;
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(&_nsc_drv_lock);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh if (i >= _nsc_maxdev) {
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh mutex_destroy(slp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_kmem_free(slp, sizeof (kmutex_t));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (EAGAIN);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *devp = makedevice(getmajor(*devp), i);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_nscopen(dev_t dev, intptr_t arg, int mode, int *rvp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh minor_t mindev = getminor(dev);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh struct nscioc_open *op;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_fd_t *fd;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int rc;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh op = nsc_kmem_alloc(sizeof (*op), KM_SLEEP, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (op == NULL) {
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (ENOMEM);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
b18a19c275d2531444fcd2f66664cbe3c6897f6aJesse Butler
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, op, sizeof (*op), mode) < 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_kmem_free(op, sizeof (*op));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (EFAULT);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
b18a19c275d2531444fcd2f66664cbe3c6897f6aJesse Butler
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_enter(_nsc_minor_slp[mindev]);
b18a19c275d2531444fcd2f66664cbe3c6897f6aJesse Butler
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana if (_nsc_minor_fd[mindev]) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh nsc_kmem_free(op, sizeof (*op));
b18a19c275d2531444fcd2f66664cbe3c6897f6aJesse Butler return (EBUSY);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
b18a19c275d2531444fcd2f66664cbe3c6897f6aJesse Butler
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh op->path[sizeof (op->path)-1] = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh fd = nsc_open(op->path, (op->flag & NSC_TYPES), 0, 0, &rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (fd == NULL) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh nsc_kmem_free(op, sizeof (*op));
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (rc);
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mode |= (op->mode - FOPEN);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mode & (FWRITE|FEXCL)) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (void) nsc_close(fd);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_kmem_free(op, sizeof (*op));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *rvp = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_fd[mindev] = fd;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh nsc_kmem_free(op, sizeof (*op));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnscclose(dev_t dev, int flag, int otyp, cred_t *crp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh minor_t mindev = getminor(dev);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh kmutex_t *slp;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_fd_t *fd;
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana if (!_nsc_minor_fd || !_nsc_minor_slp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((slp = _nsc_minor_slp[mindev]) == 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((fd = _nsc_minor_fd[mindev]) != NULL)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (void) nsc_close(fd);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_fd[mindev] = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_slp[mindev] = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_destroy(slp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_kmem_free(slp, sizeof (kmutex_t));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
b18a19c275d2531444fcd2f66664cbe3c6897f6aJesse Butler/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnscread(dev_t dev, uio_t *uiop, cred_t *crp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh minor_t mindev = getminor(dev);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int rc, resv;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_fd_t *fd;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((fd = _nsc_minor_fd[mindev]) == 0)
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana return (EIO);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_enter(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh resv = (nsc_held(fd) == 0);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana mutex_exit(_nsc_minor_slp[mindev]);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana return (rc);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = nsc_uread(fd, uiop, crp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (resv)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_release(fd);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (rc);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramanaint
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramananscwrite(dev_t dev, uio_t *uiop, cred_t *crp)
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana{
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana minor_t mindev = getminor(dev);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana int rc, resv;
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana nsc_fd_t *fd;
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana if ((fd = _nsc_minor_fd[mindev]) == 0)
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana return (EIO);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana mutex_enter(_nsc_minor_slp[mindev]);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana resv = (nsc_held(fd) == 0);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana mutex_exit(_nsc_minor_slp[mindev]);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana return (rc);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana }
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana rc = nsc_uwrite(fd, uiop, crp);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana if (resv)
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana nsc_release(fd);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana mutex_exit(_nsc_minor_slp[mindev]);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana return (rc);
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_nscreserve(dev_t dev, int *rvp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh minor_t mindev = getminor(dev);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_fd_t *fd;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int rc;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((fd = _nsc_minor_fd[mindev]) == 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (EIO);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_enter(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (nsc_held(fd)) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (EBUSY);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *rvp = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_nscrelease(dev_t dev, int *rvp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh minor_t mindev = getminor(dev);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_fd_t *fd;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((fd = _nsc_minor_fd[mindev]) == 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (EIO);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_enter(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (!nsc_held(fd)) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (EINVAL);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_release(fd);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *rvp = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_nscpartsize(dev_t dev, intptr_t arg, int mode)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh struct nscioc_partsize partsize;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh minor_t mindev = getminor(dev);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_size_t size;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int rc, resv;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_fd_t *fd;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((fd = _nsc_minor_fd[mindev]) == 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (EIO);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_enter(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh resv = (nsc_held(fd) == 0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = nsc_partsize(fd, &size);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh partsize.partsize = (uint64_t)size;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (resv)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_release(fd);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mutex_exit(_nsc_minor_slp[mindev]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyout((void *)&partsize, (void *)arg,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh sizeof (partsize), mode) < 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (EFAULT);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnscioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh struct nscioc_bsize *bsize = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh char *path = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int rc = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *rvp = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh switch (cmd) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_OPEN:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nscopen(dev, arg, mode, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_RESERVE:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nscreserve(dev, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
b18a19c275d2531444fcd2f66664cbe3c6897f6aJesse Butler case NSCIOC_RELEASE:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nscrelease(dev, rvp);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_PARTSIZE:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nscpartsize(dev, arg, mode);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_FREEZE:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (path == NULL) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = ENOMEM;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = EFAULT;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh else {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path[NSC_MAXPATH-1] = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nsc_frz_start(path, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_UNFREEZE:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (path == NULL) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = ENOMEM;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = EFAULT;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh else {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path[NSC_MAXPATH-1] = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nsc_frz_stop(path, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_ISFROZEN:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (path == NULL) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = ENOMEM;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = EFAULT;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh else {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path[NSC_MAXPATH-1] = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nsc_frz_isfrozen(path, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#ifdef ENABLE_POWER_MSG
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_POWERMSG:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nsc_power((void *)arg, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#endif
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_NSKERND:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = nskernd_command(arg, mode, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* return sizes of global memory segments */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_GLOBAL_SIZES:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (!_nsc_init_done) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = EINVAL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nsc_get_global_sizes((void *)arg, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* return contents of global segments */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_GLOBAL_DATA:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (!_nsc_init_done) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = EINVAL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nsc_get_global_data((void *)arg, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * nvmem systems:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * clear the hdr dirty bit to prevent loading from nvme on reboot
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_NVMEM_CLEANF:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nsc_clear_dirty(1); /* dont be nice about it */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_NVMEM_CLEAN:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = _nsc_clear_dirty(0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh case NSCIOC_BSIZE:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bsize = nsc_kmem_alloc(sizeof (*bsize), KM_SLEEP,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (bsize == NULL) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = ENOMEM;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, bsize, sizeof (*bsize), mode) < 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = EFAULT;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = nskern_bsize(bsize, rvp);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (rc == 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyout(bsize, (void *)arg,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh sizeof (*bsize), mode) < 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh rc = EFAULT;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh break;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh default:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (ENOTTY);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (bsize != NULL) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_kmem_free(bsize, sizeof (*bsize));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bsize = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (path != NULL) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_kmem_free(path, NSC_MAXPATH);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnsc_max_devices(void)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (_nsc_max_devices);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Used by _nsc_global_setup() in case nvram is dirty and has saved a different
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * value for nsc_max_devices. We need to use the saved value, not the new
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * one configured by the user.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhvoid
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_nsc_set_max_devices(int maxdev)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_max_devices = maxdev;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_maxdev = _nsc_max_devices;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh