1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER START
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The contents of this file are subject to the terms of the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Common Development and Distribution License (the "License").
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You may not use this file except in compliance with the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * or http://www.opensolaris.org/os/licensing.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * See the License for the specific language governing permissions
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * and limitations under the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * When distributing Covered Code, include this CDDL HEADER in each
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If applicable, add the following below this CDDL HEADER, with the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * fields enclosed by brackets "[]" replaced with your own identifying
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * information: Portions Copyright [yyyy] [name of copyright owner]
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER END
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
193974072f41a843678abf5f61979c748687e66bSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Use is subject to license terms.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
a5eb7107f06a6e23e8e77e8d3a84c1ff90a73ac6Bryan Cantrill/*
a5eb7107f06a6e23e8e77e8d3a84c1ff90a73ac6Bryan Cantrill * Copyright (c) 2014, Joyent, Inc. All rights reserved.
a5eb7107f06a6e23e8e77e8d3a84c1ff90a73ac6Bryan Cantrill */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/types.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/file.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/errno.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/uio.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/open.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/cred.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/kmem.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/conf.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/cmn_err.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/ksynch.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/modctl.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/stat.h> /* needed for S_IFBLK and S_IFCHR */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/debug.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/promif.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/ddi.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/sunddi.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/cyclic.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/termio.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/intr.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/ivintr.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/note.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/stat.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/fcntl.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/sysmacros.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/ldc.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/mdeg.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/vcc_impl.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb#define VCC_LDC_RETRIES 5
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb#define VCC_LDC_DELAY 1000 /* usec */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Function prototypes.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* DDI entrypoints */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_open(dev_t *devp, int flag, int otyp, cred_t *cred);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_close(dev_t dev, int flag, int otyp, cred_t *cred);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cred_t *credp, int *rvalp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_read(dev_t dev, struct uio *uiop, cred_t *credp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_write(dev_t dev, struct uio *uiop, cred_t *credp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_chpoll(dev_t dev, short events, int anyyet,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo short *reventsp, struct pollhead **phpp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo void *arg, void **resultp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* callback functions */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic uint_t vcc_ldc_cb(uint64_t event, caddr_t arg);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int vcc_mdeg_cb(void *cb_argp, mdeg_result_t *resp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* Internal functions */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int i_vcc_ldc_init(vcc_t *vccp, vcc_port_t *vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int i_vcc_add_port(vcc_t *vccp, char *group_name, uint64_t tcp_port,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t portno, char *domain_name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int i_vcc_config_port(vcc_t *vccp, uint_t portno, uint64_t ldc_id);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int i_vcc_reset_events(vcc_t *vccp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int i_vcc_cons_tbl(vcc_t *vccp, uint_t num_ports,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo caddr_t buf, int mode);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int i_vcc_del_cons_ok(vcc_t *vccp, caddr_t buf, int mode);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int i_vcc_close_port(vcc_port_t *vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int i_vcc_write_ldc(vcc_port_t *vport, vcc_msg_t *buf);
7636cb21f250f0485ca6052ffadc80ace93e6358lmstatic int i_vcc_read_ldc(vcc_port_t *vport, char *data_buf, size_t *sz);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void *vcc_ssp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic struct cb_ops vcc_cb_ops = {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_open, /* open */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_close, /* close */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo nodev, /* strategy */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo nodev, /* print */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo nodev, /* dump */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_read, /* read */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_write, /* write */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_ioctl, /* ioctl */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo nodev, /* devmap */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo nodev, /* mmap */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_segmap, /* segmap */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_chpoll, /* chpoll */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_prop_op, /* prop_op */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo NULL, /* stream */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D_NEW | D_MP /* flags */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo};
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic struct dev_ops vcc_ops = {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo DEVO_REV, /* rev */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo 0, /* ref count */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_getinfo, /* getinfo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo nulldev, /* identify */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo nulldev, /* probe */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_attach, /* attach */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_detach, /* detach */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo nodev, /* reset */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo &vcc_cb_ops, /* cb_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore (struct bus_ops *)NULL, /* bus_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_needed, /* quiesce */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo};
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoextern struct mod_ops mod_driverops;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define VCC_CHANNEL_ENDPOINT "channel-endpoint"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define VCC_ID_PROP "id"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * This is the string displayed by modinfo(1m).
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
193974072f41a843678abf5f61979c748687e66bSherry Moorestatic char vcc_ident[] = "sun4v Virtual Console Concentrator Driver";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic struct modldrv md = {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo &mod_driverops, /* Type - it is a driver */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_ident, /* Name of the module */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo &vcc_ops, /* driver specfic opts */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo};
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic struct modlinkage ml = {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo MODREV_1,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo &md,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo NULL
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo};
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Matching criteria passed to the MDEG to register interest
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * in changes to 'virtual-device-port' nodes identified by their
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * 'id' property.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic md_prop_match_t vcc_port_prop_match[] = {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo { MDET_PROP_VAL, "id" },
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo { MDET_LIST_END, NULL }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo};
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic mdeg_node_match_t vcc_port_match = {"virtual-device-port",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_prop_match};
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Specification of an MD node passed to the MDEG to filter any
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * 'virtual-device-port' nodes that do not belong to the specified node.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * This template is copied for each vldc instance and filled in with
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * the appropriate 'cfg-handle' value before being passed to the MDEG.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic mdeg_prop_spec_t vcc_prop_template[] = {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo { MDET_PROP_STR, "name", "virtual-console-concentrator" },
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo { MDET_PROP_VAL, "cfg-handle", NULL },
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo { MDET_LIST_END, NULL, NULL }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo};
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define VCC_SET_MDEG_PROP_INST(specp, val) (specp)[1].ps_val = (val);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#ifdef DEBUG
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Print debug messages
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * set vldcdbg to 0xf to enable all messages
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * 0x8 - Errors
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * 0x4 - Warnings
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * 0x2 - All debug messages (most verbose)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * 0x1 - Minimal debug messages
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint vccdbg = 0x8;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovccdebug(const char *fmt, ...)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char buf[512];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo va_list ap;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo va_start(ap, fmt);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) vsprintf(buf, fmt, ap);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo va_end(ap);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "%s\n", buf);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define D1 \
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoif (vccdbg & 0x01) \
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccdebug
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define D2 \
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoif (vccdbg & 0x02) \
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccdebug
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define DWARN \
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoif (vccdbg & 0x04) \
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccdebug
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#else
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define D1
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define D2
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define DWARN
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* _init(9E): initialize the loadable module */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo_init(void)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int error;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* init the soft state structure */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo error = ddi_soft_state_init(&vcc_ssp, sizeof (vcc_t), 1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (error != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (error);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* Link the driver into the system */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo error = mod_install(&ml);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (error);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* _info(9E): return information about the loadable module */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo_info(struct modinfo *modinfop)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* Report status of the dynamically loadable driver module */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (mod_info(&ml, modinfop));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* _fini(9E): prepare the module for unloading. */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo_fini(void)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int error;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* Unlink the driver module from the system */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((error = mod_remove(&ml)) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * We have successfully "removed" the driver.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * destroy soft state
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_soft_state_fini(&vcc_ssp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (error);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* getinfo(9E) */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo _NOTE(ARGUNUSED(dip))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int instance = VCCINST(getminor((dev_t)arg));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp = NULL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo switch (cmd) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case DDI_INFO_DEVT2DEVINFO:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vccp = ddi_get_soft_state(vcc_ssp, instance)) == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *resultp = NULL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *resultp = vccp->dip;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case DDI_INFO_DEVT2INSTANCE:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *resultp = (void *)(uintptr_t)instance;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo default:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *resultp = NULL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * There are two cases that need special blocking. One of them is to block
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * a minor node without a port and another is to block application other
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * than vntsd.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * A minor node can exist in the file system without associated with a port
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * because when a port is deleted, ddi_remove_minor does not unlink it.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Clients might try to open a minor node even after the corresponding port
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * node has been removed. To identify and block these calls,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * we need to validate the association between a port and its minor node.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * An application other than vntsd can access a console port as long
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * as vntsd is not using the port. A port opened by an application other
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * than vntsd will be closed when vntsd wants to use the port.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * However, other application could use same file descriptor
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * access vcc cb_ops. So we need to identify and block caller other
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * than vntsd, when vntsd is using the port.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_can_use_port(vcc_minor_t *minorp, vcc_port_t *vport)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->minorp != minorp) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* port config changed */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->valid_pid == VCC_NO_PID_BLOCKING) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no blocking needed */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->valid_pid != ddi_get_pid()) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* Syncronization between thread using cv_wait */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_wait_port_status(vcc_port_t *vport, kcondvar_t *cv, uint32_t status)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(mutex_owned(&vport->lock));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (; ; ) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* port has been deleted */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_wait_port_status: port%d deleted\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_OPEN) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_wait_port_status: port%d is closed \n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_LDC_LINK_DOWN) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->valid_pid != VCC_NO_PID_BLOCKING) &&
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (vport->valid_pid != ddi_get_pid())) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & status) == status) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (!ddi_can_receive_sig()) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = cv_wait_sig(cv, &vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_wait_port_status: port%d get intr \n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* got signal */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINTR);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* Syncronization between threads, signal state change */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_set_port_status(vcc_port_t *vport, kcondvar_t *cv, uint32_t status)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= status;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_broadcast(cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* initialize a ldc channel */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_ldc_init(vcc_t *vccp, vcc_port_t *vport)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ldc_attr_t attr;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = EIO;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(mutex_owned(&vport->lock));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(vport->ldc_id != VCC_INVALID_CHANNEL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* initialize the channel */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo attr.devclass = LDC_DEV_SERIAL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo attr.instance = ddi_get_instance(vccp->dip);
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm attr.mtu = VCC_MTU_SZ;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo attr.mode = LDC_MODE_RAW;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = ldc_init(vport->ldc_id, &attr, &(vport->ldc_handle))) != 0) {
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg cmn_err(CE_CONT, "i_vcc_ldc_init: port %d ldc channel %ld"
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg " failed ldc_init %d \n", vport->number, vport->ldc_id, rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->ldc_id = VCC_INVALID_CHANNEL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* register it */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = ldc_reg_callback(vport->ldc_handle, vcc_ldc_cb,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_ldc_init: port@%d ldc_register_cb"
193974072f41a843678abf5f61979c748687e66bSherry Moore "failed\n", vport->number);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) ldc_fini(vport->ldc_handle);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->ldc_id = VCC_INVALID_CHANNEL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* open and bring channel up */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = ldc_open(vport->ldc_handle)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_ldc_init: port@%d inv channel 0x%lx\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number, vport->ldc_id);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) ldc_unreg_callback(vport->ldc_handle);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) ldc_fini(vport->ldc_handle);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->ldc_id = VCC_INVALID_CHANNEL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* init the channel status */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = ldc_status(vport->ldc_handle, &vport->ldc_status)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_ldc_init: port@%d ldc_status failed\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) ldc_close(vport->ldc_handle);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) ldc_unreg_callback(vport->ldc_handle);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) ldc_fini(vport->ldc_handle);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->ldc_id = VCC_INVALID_CHANNEL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* release a ldc channel */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsbstatic void
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_ldc_fini(vcc_port_t *vport)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = EIO;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_msg_t buf;
7636cb21f250f0485ca6052ffadc80ace93e6358lm size_t sz;
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb int retry = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_ldc_fini: port@%lld, ldc_id%%llx\n", vport->number,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->ldc_id);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(mutex_owned(&vport->lock));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* wait for write available */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_wait_port_status(vport, &vport->write_cv,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VCC_PORT_USE_WRITE_LDC);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb if (rv == 0) {
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb vport->status &= ~VCC_PORT_USE_WRITE_LDC;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb /* send a HUP message */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb buf.type = LDC_CONSOLE_CTRL;
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb buf.ctrl_msg = LDC_CONSOLE_HUP;
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb buf.size = 0;
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb /*
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * ignore write error since we still want to clean up
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * ldc channel.
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb (void) i_vcc_write_ldc(vport, &buf);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb mutex_exit(&vport->lock);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb i_vcc_set_port_status(vport, &vport->write_cv,
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb VCC_PORT_USE_WRITE_LDC);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb mutex_enter(&vport->lock);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* flush ldc channel */
7636cb21f250f0485ca6052ffadc80ace93e6358lm rv = i_vcc_wait_port_status(vport, &vport->read_cv,
7636cb21f250f0485ca6052ffadc80ace93e6358lm VCC_PORT_USE_READ_LDC);
7636cb21f250f0485ca6052ffadc80ace93e6358lm
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb if (rv == 0) {
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb vport->status &= ~VCC_PORT_USE_READ_LDC;
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb do {
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb sz = sizeof (buf);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb rv = i_vcc_read_ldc(vport, (char *)&buf, &sz);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb } while (rv == 0 && sz > 0);
7636cb21f250f0485ca6052ffadc80ace93e6358lm
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb vport->status |= VCC_PORT_USE_READ_LDC;
7636cb21f250f0485ca6052ffadc80ace93e6358lm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb /*
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * ignore read error since we still want to clean up
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * ldc channel.
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb (void) ldc_set_cb_mode(vport->ldc_handle, LDC_CB_DISABLE);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb /* close LDC channel - retry on EAGAIN */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb while ((rv = ldc_close(vport->ldc_handle)) == EAGAIN) {
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb if (++retry > VCC_LDC_RETRIES) {
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb cmn_err(CE_CONT, "i_vcc_ldc_fini: cannot close channel"
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb " %ld\n", vport->ldc_id);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb break;
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb }
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb drv_usecwait(VCC_LDC_DELAY);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb if (rv == 0) {
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb (void) ldc_unreg_callback(vport->ldc_handle);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb (void) ldc_fini(vport->ldc_handle);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb } else {
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb /*
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * Closing the LDC channel has failed. Ideally we should
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * fail here but there is no Zeus level infrastructure
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * to handle this. The MD has already been changed and
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * we have to do the close. So we try to do as much
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * clean up as we can.
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb while (ldc_unreg_callback(vport->ldc_handle) == EAGAIN)
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb drv_usecwait(VCC_LDC_DELAY);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* read data from ldc channel */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_read_ldc(vcc_port_t *vport, char *data_buf, size_t *sz)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t size;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t space_left = *sz;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_msg_t buf;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int i;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* make sure holding read lock */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT((vport->status & VCC_PORT_USE_READ_LDC) == 0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(space_left >= VCC_MTU_SZ);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *sz = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while (space_left >= VCC_MTU_SZ) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size = sizeof (buf);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = ldc_read(vport->ldc_handle, (caddr_t)&buf, &size);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * FIXME: ldc_read should not reaturn 0 with
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * either size == 0, buf.size == 0 or size < VCC_HDR_SZ
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (size == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (*sz > 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EAGAIN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (size < VCC_HDR_SZ) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * only data is expected from console - otherwise
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * return error
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (buf.type != LDC_CONSOLE_DATA) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (buf.size == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (*sz > 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EAGAIN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* copy data */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < buf.size; i++, (*sz)++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo data_buf[*sz] = buf.data[i];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo space_left -= buf.size;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* callback from ldc */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic uint_t
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_ldc_cb(uint64_t event, caddr_t arg)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport = (vcc_port_t *)arg;
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm boolean_t hasdata;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * do not need to hold lock because if ldc calls back, the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * ldc_handle must be valid.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D2("vcc_ldc_cb: callback invoked port=%d events=%llx\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number, event);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check event from ldc */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (event & LDC_EVT_WRITE) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* channel has space for write */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_set_port_status(vport, &vport->write_cv,
193974072f41a843678abf5f61979c748687e66bSherry Moore VCC_PORT_LDC_WRITE_READY);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (LDC_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (event & LDC_EVT_READ) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* channel has data for read */
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm (void) ldc_chkq(vport->ldc_handle, &hasdata);
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm if (!hasdata) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* data already read */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (LDC_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_set_port_status(vport, &vport->read_cv,
193974072f41a843678abf5f61979c748687e66bSherry Moore VCC_PORT_LDC_DATA_READY);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (LDC_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (event & LDC_EVT_DOWN) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* channel is down */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_set_port_status(vport, &vport->write_cv,
193974072f41a843678abf5f61979c748687e66bSherry Moore VCC_PORT_LDC_LINK_DOWN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_broadcast(&vport->read_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (LDC_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* configure a vcc port with ldc channel */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_config_port(vcc_t *vccp, uint_t portno, uint64_t ldc_id)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = EIO;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((portno >= VCC_MAX_PORTS) || (portno == VCC_CONTROL_PORT)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_config_port: invalid port number %d\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[portno]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_config_port: port@%d does not exist\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->ldc_id != VCC_INVALID_CHANNEL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_config_port: port@%d channel already"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "configured\n", portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* store the ldc ID */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->ldc_id = ldc_id;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check if someone has already opened this port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_OPEN) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_ldc_init(vccp, vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* mark port as ready */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= VCC_PORT_LDC_CHANNEL_READY;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_broadcast(&vport->read_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_broadcast(&vport->write_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_config_port: port@%d ldc=%d, domain=%s",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number, vport->ldc_id, vport->minorp->domain_name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* add a vcc console port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_add_port(vcc_t *vccp, char *group_name, uint64_t tcp_port,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t portno, char *domain_name)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int instance;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = MDEG_FAILURE;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor_t minor;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t minor_idx;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char name[MAXPATHLEN];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((portno >= VCC_MAX_PORTS) || (portno == VCC_CONTROL_PORT)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo DWARN("i_vcc_add_port: invalid port number %d\n", portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[portno]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_AVAIL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* this port already exists */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_add_port: invalid port - port@%d "
193974072f41a843678abf5f61979c748687e66bSherry Moore "exists\n", portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number = portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->ldc_id = VCC_INVALID_CHANNEL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (domain_name == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_add_port: invalid domain name\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (group_name == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_add_port: invalid group name\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* look up minor number */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (minor_idx = 0; minor_idx < vccp->minors_assigned; minor_idx++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (strcmp(vccp->minor_tbl[minor_idx].domain_name,
193974072f41a843678abf5f61979c748687e66bSherry Moore domain_name) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* found previous assigned minor number */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (minor_idx == vccp->minors_assigned) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* end of lookup - assign new minor number */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (minor_idx == VCC_MAX_PORTS) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_add_port:"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "too many minornodes (%d)\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor_idx);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) strlcpy(vccp->minor_tbl[minor_idx].domain_name,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo domain_name, MAXPATHLEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp->minors_assigned++;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->minorp = &vccp->minor_tbl[minor_idx];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp->minor_tbl[minor_idx].portno = portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) strlcpy(vport->group_name, group_name, MAXPATHLEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->tcp_port = tcp_port;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_add_port:@%d domain=%s, group=%s, tcp=%lld",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number, vport->minorp->domain_name,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->group_name, vport->tcp_port);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Create a minor node. The minor number is
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * (instance << VCC_INST_SHIFT) | minor_idx
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance = ddi_get_instance(vccp->dip);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor = (instance << VCC_INST_SHIFT) | (minor_idx);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) snprintf(name, MAXPATHLEN - 1, "%s%s", VCC_MINOR_NAME_PREFIX,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo domain_name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = ddi_create_minor_node(vccp->dip, name, S_IFCHR, minor,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo DDI_NT_SERIAL, 0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv != DDI_SUCCESS) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp->minors_assigned--;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status = VCC_PORT_AVAIL | VCC_PORT_ADDED;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* delete a port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_delete_port(vcc_t *vccp, vcc_port_t *vport)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char name[MAXPATHLEN];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(mutex_owned(&vport->lock));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_del_port port already deleted \n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_OPEN) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* do not block mdeg callback */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->valid_pid = VCC_NO_PID_BLOCKING;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_close_port(vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* remove minor node */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) snprintf(name, MAXPATHLEN-1, "%s%s", VCC_MINOR_NAME_PREFIX,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->minorp->domain_name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_remove_minor_node(vccp->dip, name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* let read and write thread know */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_broadcast(&vport->read_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_broadcast(&vport->write_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* register callback to MDEG */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_mdeg_register(vcc_t *vccp, int instance)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mdeg_prop_spec_t *pspecp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mdeg_node_spec_t *ispecp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mdeg_handle_t mdeg_hdl;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int sz;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Allocate and initialize a per-instance copy
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * of the global property spec array that will
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * uniquely identify this vcc instance.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo sz = sizeof (vcc_prop_template);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pspecp = kmem_alloc(sz, KM_SLEEP);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bcopy(vcc_prop_template, pspecp, sz);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VCC_SET_MDEG_PROP_INST(pspecp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* initialize the complete prop spec structure */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ispecp = kmem_zalloc(sizeof (mdeg_node_spec_t), KM_SLEEP);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ispecp->namep = "virtual-device";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ispecp->specp = pspecp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* perform the registration */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = mdeg_register(ispecp, &vcc_port_match, vcc_mdeg_cb,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp, &mdeg_hdl);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv != MDEG_SUCCESS) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_mdeg_register:"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "mdeg_register failed (%d)\n", rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(ispecp, sizeof (mdeg_node_spec_t));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(pspecp, sz);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* save off data that will be needed later */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp->md_ispecp = (void *)ispecp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp->mdeg_hdl = mdeg_hdl;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* destroy all mutex from port table */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_cleanup_port_table(vcc_t *vccp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int i;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < VCC_MAX_PORTS; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[i]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_destroy(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_destroy(&vport->read_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_destroy(&vport->write_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * attach(9E): attach a device to the system.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * called once for each instance of the device on the system.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int i, instance, inst;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = DDI_FAILURE;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor_t minor;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo switch (cmd) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case DDI_ATTACH:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance = ddi_get_instance(dip);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_soft_state_zalloc(vcc_ssp, instance) != DDI_SUCCESS)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp = ddi_get_soft_state(vcc_ssp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vccp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_soft_state_free(vccp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_attach: DDI_ATTACH instance=%d\n", instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* initialize the mutex */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_init(&vccp->lock, NULL, MUTEX_DRIVER, NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp->dip = dip;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < VCC_MAX_PORTS; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[i]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_init(&vport->lock, NULL, MUTEX_DRIVER, NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_init(&vport->read_cv, NULL, CV_DRIVER, NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_init(&vport->write_cv, NULL, CV_DRIVER, NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->valid_pid = VCC_NO_PID_BLOCKING;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[VCC_CONTROL_PORT];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->minorp = &vccp->minor_tbl[VCC_CONTROL_MINOR_IDX];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= VCC_PORT_AVAIL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* create a minor node for vcc control */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor = (instance << VCC_INST_SHIFT) | VCC_CONTROL_MINOR_IDX;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp->minor_tbl[VCC_CONTROL_PORT].portno =
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VCC_CONTROL_MINOR_IDX;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = ddi_create_minor_node(vccp->dip, "ctl", S_IFCHR, minor,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo DDI_NT_SERIAL, 0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv != DDI_SUCCESS) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "vcc_attach: error"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "creating control minor node\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_cleanup_port_table(vccp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up soft state */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_soft_state_free(vccp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* get the instance number by reading 'reg' property */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo inst = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "reg", -1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (inst == -1) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "vcc_attach: vcc%d has no "
193974072f41a843678abf5f61979c748687e66bSherry Moore "'reg' property\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_get_instance(dip));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_cleanup_port_table(vccp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* remove minor */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_remove_minor_node(vccp->dip, NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up soft state */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_soft_state_free(vccp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Mdeg might invoke callback in the same call sequence
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * if there is a domain port at the time of registration.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Since the callback also grabs vcc->lock mutex, to avoid
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * mutex reentry error, release the lock before registration
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* register for notifications from Zeus */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_mdeg_register(vccp, inst);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv != MDEG_SUCCESS) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "vcc_attach: error register to MD\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_cleanup_port_table(vccp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* remove minor */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_remove_minor_node(vccp->dip, NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up soft state */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_soft_state_free(vccp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case DDI_RESUME:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo default:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * detach(9E): detach a device from the system.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int i, instance;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mdeg_node_spec_t *ispecp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo switch (cmd) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case DDI_DETACH:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance = ddi_get_instance(dip);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp = ddi_get_soft_state(vcc_ssp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vccp == NULL)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_detach: DDI_DETACH instance=%d\n", instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* unregister from MD event generator */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(vccp->mdeg_hdl);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) mdeg_unregister(vccp->mdeg_hdl);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ispecp = (mdeg_node_spec_t *)vccp->md_ispecp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(ispecp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(ispecp->specp, sizeof (vcc_prop_template));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(ispecp, sizeof (mdeg_node_spec_t));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* remove minor nodes */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_remove_minor_node(vccp->dip, NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < VCC_MAX_PORTS; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[i];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (i == VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_OPEN) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) i_vcc_close_port(vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vccp->port[i].status & VCC_PORT_AVAIL) &&
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (i != VCC_CONTROL_PORT)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_detach: removing port port@%d\n", i);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) i_vcc_delete_port(vccp, vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_destroy(&vport->read_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_destroy(&vport->write_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_destroy(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* destroy mutex and free the soft state */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_destroy(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ddi_soft_state_free(vcc_ssp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case DDI_SUSPEND:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo default:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (DDI_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* cb_open */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_open(dev_t *devp, int flag, int otyp, cred_t *cred)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo _NOTE(ARGUNUSED(otyp, cred))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int instance;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = EIO;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor_t minor;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor = getminor(*devp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance = VCCINST(minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp = ddi_get_soft_state(vcc_ssp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vccp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno = VCCPORT(vccp, minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[portno]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg if ((vport->status & VCC_PORT_AVAIL) == 0) {
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg /* port may be removed */
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg mutex_exit(&vport->lock);
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg return (ENXIO);
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg }
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_OPEN) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* only one open per port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "vcc_open: virtual-console-concentrator@%d:%d "
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "is already open\n", instance, portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EAGAIN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check minor no and pid */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_can_use_port(VCCMINORP(vccp, minor),
193974072f41a843678abf5f61979c748687e66bSherry Moore vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (portno == VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= VCC_PORT_OPEN;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb /*
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * the port may just be added by mdeg callback and may
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * not be configured yet.
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb if (vport->ldc_id == VCC_INVALID_CHANNEL) {
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb mutex_exit(&vport->lock);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb return (ENXIO);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb }
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check if channel has been initialized */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_LDC_CHANNEL_READY) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_ldc_init(vccp, vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* mark port as ready */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= VCC_PORT_LDC_CHANNEL_READY;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= VCC_PORT_USE_READ_LDC | VCC_PORT_USE_WRITE_LDC|
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VCC_PORT_TERM_RD|VCC_PORT_TERM_WR|VCC_PORT_OPEN;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((flag & O_NONBLOCK) || (flag & O_NDELAY)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= VCC_PORT_NONBLOCK;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* close port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_close_port(vcc_port_t *vport)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_OPEN) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(mutex_owned(&vport->lock));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_LDC_CHANNEL_READY) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up ldc channel */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb i_vcc_ldc_fini(vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_LDC_CHANNEL_READY;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* reset rd/wr suspends */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= VCC_PORT_TERM_RD | VCC_PORT_TERM_WR;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_NONBLOCK;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_OPEN;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->valid_pid = VCC_NO_PID_BLOCKING;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* signal any blocked read and write thread */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_broadcast(&vport->read_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_broadcast(&vport->write_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* cb_close */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_close(dev_t dev, int flag, int otyp, cred_t *cred)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo _NOTE(ARGUNUSED(flag, otyp, cred))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int instance;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor_t minor;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = EIO;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor = getminor(dev);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance = VCCINST(minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp = ddi_get_soft_state(vcc_ssp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vccp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno = VCCPORT(vccp, minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_close: closing virtual-console-concentrator@%d:%d\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance, portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[portno]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb /*
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * needs lock to provent i_vcc_delete_port, which is called by
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb * the mdeg callback, from closing port.
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb mutex_enter(&vport->lock);
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_OPEN) == 0) {
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (portno == VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * vntsd closes control port before it exits. There
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * could be events still pending for vntsd.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
445b4c2ed2d52ef648ae6b36e4f5e14ff3d234afsb mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_reset_events(vccp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check minor no and pid */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_can_use_port(VCCMINORP(vccp, minor),
193974072f41a843678abf5f61979c748687e66bSherry Moore vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_close_port(vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * ioctl VCC_CONS_TBL - vntsd allocates buffer according to return of
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * VCC_NUM_PORTS. However, when vntsd requests for the console table, console
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * ports could be deleted or added. parameter num_ports is number of structures
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * that vntsd allocated for the table. If there are more ports than
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * num_ports, set up to wakeup vntsd to add ports.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If there less ports than num_ports, fill (-1) for cons_no to tell vntsd.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_cons_tbl(vcc_t *vccp, uint_t num_ports, caddr_t buf, int mode)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_console_t cons;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int i;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo boolean_t notify_vntsd = B_FALSE;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char pathname[MAXPATHLEN];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) ddi_pathname(vccp->dip, pathname);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < VCC_MAX_PORTS; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[i];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (i == VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* a port exists before vntsd becomes online */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (num_ports == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* more ports than vntsd's buffer can hold */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= VCC_PORT_ADDED;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo notify_vntsd = B_TRUE;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bzero(&cons, sizeof (vcc_console_t));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* construct console buffer */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cons.cons_no = vport->number;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cons.tcp_port = vport->tcp_port;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) memcpy(cons.domain_name,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->minorp->domain_name, MAXPATHLEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) memcpy(cons.group_name, vport->group_name,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo MAXPATHLEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_ADDED;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) snprintf(cons.dev_name, MAXPATHLEN-1, "%s:%s%s",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pathname, VCC_MINOR_NAME_PREFIX, cons.domain_name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* copy out data */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyout(&cons, (void *)buf,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (vcc_console_t), mode)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf += sizeof (vcc_console_t);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo num_ports--;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (num_ports == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* vntsd's buffer is full */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (notify_vntsd) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* more ports need to notify vntsd */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[VCC_CONTROL_PORT];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->pollevent |= VCC_POLL_ADD_PORT;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* less ports than vntsd expected */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bzero(&cons, sizeof (vcc_console_t));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cons.cons_no = -1;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while (num_ports > 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* fill vntsd buffer with no console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyout(&cons, (void *)buf,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (vcc_console_t), mode) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_cons_tbl: a port is deleted\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf += sizeof (vcc_console_t) +MAXPATHLEN;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo num_ports--;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* turn off event flag if there is no more change */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_turn_off_event(vcc_t *vccp, uint32_t port_status, uint32_t event)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int i;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < VCC_MAX_PORTS; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[i]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & port_status) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* more port changes status */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no more changed port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[VCC_CONTROL_PORT];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* turn off event */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->pollevent &= ~event;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* ioctl VCC_CONS_INFO */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_cons_info(vcc_t *vccp, caddr_t buf, int mode)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_console_t cons;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char pathname[MAXPATHLEN];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* read in portno */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyin((void*)buf, &portno, sizeof (uint_t), mode)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_cons_info@%d:\n", portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((portno >= VCC_MAX_PORTS) || (portno == VCC_CONTROL_PORT)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[portno];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_ADDED;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* construct configruation data */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bzero(&cons, sizeof (vcc_console_t));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cons.cons_no = vport->number;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cons.tcp_port = vport->tcp_port;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) memcpy(cons.domain_name, vport->minorp->domain_name, MAXPATHLEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) memcpy(cons.group_name, vport->group_name, MAXPATHLEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) ddi_pathname(vccp->dip, pathname),
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
193974072f41a843678abf5f61979c748687e66bSherry Moore /* copy device name */
193974072f41a843678abf5f61979c748687e66bSherry Moore (void) snprintf(cons.dev_name, MAXPATHLEN-1, "%s:%s%s",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pathname, VCC_MINOR_NAME_PREFIX, cons.domain_name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* copy data */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyout(&cons, (void *)buf,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (vcc_console_t), mode) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_cons_info@%d:domain:%s serv:%s tcp@%lld %s\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cons.cons_no, cons.domain_name,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cons.group_name, cons.tcp_port, cons.dev_name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_turn_off_event(vccp, VCC_PORT_ADDED, VCC_POLL_ADD_PORT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* response to vntsd inquiry ioctl call */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_inquiry(vcc_t *vccp, caddr_t buf, int mode)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t i;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_response_t msg;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[VCC_CONTROL_PORT]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->pollevent & VCC_POLL_ADD_PORT) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg /* an added port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_inquiry\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < VCC_MAX_PORTS; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vccp->port[i].status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vccp->port[i].status & VCC_PORT_ADDED) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* port added */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo msg.reason = VCC_CONS_ADDED;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo msg.cons_no = i;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyout((void *)&msg, (void *)buf,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (msg), mode) == -1) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_find_changed_port:"
193974072f41a843678abf5f61979c748687e66bSherry Moore "ddi_copyout"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo " failed\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* the added port was deleted before vntsd wakes up */
7636cb21f250f0485ca6052ffadc80ace93e6358lm msg.reason = VCC_CONS_MISS_ADDED;
7636cb21f250f0485ca6052ffadc80ace93e6358lm
7636cb21f250f0485ca6052ffadc80ace93e6358lm if (ddi_copyout((void *)&msg, (void *)buf,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (msg), mode) == -1) {
7636cb21f250f0485ca6052ffadc80ace93e6358lm cmn_err(CE_CONT, "i_vcc_find_changed_port: ddi_copyout"
7636cb21f250f0485ca6052ffadc80ace93e6358lm " failed\n");
7636cb21f250f0485ca6052ffadc80ace93e6358lm return (EFAULT);
7636cb21f250f0485ca6052ffadc80ace93e6358lm }
7636cb21f250f0485ca6052ffadc80ace93e6358lm
7636cb21f250f0485ca6052ffadc80ace93e6358lm return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* clean up events after vntsd exits */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_reset_events(vcc_t *vccp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t i;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < VCC_MAX_PORTS; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[i]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(!mutex_owned(&vport->lock));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (i == VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* close control port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_OPEN;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up poll events */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->pollevent = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->pollflag = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_ADDED) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* pending added port event to vntsd */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_ADDED;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[VCC_CONTROL_PORT];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* ioctl VCC_FORCE_CLOSE */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_force_close(vcc_t *vccp, caddr_t buf, int mode)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* read in portno */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyin((void*)buf, &portno, sizeof (uint_t), mode)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_force_close@%d:\n", portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((portno >= VCC_MAX_PORTS) || (portno == VCC_CONTROL_PORT)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[portno];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_close_port(vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* block callers other than vntsd */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->valid_pid = ddi_get_pid();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* ioctl VCC_CONS_STATUS */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_cons_status(vcc_t *vccp, caddr_t buf, int mode)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_console_t console;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* read in portno */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyin((void*)buf, &console, sizeof (console), mode)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_cons_status@%d:\n", console.cons_no);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((console.cons_no >= VCC_MAX_PORTS) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (console.cons_no == VCC_CONTROL_PORT)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[console.cons_no];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo console.cons_no = -1;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo } else if (strncmp(console.domain_name, vport->minorp->domain_name,
193974072f41a843678abf5f61979c748687e66bSherry Moore MAXPATHLEN)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo console.cons_no = -1;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo } else if (strncmp(console.group_name, vport->group_name,
193974072f41a843678abf5f61979c748687e66bSherry Moore MAXPATHLEN)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo console.cons_no = -1;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo } else if (console.tcp_port != vport->tcp_port) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo console.cons_no = -1;
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg } else if (vport->ldc_id == VCC_INVALID_CHANNEL) {
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg console.cons_no = -1;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_cons_status@%d: %s %s %llx\n", console.cons_no,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo console.group_name, console.domain_name, console.tcp_port);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyout(&console, (void *)buf, sizeof (console), mode) == -1) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_cons_status ddi_copyout failed\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* cb_ioctl handler for vcc control port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_ctrl_ioctl(vcc_t *vccp, int cmd, void* arg, int mode)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo static uint_t num_ports;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo switch (cmd) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case VCC_NUM_CONSOLE:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo num_ports = vccp->num_ports;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* number of consoles */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ddi_copyout((void *)&num_ports, arg,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (int), mode));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case VCC_CONS_TBL:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* console config table */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (i_vcc_cons_tbl(vccp, num_ports, (caddr_t)arg, mode));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case VCC_INQUIRY:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* reason for wakeup */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (i_vcc_inquiry(vccp, (caddr_t)arg, mode));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case VCC_CONS_INFO:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* a console config */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (i_vcc_cons_info(vccp, (caddr_t)arg, mode));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case VCC_FORCE_CLOSE:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* force to close a console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (i_vcc_force_close(vccp, (caddr_t)arg, mode));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case VCC_CONS_STATUS:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* console status */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (i_vcc_cons_status(vccp, (caddr_t)arg, mode));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo default:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* unknown command */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENODEV);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* write data to ldc. may block if channel has no space for write */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_write_ldc(vcc_port_t *vport, vcc_msg_t *buf)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = EIO;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t size;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(mutex_owned(&vport->lock));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT((vport->status & VCC_PORT_USE_WRITE_LDC) == 0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (; ; ) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size = VCC_HDR_SZ + buf->size;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = ldc_write(vport->ldc_handle, (caddr_t)buf, &size);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_write_ldc: port@%d: err=%d %d bytes\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->number, rv, size);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv != EWOULDBLOCK) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_NONBLOCK) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EAGAIN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* block util ldc has more space */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_wait_port_status(vport, &vport->write_cv,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VCC_PORT_LDC_WRITE_READY);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_LDC_WRITE_READY;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* cb_ioctl handler for port ioctl */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_port_ioctl(vcc_t *vccp, minor_t minor, int portno, int cmd, void *arg,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int mode)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct termios term;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_msg_t buf;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_port_ioctl@%d cmd %d\n", portno, cmd);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[portno]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((vport->status & VCC_PORT_AVAIL) == 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo switch (cmd) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* terminal support */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case TCGETA:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case TCGETS:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check minor no and pid */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_can_use_port(VCCMINORP(vccp, minor),
193974072f41a843678abf5f61979c748687e66bSherry Moore vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) memcpy(&term, &vport->term, sizeof (term));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ddi_copyout(&term, arg, sizeof (term), mode));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case TCSETS:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case TCSETA:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case TCSETAW:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case TCSETAF:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyin(arg, &term, sizeof (term), mode) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check minor no and pid */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_can_use_port(VCCMINORP(vccp, minor),
193974072f41a843678abf5f61979c748687e66bSherry Moore vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) memcpy(&vport->term, &term, sizeof (term));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case TCSBRK:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* send break to console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check minor no and pid */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_can_use_port(VCCMINORP(vccp, minor),
193974072f41a843678abf5f61979c748687e66bSherry Moore vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* wait for write available */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_wait_port_status(vport, &vport->write_cv,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VCC_PORT_LDC_CHANNEL_READY| VCC_PORT_USE_WRITE_LDC);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_USE_WRITE_LDC;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf.type = LDC_CONSOLE_CTRL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf.ctrl_msg = LDC_CONSOLE_BREAK;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf.size = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_write_ldc(vport, &buf);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_set_port_status(vport, &vport->write_cv,
193974072f41a843678abf5f61979c748687e66bSherry Moore VCC_PORT_USE_WRITE_LDC);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case TCXONC:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* suspend read or write */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (ddi_copyin(arg, &cmd, sizeof (int), mode) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EFAULT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check minor no and pid */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_can_use_port(VCCMINORP(vccp, minor),
193974072f41a843678abf5f61979c748687e66bSherry Moore vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo switch (cmd) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case 0:
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* suspend read */
7636cb21f250f0485ca6052ffadc80ace93e6358lm vport->status &= ~VCC_PORT_TERM_RD;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
7636cb21f250f0485ca6052ffadc80ace93e6358lm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case 1:
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* resume read */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status |= VCC_PORT_TERM_RD;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cv_broadcast(&vport->read_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
7636cb21f250f0485ca6052ffadc80ace93e6358lm
7636cb21f250f0485ca6052ffadc80ace93e6358lm case 2:
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* suspend write */
7636cb21f250f0485ca6052ffadc80ace93e6358lm vport->status &= ~VCC_PORT_TERM_WR;
7636cb21f250f0485ca6052ffadc80ace93e6358lm break;
7636cb21f250f0485ca6052ffadc80ace93e6358lm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case 3:
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* resume write */
7636cb21f250f0485ca6052ffadc80ace93e6358lm vport->status |= VCC_PORT_TERM_WR;
7636cb21f250f0485ca6052ffadc80ace93e6358lm cv_broadcast(&vport->write_cv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo default:
7636cb21f250f0485ca6052ffadc80ace93e6358lm mutex_exit(&vport->lock);
7636cb21f250f0485ca6052ffadc80ace93e6358lm return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo case TCFLSH:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo default:
7636cb21f250f0485ca6052ffadc80ace93e6358lm return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* cb_ioctl */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cred_t *credp, int *rvalp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo _NOTE(ARGUNUSED(credp, rvalp))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int instance;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor_t minor;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor = getminor(dev);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance = VCCINST(minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp = ddi_get_soft_state(vcc_ssp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vccp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno = VCCPORT(vccp, minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_ioctl: virtual-console-concentrator@%d:%d\n", instance, portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (portno >= VCC_MAX_PORTS) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "vcc_ioctl:virtual-console-concentrator@%d"
193974072f41a843678abf5f61979c748687e66bSherry Moore " invalid portno\n", portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_ioctl: virtual-console-concentrator@%d:%d ioctl cmd=%d\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance, portno, cmd);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (portno == VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* control ioctl */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (i_vcc_ctrl_ioctl(vccp, cmd, (void *)arg, mode));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* data port ioctl */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (i_vcc_port_ioctl(vccp, minor, portno, cmd, (void *)arg, mode));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* cb_read */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_read(dev_t dev, struct uio *uiop, cred_t *credp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo _NOTE(ARGUNUSED(credp))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int instance;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor_t minor;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = EIO; /* by default fail ! */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *buf;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t uio_size;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t size;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor = getminor(dev);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance = VCCINST(minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp = ddi_get_soft_state(vcc_ssp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vccp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno = VCCPORT(vccp, minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no read for control port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (portno == VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* temp buf to hold ldc data */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uio_size = uiop->uio_resid;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (uio_size < VCC_MTU_SZ) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EINVAL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[portno]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check minor no and pid */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_can_use_port(VCCMINORP(vccp, minor),
193974072f41a843678abf5f61979c748687e66bSherry Moore vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_wait_port_status(vport, &vport->read_cv,
193974072f41a843678abf5f61979c748687e66bSherry Moore VCC_PORT_TERM_RD|VCC_PORT_LDC_CHANNEL_READY|
193974072f41a843678abf5f61979c748687e66bSherry Moore VCC_PORT_USE_READ_LDC);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf = kmem_alloc(uio_size, KM_SLEEP);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_USE_READ_LDC;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (; ; ) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size = uio_size;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_read_ldc(vport, buf, &size);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv == EAGAIN) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* should block? */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->status & VCC_PORT_NONBLOCK) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo } else if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* error */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (size > 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* got data */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* wait for data from ldc */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_LDC_DATA_READY;
7636cb21f250f0485ca6052ffadc80ace93e6358lm
7636cb21f250f0485ca6052ffadc80ace93e6358lm mutex_exit(&vport->lock);
7636cb21f250f0485ca6052ffadc80ace93e6358lm i_vcc_set_port_status(vport, &vport->read_cv,
7636cb21f250f0485ca6052ffadc80ace93e6358lm VCC_PORT_USE_READ_LDC);
7636cb21f250f0485ca6052ffadc80ace93e6358lm mutex_enter(&vport->lock);
7636cb21f250f0485ca6052ffadc80ace93e6358lm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_wait_port_status(vport, &vport->read_cv,
7636cb21f250f0485ca6052ffadc80ace93e6358lm VCC_PORT_TERM_RD|VCC_PORT_LDC_CHANNEL_READY|
7636cb21f250f0485ca6052ffadc80ace93e6358lm VCC_PORT_USE_READ_LDC| VCC_PORT_LDC_DATA_READY);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
7636cb21f250f0485ca6052ffadc80ace93e6358lm
7636cb21f250f0485ca6052ffadc80ace93e6358lm vport->status &= ~VCC_PORT_USE_READ_LDC;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv == 0) && (size > 0)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* data is in buf */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = uiomove(buf, size, UIO_READ, uiop);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(buf, uio_size);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_set_port_status(vport, &vport->read_cv, VCC_PORT_USE_READ_LDC);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* cb_write */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_write(dev_t dev, struct uio *uiop, cred_t *credp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo _NOTE(ARGUNUSED(credp))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int instance;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor_t minor;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t size;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t bytes;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = EIO;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_msg_t buf;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor = getminor(dev);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance = VCCINST(minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp = ddi_get_soft_state(vcc_ssp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vccp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno = VCCPORT(vccp, minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no write for control port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (portno == VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (EIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[portno]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * check if the channel has been configured,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * if write has been suspend and grab write lock.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check minor no and pid */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_can_use_port(VCCMINORP(vccp, minor),
193974072f41a843678abf5f61979c748687e66bSherry Moore vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_wait_port_status(vport, &vport->write_cv,
193974072f41a843678abf5f61979c748687e66bSherry Moore VCC_PORT_TERM_WR|VCC_PORT_LDC_CHANNEL_READY|
193974072f41a843678abf5f61979c748687e66bSherry Moore VCC_PORT_USE_WRITE_LDC);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->status &= ~VCC_PORT_USE_WRITE_LDC;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size = uiop->uio_resid;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D2("vcc_write: virtual-console-concentrator@%d:%d writing %d bytes\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance, portno, size);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf.type = LDC_CONSOLE_DATA;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while (size) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bytes = MIN(size, VCC_MTU_SZ);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* move data */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = uiomove(&(buf.data), bytes, UIO_WRITE, uiop);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* write to ldc */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo buf.size = bytes;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* check minor no and pid */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = i_vcc_can_use_port(VCCMINORP(vccp, minor),
193974072f41a843678abf5f61979c748687e66bSherry Moore vport)) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_write_ldc(vport, &buf);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size -= bytes;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo i_vcc_set_port_status(vport, &vport->write_cv, VCC_PORT_USE_WRITE_LDC);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* mdeg callback for a removed port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_md_remove_port(md_t *mdp, mde_cookie_t mdep, vcc_t *vccp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint64_t portno; /* md requires 64bit for port number */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = MDEG_FAILURE;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (md_get_prop_val(mdp, mdep, "id", &portno)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "vcc_mdeg_cb: port has no 'id' property\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((portno >= VCC_MAX_PORTS) || (portno < 0)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_md_remove_port@%ld invalid port no\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (portno == VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_md_remove_port@%ld can not remove"
193974072f41a843678abf5f61979c748687e66bSherry Moore "control port\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[portno]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* delete the port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_delete_port(vccp, vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp->num_ports--;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv ? MDEG_FAILURE : MDEG_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_get_ldc_id(md_t *md, mde_cookie_t mdep, uint64_t *ldc_id)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int num_nodes;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size_t size;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mde_cookie_t *channel;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int num_channels;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((num_nodes = md_node_count(md)) <= 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_get_ldc_channel_id:"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo " Invalid node count in Machine Description subtree");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo size = num_nodes*(sizeof (*channel));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo channel = kmem_zalloc(size, KM_SLEEP);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(channel != NULL); /* because KM_SLEEP */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* Look for channel endpoint child(ren) of the vdisk MD node */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((num_channels = md_scan_dag(md, mdep,
193974072f41a843678abf5f61979c748687e66bSherry Moore md_find_name(md, "channel-endpoint"),
193974072f41a843678abf5f61979c748687e66bSherry Moore md_find_name(md, "fwd"), channel)) <= 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_get_ldc_id: No 'channel-endpoint'"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo " found for vcc");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(channel, size);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* Get the "id" value for the first channel endpoint node */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (md_get_prop_val(md, channel[0], "id", ldc_id) != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_get_ldc: No id property found "
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "for channel-endpoint of vcc");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(channel, size);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (num_channels > 1) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_get_ldc: Warning: Using ID of first"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo " of multiple channels for this vcc");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(channel, size);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* mdeg callback for an added port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoi_vcc_md_add_port(md_t *mdp, mde_cookie_t mdep, vcc_t *vccp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint64_t portno; /* md requires 64 bit */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *domain_name;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *group_name;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint64_t ldc_id;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint64_t tcp_port;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* read in the port's reg property */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (md_get_prop_val(mdp, mdep, "id", &portno)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_md_add_port_: port has no 'id' "
193974072f41a843678abf5f61979c748687e66bSherry Moore "property\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* read in the port's "vcc-doman-name" property */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (md_get_prop_str(mdp, mdep, "vcc-domain-name", &domain_name)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_md_add_port: port%ld has "
193974072f41a843678abf5f61979c748687e66bSherry Moore "no 'vcc-domain-name' property\n", portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* read in the port's "vcc-group-name" property */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (md_get_prop_str(mdp, mdep, "vcc-group-name", &group_name)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_md_add_port: port%ld has no "
193974072f41a843678abf5f61979c748687e66bSherry Moore "'vcc-group-name'property\n", portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* read in the port's "vcc-tcp-port" property */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (md_get_prop_val(mdp, mdep, "vcc-tcp-port", &tcp_port)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmn_err(CE_CONT, "i_vcc_md_add_port: port%ld has no"
193974072f41a843678abf5f61979c748687e66bSherry Moore "'vcc-tcp-port' property\n", portno);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("i_vcc_md_add_port: port@%d domain-name=%s group-name=%s"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo " tcp-port=%lld\n", portno, domain_name, group_name, tcp_port);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* add the port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (i_vcc_add_port(vccp, group_name, tcp_port, portno, domain_name)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[portno];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (i_vcc_get_ldc_id(mdp, mdep, &ldc_id)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) i_vcc_delete_port(vccp, vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* configure the port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (i_vcc_config_port(vccp, portno, ldc_id)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) i_vcc_delete_port(vccp, vport);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp->num_ports++;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vccp->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &vccp->port[VCC_CONTROL_PORT];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->pollflag & VCC_POLL_CONFIG) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* wakeup vntsd */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->pollevent |= VCC_POLL_ADD_PORT;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pollwakeup(&vport->poll, POLLIN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* mdeg callback */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_mdeg_cb(void *cb_argp, mdeg_result_t *resp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int idx;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp = (vcc_t *)cb_argp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(vccp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (resp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_FAILURE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* added port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_mdeg_cb: added %d port(s)\n", resp->added.nelem);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (idx = 0; idx < resp->added.nelem; idx++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_md_add_port(resp->added.mdp,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo resp->added.mdep[idx], vccp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv != MDEG_SUCCESS) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* removed port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_mdeg_cb: removed %d port(s)\n", resp->removed.nelem);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (idx = 0; idx < resp->removed.nelem; idx++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = i_vcc_md_remove_port(resp->removed.mdp,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo resp->removed.mdep[idx], vccp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (rv != MDEG_SUCCESS) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
4d39be2b45b5ac811d28452e6eb629ac64aebfc4sg
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * XXX - Currently no support for updating already active
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * ports. So, ignore the match_curr and match_prev arrays
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * for now.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (MDEG_SUCCESS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* cb_chpoll */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovcc_chpoll(dev_t dev, short events, int anyyet, short *reventsp,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct pollhead **phpp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int instance;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor_t minor;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t portno;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_t *vccp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vcc_port_t *vport;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo minor = getminor(dev);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance = VCCINST(minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vccp = ddi_get_soft_state(vcc_ssp, instance);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vccp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno = VCCPORT(vccp, minor);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport = &(vccp->port[portno]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_chpoll: virtual-console-concentrator@%d events 0x%x\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo portno, events);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *reventsp = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (portno != VCC_CONTROL_PORT) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* poll for config change */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vport->pollevent) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *reventsp |= (events & POLLIN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
a5eb7107f06a6e23e8e77e8d3a84c1ff90a73ac6Bryan Cantrill if ((((*reventsp) == 0) && (!anyyet)) || (events & POLLET)) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *phpp = &vport->poll;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (events & POLLIN) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_enter(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->pollflag |= VCC_POLL_CONFIG;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo mutex_exit(&vport->lock);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo } else {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (ENXIO);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1("vcc_chpoll: virtual-console-concentrator@%d:%d ev=0x%x, "
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "rev=0x%x pev=0x%x, flag=0x%x\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo instance, portno, events, (*reventsp),
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vport->pollevent, vport->pollflag);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}