xref: /titanic_44/usr/src/uts/common/avs/ns/nsctl/nsc_dev.c (revision 3270659f55e0928d6edec3d26217cc29398a8149)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/debug.h>
28 #include <sys/ksynch.h>
29 #include <sys/kmem.h>
30 #include <sys/cmn_err.h>
31 #include <sys/errno.h>
32 #include <sys/ddi.h>
33 
34 #include <sys/ncall/ncall.h>
35 
36 #define	__NSC_GEN__
37 #include "nsc_dev.h"
38 
39 #ifdef DS_DDICT
40 #include "../contract.h"
41 #endif
42 
43 #include "../nsctl.h"
44 
45 #define	NSC_DEVMIN	"DevMin"
46 #define	NSC_DEVMAJ	"DevMaj"
47 
48 #define	_I(x)	(((long)(&((nsc_io_t *)0)->x))/sizeof (long))
49 #define	_F(x)	(((long)(&((nsc_fd_t *)0)->x))/sizeof (long))
50 
51 
52 nsc_def_t _nsc_io_def[] = {
53 	"Open",		(uintptr_t)nsc_null,	_I(open),
54 	"Close",	(uintptr_t)nsc_null,	_I(close),
55 	"Attach",	(uintptr_t)nsc_null,	_I(attach),
56 	"Detach",	(uintptr_t)nsc_null,	_I(detach),
57 	"Flush",	(uintptr_t)nsc_null,	_I(flush),
58 	"Provide",	0,		_I(provide),
59 	0,		0,		0
60 };
61 
62 nsc_def_t _nsc_fd_def[] = {
63 	"Pinned",	(uintptr_t)nsc_null,	_F(sf_pinned),
64 	"Unpinned",	(uintptr_t)nsc_null,	_F(sf_unpinned),
65 	"Attach",	(uintptr_t)nsc_null,	_F(sf_attach),
66 	"Detach",	(uintptr_t)nsc_null,	_F(sf_detach),
67 	"Flush",	(uintptr_t)nsc_null,	_F(sf_flush),
68 	0,		0,		0
69 };
70 
71 kmutex_t _nsc_io_lock;
72 kmutex_t _nsc_devval_lock;
73 
74 nsc_io_t *_nsc_io_top = NULL;
75 nsc_io_t *_nsc_null_io = NULL;
76 nsc_dev_t *_nsc_dev_top = NULL;
77 nsc_dev_t *_nsc_dev_pend = NULL;
78 nsc_path_t *_nsc_path_top = NULL;
79 nsc_devval_t *_nsc_devval_top = NULL;
80 
81 extern nsc_def_t _nsc_disk_def[];
82 extern nsc_def_t _nsc_cache_def[];
83 
84 extern nsc_mem_t *_nsc_local_mem;
85 extern nsc_rmmap_t *_nsc_global_map;
86 
87 static clock_t _nsc_io_lbolt;
88 
89 static nsc_io_t *_nsc_find_io(char *, int, int *);
90 nsc_io_t *_nsc_reserve_io(char *, int);
91 static nsc_io_t *_nsc_alloc_io(int, char *, int);
92 
93 static int _nsc_open_fn(nsc_fd_t *, int);
94 static int _nsc_close_fn(nsc_fd_t *);
95 static int _nsc_alloc_fd(char *, int, int, nsc_fd_t **);
96 static int _nsc_alloc_iodev(nsc_dev_t *, int, nsc_iodev_t **);
97 static int _nsc_alloc_dev(char *, nsc_dev_t **);
98 static int _nsc_reopen_io(char *, int);
99 static int _nsc_reopen_dev(nsc_dev_t *, int);
100 static int _nsc_relock_dev(nsc_dev_t *, nsc_fd_t *, nsc_iodev_t *);
101 static int _nsc_reopen_fd(nsc_fd_t *, int);
102 static int _nsc_decode_io(nsc_def_t *, nsc_io_t *);
103 
104 void _nsc_release_io(nsc_io_t *);
105 static void _nsc_free_fd(nsc_fd_t *);
106 static void _nsc_free_iodev(nsc_iodev_t *);
107 static void _nsc_free_dev(nsc_dev_t *);
108 static void _nsc_free_io(nsc_io_t *);
109 static void _nsc_relink_fd(nsc_fd_t *, nsc_fd_t **, nsc_fd_t **, nsc_iodev_t *);
110 
111 static int _nsc_setval(nsc_dev_t *, char *, char *, int, int);
112 static void r_nsc_setval(ncall_t *, int *);
113 static void r_nsc_setval_all(ncall_t *, int *);
114 
115 extern void _nsc_add_disk(nsc_io_t *);
116 extern void _nsc_add_cache(nsc_io_t *);
117 
118 
119 /*
120  * void
121  * _nsc_init_dev (void)
122  *	Initialise device subsystem.
123  *
124  * Calling/Exit State:
125  *	Called at driver initialisation time to allocate necessary
126  *	data structures.
127  */
128 void
_nsc_init_dev()129 _nsc_init_dev()
130 {
131 	mutex_init(&_nsc_io_lock, NULL, MUTEX_DRIVER, NULL);
132 	mutex_init(&_nsc_devval_lock, NULL, MUTEX_DRIVER, NULL);
133 
134 	_nsc_null_io = nsc_register_io("null", NSC_NULL, (nsc_def_t *)0);
135 
136 	if (!_nsc_null_io)
137 		cmn_err(CE_PANIC, "nsctl: nsc_init_dev");
138 
139 	ncall_register_svc(NSC_SETVAL_ALL, r_nsc_setval_all);
140 	ncall_register_svc(NSC_SETVAL, r_nsc_setval);
141 }
142 
143 
144 void
_nsc_deinit_dev()145 _nsc_deinit_dev()
146 {
147 	nsc_devval_t *dv;
148 	nsc_val_t *vp;
149 
150 	mutex_enter(&_nsc_devval_lock);
151 
152 	while ((dv = _nsc_devval_top) != NULL) {
153 		while ((vp = dv->dv_values) != NULL) {
154 			dv->dv_values = vp->sv_next;
155 			nsc_kmem_free(vp, sizeof (*vp));
156 		}
157 
158 		_nsc_devval_top = dv->dv_next;
159 		nsc_kmem_free(dv, sizeof (*dv));
160 	}
161 
162 	mutex_exit(&_nsc_devval_lock);
163 
164 	ncall_unregister_svc(NSC_SETVAL_ALL);
165 	ncall_unregister_svc(NSC_SETVAL);
166 
167 	mutex_destroy(&_nsc_devval_lock);
168 	mutex_destroy(&_nsc_io_lock);
169 }
170 
171 
172 /*
173  * nsc_io_t *
174  * nsc_register_io (char *name, int type, nsc_def_t *def)
175  *	Register an I/O module.
176  *
177  * Calling/Exit State:
178  *	Returns a token for use in future calls to nsc_unregister_io.
179  *	The ID and flags for the module are specified by 'type' and
180  *	the appropriate entry points are defined using 'def'. If
181  *	registration fails NULL is returned.
182  *
183  * Description:
184  *	Registers an I/O module for use by subsequent calls to
185  *	nsc_open.
186  */
187 nsc_io_t *
nsc_register_io(name,type,def)188 nsc_register_io(name, type, def)
189 char *name;
190 int type;
191 nsc_def_t *def;
192 {
193 	nsc_io_t *io, *tp;
194 	int rc, id, flag;
195 	nsc_io_t **iop;
196 
197 	id = (type & NSC_TYPES);
198 	flag = (type & ~NSC_TYPES);
199 
200 	if ((!(id & NSC_ID) || (id & ~NSC_IDS)) &&
201 			(id != NSC_NULL || _nsc_null_io))
202 		return (NULL);
203 
204 	if (!(io = _nsc_alloc_io(id, name, flag)))
205 		return (NULL);
206 
207 	rc = _nsc_decode_io(def, io);
208 
209 	if (!rc && id != NSC_NULL) {
210 		_nsc_free_io(io);
211 		return (NULL);
212 	}
213 
214 	mutex_enter(&_nsc_io_lock);
215 
216 	for (tp = _nsc_io_top; tp; tp = tp->next) {
217 		if (strcmp(tp->name, name) == 0 || tp->id == id) {
218 			mutex_exit(&_nsc_io_lock);
219 			_nsc_free_io(io);
220 			return (NULL);
221 		}
222 	}
223 
224 	for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next)
225 		if (id >= (*iop)->id)
226 			break;
227 
228 	io->next = (*iop);
229 	(*iop) = io;
230 
231 	_nsc_io_lbolt = nsc_lbolt();
232 
233 	while ((rc = _nsc_reopen_io(NULL, 0)) != 0)
234 		if (rc != ERESTART)
235 			break;
236 
237 	mutex_exit(&_nsc_io_lock);
238 	return (io);
239 }
240 
241 
242 /*
243  * static int
244  * _nsc_decode_io (nsc_def_t *def, nsc_io_t *io)
245  *	Decode I/O module definition.
246  *
247  * Calling/Exit State:
248  *	Returns TRUE if the definition contains an adequate
249  *	description of an I/O module.
250  *
251  * Description:
252  *	Decode the definition of an I/O module and supply
253  *	translation routines where possible for operations
254  *	that are not defined.
255  */
256 static int
_nsc_decode_io(def,io)257 _nsc_decode_io(def, io)
258 nsc_def_t *def;
259 nsc_io_t *io;
260 {
261 	nsc_decode_param(def, _nsc_io_def, (long *)io);
262 	nsc_decode_param(def, _nsc_disk_def, (long *)io);
263 	nsc_decode_param(def, _nsc_cache_def, (long *)io);
264 
265 	_nsc_add_disk(io);
266 	_nsc_add_cache(io);
267 
268 	return (1);
269 }
270 
271 
272 /*
273  * int
274  * nsc_unregister_io (nsc_io_t *io, int flag)
275  *	Un-register an I/O module.
276  *
277  * Calling/Exit State:
278  *	Returns 0 on success, otherwise returns an error code.
279  *
280  * Description:
281  *	The specified I/O module is un-registered if possible.
282  *	All open file descriptors using the module will be closed
283  *	in preparation for a subsequent re-open.
284  *
285  *	If NSC_PCATCH is specified and a signal is received,
286  *	the unregister will be terminated and EINTR returned.
287  */
288 int
nsc_unregister_io(nsc_io_t * io,int flag)289 nsc_unregister_io(nsc_io_t *io, int flag)
290 {
291 	nsc_path_t *sp;
292 	nsc_io_t *xio;
293 	int rc = 0;
294 
295 	if (io == _nsc_null_io)
296 		return (EINVAL);
297 
298 	mutex_enter(&_nsc_io_lock);
299 
300 	for (xio = _nsc_io_top; xio; xio = xio->next)
301 		if (xio == io)
302 			break;
303 
304 	if (!xio || io->pend) {
305 		mutex_exit(&_nsc_io_lock);
306 		return (xio ? EALREADY : 0);
307 	}
308 
309 	io->pend = 1;
310 lp:
311 	for (sp = _nsc_path_top; sp; sp = sp->sp_next)
312 		if (sp->sp_io == io) {
313 			mutex_exit(&_nsc_io_lock);
314 
315 			if ((rc = nsc_unregister_path(sp, flag)) != 0) {
316 				io->pend = 0;
317 				return (rc);
318 			}
319 
320 			mutex_enter(&_nsc_io_lock);
321 			goto lp;
322 		}
323 
324 	_nsc_io_lbolt = nsc_lbolt();
325 
326 	while (io->refcnt && !rc) {
327 		while ((rc = _nsc_reopen_io(NULL, flag)) != 0)
328 			if (rc != ERESTART)
329 				break;
330 
331 		if (rc || !io->refcnt)
332 			break;
333 
334 		if (!cv_wait_sig(&io->cv, &_nsc_io_lock))
335 			rc = EINTR;
336 	}
337 
338 	/*
339 	 * We have tried to get rid of all the IO provider's clients.
340 	 * If there are still anonymous buffers outstanding, then fail
341 	 * the unregister.
342 	 */
343 
344 	if (!rc && io->abufcnt > 0)
345 		rc = EUSERS;
346 
347 	if (rc)
348 		io->pend = 0;
349 
350 	mutex_exit(&_nsc_io_lock);
351 
352 	if (!rc)
353 		_nsc_free_io(io);
354 
355 	return (rc);
356 }
357 
358 
359 /*
360  * nsc_path_t *
361  * nsc_register_path (char *path, int type, nsc_io_t *io)
362  *	Register interest in pathname.
363  *
364  * Calling/Exit State:
365  *	Returns a token for use in future calls to
366  *	nsc_unregister_path. The 'path' argument can contain
367  *	wild characters. If registration fails NULL is returned.
368  *	May not be called for io providers that support NSC_ANON.
369  *
370  * Description:
371  *	Registers an interest in any pathnames matching 'path'
372  *	which are opened with the specified type.
373  */
374 nsc_path_t *
nsc_register_path(char * path,int type,nsc_io_t * io)375 nsc_register_path(char *path, int type, nsc_io_t *io)
376 {
377 	nsc_path_t *sp, **spp;
378 	int rc;
379 
380 	if ((type & NSC_IDS) || !io || (io->provide & NSC_ANON) ||
381 	    !(sp = nsc_kmem_zalloc(sizeof (*sp), KM_SLEEP, _nsc_local_mem)))
382 		return (NULL);
383 
384 	sp->sp_path = nsc_strdup(path);
385 	sp->sp_type = type;
386 	sp->sp_io = io;
387 
388 	mutex_enter(&_nsc_io_lock);
389 
390 	for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next)
391 		if (io->id >= (*spp)->sp_io->id)
392 			break;
393 
394 	sp->sp_next = (*spp);
395 	(*spp) = sp;
396 
397 	_nsc_io_lbolt = nsc_lbolt();
398 
399 	while ((rc = _nsc_reopen_io(path, 0)) != 0)
400 		if (rc != ERESTART)
401 			break;
402 
403 	mutex_exit(&_nsc_io_lock);
404 	return (sp);
405 }
406 
407 
408 /*
409  * int
410  * nsc_unregister_path (nsc_path_t *sp, int flag)
411  *	Un-register interest in pathname.
412  *
413  * Calling/Exit State:
414  *	Returns 0 on success, otherwise returns an error code.
415  *
416  * Description:
417  *	Interest in the specified pathname is un-registered
418  *	if possible. All appropriate file descriptors will be
419  *	closed in preparation for a subsequent re-open.
420  *
421  *	If NSC_PCATCH is specified and a signal is received,
422  *	the unregister will be terminated and EINTR returned.
423  */
424 int
nsc_unregister_path(sp,flag)425 nsc_unregister_path(sp, flag)
426 nsc_path_t *sp;
427 int flag;
428 {
429 	nsc_path_t *xsp, **spp;
430 	int rc;
431 
432 	mutex_enter(&_nsc_io_lock);
433 
434 	for (xsp = _nsc_path_top; xsp; xsp = xsp->sp_next)
435 		if (xsp == sp)
436 			break;
437 
438 	if (!xsp || sp->sp_pend) {
439 		mutex_exit(&_nsc_io_lock);
440 		return (xsp ? EALREADY : 0);
441 	}
442 
443 	sp->sp_pend = 1;
444 	_nsc_io_lbolt = nsc_lbolt();
445 
446 	while ((rc = _nsc_reopen_io(sp->sp_path, flag)) != 0)
447 		if (rc != ERESTART) {
448 			sp->sp_pend = 0;
449 			mutex_exit(&_nsc_io_lock);
450 			return (rc);
451 		}
452 
453 	for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next)
454 		if (*spp == sp)
455 			break;
456 
457 	if (*spp)
458 		(*spp) = sp->sp_next;
459 
460 	mutex_exit(&_nsc_io_lock);
461 
462 	nsc_strfree(sp->sp_path);
463 	nsc_kmem_free(sp, sizeof (*sp));
464 	return (0);
465 }
466 
467 
468 /*
469  * static int
470  * _nsc_reopen_io (char *path, int flag)
471  *	Force re-open of all file descriptors.
472  *
473  * Calling/Exit State:
474  *	The _nsc_io_lock must be held across calls to
475  *	this function.
476  *
477  *	Returns 0 if the force succeeds without releasing
478  *	_nsc_io_lock, otherwise returns an error code.
479  *
480  * Description:
481  *	A re-open is forced for all file descriptors as
482  *	appropriate. For performance reasons available
483  *	devices are re-opened before those that would block.
484  */
485 static int
_nsc_reopen_io(path,flag)486 _nsc_reopen_io(path, flag)
487 char *path;
488 int flag;
489 {
490 	nsc_dev_t *dp, *dev;
491 	int rc, errno = 0;
492 	int try, run;
493 
494 	for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0) {
495 		for (dev = _nsc_dev_top; dev; dev = dev->nsc_next) {
496 			if (path && !nsc_strmatch(dev->nsc_path, path))
497 				continue;
498 
499 			if (!(rc = _nsc_reopen_dev(dev, flag | try)))
500 				continue;
501 
502 			for (dp = _nsc_dev_top; dp; dp = dp->nsc_next)
503 				if (dp == dev)
504 					break;
505 
506 			if (!dp)
507 				return (ERESTART);
508 
509 			if (try && !(flag & NSC_TRY))
510 				run = 1;
511 			if (!run && errno != ERESTART)
512 				errno = rc;
513 		}
514 	}
515 
516 	return (errno);
517 }
518 
519 
520 /*
521  * static int
522  * _nsc_reopen_dev (nsc_dev_t *dev, int flag)
523  *	Force re-open of entire device.
524  *
525  * Calling/Exit State:
526  *	The _nsc_io_lock must be held across calls to
527  *	this function.
528  *
529  *	Returns 0 if the force succeeds without releasing
530  *	_nsc_io_lock, otherwise returns an error code.
531  *
532  * Description:
533  *	A re-open is forced for all file descriptors for the
534  *	device as appropriate.
535  */
536 static int
_nsc_reopen_dev(dev,flag)537 _nsc_reopen_dev(dev, flag)
538 nsc_dev_t *dev;
539 int flag;
540 {
541 	int rc, errno = 0;
542 	nsc_iodev_t *iodev;
543 	int try, run;
544 	nsc_fd_t *fd;
545 
546 	mutex_enter(&dev->nsc_lock);
547 
548 	for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0)
549 		for (iodev = dev->nsc_list; iodev; iodev = iodev->si_next) {
550 			for (fd = iodev->si_open; fd; fd = fd->sf_next) {
551 				if (!(rc = _nsc_reopen_fd(fd, flag | try)))
552 					continue;
553 
554 				if (rc == -ERESTART)
555 					return (ERESTART);
556 
557 				if (!_nsc_relock_dev(dev, fd, iodev))
558 					return (ERESTART);
559 
560 				if (try && !(flag & NSC_TRY))
561 					run = 1;
562 				if (!run && errno != ERESTART)
563 					errno = rc;
564 			}
565 		}
566 
567 	for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0)
568 		for (fd = dev->nsc_close; fd; fd = fd->sf_next) {
569 			if (!(rc = _nsc_reopen_fd(fd, flag | try)))
570 				continue;
571 
572 			if (rc == -ERESTART)
573 				return (ERESTART);
574 
575 			if (!_nsc_relock_dev(dev, fd, NULL))
576 				return (ERESTART);
577 
578 			if (try && !(flag & NSC_TRY))
579 				run = 1;
580 			if (!run && errno != ERESTART)
581 				errno = rc;
582 		}
583 
584 	mutex_exit(&dev->nsc_lock);
585 	return (errno);
586 }
587 
588 
589 /*
590  * static int
591  * _nsc_relock_dev (nsc_dev_t *dev, nsc_fd_t *fd, nsc_iodev_t *iodev)
592  *	Relock device structure if possible.
593  *
594  * Calling/Exit State:
595  *	The _nsc_io_lock must be held across calls to
596  *	this function.
597  *
598  *	Checks whether the file descriptor is still part
599  *	of the specified device and I/O device. If so the
600  *	device lock is taken. Otherwise FALSE is returned.
601  */
602 static int
_nsc_relock_dev(nsc_dev_t * dev,nsc_fd_t * fd,nsc_iodev_t * iodev)603 _nsc_relock_dev(nsc_dev_t *dev, nsc_fd_t *fd, nsc_iodev_t *iodev)
604 {
605 	nsc_fd_t *fp = NULL;
606 	nsc_iodev_t *iop;
607 	nsc_dev_t *dp;
608 
609 	for (dp = _nsc_dev_top; dp; dp = dp->nsc_next)
610 		if (dp == dev)
611 			break;
612 
613 	if (!dp)
614 		return (0);
615 
616 	mutex_enter(&dev->nsc_lock);
617 
618 	if (iodev)
619 		for (iop = dev->nsc_list; iop; iop = iop->si_next)
620 			if (iop == iodev)
621 				break;
622 
623 	if (!iodev || iop) {
624 		fp = (iodev) ? iodev->si_open : dev->nsc_close;
625 
626 		for (; fp; fp = fp->sf_next)
627 			if (fp == fd)
628 				break;
629 	}
630 
631 	if (!fp) {
632 		mutex_exit(&dev->nsc_lock);
633 		return (0);
634 	}
635 
636 	return (1);
637 }
638 
639 
640 /*
641  * static int
642  * _nsc_reopen_fd (nsc_fd_t *dev, int flag)
643  *	Force re-open of file descriptor.
644  *
645  * Calling/Exit State:
646  *	Both _nsc_io_lock and the device lock must be held
647  *	across calls to this function.
648  *
649  *	Returns 0 if the force succeeds without releasing
650  *	any locks, otherwise returns an error code. If an
651  *	error code is returned the device lock is released.
652  *
653  * Description:
654  *	If appropriate the file descriptor is closed in order
655  *	to force a subsequent open using the currently available
656  *	resources.
657  */
658 static int
_nsc_reopen_fd(fd,flag)659 _nsc_reopen_fd(fd, flag)
660 nsc_fd_t *fd;
661 int flag;
662 {
663 	nsc_dev_t *dev = fd->sf_dev;
664 	nsc_iodev_t *iodev = fd->sf_iodev;
665 	int changed = 0;
666 	int rc;
667 
668 	if (!fd->sf_pend && !iodev)
669 		return (0);
670 
671 	if (fd->sf_pend == _NSC_OPEN)
672 		if (fd->sf_lbolt - _nsc_io_lbolt > 0)
673 			return (0);
674 
675 	if (iodev &&
676 	    (iodev->si_io ==
677 		_nsc_find_io(dev->nsc_path, fd->sf_type, &changed)) &&
678 	    !changed)
679 		return (0);
680 
681 	if (iodev)
682 		fd->sf_reopen = 1;
683 
684 	mutex_exit(&_nsc_io_lock);
685 
686 	dev->nsc_reopen = 1;
687 
688 	rc = _nsc_close_fd(fd, flag);
689 
690 	dev->nsc_reopen = 0;
691 
692 	if (rc == EAGAIN && (flag & NSC_DEFER) && fd->sf_reopen)
693 		dev->nsc_drop = 1;
694 
695 	mutex_exit(&dev->nsc_lock);
696 
697 	if (rc == -ERESTART)
698 		delay(2);	/* allow other threads cpu time */
699 
700 	mutex_enter(&_nsc_io_lock);
701 	return (rc ? rc : ERESTART);
702 }
703 
704 
705 /*
706  * nsc_fd_t *
707  * nsc_open (char *path, int type, nsc_def_t *def, blind_t arg, int *sts)
708  *	Open file descriptor for pathname.
709  *
710  * Calling/Exit State:
711  *	Returns file descriptor if open succeeds, otherwise
712  *	returns 0 and puts error code in the location pointed
713  *	to by sts.
714  *
715  * Description:
716  *	Open the specified pathname using an appropriate access
717  *	method.
718  */
719 nsc_fd_t *
nsc_open(path,type,def,arg,sts)720 nsc_open(path, type, def, arg, sts)
721 char *path;
722 int type;
723 nsc_def_t *def;
724 blind_t arg;
725 int *sts;
726 {
727 	int flag, rc;
728 	nsc_fd_t *fd;
729 
730 	flag = (type & ~NSC_TYPES);
731 	type &= NSC_TYPES;
732 
733 	if ((flag & NSC_READ) == 0)
734 		flag |= NSC_RDWR;
735 
736 	if ((rc = _nsc_alloc_fd(path, type, flag, &fd)) != 0) {
737 		if (sts)
738 			*sts = rc;
739 		return (NULL);
740 	}
741 
742 	fd->sf_arg = arg;
743 	fd->sf_aio = _nsc_null_io;
744 
745 	nsc_decode_param(def, _nsc_fd_def, (long *)fd);
746 
747 	mutex_enter(&fd->sf_dev->nsc_lock);
748 
749 	while ((rc = _nsc_open_fd(fd, flag)) != 0)
750 		if (rc != ERESTART)
751 			break;
752 
753 	mutex_exit(&fd->sf_dev->nsc_lock);
754 
755 	if (rc) {
756 		_nsc_free_fd(fd);
757 		if (sts)
758 			*sts = rc;
759 		return (NULL);
760 	}
761 
762 	return (fd);
763 }
764 
765 
766 /*
767  * int
768  * _nsc_open_fd (nsc_fd_t *fd, int flag)
769  *	Open file descriptor.
770  *
771  * Calling/Exit State:
772  *	The device lock must be held across calls to
773  *	this function.
774  *
775  *	Returns 0 if the open succeeds, otherwise
776  *	returns an error code.
777  *
778  * Description:
779  *	Open the specified file descriptor.
780  */
781 int
_nsc_open_fd(fd,flag)782 _nsc_open_fd(fd, flag)
783 nsc_fd_t *fd;
784 int flag;
785 {
786 	nsc_dev_t *dev = fd->sf_dev;
787 	int rc;
788 
789 	if (fd->sf_pend)
790 		return (_nsc_wait_dev(dev, flag));
791 
792 	if (fd->sf_iodev)
793 		return (0);
794 	if (flag & NSC_NOBLOCK)
795 		return (EAGAIN);
796 
797 	fd->sf_pend = _NSC_OPEN;
798 	fd->sf_lbolt = nsc_lbolt();
799 
800 	mutex_exit(&dev->nsc_lock);
801 
802 	rc = _nsc_open_fn(fd, flag);
803 
804 	mutex_enter(&dev->nsc_lock);
805 	fd->sf_pend = 0;
806 
807 	if (!rc)
808 		fd->sf_iodev->si_pend = 0;
809 
810 	if (dev->nsc_wait || dev->nsc_refcnt <= 0)
811 		cv_broadcast(&dev->nsc_cv);
812 
813 	return (rc ? rc : ERESTART);
814 }
815 
816 
817 /*
818  * static int
819  * _nsc_open_fn (nsc_fd_t *fd, int flag)
820  *	Allocate I/O device and open file descriptor.
821  *
822  * Calling/Exit State:
823  *	No locks may be held across this function.
824  *
825  *	If the open succeeds an I/O device will be
826  *	attached to the file descriptor, marked as
827  *	pending and 0 returned. Otherwise, returns
828  *	an error code.
829  *
830  * Description:
831  *	Allocate an I/O device and open the specified
832  *	file descriptor.
833  */
834 static int
_nsc_open_fn(fd,flag)835 _nsc_open_fn(fd, flag)
836 nsc_fd_t *fd;
837 int flag;
838 {
839 	nsc_dev_t *dev = fd->sf_dev;
840 	nsc_iodev_t *iodev;
841 	int rc;
842 
843 	if ((rc = _nsc_alloc_iodev(dev, fd->sf_type, &iodev)) != 0)
844 		return (rc);
845 
846 	mutex_enter(&dev->nsc_lock);
847 
848 	if (iodev->si_pend) {
849 		rc = _nsc_wait_dev(dev, flag);
850 		mutex_exit(&dev->nsc_lock);
851 		_nsc_free_iodev(iodev);
852 		return (rc);
853 	}
854 
855 	iodev->si_pend = _NSC_OPEN;
856 	mutex_exit(&dev->nsc_lock);
857 
858 	rc = (*iodev->si_io->open)(dev->nsc_path,
859 			(fd->sf_flag & ~NSC_RDWR), &fd->sf_cd, iodev);
860 
861 	if (rc) {
862 		iodev->si_pend = 0;
863 		_nsc_free_iodev(iodev);
864 		return (rc);
865 	}
866 
867 	/* save away the DevMaj and DevMin values */
868 	if (iodev->si_io->id == NSC_RAW_ID) {
869 		rc = _nsc_setval(dev, NULL, NSC_DEVMAJ,
870 		    (int)getmajor((dev_t)fd->sf_cd), FALSE);
871 #ifdef DEBUG
872 		if (rc != 1) {
873 			cmn_err(CE_NOTE, "!nsctl: could not set DevMaj (%s:%x)",
874 			    dev->nsc_path, (int)getmajor((dev_t)fd->sf_cd));
875 		}
876 #endif
877 
878 		rc = _nsc_setval(dev, NULL, NSC_DEVMIN,
879 		    (int)getminor((dev_t)fd->sf_cd), FALSE);
880 #ifdef DEBUG
881 		if (rc != 1) {
882 			cmn_err(CE_NOTE, "!nsctl: could not set DevMin (%s:%x)",
883 			    dev->nsc_path, (int)getminor((dev_t)fd->sf_cd));
884 		}
885 #endif
886 	}
887 
888 	fd->sf_iodev = iodev;
889 	_nsc_relink_fd(fd, &dev->nsc_close, &iodev->si_open, iodev);
890 
891 	return (0);
892 }
893 
894 
895 /*
896  * int
897  * nsc_close (nsc_fd_t *fd)
898  *	Close file descriptor for pathname.
899  *
900  * Calling/Exit State:
901  *	Returns 0 if close succeeds, otherwise returns error
902  *	code.
903  *
904  * Description:
905  *	Close the specified file descriptor. It is assumed
906  *	that all other users of this file descriptor have
907  *	finished. Any reserve will be discarded before the
908  *	close is performed.
909  */
910 int
nsc_close(fd)911 nsc_close(fd)
912 nsc_fd_t *fd;
913 {
914 	int rc;
915 
916 	if (!fd)
917 		return (0);
918 
919 	while (fd->sf_reserve)
920 		nsc_release(fd);
921 
922 	mutex_enter(&fd->sf_dev->nsc_lock);
923 
924 	fd->sf_owner = NULL;
925 
926 	while ((rc = _nsc_close_fd(fd, 0)) != 0)
927 		if (rc != ERESTART)
928 			break;
929 
930 	nsc_decode_param(_nsc_fd_def, _nsc_fd_def, (long *)fd);
931 
932 	mutex_exit(&fd->sf_dev->nsc_lock);
933 
934 	if (!rc)
935 		_nsc_free_fd(fd);
936 	return (rc);
937 }
938 
939 
940 /*
941  * int
942  * _nsc_close_fd (nsc_fd_t *fd, int flag)
943  *	Close file descriptor.
944  *
945  * Calling/Exit State:
946  *	The device lock must be held across calls to
947  *	this function.
948  *
949  *	Returns 0 if the close succeeds, otherwise
950  *	returns an error code.
951  *
952  * Description:
953  *	Close the specified file descriptor.
954  */
955 int
_nsc_close_fd(fd,flag)956 _nsc_close_fd(fd, flag)
957 nsc_fd_t *fd;
958 int flag;
959 {
960 	nsc_dev_t *dev = fd->sf_dev;
961 	nsc_iodev_t *iodev;
962 	int rc;
963 
964 	if (fd->sf_pend) {
965 		if (fd->sf_pend == _NSC_CLOSE && dev->nsc_reopen != 0)
966 			return (-ERESTART);
967 
968 		return (_nsc_wait_dev(dev, flag));
969 	}
970 
971 	flag |= NSC_RDWR;
972 	iodev = fd->sf_iodev;
973 
974 	if (!iodev)
975 		return (0);
976 
977 	if ((rc = _nsc_detach_fd(fd, flag)) != 0)
978 		return (rc);
979 
980 	if (iodev->si_pend)
981 		return (_nsc_wait_dev(dev, flag));
982 
983 	if (iodev->si_open == fd && !fd->sf_next) {
984 		if ((rc = _nsc_detach_iodev(iodev, NULL, flag)) != 0)
985 			return (rc);
986 
987 		if (dev->nsc_list == iodev && !iodev->si_next)
988 			if ((rc = _nsc_detach_dev(dev, NULL, flag)) != 0)
989 				return (rc);
990 	}
991 
992 	if (flag & NSC_NOBLOCK)
993 		return (EAGAIN);
994 
995 	fd->sf_pend = _NSC_CLOSE;
996 	iodev->si_pend = _NSC_CLOSE;
997 	mutex_exit(&dev->nsc_lock);
998 
999 	rc = _nsc_close_fn(fd);
1000 
1001 	mutex_enter(&dev->nsc_lock);
1002 	fd->sf_pend = 0;
1003 
1004 	fd->sf_reopen = 0;
1005 	if (rc)
1006 		iodev->si_pend = 0;
1007 
1008 	if (dev->nsc_wait || dev->nsc_refcnt <= 0)
1009 		cv_broadcast(&dev->nsc_cv);
1010 
1011 	return (rc ? rc : ERESTART);
1012 }
1013 
1014 
1015 /*
1016  * static int
1017  * _nsc_close_fn (nsc_fd_t *fd)
1018  *	Close file descriptor and free I/O device.
1019  *
1020  * Calling/Exit State:
1021  *	No locks may be held across this function.
1022  *
1023  *	Returns 0 if the close succeeds, otherwise
1024  *	returns an error code.
1025  *
1026  *	If the close succeeds the I/O device will be
1027  *	detached from the file descriptor, released
1028  *	and 0 returned. Otherwise, returns an error
1029  *	code.
1030  *
1031  * Description:
1032  *	Close the specified file descriptor and free
1033  *	the I/O device.
1034  */
1035 static int
_nsc_close_fn(fd)1036 _nsc_close_fn(fd)
1037 nsc_fd_t *fd;
1038 {
1039 	nsc_iodev_t *iodev = fd->sf_iodev;
1040 	nsc_dev_t *dev = fd->sf_dev;
1041 	int last, rc;
1042 
1043 	last = (iodev->si_open == fd && !fd->sf_next);
1044 
1045 	if (last || (iodev->si_io->flag & NSC_REFCNT))
1046 		if ((rc = (*iodev->si_io->close)(fd->sf_cd)) != 0)
1047 			return (rc);
1048 
1049 	fd->sf_iodev = NULL;
1050 	_nsc_relink_fd(fd, &iodev->si_open, &dev->nsc_close, iodev);
1051 
1052 	iodev->si_pend = 0;
1053 	_nsc_free_iodev(iodev);
1054 
1055 	return (0);
1056 }
1057 
1058 
1059 /*
1060  * void
1061  * nsc_set_owner (nsc_fd_t *fd, nsc_iodev_t *iodev)
1062  *	Set owner associated with file descriptor.
1063  *
1064  * Calling/Exit State:
1065  *	Sets the owner field in the file descriptor.
1066  */
1067 void
nsc_set_owner(nsc_fd_t * fd,nsc_iodev_t * iodev)1068 nsc_set_owner(nsc_fd_t *fd, nsc_iodev_t *iodev)
1069 {
1070 	if (fd) {
1071 		mutex_enter(&fd->sf_dev->nsc_lock);
1072 		fd->sf_owner = iodev;
1073 		mutex_exit(&fd->sf_dev->nsc_lock);
1074 	}
1075 }
1076 
1077 
1078 /*
1079  * char *
1080  * nsc_pathname (nsc_fd_t *fd)
1081  *	Pathname associated with file descriptor.
1082  *
1083  * Calling/Exit State:
1084  *	Returns a pointer to the pathname associated
1085  *	with the given file descriptor.
1086  */
1087 char *
nsc_pathname(fd)1088 nsc_pathname(fd)
1089 nsc_fd_t *fd;
1090 {
1091 	return ((fd) ? (fd->sf_dev->nsc_path) : 0);
1092 }
1093 
1094 
1095 /*
1096  * int
1097  * nsc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path)
1098  *	Compare fd to pathname and hash
1099  *
1100  * Calling/Exit State:
1101  *	Returns comparison value like strcmp(3C).
1102  *
1103  * Description:
1104  *	Does an optimised comparison of the pathname and associated hash
1105  *	value (as returned from nsc_strhash()) against the pathname of
1106  *	the filedescriptor, fd.
1107  */
1108 int
nsc_fdpathcmp(nsc_fd_t * fd,uint64_t phash,char * path)1109 nsc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path)
1110 {
1111 	int rc = -1;
1112 
1113 	if (fd != NULL && fd->sf_dev->nsc_phash == phash)
1114 		rc = strcmp(fd->sf_dev->nsc_path, path);
1115 
1116 	return (rc);
1117 }
1118 
1119 
1120 static int
_nsc_setval(nsc_dev_t * dev,char * path,char * name,int val,int do_ncall)1121 _nsc_setval(nsc_dev_t *dev, char *path, char *name, int val, int do_ncall)
1122 {
1123 	nsc_devval_t *dv;
1124 	nsc_rval_t *rval;
1125 	ncall_t *ncall;
1126 	nsc_val_t *vp;
1127 	uint64_t phash;
1128 	char *pp;
1129 	int rc;
1130 
1131 	ASSERT(dev != NULL || path != NULL);
1132 #ifdef DEBUG
1133 	if (dev != NULL && path != NULL) {
1134 		ASSERT(strcmp(dev->nsc_path, path) == 0);
1135 	}
1136 #endif
1137 
1138 	pp = (dev != NULL) ? dev->nsc_path : path;
1139 
1140 	if (strlen(name) >= NSC_SETVAL_MAX) {
1141 #ifdef DEBUG
1142 		cmn_err(CE_WARN, "!nsc_setval: max name size(%d) exceeded(%d)",
1143 		    NSC_SETVAL_MAX-1, (int)strlen(name));
1144 #endif
1145 		return (0);
1146 	}
1147 
1148 	phash = nsc_strhash(pp);
1149 
1150 	mutex_enter(&_nsc_devval_lock);
1151 
1152 	if (dev != NULL)
1153 		dv = dev->nsc_values;
1154 	else {
1155 		for (dv = _nsc_devval_top; dv != NULL; dv = dv->dv_next) {
1156 			if (phash == dv->dv_phash &&
1157 			    strcmp(pp, dv->dv_path) == 0)
1158 				/* found dv for device */
1159 				break;
1160 		}
1161 	}
1162 
1163 	if (dv == NULL) {
1164 		dv = nsc_kmem_zalloc(sizeof (*dv), KM_SLEEP, _nsc_local_mem);
1165 		if (dv == NULL) {
1166 			mutex_exit(&_nsc_devval_lock);
1167 			return (0);
1168 		}
1169 
1170 		(void) strncpy(dv->dv_path, pp, sizeof (dv->dv_path));
1171 		dv->dv_phash = phash;
1172 
1173 		dv->dv_next = _nsc_devval_top;
1174 		_nsc_devval_top = dv;
1175 		if (dev != NULL)
1176 			dev->nsc_values = dv;
1177 	}
1178 
1179 	for (vp = dv->dv_values; vp; vp = vp->sv_next) {
1180 		if (strcmp(vp->sv_name, name) == 0) {
1181 			vp->sv_value = val;
1182 			break;
1183 		}
1184 	}
1185 
1186 	if (vp == NULL) {
1187 		vp = nsc_kmem_zalloc(sizeof (*vp), KM_SLEEP, _nsc_local_mem);
1188 		if (vp != NULL) {
1189 			(void) strncpy(vp->sv_name, name, sizeof (vp->sv_name));
1190 			vp->sv_value = val;
1191 			vp->sv_next = dv->dv_values;
1192 			dv->dv_values = vp;
1193 		}
1194 	}
1195 
1196 	mutex_exit(&_nsc_devval_lock);
1197 
1198 	/*
1199 	 * phoenix: ncall the new value to the other node now.
1200 	 */
1201 
1202 	if (vp && do_ncall) {
1203 		/* CONSTCOND */
1204 		ASSERT(sizeof (nsc_rval_t) <= NCALL_DATA_SZ);
1205 
1206 		rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP,
1207 		    _nsc_local_mem);
1208 		if (rval == NULL) {
1209 			goto out;
1210 		}
1211 
1212 		rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &ncall);
1213 		if (rc == 0) {
1214 			(void) strncpy(rval->path, pp, sizeof (rval->path));
1215 			(void) strncpy(rval->name, name, sizeof (rval->name));
1216 			rval->value = val;
1217 
1218 			rc = ncall_put_data(ncall, rval, sizeof (*rval));
1219 			if (rc == 0) {
1220 				/*
1221 				 * Send synchronously and read a reply
1222 				 * so that we know that the remote
1223 				 * setval has completed before this
1224 				 * function returns and hence whilst
1225 				 * the device is still reserved on this
1226 				 * node.
1227 				 */
1228 				if (ncall_send(ncall, 0, NSC_SETVAL) == 0)
1229 					(void) ncall_read_reply(ncall, 1, &rc);
1230 			}
1231 
1232 			ncall_free(ncall);
1233 		}
1234 
1235 		nsc_kmem_free(rval, sizeof (*rval));
1236 	}
1237 
1238 out:
1239 	return (vp ? 1 : 0);
1240 }
1241 
1242 
1243 /* ARGSUSED */
1244 
1245 static void
r_nsc_setval(ncall_t * ncall,int * ap)1246 r_nsc_setval(ncall_t *ncall, int *ap)
1247 {
1248 	nsc_rval_t *rval;
1249 	int rc;
1250 
1251 	rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem);
1252 	if (rval == NULL) {
1253 		ncall_reply(ncall, ENOMEM);
1254 		return;
1255 	}
1256 
1257 	rc = ncall_get_data(ncall, rval, sizeof (*rval));
1258 	if (rc != 0) {
1259 		ncall_reply(ncall, EFAULT);
1260 		return;
1261 	}
1262 
1263 	if (_nsc_setval(NULL, rval->path, rval->name, rval->value, FALSE))
1264 		rc = 0;
1265 	else
1266 		rc = ENOMEM;
1267 
1268 	ncall_reply(ncall, rc);
1269 	nsc_kmem_free(rval, sizeof (*rval));
1270 }
1271 
1272 
1273 /* ARGSUSED */
1274 
1275 static void
r_nsc_setval_all(ncall_t * ncall,int * ap)1276 r_nsc_setval_all(ncall_t *ncall, int *ap)
1277 {
1278 	nsc_rval_t *in = NULL, *out = NULL;
1279 	nsc_devval_t *dv;
1280 	nsc_val_t *vp;
1281 	ncall_t *np;
1282 	uint64_t phash;
1283 	int rc;
1284 
1285 	/* CONSTCOND */
1286 	ASSERT(sizeof (nsc_rval_t) <= NCALL_DATA_SZ);
1287 
1288 	in = nsc_kmem_zalloc(sizeof (*in), KM_SLEEP, _nsc_local_mem);
1289 	out = nsc_kmem_zalloc(sizeof (*out), KM_SLEEP, _nsc_local_mem);
1290 	if (in == NULL || out == NULL) {
1291 		if (in != NULL) {
1292 			nsc_kmem_free(in, sizeof (*in));
1293 			in = NULL;
1294 		}
1295 		if (out != NULL) {
1296 			nsc_kmem_free(out, sizeof (*out));
1297 			out = NULL;
1298 		}
1299 		ncall_reply(ncall, ENOMEM);
1300 	}
1301 
1302 	rc = ncall_get_data(ncall, in, sizeof (*in));
1303 	if (rc != 0) {
1304 		ncall_reply(ncall, EFAULT);
1305 		return;
1306 	}
1307 
1308 	phash = nsc_strhash(in->path);
1309 
1310 	(void) strncpy(out->path, in->path, sizeof (out->path));
1311 
1312 	rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &np);
1313 	if (rc != 0) {
1314 		ncall_reply(ncall, ENOMEM);
1315 		return;
1316 	}
1317 
1318 	mutex_enter(&_nsc_devval_lock);
1319 
1320 	for (dv = _nsc_devval_top; dv; dv = dv->dv_next) {
1321 		if (dv->dv_phash == phash &&
1322 		    strcmp(dv->dv_path, in->path) == 0)
1323 			break;
1324 	}
1325 
1326 	if (dv) {
1327 		for (vp = dv->dv_values; vp; vp = vp->sv_next) {
1328 			if (strcmp(vp->sv_name, NSC_DEVMIN) == 0 ||
1329 			    strcmp(vp->sv_name, NSC_DEVMAJ) == 0) {
1330 				/* ignore the implicit DevMin/DevMaj values */
1331 				continue;
1332 			}
1333 
1334 			(void) strncpy(out->name, vp->sv_name,
1335 			    sizeof (out->name));
1336 			out->value = vp->sv_value;
1337 
1338 			rc = ncall_put_data(np, out, sizeof (*out));
1339 			if (rc == 0) {
1340 				/*
1341 				 * Send synchronously and read a reply
1342 				 * so that we know that the remote
1343 				 * setval has completed before this
1344 				 * function returns.
1345 				 */
1346 				if (ncall_send(np, 0, NSC_SETVAL) == 0)
1347 					(void) ncall_read_reply(np, 1, &rc);
1348 			}
1349 
1350 			ncall_reset(np);
1351 		}
1352 
1353 		ncall_free(np);
1354 		rc = 0;
1355 	} else {
1356 		rc = ENODEV;
1357 	}
1358 
1359 	mutex_exit(&_nsc_devval_lock);
1360 
1361 	ncall_reply(ncall, rc);
1362 
1363 	nsc_kmem_free(out, sizeof (*out));
1364 	nsc_kmem_free(in, sizeof (*in));
1365 }
1366 
1367 
1368 /*
1369  * int
1370  * nsc_setval (nsc_fd_t *fd, char *name, int val)
1371  *	Set value for device.
1372  *
1373  * Calling/Exit State:
1374  *	Returns 1 if the value has been set, otherwise 0.
1375  *	Must be called with the fd reserved.
1376  *
1377  * Description:
1378  *	Sets the specified global variable for the device
1379  *	to the value provided.
1380  */
1381 int
nsc_setval(nsc_fd_t * fd,char * name,int val)1382 nsc_setval(nsc_fd_t *fd, char *name, int val)
1383 {
1384 	if (!fd)
1385 		return (0);
1386 
1387 	if (!nsc_held(fd))
1388 		return (0);
1389 
1390 	return (_nsc_setval(fd->sf_dev, NULL, name, val, TRUE));
1391 }
1392 
1393 
1394 /*
1395  * int
1396  * nsc_getval (nsc_fd_t *fd, char *name, int *vp)
1397  *	Get value from device.
1398  *
1399  * Calling/Exit State:
1400  *	Returns 1 if the value has been found, otherwise 0.
1401  *	Must be called with the fd reserved, except for "DevMaj" / "DevMin".
1402  *
1403  * Description:
1404  *	Finds the value of the specified device variable for
1405  *	the device and returns it in the location pointed to
1406  *	by vp.
1407  */
1408 int
nsc_getval(nsc_fd_t * fd,char * name,int * vp)1409 nsc_getval(nsc_fd_t *fd, char *name, int *vp)
1410 {
1411 	nsc_devval_t *dv;
1412 	nsc_val_t *val;
1413 
1414 	if (!fd)
1415 		return (0);
1416 
1417 	/*
1418 	 * Don't check for nsc_held() for the device number values
1419 	 * since these are magically created and cannot change when
1420 	 * the fd is not reserved.
1421 	 */
1422 
1423 	if (strcmp(name, NSC_DEVMAJ) != 0 &&
1424 	    strcmp(name, NSC_DEVMIN) != 0 &&
1425 	    !nsc_held(fd))
1426 		return (0);
1427 
1428 	mutex_enter(&_nsc_devval_lock);
1429 
1430 	dv = fd->sf_dev->nsc_values;
1431 	val = NULL;
1432 
1433 	if (dv != NULL) {
1434 		for (val = dv->dv_values; val; val = val->sv_next) {
1435 			if (strcmp(val->sv_name, name) == 0) {
1436 				*vp = val->sv_value;
1437 				break;
1438 			}
1439 		}
1440 	}
1441 
1442 	mutex_exit(&_nsc_devval_lock);
1443 
1444 	return (val ? 1 : 0);
1445 }
1446 
1447 
1448 /*
1449  * char *
1450  * nsc_shared (nsc_fd_t *fd)
1451  *	Device is currently shared.
1452  *
1453  * Calling/Exit State:
1454  *	The device lock must be held across calls to this
1455  *	this function.
1456  *
1457  *	Returns an indication of whether the device accessed
1458  *	by the file descriptor is currently referenced by more
1459  *	than one user.
1460  *
1461  *	This is only intended for use in performance critical
1462  *	situations.
1463  */
1464 int
nsc_shared(fd)1465 nsc_shared(fd)
1466 nsc_fd_t *fd;
1467 {
1468 	nsc_iodev_t *iodev;
1469 	int cnt = 0;
1470 
1471 	if (!fd)
1472 		return (0);
1473 	if (!fd->sf_iodev)
1474 		return (1);
1475 
1476 	for (iodev = fd->sf_dev->nsc_list; iodev; iodev = iodev->si_next)
1477 		for (fd = iodev->si_open; fd; fd = fd->sf_next)
1478 			if (!fd->sf_owner && cnt++)
1479 				return (1);
1480 
1481 	return (0);
1482 }
1483 
1484 
1485 /*
1486  * kmutex_t *
1487  * nsc_lock_addr (nsc_fd_t *fd)
1488  *	Address of device lock.
1489  *
1490  * Calling/Exit State:
1491  *	Returns a pointer to the spin lock associated with the
1492  *	device.
1493  *
1494  * Description:
1495  *	This is only intended for use in performance critical
1496  *	situations in conjunction with nsc_reserve_lk.
1497  */
1498 kmutex_t *
nsc_lock_addr(fd)1499 nsc_lock_addr(fd)
1500 nsc_fd_t *fd;
1501 {
1502 	return (&fd->sf_dev->nsc_lock);
1503 }
1504 
1505 
1506 /*
1507  * int
1508  * _nsc_call_io (long f, blind_t a, blind_t b, blind_t c)
1509  *	Call information function.
1510  *
1511  * Calling/Exit State:
1512  *	Returns result from function or 0 if not available.
1513  *	f represents the offset into the I/O structure at which
1514  *	the required function can be found and a, b, c are the
1515  *	desired arguments.
1516  *
1517  * Description:
1518  *	Calls the requested function for the first available
1519  *	cache interface.
1520  */
1521 int
_nsc_call_io(long f,blind_t a,blind_t b,blind_t c)1522 _nsc_call_io(long f, blind_t a, blind_t b, blind_t c)
1523 {
1524 	nsc_io_t *io;
1525 	int (*fn)();
1526 	int rc;
1527 
1528 	io = _nsc_reserve_io(NULL, NSC_SDBC_ID);
1529 	if (!io)
1530 		io = _nsc_reserve_io(NULL, NSC_NULL);
1531 
1532 	fn = (blindfn_t)(((long *)io)[f]);
1533 	rc = (*fn)(a, b, c);
1534 
1535 	_nsc_release_io(io);
1536 	return (rc);
1537 }
1538 
1539 
1540 /*
1541  * nsc_io_t *
1542  * _nsc_reserve_io (char *, int type)
1543  *	Reserve I/O module.
1544  *
1545  * Calling/Exit State:
1546  *	Returns address of I/O structure matching specified
1547  *	type, or NULL.
1548  *
1549  * Description:
1550  *	Searches for an appropriate I/O module and increments
1551  *	the reference count to prevent it being unregistered.
1552  */
1553 nsc_io_t *
_nsc_reserve_io(path,type)1554 _nsc_reserve_io(path, type)
1555 char *path;
1556 int type;
1557 {
1558 	nsc_io_t *io;
1559 
1560 	mutex_enter(&_nsc_io_lock);
1561 
1562 	if ((io = _nsc_find_io(path, type, NULL)) != 0)
1563 		io->refcnt++;
1564 
1565 	mutex_exit(&_nsc_io_lock);
1566 	return (io);
1567 }
1568 
1569 
1570 /*
1571  * static nsc_io_t *
1572  * _nsc_find_io (char *path, int type, int *changed)
1573  *	Find I/O module.
1574  *
1575  * Calling/Exit State:
1576  *	The _nsc_io_lock must be held across calls to
1577  *	this function.
1578  *
1579  *	Returns address of I/O structure matching specified
1580  *	type, or NULL.
1581  *
1582  *	'changed' will be set to non-zero if there is a pending
1583  *	nsc_path_t that matches the criteria for the requested type.
1584  *	This allows nsctl to distinguish between multiple
1585  *	nsc_register_path's done by the same I/O provider.
1586  *
1587  * Description:
1588  *	Searches for an appropriate I/O module.
1589  *
1590  *	1.  If <type> is a single module id find the specified I/O
1591  *	    module by module id.
1592  *
1593  *	2.  Find the highest module that provides any of the I/O types
1594  *	    included in <type>, taking into account any modules
1595  *	    registered via the nsc_register_path() interface if <path>
1596  *	    is non-NULL.
1597  *
1598  *	3.  Find an I/O module following the rules in (2), but whose
1599  *	    module id is less than the id OR'd into <type>.
1600  *
1601  *	If no module is found by the above algorithms and NSC_NULL was
1602  *	included in <type>, return the _nsc_null_io module. Otherwise
1603  *	return NULL.
1604  */
1605 static nsc_io_t *
_nsc_find_io(char * path,int type,int * changed)1606 _nsc_find_io(char *path, int type, int *changed)
1607 {
1608 	nsc_path_t *sp = NULL;
1609 	nsc_path_t *pp = NULL;
1610 	nsc_io_t *io;
1611 
1612 	type &= NSC_TYPES;
1613 
1614 	if (path) {
1615 		for (sp = _nsc_path_top; sp; sp = sp->sp_next) {
1616 			if ((type & NSC_ID) &&
1617 			    sp->sp_io->id >= (type & NSC_IDS))
1618 				continue;
1619 
1620 			if (sp->sp_pend || (type & sp->sp_type) == 0)
1621 				continue;
1622 
1623 			if (nsc_strmatch(path, sp->sp_path))
1624 				break;
1625 		}
1626 
1627 		if (sp) {
1628 			/* look for matching pending paths */
1629 			for (pp = _nsc_path_top; pp; pp = pp->sp_next) {
1630 				if (pp->sp_pend &&
1631 				    (type & pp->sp_type) &&
1632 				    nsc_strmatch(path, pp->sp_path)) {
1633 					break;
1634 				}
1635 			}
1636 		}
1637 	}
1638 
1639 	for (io = _nsc_io_top; io; io = io->next) {
1640 		if (io->pend)
1641 			continue;
1642 
1643 		if (type & NSC_ID) {
1644 			if ((type & ~NSC_IDS) == 0) {
1645 				if (io->id == type)
1646 					break;
1647 				continue;
1648 			}
1649 
1650 			if (io->id >= (type & NSC_IDS))
1651 				continue;
1652 		}
1653 
1654 		if (io->provide & type)
1655 			break;
1656 	}
1657 
1658 	if (pp && (!io || pp->sp_io->id >= io->id)) {
1659 		/*
1660 		 * Mark this as a path change.
1661 		 */
1662 		if (changed) {
1663 			*changed = 1;
1664 		}
1665 	}
1666 
1667 	if (sp && (!io || sp->sp_io->id >= io->id))
1668 		io = sp->sp_io;
1669 
1670 	if (!io && !(type & NSC_NULL))
1671 		return (NULL);
1672 
1673 	if (!io)
1674 		io = _nsc_null_io;
1675 
1676 	return (io);
1677 }
1678 
1679 
1680 /*
1681  * void
1682  * _nsc_release_io (nsc_io_t *)
1683  *	Release I/O module.
1684  *
1685  * Description:
1686  *	Releases reference to I/O structure and wakes up
1687  *	anybody waiting on it.
1688  */
1689 void
_nsc_release_io(io)1690 _nsc_release_io(io)
1691 nsc_io_t *io;
1692 {
1693 	mutex_enter(&_nsc_io_lock);
1694 
1695 	io->refcnt--;
1696 	cv_broadcast(&io->cv);
1697 
1698 	mutex_exit(&_nsc_io_lock);
1699 }
1700 
1701 
1702 /*
1703  * static int
1704  * _nsc_alloc_fd (char *path, int type, int flag, nsc_fd_t **fdp)
1705  *	Allocate file descriptor structure.
1706  *
1707  * Calling/Exit State:
1708  *	Stores address of file descriptor through fdp and
1709  *	returns 0 on success, otherwise returns error code.
1710  *
1711  * Description:
1712  *	A new file descriptor is allocated and linked in to
1713  *	the file descriptor chain which is protected by the
1714  *	device lock.
1715  *
1716  *	On return the file descriptor must contain all the
1717  *	information necessary to perform an open. Details
1718  *	specific to user callbacks are not required yet.
1719  */
1720 static int
_nsc_alloc_fd(path,type,flag,fdp)1721 _nsc_alloc_fd(path, type, flag, fdp)
1722 char *path;
1723 int type, flag;
1724 nsc_fd_t **fdp;
1725 {
1726 	nsc_dev_t *dev;
1727 	nsc_fd_t *fd;
1728 	int rc;
1729 
1730 	if (!(fd = (nsc_fd_t *)nsc_kmem_zalloc(
1731 				sizeof (*fd), KM_SLEEP, _nsc_local_mem)))
1732 		return (ENOMEM);
1733 
1734 	if ((rc = _nsc_alloc_dev(path, &dev)) != 0) {
1735 		nsc_kmem_free(fd, sizeof (*fd));
1736 		return (rc);
1737 	}
1738 
1739 	mutex_enter(&dev->nsc_lock);
1740 
1741 	fd->sf_type = type;
1742 	fd->sf_flag = flag;
1743 	fd->sf_dev = dev;
1744 	fd->sf_next = dev->nsc_close;
1745 	dev->nsc_close = fd;
1746 
1747 	mutex_exit(&dev->nsc_lock);
1748 
1749 	*fdp = fd;
1750 	return (0);
1751 }
1752 
1753 
1754 /*
1755  * static int
1756  * _nsc_free_fd (nsc_fd_t *)
1757  *	Free file descriptor.
1758  *
1759  * Description:
1760  *	The file descriptor is removed from the chain and free'd
1761  *	once pending activity has completed.
1762  */
1763 static void
_nsc_free_fd(fd)1764 _nsc_free_fd(fd)
1765 nsc_fd_t *fd;
1766 {
1767 	nsc_dev_t *dev = fd->sf_dev;
1768 	nsc_fd_t **fdp;
1769 
1770 	if (!fd)
1771 		return;
1772 
1773 	mutex_enter(&dev->nsc_lock);
1774 
1775 	for (fdp = &dev->nsc_close; *fdp; fdp = &(*fdp)->sf_next)
1776 		if (*fdp == fd) {
1777 			*fdp = fd->sf_next;
1778 			break;
1779 		}
1780 
1781 	if (dev->nsc_wait || dev->nsc_refcnt <= 0)
1782 		cv_broadcast(&dev->nsc_cv);
1783 
1784 	while (fd->sf_pend)
1785 		(void) _nsc_wait_dev(dev, 0);
1786 
1787 	mutex_exit(&dev->nsc_lock);
1788 
1789 	_nsc_free_dev(dev);
1790 
1791 	nsc_kmem_free(fd, sizeof (*fd));
1792 }
1793 
1794 
1795 /*
1796  * static void
1797  * _nsc_relink_fd (nsc_fd_t *fd, nsc_fd_t **from,
1798  *				nsc_fd_t **to, nsc_iodev_t *iodev)
1799  *	Relink file descriptor.
1800  *
1801  * Description:
1802  *	Remove the file descriptor from the 'from' chain and
1803  *	add it to the 'to' chain. The busy flag in iodev is
1804  *	used to prevent modifications to the chain whilst a
1805  *	callback is in progress.
1806  */
1807 static void
_nsc_relink_fd(nsc_fd_t * fd,nsc_fd_t ** from,nsc_fd_t ** to,nsc_iodev_t * iodev)1808 _nsc_relink_fd(nsc_fd_t *fd, nsc_fd_t **from, nsc_fd_t **to, nsc_iodev_t *iodev)
1809 {
1810 	nsc_dev_t *dev = fd->sf_dev;
1811 	nsc_fd_t **fdp;
1812 
1813 	mutex_enter(&dev->nsc_lock);
1814 
1815 	while (iodev->si_busy)
1816 		(void) _nsc_wait_dev(dev, 0);
1817 
1818 	for (fdp = from; *fdp; fdp = &(*fdp)->sf_next)
1819 		if (*fdp == fd) {
1820 			*fdp = fd->sf_next;
1821 			break;
1822 		}
1823 
1824 	fd->sf_next = (*to);
1825 	(*to) = fd;
1826 
1827 	mutex_exit(&dev->nsc_lock);
1828 }
1829 
1830 
1831 /*
1832  * static int
1833  * _nsc_alloc_iodev (nsc_dev_t *dev, int type, nsc_iodev_t **iodevp)
1834  *	Allocate I/O device structure.
1835  *
1836  * Calling/Exit State:
1837  *	Stores address of I/O device structure through iodevp
1838  *	and returns 0 on success, otherwise returns error code.
1839  *
1840  * Description:
1841  *	If an entry for the I/O device already exists increment
1842  *	the reference count and return the address, otherwise
1843  *	allocate a new structure.
1844  *
1845  *	A new structure is allocated before scanning the chain
1846  *	to avoid calling the memory allocator with a spin lock
1847  *	held. If an entry is found the new structure is free'd.
1848  *
1849  *	The I/O device chain is protected by the device lock.
1850  */
1851 static int
_nsc_alloc_iodev(dev,type,iodevp)1852 _nsc_alloc_iodev(dev, type, iodevp)
1853 nsc_dev_t *dev;
1854 int type;
1855 nsc_iodev_t **iodevp;
1856 {
1857 	nsc_iodev_t *iodev, *ip;
1858 	nsc_io_t *io;
1859 
1860 	if (!(iodev = (nsc_iodev_t *)nsc_kmem_zalloc(
1861 				sizeof (*iodev), KM_SLEEP, _nsc_local_mem)))
1862 		return (ENOMEM);
1863 
1864 	mutex_init(&iodev->si_lock, NULL, MUTEX_DRIVER, NULL);
1865 	cv_init(&iodev->si_cv, NULL, CV_DRIVER, NULL);
1866 
1867 	if (!(io = _nsc_reserve_io(dev->nsc_path, type))) {
1868 		mutex_destroy(&iodev->si_lock);
1869 		cv_destroy(&iodev->si_cv);
1870 		nsc_kmem_free(iodev, sizeof (*iodev));
1871 		return (ENXIO);
1872 	}
1873 
1874 	iodev->si_refcnt++;
1875 	iodev->si_io = io;
1876 	iodev->si_dev = dev;
1877 
1878 	mutex_enter(&_nsc_io_lock);
1879 	dev->nsc_refcnt++;
1880 	mutex_exit(&_nsc_io_lock);
1881 
1882 	mutex_enter(&dev->nsc_lock);
1883 
1884 	for (ip = dev->nsc_list; ip; ip = ip->si_next)
1885 		if (ip->si_io == io) {
1886 			ip->si_refcnt++;
1887 			break;
1888 		}
1889 
1890 	if (!ip) {
1891 		iodev->si_next = dev->nsc_list;
1892 		dev->nsc_list = iodev;
1893 	}
1894 
1895 	mutex_exit(&dev->nsc_lock);
1896 
1897 	if (ip) {
1898 		_nsc_free_iodev(iodev);
1899 		iodev = ip;
1900 	}
1901 
1902 	*iodevp = iodev;
1903 	return (0);
1904 }
1905 
1906 
1907 /*
1908  * static int
1909  * _nsc_free_iodev (nsc_iodev_t *iodev)
1910  *	Free I/O device structure.
1911  *
1912  * Description:
1913  *	Decrements the reference count of a previously allocated
1914  *	I/O device structure. If this is the last reference it
1915  *	is removed from the device chain and free'd once pending
1916  *	activity has completed.
1917  */
1918 static void
_nsc_free_iodev(nsc_iodev_t * iodev)1919 _nsc_free_iodev(nsc_iodev_t *iodev)
1920 {
1921 	nsc_iodev_t **ipp;
1922 	nsc_dev_t *dev;
1923 
1924 	if (!iodev)
1925 		return;
1926 
1927 	dev = iodev->si_dev;
1928 
1929 	mutex_enter(&dev->nsc_lock);
1930 
1931 	if (--iodev->si_refcnt > 0) {
1932 		mutex_exit(&dev->nsc_lock);
1933 		return;
1934 	}
1935 
1936 	for (ipp = &dev->nsc_list; *ipp; ipp = &(*ipp)->si_next)
1937 		if (*ipp == iodev) {
1938 			*ipp = iodev->si_next;
1939 			break;
1940 		}
1941 
1942 	if (dev->nsc_wait || dev->nsc_refcnt <= 0)
1943 		cv_broadcast(&dev->nsc_cv);
1944 
1945 	while (iodev->si_pend || iodev->si_rpend || iodev->si_busy)
1946 		(void) _nsc_wait_dev(dev, 0);
1947 
1948 	mutex_exit(&dev->nsc_lock);
1949 
1950 	_nsc_release_io(iodev->si_io);
1951 	_nsc_free_dev(dev);
1952 
1953 	mutex_destroy(&iodev->si_lock);
1954 	cv_destroy(&iodev->si_cv);
1955 
1956 	nsc_kmem_free(iodev, sizeof (*iodev));
1957 }
1958 
1959 
1960 /*
1961  * static int
1962  * _nsc_alloc_dev (char *path, nsc_dev_t **devp)
1963  *	Allocate device structure.
1964  *
1965  * Calling/Exit State:
1966  *	Stores address of device structure through devp
1967  *	and returns 0 on success, otherwise returns error
1968  *	code.
1969  *
1970  * Description:
1971  *	If an entry for the device already exists increment
1972  *	the reference count and return the address, otherwise
1973  *	allocate a new structure.
1974  *
1975  *	A new structure is allocated before scanning the device
1976  *	chain to avoid calling the memory allocator with a spin
1977  *	lock held. If the device is found the new structure is
1978  *	free'd.
1979  *
1980  *	The device chain is protected by _nsc_io_lock.
1981  */
1982 static int
_nsc_alloc_dev(char * path,nsc_dev_t ** devp)1983 _nsc_alloc_dev(char *path, nsc_dev_t **devp)
1984 {
1985 	nsc_dev_t *dev, *dp, **ddp;
1986 	nsc_devval_t *dv;
1987 	nsc_rval_t *rval;
1988 	ncall_t *ncall;
1989 	int rc;
1990 
1991 	if (!(dev = (nsc_dev_t *)nsc_kmem_zalloc(
1992 	    sizeof (*dev), KM_SLEEP, _nsc_local_mem)))
1993 		return (ENOMEM);
1994 
1995 	dev->nsc_refcnt++;
1996 
1997 	mutex_init(&dev->nsc_lock, NULL, MUTEX_DRIVER, NULL);
1998 	cv_init(&dev->nsc_cv, NULL, CV_DRIVER, NULL);
1999 
2000 	dev->nsc_phash = nsc_strhash(path);
2001 	dev->nsc_path = nsc_strdup(path);
2002 
2003 	mutex_enter(&_nsc_io_lock);
2004 
2005 	dev->nsc_next = _nsc_dev_pend;
2006 	_nsc_dev_pend = dev;
2007 
2008 	mutex_exit(&_nsc_io_lock);
2009 
2010 	mutex_enter(&_nsc_io_lock);
2011 
2012 	for (dp = _nsc_dev_top; dp; dp = dp->nsc_next)
2013 		if (dp->nsc_phash == dev->nsc_phash &&
2014 		    strcmp(dp->nsc_path, dev->nsc_path) == 0) {
2015 			dp->nsc_refcnt++;
2016 			break;
2017 		}
2018 
2019 	if (!dp) {
2020 		for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next)
2021 			if (*ddp == dev) {
2022 				*ddp = dev->nsc_next;
2023 				break;
2024 			}
2025 
2026 		dev->nsc_next = _nsc_dev_top;
2027 		_nsc_dev_top = dev;
2028 	}
2029 
2030 	mutex_exit(&_nsc_io_lock);
2031 
2032 	if (dp) {
2033 		_nsc_free_dev(dev);
2034 		dev = dp;
2035 	}
2036 
2037 	/*
2038 	 * Try and find the device/values header for this device
2039 	 * and link it back to the device structure.
2040 	 */
2041 
2042 	mutex_enter(&_nsc_devval_lock);
2043 
2044 	if (dev->nsc_values == NULL) {
2045 		for (dv = _nsc_devval_top; dv; dv = dv->dv_next) {
2046 			if (dv->dv_phash == dev->nsc_phash &&
2047 			    strcmp(dv->dv_path, dev->nsc_path) == 0) {
2048 				dev->nsc_values = dv;
2049 				break;
2050 			}
2051 		}
2052 	}
2053 
2054 	mutex_exit(&_nsc_devval_lock);
2055 
2056 	/*
2057 	 * Refresh the device/values from the other node
2058 	 */
2059 
2060 	rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem);
2061 	if (rval == NULL) {
2062 		goto out;
2063 	}
2064 
2065 	rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &ncall);
2066 	if (rc == 0) {
2067 		(void) strncpy(rval->path, path, sizeof (rval->path));
2068 
2069 		rc = ncall_put_data(ncall, rval, sizeof (*rval));
2070 		if (rc == 0) {
2071 			/*
2072 			 * Send synchronously and read a reply
2073 			 * so that we know that the updates
2074 			 * have completed before this
2075 			 * function returns.
2076 			 */
2077 			if (ncall_send(ncall, 0, NSC_SETVAL_ALL) == 0)
2078 				(void) ncall_read_reply(ncall, 1, &rc);
2079 		}
2080 
2081 		ncall_free(ncall);
2082 	}
2083 
2084 	nsc_kmem_free(rval, sizeof (*rval));
2085 
2086 out:
2087 	*devp = dev;
2088 	return (0);
2089 }
2090 
2091 
2092 /*
2093  * static void
2094  * _nsc_free_dev (nsc_dev_t *dev)
2095  *	Free device structure.
2096  *
2097  * Description:
2098  *	Decrements the reference count of a previously allocated
2099  *	device structure. If this is the last reference it is
2100  *	removed from the device chain and free'd once pending
2101  *	activity has completed.
2102  *
2103  *	Whilst waiting for pending activity to cease the device is
2104  *	relinked onto the pending chain.
2105  */
2106 static void
_nsc_free_dev(dev)2107 _nsc_free_dev(dev)
2108 nsc_dev_t *dev;
2109 {
2110 	nsc_dev_t **ddp;
2111 
2112 	if (!dev)
2113 		return;
2114 
2115 	mutex_enter(&_nsc_io_lock);
2116 
2117 	if (--dev->nsc_refcnt > 0) {
2118 		mutex_exit(&_nsc_io_lock);
2119 		return;
2120 	}
2121 
2122 	for (ddp = &_nsc_dev_top; *ddp; ddp = &(*ddp)->nsc_next)
2123 		if (*ddp == dev) {
2124 			*ddp = dev->nsc_next;
2125 			dev->nsc_next = _nsc_dev_pend;
2126 			_nsc_dev_pend = dev;
2127 			break;
2128 		}
2129 
2130 	mutex_exit(&_nsc_io_lock);
2131 
2132 	mutex_enter(&dev->nsc_lock);
2133 
2134 	while (dev->nsc_pend || dev->nsc_rpend || dev->nsc_wait) {
2135 		cv_wait(&dev->nsc_cv, &dev->nsc_lock);
2136 	}
2137 
2138 	mutex_exit(&dev->nsc_lock);
2139 
2140 	mutex_enter(&_nsc_io_lock);
2141 
2142 	for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next)
2143 		if (*ddp == dev) {
2144 			*ddp = dev->nsc_next;
2145 			break;
2146 		}
2147 
2148 	mutex_exit(&_nsc_io_lock);
2149 
2150 	mutex_destroy(&dev->nsc_lock);
2151 	cv_destroy(&dev->nsc_cv);
2152 	nsc_strfree(dev->nsc_path);
2153 
2154 	nsc_kmem_free(dev, sizeof (*dev));
2155 }
2156 
2157 
2158 /*
2159  * static nsc_io_t *
2160  * _nsc_alloc_io (int id, char *name, int flag)
2161  *	Allocate an I/O structure.
2162  *
2163  * Calling/Exit State:
2164  *	Returns the address of the I/O structure, or NULL.
2165  */
2166 static nsc_io_t *
_nsc_alloc_io(id,name,flag)2167 _nsc_alloc_io(id, name, flag)
2168 int id;
2169 char *name;
2170 int flag;
2171 {
2172 	nsc_io_t *io;
2173 
2174 	if (!(io = (nsc_io_t *)nsc_kmem_zalloc(
2175 			sizeof (*io), KM_NOSLEEP, _nsc_local_mem)))
2176 		return (NULL);
2177 
2178 	cv_init(&io->cv, NULL, CV_DRIVER, NULL);
2179 
2180 	io->id = id;
2181 	io->name = name;
2182 	io->flag = flag;
2183 
2184 	return (io);
2185 }
2186 
2187 
2188 /*
2189  * static void
2190  * _nsc_free_io (int id, char *name, int flag)
2191  *	Free an I/O structure.
2192  *
2193  * Calling/Exit State:
2194  *	Free the I/O structure and remove it from the chain.
2195  */
2196 static void
_nsc_free_io(io)2197 _nsc_free_io(io)
2198 nsc_io_t *io;
2199 {
2200 	nsc_io_t **iop;
2201 
2202 	mutex_enter(&_nsc_io_lock);
2203 
2204 	for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next)
2205 		if (*iop == io)
2206 			break;
2207 
2208 	if (*iop)
2209 		(*iop) = io->next;
2210 
2211 	mutex_exit(&_nsc_io_lock);
2212 
2213 	cv_destroy(&io->cv);
2214 	nsc_kmem_free(io, sizeof (*io));
2215 }
2216