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