vlds.c revision a600f50d43405fe4fd9ab16cc92b28df19656392
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/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Use is subject to license terms.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * LDOMs Domain Services Device Driver
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/types.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/file.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/errno.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/open.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/cred.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/uio.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/stat.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/ksynch.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/modctl.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/conf.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/devops.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/debug.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/cmn_err.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/ddi.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/sunddi.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/taskq.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/disp.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#include <sys/vlds.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/bitmap.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#include <sys/sysevent.h>
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic dev_info_t *vlds_devi;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensentypedef struct vlds_state {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dev_info_t *dip;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int instance;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen evchan_t *evchan;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen} vlds_state_t;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void *vlds_statep;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensentypedef struct vlds_recv_hdr {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen struct vlds_recv_hdr *next; /* next in recv list */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen void *data; /* the data itself */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t datasz; /* size of the data */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen} vlds_recv_hdr_t;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensentypedef struct vlds_svc_info {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int state; /* driver svc info state VLDS_RECV* */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_recv_hdr_t *recv_headp; /* ptr to head of recv queue */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_recv_hdr_t *recv_tailp; /* ptr to tail of recv queue */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t recv_size; /* no. of bytes in recv queue */
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen uint_t recv_cnt; /* no of messages in recv queue */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmutex_t recv_lock; /* lock for recv queue */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kcondvar_t recv_cv; /* condition variable for recv queue */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int recv_nreaders; /* no of currently waiting readers */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen} vlds_svc_info_t;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#define VLDS_RECV_OK 1
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#define VLDS_RECV_UNREG_PENDING 2
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen#define VLDS_RECV_OVERFLOW 3
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_ports_inited = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic uint_t vlds_flags_to_svc(uint64_t flags);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#define VLDS_NAME "vlds"
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_open(dev_t *devp, int flag, int otyp, cred_t *credp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_close(dev_t dev, int flag, int otyp, cred_t *credp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int *rvalp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen void **resultp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* mdeg register functions */
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic void vlds_mdeg_init(void);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic int vlds_mdeg_cb(void *cb_argp, mdeg_result_t *resp);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic int vlds_mdeg_register(void);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic int vlds_mdeg_unregister(void);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic int vlds_add_mdeg_port(md_t *mdp, mde_cookie_t node);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* driver utilities */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void vlds_user_reg_cb(ds_cb_arg_t arg, ds_ver_t *ver, ds_svc_hdl_t hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void vlds_user_unreg_cb(ds_cb_arg_t arg);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void vlds_user_data_cb(ds_cb_arg_t arg, void *buf, size_t buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void vlds_recvq_init(vlds_svc_info_t *dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void vlds_recvq_destroy(vlds_svc_info_t *dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_recvq_get_data(vlds_svc_info_t *dpsp, void *buf, size_t buflen,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t *msglenp, int mode);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void vlds_recvq_drain(vlds_svc_info_t *dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_recvq_put_data(vlds_svc_info_t *dpsp, void *buf, size_t buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int vlds_recv_msg(ds_svc_hdl_t hdl, void *buf, size_t buflen,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t *msglenp, int mode);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * DS driver Ops Vector
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic struct cb_ops vlds_cb_ops = {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_open, /* cb_open */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_close, /* cb_close */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* cb_strategy */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* cb_print */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* cb_dump */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* cb_read */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* cb_write */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_ioctl, /* cb_ioctl */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* cb_devmap */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* cb_mmap */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* cb_segmap */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nochpoll, /* cb_chpoll */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ddi_prop_op, /* cb_prop_op */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (struct streamtab *)NULL, /* cb_str */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen D_MP | D_64BIT, /* cb_flag */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen CB_REV, /* cb_rev */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* cb_aread */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev /* cb_awrite */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen};
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic struct dev_ops vlds_dev_ops = {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DEVO_REV, /* devo_rev */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen 0, /* devo_refcnt */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_getinfo, /* devo_getinfo */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nulldev, /* devo_identify */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nulldev, /* devo_probe */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_attach, /* devo_attach */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_detach, /* devo_detach */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nodev, /* devo_reset */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen &vlds_cb_ops, /* devo_cb_ops */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (struct bus_ops *)NULL, /* devo_bus_ops */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nulldev /* devo_power */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen};
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic struct modldrv modldrv = {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen &mod_driverops,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "Domain Services Driver 1.0",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen &vlds_dev_ops
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen};
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic struct modlinkage modlinkage = {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen MODREV_1,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void *)&modldrv,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen NULL
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen};
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Callback ops for user-land services.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic ds_clnt_ops_t ds_user_ops = {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_user_reg_cb, /* register */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_user_unreg_cb, /* unregister */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_user_data_cb, /* data */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen NULL /* ds_ucap_init will fill in */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen};
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensenstatic size_t vlds_recvq_maxsize = DS_STREAM_MTU * 8;
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensenstatic uint_t vlds_recvq_maxmsg = 16;
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#define VLDS_MINOR_MAX SHRT_MAX
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* Definitions for binding handle array */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic ulong_t vlds_bitmap_initial = 1; /* index 0 indicates error */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic ulong_t *vlds_minor_bitmap = &vlds_bitmap_initial;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic size_t vlds_minor_bits = BT_NBIPUL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic kmutex_t vlds_minor_mutex;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Following vlds_minor_* routines map a binding handle to a minor number.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Has to be called w/ locks held.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic ulong_t *
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_minor_alloc(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ulong_t *bhst = vlds_minor_bitmap;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* Increase bitmap by one BT_NBIPUL */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (vlds_minor_bits + BT_NBIPUL > VLDS_MINOR_MAX) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return ((ulong_t *)NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_minor_bitmap = kmem_zalloc(
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen BT_SIZEOFMAP(vlds_minor_bits + BT_NBIPUL), KM_SLEEP);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen bcopy(bhst, vlds_minor_bitmap, BT_SIZEOFMAP(vlds_minor_bits));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (bhst != &vlds_bitmap_initial)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(bhst, BT_SIZEOFMAP(vlds_minor_bits));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_minor_bits += BT_NBIPUL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (vlds_minor_bitmap);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_minor_free(ulong_t *bitmap)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (bitmap != &vlds_bitmap_initial)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(bitmap, BT_SIZEOFMAP(vlds_minor_bits));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic index_t
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_minor_get(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen index_t idx;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ulong_t *bhst;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* Search for an available index */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&vlds_minor_mutex);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((idx = bt_availbit(vlds_minor_bitmap,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_minor_bits)) == -1) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* All busy - allocate additional binding handle bitmap space */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((bhst = vlds_minor_alloc()) == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* Reached our maximum of id's == SHRT_MAX */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&vlds_minor_mutex);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_minor_bitmap = bhst;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen idx = bt_availbit(vlds_minor_bitmap, vlds_minor_bits);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen BT_SET(vlds_minor_bitmap, idx);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&vlds_minor_mutex);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (idx);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_minor_rele(index_t idx)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&vlds_minor_mutex);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(BT_TEST(vlds_minor_bitmap, idx) == 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen BT_CLEAR(vlds_minor_bitmap, idx);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&vlds_minor_mutex);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_minor_init(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_init(&vlds_minor_mutex, NULL, MUTEX_DEFAULT, NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen_init(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int s;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((s = ddi_soft_state_init(&vlds_statep, sizeof (vlds_state_t), 0))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen != 0)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (s);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((s = mod_install(&modlinkage)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ddi_soft_state_fini(&vlds_statep);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (s);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen vlds_mdeg_init();
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen (void) vlds_mdeg_register();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (s);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen_fini(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int s;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((s = mod_remove(&modlinkage)) != 0)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (s);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ddi_soft_state_fini(&vlds_statep);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen (void) vlds_mdeg_unregister();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (s);
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 Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*ARGSUSED*/
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen switch (cmd) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case DDI_INFO_DEVT2DEVINFO:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *resultp = vlds_devi;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_SUCCESS);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case DDI_INFO_DEVT2INSTANCE:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *resultp = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_SUCCESS);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (cmd != DDI_ATTACH) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_create_minor_node(devi, VLDS_NAME, S_IFCHR,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen 0, DDI_PSEUDO, NULL) == DDI_FAILURE) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ddi_remove_minor_node(devi, NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_devi = devi;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_minor_init();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_SUCCESS);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*ARGSUSED*/
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (cmd != DDI_DETACH) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_minor_free(vlds_minor_bitmap);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ddi_remove_minor_node(devi, NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_SUCCESS);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*ARGSUSED*/
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_open(dev_t *devp, int flag, int otyp, cred_t *credp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int minor;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (otyp != OTYP_CHR)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (getminor(*devp) != 0)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen minor = vlds_minor_get();
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (minor == 0)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* All minors are busy */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EBUSY);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_soft_state_zalloc(vlds_statep, minor) != DDI_SUCCESS) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_minor_rele(minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENOMEM);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *devp = makedevice(getmajor(*devp), minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*ARGSUSED*/
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_close(dev_t dev, int flag, int otyp, cred_t *credp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int minor = (int)getminor(dev);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_state_t *sp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "vlds_close");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Unregister all handles associated with this process.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_unreg_all(minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (otyp != OTYP_CHR)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sp = ddi_get_soft_state(vlds_statep, minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (sp == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (sp->evchan) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sysevent_evc_unbind(sp->evchan);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sp->evchan = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ddi_soft_state_free(vlds_statep, minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_minor_rele(minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenint
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_init_sysevent(vlds_state_t *sp, uint32_t flags)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char evchan_name[MAX_CHNAME_LEN];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (flags & DSSF_ANYCB_VALID) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (sp->evchan) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: sysevent already bound",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) sprintf(evchan_name, VLDS_SYSEV_CHAN_FMT, ddi_get_pid());
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = sysevent_evc_bind(evchan_name, &sp->evchan,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen EVCH_CREAT|EVCH_HOLD_PEND)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "%s: can't bind to '%s' (%d)",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, evchan_name, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: sysevent bind to '%s' successful",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, evchan_name);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#define ARGTOPTR(x) ((void *)((uintptr_t)(x)))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#define ARGTOUINT(x) ((uint_t)(x))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen#define ARGTOINT(x) ((int)(x))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_get_string(vlds_string_t *strp, char **rstrp, int mode)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *str;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint_t len = strp->vlds_strlen;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint_t slen;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (len == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *rstrp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (len > MAXNAMELEN) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: invalid string length: %d", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen len);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen str = DS_MALLOC(len);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin(ARGTOPTR(strp->vlds_strp), str, len, mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: ddi copyin failed (%p)", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ARGTOPTR(strp->vlds_strp));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(str, len);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen slen = strlen(str) + 1;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (slen != len) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: invalid string len: %d != len: %d",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, slen, len);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(str, len);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *rstrp = str;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_put_string(char *str, vlds_string_t *strp, int mode)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint_t len;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *tstr = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (str == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen str = "";
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen len = strlen(str) + 1;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * If string is longer than user buffer, return a
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * truncated, null-terminated string.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (len > strp->vlds_strlen) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen len = strp->vlds_strlen;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (len > 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen tstr = DS_MALLOC(len);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) memcpy(tstr, str, len - 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen tstr[len - 1] = '\0';
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen str = tstr;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = ddi_copyout(str, ARGTOPTR(strp->vlds_strp), len, mode);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (tstr) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(tstr, len);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: copyout (%p) failed", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ARGTOPTR(strp->vlds_strp));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_get_ucap(vlds_cap_t *capp, ds_capability_t *ucap, int mode)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *servp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_ver_t *dsvp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_cap_t vlds_cap;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint_t n;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint_t nver;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int i;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin(capp, &vlds_cap, sizeof (vlds_cap), mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: cap copyin failed (%p)", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void *)capp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nver = ARGTOUINT(vlds_cap.vlds_nver);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nver > VLDS_MAX_VERS) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: vlds_nver (%d) invalid", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nver);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = vlds_get_string(&vlds_cap.vlds_service, &servp, mode)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: vlds_get_string vlds_service failed "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "(%d)", __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else if (servp == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: vlds_get_string vlds_service is NULL",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen n = nver * sizeof (vlds_ver_t);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dsvp = DS_MALLOC(n);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin(ARGTOPTR(vlds_cap.vlds_versp), dsvp, n, mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: copyin of vers (%p, %d) failed",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, ARGTOPTR(vlds_cap.vlds_versp), n);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(servp, strlen(servp) + 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(dsvp, n);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ucap->svc_id = servp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ucap->vers = DS_MALLOC(nver * sizeof (ds_ver_t));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (i = 0; i < nver; i++) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ucap->vers[i].major = dsvp[i].vlds_major;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ucap->vers[i].minor = dsvp[i].vlds_minor;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ucap->nvers = nver;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(dsvp, n);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_free_ucap(ds_capability_t *ucap)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(ucap->svc_id, strlen(ucap->svc_id) + 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(ucap->vers, ucap->nvers * sizeof (ds_ver_t));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*ARGSUSED*/
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int *rvalp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_state_t *sp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_hdl_t hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_domain_hdl_t dhdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *servicep;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int minor = (int)getminor(dev);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((sp = ddi_get_soft_state(vlds_statep, minor)) == NULL)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen switch (cmd) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case VLDS_SVC_REG:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_svc_reg_arg_t vlds_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_capability_t ucap;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t hdl_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint_t flags;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin((void *)arg, &vlds_arg, sizeof (vlds_arg),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SVC REG arg copyin failed",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = vlds_get_ucap(ARGTOPTR(vlds_arg.vlds_capp), &ucap,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SVC REG get_ucap failed (%d)",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen flags = vlds_flags_to_svc(vlds_arg.vlds_reg_flags);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = vlds_init_sysevent(sp, flags)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_free_ucap(&ucap);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = ds_ucap_init(&ucap, &ds_user_ops,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_flags_to_svc(vlds_arg.vlds_reg_flags) | DSSF_ISUSER,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen minor, &hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_free_ucap(&ucap);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SVC REG ds_ucap_init failed "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "(%d)", __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl_arg = hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyout(&hdl_arg, ARGTOPTR(vlds_arg.vlds_hdlp),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sizeof (hdl_arg), mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SVC REG copyout failed",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SVC REG succeeded: hdl: %lx",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case VLDS_UNREG_HDL:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_unreg_hdl_arg_t vlds_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin((void *)arg, &vlds_arg, sizeof (vlds_arg),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: UNREG_HDL arg copyin failed",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl = vlds_arg.vlds_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_is_my_hdl(hdl, minor)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: UNREG_HDL ds_is_my_hdl "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " hdl: %lx inst: %d failed (%d)", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl, rv, minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_unreg_hdl(hdl)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: UNREG_HDL ds_cap_unreg "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " hdl: %lx failed (%d)", __func__, hdl, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: UNREG_HDL hdl: %lx succeeded",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case VLDS_HDL_LOOKUP:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_hdl_lookup_arg_t vlds_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_hdl_t *hdlsp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint_t is_client, maxhdls, nhdls;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t nhdls_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin((void *)arg, &vlds_arg, sizeof (vlds_arg),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_LOOKUP arg copyin failed",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen is_client = ARGTOUINT(vlds_arg.vlds_isclient);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen maxhdls = ARGTOUINT(vlds_arg.vlds_maxhdls);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (maxhdls == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_LOOKUP invalid maxhdls "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "%d", __func__, maxhdls);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = vlds_get_string(&vlds_arg.vlds_service, &servicep,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_LOOKUP vlds_get_string "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "(service) failed (%d)", __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else if (servicep == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_LOOKUP vlds_get_string "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " service is NULL", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ARGTOPTR(vlds_arg.vlds_hdlsp) == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdlsp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdlsp = DS_MALLOC(maxhdls * sizeof (*hdlsp));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_LOOKUP (%s, %d) entered",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, servicep, is_client);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = ds_hdl_lookup(servicep, is_client, hdlsp, maxhdls, &nhdls);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(servicep, strlen(servicep) + 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (hdlsp) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(hdlsp, maxhdls * sizeof (*hdlsp));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_LOOKUP failed: (%d)",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (hdlsp != NULL && nhdls > 0 &&
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ddi_copyout(hdlsp, ARGTOPTR(vlds_arg.vlds_hdlsp),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nhdls * sizeof (ds_svc_hdl_t), mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (hdlsp) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(hdlsp, maxhdls * sizeof (*hdlsp));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_LOOKUP copyout of hdls "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " failed", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (hdlsp) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(hdlsp, maxhdls * sizeof (*hdlsp));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nhdls_arg = nhdls;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyout(&nhdls_arg, ARGTOPTR(vlds_arg.vlds_nhdlsp),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sizeof (nhdls_arg), mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_LOOKUP copyout of nhdls "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " failed", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_LOOKUP succeeded: nhdls: %d",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, nhdls);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case VLDS_DMN_LOOKUP:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_dmn_lookup_arg_t vlds_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t dhdl_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin((void *)arg, &vlds_arg, sizeof (vlds_arg),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DMN_LOOKUP arg copyin failed",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl = vlds_arg.vlds_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_domain_lookup(hdl, &dhdl)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DMN_LOOKUP lookup hdl: 0x%lx "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed (%d)", __func__, hdl, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dhdl_arg = dhdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyout(&dhdl_arg, ARGTOPTR(vlds_arg.vlds_dhdlp),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sizeof (dhdl_arg), mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DMN_LOOKUP copyout "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed (%d)", __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DMN_LOOKUP hdl: 0x%lx, dhdl: 0x%lx "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "succeeded", __func__, hdl, dhdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case VLDS_SEND_MSG:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_send_msg_arg_t vlds_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t buflen;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *bufp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin((void *)arg, &vlds_arg, sizeof (vlds_arg),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SEND_MSG arg copyin failed",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl = vlds_arg.vlds_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_is_my_hdl(hdl, minor)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SEND_MSG ds_is_my_hdl "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " hdl: %lx inst: %d failed (%d)", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl, rv, minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen buflen = ARGTOUINT(vlds_arg.vlds_buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen bufp = DS_MALLOC(buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SEND_MSG (hdl: %lx, bufp: %p, "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "buflen: %ld", __func__, hdl, ARGTOPTR(vlds_arg.vlds_bufp),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin(ARGTOPTR(vlds_arg.vlds_bufp), bufp, buflen,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SEND_MSG buf (%p, %ld) "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "copyin failed", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ARGTOPTR(vlds_arg.vlds_bufp), buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(bufp, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_cap_send(hdl, bufp, buflen)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(bufp, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SEND_MSG ds_cap_send failed "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "(%d)", __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: SEND_MSG hdl: %lx, bufp: %p, "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "buflen: %ld succeeded", __func__, hdl, (void *)bufp,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DUMP_MSG(DS_DBG_FLAG_VLDS, bufp, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(bufp, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case VLDS_RECV_MSG:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_recv_msg_arg_t vlds_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t buflen, msglen;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t msglen_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin((void *)arg, &vlds_arg, sizeof (vlds_arg),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: RECV_MSG arg copyin failed",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl = vlds_arg.vlds_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_is_my_hdl(hdl, minor)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: RECV_MSG ds_is_my_hdl "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " hdl: %lx inst: %d failed (%d)", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl, rv, minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen buflen = ARGTOUINT(vlds_arg.vlds_buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = vlds_recv_msg(hdl, ARGTOPTR(vlds_arg.vlds_bufp),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen buflen, &msglen, mode)) != 0 && rv != EFBIG) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: RECV_MSG vlds_recv_msg "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " failed (%d)", __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen msglen_arg = msglen;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyout(&msglen_arg, ARGTOPTR(vlds_arg.vlds_msglenp),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sizeof (msglen_arg), mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: RECV_MSG copyout of msglen "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv == EFBIG) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFBIG);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: RECV_MSG hdl: %lx, "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "msglen: %ld succeeded", __func__, hdl, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case VLDS_HDL_ISREADY:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_hdl_isready_arg_t vlds_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_hdl_t hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t is_ready_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint_t is_ready;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin((void *)arg, &vlds_arg, sizeof (vlds_arg),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_ISREADY arg copyin "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl = vlds_arg.vlds_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_hdl_isready(hdl, &is_ready)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_ISREADY ds_hdl_isready "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "error (%d)", __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen is_ready_arg = is_ready;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyout(&is_ready_arg, ARGTOPTR(vlds_arg.vlds_isreadyp),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sizeof (is_ready_arg), mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_ISREADY copyout of "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "vlds_isready failed", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: HDL_ISREADY succeeded hdl: %lx, "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "is_ready: %d", __func__, hdl, is_ready);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case VLDS_DOM_NAM2HDL:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_dom_nam2hdl_arg_t vlds_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *domain_name;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t dhdl_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_domain_hdl_t dhdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin((void *)arg, &vlds_arg, sizeof (vlds_arg),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_NAM2HDL arg copyin "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = vlds_get_string(&vlds_arg.vlds_domain_name,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen &domain_name, mode)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_NAM2HDL vlds_get_string "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "domain_name failed (%d)", __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else if (servicep == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_NAM2HDL vlds_get_string "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " domain_name is NULL", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_NAM2HDL (%s) entered", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen domain_name);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_dom_name_to_hdl(domain_name, &dhdl)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_NAM2HDL name: '%s' "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed: (%d)", __func__, domain_name, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(domain_name, strlen(domain_name) + 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dhdl_arg = dhdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyout(&dhdl_arg, ARGTOPTR(vlds_arg.vlds_dhdlp),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sizeof (dhdl_arg), mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(domain_name, strlen(domain_name) + 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_NAM2HDL copyout of dhdl "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " failed", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_NAM2HDL succeeded: name: '%s', "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "dhdl: 0x%lx", __func__, domain_name, dhdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(domain_name, strlen(domain_name) + 1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen case VLDS_DOM_HDL2NAM:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_dom_hdl2nam_arg_t vlds_arg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_domain_hdl_t dhdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *domain_name;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (ddi_copyin((void *)arg, &vlds_arg, sizeof (vlds_arg),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mode) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_HDL2NAM arg copyin "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dhdl = vlds_arg.vlds_dhdl;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if ((rv = ds_dom_hdl_to_name(dhdl, &domain_name)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_HDL2NAM lookup dhdl: %lx "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed (%d)", __func__, dhdl, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = vlds_put_string(domain_name,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen &vlds_arg.vlds_domain_name, mode)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_HDL2NAM vlds_put_string "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "'%s' failed (%d)", __func__, domain_name, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: DOM_HDL2NAM dhdl: 0x%lx name: '%s'",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, dhdl, domain_name);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen default:
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic uint_t
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_flags_to_svc(uint64_t flags)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint_t sflags = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (flags & VLDS_REG_CLIENT)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sflags |= DSSF_ISCLIENT;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (flags & VLDS_REGCB_VALID)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sflags |= DSSF_REGCB_VALID;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (flags & VLDS_UNREGCB_VALID)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sflags |= DSSF_UNREGCB_VALID;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (flags & VLDS_DATACB_VALID)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sflags |= DSSF_DATACB_VALID;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (sflags);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * MD registration code.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Placed in vlds rather than ds module due to cirular dependency of
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * platsvc module which contains the mdeg code.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenmdeg_handle_t vlds_mdeg_hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen * Look for "virtual-device-service" node among the
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen * "virtual-device" nodes.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic mdeg_prop_spec_t vlds_prop_template[] = {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen { MDET_PROP_STR, "name", VLDS_MD_VIRT_ROOT_NAME },
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen { MDET_LIST_END, NULL, NULL }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen};
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic mdeg_node_spec_t vlds_node_template =
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen { VLDS_MD_VIRT_DEV_NAME, vlds_prop_template };
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Matching criteria passed to the MDEG to register interest
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * in changes to domain services port nodes identified by their
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * 'id' property.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic md_prop_match_t vlds_port_prop_match[] = {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen { MDET_PROP_VAL, "id" },
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen { MDET_LIST_END, NULL }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen};
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic mdeg_node_match_t vlds_port_match = { VLDS_MD_VIRT_PORT_NAME,
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen vlds_port_prop_match };
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* mdeg callback */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenvlds_mdeg_cb(void *cb_argp, mdeg_result_t *resp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen _NOTE(ARGUNUSED(cb_argp))
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int idx;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t portno;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen md_t *mdp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mde_cookie_t node;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (resp == NULL) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_VLDS(CE_NOTE, "vlds_mdeg_cb: no result returned");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (MDEG_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: added=%d, removed=%d, matched=%d", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen resp->added.nelem, resp->removed.nelem, resp->match_prev.nelem);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* process added ports */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (idx = 0; idx < resp->added.nelem; idx++) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mdp = resp->added.mdp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen node = resp->added.mdep[idx];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: processing added node 0x%lx",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, node);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* attempt to add a port */
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if ((rv = vlds_add_mdeg_port(mdp, node)) != MDEG_SUCCESS) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (vlds_ports_inited) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_NOTE, "%s: unable to add port, "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "err = %d", __func__, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* process removed ports */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (idx = 0; idx < resp->removed.nelem; idx++) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mdp = resp->removed.mdp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen node = resp->removed.mdep[idx];
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: processing removed node 0x%lx",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, node);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* read in the port's id property */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (md_get_prop_val(mdp, node, "id", &portno)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_NOTE, "%s: node 0x%lx of removed list "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "has no 'id' property", __func__, node);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen continue;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* attempt to remove a port */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_remove_port(portno, 0)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_NOTE, "%s: unable to remove port %lu, "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " err %d", __func__, portno, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_ports_inited = 1;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (MDEG_SUCCESS);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* register callback to mdeg */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenvlds_mdeg_register(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_VLDS(CE_NOTE, "vlds_mdeg_register: entered");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* perform the registration */
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen rv = mdeg_register(&vlds_node_template, &vlds_port_match, vlds_mdeg_cb,
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen NULL, &vlds_mdeg_hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv != MDEG_SUCCESS) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen cmn_err(CE_NOTE, "vlds_mdeg_register: mdeg_register "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed, err = %d", rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (DDI_SUCCESS);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* unregister callback from mdeg */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenvlds_mdeg_unregister(void)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_VLDS(CE_NOTE, "vlds_mdeg_unregister: hdl=0x%lx", vlds_mdeg_hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen return (mdeg_unregister(vlds_mdeg_hdl));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenvlds_get_port_channel(md_t *mdp, mde_cookie_t node, uint64_t *ldc_id)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int num_nodes, nchan;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t listsz;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mde_cookie_t *listp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Find the channel-endpoint node(s) (which should be under this
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * port node) which contain the channel id(s).
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((num_nodes = md_node_count(mdp)) <= 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_NOTE, "%s: invalid number of channel-endpoint nodes "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "found (%d)", __func__, num_nodes);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (-1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* allocate space for node list */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen listsz = num_nodes * sizeof (mde_cookie_t);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen listp = kmem_alloc(listsz, KM_SLEEP);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nchan = md_scan_dag(mdp, node, md_find_name(mdp, "channel-endpoint"),
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen md_find_name(mdp, "fwd"), listp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nchan <= 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_NOTE, "%s: no channel-endpoint nodes found",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(listp, listsz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (-1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: %d channel-endpoint nodes found", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nchan);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* use property from first node found */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (md_get_prop_val(mdp, listp[0], "id", ldc_id)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_NOTE, "%s: channel-endpoint has no 'id' property",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(listp, listsz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (-1);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen kmem_free(listp, listsz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/* add a DS services port */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenvlds_add_mdeg_port(md_t *mdp, mde_cookie_t node)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t portno;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t ldc_id;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint64_t dhdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *dom_name;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* read in the port's id property */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (md_get_prop_val(mdp, node, "id", &portno)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_NOTE, "%s: node 0x%lx of added list has no "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "'id' property", __func__, node);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (MDEG_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (portno >= DS_MAX_PORTS) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_NOTE, "%s: found port number (%lu) "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "larger than maximum supported number of ports", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen portno);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (MDEG_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /* get all channels for this device (currently only one) */
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (vlds_get_port_channel(mdp, node, &ldc_id) == -1) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (MDEG_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (md_get_prop_val(mdp, node, VLDS_MD_REM_DOMAIN_HDL, &dhdl) != 0) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen cmn_err(CE_NOTE, "!ds%lx: %s no %s property", portno, __func__,
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen VLDS_MD_REM_DOMAIN_HDL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dhdl = DS_DHDL_INVALID;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (md_get_prop_str(mdp, node, VLDS_MD_REM_DOMAIN_NAME, &dom_name)
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen != 0) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen cmn_err(CE_NOTE, "!ds%lx: %s no %s property", portno, __func__,
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen VLDS_MD_REM_DOMAIN_NAME);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dom_name = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = ds_add_port(portno, ldc_id, dhdl, dom_name, vlds_ports_inited);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (vlds_ports_inited) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "ds%lx: %s LDC chan: %lx "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "failed err = %d", portno, __func__, ldc_id, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (MDEG_FAILURE);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "ds%lx: %s LDC chan: %lx inited", portno,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, ldc_id);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (MDEG_SUCCESS);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenstatic void
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensenvlds_mdeg_init(void)
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen{
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen md_t *mdp;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen int num_nodes;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen int listsz;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen mde_cookie_t rootnode;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen mde_cookie_t vldsnode;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen mde_cookie_t *vlds_nodes = NULL;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen int nvlds;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen int i;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen ds_domain_hdl_t dhdl;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen char *dom_name;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen char *svc_name;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if ((mdp = md_get_handle()) == NULL) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen cmn_err(CE_NOTE, "Unable to initialize machine description");
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen return;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen num_nodes = md_node_count(mdp);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen ASSERT(num_nodes > 0);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen listsz = num_nodes * sizeof (mde_cookie_t);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen /* allocate temporary storage for MD scans */
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen vlds_nodes = kmem_zalloc(listsz, KM_SLEEP);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen rootnode = md_root_node(mdp);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen ASSERT(rootnode != MDE_INVAL_ELEM_COOKIE);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen /*
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen * Search for Virtual Domain Service node.
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen */
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen nvlds = md_scan_dag(mdp, rootnode, md_find_name(mdp,
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen VLDS_MD_VIRT_DEV_NAME), md_find_name(mdp, "fwd"), vlds_nodes);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (nvlds <= 0) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_MD(CE_NOTE, "No '%s' nodes in MD",
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen VLDS_MD_VIRT_DEV_NAME);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen goto done;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen for (i = 0; i < nvlds; i++) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (md_get_prop_str(mdp, vlds_nodes[i], "name", &svc_name)) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_MD(CE_NOTE, "%s: missing 'name' property for"
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen " IO node %d\n", __func__, i);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen continue;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (strcmp(svc_name, VLDS_MD_VIRT_ROOT_NAME) == 0) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen vldsnode = vlds_nodes[i];
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen break;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (i >= nvlds) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_MD(CE_NOTE, "No '%s' node in MD",
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen VLDS_MD_VIRT_ROOT_NAME);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen goto done;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (md_get_prop_val(mdp, vldsnode, VLDS_MD_DOMAIN_HDL, &dhdl) != 0) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_MD(CE_NOTE, "No '%s' property for '%s' node in MD",
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen VLDS_MD_DOMAIN_HDL, VLDS_MD_VIRT_ROOT_NAME);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen dhdl = DS_DHDL_INVALID;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen if (md_get_prop_str(mdp, vldsnode, VLDS_MD_DOMAIN_NAME, &dom_name)
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen != 0) {
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_MD(CE_NOTE, "No '%s' property for '%s' node in MD",
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen VLDS_MD_DOMAIN_NAME, VLDS_MD_VIRT_ROOT_NAME);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen dom_name = NULL;
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen }
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_DBG_MD(CE_NOTE, "My Domain Hdl: 0x%lx, Name: '%s'", dhdl,
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen dom_name == NULL ? "NULL" : dom_name);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen ds_set_my_dom_hdl_name(dhdl, dom_name);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensendone:
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen DS_FREE(vlds_nodes, listsz);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen (void) md_fini_handle(mdp);
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen}
a600f50d43405fe4fd9ab16cc92b28df19656392Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_user_reg_cb(ds_cb_arg_t arg, ds_ver_t *ver, ds_svc_hdl_t hdl)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_t *nvl = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_domain_hdl_t dhdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen char *servicep;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint32_t flags;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int minor;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_state_t *sp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_svc_info_t *dpsp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_flags(arg, &flags);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT((flags & DSSF_ISUSER) != 0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((flags & DSSF_DATACB_VALID) == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * must allocate and init the svc read queue.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: hdl: 0x%lx initing recvq", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp = DS_MALLOC(sizeof (vlds_svc_info_t));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_recvq_init(dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_set_drv_per_svc_ptr(arg, dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((flags & DSSF_REGCB_VALID) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_drv_info(arg, &minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sp = ddi_get_soft_state(vlds_statep, minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(sp != NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(sp->evchan != NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_domain(arg, &dhdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_service_id(arg, &servicep);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: regcb: hdl: 0x%lx, ver%d.%d, "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " dhdl: 0x%lx", __func__, hdl, ver->major,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ver->minor, dhdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_add_uint64(nvl, VLDS_HDL, hdl) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_add_uint16(nvl, VLDS_VER_MAJOR, ver->major) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_add_uint16(nvl, VLDS_VER_MINOR, ver->minor) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_add_uint64(nvl, VLDS_DOMAIN_HDL, dhdl) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_add_string(nvl, VLDS_SERVICE_ID, servicep) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_add_boolean_value(nvl, VLDS_ISCLIENT,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (flags & DSSF_ISCLIENT) != 0) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sysevent_evc_publish(sp->evchan, EC_VLDS,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ESC_VLDS_REGISTER, "sun.com", "kernel", nvl, EVCH_SLEEP)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "Failed to send REG Callback");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: sysevent_evc_publish "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen "succeeded", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_free(nvl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_user_unreg_cb(ds_cb_arg_t arg)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_t *nvl = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int minor;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_hdl_t hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_state_t *sp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen void *dpsp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint32_t flags;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_flags(arg, &flags);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT((flags & DSSF_ISUSER) != 0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((flags & DSSF_DATACB_VALID) == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_drv_per_svc_ptr(arg, &dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (dpsp) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: unregcb draining recvq",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_recvq_drain(dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_recvq_destroy(dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_set_drv_per_svc_ptr(arg, NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((flags & DSSF_UNREGCB_VALID) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_hdl(arg, &hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: unregcb hdl: 0x%lx", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_drv_info(arg, &minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sp = ddi_get_soft_state(vlds_statep, minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(sp != NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(sp->evchan != NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_add_uint64(nvl, VLDS_HDL, hdl) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sysevent_evc_publish(sp->evchan, EC_VLDS,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ESC_VLDS_UNREGISTER, "sun.com", "kernel", nvl,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen EVCH_SLEEP)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "Failed to send UNREG Callback");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_free(nvl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_user_data_cb(ds_cb_arg_t arg, void *buf, size_t buflen)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_t *nvl = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_svc_hdl_t hdl;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int minor;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen void *dpsp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_state_t *sp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint32_t flags;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_flags(arg, &flags);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT((flags & DSSF_ISUSER) != 0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((flags & DSSF_DATACB_VALID) == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_drv_per_svc_ptr(arg, &dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(dpsp != NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: datacb: to recvq: buflen: %ld",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) vlds_recvq_put_data(dpsp, buf, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_hdl(arg, &hdl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: datacb: usercb: hdl: 0x%lx, "
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen " buflen: %ld", __func__, hdl, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_drv_info(arg, &minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sp = ddi_get_soft_state(vlds_statep, minor);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(sp != NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(sp->evchan != NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_add_uint64(nvl, VLDS_HDL, hdl) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_add_byte_array(nvl, VLDS_DATA, buf, buflen) ||
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen sysevent_evc_publish(sp->evchan, EC_VLDS,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ESC_VLDS_DATA, "sun.com", "kernel", nvl, EVCH_SLEEP)) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cmn_err(CE_WARN, "Failed to send DATA Callback");
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nvlist_free(nvl);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen/*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Initialize receive queue if request is from user land but
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * data callback is null (implying user will be using ds_recv_msg).
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_recvq_init(vlds_svc_info_t *dpsp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->state = VLDS_RECV_OK;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_init(&dpsp->recv_lock, NULL, MUTEX_DRIVER, NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cv_init(&dpsp->recv_cv, NULL, CV_DRIVER, NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_headp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_tailp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_size = 0;
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen dpsp->recv_cnt = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_recvq_destroy(vlds_svc_info_t *dpsp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(dpsp->state == VLDS_RECV_UNREG_PENDING);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(dpsp->recv_size == 0);
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen ASSERT(dpsp->recv_cnt == 0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(dpsp->recv_headp == NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(dpsp->recv_tailp == NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_destroy(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cv_destroy(&dpsp->recv_cv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(dpsp, sizeof (vlds_svc_info_t));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_recvq_get_data(vlds_svc_info_t *dpsp, void *buf, size_t buflen,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t *msglenp, int mode)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_recv_hdr_t *rhp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen size_t msglen;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen while (dpsp->recv_size == 0) {
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen ASSERT(dpsp->recv_cnt == 0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (dpsp->state == VLDS_RECV_UNREG_PENDING)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen break;
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen if (dpsp->state == VLDS_RECV_OVERFLOW) {
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen DS_DBG_RCVQ(CE_NOTE, "%s: user data queue overflow",
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen __func__);
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen dpsp->state = VLDS_RECV_OK;
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen mutex_exit(&dpsp->recv_lock);
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen return (ENOBUFS);
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Passing in a buflen of 0 allows user to poll for msgs.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (buflen == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *msglenp = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFBIG);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_nreaders += 1;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = cv_wait_sig(&dpsp->recv_cv, &dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_nreaders -= 1;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_RCVQ(CE_NOTE, "%s: signal EINTR", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINTR);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (dpsp->state == VLDS_RECV_UNREG_PENDING) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_RCVQ(CE_NOTE, "%s: unreg pending", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cv_broadcast(&dpsp->recv_cv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(dpsp->recv_headp != NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rhp = dpsp->recv_headp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Don't transfer truncated data, return EFBIG error if user-supplied
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * buffer is too small.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rhp->datasz > buflen) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *msglenp = rhp->datasz;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFBIG);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rhp == dpsp->recv_tailp) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_headp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_tailp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_headp = rhp->next;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ASSERT(dpsp->recv_headp != NULL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen ASSERT(dpsp->recv_cnt > 0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_size -= rhp->datasz;
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen dpsp->recv_cnt -= 1;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen msglen = rhp->datasz;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = ddi_copyout(rhp->data, buf, msglen, mode);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv == 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: user data dequeued msglen: %ld",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, rhp->datasz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DUMP_MSG(DS_DBG_FLAG_VLDS, rhp->data, rhp->datasz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(rhp->data, rhp->datasz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(rhp, sizeof (vlds_recv_hdr_t));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (rv != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: copyout failed", __func__);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EFAULT);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen *msglenp = msglen;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenuint64_t vlds_recv_drain_delay_time = 1 * MILLISEC;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic void
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_recvq_drain(vlds_svc_info_t *dpsp)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_recv_hdr_t *rhp, *nextp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->state = VLDS_RECV_UNREG_PENDING;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen for (rhp = dpsp->recv_tailp; rhp != NULL; rhp = nextp) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen nextp = rhp->next;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(rhp->data, rhp->datasz);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_FREE(rhp, sizeof (vlds_recv_hdr_t));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_headp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_tailp = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_size = 0;
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen dpsp->recv_cnt = 0;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen /*
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen * Make sure other readers have exited.
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen */
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen while (dpsp->recv_nreaders > 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cv_broadcast(&dpsp->recv_cv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen delay(vlds_recv_drain_delay_time);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_recvq_put_data(vlds_svc_info_t *dpsp, void *buf, size_t buflen)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen vlds_recv_hdr_t *rhp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_enter(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (dpsp->state != VLDS_RECV_UNREG_PENDING) {
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen /*
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen * If we've already encountered an overflow, or there
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen * are pending messages and either queue size and
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen * message limits will be exceeded with this message,
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen * we mark the recvq as overflowed and return an ENOBUFS
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen * error. This allows the enqueuing of one big message
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen * or several little messages.
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen */
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen if ((dpsp->state == VLDS_RECV_OVERFLOW) ||
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen ((dpsp->recv_cnt != 0) &&
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen ((dpsp->recv_size + buflen) > vlds_recvq_maxsize) ||
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen ((dpsp->recv_cnt + 1) > vlds_recvq_maxmsg))) {
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen DS_DBG_RCVQ(CE_NOTE, "%s: user data queue overflow",
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen __func__);
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen dpsp->state = VLDS_RECV_OVERFLOW;
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen cv_broadcast(&dpsp->recv_cv);
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen mutex_exit(&dpsp->recv_lock);
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen return (ENOBUFS);
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen }
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_RCVQ(CE_NOTE, "%s: user data enqueued msglen: %ld",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DUMP_MSG(DS_DBG_FLAG_RCVQ, buf, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rhp = DS_MALLOC(sizeof (vlds_recv_hdr_t));
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rhp->data = DS_MALLOC(buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen (void) memcpy(rhp->data, buf, buflen);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rhp->datasz = buflen;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rhp->next = NULL;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (dpsp->recv_headp == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_headp = rhp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_tailp = rhp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen } else {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_tailp->next = rhp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_tailp = rhp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen dpsp->recv_size += rhp->datasz;
ba9236fbcb49a99c7d71c0c25d1e45cb2a75ac78Mike Christensen dpsp->recv_cnt += 1;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen cv_broadcast(&dpsp->recv_cv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen mutex_exit(&dpsp->recv_lock);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (0);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenstatic int
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensenvlds_recv_msg(ds_svc_hdl_t hdl, void *buf, size_t buflen, size_t *msglenp,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int mode)
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen{
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen void *dpsp;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cb_arg_t cbarg;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen uint32_t flags;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen int rv;
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((rv = ds_hdl_get_cbarg(hdl, &cbarg)) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: handle %lx not found (%d)", __func__,
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen hdl, rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_flags(cbarg, &flags);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if ((flags & DSSF_ISUSER) == 0 || (flags & DSSF_DATACB_VALID) != 0) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: invalid flags: %x", __func__, flags);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (EINVAL);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen ds_cbarg_get_drv_per_svc_ptr(cbarg, &dpsp);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen if (dpsp == NULL) {
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen DS_DBG_VLDS(CE_NOTE, "%s: recv on non-ready handle: %x",
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen __func__, flags);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (ENXIO);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen }
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen rv = vlds_recvq_get_data(dpsp, buf, buflen, msglenp, mode);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen return (rv);
30588217a56ff2c9137248fb2e5065c4f0101459Mike Christensen}