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/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 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/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/file.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/open.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cred.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/uio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define __NSC_GEN__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "nsc_dev.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "nsc_ioctl.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "nsc_power.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "../nsctl.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern nsc_mem_t *_nsc_local_mem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int null_power(void);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct _nsc_power_s {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct _nsc_power_s *next; /* chain */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *name; /* module name */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void (*pw_power_lost)(int); /* callback power lost(rideout) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void (*pw_power_ok)(void); /* callback power ok */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void (*pw_power_down)(void);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* callback power down (shutdown imminent) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} _nsc_power_t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define _P(x) (((long)(&((_nsc_power_t *)0)->x))/sizeof (long))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_def_t _nsc_power_def[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Power_Lost", (uintptr_t)null_power, _P(pw_power_lost),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Power_OK", (uintptr_t)null_power, _P(pw_power_ok),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Power_Down", (uintptr_t)null_power, _P(pw_power_down),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic _nsc_power_t *_power_clients;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kmutex_t _power_mutex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int null_power(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * init null_power - dummy power routine for clients that choose not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to implement all the power hooks.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_power
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call registered clients of the generic power ioctls.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calls all the registered clients with a message describing the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * current state of the power for the system.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_power(blind_t argp, int *rvp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_power_ctl_t opc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_power_t *pp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *rvp = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (copyin((void *) argp, &opc, sizeof (nsc_power_ctl_t)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pp = _power_clients;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch ((nsc_power_ops_t)opc.msg) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case Power_OK:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*pp->pw_power_ok)();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case Power_Down:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*pp->pw_power_down)();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case Power_Lost:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*pp->pw_power_lost)(opc.arg1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pp = pp->next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_init_power (void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialise power ioctl 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 Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_init_power(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&_power_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_deinit_power (void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialise power ioctl 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 Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_deinit_power(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_power_t *pp, *npp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pp = _power_clients;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npp = pp->next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(pp, sizeof (_nsc_power_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pp = npp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _power_clients = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * blind_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_register_power (char *name, nsc_def_t *def)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Register an power ioctl client.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a token for use in future calls to nsc_unregister_power.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If a client with the same name is already registered then NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is return to indicate failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If registration fails NULL is returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Registers an power ioctl client for notifications during subsequent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ioctl from UPS/PCU management.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteblind_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_register_power(char *name, nsc_def_t *def)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_power_t *entry, *pp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte entry = nsc_kmem_alloc(sizeof (_nsc_power_t), 0, _nsc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (entry == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_decode_param(def, _nsc_power_def, (long *)entry);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (pp = _power_clients; pp; pp = pp->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(pp->name, name) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(entry, sizeof (_nsc_power_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte entry->name = name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte entry->next = _power_clients;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _power_clients = entry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return ((blind_t)entry);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_unregister_power (blind_t powerp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Un-register a power ioctl client.
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 power ioctl client is un-registered if possible.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Zero is returned on success otherwise an error code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_unregister_power(blind_t powerp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_power_t **xpp, *entry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte entry = (_nsc_power_t *)powerp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (entry == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (xpp = &_power_clients; *xpp; xpp = &(*xpp)->next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*xpp == entry)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*xpp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EALREADY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *xpp = entry->next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_power_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(entry, sizeof (_nsc_power_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}