ds_drv.c revision 40c61268017ed628fcfb89162250c59130d14824
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * CDDL HEADER START
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * The contents of this file are subject to the terms of the
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Common Development and Distribution License (the "License").
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * You may not use this file except in compliance with the License.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * or http://www.opensolaris.org/os/licensing.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * See the License for the specific language governing permissions
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * and limitations under the License.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * When distributing Covered Code, include this CDDL HEADER in each
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * If applicable, add the following below this CDDL HEADER, with the
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * fields enclosed by brackets "[]" replaced with your own identifying
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * information: Portions Copyright [yyyy] [name of copyright owner]
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * CDDL HEADER END
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
40c61268017ed628fcfb89162250c59130d14824Mike Christensen * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Use is subject to license terms.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Domain Services Module System Specific Code.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * The Domain Services (DS) module is responsible for communication
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * with external service entities. It provides a kernel API for clients to
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * publish capabilities and handles the low level communication and
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * version negotiation required to export those capabilities to any
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * interested service entity. Once a capability has been successfully
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * registered with a service entity, the DS module facilitates all
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * data transfers between the service entity and the client providing
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * that particular capability.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * This file provides the system interfaces that are required for
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * the ds.c module, which is common to both Solaris and VBSC (linux).
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/modctl.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/ksynch.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/taskq.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/disp.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/cmn_err.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/note.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/mach_descrip.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/mdesc.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/mdeg.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/ldc.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/ds.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/ds_impl.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * All DS ports in the system
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * The list of DS ports is read in from the MD when the DS module is
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * initialized and is never modified. This eliminates the need for
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * locking to access the port array itself. Access to the individual
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * ports are synchronized at the port level.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_port_t ds_ports[DS_MAX_PORTS];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_portset_t ds_allports; /* all DS ports in the system */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Table of registered services
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Locking: Accesses to the table of services are synchronized using
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * a mutex lock. The reader lock must be held when looking up service
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * information in the table. The writer lock must be held when any
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * service information is being modified.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_svcs_t ds_svcs;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Taskq for internal task processing
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic taskq_t *ds_taskq;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * The actual required number of parallel threads is not expected
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * to be very large. Use the maximum number of CPUs in the system
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * as a rough upper bound.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#define DS_MAX_TASKQ_THR NCPU
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#define DS_DISPATCH(fn, arg) taskq_dispatch(ds_taskq, fn, arg, TQ_SLEEP)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensends_domain_hdl_t ds_my_domain_hdl = DS_DHDL_INVALID;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenchar *ds_my_domain_name = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#ifdef DEBUG
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Debug Flag
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenuint_t ds_debug = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#endif /* DEBUG */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* initialization functions */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void ds_init(void);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void ds_fini(void);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int ds_ports_init(void);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int ds_ports_fini(void);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* port utilities */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int ds_port_add(md_t *mdp, mde_cookie_t port, mde_cookie_t chan);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* log functions */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void ds_log_init(void);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void ds_log_fini(void);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int ds_log_remove(void);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void ds_log_purge(void *arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic struct modlmisc modlmisc = {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen &mod_miscops,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "Domain Services 1.9"
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen};
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic struct modlinkage modlinkage = {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen MODREV_1,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void *)&modlmisc,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen NULL
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen};
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen_init(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Perform all internal setup before initializing
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * the DS ports. This ensures that events can be
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * processed as soon as the port comes up.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_init();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* force attach channel nexus */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) i_ddi_attach_hw_nodes("cnex");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_ports_init()) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "Domain Services initialization failed");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_fini();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = mod_install(&modlinkage)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_ports_fini();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_fini();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen_info(struct modinfo *modinfop)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (mod_info(&modlinkage, modinfop));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen_fini(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = mod_remove(&modlinkage)) == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_ports_fini();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_fini();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_fini(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Flip the enabled switch to make sure that no
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * incoming events get dispatched while things
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * are being torn down.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_enabled = B_FALSE;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Destroy the taskq.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen taskq_destroy(ds_taskq);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Destroy the message log.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_fini();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Deallocate the table of registered services
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* clear out all entries */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_walk_svcs(ds_svc_free, NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* destroy the table itself */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(ds_svcs.tbl, ds_svcs.maxsvcs * sizeof (ds_svc_t *));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_destroy(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen bzero(&ds_svcs, sizeof (ds_svcs));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Initialize the list of ports based on the MD.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_ports_init(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int idx;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen md_t *mdp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int num_nodes;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int listsz;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mde_cookie_t rootnode;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mde_cookie_t dsnode;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mde_cookie_t *portp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mde_cookie_t *chanp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int nport;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int nchan;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((mdp = md_get_handle()) == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "Unable to initialize machine description");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (-1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen num_nodes = md_node_count(mdp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(num_nodes > 0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen listsz = num_nodes * sizeof (mde_cookie_t);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* allocate temporary storage for MD scans */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen portp = kmem_zalloc(listsz, KM_SLEEP);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen chanp = kmem_zalloc(listsz, KM_SLEEP);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rootnode = md_root_node(mdp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(rootnode != MDE_INVAL_ELEM_COOKIE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * The root of the search for DS port nodes is the
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * DS node. Perform a scan to find that node.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nport = md_scan_dag(mdp, rootnode, md_find_name(mdp, DS_MD_ROOT_NAME),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen md_find_name(mdp, "fwd"), portp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nport <= 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_MD(CE_NOTE, "No '%s' node in MD", DS_MD_ROOT_NAME);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen goto done;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* expecting only one DS node */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nport != 1) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_MD(CE_NOTE, "Expected one '%s' node in the MD, found %d",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_MD_ROOT_NAME, nport);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dsnode = portp[0];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* find all the DS ports in the MD */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nport = md_scan_dag(mdp, dsnode, md_find_name(mdp, DS_MD_PORT_NAME),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen md_find_name(mdp, "fwd"), portp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nport <= 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_MD(CE_NOTE, "No '%s' nodes in MD", DS_MD_PORT_NAME);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen goto done;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Initialize all the ports found in the MD.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (idx = 0; idx < nport; idx++) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* get the channels for this port */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nchan = md_scan_dag(mdp, portp[idx],
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen md_find_name(mdp, DS_MD_CHAN_NAME),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen md_find_name(mdp, "fwd"), chanp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nchan <= 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "No '%s' node for DS port",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_MD_CHAN_NAME);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = -1;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen goto done;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* expecting only one channel */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nchan != 1) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_MD(CE_NOTE, "Expected one '%s' node for DS "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " port, found %d", DS_MD_CHAN_NAME, nchan);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ds_port_add(mdp, portp[idx], chanp[0]) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = -1;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen goto done;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensendone:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv != 0)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_ports_fini();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(portp, listsz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(chanp, listsz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) md_fini_handle(mdp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_ports_fini(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int idx;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Tear down each initialized port.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (idx = 0; idx < DS_MAX_PORTS; idx++) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (DS_PORT_IN_SET(ds_allports, idx)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_remove_port(idx, 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_port_add(md_t *mdp, mde_cookie_t port, mde_cookie_t chan)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t port_id;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t ldc_id;
40c61268017ed628fcfb89162250c59130d14824Mike Christensen uint8_t *ldcidsp;
40c61268017ed628fcfb89162250c59130d14824Mike Christensen int len;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* get the ID for this port */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (md_get_prop_val(mdp, port, "id", &port_id) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "%s: port 'id' property not found",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (-1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* sanity check the port id */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (port_id > DS_MAX_PORT_ID) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "%s: port ID %ld out of range",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, port_id);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (-1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* get the channel ID for this port */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (md_get_prop_val(mdp, chan, "id", &ldc_id) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "ds@%lx: %s: no channel 'id' property",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen port_id, __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (-1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (ds_add_port(port_id, ldc_id, DS_DHDL_INVALID, NULL, 1) != 0)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (-1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
40c61268017ed628fcfb89162250c59130d14824Mike Christensen /*
40c61268017ed628fcfb89162250c59130d14824Mike Christensen * Identify the SP Port. The SP port is the only one with
40c61268017ed628fcfb89162250c59130d14824Mike Christensen * the "ldc-ids" property, and is only on the primary domain.
40c61268017ed628fcfb89162250c59130d14824Mike Christensen */
40c61268017ed628fcfb89162250c59130d14824Mike Christensen if (ds_sp_port_id == DS_PORTID_INVALID &&
40c61268017ed628fcfb89162250c59130d14824Mike Christensen md_get_prop_data(mdp, port, "ldc-ids", &ldcidsp, &len) == 0) {
40c61268017ed628fcfb89162250c59130d14824Mike Christensen ds_sp_port_id = port_id;
40c61268017ed628fcfb89162250c59130d14824Mike Christensen }
40c61268017ed628fcfb89162250c59130d14824Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenvoid
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensends_set_my_dom_hdl_name(ds_domain_hdl_t dhdl, char *name)
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen{
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen ds_my_domain_hdl = dhdl;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (ds_my_domain_name != NULL) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_FREE(ds_my_domain_name, strlen(ds_my_domain_name)+1);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen ds_my_domain_name = NULL;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (name != NULL) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen ds_my_domain_name = ds_strdup(name);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen}
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_init()
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_common_init();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Create taskq for internal processing threads. This
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * includes processing incoming request messages and
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * sending out of band registration messages.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_taskq = taskq_create("ds_taskq", 1, minclsyspri, 1,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_MAX_TASKQ_THR, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Initialize the message log.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_init();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_sys_dispatch_func(void (func)(void *), void *arg)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DS_DISPATCH(func, arg) == NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Drain event queue, if necessary.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_sys_drain_events(ds_port_t *port)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen _NOTE(ARGUNUSED(port))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * System specific port initalization.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_sys_port_init(ds_port_t *port)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen _NOTE(ARGUNUSED(port))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * System specific port teardown.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_sys_port_fini(ds_port_t *port)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen _NOTE(ARGUNUSED(port))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * System specific LDC channel initialization.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_sys_ldc_init(ds_port_t *port)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char ebuf[DS_EBUFSIZE];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(MUTEX_HELD(&port->lock));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ldc_open(port->ldc.hdl)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "ds@%lx: %s: ldc_open: %s",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen PORTID(port), __func__, ds_errno_to_str(rv, ebuf));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ldc_up(port->ldc.hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ldc_status(port->ldc.hdl, &port->ldc.state);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_LDC(CE_NOTE, "ds@%lx: %s: initial LDC state 0x%x",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen PORTID(port), __func__, port->ldc.state);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen port->state = DS_PORT_LDC_INIT;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * DS message log
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Locking: The message log is protected by a single mutex. This
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * protects all fields in the log structure itself as well as
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * everything in the entry structures on both the log and the
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * free list.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic struct log {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *head; /* head of the log */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *freelist; /* head of the free list */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t size; /* size of the log in bytes */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint32_t nentry; /* number of entries */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmutex_t lock; /* log lock */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen} ds_log;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* log soft limit */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenuint_t ds_log_sz = DS_LOG_DEFAULT_SZ;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* initial pool of log entry structures */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic ds_log_entry_t ds_log_entry_pool[DS_LOG_NPOOL];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Logging Support
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_log_init(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *new;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* initialize global lock */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_init(&ds_log.lock, NULL, MUTEX_DRIVER, NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_log.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* initialize the log */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.head = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.size = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.nentry = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* initialize the free list */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (new = ds_log_entry_pool; new < DS_LOG_POOL_END; new++) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->next = ds_log.freelist;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.freelist = new;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_log.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_LOG(CE_NOTE, "ds_log initialized: size=%d bytes, "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " limit=%d bytes, ninit=%ld", ds_log_sz, DS_LOG_LIMIT,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_LOG_NPOOL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_log_fini(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *next;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_log.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* clear out the log */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen while (ds_log.nentry > 0)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_log_remove();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Now all the entries are on the free list.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Clear out the free list, deallocating any
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * entry that was dynamically allocated.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen while (ds_log.freelist != NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen next = ds_log.freelist->next;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (!DS_IS_POOL_ENTRY(ds_log.freelist)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(ds_log.freelist, sizeof (ds_log_entry_t));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.freelist = next;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_log.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_destroy(&ds_log.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic ds_log_entry_t *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_log_entry_alloc(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *new = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(MUTEX_HELD(&ds_log.lock));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ds_log.freelist != NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new = ds_log.freelist;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.freelist = ds_log.freelist->next;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (new == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* free list was empty */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new = kmem_zalloc(sizeof (ds_log_entry_t), KM_SLEEP);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(new);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (new);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_log_entry_free(ds_log_entry_t *entry)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(MUTEX_HELD(&ds_log.lock));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (entry == NULL)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (entry->data != NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(entry->data, entry->datasz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen entry->data = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* place entry on the free list */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen entry->next = ds_log.freelist;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.freelist = entry;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Add a message to the end of the log
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_log_add(ds_log_entry_t *new)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(MUTEX_HELD(&ds_log.lock));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ds_log.head == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->prev = new;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->next = new;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.head = new;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *head = ds_log.head;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *tail = ds_log.head->prev;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->next = head;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->prev = tail;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen tail->next = new;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head->prev = new;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* increase the log size, including the metadata size */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.size += DS_LOG_ENTRY_SZ(new);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.nentry++;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_LOG(CE_NOTE, "ds_log: added %ld data bytes, %ld total bytes",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->datasz, DS_LOG_ENTRY_SZ(new));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Remove an entry from the head of the log
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_log_remove(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *head;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(MUTEX_HELD(&ds_log.lock));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head = ds_log.head;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* empty list */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (head == NULL)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (head->next == ds_log.head) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* one element list */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.head = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head->next->prev = head->prev;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head->prev->next = head->next;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.head = head->next;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_LOG(CE_NOTE, "ds_log: removed %ld data bytes, %ld total bytes",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head->datasz, DS_LOG_ENTRY_SZ(head));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.size -= DS_LOG_ENTRY_SZ(head);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.nentry--;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_free(head);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Replace the data in the entry at the front of the list with then
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * new data. This has the effect of removing the oldest entry and
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * adding the new entry.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_log_replace(int32_t dest, uint8_t *msg, size_t sz)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *head;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(MUTEX_HELD(&ds_log.lock));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head = ds_log.head;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_LOG(CE_NOTE, "ds_log: replaced %ld data bytes (%ld total) with "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " %ld data bytes (%ld total)", head->datasz,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_LOG_ENTRY_SZ(head), sz, sz + sizeof (ds_log_entry_t));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.size -= DS_LOG_ENTRY_SZ(head);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(head->data, head->datasz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head->data = msg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head->datasz = sz;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head->timestamp = ddi_get_time();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen head->dest = dest;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.size += DS_LOG_ENTRY_SZ(head);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log.head = head->next;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_log_purge(void *arg)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen _NOTE(ARGUNUSED(arg))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_log.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_LOG(CE_NOTE, "ds_log: purging oldest log entries");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen while ((ds_log.nentry) && (ds_log.size >= ds_log_sz)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_log_remove();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_log.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_log_add_msg(int32_t dest, uint8_t *msg, size_t sz)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen void *data;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_log.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* allocate a local copy of the data */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen data = kmem_alloc(sz, KM_SLEEP);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen bcopy(msg, data, sz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* check if the log is larger than the soft limit */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((ds_log.nentry) && ((ds_log.size + sz) >= ds_log_sz)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * The log is larger than the soft limit.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Swap the oldest entry for the newest.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_LOG(CE_NOTE, "%s: replacing oldest entry with new entry",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_log_replace(dest, data, sz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Still have headroom under the soft limit.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Add the new entry to the log.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_log_entry_t *new;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new = ds_log_entry_alloc();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* fill in message data */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->data = data;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->datasz = sz;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->timestamp = ddi_get_time();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen new->dest = dest;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = ds_log_add(new);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* check if the log is larger than the hard limit */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((ds_log.nentry > 1) && (ds_log.size >= DS_LOG_LIMIT)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Wakeup the thread to remove entries
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * from the log until it is smaller than
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * the soft limit.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_LOG(CE_NOTE, "%s: log exceeded %d bytes, scheduling"
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " a purge...", __func__, DS_LOG_LIMIT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (DS_DISPATCH(ds_log_purge, NULL) == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_NOTE, "%s: purge thread failed to start",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_log.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_add_port(uint64_t port_id, uint64_t ldc_id, ds_domain_hdl_t dhdl,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *dom_name, int verbose)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_port_t *newport;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* sanity check the port id */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (port_id > DS_MAX_PORT_ID) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "%s: port ID %ld out of range",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, port_id);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_MD(CE_NOTE, "%s: adding port ds@%ld, LDC: 0x%lx, dhdl: 0x%lx "
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen "name: '%s'", __func__, port_id, ldc_id, dhdl,
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen dom_name == NULL ? "NULL" : dom_name);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* get the port structure from the array of ports */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen newport = &ds_ports[port_id];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* check for a duplicate port in the MD */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (newport->state != DS_PORT_FREE) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (verbose) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "ds@%lx: %s: port already exists",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen port_id, __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (newport->domain_hdl == DS_DHDL_INVALID) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen newport->domain_hdl = dhdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (newport->domain_name == NULL && dom_name != NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen newport->domain_name = ds_strdup(dom_name);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EBUSY);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* initialize the port */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen newport->id = port_id;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen newport->ldc.id = ldc_id;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen newport->domain_hdl = dhdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (dom_name) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen newport->domain_name = ds_strdup(dom_name);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen newport->domain_name = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_port_common_init(newport);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_remove_port(uint64_t port_id, int is_fini)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_port_t *port;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (port_id >= DS_MAX_PORTS || !DS_PORT_IN_SET(ds_allports, port_id)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_MD(CE_NOTE, "%s: invalid port %lx", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen port_id);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_MD(CE_NOTE, "%s: removing port ds@%lx", __func__, port_id);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen port = &ds_ports[port_id];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&port->lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (port->state >= DS_PORT_LDC_INIT) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* shut down the LDC for this port */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_ldc_fini(port);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&port->lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (port->domain_name) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(port->domain_name, strlen(port->domain_name) + 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen port->domain_name = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen port->domain_hdl = DS_DHDL_INVALID;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* clean up the port structure */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_port_common_fini(port, is_fini);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Interface for ds_service_lookup in lds driver.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_service_lookup(ds_svc_hdl_t hdl, char **servicep, uint_t *is_client)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((svc = ds_get_svc(hdl)) == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG(CE_NOTE, "%s: handle 0x%llx not found", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (u_longlong_t)hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *servicep = svc->cap.svc_id;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *is_client = svc->flags & DSSF_ISCLIENT;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Interface for ds_domain_lookup in lds driver.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_domain_lookup(ds_svc_hdl_t hdl, ds_domain_hdl_t *dhdlp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((svc = ds_get_svc(hdl)) == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG(CE_NOTE, "%s: handle 0x%llx not found", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (u_longlong_t)hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (svc->port == NULL)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *dhdlp = ds_my_domain_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen else
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *dhdlp = svc->port->domain_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Interface for ds_hdl_isready in lds driver.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_hdl_isready(ds_svc_hdl_t hdl, uint_t *is_ready)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((svc = ds_get_svc(hdl)) == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG(CE_NOTE, "%s: handle 0x%llx not found", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (u_longlong_t)hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *is_ready = (svc->state == DS_SVC_ACTIVE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Interface for ds_dom_name_to_hdl in lds driver.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_dom_name_to_hdl(char *domain_name, ds_domain_hdl_t *dhdlp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int i;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_port_t *port;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (domain_name == NULL) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen return (ENXIO);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (ds_my_domain_name != NULL &&
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen strcmp(ds_my_domain_name, domain_name) == 0) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen *dhdlp = ds_my_domain_hdl;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen return (0);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (i = 0, port = ds_ports; i < DS_MAX_PORTS; i++, port++) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (port->state != DS_PORT_FREE &&
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen port->domain_name != NULL &&
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen strcmp(port->domain_name, domain_name) == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *dhdlp = port->domain_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Interface for ds_dom_hdl_to_name in lds driver.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_dom_hdl_to_name(ds_domain_hdl_t dhdl, char **domain_namep)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int i;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_port_t *port;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (dhdl == ds_my_domain_hdl) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (ds_my_domain_name != NULL) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen *domain_namep = ds_my_domain_name;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen return (0);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen return (ENXIO);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (i = 0, port = ds_ports; i < DS_MAX_PORTS; i++, port++) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (port->state != DS_PORT_FREE &&
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen port->domain_hdl == dhdl) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *domain_namep = port->domain_name;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Unregister all handles related to device open instance.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_unreg_all(int instance)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int idx;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_hdl_t hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_USR(CE_NOTE, "%s: entered", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* walk every table entry */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (idx = 0; idx < ds_svcs.maxsvcs; idx++) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen svc = ds_svcs.tbl[idx];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (DS_SVC_ISFREE(svc))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen continue;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((svc->flags & DSSF_ISUSER) != 0 && svc->drvi == instance) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl = svc->hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) ds_unreg_hdl(hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_USR(CE_NOTE, "%s: ds_unreg_hdl(0x%llx):",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, (u_longlong_t)hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Special callbacks to allow the lds module revision-independent access
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * to service structure data in the callback routines. This assumes that
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * we put a special "cookie" in the arg argument passed to those
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * routines (for now, a ptr to the svc structure, but it could be a svc
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * table index or something that we could get back to the svc table entry).
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_cbarg_get_hdl(ds_cb_arg_t arg, ds_svc_hdl_t *hdlp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc = (ds_svc_t *)arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(svc == (ds_svc_t *)svc->ops.cb_arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *hdlp = svc->hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_cbarg_get_flags(ds_cb_arg_t arg, uint32_t *flagsp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc = (ds_svc_t *)arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(svc == (ds_svc_t *)svc->ops.cb_arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *flagsp = svc->flags;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_cbarg_get_drv_info(ds_cb_arg_t arg, int *drvip)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc = (ds_svc_t *)arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(svc == (ds_svc_t *)svc->ops.cb_arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *drvip = svc->drvi;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_cbarg_get_drv_per_svc_ptr(ds_cb_arg_t arg, void **dpspp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc = (ds_svc_t *)arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(svc == (ds_svc_t *)svc->ops.cb_arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *dpspp = svc->drv_psp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_cbarg_get_domain(ds_cb_arg_t arg, ds_domain_hdl_t *dhdlp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc = (ds_svc_t *)arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(svc == (ds_svc_t *)svc->ops.cb_arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (svc->port == NULL)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *dhdlp = ds_my_domain_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen else
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *dhdlp = svc->port->domain_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_cbarg_get_service_id(ds_cb_arg_t arg, char **servicep)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc = (ds_svc_t *)arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(svc == (ds_svc_t *)svc->ops.cb_arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *servicep = svc->cap.svc_id;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_cbarg_set_drv_per_svc_ptr(ds_cb_arg_t arg, void *dpsp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc = (ds_svc_t *)arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(svc == (ds_svc_t *)svc->ops.cb_arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen svc->drv_psp = dpsp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvoid
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_cbarg_set_cookie(ds_svc_t *svc)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen svc->ops.cb_arg = (ds_cb_arg_t)(svc);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_hdl_get_cbarg(ds_svc_hdl_t hdl, ds_cb_arg_t *cbargp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((svc = ds_get_svc(hdl)) != NULL &&
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (svc->flags & DSSF_ISUSER) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(svc == (ds_svc_t *)svc->ops.cb_arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *cbargp = svc->ops.cb_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensends_is_my_hdl(ds_svc_hdl_t hdl, int instance)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_t *svc;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((svc = ds_get_svc(hdl)) == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_USR(CE_NOTE, "%s: invalid hdl: 0x%llx\n", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (u_longlong_t)hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = ENXIO;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else if (instance == DS_INVALID_INSTANCE) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((svc->flags & DSSF_ISUSER) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_USR(CE_NOTE, "%s: unowned hdl: 0x%llx\n",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, (u_longlong_t)hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = EACCES;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else if ((svc->flags & DSSF_ISUSER) == 0 || svc->drvi != instance) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_USR(CE_NOTE, "%s: unowned hdl: 0x%llx\n", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (u_longlong_t)hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = EACCES;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&ds_svcs.lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}