e11c3f44f531fdff80941ce57c065d2ae861cefcmeem/*
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * CDDL HEADER START
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem *
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * The contents of this file are subject to the terms of the
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * Common Development and Distribution License (the "License").
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * You may not use this file except in compliance with the License.
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem *
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * or http://www.opensolaris.org/os/licensing.
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * See the License for the specific language governing permissions
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * and limitations under the License.
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem *
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * When distributing Covered Code, include this CDDL HEADER in each
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * If applicable, add the following below this CDDL HEADER, with the
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * fields enclosed by brackets "[]" replaced with your own identifying
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * information: Portions Copyright [yyyy] [name of copyright owner]
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem *
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * CDDL HEADER END
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem/*
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * Use is subject to license terms.
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem/*
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * DLPI stub driver; currently supports VNI and IPMP stub devices.
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/conf.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/ddi.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/sunddi.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/dlpi.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/stat.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/strsun.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/stropts.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/types.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/id_space.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/sysmacros.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/kmem.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/modctl.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/mkdev.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include <sys/sdt.h>
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem#include "dlpistub_impl.h"
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic id_space_t *ds_minors;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic dev_info_t *ds_dip;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem/*
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem * DL_INFO_ACK template.
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic dl_info_ack_t ds_infoack = {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem DL_INFO_ACK, /* dl_primitive */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_max_sdu */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_min_sdu */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_addr_length */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_mac_type */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_reserved */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_current_state */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_sap_length */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem DL_CLDLS, /* dl_service_mode */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_qos_length */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_qos_offset */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_qos_range_length */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_qos_range_offset */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem DL_STYLE2, /* dl_provider_style */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_addr_offset */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem DL_VERSION_2, /* dl_version */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_brdcst_addr_length */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* dl_brdcst_addr_offset */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0 /* dl_growth */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem};
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic int
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemds_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (cmd != DDI_ATTACH)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (DDI_FAILURE);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (ddi_create_minor_node(dip, "vni", S_IFCHR, DS_MINOR_VNI,
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem DDI_PSEUDO, 0) == DDI_FAILURE ||
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ddi_create_minor_node(dip, "ipmpstub", S_IFCHR, DS_MINOR_IPMP,
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem DDI_PSEUDO, 0) == DDI_FAILURE) {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ddi_remove_minor_node(dip, NULL);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem cmn_err(CE_NOTE, "ds_attach: cannot create minor nodes");
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (DDI_FAILURE);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem }
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ds_dip = dip;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ds_minors = id_space_create("ds_minors", DS_MINOR_START, MAXMIN32);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (DDI_SUCCESS);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic int
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemds_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (cmd != DDI_DETACH)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (DDI_FAILURE);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem id_space_destroy(ds_minors);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ds_minors = NULL;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ASSERT(dip == ds_dip);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ddi_remove_minor_node(dip, NULL);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ds_dip = NULL;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (DDI_SUCCESS);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem/* ARGSUSED */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic int
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemds_devinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem int error = DDI_FAILURE;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem switch (infocmd) {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DDI_INFO_DEVT2INSTANCE:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem *result = (void *)0;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem error = DDI_SUCCESS;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DDI_INFO_DEVT2DEVINFO:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (ds_dip != NULL) {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem *result = ds_dip;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem error = DDI_SUCCESS;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem }
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem }
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (error);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem/* ARGSUSED */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic int
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemds_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem int type;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlpistub_t *dsp;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (sflag == CLONEOPEN || sflag == MODOPEN)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (EINVAL);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (q->q_ptr != NULL)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem switch (getminor(*devp)) {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DS_MINOR_VNI:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem type = SUNW_DL_VNI;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DS_MINOR_IPMP:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem type = SUNW_DL_IPMP;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem default:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ENXIO);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem }
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dsp = kmem_zalloc(sizeof (dlpistub_t), KM_SLEEP);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dsp->ds_type = type;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dsp->ds_minor = (minor_t)id_alloc(ds_minors);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dsp->ds_state = DL_UNATTACHED;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem *devp = makedevice(getmajor(*devp), dsp->ds_minor);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem q->q_ptr = WR(q)->q_ptr = dsp;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem qprocson(q);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem/* ARGSUSED */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic int
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemds_close(queue_t *q, int flag, cred_t *credp)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlpistub_t *dsp = q->q_ptr;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem qprocsoff(q);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem q->q_ptr = WR(q)->q_ptr = NULL;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem id_free(ds_minors, dsp->ds_minor);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem kmem_free(dsp, sizeof (dlpistub_t));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic int
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemds_badprim(queue_t *q, mblk_t *mp, t_scalar_t prim)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlerrorack(q, mp, prim, DL_BADPRIM, 0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic int
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemds_outstate(queue_t *q, mblk_t *mp, t_scalar_t prim)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlerrorack(q, mp, prim, DL_OUTSTATE, 0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic int
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemds_wput(queue_t *q, mblk_t *mp)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem union DL_primitives *dlp;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dl_info_ack_t *dlip;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlpistub_t *dsp = q->q_ptr;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem t_scalar_t prim;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem switch (DB_TYPE(mp)) {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case M_PROTO:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case M_PCPROTO:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (MBLKL(mp) < sizeof (t_scalar_t)) {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlerrorack(q, mp, DL_PRIM_INVAL, DL_UNSUPPORTED, 0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem }
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlp = (void *)mp->b_rptr;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem prim = dlp->dl_primitive;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem switch (prim) {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DL_ATTACH_REQ:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (MBLKL(mp) < DL_ATTACH_REQ_SIZE)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_badprim(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (dsp->ds_state != DL_UNATTACHED)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_outstate(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dsp->ds_state = DL_UNBOUND;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlokack(q, mp, DL_ATTACH_REQ);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DL_BIND_REQ:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (MBLKL(mp) < DL_BIND_REQ_SIZE)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_badprim(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (dsp->ds_state != DL_UNBOUND)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_outstate(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dsp->ds_state = DL_IDLE;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlbindack(q, mp, dlp->bind_req.dl_sap, NULL, 0, 0, 0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DL_INFO_REQ:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (MBLKL(mp) < DL_INFO_REQ_SIZE)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_badprim(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem mp = mexchange(q, mp, sizeof (dl_info_ack_t),
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem M_PCPROTO, DL_INFO_ACK);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (mp != NULL) {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlip = (void *)mp->b_rptr;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem *dlip = ds_infoack;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlip->dl_mac_type = dsp->ds_type;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlip->dl_current_state = dsp->ds_state;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem qreply(q, mp);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem }
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DL_PHYS_ADDR_REQ:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (MBLKL(mp) < DL_PHYS_ADDR_REQ_SIZE)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_badprim(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlphysaddrack(q, mp, NULL, 0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DL_UNBIND_REQ:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (MBLKL(mp) < DL_UNBIND_REQ_SIZE)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_badprim(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (dsp->ds_state != DL_IDLE)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_outstate(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dsp->ds_state = DL_UNBOUND;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlokack(q, mp, DL_UNBIND_REQ);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DL_DETACH_REQ:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (MBLKL(mp) < DL_DETACH_REQ_SIZE)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_badprim(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (dsp->ds_state != DL_UNBOUND)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (ds_outstate(q, mp, prim));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dsp->ds_state = DL_UNATTACHED;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlokack(q, mp, DL_DETACH_REQ);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case DL_UNITDATA_REQ:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem DTRACE_PROBE2(dlpistub__data, dlpistub_t *, dsp,
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem mblk_t *, mp);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem freemsg(mp);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem default:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem dlerrorack(q, mp, prim, DL_UNSUPPORTED, 0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem }
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case M_IOCTL:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem miocnak(q, mp, 0, EINVAL);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem case M_FLUSH:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem *mp->b_rptr &= ~FLUSHW;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem if (*mp->b_rptr & FLUSHR)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem qreply(q, mp);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem else
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem freemsg(mp);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem default:
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem freemsg(mp);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem break;
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem }
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (0);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic struct module_info ds_minfo = {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem DS_IDNUM, /* mi_idnum */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem "dlpistub", /* mi_idname */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* mi_minpsz */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem INFPSZ, /* mi_maxpsz */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* mi_hiwat */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem 0, /* mi_lowat */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem};
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic struct qinit ds_rinit = {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem NULL, /* qi_putp */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem NULL, /* qi_srvp */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ds_open, /* qi_qopen */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ds_close, /* qi_qclose */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem NULL, /* qi_qadmin */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem &ds_minfo, /* qi_minfo */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem};
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic struct qinit ds_winit = {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem ds_wput, /* qi_putp */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem NULL, /* qi_srvp */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem NULL, /* qi_qopen */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem NULL, /* qi_qclose */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem NULL, /* qi_qadmin */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem &ds_minfo, /* qi_minfo */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem};
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic struct streamtab ds_info = {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem &ds_rinit, /* st_rdinit */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem &ds_winit /* st_wrinit */
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem};
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemDDI_DEFINE_STREAM_OPS(ds_ops, nulldev, nulldev, ds_attach, ds_detach,
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem nodev, ds_devinfo, D_MP|D_MTPERMOD, &ds_info, ddi_quiesce_not_supported);
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic struct modldrv modldrv = {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem &mod_driverops,
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem "DLPI stub driver",
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem &ds_ops,
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem};
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemstatic struct modlinkage modlinkage = {
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem MODREV_1, &modldrv, NULL
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem};
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemint
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem_init(void)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (mod_install(&modlinkage));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemint
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem_fini(void)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (mod_remove(&modlinkage));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
e11c3f44f531fdff80941ce57c065d2ae861cefcmeemint
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem_info(struct modinfo *modinfop)
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem{
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem return (mod_info(&modlinkage, modinfop));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem}