fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
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 * CDDL HEADER END
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
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 "Unpinned", (uintptr_t)nsc_null, _F(sf_unpinned),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_io_t *_nsc_find_io(char *, int, int *);
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_reopen_io(char *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_relock_dev(nsc_dev_t *, nsc_fd_t *, nsc_iodev_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_decode_io(nsc_def_t *, nsc_io_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _nsc_relink_fd(nsc_fd_t *, nsc_fd_t **, nsc_fd_t **, nsc_iodev_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_setval(nsc_dev_t *, char *, char *, int, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_init_dev (void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialise device subsystem.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called at driver initialisation time to allocate necessary
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data structures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&_nsc_io_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&_nsc_devval_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_null_io = nsc_register_io("null", NSC_NULL, (nsc_def_t *)0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ncall_register_svc(NSC_SETVAL_ALL, r_nsc_setval_all);
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 * 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 * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Registers an I/O module for use by subsequent calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(tp->name, name) == 0 || tp->id == id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next)
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 * Returns TRUE if the definition contains an adequate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * description of an I/O module.
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 nsc_decode_param(def, _nsc_disk_def, (long *)io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_decode_param(def, _nsc_cache_def, (long *)io);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_unregister_io (nsc_io_t *io, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Un-register an I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 on success, otherwise returns an error code.
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 * If NSC_PCATCH is specified and a signal is received,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the unregister will be terminated and EINTR returned.
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 * nsc_path_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_register_path (char *path, int type, nsc_io_t *io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Register interest in pathname.
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 * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Registers an interest in any pathnames matching 'path'
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which are opened with the specified type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_register_path(char *path, int type, nsc_io_t *io)
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 for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_unregister_path (nsc_path_t *sp, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Un-register interest in pathname.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 on success, otherwise returns an error code.
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 * If NSC_PCATCH is specified and a signal is received,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the unregister will be terminated and EINTR returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (xsp = _nsc_path_top; xsp; xsp = xsp->sp_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((rc = _nsc_reopen_io(sp->sp_path, flag)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_reopen_io (char *path, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Force re-open of all file descriptors.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The _nsc_io_lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the force succeeds without releasing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_io_lock, otherwise returns an error code.
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 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 * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_reopen_dev (nsc_dev_t *dev, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Force re-open of entire device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The _nsc_io_lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the force succeeds without releasing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_io_lock, otherwise returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A re-open is forced for all file descriptors for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device as appropriate.
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 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 * 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 * The _nsc_io_lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
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_nsc_relock_dev(nsc_dev_t *dev, nsc_fd_t *fd, nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iop = dev->nsc_list; iop; iop = iop->si_next)
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 * Both _nsc_io_lock and the device lock must be held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * across calls to this function.
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 * 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 _nsc_find_io(dev->nsc_path, fd->sf_type, &changed)) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == EAGAIN && (flag & NSC_DEFER) && fd->sf_reopen)
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 * 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 * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open the specified pathname using an appropriate access
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_alloc_fd(path, type, flag, &fd)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_open_fd (nsc_fd_t *fd, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The device lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the open succeeds, otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open the specified file descriptor.
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 * No locks may be held across this function.
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 * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate an I/O device and open the specified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_alloc_iodev(dev, fd->sf_type, &iodev)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* save away the DevMaj and DevMin values */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!nsctl: could not set DevMaj (%s:%x)",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!nsctl: could not set DevMin (%s:%x)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_relink_fd(fd, &dev->nsc_close, &iodev->si_open, iodev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_close (nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close file descriptor for pathname.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if close succeeds, otherwise returns error
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 nsc_decode_param(_nsc_fd_def, _nsc_fd_def, (long *)fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_close_fd (nsc_fd_t *fd, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The device lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the close succeeds, otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close the specified file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd->sf_pend == _NSC_CLOSE && dev->nsc_reopen != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_detach_iodev(iodev, NULL, flag)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_detach_dev(dev, NULL, flag)) != 0)
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 * No locks may be held across this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the close succeeds, otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns an error code.
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 * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close the specified file descriptor and free
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the I/O device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = (*iodev->si_io->close)(fd->sf_cd)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_relink_fd(fd, &iodev->si_open, &dev->nsc_close, iodev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_set_owner (nsc_fd_t *fd, nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set owner associated with file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sets the owner field in the file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_pathname (nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Pathname associated with file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a pointer to the pathname associated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with the given file descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Compare fd to pathname and hash
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns comparison value like strcmp(3C).
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 Fortensc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd != NULL && fd->sf_dev->nsc_phash == phash)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_setval(nsc_dev_t *dev, char *path, char *name, int val, int do_ncall)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!nsc_setval: max name size(%d) exceeded(%d)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dv = _nsc_devval_top; dv != NULL; dv = dv->dv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* found dv for device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dv = nsc_kmem_zalloc(sizeof (*dv), KM_SLEEP, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(dv->dv_path, pp, sizeof (dv->dv_path));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vp = nsc_kmem_zalloc(sizeof (*vp), KM_SLEEP, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(vp->sv_name, name, sizeof (vp->sv_name));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * phoenix: ncall the new value to the other node now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
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 rc = ncall_put_data(ncall, rval, sizeof (*rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
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/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_get_data(ncall, rval, sizeof (*rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_nsc_setval(NULL, rval->path, rval->name, rval->value, FALSE))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
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 (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(out->path, in->path, sizeof (out->path));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &np);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dv = _nsc_devval_top; dv; dv = dv->dv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ignore the implicit DevMin/DevMaj values */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
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 * nsc_setval (nsc_fd_t *fd, char *name, int val)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set value for device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 1 if the value has been set, otherwise 0.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Must be called with the fd reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sets the specified global variable for the device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the value provided.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_setval(fd->sf_dev, NULL, name, val, TRUE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_getval (nsc_fd_t *fd, char *name, int *vp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get value from device.
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 * 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 * 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 for (val = dv->dv_values; val; val = val->sv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_shared (nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Device is currently shared.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The device lock must be held across calls to this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
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 * This is only intended for use in performance critical
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * situations.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iodev = fd->sf_dev->nsc_list; iodev; iodev = iodev->si_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * kmutex_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_lock_addr (nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Address of device lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a pointer to the spin lock associated with the
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 * _nsc_call_io (long f, blind_t a, blind_t b, blind_t c)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call information function.
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 * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calls the requested function for the first available
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cache interface.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_call_io(long f, blind_t a, blind_t b, blind_t c)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_reserve_io (char *, int type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reserve I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns address of I/O structure matching specified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * type, or NULL.
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 * static nsc_io_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_find_io (char *path, int type, int *changed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Find I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The _nsc_io_lock must be held across calls to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns address of I/O structure matching specified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * type, or NULL.
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 * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Searches for an appropriate I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1. If <type> is a single module id find the specified I/O
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * module by module id.
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 * 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 * 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 /* look for matching pending paths */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark this as a path change.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_release_io (nsc_io_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Release I/O module.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Releases reference to I/O structure and wakes up
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * anybody waiting on it.
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 * Stores address of file descriptor through fdp and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns 0 on success, otherwise returns error code.
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 * 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 * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_free_fd (nsc_fd_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free file descriptor.
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 for (fdp = &dev->nsc_close; *fdp; fdp = &(*fdp)->sf_next)
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 * 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_nsc_relink_fd(nsc_fd_t *fd, nsc_fd_t **from, nsc_fd_t **to, nsc_iodev_t *iodev)
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 * Stores address of I/O device structure through iodevp
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and returns 0 on success, otherwise returns error code.
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 * 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 * The I/O device chain is protected by the device lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&iodev->si_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(io = _nsc_reserve_io(dev->nsc_path, type))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_free_iodev (nsc_iodev_t *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free I/O device structure.
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 for (ipp = &dev->nsc_list; *ipp; ipp = &(*ipp)->si_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (iodev->si_pend || iodev->si_rpend || iodev->si_busy)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_alloc_dev (char *path, nsc_dev_t **devp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Stores address of device structure through devp
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and returns 0 on success, otherwise returns error
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 * 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 * The device chain is protected by _nsc_io_lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&dev->nsc_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try and find the device/values header for this device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and link it back to the device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dv = _nsc_devval_top; dv; dv = dv->dv_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Refresh the device/values from the other node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem);
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 rc = ncall_put_data(ncall, rval, sizeof (*rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
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 * static void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_free_dev (nsc_dev_t *dev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free device structure.
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 * Whilst waiting for pending activity to cease the device is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * relinked onto the pending chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ddp = &_nsc_dev_top; *ddp; ddp = &(*ddp)->nsc_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (dev->nsc_pend || dev->nsc_rpend || dev->nsc_wait) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next)
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 * Returns the address of the I/O structure, or NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_free_io (int id, char *name, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free an I/O structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free the I/O structure and remove it from the chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next)