25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER START
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The contents of this file are subject to the terms of the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Common Development and Distribution License (the "License").
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You may not use this file except in compliance with the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * or http://www.opensolaris.org/os/licensing.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * See the License for the specific language governing permissions
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * and limitations under the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * When distributing Covered Code, include this CDDL HEADER in each
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If applicable, add the following below this CDDL HEADER, with the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * fields enclosed by brackets "[]" replaced with your own identifying
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information: Portions Copyright [yyyy] [name of copyright owner]
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER END
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
193974072f41a843678abf5f61979c748687e66bSherry Moore
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * All Rights Reserved, Copyright (c) FUJITSU LIMITED 2006
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
193974072f41a843678abf5f61979c748687e66bSherry Moore/*
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
193974072f41a843678abf5f61979c748687e66bSherry Moore * Use is subject to license terms.
193974072f41a843678abf5f61979c748687e66bSherry Moore */
193974072f41a843678abf5f61979c748687e66bSherry Moore
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/errno.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/modctl.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/stat.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/kmem.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/ksynch.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/stream.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/stropts.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/termio.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/ddi.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/file.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/disp.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/sunddi.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/sunldi.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/sunndi.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/kbio.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/prom_plat.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/oplmsu/oplmsu.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/oplmsu/oplmsu_proto.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlextern int ddi_create_internal_pathname(dev_info_t *, char *, int, minor_t);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define MOD_ID 0xe145
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define MOD_NAME "oplmsu"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define META_NAME "oplmsu"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define USER_NAME "a"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct module_info oplmsu_mod_info = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl MOD_ID,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl MOD_NAME,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 16384,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 14336,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 2048
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct qinit oplmsu_urinit = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_ursrv,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_open,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_close,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &oplmsu_mod_info,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct qinit oplmsu_uwinit = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uwput,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uwsrv,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_open,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_close,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &oplmsu_mod_info,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct qinit oplmsu_lrinit = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_lrput,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_lrsrv,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_open,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_close,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &oplmsu_mod_info,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct qinit oplmsu_lwinit = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_lwsrv,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_open,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_close,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &oplmsu_mod_info,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct streamtab oplmsu_info = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &oplmsu_urinit,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &oplmsu_uwinit,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &oplmsu_lrinit,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &oplmsu_lwinit
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic struct cb_ops cb_oplmsu_ops = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nulldev, /* cb_open */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nulldev, /* cb_close */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* cb_strategy */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* cb_print */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* cb_dump */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* cb_read */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* cb_write */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* cb_ioctl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* cb_devmap */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* cb_mmap */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* cb_segmap */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nochpoll, /* cb_chpoll */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_prop_op, /* cb_prop_op */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (&oplmsu_info), /* cb_stream */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (int)(D_NEW|D_MP|D_HOTPLUG) /* cb_flag */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic struct dev_ops oplmsu_ops = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DEVO_REV, /* devo_rev */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0, /* devo_refcnt */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (oplmsu_getinfo), /* devo_getinfo */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (nulldev), /* devo_identify */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (nulldev), /* devo_probe */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (oplmsu_attach), /* devo_attach */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (oplmsu_detach), /* devo_detach */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (nodev), /* devo_reset */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &(cb_oplmsu_ops), /* devo_cb_ops */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (struct bus_ops *)NULL, /* devo_bus_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL, /* devo_power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_needed, /* dev_quiesce */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct modldrv modldrv = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &mod_driverops,
193974072f41a843678abf5f61979c748687e66bSherry Moore "OPL serial mux driver",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &oplmsu_ops
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct modlinkage modlinkage = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl MODREV_1,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void *)&modldrv,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jluinst_t oplmsu_uinst_local; /* upper_instance_table structure */
25cf1a301a396c38e8adf52c15f537b80d2483f7jluinst_t *oplmsu_uinst = &oplmsu_uinst_local;
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint oplmsu_queue_flag; /* Enable/disable queueing flag */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint oplmsu_check_su; /* Check super-user flag */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef DEBUG
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint oplmsu_debug_mode = 0; /* Enable/disable debug mode */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint oplmsu_trace_on; /* Enable/disable trace */
25cf1a301a396c38e8adf52c15f537b80d2483f7jluint_t oplmsu_ltrc_size; /* Trace buffer size */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlmsu_trc_t *oplmsu_ltrc_top; /* Top of trace data area */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlmsu_trc_t *oplmsu_ltrc_tail; /* Tail of trace data area */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlmsu_trc_t *oplmsu_ltrc_cur; /* Current pointer of trace data area */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlulong_t oplmsu_ltrc_ccnt; /* Current counter */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlkmutex_t oplmsu_ltrc_lock; /* Lock table for trace mode */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* oplmsu_conf_st */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define MSU_CONFIGURED 2
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define MSU_CONFIGURING 1
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define MSU_UNCONFIGURED 0
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic kmutex_t oplmsu_bthrd_excl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic kthread_id_t oplmsu_bthrd_id = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int oplmsu_conf_st = MSU_UNCONFIGURED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic kcondvar_t oplmsu_conf_cv;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Locking hierarcy of oplmsu driver. This driver have 5 locks in uinst_t.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Each mutex guards as follows.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * uinst_t->lock: This mutex is read/write mutex.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * read lock : acquired if the member of uinst_t is refered only.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * write lock: acquired if the member of uinst_t is changed.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * uinst_t->u_lock: This mutex is normal mutex.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * This mutex is acquired at reading/changing the member of all upath_t.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * uinst_t->l_lock: This mutex is normal mutex.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * This mutex is acquired at reading/changing the member of all lpath_t.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * uinst_t->c_lock: This mutex is normal mutex.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * This mutex is acquired at reading/changing the member of the ctrl_t.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * oplmsu_bthrd_excl: This mutex is normal mutex.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * This mutex is used only to start/stop the configuring thread of the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * multiplexed STREAMS.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * This mutex is exclusively acquired with the above-mentioned 4 mutexes.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * To guard of the deadlock by cross locking, the base locking hierarcy
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * is as follows:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * uisnt->lock ==> uinst->u_lock ==> uinst->l_lock ==> uinst->c_lock
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_init(void)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Initialize R/W lock for uinst_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_init(&oplmsu_uinst->lock, "uinst rwlock", RW_DRIVER, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Initialize mutex for upath_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_init(&oplmsu_uinst->u_lock, "upath lock", MUTEX_DRIVER, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Initialize mutex for lpath_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_init(&oplmsu_uinst->l_lock, "lpath lock", MUTEX_DRIVER, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Initialize mutex for ctrl_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_init(&oplmsu_uinst->c_lock, "ctrl lock", MUTEX_DRIVER, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Initialize mutex for protecting background thread */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_init(&oplmsu_bthrd_excl, NULL, MUTEX_DRIVER, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Initialize condition variable */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_init(&oplmsu_conf_cv, NULL, CV_DRIVER, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = mod_install(&modlinkage);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != DDI_SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_destroy(&oplmsu_conf_cv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_destroy(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_fini(void)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = mod_remove(&modlinkage);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval == DDI_SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_destroy(&oplmsu_conf_cv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_destroy(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_info(struct modinfo *modinfop)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (mod_info(&modlinkage, modinfop));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* ARGSUSED */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_t dev = (dev_t)arg;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl minor_t inst;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval = DDI_SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (cmd) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_INFO_DEVT2DEVINFO :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_uinst->msu_dip == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = DDI_FAILURE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *resultp = oplmsu_uinst->msu_dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_INFO_DEVT2INSTANCE :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl inst = getminor(dev) & ~(META_NODE_MASK|USER_NODE_MASK);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *resultp = (void *)(uintptr_t)inst;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = DDI_FAILURE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl minor_t meta_minor, user_minor;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define CNTRL(c) ((c) & 037)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char abt_ch_seq[3] = { '\r', '~', CNTRL('b') };
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cmd == DDI_RESUME) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cmd != DDI_ATTACH) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance = ddi_get_instance(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (instance != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: attach: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Invaild instance => %d", instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Create minor number for meta control node */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl meta_minor = instance | META_NODE_MASK;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Create minor number for user access node */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl user_minor = instance | USER_NODE_MASK;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Create minor node for user access */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = ddi_create_minor_node(dip, USER_NAME, S_IFCHR, user_minor,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DDI_NT_SERIAL, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != DDI_SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: attach: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "ddi_create_minor_node failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_remove_minor_node(dip, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Create minor node for meta control */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = ddi_create_internal_pathname(dip, META_NAME, S_IFCHR,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl meta_minor);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != DDI_SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: attach: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "ddi_create_internal_pathname failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_remove_minor_node(dip, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Get each properties */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_check_su = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (DDI_PROP_DONTPASS|DDI_PROP_NOTPROM), "check-superuser", 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Initialize members of uinst_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->inst_status = INST_STAT_UNCONFIGURED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->path_num = UNDEFINED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->msu_dip = dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) strcpy(oplmsu_uinst->abts, abt_ch_seq);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef DEBUG
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_trace_on = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (DDI_PROP_DONTPASS|DDI_PROP_NOTPROM), "trace-mode", 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_ltrc_size = (uint_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (DDI_PROP_DONTPASS|DDI_PROP_NOTPROM), "trace-bufsize", 128);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_trace_on == MSU_TRACE_ON) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Initialize mutex for msu_trc_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_init(&oplmsu_ltrc_lock, "trc lock", MUTEX_DRIVER, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_ltrc_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_ltrc_top = (msu_trc_t *)kmem_zalloc(
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (sizeof (msu_trc_t) * oplmsu_ltrc_size), KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_ltrc_cur = (msu_trc_t *)(oplmsu_ltrc_top - 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_ltrc_tail =
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (msu_trc_t *)(oplmsu_ltrc_top + (oplmsu_ltrc_size - 1));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_ltrc_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_report_dev(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath, *next_lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cmd == DDI_SUSPEND) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cmd != DDI_DETACH) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Delete all upath_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_delete_upath_info();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Delete all lpath_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = oplmsu_uinst->first_lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->first_lpath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->last_lpath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef DEBUG
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_trace_on == MSU_TRACE_ON) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_ltrc_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_ltrc_top != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(oplmsu_ltrc_top,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (sizeof (msu_trc_t) * oplmsu_ltrc_size));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_ltrc_top = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_ltrc_cur = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_ltrc_tail = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_ltrc_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&oplmsu_ltrc_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (lpath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath->rbuf_id) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl unbufcall(lpath->rbuf_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath->rtout_id) {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) untimeout(lpath->rtout_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath->rbuftbl) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(lpath->rbuftbl, sizeof (struct buf_tbl));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_destroy(&lpath->sw_cv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl next_lpath = lpath->l_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(lpath, sizeof (lpath_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = next_lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_remove_minor_node(dip, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* ARGSUSED */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_open(queue_t *urq, dev_t *dev, int oflag, int sflag, cred_t *cred_p)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl_t *ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl minor_t mindev = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl minor_t qmindev = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl major_t majdev;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ulong_t node_flag;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: open: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "devt = 0x%lx, sflag = 0x%x", *dev, sflag));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (sflag == CLONEOPEN) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Get minor device number */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl qmindev = (minor_t)getminor(*dev);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Get node type */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl node_flag = MSU_NODE_TYPE(qmindev);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((node_flag != MSU_NODE_USER) && (node_flag != MSU_NODE_META)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((node_flag == MSU_NODE_USER) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (oplmsu_conf_st != MSU_CONFIGURED)) { /* User access & First open */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int cv_rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: open: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "oplmsu_conf_st = %x", oplmsu_conf_st));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_conf_st == MSU_UNCONFIGURED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_conf_st = MSU_CONFIGURING;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Start up background thread */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_bthrd_id = thread_create(NULL, 2 * DEFAULTSTKSZ,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_setup, (void *)oplmsu_uinst, 0, &p0, TS_RUN,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl minclsyspri);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Wait with cv_wait_sig() until background thread is
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * completed.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (oplmsu_conf_st == MSU_CONFIGURING) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_rval =
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_wait_sig(&oplmsu_conf_cv, &oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cv_rval == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINTR);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If the node which will open is meta-control-node or
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * user-access-node, and q_ptr, this is queue_t queue
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * table member, is not NULL, then oplmsu returns
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * SUCCESS immidiately.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * This process is used to protect dual open.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((urq != NULL) && (urq->q_ptr != NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If the node which will open is User-Access-Node, and instance
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * status of oplmsu is no ONLINE, then oplmsu_open process fails
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * with return value 'EIO'.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((node_flag == MSU_NODE_USER) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (oplmsu_uinst->inst_status != INST_STAT_ONLINE)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mindev |= qmindev; /* Create minor device number */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl majdev = getmajor(*dev); /* Get major device number */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *dev = makedevice(majdev, mindev); /* Make device number */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Allocate kernel memory for ctrl_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl = (ctrl_t *)kmem_zalloc(sizeof (ctrl_t), KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Initialize members of ctrl_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->minor = (minor_t)mindev;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->queue = urq;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->sleep_flag = CV_WAKEUP;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->node_type = node_flag;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->wbuftbl =
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (struct buf_tbl *)kmem_zalloc(sizeof (struct buf_tbl), KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_init(&ctrl->cvp, "oplmsu ctrl_tbl condvar", CV_DRIVER, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (node_flag == MSU_NODE_USER) { /* User access node */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->user_ctrl = ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_queue_flag = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else { /* Meta control node */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->meta_ctrl = ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl RD(urq)->q_ptr = ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl WR(urq)->q_ptr = ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OPLMSU_TRACE(urq, (mblk_t *)node_flag, MSU_TRC_OPN);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl qprocson(urq); /* Enable put and service routine */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* ARGSUSED */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_close(queue_t *urq, int flag, cred_t *cred_p)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl_t *ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl minor_t qmindev = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ulong_t node_flag;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl bufcall_id_t wbuf_id;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl timeout_id_t wtout_id;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((ctrl = urq->q_ptr) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: close: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "close has already been completed"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl qmindev = ctrl->minor;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: close: ctrl->minor = 0x%x", qmindev));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl node_flag = MSU_NODE_TYPE(qmindev);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (node_flag > MSU_NODE_META) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Check that queue which is waiting for response from lower stream
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * exist. If queue exists, oplmsu sets CV_SLEEP to sleep_flag.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (lpath = oplmsu_uinst->first_lpath; lpath; ) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (((RD(urq) == lpath->hndl_uqueue) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (WR(urq) == lpath->hndl_uqueue)) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (lpath->hndl_mp != NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->sleep_flag = CV_SLEEP;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = lpath->l_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* If sleep_flag is not CV_SLEEP, oplmsu calls cv_wait. */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (ctrl->sleep_flag != CV_WAKEUP) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_wait(&ctrl->cvp, &oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl flushq(RD(urq), FLUSHALL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl flushq(WR(urq), FLUSHALL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl qprocsoff(urq); /* Disable queuing of queue */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (node_flag) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case MSU_NODE_USER : /* User access node */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->user_ctrl = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_queue_flag = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case MSU_NODE_META : /* Meta control node */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->meta_ctrl = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: close: node_flag = 0x%lx", node_flag);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->minor = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->queue = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl wbuf_id = ctrl->wbuf_id;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl wtout_id = ctrl->wtout_id;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->wbuf_id = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->wtout_id = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_destroy(&ctrl->cvp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(ctrl->wbuftbl, sizeof (struct buf_tbl));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->wbuftbl = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl RD(urq)->q_ptr = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl WR(urq)->q_ptr = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (wbuf_id != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl unbufcall(wbuf_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (wtout_id != 0) {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) untimeout(wtout_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Free kernel memory for ctrl_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(ctrl, sizeof (ctrl_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OPLMSU_TRACE(urq, (mblk_t *)node_flag, MSU_TRC_CLS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Upper write put procedure
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_uwput(queue_t *uwq, mblk_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((uwq == NULL) || (uwq->q_ptr == NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl freemsg(mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OPLMSU_TRACE(uwq, mp, MSU_TRC_UI);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->b_datap->db_type == M_FLUSH) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_wcmn_flush_hndl(uwq, mp, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if (mp->b_datap->db_type >= QPCTL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl_t *ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl = (ctrl_t *)uwq->q_ptr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Link high priority message to local queue */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_link_high_primsg(&ctrl->first_upri_hi,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &ctrl->last_upri_hi, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_wcmn_high_qenable(WR(uwq), RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) putq(WR(uwq), mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Upper write service procedure
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_uwsrv(queue_t *uwq)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct iocblk *iocp = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mblk_t *mp = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((uwq == NULL) || (uwq->q_ptr == NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Handle high priority message */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (mp = oplmsu_wcmn_high_getq(uwq)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->b_datap->db_type == M_FLUSH) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_wcmn_flush_hndl(uwq, mp, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_wcmn_through_hndl(uwq, mp, MSU_HIGH, RW_READER) ==
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FAILURE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Handle normal priority message */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (mp = getq(uwq)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (mp->b_datap->db_type) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case M_IOCTL :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl iocp = (struct iocblk *)mp->b_rptr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (iocp->ioc_cmd) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case I_PLINK :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_cmn_pullup_msg(uwq, mp) != FAILURE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_uwioctl_iplink(uwq, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case I_PUNLINK :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_cmn_pullup_msg(uwq, mp) != FAILURE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_uwioctl_ipunlink(uwq, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case TCSETS : /* FALLTHRU */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case TCSETSW : /* FALLTHRU */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case TCSETSF : /* FALLTHRU */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case TIOCMSET : /* FALLTHRU */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case TIOCSPPS : /* FALLTHRU */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case TIOCSWINSZ : /* FALLTHRU */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case TIOCSSOFTCAR :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_uwioctl_termios(uwq, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_wcmn_through_hndl(uwq, mp,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl MSU_NORM, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_wcmn_through_hndl(uwq, mp, MSU_NORM,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval == FAILURE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Lower write service procedure
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_lwsrv(queue_t *lwq)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mblk_t *mp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl queue_t *dst_queue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (mp = getq(lwq)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->b_datap->db_type >= QPCTL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OPLMSU_TRACE(WR(lwq), mp, MSU_TRC_LO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl putnext(WR(lwq), mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dst_queue = WR(lwq);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (canputnext(dst_queue)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OPLMSU_TRACE(dst_queue, mp, MSU_TRC_LO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl putnext(dst_queue, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) putbq(WR(lwq), mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = (lpath_t *)lwq->q_ptr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath->uwq_flag != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl qenable(WR(lpath->uwq_queue));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->uwq_flag = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->uwq_queue = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Lower read put procedure
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_lrput(queue_t *lrq, mblk_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((lrq == NULL) || (lrq->q_ptr == NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl freemsg(mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OPLMSU_TRACE(lrq, mp, MSU_TRC_LI);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->b_datap->db_type == M_FLUSH) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_rcmn_flush_hndl(lrq, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if (mp->b_datap->db_type >= QPCTL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = lrq->q_ptr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Link high priority message to local queue */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_link_high_primsg(&lpath->first_lpri_hi,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &lpath->last_lpri_hi, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_rcmn_high_qenable(lrq);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) putq(lrq, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Lower read service procedure
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_lrsrv(queue_t *lrq)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mblk_t *mp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl boolean_t aborted;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((lrq == NULL) || (lrq->q_ptr == NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Handle normal priority message */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (mp = getq(lrq)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->b_datap->db_type >= QPCTL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: lr-srv: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Invalid db_type => %x", mp->b_datap->db_type);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (mp->b_datap->db_type) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case M_DATA :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl aborted = B_FALSE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((abort_enable == KIOCABORTALTERNATE) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (RD(oplmsu_uinst->lower_queue) == lrq)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uchar_t *rx_char = mp->b_rptr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = lrq->q_ptr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (rx_char != mp->b_wptr) {
193974072f41a843678abf5f61979c748687e66bSherry Moore if (*rx_char == *lpath->abt_char) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->abt_char++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (*lpath->abt_char == '\0') {
193974072f41a843678abf5f61979c748687e66bSherry Moore abort_sequence_enter((char *)
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL);
193974072f41a843678abf5f61979c748687e66bSherry Moore lpath->abt_char
193974072f41a843678abf5f61979c748687e66bSherry Moore = oplmsu_uinst->abts;
193974072f41a843678abf5f61979c748687e66bSherry Moore aborted = B_TRUE;
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
193974072f41a843678abf5f61979c748687e66bSherry Moore } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->abt_char = (*rx_char ==
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *oplmsu_uinst->abts) ?
193974072f41a843678abf5f61979c748687e66bSherry Moore oplmsu_uinst->abts + 1 :
193974072f41a843678abf5f61979c748687e66bSherry Moore oplmsu_uinst->abts;
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore rx_char++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (aborted) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl freemsg(mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * When 1st byte of the received M_DATA is XON or,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * 1st byte is XOFF and 2nd byte is XON.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((*(mp->b_rptr) == MSU_XON) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (((mp->b_wptr - mp->b_rptr) == 2) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ((*(mp->b_rptr) == MSU_XOFF) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (*(mp->b_rptr + 1) == MSU_XON)))) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Path switching by XOFF/XON */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_lrdata_xoffxon(lrq, mp) == FAILURE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval =
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_rcmn_through_hndl(lrq, mp, MSU_NORM);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval == FAILURE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case M_BREAK :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((mp->b_wptr - mp->b_rptr) == 0 && msgdsize(mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((abort_enable != KIOCABORTALTERNATE) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (RD(oplmsu_uinst->lower_queue) == lrq)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl abort_sequence_enter((char *)NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl freemsg(mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* FALLTHRU */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) oplmsu_rcmn_through_hndl(lrq, mp, MSU_NORM);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Upper read service procedure
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_ursrv(queue_t *urq)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mblk_t *mp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl queue_t *dst_queue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl_t *ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int res_chk = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (mp = getq(urq)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->b_datap->db_type >= QPCTL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((mp->b_datap->db_type == M_IOCACK) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (mp->b_datap->db_type == M_IOCNAK)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl res_chk = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OPLMSU_TRACE(RD(urq), mp, MSU_TRC_UO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl putnext(RD(urq), mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = oplmsu_uinst->first_lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (lpath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl qenable(RD(lpath->lower_queue));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = lpath->l_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (res_chk == 1) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl = (ctrl_t *)urq->q_ptr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ctrl != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ctrl->wait_queue != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl qenable(WR(ctrl->wait_queue));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->wait_queue = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl res_chk = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dst_queue = RD(urq);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (canputnext(dst_queue)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OPLMSU_TRACE(dst_queue, mp, MSU_TRC_UO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl putnext(dst_queue, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) putbq(urq, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl = urq->q_ptr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ctrl->lrq_flag != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl qenable(ctrl->lrq_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->lrq_flag = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl->lrq_queue = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_open_msu(dev_info_t *dip, ldi_ident_t *lip, ldi_handle_t *lhp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_t devt;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Allocate LDI identifier */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = ldi_ident_from_dip(dip, lip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: open-msu: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "ldi_ident_from_dip failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Open oplmsu(meta ctrl node) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl devt = makedevice(ddi_driver_major(dip), META_NODE_MASK);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval =
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_open_by_dev(&devt, OTYP_CHR, (FREAD|FWRITE), kcred, lhp, *lip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: open-msu: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "ldi_open_by_dev failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(*lip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_plink_serial(dev_info_t *dip, ldi_handle_t msu_lh, int *id)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_t li = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_handle_t lh = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int param;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char pathname[MSU_PATHNAME_SIZE];
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char wrkbuf[MSU_PATHNAME_SIZE];
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Create physical path-name for serial */
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) ddi_pathname(dip, wrkbuf);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *(wrkbuf + strlen(wrkbuf)) = '\0';
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) sprintf(pathname, "/devices%s:%c", wrkbuf,
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki 'a'+ ddi_get_instance(dip));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Allocate LDI identifier */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = ldi_ident_from_dip(dip, &li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: plink-serial: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "%s ldi_ident_from_dip failed. errno = %d", pathname, rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Open serial */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = ldi_open_by_name(pathname, (FREAD|FWRITE|FEXCL), kcred, &lh, li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: plink-serial: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "%s open failed. errno = %d", pathname, rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Try to remove the top module from the stream */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl param = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while ((ldi_ioctl(lh, I_POP, (intptr_t)0, FKIOCTL, kcred, &param))
25cf1a301a396c38e8adf52c15f537b80d2483f7jl == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Issue ioctl(I_PLINK) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl param = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = ldi_ioctl(msu_lh, I_PLINK, (intptr_t)lh, FKIOCTL, kcred, &param);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: plink-serial: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "%s ioctl(I_PLINK) failed. errno = %d", pathname, rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(lh, (FREAD|FWRITE|FEXCL), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *id = param; /* Save link-id */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_set_lpathnum(int lnk_id, int instance)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval = SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = oplmsu_uinst->first_lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (lpath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((lpath->path_no == UNDEFINED) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (lpath->link_id == lnk_id)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->path_no = instance; /* Set instance number */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->status = MSU_SETID_NU;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = lpath->l_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = EINVAL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_dr_attach(dev_info_t *dip)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_t msu_li = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_handle_t msu_lh = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath_t *upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int lnk_id = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int param = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Get instance for serial */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance = ddi_get_instance(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Get current number of paths */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->path_num = oplmsu_get_pathnum();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Check specified upath_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = oplmsu_uinst->first_upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (upath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (instance == upath->path_no) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = upath->u_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (upath != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: attach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Instance %d already exist", instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Open oplmsu */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_open_msu(oplmsu_uinst->msu_dip, &msu_li, &msu_lh);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: attach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "msu open failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Connect two streams */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_plink_serial(dip, msu_lh, &lnk_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: attach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "i_plink failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(msu_lh, (FREAD|FWRITE), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(msu_li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_set_lpathnum(lnk_id, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: attach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Link id %d is not found", lnk_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Issue ioctl(I_PUNLINK) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_ioctl(msu_lh, I_PUNLINK, (intptr_t)lnk_id, FKIOCTL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kcred, &param);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(msu_lh, (FREAD|FWRITE), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(msu_li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Add the path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_config_add(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: attach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to add the path. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Issue ioctl(I_PUNLINK) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_ioctl(msu_lh, I_PUNLINK, (intptr_t)lnk_id, FKIOCTL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kcred, &param);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(msu_lh, (FREAD|FWRITE), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(msu_li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Start to use the path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_config_start(instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct msu_path *mpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct msu_dev *mdev;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: attach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to start the path. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl len = sizeof (struct msu_path) + sizeof (struct msu_dev);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mpath = (struct msu_path *)kmem_zalloc((size_t)len, KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mpath->num = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev = (struct msu_dev *)(mpath + 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev->dip = dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Delete the path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((oplmsu_config_del(mpath)) == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Issue ioctl(I_PUNLINK) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_ioctl(msu_lh, I_PUNLINK, (intptr_t)lnk_id,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FKIOCTL, kcred, &param);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(mpath, (size_t)len);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Close oplmsu */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(msu_lh, (FREAD|FWRITE), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(msu_li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_dr_detach(dev_info_t *dip)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_t msu_li = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_handle_t msu_lh = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct msu_path *mpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct msu_dev *mdev;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath_t *upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int count = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int param = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int status;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Get instance for serial */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance = ddi_get_instance(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Get current number of paths */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->path_num = oplmsu_get_pathnum();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = FAILURE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Check specified upath_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = oplmsu_uinst->first_upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (upath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (instance == upath->path_no) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Save status of specified path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = upath->status;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = upath->u_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl count += 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval == FAILURE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (count <= 1) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: detach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Instance %d is last path", instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: detach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Instance %d doesn't find", instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Check status of specified path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((status == MSU_PSTAT_ACTIVE) || (status == MSU_PSTAT_STANDBY)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Stop to use the path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_config_stop(instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: detach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to stop the path. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Prepare to unlink the path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_config_disc(instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: detach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to disconnect the path. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = oplmsu_uinst->first_lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (lpath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath->path_no == instance) { /* Get link ID */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = lpath->l_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: detach(dr): Can not find link ID");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Open oplmsu */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_open_msu(oplmsu_uinst->msu_dip, &msu_li, &msu_lh);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: detach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "msu open failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Issue ioctl(I_PUNLINK) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = ldi_ioctl(msu_lh, I_PUNLINK, (intptr_t)lpath->link_id, FKIOCTL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kcred, &param);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: detach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "ioctl(I_PUNLINK) failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(msu_lh, (FREAD|FWRITE), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(msu_li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Close oplmsu(meta node) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(msu_lh, (FREAD|FWRITE), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(msu_li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl len = sizeof (struct msu_path) + sizeof (struct msu_dev);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mpath = (struct msu_path *)kmem_zalloc((size_t)len, KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mpath->num = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev = (struct msu_dev *)(mpath + 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev->dip = dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Delete the path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_config_del(mpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: detach(dr): "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to delete the path. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(mpath, (size_t)len);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The ebus and the serial device path under a given CMU_CH chip
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * is expected to be always at the same address. So, it is safe
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * to hard-code the pathnames as below.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EBUS_PATH "ebus@1"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define SERIAL_PATH "serial@14,400000"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EBUS_SERIAL_PATH ("/" EBUS_PATH "/" SERIAL_PATH)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Given the CMU_CH dip, find the serial device dip.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jldev_info_t *
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_find_ser_dip(dev_info_t *cmuch_dip)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int circ1, circ2;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_info_t *ebus_dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_info_t *ser_dip = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ndi_devi_enter(cmuch_dip, &circ1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ebus_dip = ndi_devi_findchild(cmuch_dip, EBUS_PATH);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: find-serial-dip: "
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki "ebus_dip = %p", (void *)ebus_dip));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ebus_dip != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ndi_devi_enter(ebus_dip, &circ2);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ser_dip = ndi_devi_findchild(ebus_dip, SERIAL_PATH);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: find-serial-dip: "
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki "ser_dip = %p", (void *)ser_dip));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ndi_devi_exit(ebus_dip, circ2);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ndi_devi_exit(cmuch_dip, circ1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ser_dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Find all console related serial devices.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_find_serial(ser_devl_t **ser_dl)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_info_t *root_dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_info_t *cmuch_dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_info_t *dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ser_devl_t *wrk_ser_dl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int circ;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int count = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char pathname[MSU_PATHNAME_SIZE];
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_t devt;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char *namep;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl root_dip = ddi_root_node();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ndi_devi_enter(root_dip, &circ);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmuch_dip = ddi_get_child(root_dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (cmuch_dip != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl namep = ddi_binding_name(cmuch_dip); /* Get binding name */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (namep == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmuch_dip = ddi_get_next_sibling(cmuch_dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: find-serial: name => %s", namep));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((strcmp(namep, MSU_CMUCH_FF) != 0) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (strcmp(namep, MSU_CMUCH_DC) != 0)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef DEBUG
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (strcmp(namep, MSU_CMUCH_DBG) != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmuch_dip = ddi_get_next_sibling(cmuch_dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#else
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmuch_dip = ddi_get_next_sibling(cmuch_dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
5b20806ae198c3fcc384c453bb02089b8ab80074raghuram /*
5b20806ae198c3fcc384c453bb02089b8ab80074raghuram * Online the cmuch_dip so that its in the right state
5b20806ae198c3fcc384c453bb02089b8ab80074raghuram * to get the complete path, that is both name and address.
5b20806ae198c3fcc384c453bb02089b8ab80074raghuram */
5b20806ae198c3fcc384c453bb02089b8ab80074raghuram (void) ndi_devi_online(cmuch_dip, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ddi_pathname(cmuch_dip, pathname);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "oplmsu: find-serial: cmu-ch path => %s", pathname));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) strcat(pathname, EBUS_SERIAL_PATH);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Call ddi_pathname_to_dev_t to forceload and attach
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * the required drivers.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl devt = ddi_pathname_to_dev_t(pathname);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: find-serial: serial device "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "dev_t = %lx", devt));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((devt != NODEV) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ((dip = oplmsu_find_ser_dip(cmuch_dip)) != NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl wrk_ser_dl = (ser_devl_t *)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_zalloc(sizeof (ser_devl_t), KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl wrk_ser_dl->dip = dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl count += 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (*ser_dl != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl wrk_ser_dl->next = *ser_dl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *ser_dl = wrk_ser_dl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmuch_dip = ddi_get_next_sibling(cmuch_dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ndi_devi_exit(root_dip, circ);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (count);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Configure STREAM */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlvoid
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_conf_stream(uinst_t *msu_uinst)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_t msu_li = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_handle_t msu_lh = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct msu_path *mpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct msu_dev *mdev;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ser_devl_t *ser_dl = NULL, *next_ser_dl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int *plink_id;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int size;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int i;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int param;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int connected = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int devcnt = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "oplmsu: conf-stream: stream configuration start!"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Find serial devices */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl devcnt = oplmsu_find_serial(&ser_dl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((devcnt == 0) || (ser_dl == NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stream: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Discovered serial device = %d", devcnt);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Open oplmsu */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_open_msu(msu_uinst->msu_dip, &msu_li, &msu_lh);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stream: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "msu open failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl size = (sizeof (struct msu_path) + (sizeof (struct msu_dev) * devcnt));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mpath = (struct msu_path *)kmem_zalloc((size_t)size, KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl plink_id = (int *)kmem_zalloc((sizeof (int) * devcnt), KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev = (struct msu_dev *)(mpath + 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (i = 0; i < devcnt; i++) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Connect two streams */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_plink_serial(ser_dl->dip, msu_lh, &plink_id[i]);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stream: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "i_plink failed. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl next_ser_dl = ser_dl->next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(ser_dl, sizeof (ser_devl_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ser_dl = next_ser_dl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_set_lpathnum(plink_id[i],
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_get_instance(ser_dl->dip));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stream: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Link id %d is not found", plink_id[i]);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Issue ioctl(I_PUNLINK) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_ioctl(msu_lh, I_PUNLINK,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (intptr_t)plink_id[i], FKIOCTL, kcred, &param);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl next_ser_dl = ser_dl->next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(ser_dl, sizeof (ser_devl_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ser_dl = next_ser_dl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev->dip = ser_dl->dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl next_ser_dl = ser_dl->next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(ser_dl, sizeof (ser_devl_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ser_dl = next_ser_dl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl connected++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (connected == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stream: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Connected paths = %d", connected);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(msu_lh, (FREAD|FWRITE), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(msu_li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(plink_id, (sizeof (int) * devcnt));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(mpath, size);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Setup all structure */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mpath->num = connected;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_config_new(mpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stream: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to create all paths. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_unlinks(msu_lh, plink_id, devcnt);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(msu_lh, (FREAD|FWRITE), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(msu_li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(plink_id, (sizeof (int) * devcnt));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(mpath, size);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Start to use all paths */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_config_start(MSU_PATH_ALL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stream: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to start all paths. errno = %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Delete the path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_config_del(mpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_unlinks(msu_lh, plink_id, devcnt);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_close(msu_lh, (FREAD|FWRITE), kcred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ldi_ident_release(msu_li);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(plink_id, (sizeof (int) * devcnt));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(mpath, size);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: conf-stream: stream configuration end!"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlvoid
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_unlinks(ldi_handle_t msu_lh, int *plink_id, int devcnt)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int i;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int param = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (i = 0; i < devcnt; i++) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (plink_id[i] == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Issue ioctl(I_PUNLINK) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) ldi_ioctl(msu_lh, I_PUNLINK, (intptr_t)plink_id[i],
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FKIOCTL, kcred, &param);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlvoid
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_setup(uinst_t *msu_uinst)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: setup: Background thread start!"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_conf_st == MSU_CONFIGURING) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_conf_stream(msu_uinst); /* Configure stream */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_conf_st = MSU_CONFIGURED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_broadcast(&oplmsu_conf_cv); /* Wake up from cv_wait_sig() */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_bthrd_id != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_bthrd_id = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_bthrd_excl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: setup: Background thread end!"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl thread_exit();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_create_upath(dev_info_t *dip)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath_t *upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_info_t *cmuch_dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int lsb;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmuch_dip = ddi_get_parent(ddi_get_parent(dip));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lsb = ddi_prop_get_int(DDI_DEV_T_ANY, cmuch_dip, 0, MSU_BOARD_PROP,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lsb == FAILURE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (lsb);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance = ddi_get_instance(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = oplmsu_uinst->first_lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (lpath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath->path_no == instance) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = lpath->l_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ENODEV);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = (upath_t *)kmem_zalloc(sizeof (upath_t), KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Initialize members of upath_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->path_no = instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->lpath = lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->ser_devcb.dip = dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->ser_devcb.lsb = lsb;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_STOP, MSU_PSTAT_EMPTY,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl MSU_STOP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->status = MSU_EXT_NOTUSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_link_upath(upath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Setup new upper instance structure */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_config_new(struct msu_path *mpath)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct msu_dev *mdev;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int i;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval = SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: conf-new: config_new() called"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(mpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mpath->num == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-new: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Number of paths = %d", mpath->num);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_check_lpath_usable();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval == BUSY) { /* Check whether Lower path is usable */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-new: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Other processing is using this device");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBUSY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Because the OPLMSU instance already exists when the upper path
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * table exists, the configure_new processing cannot be done.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((oplmsu_uinst->first_upath != NULL) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (oplmsu_uinst->last_upath != NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-new: upath_t already exist");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Because the config_new processing has already been done
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * if oplmsu_uinst->path_num isn't -1, this processing cannot be
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * continued.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_uinst->path_num != UNDEFINED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-new: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "conf-new processing has already been completed");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Only the number of specified paths makes the upper path
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information tables.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev = (struct msu_dev *)(mpath + 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (i = 0; i < mpath->num; i++) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Associate upper path information table with lower path
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information table.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If the upper path information table and the lower path
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information table cannot be associated, the link list of
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * the upper path information table is released.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_create_upath(mdev->dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_delete_upath_info();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-new: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to create upath %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Setup members of uinst_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->inst_status = oplmsu_get_inst_status();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->path_num = mpath->num;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->lower_queue = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Add path information */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_config_add(dev_info_t *dip)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath_t *upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval = SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: conf-add: config_add() called"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance = ddi_get_instance(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_uinst->path_num == UNDEFINED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-add: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "conf-new processing has not been completed yet");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = oplmsu_search_upath_info(instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (upath != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-add: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper upath_t doesn't find");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = oplmsu_create_upath(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rval != SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-add: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to create upath %d", rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->inst_status = oplmsu_get_inst_status();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->path_num = oplmsu_get_pathnum();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Delete each path information */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_config_del(struct msu_path *mpath)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct msu_dev *mdev;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath_t *upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rval = SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int use_flag;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int i;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: conf-del: config_del() called"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(mpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev = (struct msu_dev *)(mpath + 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (i = 0; i < mpath->num; i++) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = oplmsu_search_upath_info(ddi_get_instance(mdev->dip));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (upath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-del: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper upath_t doesn't find");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = ENODEV;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = upath->lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((upath->traditional_status == MSU_WSTP_ACK) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_WSTR_ACK) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_WPTH_CHG) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_WTCS_ACK) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_WTMS_ACK) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_WPPS_ACK) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_WWSZ_ACK) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_WCAR_ACK)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-del: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Other processing is using this device");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = EBUSY;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((upath->status != MSU_PSTAT_DISCON) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status != MSU_DISCON)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-del: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Status of path is improper");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = EINVAL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl use_flag = oplmsu_set_ioctl_path(lpath, NULL, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (use_flag == BUSY) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-del: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Other processing is using lower path");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = EBUSY;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (((upath->status != MSU_PSTAT_STOP) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status != MSU_STOP)) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ((upath->status != MSU_PSTAT_FAIL) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status != MSU_FAIL))) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-del: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Status of path isn't 'Offline:stop/fail'");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rval = EINVAL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->status = MSU_SETID_NU;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_unlink_upath(upath); /* Unlink upath_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(upath, sizeof (upath_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mdev++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->inst_status = oplmsu_get_inst_status();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->path_num = oplmsu_get_pathnum();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Stop to use the path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_config_stop(int pathnum)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath_t *upath, *altn_upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath, *altn_lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl queue_t *stp_queue = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl queue_t *dst_queue = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mblk_t *nmp = NULL, *fmp = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl_t *ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int term_ioctl, term_stat;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int use_flag;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "oplmsu: conf-stop: config_stop(%d) called", pathnum));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (pathnum == MSU_PATH_ALL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stop: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "All path can't be transferred to the status of "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "'Offline:stop'");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = oplmsu_search_upath_info(pathnum); /* Search upath_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (upath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stop: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper upath_t doesn't find");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ENODEV);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = upath->lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stop: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper lpath_t doesn't exist");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ENODEV);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Check status of lpath_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl use_flag = oplmsu_set_ioctl_path(lpath, NULL, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (use_flag == BUSY) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stop: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Other processing is using lower path");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBUSY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (upath->status == MSU_PSTAT_FAIL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if ((upath->status == MSU_PSTAT_STOP) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_STOP)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if ((upath->status == MSU_PSTAT_STANDBY) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_STANDBY)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_STOP,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->status, MSU_STOP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->status = MSU_EXT_NOTUSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->inst_status = oplmsu_get_inst_status();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if ((upath->status == MSU_PSTAT_ACTIVE) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_ACTIVE)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_upath = oplmsu_search_standby();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (altn_upath == NULL) { /* Alternate path doesn't exist */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE, "oplmsu: conf-stop: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Alternate upper path doesn't find"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((fmp = allocb(sizeof (char), BPRI_LO)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ENOSR);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_stop_prechg(&nmp, &term_ioctl, &term_stat) !=
25cf1a301a396c38e8adf52c15f537b80d2483f7jl SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl freeb(fmp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ENOSR);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath = altn_upath->lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl use_flag = oplmsu_set_ioctl_path(altn_lpath, NULL, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (use_flag == BUSY) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stop: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Other processing is using alternate lower path");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl freeb(fmp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl freemsg(nmp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBUSY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dst_queue = WR(altn_lpath->lower_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* termios is not held. Change alternate path to MSU_ACTIVE */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (nmp == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_upath->traditional_status = term_stat;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->src_upath = upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->status = MSU_EXT_VOID;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->lower_queue = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl = oplmsu_uinst->user_ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ctrl != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl stp_queue = WR(ctrl->queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl noenable(stp_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_queue_flag = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Make M_FLUSH and send to alternate path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_mflush(fmp);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) putq(dst_queue, fmp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Change status of alternate path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_upath_sts(altn_upath, MSU_PSTAT_ACTIVE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_upath->status, MSU_ACTIVE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(altn_lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->uinst = oplmsu_uinst;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->status = MSU_EXT_NOTUSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Notify of the active path changing */
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) prom_opl_switch_console(
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki altn_upath->ser_devcb.lsb);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Send XON to notify active path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) oplmsu_cmn_put_xoffxon(dst_queue, MSU_XON_4);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Send XOFF to notify all standby paths */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_putxoff_standby();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->lower_queue = RD(dst_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl = oplmsu_uinst->user_ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Switch active path of oplmsu */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ctrl != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl queue_t *altn_queue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_queue = WR(ctrl->queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Restart queuing of user access node */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl enableok(altn_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_queue_flag = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_wcmn_high_qenable(altn_queue, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Stop previous active path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_STOP,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->status, MSU_STOP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->uinst = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->status = MSU_EXT_NOTUSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->inst_status = oplmsu_get_inst_status();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Send termios information to alternate path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (canput(dst_queue)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_upath->traditional_status = term_stat;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->src_upath = upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->status = MSU_EXT_VOID;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->traditional_status = MSU_WSTP_ACK;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->uinst = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->lower_queue = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ctrl = oplmsu_uinst->user_ctrl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ctrl != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl stp_queue = WR(ctrl->queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->c_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl noenable(stp_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_queue_flag = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_mflush(fmp);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) putq(dst_queue, fmp);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) putq(dst_queue, nmp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->sw_flag = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (lpath->sw_flag != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Wait for the completion of path switching */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_wait(&lpath->sw_cv, &oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(altn_lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl freeb(fmp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl freemsg(nmp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* NOTREACHED */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-stop: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Status of path is improper");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* NOTREACHED */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Start to use path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_config_start(int pathnum)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath_t *upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl queue_t *dst_queue, *main_rq = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int msu_tty_port;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "oplmsu: conf-start: config_start(%d) called", pathnum));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_WRITER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (oplmsu_get_inst_status() == INST_STAT_BUSY) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBUSY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (pathnum == MSU_PATH_ALL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) oplmsu_search_min_stop_path();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (upath = oplmsu_uinst->first_upath; upath; ) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((pathnum != MSU_PATH_ALL) && (upath->path_no != pathnum)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = upath->u_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (upath->path_no == pathnum) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = upath->lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-start: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper lpath_t doesn't exist");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_STANDBY,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->status, MSU_STANDBY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->status = MSU_EXT_NOTUSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * with PATH_ALL
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = upath->lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = upath->u_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_WARN, "oplmsu: conf-start: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper lpath_t doesn't exist"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl msu_tty_port = ddi_prop_get_int(DDI_DEV_T_ANY,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->msu_dip, 0, MSU_TTY_PORT_PROP, -1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (upath->ser_devcb.lsb == msu_tty_port) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Notify of the active path changing */
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) prom_opl_switch_console(upath->ser_devcb.lsb);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_ACTIVE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->status, MSU_ACTIVE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl main_rq = RD(lpath->lower_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dst_queue = WR(lpath->lower_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->status = MSU_EXT_NOTUSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->uinst = oplmsu_uinst;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Send XON to notify active path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) oplmsu_cmn_put_xoffxon(dst_queue, MSU_XON_4);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_upath_sts(upath, MSU_PSTAT_STANDBY,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->status, MSU_STANDBY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath->status = MSU_EXT_NOTUSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = upath->u_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (main_rq == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath_t *altn_upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *altn_lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_upath = oplmsu_search_standby();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (altn_upath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_set_upath_sts(altn_upath, MSU_PSTAT_ACTIVE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_upath->status, MSU_ACTIVE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Notify of the active path changing */
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) prom_opl_switch_console(
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki altn_upath->ser_devcb.lsb);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath = altn_upath->lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (altn_lpath) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl main_rq = RD(altn_lpath->lower_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dst_queue = WR(altn_lpath->lower_queue);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->src_upath = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->status = MSU_EXT_NOTUSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl altn_lpath->uinst = oplmsu_uinst;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Send XON to notify active path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) oplmsu_cmn_put_xoffxon(dst_queue,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl MSU_XON_4);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-start: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper alternate lpath_t doesn't exist");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-start: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper alternate upath_t doesn't exist");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Send XOFF to notify all standby paths */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_cmn_putxoff_standby();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Change active path of oplmsu */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->lower_queue = main_rq;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_uinst->inst_status = oplmsu_get_inst_status();
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Prepare of unlink path */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jloplmsu_config_disc(int pathnum)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath_t *upath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath_t *lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int use_flag;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DBG_PRINT((CE_NOTE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "oplmsu: conf-disc: config_disc(%d) called", pathnum));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_enter(&oplmsu_uinst->lock, RW_READER);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath = oplmsu_search_upath_info(pathnum);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (upath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-disc: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper upath_t doesn't find");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((upath->status == MSU_PSTAT_DISCON) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status == MSU_DISCON)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if (((upath->status != MSU_PSTAT_STOP) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status != MSU_STOP)) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ((upath->status != MSU_PSTAT_FAIL) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (upath->traditional_status != MSU_FAIL))) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-disc: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Status of path is improper");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl lpath = upath->lpath;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (lpath == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-disc: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Proper lpath_t doesn't exist");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ENODEV);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Check lower path status */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl use_flag = oplmsu_set_ioctl_path(lpath, NULL, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (use_flag == BUSY) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "oplmsu: conf-disc: "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Other processing is using lower path");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBUSY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->status = MSU_PSTAT_STOP;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl upath->traditional_status = MSU_SETID;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl oplmsu_clear_ioctl_path(lpath);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->l_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&oplmsu_uinst->u_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rw_exit(&oplmsu_uinst->lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}