fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/debug.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ncall/ncall.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define __NSC_GEN__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "nsc_dev.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DS_DDICT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "../contract.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "../nsctl.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NSC_DEVMIN "DevMin"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NSC_DEVMAJ "DevMaj"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define _I(x) (((long)(&((nsc_io_t *)0)->x))/sizeof (long))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define _F(x) (((long)(&((nsc_fd_t *)0)->x))/sizeof (long))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_def_t _nsc_io_def[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Open", (uintptr_t)nsc_null, _I(open),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Close", (uintptr_t)nsc_null, _I(close),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Attach", (uintptr_t)nsc_null, _I(attach),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Detach", (uintptr_t)nsc_null, _I(detach),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Flush", (uintptr_t)nsc_null, _I(flush),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Provide", 0, _I(provide),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_def_t _nsc_fd_def[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Pinned", (uintptr_t)nsc_null, _F(sf_pinned),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unpinned", (uintptr_t)nsc_null, _F(sf_unpinned),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Attach", (uintptr_t)nsc_null, _F(sf_attach),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Detach", (uintptr_t)nsc_null, _F(sf_detach),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Flush", (uintptr_t)nsc_null, _F(sf_flush),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortekmutex_t _nsc_io_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortekmutex_t _nsc_devval_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_io_t *_nsc_io_top = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_io_t *_nsc_null_io = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_dev_t *_nsc_dev_top = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_dev_t *_nsc_dev_pend = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_path_t *_nsc_path_top = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_devval_t *_nsc_devval_top = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern nsc_def_t _nsc_disk_def[];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern nsc_def_t _nsc_cache_def[];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern nsc_mem_t *_nsc_local_mem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern nsc_rmmap_t *_nsc_global_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic clock_t _nsc_io_lbolt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_io_t *_nsc_find_io(char *, int, int *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_io_t *_nsc_reserve_io(char *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_io_t *_nsc_alloc_io(int, char *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_open_fn(nsc_fd_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_close_fn(nsc_fd_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_alloc_fd(char *, int, int, nsc_fd_t **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_alloc_iodev(nsc_dev_t *, int, nsc_iodev_t **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_alloc_dev(char *, nsc_dev_t **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_reopen_io(char *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_reopen_dev(nsc_dev_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_relock_dev(nsc_dev_t *, nsc_fd_t *, nsc_iodev_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_reopen_fd(nsc_fd_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_decode_io(nsc_def_t *, nsc_io_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid _nsc_release_io(nsc_io_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _nsc_free_fd(nsc_fd_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _nsc_free_iodev(nsc_iodev_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _nsc_free_dev(nsc_dev_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _nsc_free_io(nsc_io_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _nsc_relink_fd(nsc_fd_t *, nsc_fd_t **, nsc_fd_t **, nsc_iodev_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_setval(nsc_dev_t *, char *, char *, int, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void r_nsc_setval(ncall_t *, int *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void r_nsc_setval_all(ncall_t *, int *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern void _nsc_add_disk(nsc_io_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern void _nsc_add_cache(nsc_io_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_init_dev (void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialise device subsystem.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called at driver initialisation time to allocate necessary
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data structures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_init_dev()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&_nsc_io_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&_nsc_devval_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_null_io = nsc_register_io("null", NSC_NULL, (nsc_def_t *)0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_nsc_null_io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC, "nsctl: nsc_init_dev");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_register_svc(NSC_SETVAL_ALL, r_nsc_setval_all);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_register_svc(NSC_SETVAL, r_nsc_setval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_deinit_dev()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_devval_t *dv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_val_t *vp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((dv = _nsc_devval_top) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((vp = dv->dv_values) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dv->dv_values = vp->sv_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(vp, sizeof (*vp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_devval_top = dv->dv_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(dv, sizeof (*dv));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_unregister_svc(NSC_SETVAL_ALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_unregister_svc(NSC_SETVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_register_io (char *name, int type, nsc_def_t *def)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Register an I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a token for use in future calls to nsc_unregister_io.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The ID and flags for the module are specified by 'type' and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the appropriate entry points are defined using 'def'. If
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * registration fails NULL is returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Registers an I/O module for use by subsequent calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_open.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_register_io(name, type, def)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_def_t *def;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_io_t *io, *tp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc, id, flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_io_t **iop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte id = (type & NSC_TYPES);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flag = (type & ~NSC_TYPES);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((!(id & NSC_ID) || (id & ~NSC_IDS)) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (id != NSC_NULL || _nsc_null_io))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(io = _nsc_alloc_io(id, name, flag)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _nsc_decode_io(def, io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rc && id != NSC_NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_io(io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (tp = _nsc_io_top; tp; tp = tp->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(tp->name, name) == 0 || tp->id == id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_io(io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (id >= (*iop)->id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->next = (*iop);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*iop) = io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_io_lbolt = nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((rc = _nsc_reopen_io(NULL, 0)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_decode_io (nsc_def_t *def, nsc_io_t *io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Decode I/O module definition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns TRUE if the definition contains an adequate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * description of an I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Decode the definition of an I/O module and supply
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * translation routines where possible for operations
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that are not defined.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_decode_io(def, io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_def_t *def;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_io_t *io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_decode_param(def, _nsc_io_def, (long *)io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_decode_param(def, _nsc_disk_def, (long *)io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_decode_param(def, _nsc_cache_def, (long *)io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_add_disk(io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_add_cache(io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_unregister_io (nsc_io_t *io, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Un-register an I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 on success, otherwise returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The specified I/O module is un-registered if possible.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All open file descriptors using the module will be closed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in preparation for a subsequent re-open.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If NSC_PCATCH is specified and a signal is received,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the unregister will be terminated and EINTR returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_unregister_io(nsc_io_t *io, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_path_t *sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_io_t *xio;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io == _nsc_null_io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (xio = _nsc_io_top; xio; xio = xio->next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (xio == io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!xio || io->pend) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (xio ? EALREADY : 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->pend = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortelp:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (sp = _nsc_path_top; sp; sp = sp->sp_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sp->sp_io == io) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = nsc_unregister_path(sp, flag)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->pend = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto lp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_io_lbolt = nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (io->refcnt && !rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((rc = _nsc_reopen_io(NULL, flag)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc || !io->refcnt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!cv_wait_sig(&io->cv, &_nsc_io_lock))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EINTR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We have tried to get rid of all the IO provider's clients.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are still anonymous buffers outstanding, then fail
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the unregister.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rc && io->abufcnt > 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EUSERS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->pend = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_io(io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_path_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_register_path (char *path, int type, nsc_io_t *io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Register interest in pathname.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a token for use in future calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_unregister_path. The 'path' argument can contain
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wild characters. If registration fails NULL is returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * May not be called for io providers that support NSC_ANON.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Registers an interest in any pathnames matching 'path'
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which are opened with the specified type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_path_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_register_path(char *path, int type, nsc_io_t *io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_path_t *sp, **spp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((type & NSC_IDS) || !io || (io->provide & NSC_ANON) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(sp = nsc_kmem_zalloc(sizeof (*sp), KM_SLEEP, _nsc_local_mem)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp->sp_path = nsc_strdup(path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp->sp_type = type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp->sp_io = io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io->id >= (*spp)->sp_io->id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp->sp_next = (*spp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*spp) = sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_io_lbolt = nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((rc = _nsc_reopen_io(path, 0)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_unregister_path (nsc_path_t *sp, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Un-register interest in pathname.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 on success, otherwise returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Interest in the specified pathname is un-registered
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if possible. All appropriate file descriptors will be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * closed in preparation for a subsequent re-open.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If NSC_PCATCH is specified and a signal is received,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the unregister will be terminated and EINTR returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_unregister_path(sp, flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_path_t *sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_path_t *xsp, **spp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (xsp = _nsc_path_top; xsp; xsp = xsp->sp_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (xsp == sp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!xsp || sp->sp_pend) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (xsp ? EALREADY : 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp->sp_pend = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_io_lbolt = nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((rc = _nsc_reopen_io(sp->sp_path, flag)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != ERESTART) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp->sp_pend = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*spp == sp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*spp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*spp) = sp->sp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_strfree(sp->sp_path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(sp, sizeof (*sp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_reopen_io (char *path, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Force re-open of all file descriptors.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The _nsc_io_lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the force succeeds without releasing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_io_lock, otherwise returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A re-open is forced for all file descriptors as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * appropriate. For performance reasons available
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices are re-opened before those that would block.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_reopen_io(path, flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *path;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dp, *dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc, errno = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int try, run;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dev = _nsc_dev_top; dev; dev = dev->nsc_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (path && !nsc_strmatch(dev->nsc_path, path))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(rc = _nsc_reopen_dev(dev, flag | try)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dp = _nsc_dev_top; dp; dp = dp->nsc_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dp == dev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!dp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ERESTART);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (try && !(flag & NSC_TRY))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte run = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!run && errno != ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_reopen_dev (nsc_dev_t *dev, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Force re-open of entire device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The _nsc_io_lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the force succeeds without releasing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_io_lock, otherwise returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A re-open is forced for all file descriptors for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device as appropriate.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_reopen_dev(dev, flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_dev_t *dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc, errno = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int try, run;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iodev = dev->nsc_list; iodev; iodev = iodev->si_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fd = iodev->si_open; fd; fd = fd->sf_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(rc = _nsc_reopen_fd(fd, flag | try)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == -ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ERESTART);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_nsc_relock_dev(dev, fd, iodev))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ERESTART);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (try && !(flag & NSC_TRY))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte run = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!run && errno != ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fd = dev->nsc_close; fd; fd = fd->sf_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(rc = _nsc_reopen_fd(fd, flag | try)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == -ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ERESTART);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_nsc_relock_dev(dev, fd, NULL))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ERESTART);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (try && !(flag & NSC_TRY))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte run = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!run && errno != ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_relock_dev (nsc_dev_t *dev, nsc_fd_t *fd, nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Relock device structure if possible.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The _nsc_io_lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Checks whether the file descriptor is still part
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the specified device and I/O device. If so the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device lock is taken. Otherwise FALSE is returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_relock_dev(nsc_dev_t *dev, nsc_fd_t *fd, nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_fd_t *fp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dp = _nsc_dev_top; dp; dp = dp->nsc_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dp == dev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!dp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iop = dev->nsc_list; iop; iop = iop->si_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iop == iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iodev || iop) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp = (iodev) ? iodev->si_open : dev->nsc_close;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; fp; fp = fp->sf_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp == fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_reopen_fd (nsc_fd_t *dev, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Force re-open of file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Both _nsc_io_lock and the device lock must be held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * across calls to this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the force succeeds without releasing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * any locks, otherwise returns an error code. If an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * error code is returned the device lock is released.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If appropriate the file descriptor is closed in order
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to force a subsequent open using the currently available
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * resources.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_reopen_fd(fd, flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev = fd->sf_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iodev = fd->sf_iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int changed = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fd->sf_pend && !iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd->sf_pend == _NSC_OPEN)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd->sf_lbolt - _nsc_io_lbolt > 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iodev &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iodev->si_io ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_find_io(dev->nsc_path, fd->sf_type, &changed)) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !changed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_reopen = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_reopen = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _nsc_close_fd(fd, flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_reopen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == EAGAIN && (flag & NSC_DEFER) && fd->sf_reopen)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_drop = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == -ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(2); /* allow other threads cpu time */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc ? rc : ERESTART);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_fd_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_open (char *path, int type, nsc_def_t *def, blind_t arg, int *sts)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open file descriptor for pathname.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns file descriptor if open succeeds, otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns 0 and puts error code in the location pointed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to by sts.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open the specified pathname using an appropriate access
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * method.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_open(path, type, def, arg, sts)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *path;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_def_t *def;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteblind_t arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint *sts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flag, rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flag = (type & ~NSC_TYPES);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte type &= NSC_TYPES;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((flag & NSC_READ) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flag |= NSC_RDWR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_alloc_fd(path, type, flag, &fd)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sts)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *sts = rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_arg = arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_aio = _nsc_null_io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_decode_param(def, _nsc_fd_def, (long *)fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fd->sf_dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((rc = _nsc_open_fd(fd, flag)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fd->sf_dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_fd(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sts)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *sts = rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_open_fd (nsc_fd_t *fd, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The device lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the open succeeds, otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open the specified file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_open_fd(fd, flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev = fd->sf_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd->sf_pend)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_wait_dev(dev, flag));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd->sf_iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & NSC_NOBLOCK)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EAGAIN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_pend = _NSC_OPEN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_lbolt = nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _nsc_open_fn(fd, flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_pend = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_iodev->si_pend = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev->nsc_wait || dev->nsc_refcnt <= 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&dev->nsc_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc ? rc : ERESTART);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_open_fn (nsc_fd_t *fd, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate I/O device and open file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No locks may be held across this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the open succeeds an I/O device will be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * attached to the file descriptor, marked as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pending and 0 returned. Otherwise, returns
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate an I/O device and open the specified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_open_fn(fd, flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev = fd->sf_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_alloc_iodev(dev, fd->sf_type, &iodev)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iodev->si_pend) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _nsc_wait_dev(dev, flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_iodev(iodev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_pend = _NSC_OPEN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*iodev->si_io->open)(dev->nsc_path,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fd->sf_flag & ~NSC_RDWR), &fd->sf_cd, iodev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_pend = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_iodev(iodev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* save away the DevMaj and DevMin values */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iodev->si_io->id == NSC_RAW_ID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _nsc_setval(dev, NULL, NSC_DEVMAJ,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (int)getmajor((dev_t)fd->sf_cd), FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 1) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!nsctl: could not set DevMaj (%s:%x)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_path, (int)getmajor((dev_t)fd->sf_cd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _nsc_setval(dev, NULL, NSC_DEVMIN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (int)getminor((dev_t)fd->sf_cd), FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 1) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!nsctl: could not set DevMin (%s:%x)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_path, (int)getminor((dev_t)fd->sf_cd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_iodev = iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_relink_fd(fd, &dev->nsc_close, &iodev->si_open, iodev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_close (nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close file descriptor for pathname.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if close succeeds, otherwise returns error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close the specified file descriptor. It is assumed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that all other users of this file descriptor have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * finished. Any reserve will be discarded before the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * close is performed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_close(fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fd->sf_reserve)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fd->sf_dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_owner = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((rc = _nsc_close_fd(fd, 0)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != ERESTART)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_decode_param(_nsc_fd_def, _nsc_fd_def, (long *)fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fd->sf_dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_fd(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_close_fd (nsc_fd_t *fd, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The device lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the close succeeds, otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close the specified file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_close_fd(fd, flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev = fd->sf_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd->sf_pend) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd->sf_pend == _NSC_CLOSE && dev->nsc_reopen != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-ERESTART);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_wait_dev(dev, flag));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flag |= NSC_RDWR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev = fd->sf_iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_detach_fd(fd, flag)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iodev->si_pend)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_wait_dev(dev, flag));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iodev->si_open == fd && !fd->sf_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_detach_iodev(iodev, NULL, flag)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev->nsc_list == iodev && !iodev->si_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_detach_dev(dev, NULL, flag)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & NSC_NOBLOCK)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EAGAIN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_pend = _NSC_CLOSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_pend = _NSC_CLOSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _nsc_close_fn(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_pend = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_reopen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_pend = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev->nsc_wait || dev->nsc_refcnt <= 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&dev->nsc_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc ? rc : ERESTART);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_close_fn (nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close file descriptor and free I/O device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No locks may be held across this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the close succeeds, otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the close succeeds the I/O device will be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * detached from the file descriptor, released
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and 0 returned. Otherwise, returns an error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close the specified file descriptor and free
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the I/O device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_close_fn(fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iodev = fd->sf_iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev = fd->sf_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int last, rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = (iodev->si_open == fd && !fd->sf_next);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last || (iodev->si_io->flag & NSC_REFCNT))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = (*iodev->si_io->close)(fd->sf_cd)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_iodev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_relink_fd(fd, &iodev->si_open, &dev->nsc_close, iodev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_pend = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_iodev(iodev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_set_owner (nsc_fd_t *fd, nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set owner associated with file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sets the owner field in the file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_set_owner(nsc_fd_t *fd, nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fd->sf_dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_owner = iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fd->sf_dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * char *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_pathname (nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Pathname associated with file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a pointer to the pathname associated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with the given file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_pathname(fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return ((fd) ? (fd->sf_dev->nsc_path) : 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Compare fd to pathname and hash
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns comparison value like strcmp(3C).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Does an optimised comparison of the pathname and associated hash
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * value (as returned from nsc_strhash()) against the pathname of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the filedescriptor, fd.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd != NULL && fd->sf_dev->nsc_phash == phash)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = strcmp(fd->sf_dev->nsc_path, path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_setval(nsc_dev_t *dev, char *path, char *name, int val, int do_ncall)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_devval_t *dv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_rval_t *rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_t *ncall;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_val_t *vp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t phash;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *pp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(dev != NULL || path != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev != NULL && path != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(strcmp(dev->nsc_path, path) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pp = (dev != NULL) ? dev->nsc_path : path;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strlen(name) >= NSC_SETVAL_MAX) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!nsc_setval: max name size(%d) exceeded(%d)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NSC_SETVAL_MAX-1, (int)strlen(name));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phash = nsc_strhash(pp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dv = dev->nsc_values;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dv = _nsc_devval_top; dv != NULL; dv = dv->dv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (phash == dv->dv_phash &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(pp, dv->dv_path) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* found dv for device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dv == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dv = nsc_kmem_zalloc(sizeof (*dv), KM_SLEEP, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dv == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(dv->dv_path, pp, sizeof (dv->dv_path));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dv->dv_phash = phash;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dv->dv_next = _nsc_devval_top;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_devval_top = dv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_values = dv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (vp = dv->dv_values; vp; vp = vp->sv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(vp->sv_name, name) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vp->sv_value = val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vp = nsc_kmem_zalloc(sizeof (*vp), KM_SLEEP, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(vp->sv_name, name, sizeof (vp->sv_name));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vp->sv_value = val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vp->sv_next = dv->dv_values;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dv->dv_values = vp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * phoenix: ncall the new value to the other node now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vp && do_ncall) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(sizeof (nsc_rval_t) <= NCALL_DATA_SZ);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &ncall);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(rval->path, pp, sizeof (rval->path));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(rval->name, name, sizeof (rval->name));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval->value = val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_put_data(ncall, rval, sizeof (*rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send synchronously and read a reply
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so that we know that the remote
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * setval has completed before this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * function returns and hence whilst
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the device is still reserved on this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ncall_send(ncall, 0, NSC_SETVAL) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ncall_read_reply(ncall, 1, &rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_free(ncall);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(rval, sizeof (*rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteout:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (vp ? 1 : 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forter_nsc_setval(ncall_t *ncall, int *ap)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_rval_t *rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_reply(ncall, ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_get_data(ncall, rval, sizeof (*rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_reply(ncall, EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_nsc_setval(NULL, rval->path, rval->name, rval->value, FALSE))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ENOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_reply(ncall, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(rval, sizeof (*rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forter_nsc_setval_all(ncall_t *ncall, int *ap)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_rval_t *in = NULL, *out = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_devval_t *dv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_val_t *vp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_t *np;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t phash;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(sizeof (nsc_rval_t) <= NCALL_DATA_SZ);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte in = nsc_kmem_zalloc(sizeof (*in), KM_SLEEP, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte out = nsc_kmem_zalloc(sizeof (*out), KM_SLEEP, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (in == NULL || out == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (in != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(in, sizeof (*in));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte in = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (out != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(out, sizeof (*out));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte out = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_reply(ncall, ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_get_data(ncall, in, sizeof (*in));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_reply(ncall, EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phash = nsc_strhash(in->path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(out->path, in->path, sizeof (out->path));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &np);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_reply(ncall, ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dv = _nsc_devval_top; dv; dv = dv->dv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dv->dv_phash == phash &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(dv->dv_path, in->path) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dv) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (vp = dv->dv_values; vp; vp = vp->sv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(vp->sv_name, NSC_DEVMIN) == 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(vp->sv_name, NSC_DEVMAJ) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ignore the implicit DevMin/DevMaj values */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(out->name, vp->sv_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (out->name));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte out->value = vp->sv_value;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_put_data(np, out, sizeof (*out));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send synchronously and read a reply
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so that we know that the remote
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * setval has completed before this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * function returns.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ncall_send(np, 0, NSC_SETVAL) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ncall_read_reply(np, 1, &rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_reset(np);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_free(np);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ENODEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_reply(ncall, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(out, sizeof (*out));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(in, sizeof (*in));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_setval (nsc_fd_t *fd, char *name, int val)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set value for device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 1 if the value has been set, otherwise 0.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Must be called with the fd reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sets the specified global variable for the device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the value provided.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_setval(nsc_fd_t *fd, char *name, int val)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!nsc_held(fd))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_setval(fd->sf_dev, NULL, name, val, TRUE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_getval (nsc_fd_t *fd, char *name, int *vp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get value from device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 1 if the value has been found, otherwise 0.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Must be called with the fd reserved, except for "DevMaj" / "DevMin".
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Finds the value of the specified device variable for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the device and returns it in the location pointed to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by vp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_getval(nsc_fd_t *fd, char *name, int *vp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_devval_t *dv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_val_t *val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Don't check for nsc_held() for the device number values
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * since these are magically created and cannot change when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fd is not reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(name, NSC_DEVMAJ) != 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(name, NSC_DEVMIN) != 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !nsc_held(fd))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dv = fd->sf_dev->nsc_values;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dv != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (val = dv->dv_values; val; val = val->sv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(val->sv_name, name) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *vp = val->sv_value;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (val ? 1 : 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * char *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_shared (nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Device is currently shared.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The device lock must be held across calls to this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns an indication of whether the device accessed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by the file descriptor is currently referenced by more
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * than one user.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is only intended for use in performance critical
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * situations.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_shared(fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fd->sf_iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iodev = fd->sf_dev->nsc_list; iodev; iodev = iodev->si_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fd = iodev->si_open; fd; fd = fd->sf_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fd->sf_owner && cnt++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * kmutex_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_lock_addr (nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Address of device lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a pointer to the spin lock associated with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is only intended for use in performance critical
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * situations in conjunction with nsc_reserve_lk.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortekmutex_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_lock_addr(fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (&fd->sf_dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_call_io (long f, blind_t a, blind_t b, blind_t c)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call information function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns result from function or 0 if not available.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * f represents the offset into the I/O structure at which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the required function can be found and a, b, c are the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * desired arguments.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calls the requested function for the first available
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cache interface.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_call_io(long f, blind_t a, blind_t b, blind_t c)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_io_t *io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*fn)();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io = _nsc_reserve_io(NULL, NSC_SDBC_ID);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io = _nsc_reserve_io(NULL, NSC_NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fn = (blindfn_t)(((long *)io)[f]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*fn)(a, b, c);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_release_io(io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_reserve_io (char *, int type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reserve I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns address of I/O structure matching specified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * type, or NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Searches for an appropriate I/O module and increments
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the reference count to prevent it being unregistered.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_reserve_io(path, type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *path;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_io_t *io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((io = _nsc_find_io(path, type, NULL)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->refcnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static nsc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_find_io (char *path, int type, int *changed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Find I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The _nsc_io_lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns address of I/O structure matching specified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * type, or NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 'changed' will be set to non-zero if there is a pending
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_path_t that matches the criteria for the requested type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This allows nsctl to distinguish between multiple
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_register_path's done by the same I/O provider.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Searches for an appropriate I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1. If <type> is a single module id find the specified I/O
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * module by module id.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 2. Find the highest module that provides any of the I/O types
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * included in <type>, taking into account any modules
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * registered via the nsc_register_path() interface if <path>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is non-NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 3. Find an I/O module following the rules in (2), but whose
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * module id is less than the id OR'd into <type>.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If no module is found by the above algorithms and NSC_NULL was
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * included in <type>, return the _nsc_null_io module. Otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_find_io(char *path, int type, int *changed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_path_t *sp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_path_t *pp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_io_t *io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte type &= NSC_TYPES;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (path) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (sp = _nsc_path_top; sp; sp = sp->sp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((type & NSC_ID) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp->sp_io->id >= (type & NSC_IDS))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sp->sp_pend || (type & sp->sp_type) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nsc_strmatch(path, sp->sp_path))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* look for matching pending paths */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (pp = _nsc_path_top; pp; pp = pp->sp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pp->sp_pend &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (type & pp->sp_type) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_strmatch(path, pp->sp_path)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (io = _nsc_io_top; io; io = io->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io->pend)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (type & NSC_ID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((type & ~NSC_IDS) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io->id == type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io->id >= (type & NSC_IDS))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io->provide & type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pp && (!io || pp->sp_io->id >= io->id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark this as a path change.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (changed) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *changed = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sp && (!io || sp->sp_io->id >= io->id))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io = sp->sp_io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!io && !(type & NSC_NULL))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io = _nsc_null_io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_release_io (nsc_io_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Release I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Releases reference to I/O structure and wakes up
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * anybody waiting on it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_release_io(io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_io_t *io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->refcnt--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&io->cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_alloc_fd (char *path, int type, int flag, nsc_fd_t **fdp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate file descriptor structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Stores address of file descriptor through fdp and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns 0 on success, otherwise returns error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A new file descriptor is allocated and linked in to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the file descriptor chain which is protected by the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * On return the file descriptor must contain all the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information necessary to perform an open. Details
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * specific to user callbacks are not required yet.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_alloc_fd(path, type, flag, fdp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *path;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint type, flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t **fdp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(fd = (nsc_fd_t *)nsc_kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*fd), KM_SLEEP, _nsc_local_mem)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_alloc_dev(path, &dev)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(fd, sizeof (*fd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_type = type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_flag = flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_dev = dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_next = dev->nsc_close;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_close = fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *fdp = fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_free_fd (nsc_fd_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The file descriptor is removed from the chain and free'd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * once pending activity has completed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_free_fd(fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_fd_t *fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev = fd->sf_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_fd_t **fdp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fdp = &dev->nsc_close; *fdp; fdp = &(*fdp)->sf_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*fdp == fd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *fdp = fd->sf_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev->nsc_wait || dev->nsc_refcnt <= 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&dev->nsc_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fd->sf_pend)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _nsc_wait_dev(dev, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_dev(dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(fd, sizeof (*fd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_relink_fd (nsc_fd_t *fd, nsc_fd_t **from,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_fd_t **to, nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Relink file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove the file descriptor from the 'from' chain and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * add it to the 'to' chain. The busy flag in iodev is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * used to prevent modifications to the chain whilst a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * callback is in progress.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_relink_fd(nsc_fd_t *fd, nsc_fd_t **from, nsc_fd_t **to, nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev = fd->sf_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_fd_t **fdp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (iodev->si_busy)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _nsc_wait_dev(dev, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fdp = from; *fdp; fdp = &(*fdp)->sf_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*fdp == fd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *fdp = fd->sf_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd->sf_next = (*to);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*to) = fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_alloc_iodev (nsc_dev_t *dev, int type, nsc_iodev_t **iodevp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate I/O device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Stores address of I/O device structure through iodevp
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and returns 0 on success, otherwise returns error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If an entry for the I/O device already exists increment
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the reference count and return the address, otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocate a new structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A new structure is allocated before scanning the chain
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to avoid calling the memory allocator with a spin lock
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * held. If an entry is found the new structure is free'd.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The I/O device chain is protected by the device lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_alloc_iodev(dev, type, iodevp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_dev_t *dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_iodev_t **iodevp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iodev, *ip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_io_t *io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(iodev = (nsc_iodev_t *)nsc_kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*iodev), KM_SLEEP, _nsc_local_mem)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&iodev->si_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&iodev->si_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(io = _nsc_reserve_io(dev->nsc_path, type))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&iodev->si_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&iodev->si_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(iodev, sizeof (*iodev));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_refcnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_io = io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_dev = dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_refcnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ip = dev->nsc_list; ip; ip = ip->si_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ip->si_io == io) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ip->si_refcnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!ip) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_next = dev->nsc_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_list = iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ip) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_iodev(iodev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev = ip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *iodevp = iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_free_iodev (nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free I/O device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Decrements the reference count of a previously allocated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * I/O device structure. If this is the last reference it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is removed from the device chain and free'd once pending
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * activity has completed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_free_iodev(nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t **ipp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev = iodev->si_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--iodev->si_refcnt > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ipp = &dev->nsc_list; *ipp; ipp = &(*ipp)->si_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*ipp == iodev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ipp = iodev->si_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev->nsc_wait || dev->nsc_refcnt <= 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&dev->nsc_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (iodev->si_pend || iodev->si_rpend || iodev->si_busy)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _nsc_wait_dev(dev, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_release_io(iodev->si_io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_dev(dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&iodev->si_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&iodev->si_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(iodev, sizeof (*iodev));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_alloc_dev (char *path, nsc_dev_t **devp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Stores address of device structure through devp
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and returns 0 on success, otherwise returns error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If an entry for the device already exists increment
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the reference count and return the address, otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocate a new structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A new structure is allocated before scanning the device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * chain to avoid calling the memory allocator with a spin
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * lock held. If the device is found the new structure is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free'd.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The device chain is protected by _nsc_io_lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_alloc_dev(char *path, nsc_dev_t **devp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t *dev, *dp, **ddp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_devval_t *dv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_rval_t *rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_t *ncall;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(dev = (nsc_dev_t *)nsc_kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*dev), KM_SLEEP, _nsc_local_mem)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_refcnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&dev->nsc_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&dev->nsc_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_phash = nsc_strhash(path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_path = nsc_strdup(path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_next = _nsc_dev_pend;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_dev_pend = dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dp = _nsc_dev_top; dp; dp = dp->nsc_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dp->nsc_phash == dev->nsc_phash &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(dp->nsc_path, dev->nsc_path) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dp->nsc_refcnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!dp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*ddp == dev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ddp = dev->nsc_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_next = _nsc_dev_top;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_dev_top = dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_free_dev(dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev = dp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try and find the device/values header for this device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and link it back to the device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev->nsc_values == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dv = _nsc_devval_top; dv; dv = dv->dv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dv->dv_phash == dev->nsc_phash &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(dv->dv_path, dev->nsc_path) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_values = dv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_devval_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Refresh the device/values from the other node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &ncall);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(rval->path, path, sizeof (rval->path));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_put_data(ncall, rval, sizeof (*rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send synchronously and read a reply
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so that we know that the updates
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have completed before this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * function returns.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ncall_send(ncall, 0, NSC_SETVAL_ALL) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ncall_read_reply(ncall, 1, &rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_free(ncall);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(rval, sizeof (*rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteout:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *devp = dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_free_dev (nsc_dev_t *dev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Decrements the reference count of a previously allocated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device structure. If this is the last reference it is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * removed from the device chain and free'd once pending
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * activity has completed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Whilst waiting for pending activity to cease the device is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * relinked onto the pending chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_free_dev(dev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_dev_t *dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dev_t **ddp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!dev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--dev->nsc_refcnt > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ddp = &_nsc_dev_top; *ddp; ddp = &(*ddp)->nsc_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*ddp == dev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ddp = dev->nsc_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev->nsc_next = _nsc_dev_pend;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_dev_pend = dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (dev->nsc_pend || dev->nsc_rpend || dev->nsc_wait) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&dev->nsc_cv, &dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*ddp == dev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ddp = dev->nsc_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&dev->nsc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&dev->nsc_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_strfree(dev->nsc_path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(dev, sizeof (*dev));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static nsc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_alloc_io (int id, char *name, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate an I/O structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns the address of the I/O structure, or NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_alloc_io(id, name, flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_io_t *io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(io = (nsc_io_t *)nsc_kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*io), KM_NOSLEEP, _nsc_local_mem)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&io->cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->id = id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->name = name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->flag = flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_free_io (int id, char *name, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free an I/O structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free the I/O structure and remove it from the chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_free_io(io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_io_t *io;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_io_t **iop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*iop == io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*iop)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*iop) = io->next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_io_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&io->cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(io, sizeof (*io));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}