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
52nsc_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
62nsc_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
71kmutex_t _nsc_io_lock;
72kmutex_t _nsc_devval_lock;
73
74nsc_io_t *_nsc_io_top = NULL;
75nsc_io_t *_nsc_null_io = NULL;
76nsc_dev_t *_nsc_dev_top = NULL;
77nsc_dev_t *_nsc_dev_pend = NULL;
78nsc_path_t *_nsc_path_top = NULL;
79nsc_devval_t *_nsc_devval_top = NULL;
80
81extern nsc_def_t _nsc_disk_def[];
82extern nsc_def_t _nsc_cache_def[];
83
84extern nsc_mem_t *_nsc_local_mem;
85extern nsc_rmmap_t *_nsc_global_map;
86
87static clock_t _nsc_io_lbolt;
88
89static nsc_io_t *_nsc_find_io(char *, int, int *);
90nsc_io_t *_nsc_reserve_io(char *, int);
91static nsc_io_t *_nsc_alloc_io(int, char *, int);
92
93static int _nsc_open_fn(nsc_fd_t *, int);
94static int _nsc_close_fn(nsc_fd_t *);
95static int _nsc_alloc_fd(char *, int, int, nsc_fd_t **);
96static int _nsc_alloc_iodev(nsc_dev_t *, int, nsc_iodev_t **);
97static int _nsc_alloc_dev(char *, nsc_dev_t **);
98static int _nsc_reopen_io(char *, int);
99static int _nsc_reopen_dev(nsc_dev_t *, int);
100static int _nsc_relock_dev(nsc_dev_t *, nsc_fd_t *, nsc_iodev_t *);
101static int _nsc_reopen_fd(nsc_fd_t *, int);
102static int _nsc_decode_io(nsc_def_t *, nsc_io_t *);
103
104void _nsc_release_io(nsc_io_t *);
105static void _nsc_free_fd(nsc_fd_t *);
106static void _nsc_free_iodev(nsc_iodev_t *);
107static void _nsc_free_dev(nsc_dev_t *);
108static void _nsc_free_io(nsc_io_t *);
109static void _nsc_relink_fd(nsc_fd_t *, nsc_fd_t **, nsc_fd_t **, nsc_iodev_t *);
110
111static int _nsc_setval(nsc_dev_t *, char *, char *, int, int);
112static void r_nsc_setval(ncall_t *, int *);
113static void r_nsc_setval_all(ncall_t *, int *);
114
115extern void _nsc_add_disk(nsc_io_t *);
116extern 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 */
128void
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
144void
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 */
187nsc_io_t *
188nsc_register_io(name, type, def)
189char *name;
190int type;
191nsc_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 */
256static int
257_nsc_decode_io(def, io)
258nsc_def_t *def;
259nsc_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 */
288int
289nsc_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;
310lp:
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 */
374nsc_path_t *
375nsc_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 */
424int
425nsc_unregister_path(sp, flag)
426nsc_path_t *sp;
427int 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 */
485static int
486_nsc_reopen_io(path, flag)
487char *path;
488int 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 */
536static int
537_nsc_reopen_dev(dev, flag)
538nsc_dev_t *dev;
539int 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 */
602static int
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 */
658static int
659_nsc_reopen_fd(fd, flag)
660nsc_fd_t *fd;
661int 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 */
719nsc_fd_t *
720nsc_open(path, type, def, arg, sts)
721char *path;
722int type;
723nsc_def_t *def;
724blind_t arg;
725int *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 */
781int
782_nsc_open_fd(fd, flag)
783nsc_fd_t *fd;
784int 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 */
834static int
835_nsc_open_fn(fd, flag)
836nsc_fd_t *fd;
837int 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 */
910int
911nsc_close(fd)
912nsc_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 */
955int
956_nsc_close_fd(fd, flag)
957nsc_fd_t *fd;
958int 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 */
1035static int
1036_nsc_close_fn(fd)
1037nsc_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 */
1067void
1068nsc_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 */
1087char *
1088nsc_pathname(fd)
1089nsc_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 */
1108int
1109nsc_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
1120static int
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
1238out:
1239	return (vp ? 1 : 0);
1240}
1241
1242
1243/* ARGSUSED */
1244
1245static void
1246r_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
1275static void
1276r_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 */
1381int
1382nsc_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 */
1408int
1409nsc_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 */
1464int
1465nsc_shared(fd)
1466nsc_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 */
1498kmutex_t *
1499nsc_lock_addr(fd)
1500nsc_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 */
1521int
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 */
1553nsc_io_t *
1554_nsc_reserve_io(path, type)
1555char *path;
1556int 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 */
1605static nsc_io_t *
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 */
1689void
1690_nsc_release_io(io)
1691nsc_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 */
1720static int
1721_nsc_alloc_fd(path, type, flag, fdp)
1722char *path;
1723int type, flag;
1724nsc_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 */
1763static void
1764_nsc_free_fd(fd)
1765nsc_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 */
1807static void
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 */
1851static int
1852_nsc_alloc_iodev(dev, type, iodevp)
1853nsc_dev_t *dev;
1854int type;
1855nsc_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 */
1918static void
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 */
1982static int
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
2086out:
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 */
2106static void
2107_nsc_free_dev(dev)
2108nsc_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 */
2166static nsc_io_t *
2167_nsc_alloc_io(id, name, flag)
2168int id;
2169char *name;
2170int 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 */
2196static void
2197_nsc_free_io(io)
2198nsc_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