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
_init(void)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
_fini(void)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
_info(struct modinfo * modinfop)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
_nsctl_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)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
_nsctl_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)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
_nsctl_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)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
_nsctl_print(dev_t dev,char * s)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
nsc_init()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
nscsetup()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
nscteardown()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
nsc_load()428fcf3ce44SJohn Forte nsc_load()
429fcf3ce44SJohn Forte {
430fcf3ce44SJohn Forte nsc_init();
431fcf3ce44SJohn Forte return (0);
432fcf3ce44SJohn Forte }
433fcf3ce44SJohn Forte
434fcf3ce44SJohn Forte
435fcf3ce44SJohn Forte int
nsc_unload()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
nscopen(dev_t * devp,int flag,int otyp,cred_t * crp)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
_nscopen(dev_t dev,intptr_t arg,int mode,int * rvp)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
nscclose(dev_t dev,int flag,int otyp,cred_t * crp)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
nscread(dev_t dev,uio_t * uiop,cred_t * crp)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
nscwrite(dev_t dev,uio_t * uiop,cred_t * crp)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
_nscreserve(dev_t dev,int * rvp)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
_nscrelease(dev_t dev,int * rvp)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
_nscpartsize(dev_t dev,intptr_t arg,int mode)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
nscioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * crp,int * rvp)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
nsc_max_devices(void)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
_nsc_set_max_devices(int maxdev)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