usr/src/uts/common/os/sunmdi.c
author ramat
Thu, 10 Nov 2005 07:14:29 -0800
changeset 878 964ddd439490
parent 82 0728ea41cce7
child 893 76977629f0d7
permissions -rw-r--r--
PSARC 2005/583 VHCI Driven Device Enumeration 4938301 scsi_vhci does not enumerate devices on-demand (BUS_CONFIG_ONE)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
 * Multipath driver interface (MDI) implementation; see mdi_impl.h for a more
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 * detailed discussion of the overall mpxio architecture.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * Default locking order:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * _NOTE(LOCK_ORDER(mdi_mutex, mdi_phci::ph_mutex))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * _NOTE(LOCK_ORDER(mdi_mutex, mdi_client::ct_mutex))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * _NOTE(LOCK_ORDER(mdi_phci::ph_mutex mdi_pathinfo::pi_mutex))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 * _NOTE(LOCK_ORDER(mdi_phci::ph_mutex mdi_client::ct_mutex))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 * _NOTE(LOCK_ORDER(mdi_client::ct_mutex mdi_pathinfo::pi_mutex))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/note.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/varargs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/uio.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/buf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/modctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/open.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/poll.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <sys/conf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/bootconf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
#include <sys/stat.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include <sys/ddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#include <sys/sunddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
#include <sys/ddipropdefs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#include <sys/sunndi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include <sys/ndi_impldefs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
#include <sys/promif.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
#include <sys/sunmdi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
#include <sys/mdi_impldefs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <sys/taskq.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include <sys/epm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
#include <sys/sunpm.h>
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
    67
#include <sys/modhash.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
#ifdef	DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
int	mdi_debug = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
#define	MDI_DEBUG(level, stmnt) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
	    if (mdi_debug >= (level)) i_mdi_log stmnt
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
static void i_mdi_log(int, dev_info_t *, const char *fmt, ...);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
#else	/* !DEBUG */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
#define	MDI_DEBUG(level, stmnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
#endif	/* DEBUG */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
extern pri_t	minclsyspri;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
extern int	modrootloaded;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 * Global mutex:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 * Protects vHCI list and structure members, pHCI and Client lists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
kmutex_t	mdi_mutex;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 * Registered vHCI class driver lists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
int		mdi_vhci_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
mdi_vhci_t	*mdi_vhci_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
mdi_vhci_t	*mdi_vhci_tail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 * Client Hash Table size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
static int	mdi_client_table_size = CLIENT_HASH_TABLE_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
 * taskq interface definitions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
#define	MDI_TASKQ_N_THREADS	8
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
#define	MDI_TASKQ_PRI		minclsyspri
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
#define	MDI_TASKQ_MINALLOC	(4*mdi_taskq_n_threads)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
#define	MDI_TASKQ_MAXALLOC	(500*mdi_taskq_n_threads)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
taskq_t				*mdi_taskq;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
static uint_t			mdi_taskq_n_threads = MDI_TASKQ_N_THREADS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   111
#define	TICKS_PER_SECOND	(drv_usectohz(1000000))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   112
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   113
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   114
 * The data should be "quiet" for this interval (in seconds) before the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   115
 * vhci cached data is flushed to the disk.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   116
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   117
static int mdi_vhcache_flush_delay = 10;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   118
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   119
/* number of seconds the vhcache flush daemon will sleep idle before exiting */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   120
static int mdi_vhcache_flush_daemon_idle_time = 60;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   121
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   122
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   123
 * number of seconds the asynchronous configuration thread will sleep idle
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   124
 * before exiting.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   125
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   126
static int mdi_async_config_idle_time = 600;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   127
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   128
static int mdi_bus_config_cache_hash_size = 256;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   129
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   130
/* turns off multithreaded configuration for certain operations */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   131
static int mdi_mtc_off = 0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 * MDI component property name/value string definitions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
const char 		*mdi_component_prop = "mpxio-component";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
const char		*mdi_component_prop_vhci = "vhci";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
const char		*mdi_component_prop_phci = "phci";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
const char		*mdi_component_prop_client = "client";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
 * MDI client global unique identifier property name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
const char		*mdi_client_guid_prop = "client-guid";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
 * MDI client load balancing property name/value string definitions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
const char		*mdi_load_balance = "load-balance";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
const char		*mdi_load_balance_none = "none";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
const char		*mdi_load_balance_rr = "round-robin";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
const char		*mdi_load_balance_lba = "logical-block";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
 * Obsolete vHCI class definition; to be removed after Leadville update
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
const char *mdi_vhci_class_scsi = MDI_HCI_CLASS_SCSI;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
static char vhci_greeting[] =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	"\tThere already exists one vHCI driver for class %s\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	"\tOnly one vHCI driver for each class is allowed\n";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
 * Static function prototypes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
static int		i_mdi_phci_offline(dev_info_t *, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
static int		i_mdi_client_offline(dev_info_t *, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
static int		i_mdi_phci_pre_detach(dev_info_t *, ddi_detach_cmd_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
static void		i_mdi_phci_post_detach(dev_info_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
			    ddi_detach_cmd_t, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
static int		i_mdi_client_pre_detach(dev_info_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
			    ddi_detach_cmd_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
static void		i_mdi_client_post_detach(dev_info_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
			    ddi_detach_cmd_t, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
static void		i_mdi_pm_hold_pip(mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
static void		i_mdi_pm_rele_pip(mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
static int 		i_mdi_lba_lb(mdi_client_t *ct,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
			    mdi_pathinfo_t **ret_pip, struct buf *buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
static void		i_mdi_pm_hold_client(mdi_client_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
static void		i_mdi_pm_rele_client(mdi_client_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
static void		i_mdi_pm_reset_client(mdi_client_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
static void		i_mdi_pm_hold_all_phci(mdi_client_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
static int		i_mdi_power_all_phci(mdi_client_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
 * Internal mdi_pathinfo node functions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
static int		i_mdi_pi_kstat_create(mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
static void		i_mdi_pi_kstat_destroy(mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
static mdi_vhci_t	*i_mdi_vhci_class2vhci(char *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
static mdi_vhci_t	*i_devi_get_vhci(dev_info_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
static mdi_phci_t	*i_devi_get_phci(dev_info_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
static void		i_mdi_phci_lock(mdi_phci_t *, mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
static void		i_mdi_phci_get_client_lock(mdi_phci_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
			    mdi_client_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
static void		i_mdi_phci_unlock(mdi_phci_t *);
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   199
static mdi_pathinfo_t	*i_mdi_pi_alloc(mdi_phci_t *, char *, mdi_client_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
static void		i_mdi_phci_add_path(mdi_phci_t *, mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
static void		i_mdi_client_add_path(mdi_client_t *, mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
static void		i_mdi_pi_free(mdi_phci_t *ph, mdi_pathinfo_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
			    mdi_client_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
static void		i_mdi_phci_remove_path(mdi_phci_t *, mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
static void		i_mdi_client_remove_path(mdi_client_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
			    mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
static int		i_mdi_pi_state_change(mdi_pathinfo_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
			    mdi_pathinfo_state_t, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
static int		i_mdi_pi_offline(mdi_pathinfo_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
static dev_info_t	*i_mdi_devinfo_create(mdi_vhci_t *, char *, char *,
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   212
			    char **, int);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
static dev_info_t	*i_mdi_devinfo_find(mdi_vhci_t *, char *, char *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
static int		i_mdi_devinfo_remove(dev_info_t *, dev_info_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
static int		i_mdi_is_child_present(dev_info_t *, dev_info_t *);
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   216
static mdi_client_t	*i_mdi_client_alloc(mdi_vhci_t *, char *, char *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
static void		i_mdi_client_enlist_table(mdi_vhci_t *, mdi_client_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
static void		i_mdi_client_delist_table(mdi_vhci_t *, mdi_client_t *);
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   219
static mdi_client_t	*i_mdi_client_find(mdi_vhci_t *, char *, char *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
static void		i_mdi_client_update_state(mdi_client_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
static int		i_mdi_client_compute_state(mdi_client_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
			    mdi_phci_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
static void		i_mdi_client_lock(mdi_client_t *, mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
static void		i_mdi_client_unlock(mdi_client_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
static int		i_mdi_client_free(mdi_vhci_t *, mdi_client_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
static mdi_client_t	*i_devi_get_client(dev_info_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
static int		i_mdi_pi_enable_disable(dev_info_t *, dev_info_t *, int,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
			int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
 * Failover related function prototypes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
static int		i_mdi_failover(void *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
 * misc internal functions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
static int		i_mdi_get_hash_key(char *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
static int		i_map_nvlist_error_to_mdi(int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
static void		i_mdi_report_path_state(mdi_client_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
			    mdi_pathinfo_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   242
static void		setup_vhci_cache(mdi_vhci_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   243
static int		destroy_vhci_cache(mdi_vhci_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   244
static void		setup_phci_driver_list(mdi_vhci_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   245
static void		free_phci_driver_list(mdi_vhci_config_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   246
static int		stop_vhcache_async_threads(mdi_vhci_config_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   247
static boolean_t	stop_vhcache_flush_thread(void *, int);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   248
static void		free_string_array(char **, int);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   249
static void		free_vhcache_phci(mdi_vhcache_phci_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   250
static void		free_vhcache_pathinfo(mdi_vhcache_pathinfo_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   251
static void		free_vhcache_client(mdi_vhcache_client_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   252
static int		mainnvl_to_vhcache(mdi_vhci_cache_t *, nvlist_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   253
static nvlist_t		*vhcache_to_mainnvl(mdi_vhci_cache_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   254
static void		vhcache_phci_add(mdi_vhci_config_t *, mdi_phci_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   255
static void		vhcache_phci_remove(mdi_vhci_config_t *, mdi_phci_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   256
static void		vhcache_pi_add(mdi_vhci_config_t *,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   257
			    struct mdi_pathinfo *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   258
static void		vhcache_pi_remove(mdi_vhci_config_t *,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   259
			    struct mdi_pathinfo *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   260
static void		free_phclient_path_list(mdi_phys_path_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   261
static void		sort_vhcache_paths(mdi_vhcache_client_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   262
static int		flush_vhcache(mdi_vhci_config_t *, int);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   263
static void		vhcache_dirty(mdi_vhci_config_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   264
static void		free_async_client_config(mdi_async_client_config_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   265
static nvlist_t		*read_on_disk_vhci_cache(char *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   266
extern int		fread_nvlist(char *, nvlist_t **);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   267
extern int		fwrite_nvlist(char *, nvlist_t *);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   268
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
/* called once when first vhci registers with mdi */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
i_mdi_init()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	static int initialized = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
	if (initialized)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
	initialized = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
	mutex_init(&mdi_mutex, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	 * Create our taskq resources
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	mdi_taskq = taskq_create("mdi_taskq", mdi_taskq_n_threads,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	    MDI_TASKQ_PRI, MDI_TASKQ_MINALLOC, MDI_TASKQ_MAXALLOC,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
	    TASKQ_PREPOPULATE | TASKQ_CPR_SAFE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	ASSERT(mdi_taskq != NULL);	/* taskq_create never fails */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
 * mdi_get_component_type():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
 *		Return mpxio component type
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
 *		MDI_COMPONENT_NONE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
 *		MDI_COMPONENT_VHCI
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
 *		MDI_COMPONENT_PHCI
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
 *		MDI_COMPONENT_CLIENT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
 * XXX This doesn't work under multi-level MPxIO and should be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
 *	removed when clients migrate mdi_is_*() interfaces.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
mdi_get_component_type(dev_info_t *dip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	return (DEVI(dip)->devi_mdi_component);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
 * mdi_vhci_register():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
 *		Register a vHCI module with the mpxio framework
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
 *		mdi_vhci_register() is called by vHCI drivers to register the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
 *		'class_driver' vHCI driver and its MDI entrypoints with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
 *		mpxio framework.  The vHCI driver must call this interface as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
 *		part of its attach(9e) handler.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
 *		Competing threads may try to attach mdi_vhci_register() as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
 *		the vHCI drivers are loaded and attached as a result of pHCI
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
 *		driver instance registration (mdi_phci_register()) with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
 *		framework.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
mdi_vhci_register(char *class, dev_info_t *vdip, mdi_vhci_ops_t *vops,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
    int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	mdi_vhci_t		*vh = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	ASSERT(vops->vo_revision == MDI_VHCI_OPS_REV);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	i_mdi_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	mutex_enter(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
	 * Scan for already registered vhci
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
	for (vh = mdi_vhci_head; vh != NULL; vh = vh->vh_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
		if (strcmp(vh->vh_class, class) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
			 * vHCI has already been created.  Check for valid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
			 * vHCI ops registration.  We only support one vHCI
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
			 * module per class
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
			if (vh->vh_ops != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
				mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
				cmn_err(CE_NOTE, vhci_greeting, class);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
				return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	 * if not yet created, create the vHCI component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
	if (vh == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
		struct client_hash	*hash = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
		char			*load_balance;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
		 * Allocate and initialize the mdi extensions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
		vh = kmem_zalloc(sizeof (mdi_vhci_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
		hash = kmem_zalloc(mdi_client_table_size * sizeof (*hash),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
		    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
		vh->vh_client_table = hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
		vh->vh_class = kmem_zalloc(strlen(class) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
		(void) strcpy(vh->vh_class, class);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
		vh->vh_lb = LOAD_BALANCE_RR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, vdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
		    0, LOAD_BALANCE_PROP, &load_balance) == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
			if (strcmp(load_balance, LOAD_BALANCE_PROP_NONE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
				vh->vh_lb = LOAD_BALANCE_NONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
			} else if (strcmp(load_balance, LOAD_BALANCE_PROP_LBA)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
				    == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
				vh->vh_lb = LOAD_BALANCE_LBA;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
			ddi_prop_free(load_balance);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
		 * Store the vHCI ops vectors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
		vh->vh_dip = vdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
		vh->vh_ops = vops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   387
		setup_vhci_cache(vh);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
		if (mdi_vhci_head == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
			mdi_vhci_head = vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		if (mdi_vhci_tail) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
			mdi_vhci_tail->vh_next = vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
		mdi_vhci_tail = vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
		mdi_vhci_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
	 * Claim the devfs node as a vhci component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
	DEVI(vdip)->devi_mdi_component |= MDI_COMPONENT_VHCI;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
	 * Initialize our back reference from dev_info node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
	DEVI(vdip)->devi_mdi_xhci = (caddr_t)vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
	mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
 * mdi_vhci_unregister():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
 *		Unregister a vHCI module from mpxio framework
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
 *		mdi_vhci_unregister() is called from the detach(9E) entrypoint
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
 * 		of a vhci to unregister it from the framework.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
mdi_vhci_unregister(dev_info_t *vdip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	mdi_vhci_t	*found, *vh, *prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	 * Check for invalid VHCI
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	if ((vh = i_devi_get_vhci(vdip)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	mutex_enter(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	 * Scan the list of registered vHCIs for a match
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	for (found = mdi_vhci_head; found != NULL; found = found->vh_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
		if (found == vh)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
		prev = found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
	if (found == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
		mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
	 * Check the pHCI and client count. All the pHCIs and clients
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	 * should have been unregistered, before a vHCI can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
	 * unregistered.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	 */
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   455
	if (vh->vh_phci_count || vh->vh_client_count || vh->vh_refcnt) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
		mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
	 * Remove the vHCI from the global list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	if (vh == mdi_vhci_head) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
		mdi_vhci_head = vh->vh_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
		prev->vh_next = vh->vh_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
	if (vh == mdi_vhci_tail) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
		mdi_vhci_tail = prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
	mdi_vhci_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
	mutex_exit(&mdi_mutex);
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   474
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   475
	if (destroy_vhci_cache(vh) != MDI_SUCCESS) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   476
		/* add vhci to the global list */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   477
		mutex_enter(&mdi_mutex);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   478
		if (mdi_vhci_head == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   479
			mdi_vhci_head = vh;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   480
		else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   481
			mdi_vhci_tail->vh_next = vh;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   482
		mdi_vhci_tail = vh;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   483
		mdi_vhci_count++;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   484
		mutex_exit(&mdi_mutex);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   485
		return (MDI_FAILURE);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   486
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   487
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   488
	vh->vh_ops = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
	DEVI(vdip)->devi_mdi_component &= ~MDI_COMPONENT_VHCI;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	DEVI(vdip)->devi_mdi_xhci = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
	kmem_free(vh->vh_class, strlen(vh->vh_class)+1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
	kmem_free(vh->vh_client_table,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	    mdi_client_table_size * sizeof (struct client_hash));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
	kmem_free(vh, sizeof (mdi_vhci_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
 * i_mdi_vhci_class2vhci():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
 *		Look for a matching vHCI module given a vHCI class name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
 *		Handle to a vHCI component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
 *		NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
static mdi_vhci_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
i_mdi_vhci_class2vhci(char *class)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
	mdi_vhci_t	*vh = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	ASSERT(!MUTEX_HELD(&mdi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
	mutex_enter(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	for (vh = mdi_vhci_head; vh != NULL; vh = vh->vh_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
		if (strcmp(vh->vh_class, class) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
	mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	return (vh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
 * i_devi_get_vhci():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
 *		Utility function to get the handle to a vHCI component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
 *		Handle to a vHCI component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
 *		NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
mdi_vhci_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
i_devi_get_vhci(dev_info_t *vdip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
	mdi_vhci_t	*vh = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	if (MDI_VHCI(vdip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
		vh = (mdi_vhci_t *)DEVI(vdip)->devi_mdi_xhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	return (vh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
 * mdi_phci_register():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
 *		Register a pHCI module with mpxio framework
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
 *		mdi_phci_register() is called by pHCI drivers to register with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
 *		the mpxio framework and a specific 'class_driver' vHCI.  The
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
 *		pHCI driver must call this interface as part of its attach(9e)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
 *		handler.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
mdi_phci_register(char *class, dev_info_t *pdip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
	mdi_phci_t		*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
	mdi_vhci_t		*vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
	char			*data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
	char			*pathname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
	pathname = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
	(void) ddi_pathname(pdip, pathname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
	 * Check for mpxio-disable property. Enable mpxio if the property is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
	 * missing or not set to "yes".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
	 * If the property is set to "yes" then emit a brief message.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip, 0, "mpxio-disable",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
	    &data) == DDI_SUCCESS)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
		if (strcmp(data, "yes") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
			MDI_DEBUG(1, (CE_CONT, pdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
			    "?%s (%s%d) multipath capabilities "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
			    "disabled via %s.conf.\n", pathname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
			    ddi_driver_name(pdip), ddi_get_instance(pdip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
			    ddi_driver_name(pdip)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
			ddi_prop_free(data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
			kmem_free(pathname, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
			return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
		ddi_prop_free(data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
	kmem_free(pathname, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
	 * Search for a matching vHCI
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
	vh = (mdi_vhci_t *)i_mdi_vhci_class2vhci(class);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
	if (vh == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
	ph = kmem_zalloc(sizeof (mdi_phci_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
	mutex_init(&ph->ph_mutex, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
	ph->ph_dip = pdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
	ph->ph_vhci = vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
	ph->ph_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	ph->ph_unstable = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
	ph->ph_vprivate = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
	cv_init(&ph->ph_unstable_cv, NULL, CV_DRIVER, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
	cv_init(&ph->ph_powerchange_cv, NULL, CV_DRIVER, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
	MDI_PHCI_SET_POWER_UP(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
	DEVI(pdip)->devi_mdi_component |= MDI_COMPONENT_PHCI;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
	DEVI(pdip)->devi_mdi_xhci = (caddr_t)ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   607
	vhcache_phci_add(vh->vh_config, ph);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   608
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
	mutex_enter(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
	if (vh->vh_phci_head == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
		vh->vh_phci_head = ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	if (vh->vh_phci_tail) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
		vh->vh_phci_tail->ph_next = ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
	vh->vh_phci_tail = ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
	vh->vh_phci_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
	mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
 * mdi_phci_unregister():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
 *		Unregister a pHCI module from mpxio framework
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
 *		mdi_phci_unregister() is called by the pHCI drivers from their
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
 *		detach(9E) handler to unregister their instances from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
 *		framework.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
mdi_phci_unregister(dev_info_t *pdip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
	mdi_vhci_t		*vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
	mdi_phci_t		*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
	mdi_phci_t		*tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
	mdi_phci_t		*prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
	ph = i_devi_get_phci(pdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
		MDI_DEBUG(1, (CE_WARN, pdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
		    "!pHCI unregister: Not a valid pHCI"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
	vh = ph->ph_vhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	ASSERT(vh != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
	if (vh == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
		MDI_DEBUG(1, (CE_WARN, pdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
		    "!pHCI unregister: Not a valid vHCI"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
	mutex_enter(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
	tmp = vh->vh_phci_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
	while (tmp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
		if (tmp == ph) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
		prev = tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
		tmp = tmp->ph_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
	if (ph == vh->vh_phci_head) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
		vh->vh_phci_head = ph->ph_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
		prev->ph_next = ph->ph_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	if (ph == vh->vh_phci_tail) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
		vh->vh_phci_tail = prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
	vh->vh_phci_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
	mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   681
	vhcache_phci_remove(vh->vh_config, ph);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
	cv_destroy(&ph->ph_unstable_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	cv_destroy(&ph->ph_powerchange_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
	mutex_destroy(&ph->ph_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	kmem_free(ph, sizeof (mdi_phci_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	DEVI(pdip)->devi_mdi_component &= ~MDI_COMPONENT_PHCI;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
	DEVI(pdip)->devi_mdi_xhci = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
 * i_devi_get_phci():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
 * 		Utility function to return the phci extensions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
static mdi_phci_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
i_devi_get_phci(dev_info_t *pdip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
	mdi_phci_t	*ph = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
	if (MDI_PHCI(pdip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
		ph = (mdi_phci_t *)DEVI(pdip)->devi_mdi_xhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
	return (ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
 * mdi_phci_path2devinfo():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
 * 		Utility function to search for a valid phci device given
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
 *		the devfs pathname.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
dev_info_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
mdi_phci_path2devinfo(dev_info_t *vdip, caddr_t pathname)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
	char		*temp_pathname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	mdi_vhci_t	*vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
	dev_info_t 	*pdip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
	vh = i_devi_get_vhci(vdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
	ASSERT(vh != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
	if (vh == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
		 * Invalid vHCI component, return failure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	temp_pathname = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
	mutex_enter(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
	ph = vh->vh_phci_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
	while (ph != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
		pdip = ph->ph_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
		ASSERT(pdip != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
		*temp_pathname = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
		(void) ddi_pathname(pdip, temp_pathname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
		if (strcmp(temp_pathname, pathname) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
		ph = ph->ph_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
		pdip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
	mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
	kmem_free(temp_pathname, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
	return (pdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
 * mdi_phci_get_path_count():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
 * 		get number of path information nodes associated with a given
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
 *		pHCI device.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
mdi_phci_get_path_count(dev_info_t *pdip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
	int		count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
	ph = i_devi_get_phci(pdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
	if (ph != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
		count = ph->ph_path_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	return (count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
 * i_mdi_phci_lock():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
 *		Lock a pHCI device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
 *		None
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
 * Note:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
 *		The default locking order is:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
 *		_NOTE(LOCK_ORDER(mdi_phci::ph_mutex mdi_pathinfo::pi_mutex))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
 *		But there are number of situations where locks need to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
 *		grabbed in reverse order.  This routine implements try and lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
 *		mechanism depending on the requested parameter option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
i_mdi_phci_lock(mdi_phci_t *ph, mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
		/* Reverse locking is requested. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
		while (MDI_PHCI_TRYLOCK(ph) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
			 * tryenter failed. Try to grab again
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
			 * after a small delay
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
			MDI_PI_HOLD(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
			delay(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
			MDI_PI_RELE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
		MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
 * i_mdi_phci_get_client_lock():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
 *		Lock a pHCI device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
 *		None
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
 * Note:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
 *		The default locking order is:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
 *		_NOTE(LOCK_ORDER(mdi_phci::ph_mutex mdi_client::ct_mutex))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
 *		But there are number of situations where locks need to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
 *		grabbed in reverse order.  This routine implements try and lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
 *		mechanism depending on the requested parameter option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
i_mdi_phci_get_client_lock(mdi_phci_t *ph, mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
	if (ct) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		/* Reverse locking is requested. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
		while (MDI_PHCI_TRYLOCK(ph) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
			 * tryenter failed. Try to grab again
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
			 * after a small delay
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
			delay(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
			MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
		MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
 * i_mdi_phci_unlock():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
 *		Unlock the pHCI component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
i_mdi_phci_unlock(mdi_phci_t *ph)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
	MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
 * i_mdi_devinfo_create():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
 *		create client device's devinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
 *		dev_info
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
 *		NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
 * Notes:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
static dev_info_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
i_mdi_devinfo_create(mdi_vhci_t *vh, char *name, char *guid,
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   852
	char **compatible, int ncompatible)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	dev_info_t *cdip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	ASSERT(MUTEX_HELD(&mdi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	/* Verify for duplicate entry */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	cdip = i_mdi_devinfo_find(vh, name, guid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	ASSERT(cdip == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	if (cdip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
		cmn_err(CE_WARN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
		    "i_mdi_devinfo_create: client dip %p already exists",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
			(void *)cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
   867
	ndi_devi_alloc_sleep(vh->vh_dip, name, DEVI_SID_NODEID, &cdip);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
	if (cdip == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
		goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
	 * Create component type and Global unique identifier
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
	 * properties
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
	if (ndi_prop_update_string(DDI_DEV_T_NONE, cdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
	    MDI_CLIENT_GUID_PROP, guid) != DDI_PROP_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
		goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	/* Decorate the node with compatible property */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
	if (compatible &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
	    (ndi_prop_update_string_array(DDI_DEV_T_NONE, cdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
	    "compatible", compatible, ncompatible) != DDI_PROP_SUCCESS)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
		goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
	return (cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
fail:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
	if (cdip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
		(void) ndi_prop_remove_all(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
		(void) ndi_devi_free(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
 * i_mdi_devinfo_find():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
 *		Find a matching devinfo node for given client node name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
 *		and its guid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
 *		Handle to a dev_info node or NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
static dev_info_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
i_mdi_devinfo_find(mdi_vhci_t *vh, caddr_t name, char *guid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
	char			*data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
	dev_info_t 		*cdip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
	dev_info_t 		*ndip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
	int			circular;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
	ndi_devi_enter(vh->vh_dip, &circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
	ndip = (dev_info_t *)DEVI(vh->vh_dip)->devi_child;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
	while ((cdip = ndip) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
		ndip = (dev_info_t *)DEVI(cdip)->devi_sibling;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
		if (strcmp(DEVI(cdip)->devi_node_name, name)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, cdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
		    DDI_PROP_DONTPASS, MDI_CLIENT_GUID_PROP,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
		    &data) != DDI_PROP_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
		if (strcmp(data, guid) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
			ddi_prop_free(data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
		ddi_prop_free(data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
	ndi_devi_exit(vh->vh_dip, circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
	return (cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
 * i_mdi_devinfo_remove():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
 *		Remove a client device node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
i_mdi_devinfo_remove(dev_info_t *vdip, dev_info_t *cdip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
	int	rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
	if (i_mdi_is_child_present(vdip, cdip) == MDI_SUCCESS ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
	    (flags & MDI_CLIENT_FLAGS_DEV_NOT_SUPPORTED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
		rv = ndi_devi_offline(cdip, NDI_DEVI_REMOVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
		if (rv != NDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
			MDI_DEBUG(1, (CE_NOTE, NULL, "!i_mdi_devinfo_remove:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
			    " failed. cdip = %p\n", cdip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
		 * Convert to MDI error code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
		switch (rv) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
		case NDI_SUCCESS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
			rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
		case NDI_BUSY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
			rv = MDI_BUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
			rv = MDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
 * i_devi_get_client()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
 *		Utility function to get mpxio component extensions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
static mdi_client_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
i_devi_get_client(dev_info_t *cdip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
	mdi_client_t	*ct = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
	if (MDI_CLIENT(cdip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
		ct = (mdi_client_t *)DEVI(cdip)->devi_mdi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
	return (ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
 * i_mdi_is_child_present():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
 *		Search for the presence of client device dev_info node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
i_mdi_is_child_present(dev_info_t *vdip, dev_info_t *cdip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
	int		rv = MDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
	struct dev_info	*dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
	int		circular;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	ndi_devi_enter(vdip, &circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
	dip = DEVI(vdip)->devi_child;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
	while (dip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
		if (dip == DEVI(cdip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
			rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
		dip = dip->devi_sibling;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
	ndi_devi_exit(vdip, circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
 * i_mdi_client_lock():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
 *		Grab client component lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
 *		None
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
 * Note:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
 *		The default locking order is:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
 *		_NOTE(LOCK_ORDER(mdi_client::ct_mutex mdi_pathinfo::pi_mutex))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
 *		But there are number of situations where locks need to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
 *		grabbed in reverse order.  This routine implements try and lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
 *		mechanism depending on the requested parameter option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
i_mdi_client_lock(mdi_client_t *ct, mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
		 * Reverse locking is requested.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
		while (MDI_CLIENT_TRYLOCK(ct) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
			 * tryenter failed. Try to grab again
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
			 * after a small delay
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
			MDI_PI_HOLD(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
			delay(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
			MDI_PI_RELE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
		MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
 * i_mdi_client_unlock():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
 *		Unlock a client component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
i_mdi_client_unlock(mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
 * i_mdi_client_alloc():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
 * 		Allocate and initialize a client structure.  Caller should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
 *		hold the global mdi_mutex.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
 *		Handle to a client component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
static mdi_client_t *
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  1068
i_mdi_client_alloc(mdi_vhci_t *vh, char *name, char *lguid)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
	ASSERT(MUTEX_HELD(&mdi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
	 * Allocate and initialize a component structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
	 */
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  1077
	ct = kmem_zalloc(sizeof (*ct), KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
	mutex_init(&ct->ct_mutex, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
	ct->ct_hnext = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
	ct->ct_hprev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
	ct->ct_dip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
	ct->ct_vhci = vh;
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  1083
	ct->ct_drvname = kmem_alloc(strlen(name) + 1, KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
	(void) strcpy(ct->ct_drvname, name);
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  1085
	ct->ct_guid = kmem_alloc(strlen(lguid) + 1, KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
	(void) strcpy(ct->ct_guid, lguid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
	ct->ct_cprivate = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
	ct->ct_vprivate = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
	ct->ct_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
	ct->ct_state = MDI_CLIENT_STATE_FAILED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
	MDI_CLIENT_SET_OFFLINE(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
	MDI_CLIENT_SET_DETACH(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
	MDI_CLIENT_SET_POWER_UP(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
	ct->ct_failover_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
	ct->ct_failover_status = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
	cv_init(&ct->ct_failover_cv, NULL, CV_DRIVER, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
	ct->ct_unstable = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
	cv_init(&ct->ct_unstable_cv, NULL, CV_DRIVER, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
	cv_init(&ct->ct_powerchange_cv, NULL, CV_DRIVER, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
	ct->ct_lb = vh->vh_lb;
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  1101
	ct->ct_lb_args =  kmem_zalloc(sizeof (client_lb_args_t), KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
	ct->ct_lb_args->region_size = LOAD_BALANCE_DEFAULT_REGION_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
	ct->ct_path_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
	ct->ct_path_head = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
	ct->ct_path_tail = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
	ct->ct_path_last = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
	 * Add this client component to our client hash queue
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
	i_mdi_client_enlist_table(vh, ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
	return (ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
 * i_mdi_client_enlist_table():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
 *		Attach the client device to the client hash table. Caller
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
 *		should hold the mdi_mutex
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
i_mdi_client_enlist_table(mdi_vhci_t *vh, mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
	int 			index;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
	struct client_hash	*head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
	ASSERT(MUTEX_HELD(&mdi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
	index = i_mdi_get_hash_key(ct->ct_guid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
	head = &vh->vh_client_table[index];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
	ct->ct_hnext = (mdi_client_t *)head->ct_hash_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
	head->ct_hash_head = ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
	head->ct_hash_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
	vh->vh_client_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
 * i_mdi_client_delist_table():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
 *		Attach the client device to the client hash table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
 *		Caller should hold the mdi_mutex
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
i_mdi_client_delist_table(mdi_vhci_t *vh, mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
	int			index;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	char			*guid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
	struct client_hash 	*head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	mdi_client_t		*next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
	mdi_client_t		*last;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
	ASSERT(MUTEX_HELD(&mdi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
	guid = ct->ct_guid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
	index = i_mdi_get_hash_key(guid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
	head = &vh->vh_client_table[index];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
	last = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
	next = (mdi_client_t *)head->ct_hash_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
	while (next != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
		if (next == ct) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
		last = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
		next = next->ct_hnext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
	if (next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
		head->ct_hash_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
		if (last == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
			head->ct_hash_head = ct->ct_hnext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
			last->ct_hnext = ct->ct_hnext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
		ct->ct_hnext = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
		vh->vh_client_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
 * i_mdi_client_free():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
 *		Free a client component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
i_mdi_client_free(mdi_vhci_t *vh, mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
	int		rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
	int		flags = ct->ct_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
	dev_info_t	*cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
	dev_info_t	*vdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
	ASSERT(MUTEX_HELD(&mdi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
	vdip = vh->vh_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
	cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
	(void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, MDI_CLIENT_GUID_PROP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
	DEVI(cdip)->devi_mdi_component &= ~MDI_COMPONENT_CLIENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
	DEVI(cdip)->devi_mdi_client = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
	 * Clear out back ref. to dev_info_t node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
	ct->ct_dip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
	 * Remove this client from our hash queue
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
	i_mdi_client_delist_table(vh, ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
	 * Uninitialize and free the component
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
	kmem_free(ct->ct_drvname, strlen(ct->ct_drvname) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
	kmem_free(ct->ct_guid, strlen(ct->ct_guid) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
	kmem_free(ct->ct_lb_args, sizeof (client_lb_args_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
	cv_destroy(&ct->ct_failover_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
	cv_destroy(&ct->ct_unstable_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
	cv_destroy(&ct->ct_powerchange_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
	mutex_destroy(&ct->ct_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
	kmem_free(ct, sizeof (*ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
	if (cdip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
		mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
		(void) i_mdi_devinfo_remove(vdip, cdip, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
		mutex_enter(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
 * i_mdi_client_find():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
 * 		Find the client structure corresponding to a given guid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
 *		Caller should hold the mdi_mutex
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
static mdi_client_t *
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  1235
i_mdi_client_find(mdi_vhci_t *vh, char *cname, char *guid)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
	int			index;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
	struct client_hash	*head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
	mdi_client_t		*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
	ASSERT(MUTEX_HELD(&mdi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
	index = i_mdi_get_hash_key(guid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
	head = &vh->vh_client_table[index];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
	ct = head->ct_hash_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
	while (ct != NULL) {
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  1247
		if (strcmp(ct->ct_guid, guid) == 0 &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  1248
		    (cname == NULL || strcmp(ct->ct_drvname, cname) == 0)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
		ct = ct->ct_hnext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
	return (ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
 * i_mdi_client_update_state():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
 *		Compute and update client device state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
 * Notes:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
 *		A client device can be in any of three possible states:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
 *		MDI_CLIENT_STATE_OPTIMAL - Client in optimal state with more
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
 *		one online/standby paths. Can tolerate failures.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
 *		MDI_CLIENT_STATE_DEGRADED - Client device in degraded state with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
 *		no alternate paths available as standby. A failure on the online
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
 *		would result in loss of access to device data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
 *		MDI_CLIENT_STATE_FAILED - Client device in failed state with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
 *		no paths available to access the device.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
i_mdi_client_update_state(mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
	int state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
	ASSERT(MUTEX_HELD(&ct->ct_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
	state = i_mdi_client_compute_state(ct, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
	MDI_CLIENT_SET_STATE(ct, state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
 * i_mdi_client_compute_state():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
 *		Compute client device state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
 *		mdi_phci_t *	Pointer to pHCI structure which should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
 *				while computing the new value.  Used by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
 *				i_mdi_phci_offline() to find the new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
 *				client state after DR of a pHCI.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
i_mdi_client_compute_state(mdi_client_t *ct, mdi_phci_t *ph)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
	int		state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
	int		online_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
	int		standby_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
	mdi_pathinfo_t	*pip, *next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
	ASSERT(MUTEX_HELD(&ct->ct_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
	pip = ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
	while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
		next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
		if (MDI_PI(pip)->pi_phci == ph) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
		if ((MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_MASK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
				== MDI_PATHINFO_STATE_ONLINE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
			online_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
		else if ((MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_MASK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
				== MDI_PATHINFO_STATE_STANDBY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
			standby_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
		pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
	if (online_count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
		if (standby_count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
			state = MDI_CLIENT_STATE_FAILED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
			MDI_DEBUG(2, (CE_NOTE, NULL, "!client state: failed"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
			    " ct = %p\n", ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
		} else if (standby_count == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
			state = MDI_CLIENT_STATE_DEGRADED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
			state = MDI_CLIENT_STATE_OPTIMAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
	} else if (online_count == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
		if (standby_count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
			state = MDI_CLIENT_STATE_DEGRADED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
			state = MDI_CLIENT_STATE_OPTIMAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
		state = MDI_CLIENT_STATE_OPTIMAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
	return (state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
 * i_mdi_client2devinfo():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
 *		Utility function
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
dev_info_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
i_mdi_client2devinfo(mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
	return (ct->ct_dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
 * mdi_client_path2_devinfo():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
 * 		Given the parent devinfo and child devfs pathname, search for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
 *		a valid devfs node handle.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
dev_info_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
mdi_client_path2devinfo(dev_info_t *vdip, char *pathname)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
	dev_info_t 	*cdip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
	dev_info_t 	*ndip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
	char		*temp_pathname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
	int		circular;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
	 * Allocate temp buffer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
	temp_pathname = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
	 * Lock parent against changes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
	ndi_devi_enter(vdip, &circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
	ndip = (dev_info_t *)DEVI(vdip)->devi_child;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
	while ((cdip = ndip) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
		ndip = (dev_info_t *)DEVI(cdip)->devi_sibling;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
		*temp_pathname = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
		(void) ddi_pathname(cdip, temp_pathname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
		if (strcmp(temp_pathname, pathname) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
	 * Release devinfo lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
	ndi_devi_exit(vdip, circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
	 * Free the temp buffer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
	kmem_free(temp_pathname, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
	return (cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
 * mdi_client_get_path_count():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
 * 		Utility function to get number of path information nodes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
 *		associated with a given client device.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
mdi_client_get_path_count(dev_info_t *cdip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
	int		count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
	ct = i_devi_get_client(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
	if (ct != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
		count = ct->ct_path_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
	return (count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
 * i_mdi_get_hash_key():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
 * 		Create a hash using strings as keys
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
i_mdi_get_hash_key(char *str)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
	uint32_t	g, hash = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
	char		*p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
	for (p = str; *p != '\0'; p++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
		g = *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
		hash += g;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
	return (hash % (CLIENT_HASH_TABLE_SIZE - 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
 * mdi_get_lb_policy():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
 * 		Get current load balancing policy for a given client device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
client_lb_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
mdi_get_lb_policy(dev_info_t *cdip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
	client_lb_t	lb = LOAD_BALANCE_NONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
	ct = i_devi_get_client(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
	if (ct != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
		lb = ct->ct_lb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
	return (lb);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
 * mdi_set_lb_region_size():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
 * 		Set current region size for the load-balance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
mdi_set_lb_region_size(dev_info_t *cdip, int region_size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
	int		rv = MDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
	ct = i_devi_get_client(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
	if (ct != NULL && ct->ct_lb_args != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
		ct->ct_lb_args->region_size = region_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
		rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
 * mdi_Set_lb_policy():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
 * 		Set current load balancing policy for a given client device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
mdi_set_lb_policy(dev_info_t *cdip, client_lb_t lb)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
	int		rv = MDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
	ct = i_devi_get_client(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
	if (ct != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
		ct->ct_lb = lb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
		rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
 * mdi_failover():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
 *		failover function called by the vHCI drivers to initiate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
 *		a failover operation.  This is typically due to non-availability
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
 *		of online paths to route I/O requests.  Failover can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
 *		triggered through user application also.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
 *		The vHCI driver calls mdi_failover() to initiate a failover
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
 *		operation. mdi_failover() calls back into the vHCI driver's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
 *		vo_failover() entry point to perform the actual failover
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
 *		operation.  The reason for requiring the vHCI driver to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
 *		initiate failover by calling mdi_failover(), instead of directly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
 *		executing vo_failover() itself, is to ensure that the mdi
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
 *		framework can keep track of the client state properly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
 *		Additionally, mdi_failover() provides as a convenience the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
 *		option of performing the failover operation synchronously or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
 *		asynchronously
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
 *		Upon successful completion of the failover operation, the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
 *		paths that were previously ONLINE will be in the STANDBY state,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
 *		and the newly activated paths will be in the ONLINE state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
 *		The flags modifier determines whether the activation is done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
 *		synchronously: MDI_FAILOVER_SYNC
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
 *		MDI_BUSY
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
mdi_failover(dev_info_t *vdip, dev_info_t *cdip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
	int			rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
	mdi_client_t		*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
	ct = i_devi_get_client(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
	ASSERT(ct != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
	if (ct == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
		/* cdip is not a valid client device. Nothing more to do. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
	if (MDI_CLIENT_IS_PATH_FREE_IN_PROGRESS(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
		/* A path to the client is being freed */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
		return (MDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
	if (MDI_CLIENT_IS_FAILED(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
		 * Client is in failed state. Nothing more to do.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
	if (MDI_CLIENT_IS_FAILOVER_IN_PROGRESS(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
		 * Failover is already in progress; return BUSY
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
		return (MDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
	 * Make sure that mdi_pathinfo node state changes are processed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
	 * We do not allow failovers to progress while client path state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
	 * changes are in progress
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
	if (ct->ct_unstable) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
		if (flags == MDI_FAILOVER_ASYNC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
			return (MDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
			while (ct->ct_unstable)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
				cv_wait(&ct->ct_unstable_cv, &ct->ct_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
	 * Client device is in stable state. Before proceeding, perform sanity
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
	 * checks again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
	if ((MDI_CLIENT_IS_DETACHED(ct)) || (MDI_CLIENT_IS_FAILED(ct)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
	    (i_ddi_node_state(ct->ct_dip) < DS_READY)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
		 * Client is in failed state. Nothing more to do.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
	 * Set the client state as failover in progress.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
	MDI_CLIENT_SET_FAILOVER_IN_PROGRESS(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
	ct->ct_failover_flags = flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
	if (flags == MDI_FAILOVER_ASYNC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
		 * Submit the initiate failover request via CPR safe
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
		 * taskq threads.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
		(void) taskq_dispatch(mdi_taskq, (task_func_t *)i_mdi_failover,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
		    ct, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
		return (MDI_ACCEPT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
		 * Synchronous failover mode.  Typically invoked from the user
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
		 * land.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
		rv = i_mdi_failover(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
 * i_mdi_failover():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
 *		internal failover function. Invokes vHCI drivers failover
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
 *		callback function and process the failover status
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
 *		None
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
 * Note: A client device in failover state can not be detached or freed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
i_mdi_failover(void *arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
	int		rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
	mdi_client_t	*ct = (mdi_client_t *)arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
	mdi_vhci_t	*vh = ct->ct_vhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
	ASSERT(!MUTEX_HELD(&ct->ct_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
	if (vh->vh_ops->vo_failover != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
		 * Call vHCI drivers callback routine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
		rv = (*vh->vh_ops->vo_failover)(vh->vh_dip, ct->ct_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
		    ct->ct_failover_flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
	MDI_CLIENT_CLEAR_FAILOVER_IN_PROGRESS(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
	 * Save the failover return status
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
	ct->ct_failover_status = rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
	 * As a result of failover, client status would have been changed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
	 * Update the client state and wake up anyone waiting on this client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
	 * device.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
	i_mdi_client_update_state(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
	cv_broadcast(&ct->ct_failover_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
 * Load balancing is logical block.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
 * IOs within the range described by region_size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
 * would go on the same path. This would improve the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
 * performance by cache-hit on some of the RAID devices.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
 * Search only for online paths(At some point we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
 * may want to balance across target ports).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
 * If no paths are found then default to round-robin.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
i_mdi_lba_lb(mdi_client_t *ct, mdi_pathinfo_t **ret_pip, struct buf *bp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
	int		path_index = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
	int		online_path_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
	int		online_nonpref_path_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
	int 		region_size = ct->ct_lb_args->region_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
	mdi_pathinfo_t	*pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
	mdi_pathinfo_t	*next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
	int		preferred, path_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
	pip = ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
	while (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
		if (MDI_PI(pip)->pi_state ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
		    MDI_PATHINFO_STATE_ONLINE && MDI_PI(pip)->pi_preferred) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
			online_path_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
		} else if (MDI_PI(pip)->pi_state ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
		    MDI_PATHINFO_STATE_ONLINE && !MDI_PI(pip)->pi_preferred) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
			online_nonpref_path_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
		next = (mdi_pathinfo_t *)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
		    MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
		pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
	/* if found any online/preferred then use this type */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
	if (online_path_count > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
		path_cnt = online_path_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
		preferred = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
	} else if (online_nonpref_path_count > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
		path_cnt = online_nonpref_path_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
		preferred = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
		path_cnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
	if (path_cnt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
		path_index = (bp->b_blkno >> region_size) % path_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
		pip = ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
		while (pip && path_index != -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
			if (path_index == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
			    (MDI_PI(pip)->pi_state ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
			    MDI_PATHINFO_STATE_ONLINE) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
				MDI_PI(pip)->pi_preferred == preferred) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
				MDI_PI_HOLD(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
				MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
				*ret_pip = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
				return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
			path_index --;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
			next = (mdi_pathinfo_t *)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
			    MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
		if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
			MDI_DEBUG(4, (CE_NOTE, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
			    "!lba %p, no pip !!\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
				bp->b_blkno));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
			MDI_DEBUG(4, (CE_NOTE, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
			    "!lba %p, no pip for path_index, "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
			    "pip %p\n", pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1726
	return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1727
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
 * mdi_select_path():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
 *		select a path to access a client device.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
 *		mdi_select_path() function is called by the vHCI drivers to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
 *		select a path to route the I/O request to.  The caller passes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
 *		the block I/O data transfer structure ("buf") as one of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
 *		parameters.  The mpxio framework uses the buf structure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
 *		contents to maintain per path statistics (total I/O size /
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
 *		count pending).  If more than one online paths are available to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
 *		select, the framework automatically selects a suitable path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
 *		for routing I/O request. If a failover operation is active for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
 *		this client device the call shall be failed with MDI_BUSY error
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
 *		code.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
 *		By default this function returns a suitable path in online
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
 *		state based on the current load balancing policy.  Currently
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
 *		we support LOAD_BALANCE_NONE (Previously selected online path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
 *		will continue to be used till the path is usable) and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
 *		LOAD_BALANCE_RR (Online paths will be selected in a round
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
 *		robin fashion), LOAD_BALANCE_LB(Online paths will be selected
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
 *		based on the logical block).  The load balancing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
 *		through vHCI drivers configuration file (driver.conf).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
 *		vHCI drivers may override this default behavior by specifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
 *		appropriate flags.  If start_pip is specified (non NULL) is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
 *		used as start point to walk and find the next appropriate path.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
 *		The following values are currently defined:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
 *		MDI_SELECT_ONLINE_PATH (to select an ONLINE path) and/or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
 *		MDI_SELECT_STANDBY_PATH (to select an STANDBY path).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
 *		The non-standard behavior is used by the scsi_vhci driver,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
 *		whenever it has to use a STANDBY/FAULTED path.  Eg. during
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
 *		attach of client devices (to avoid an unnecessary failover
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
 *		when the STANDBY path comes up first), during failover
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
 *		(to activate a STANDBY path as ONLINE).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
 *		The selected path in returned in a held state (ref_cnt).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
 *		Caller should release the hold by calling mdi_rele_path().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
 *		MDI_SUCCESS	- Completed successfully
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
 *		MDI_BUSY 	- Client device is busy failing over
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
 *		MDI_NOPATH	- Client device is online, but no valid path are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
 *				  available to access this client device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
 *		MDI_FAILURE	- Invalid client device or state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
 *		MDI_DEVI_ONLINING
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
 *				- Client device (struct dev_info state) is in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
 *				  onlining state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
mdi_select_path(dev_info_t *cdip, struct buf *bp, int flags,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
    mdi_pathinfo_t *start_pip, mdi_pathinfo_t **ret_pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
	mdi_pathinfo_t	*pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
	mdi_pathinfo_t	*next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
	mdi_pathinfo_t	*head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
	mdi_pathinfo_t	*start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
	client_lb_t	lbp;	/* load balancing policy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
	int		sb = 1;	/* standard behavior */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
	int		preferred = 1;	/* preferred path */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
	int		cond, cont = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
	int		retry = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
	if (flags != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
		 * disable default behavior
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
		sb = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
	*ret_pip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
	ct = i_devi_get_client(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
	if (ct == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
		/* mdi extensions are NULL, Nothing more to do */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
	if (sb) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
		if (MDI_CLIENT_IS_FAILED(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
			 * Client is not ready to accept any I/O requests.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
			 * Fail this request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
			MDI_DEBUG(2, (CE_NOTE, cdip, "!mdi_select_path: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
			    "client state offline ct = %p\n", ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
			return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
		if (MDI_CLIENT_IS_FAILOVER_IN_PROGRESS(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
			 * Check for Failover is in progress. If so tell the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
			 * caller that this device is busy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
			MDI_DEBUG(2, (CE_NOTE, cdip, "!mdi_select_path: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
			    "client failover in progress ct = %p\n", ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
			return (MDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
		 * Check to see whether the client device is attached.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
		 * If not so, let the vHCI driver manually select a path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
		 * (standby) and let the probe/attach process to continue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
		if ((MDI_CLIENT_IS_DETACHED(ct)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
		    i_ddi_node_state(cdip) < DS_READY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
			MDI_DEBUG(4, (CE_NOTE, cdip, "!Devi is onlining\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
			return (MDI_DEVI_ONLINING);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
	 * Cache in the client list head.  If head of the list is NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
	 * return MDI_NOPATH
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
	head = ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
	if (head == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
		return (MDI_NOPATH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
	 * for non default behavior, bypass current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
	 * load balancing policy and always use LOAD_BALANCE_RR
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
	 * except that the start point will be adjusted based
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
	 * on the provided start_pip
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
	lbp = sb ? ct->ct_lb : LOAD_BALANCE_RR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
	switch (lbp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
	case LOAD_BALANCE_NONE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
		 * Load balancing is None  or Alternate path mode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
		 * Start looking for a online mdi_pathinfo node starting from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
		 * last known selected path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
		preferred = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
		pip = (mdi_pathinfo_t *)ct->ct_path_last;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
		if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
			pip = head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
		start = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1881
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
			 * No need to explicitly check if the path is disabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
			 * Since we are checking for state == ONLINE and the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
			 * same veriable is used for DISABLE/ENABLE information.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
			if (MDI_PI(pip)->pi_state  ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
				MDI_PATHINFO_STATE_ONLINE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
				preferred == MDI_PI(pip)->pi_preferred) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1889
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
				 * Return the path in hold state. Caller should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
				 * release the lock by calling mdi_rele_path()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
				MDI_PI_HOLD(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
				MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
				ct->ct_path_last = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
				*ret_pip = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
				MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
				return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
			 * Path is busy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
			if (MDI_PI_IS_DRV_DISABLE_TRANSIENT(pip) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
			    MDI_PI_IS_TRANSIENT(pip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
				retry = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
			 * Keep looking for a next available online path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1910
			next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
			if (next == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
				next = head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1914
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
			if (start == pip && preferred) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
				preferred = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
			} else if (start == pip && !preferred) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
				cont = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
		} while (cont);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
	case LOAD_BALANCE_LBA:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
		 * Make sure we are looking
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
		 * for an online path. Otherwise, if it is for a STANDBY
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
		 * path request, it will go through and fetch an ONLINE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
		 * path which is not desirable.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
		if ((ct->ct_lb_args != NULL) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
			    (ct->ct_lb_args->region_size) && bp &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
				(sb || (flags == MDI_SELECT_ONLINE_PATH))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
			if (i_mdi_lba_lb(ct, ret_pip, bp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
				    == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
				MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
				return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
		/*  FALLTHROUGH */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
	case LOAD_BALANCE_RR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
		 * Load balancing is Round Robin. Start looking for a online
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
		 * mdi_pathinfo node starting from last known selected path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
		 * as the start point.  If override flags are specified,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
		 * process accordingly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
		 * If the search is already in effect(start_pip not null),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
		 * then lets just use the same path preference to continue the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
		 * traversal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
		if (start_pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
			preferred = MDI_PI(start_pip)->pi_preferred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
			preferred = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
		start = sb ? (mdi_pathinfo_t *)ct->ct_path_last : start_pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
		if (start == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
			pip = head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
			pip = (mdi_pathinfo_t *)MDI_PI(start)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
			if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
				if (!sb) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
					if (preferred == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
						/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
						 * Looks like we have completed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
						 * the traversal as preferred
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
						 * value is 0. Time to bail out.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
						 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
						*ret_pip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
						MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
						return (MDI_NOPATH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
					} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
						/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
						 * Looks like we reached the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
						 * end of the list. Lets enable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
						 * traversal of non preferred
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
						 * paths.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
						 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
						preferred = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
				pip = head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
		start = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
			if (sb) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
				cond = ((MDI_PI(pip)->pi_state ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
				    MDI_PATHINFO_STATE_ONLINE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
					MDI_PI(pip)->pi_preferred ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
						preferred) ? 1 : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
				if (flags == MDI_SELECT_ONLINE_PATH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
					cond = ((MDI_PI(pip)->pi_state ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
					    MDI_PATHINFO_STATE_ONLINE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
						MDI_PI(pip)->pi_preferred ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
						preferred) ? 1 : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
				} else if (flags == MDI_SELECT_STANDBY_PATH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
					cond = ((MDI_PI(pip)->pi_state ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
					    MDI_PATHINFO_STATE_STANDBY &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
						MDI_PI(pip)->pi_preferred ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
						preferred) ? 1 : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
				} else if (flags == (MDI_SELECT_ONLINE_PATH |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
				    MDI_SELECT_STANDBY_PATH)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
					cond = (((MDI_PI(pip)->pi_state ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
					    MDI_PATHINFO_STATE_ONLINE ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
					    (MDI_PI(pip)->pi_state ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
					    MDI_PATHINFO_STATE_STANDBY)) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
						MDI_PI(pip)->pi_preferred ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
						preferred) ? 1 : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
					cond = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
			 * No need to explicitly check if the path is disabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
			 * Since we are checking for state == ONLINE and the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
			 * same veriable is used for DISABLE/ENABLE information.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
			if (cond) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
				 * Return the path in hold state. Caller should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
				 * release the lock by calling mdi_rele_path()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
				MDI_PI_HOLD(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
				MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
				if (sb)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
					ct->ct_path_last = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
				*ret_pip = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
				MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
				return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
			 * Path is busy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
			if (MDI_PI_IS_DRV_DISABLE_TRANSIENT(pip) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
			    MDI_PI_IS_TRANSIENT(pip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
				retry = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
			 * Keep looking for a next available online path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
do_again:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
			next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
			if (next == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
				if (!sb) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
					if (preferred == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
						/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
						 * Looks like we reached the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
						 * end of the list. Lets enable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
						 * traversal of non preferred
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
						 * paths.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
						 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
						preferred = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
						next = head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
					} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
						/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
						 * We have done both the passes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
						 * Preferred as well as for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
						 * Non-preferred. Bail out now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
						 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
						cont = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
					 * Standard behavior case.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
					next = head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
			if (cont == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
			if (!sb) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2081
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
				 * We need to handle the selection of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
				 * non-preferred path in the following
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
				 * case:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
				 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
				 * +------+   +------+   +------+   +-----+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
				 * | A : 1| - | B : 1| - | C : 0| - |NULL |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
				 * +------+   +------+   +------+   +-----+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
				 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
				 * If we start the search with B, we need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
				 * skip beyond B to pick C which is non -
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
				 * preferred in the second pass. The following
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
				 * test, if true, will allow us to skip over
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
				 * the 'start'(B in the example) to select
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
				 * other non preferred elements.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
				if ((start_pip != NULL) && (start_pip == pip) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
				    (MDI_PI(start_pip)->pi_preferred
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
				    != preferred)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
					 * try again after going past the start
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
					 * pip
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
					MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
					goto do_again;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
				 * Standard behavior case
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
				if (start == pip && preferred) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
					/* look for nonpreferred paths */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
					preferred = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
				} else if (start == pip && !preferred) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
					 * Exit condition
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
					cont = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
		} while (cont);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
	if (retry == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
		return (MDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
		return (MDI_NOPATH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
 * For a client, return the next available path to any phci
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
 * Note:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
 *		Caller should hold the branch's devinfo node to get a consistent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
 *		snap shot of the mdi_pathinfo nodes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
 *		Please note that even the list is stable the mdi_pathinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
 *		node state and properties are volatile.  The caller should lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
 *		and unlock the nodes by calling mdi_pi_lock() and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
 *		mdi_pi_unlock() functions to get a stable properties.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
 *		If there is a need to use the nodes beyond the hold of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
 *		devinfo node period (For ex. I/O), then mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
 *		need to be held against unexpected removal by calling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
 *		mdi_hold_path() and should be released by calling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
 *		mdi_rele_path() on completion.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
mdi_pathinfo_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
mdi_get_next_phci_path(dev_info_t *ct_dip, mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
	mdi_client_t *ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
	if (!MDI_CLIENT(ct_dip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
	 * Walk through client link
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
	ct = (mdi_client_t *)DEVI(ct_dip)->devi_mdi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
	ASSERT(ct != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
	if (pip == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
		return ((mdi_pathinfo_t *)ct->ct_path_head);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
	return ((mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
 * For a phci, return the next available path to any client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
 * Note: ditto mdi_get_next_phci_path()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
mdi_pathinfo_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
mdi_get_next_client_path(dev_info_t *ph_dip, mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
	mdi_phci_t *ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
	if (!MDI_PHCI(ph_dip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
	 * Walk through pHCI link
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
	ph = (mdi_phci_t *)DEVI(ph_dip)->devi_mdi_xhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
	ASSERT(ph != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
	if (pip == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
		return ((mdi_pathinfo_t *)ph->ph_path_head);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
	return ((mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
 * mdi_get_nextpath():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
 *		mdi_pathinfo node walker function.  Get the next node from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
 *		client or pHCI device list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
 * XXX This is wrapper function for compatibility purposes only.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
 *	It doesn't work under Multi-level MPxIO, where a dip
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
 *	is both client and phci (which link should next_path follow?).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
 *	Once Leadville is modified to call mdi_get_next_phci/client_path,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
 *	this interface should be removed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
mdi_get_next_path(dev_info_t *dip, mdi_pathinfo_t *pip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
    mdi_pathinfo_t **ret_pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
	if (MDI_CLIENT(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
		*ret_pip = mdi_get_next_phci_path(dip, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
	} else if (MDI_PHCI(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
		*ret_pip = mdi_get_next_client_path(dip, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
		*ret_pip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
 * mdi_hold_path():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
 *		Hold the mdi_pathinfo node against unwanted unexpected free.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
 *		None
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
mdi_hold_path(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
		MDI_PI_HOLD(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
 * mdi_rele_path():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
 *		Release the mdi_pathinfo node which was selected
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
 *		through mdi_select_path() mechanism or manually held by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
 *		calling mdi_hold_path().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
 *		None
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
mdi_rele_path(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
		MDI_PI_RELE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
		if (MDI_PI(pip)->pi_ref_cnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
			cv_broadcast(&MDI_PI(pip)->pi_ref_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
 * mdi_pi_lock():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
 * 		Lock the mdi_pathinfo node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
 * Note:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
 *		The caller should release the lock by calling mdi_pi_unlock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
mdi_pi_lock(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
	ASSERT(pip != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
 * mdi_pi_unlock():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
 * 		Unlock the mdi_pathinfo node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
 * Note:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
 *		The mdi_pathinfo node should have been locked with mdi_pi_lock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
mdi_pi_unlock(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
	ASSERT(pip != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
 * mdi_pi_find():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
 *		Search the list of mdi_pathinfo nodes attached to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
 *		pHCI/Client device node whose path address matches "paddr".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
 *		Returns a pointer to the mdi_pathinfo node if a matching node is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
 *		found.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
 *		mdi_pathinfo node handle
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
 *		NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
 * Notes:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
 *		Caller need not hold any locks to call this function.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
mdi_pathinfo_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
mdi_pi_find(dev_info_t *pdip, char *caddr, char *paddr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
	mdi_phci_t		*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
	mdi_vhci_t		*vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
	mdi_client_t		*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
	mdi_pathinfo_t		*pip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
	if ((pdip == NULL) || (paddr == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
	ph = i_devi_get_phci(pdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
		 * Invalid pHCI device, Nothing more to do.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
		MDI_DEBUG(2, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
		    "!mdi_pi_find: invalid phci"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
	vh = ph->ph_vhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
	if (vh == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
		 * Invalid vHCI device, Nothing more to do.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
		MDI_DEBUG(2, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
		    "!mdi_pi_find: invalid phci"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
	 * Look for client device identified by caddr (guid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
	if (caddr == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
		 * Find a mdi_pathinfo node under pHCI list for a matching
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
		 * unit address.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
		mutex_enter(&ph->ph_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
		pip = (mdi_pathinfo_t *)ph->ph_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
		while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
			if (strcmp(MDI_PI(pip)->pi_addr, paddr) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
			pip = (mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
		mutex_exit(&ph->ph_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
		return (pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
	/*
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2355
	 * XXX - Is the rest of the code in this function really necessary?
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2356
	 * The consumers of mdi_pi_find() can search for the desired pathinfo
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2357
	 * node by calling mdi_pi_find(pdip, NULL, paddr). Irrespective of
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2358
	 * whether the search is based on the pathinfo nodes attached to
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2359
	 * the pHCI or the client node, the result will be the same.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2360
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2361
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2362
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
	 * Find the client device corresponding to 'caddr'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
	mutex_enter(&mdi_mutex);
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2366
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2367
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2368
	 * XXX - Passing NULL to the following function works as long as the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2369
	 * the client addresses (caddr) are unique per vhci basis.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2370
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2371
	ct = i_mdi_client_find(vh, NULL, caddr);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
	if (ct == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
		 * Client not found, Obviously mdi_pathinfo node has not been
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
		 * created yet.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
		mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
		return (pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
	 * Hold the client lock and look for a mdi_pathinfo node with matching
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
	 * pHCI and paddr
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
	 * Release the global mutex as it is no more needed. Note: We always
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
	 * respect the locking order while acquiring.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
	mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
	pip = (mdi_pathinfo_t *)ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
	while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
		 * Compare the unit address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
		if ((MDI_PI(pip)->pi_phci == ph) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
		    strcmp(MDI_PI(pip)->pi_addr, paddr) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
		pip = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
	return (pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
 * mdi_pi_alloc():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
 *		Allocate and initialize a new instance of a mdi_pathinfo node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
 *		The mdi_pathinfo node returned by this function identifies a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
 *		unique device path is capable of having properties attached
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
 *		and passed to mdi_pi_online() to fully attach and online the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
 *		path and client device node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
 *		The mdi_pathinfo node returned by this function must be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
 *		destroyed using mdi_pi_free() if the path is no longer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
 *		operational or if the caller fails to attach a client device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
 *		node when calling mdi_pi_online(). The framework will not free
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
 *		the resources allocated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
 *		This function can be called from both interrupt and kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
 *		contexts.  DDI_NOSLEEP flag should be used while calling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
 *		from interrupt contexts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
 *		MDI_NOMEM
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
mdi_pi_alloc_compatible(dev_info_t *pdip, char *cname, char *caddr, char *paddr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
    char **compatible, int ncompatible, int flags, mdi_pathinfo_t **ret_pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
	mdi_vhci_t	*vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
	mdi_pathinfo_t	*pip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
	dev_info_t	*cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
	int		rv = MDI_NOMEM;
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2439
	int		path_allocated = 0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
	if (pdip == NULL || cname == NULL || caddr == NULL || paddr == NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
	    ret_pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
		/* Nothing more to do */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2446
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
	*ret_pip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
	ph = i_devi_get_phci(pdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
	ASSERT(ph != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
		/* Invalid pHCI device, return failure */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
		    "!mdi_pi_alloc: invalid pHCI=%p", pdip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
	MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2458
	vh = ph->ph_vhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
	if (vh == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
		/* Invalid vHCI device, return failure */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
		    "!mdi_pi_alloc: invalid pHCI=%p", pdip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2463
		MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
	if (MDI_PHCI_IS_READY(ph) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2468
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
		 * Do not allow new node creation when pHCI is in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
		 * offline/suspended states
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2471
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
		    "mdi_pi_alloc: pHCI=%p is not ready", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2474
		MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
		return (MDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
	MDI_PHCI_UNSTABLE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
	MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2480
	/* look for a matching client, create one if not found */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
	mutex_enter(&mdi_mutex);
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2482
	ct = i_mdi_client_find(vh, cname, caddr);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
	if (ct == NULL) {
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2484
		ct = i_mdi_client_alloc(vh, cname, caddr);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2485
		ASSERT(ct != NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
	if (ct->ct_dip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
		 * Allocate a devinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
		ct->ct_dip = i_mdi_devinfo_create(vh, cname, caddr,
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2493
		    compatible, ncompatible);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
		if (ct->ct_dip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
			(void) i_mdi_client_free(vh, ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
			goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
	cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
	DEVI(cdip)->devi_mdi_component |= MDI_COMPONENT_CLIENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2502
	DEVI(cdip)->devi_mdi_client = (caddr_t)ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2503
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2504
	pip = (mdi_pathinfo_t *)ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2505
	while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2506
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2507
		 * Compare the unit address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
		if ((MDI_PI(pip)->pi_phci == ph) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
		    strcmp(MDI_PI(pip)->pi_addr, paddr) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2511
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2512
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2513
		pip = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
	if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
		 * This is a new path for this client device.  Allocate and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
		 * initialize a new pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2520
		 */
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2521
		pip = i_mdi_pi_alloc(ph, paddr, ct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2522
		ASSERT(pip != NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2523
		path_allocated = 1;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2525
	rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2527
fail:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
	 * Release the global mutex.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2530
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2531
	mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2532
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2533
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2534
	 * Mark the pHCI as stable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2535
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2536
	MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2537
	MDI_PHCI_STABLE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
	MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
	*ret_pip = pip;
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2540
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2541
	if (path_allocated)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2542
		vhcache_pi_add(vh->vh_config, MDI_PI(pip));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2543
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2545
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2546
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2547
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
mdi_pi_alloc(dev_info_t *pdip, char *cname, char *caddr, char *paddr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
    int flags, mdi_pathinfo_t **ret_pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
	return (mdi_pi_alloc_compatible(pdip, cname, caddr, paddr, NULL, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
	    flags, ret_pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
 * i_mdi_pi_alloc():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
 *		Allocate a mdi_pathinfo node and add to the pHCI path list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
 *		mdi_pathinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
static mdi_pathinfo_t *
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2565
i_mdi_pi_alloc(mdi_phci_t *ph, char *paddr, mdi_client_t *ct)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2566
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2567
	mdi_pathinfo_t	*pip;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
	int		ct_circular;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
	int		ph_circular;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2571
	pip = kmem_zalloc(sizeof (struct mdi_pathinfo), KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
	mutex_init(&MDI_PI(pip)->pi_mutex, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
	MDI_PI(pip)->pi_state = MDI_PATHINFO_STATE_INIT |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
	    MDI_PATHINFO_STATE_TRANSIENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
	if (MDI_PHCI_IS_USER_DISABLED(ph))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
		MDI_PI_SET_USER_DISABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
	if (MDI_PHCI_IS_DRV_DISABLED_TRANSIENT(ph))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
		MDI_PI_SET_DRV_DISABLE_TRANS(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
	if (MDI_PHCI_IS_DRV_DISABLED(ph))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
		MDI_PI_SET_DRV_DISABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
	MDI_PI(pip)->pi_old_state = MDI_PATHINFO_STATE_INIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
	cv_init(&MDI_PI(pip)->pi_state_cv, NULL, CV_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2587
	MDI_PI(pip)->pi_client = ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2588
	MDI_PI(pip)->pi_phci = ph;
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2589
	MDI_PI(pip)->pi_addr = kmem_alloc(strlen(paddr) + 1, KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
	(void) strcpy(MDI_PI(pip)->pi_addr, paddr);
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2591
	(void) nvlist_alloc(&MDI_PI(pip)->pi_prop, NV_UNIQUE_NAME, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2592
	ASSERT(MDI_PI(pip)->pi_prop != NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2593
	MDI_PI(pip)->pi_pprivate = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2594
	MDI_PI(pip)->pi_cprivate = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2595
	MDI_PI(pip)->pi_vprivate = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
	MDI_PI(pip)->pi_client_link = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2597
	MDI_PI(pip)->pi_phci_link = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
	MDI_PI(pip)->pi_ref_cnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
	MDI_PI(pip)->pi_kstats = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
	MDI_PI(pip)->pi_preferred = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
	cv_init(&MDI_PI(pip)->pi_ref_cv, NULL, CV_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
	 * Lock both dev_info nodes against changes in parallel.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
	ndi_devi_enter(ct->ct_dip, &ct_circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
	ndi_devi_enter(ph->ph_dip, &ph_circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
	i_mdi_phci_add_path(ph, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
	i_mdi_client_add_path(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
	ndi_devi_exit(ph->ph_dip, ph_circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
	ndi_devi_exit(ct->ct_dip, ct_circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
	return (pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
 * i_mdi_phci_add_path():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
 * 		Add a mdi_pathinfo node to pHCI list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
 * Notes:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
 *		Caller should per-pHCI mutex
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
i_mdi_phci_add_path(mdi_phci_t *ph, mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
	ASSERT(DEVI_BUSY_OWNED(ph->ph_dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
	if (ph->ph_path_head == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
		ph->ph_path_head = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2633
		MDI_PI(ph->ph_path_tail)->pi_phci_link = MDI_PI(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2634
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
	ph->ph_path_tail = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
	ph->ph_path_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
 * i_mdi_client_add_path():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
 *		Add mdi_pathinfo node to client list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
i_mdi_client_add_path(mdi_client_t *ct, mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
	ASSERT(DEVI_BUSY_OWNED(ct->ct_dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2649
	if (ct->ct_path_head == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
		ct->ct_path_head = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
		MDI_PI(ct->ct_path_tail)->pi_client_link = MDI_PI(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
	ct->ct_path_tail = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
	ct->ct_path_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2658
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2659
 * mdi_pi_free():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2660
 *		Free the mdi_pathinfo node and also client device node if this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2661
 *		is the last path to the device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2662
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2663
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2664
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2665
 *		MDI_BUSY
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2666
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2667
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2668
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2669
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2670
mdi_pi_free(mdi_pathinfo_t *pip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2671
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2672
	int		rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2673
	mdi_vhci_t	*vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2674
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2675
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2676
	int		(*f)();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2677
	int		client_held = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2679
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2680
	ph = MDI_PI(pip)->pi_phci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2681
	ASSERT(ph != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2682
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2683
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2684
		 * Invalid pHCI device, return failure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2685
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2686
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2687
		    "!mdi_pi_free: invalid pHCI"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2688
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2689
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2690
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2691
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2692
	vh = ph->ph_vhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2693
	ASSERT(vh != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2694
	if (vh == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2695
		/* Invalid pHCI device, return failure */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2696
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2697
		    "!mdi_pi_free: invalid vHCI"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2698
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2699
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2700
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2701
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2702
	ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2703
	ASSERT(ct != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2704
	if (ct == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2705
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2706
		 * Invalid Client device, return failure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2707
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2708
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2709
		    "!mdi_pi_free: invalid client"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2710
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2711
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2712
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2714
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2715
	 * Check to see for busy condition.  A mdi_pathinfo can only be freed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2716
	 * if the node state is either offline or init and the reference count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2717
	 * is zero.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2718
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2719
	if (!(MDI_PI_IS_OFFLINE(pip) || MDI_PI_IS_INIT(pip) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2720
	    MDI_PI_IS_INITING(pip))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2721
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2722
		 * Node is busy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2723
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2724
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2725
		    "!mdi_pi_free: pathinfo node is busy pip=%p", pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2726
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2727
		return (MDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2728
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2730
	while (MDI_PI(pip)->pi_ref_cnt != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2731
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2732
		 * Give a chance for pending I/Os to complete.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2733
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2734
		MDI_DEBUG(1, (CE_NOTE, ct->ct_vhci->vh_dip, "!i_mdi_pi_free: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2735
		    "%d cmds still pending on path: %p\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2736
		    MDI_PI(pip)->pi_ref_cnt, pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2737
		if (cv_timedwait(&MDI_PI(pip)->pi_ref_cv,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2738
		    &MDI_PI(pip)->pi_mutex,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2739
		    ddi_get_lbolt() + drv_usectohz(60 * 1000000)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2740
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2741
			 * The timeout time reached without ref_cnt being zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2742
			 * being signaled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2743
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2744
			MDI_DEBUG(1, (CE_NOTE, ct->ct_vhci->vh_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2745
			    "!i_mdi_pi_free: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2746
			    "Timeout reached on path %p without the cond\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2747
			    pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2748
			MDI_DEBUG(1, (CE_NOTE, ct->ct_vhci->vh_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2749
			    "!i_mdi_pi_free: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2750
			    "%d cmds still pending on path: %p\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2751
			    MDI_PI(pip)->pi_ref_cnt, pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2752
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2753
			return (MDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2754
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2755
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2756
	if (MDI_PI(pip)->pi_pm_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2757
		client_held = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2758
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2759
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2760
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2761
	vhcache_pi_remove(vh->vh_config, MDI_PI(pip));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2762
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2763
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2764
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2765
	/* Prevent further failovers till mdi_mutex is held */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2766
	MDI_CLIENT_SET_PATH_FREE_IN_PROGRESS(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2767
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2768
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2769
	 * Wait till failover is complete before removing this node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2770
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2771
	while (MDI_CLIENT_IS_FAILOVER_IN_PROGRESS(ct))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2772
		cv_wait(&ct->ct_failover_cv, &ct->ct_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2773
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2774
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2775
	mutex_enter(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2776
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2777
	MDI_CLIENT_CLEAR_PATH_FREE_IN_PROGRESS(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2779
	if (!MDI_PI_IS_INITING(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2780
		f = vh->vh_ops->vo_pi_uninit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2781
		if (f != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2782
			rv = (*f)(vh->vh_dip, pip, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2783
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2784
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2785
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2786
	 * If vo_pi_uninit() completed successfully.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2787
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2788
	if (rv == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2789
		if (client_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2790
			MDI_DEBUG(4, (CE_NOTE, ct->ct_dip, "mdi_pi_free "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2791
			    "i_mdi_pm_rele_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2792
			i_mdi_pm_rele_client(ct, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2793
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2794
		i_mdi_pi_free(ph, pip, ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2795
		if (ct->ct_path_count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2796
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2797
			 * Client lost its last path.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2798
			 * Clean up the client device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2799
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2800
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2801
			(void) i_mdi_client_free(ct->ct_vhci, ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2802
			mutex_exit(&mdi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2803
			return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2804
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2805
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2806
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2807
	mutex_exit(&mdi_mutex);
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2808
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2809
	if (rv == MDI_FAILURE)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2810
		vhcache_pi_add(vh->vh_config, MDI_PI(pip));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  2811
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2812
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2813
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2814
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2815
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2816
 * i_mdi_pi_free():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2817
 *		Free the mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2818
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2819
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2820
i_mdi_pi_free(mdi_phci_t *ph, mdi_pathinfo_t *pip, mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2821
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2822
	int	ct_circular;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2823
	int	ph_circular;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2825
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2826
	 * remove any per-path kstats
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2827
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2828
	i_mdi_pi_kstat_destroy(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2829
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2830
	ndi_devi_enter(ct->ct_dip, &ct_circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2831
	ndi_devi_enter(ph->ph_dip, &ph_circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2832
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2833
	i_mdi_client_remove_path(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2834
	i_mdi_phci_remove_path(ph, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2835
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2836
	ndi_devi_exit(ph->ph_dip, ph_circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2837
	ndi_devi_exit(ct->ct_dip, ct_circular);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2838
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2839
	mutex_destroy(&MDI_PI(pip)->pi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2840
	cv_destroy(&MDI_PI(pip)->pi_state_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2841
	cv_destroy(&MDI_PI(pip)->pi_ref_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2842
	if (MDI_PI(pip)->pi_addr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2843
		kmem_free(MDI_PI(pip)->pi_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2844
		    strlen(MDI_PI(pip)->pi_addr) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2845
		MDI_PI(pip)->pi_addr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2846
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2847
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2848
	if (MDI_PI(pip)->pi_prop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2849
		(void) nvlist_free(MDI_PI(pip)->pi_prop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2850
		MDI_PI(pip)->pi_prop = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2851
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2852
	kmem_free(pip, sizeof (struct mdi_pathinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2853
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2854
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2856
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2857
 * i_mdi_phci_remove_path():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2858
 * 		Remove a mdi_pathinfo node from pHCI list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2859
 * Notes:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2860
 *		Caller should hold per-pHCI mutex
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2861
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2863
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2864
i_mdi_phci_remove_path(mdi_phci_t *ph, mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2865
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2866
	mdi_pathinfo_t	*prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2867
	mdi_pathinfo_t	*path = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2868
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2869
	ASSERT(DEVI_BUSY_OWNED(ph->ph_dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2870
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2871
	path = ph->ph_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2872
	while (path != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2873
		if (path == pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2874
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2875
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2876
		prev = path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2877
		path = (mdi_pathinfo_t *)MDI_PI(path)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2878
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2880
	if (path) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2881
		ph->ph_path_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2882
		if (prev) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2883
			MDI_PI(prev)->pi_phci_link = MDI_PI(path)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2884
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2885
			ph->ph_path_head =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2886
			    (mdi_pathinfo_t *)MDI_PI(path)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2887
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2888
		if (ph->ph_path_tail == path) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2889
			ph->ph_path_tail = prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2890
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2891
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2892
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2893
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2894
	 * Clear the pHCI link
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2895
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2896
	MDI_PI(pip)->pi_phci_link = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2897
	MDI_PI(pip)->pi_phci = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2898
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2899
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2900
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2901
 * i_mdi_client_remove_path():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2902
 * 		Remove a mdi_pathinfo node from client path list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2903
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2904
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2905
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2906
i_mdi_client_remove_path(mdi_client_t *ct, mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2907
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2908
	mdi_pathinfo_t	*prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2909
	mdi_pathinfo_t	*path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2910
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2911
	ASSERT(DEVI_BUSY_OWNED(ct->ct_dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2912
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2913
	path = ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2914
	while (path != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2915
		if (path == pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2916
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2917
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2918
		prev = path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2919
		path = (mdi_pathinfo_t *)MDI_PI(path)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2920
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2921
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2922
	if (path) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2923
		ct->ct_path_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2924
		if (prev) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2925
			MDI_PI(prev)->pi_client_link =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2926
			    MDI_PI(path)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2927
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2928
			ct->ct_path_head =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2929
			    (mdi_pathinfo_t *)MDI_PI(path)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2930
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2931
		if (ct->ct_path_tail == path) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2932
			ct->ct_path_tail = prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2933
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2934
		if (ct->ct_path_last == path) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2935
			ct->ct_path_last = ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2936
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2937
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2938
	MDI_PI(pip)->pi_client_link = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2939
	MDI_PI(pip)->pi_client = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2940
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2941
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2942
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2943
 * i_mdi_pi_state_change():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2944
 *		online a mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2945
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2946
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2947
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2948
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2949
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2950
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2951
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2952
i_mdi_pi_state_change(mdi_pathinfo_t *pip, mdi_pathinfo_state_t state, int flag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2953
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2954
	int		rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2955
	mdi_vhci_t	*vh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2956
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2957
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2958
	int		(*f)();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2959
	dev_info_t	*cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2960
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2961
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2962
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2963
	ph = MDI_PI(pip)->pi_phci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2964
	ASSERT(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2965
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2966
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2967
		 * Invalid pHCI device, fail the request
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2968
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2969
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2970
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2971
		    "!mdi_pi_state_change: invalid phci"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2972
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2973
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2974
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2975
	vh = ph->ph_vhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2976
	ASSERT(vh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2977
	if (vh == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2978
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2979
		 * Invalid vHCI device, fail the request
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2980
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2981
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2982
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2983
		    "!mdi_pi_state_change: invalid vhci"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2984
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2985
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2986
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2987
	ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2988
	ASSERT(ct != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2989
	if (ct == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2990
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2991
		 * Invalid client device, fail the request
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2992
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2993
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2994
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2995
		    "!mdi_pi_state_change: invalid client"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2996
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2997
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2998
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2999
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3000
	 * If this path has not been initialized yet, Callback vHCI driver's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3001
	 * pathinfo node initialize entry point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3002
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3003
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3004
	if (MDI_PI_IS_INITING(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3005
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3006
		f = vh->vh_ops->vo_pi_init;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3007
		if (f != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3008
			rv = (*f)(vh->vh_dip, pip, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3009
			if (rv != MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3010
				MDI_DEBUG(1, (CE_WARN, vh->vh_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3011
				    "!vo_pi_init: failed vHCI=0x%p, pip=0x%p",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3012
				    vh, pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3013
				return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3014
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3015
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3016
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3017
		MDI_PI_CLEAR_TRANSIENT(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3018
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3019
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3020
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3021
	 * Do not allow state transition when pHCI is in offline/suspended
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3022
	 * states
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3023
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3024
	i_mdi_phci_lock(ph, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3025
	if (MDI_PHCI_IS_READY(ph) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3026
		MDI_DEBUG(1, (CE_WARN, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3027
		    "!mdi_pi_state_change: pHCI not ready, pHCI=%p", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3028
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3029
		i_mdi_phci_unlock(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3030
		return (MDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3031
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3032
	MDI_PHCI_UNSTABLE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3033
	i_mdi_phci_unlock(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3034
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3035
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3036
	 * Check if mdi_pathinfo state is in transient state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3037
	 * If yes, offlining is in progress and wait till transient state is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3038
	 * cleared.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3039
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3040
	if (MDI_PI_IS_TRANSIENT(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3041
		while (MDI_PI_IS_TRANSIENT(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3042
			cv_wait(&MDI_PI(pip)->pi_state_cv,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3043
			    &MDI_PI(pip)->pi_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3044
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3045
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3046
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3047
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3048
	 * Grab the client lock in reverse order sequence and release the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3049
	 * mdi_pathinfo mutex.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3050
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3051
	i_mdi_client_lock(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3052
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3053
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3054
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3055
	 * Wait till failover state is cleared
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3056
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3057
	while (MDI_CLIENT_IS_FAILOVER_IN_PROGRESS(ct))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3058
		cv_wait(&ct->ct_failover_cv, &ct->ct_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3059
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3060
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3061
	 * Mark the mdi_pathinfo node state as transient
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3062
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3063
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3064
	switch (state) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3065
	case MDI_PATHINFO_STATE_ONLINE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3066
		MDI_PI_SET_ONLINING(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3067
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3068
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3069
	case MDI_PATHINFO_STATE_STANDBY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3070
		MDI_PI_SET_STANDBYING(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3071
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3072
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3073
	case MDI_PATHINFO_STATE_FAULT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3074
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3075
		 * Mark the pathinfo state as FAULTED
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3076
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3077
		MDI_PI_SET_FAULTING(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3078
		MDI_PI_ERRSTAT(pip, MDI_PI_HARDERR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3079
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3080
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3081
	case MDI_PATHINFO_STATE_OFFLINE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3082
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3083
		 * ndi_devi_offline() cannot hold pip or ct locks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3084
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3085
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3086
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3087
		 * Do not offline if path will become last path and path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3088
		 * is busy for user initiated events.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3089
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3090
		cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3091
		if ((flag & NDI_DEVI_REMOVE) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3092
		    (MDI_CLIENT_STATE(ct) == MDI_CLIENT_STATE_DEGRADED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3093
			i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3094
			rv = ndi_devi_offline(cdip, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3095
			if (rv != NDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3096
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3097
				 * Convert to MDI error code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3098
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3099
				switch (rv) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3100
				case NDI_BUSY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3101
					rv = MDI_BUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3102
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3103
				default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3104
					rv = MDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3105
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3106
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3107
				goto state_change_exit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3108
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3109
				i_mdi_client_lock(ct, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3110
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3111
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3112
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3113
		 * Mark the mdi_pathinfo node state as transient
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3114
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3115
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3116
		MDI_PI_SET_OFFLINING(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3117
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3118
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3119
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3120
	MDI_CLIENT_UNSTABLE(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3121
	i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3122
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3123
	f = vh->vh_ops->vo_pi_state_change;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3124
	if (f != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3125
		rv = (*f)(vh->vh_dip, pip, state, 0, flag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3126
		if (rv == MDI_NOT_SUPPORTED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3127
			MDI_CLIENT_SET_DEV_NOT_SUPPORTED(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3128
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3129
		if (rv != MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3130
			MDI_DEBUG(2, (CE_WARN, vh->vh_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3131
			    "!vo_pi_state_change: failed rv = %x", rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3132
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3133
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3134
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3135
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3136
	if (MDI_PI_IS_TRANSIENT(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3137
		if (rv == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3138
			MDI_PI_CLEAR_TRANSIENT(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3139
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3140
			MDI_PI(pip)->pi_state = MDI_PI_OLD_STATE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3141
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3142
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3144
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3145
	 * Wake anyone waiting for this mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3146
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3147
	cv_broadcast(&MDI_PI(pip)->pi_state_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3148
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3150
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3151
	 * Mark the client device as stable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3152
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3153
	MDI_CLIENT_STABLE(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3154
	if (rv == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3155
		if (ct->ct_unstable == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3156
			cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3157
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3158
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3159
			 * Onlining the mdi_pathinfo node will impact the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3160
			 * client state Update the client and dev_info node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3161
			 * state accordingly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3162
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3163
			rv = NDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3164
			i_mdi_client_update_state(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3165
			switch (MDI_CLIENT_STATE(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3166
			case MDI_CLIENT_STATE_OPTIMAL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3167
			case MDI_CLIENT_STATE_DEGRADED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3168
				if (cdip &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3169
				    (i_ddi_node_state(cdip) < DS_READY) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3170
				    ((state == MDI_PATHINFO_STATE_ONLINE) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3171
				    (state == MDI_PATHINFO_STATE_STANDBY))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3173
					i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3174
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3175
					 * Must do ndi_devi_online() through
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3176
					 * hotplug thread for deferred
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3177
					 * attach mechanism to work
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3178
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3179
					rv = ndi_devi_online(cdip, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3180
					i_mdi_client_lock(ct, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3181
					if ((rv != NDI_SUCCESS) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3182
					    (MDI_CLIENT_STATE(ct) ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3183
					    MDI_CLIENT_STATE_DEGRADED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3184
						/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3185
						 * ndi_devi_online failed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3186
						 * Reset client flags to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3187
						 * offline.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3188
						 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3189
						MDI_DEBUG(1, (CE_WARN, cdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3190
						    "!ndi_devi_online: failed "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3191
						    " Error: %x", rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3192
						MDI_CLIENT_SET_OFFLINE(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3193
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3194
					if (rv != NDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3195
						/* Reset the path state */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3196
						MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3197
						MDI_PI(pip)->pi_state =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3198
						    MDI_PI_OLD_STATE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3199
						MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3200
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3201
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3202
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3204
			case MDI_CLIENT_STATE_FAILED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3205
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3206
				 * This is the last path case for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3207
				 * non-user initiated events.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3208
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3209
				if (((flag & NDI_DEVI_REMOVE) == 0) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3210
				    cdip && (i_ddi_node_state(cdip) >=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3211
				    DS_INITIALIZED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3212
					i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3213
					rv = ndi_devi_offline(cdip, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3214
					i_mdi_client_lock(ct, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3216
					if (rv != NDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3217
						/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3218
						 * ndi_devi_offline failed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3219
						 * Reset client flags to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3220
						 * online as the path could not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3221
						 * be offlined.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3222
						 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3223
						MDI_DEBUG(1, (CE_WARN, cdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3224
						    "!ndi_devi_offline: failed "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3225
						    " Error: %x", rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3226
						MDI_CLIENT_SET_ONLINE(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3227
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3228
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3229
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3230
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3231
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3232
			 * Convert to MDI error code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3233
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3234
			switch (rv) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3235
			case NDI_SUCCESS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3236
				MDI_CLIENT_SET_REPORT_DEV_NEEDED(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3237
				i_mdi_report_path_state(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3238
				rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3239
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3240
			case NDI_BUSY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3241
				rv = MDI_BUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3242
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3243
			default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3244
				rv = MDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3245
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3246
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3247
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3248
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3249
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3250
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3251
state_change_exit:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3252
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3253
	 * Mark the pHCI as stable again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3254
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3255
	MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3256
	MDI_PHCI_STABLE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3257
	MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3258
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3259
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3261
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3262
 * mdi_pi_online():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3263
 *		Place the path_info node in the online state.  The path is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3264
 *		now available to be selected by mdi_select_path() for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3265
 *		transporting I/O requests to client devices.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3266
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3267
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3268
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3269
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3270
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3271
mdi_pi_online(mdi_pathinfo_t *pip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3272
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3273
	mdi_client_t *ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3274
	dev_info_t *cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3275
	int		client_held = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3276
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3277
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3278
	ASSERT(ct != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3279
	rv = i_mdi_pi_state_change(pip, MDI_PATHINFO_STATE_ONLINE, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3280
	if (rv != MDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3281
		return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3282
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3283
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3284
	if (MDI_PI(pip)->pi_pm_held == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3285
		MDI_DEBUG(4, (CE_NOTE, ct->ct_dip, "mdi_pi_online "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3286
		    "i_mdi_pm_hold_pip\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3287
		i_mdi_pm_hold_pip(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3288
		client_held = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3289
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3290
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3291
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3292
	if (client_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3293
		MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3294
		if (ct->ct_power_cnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3295
			rv = i_mdi_power_all_phci(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3296
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3298
		MDI_DEBUG(4, (CE_NOTE, ct->ct_dip, "mdi_pi_online "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3299
		    "i_mdi_pm_hold_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3300
		i_mdi_pm_hold_client(ct, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3301
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3302
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3304
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3305
	 * Create the per-path (pathinfo) IO and error kstats which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3306
	 * are reported via iostat(1m).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3307
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3308
	 * Defer creating the per-path kstats if device is not yet
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3309
	 * attached;  the names of the kstats are constructed in part
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3310
	 * using the devices instance number which is assigned during
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3311
	 * process of attaching the client device.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3312
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3313
	 * The framework post_attach handler, mdi_post_attach(), is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3314
	 * is responsible for initializing the client's pathinfo list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3315
	 * once successfully attached.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3316
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3317
	cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3318
	ASSERT(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3319
	if (cdip == NULL || (i_ddi_node_state(cdip) < DS_ATTACHED))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3320
		return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3322
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3323
	rv = i_mdi_pi_kstat_create(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3324
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3325
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3326
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3327
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3328
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3329
 * mdi_pi_standby():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3330
 *		Place the mdi_pathinfo node in standby state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3331
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3332
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3333
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3334
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3335
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3336
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3337
mdi_pi_standby(mdi_pathinfo_t *pip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3338
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3339
	return (i_mdi_pi_state_change(pip, MDI_PATHINFO_STATE_STANDBY, flags));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3340
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3341
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3342
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3343
 * mdi_pi_fault():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3344
 *		Place the mdi_pathinfo node in fault'ed state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3345
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3346
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3347
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3348
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3349
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3350
mdi_pi_fault(mdi_pathinfo_t *pip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3351
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3352
	return (i_mdi_pi_state_change(pip, MDI_PATHINFO_STATE_FAULT, flags));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3353
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3355
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3356
 * mdi_pi_offline():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3357
 *		Offline a mdi_pathinfo node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3358
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3359
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3360
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3361
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3362
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3363
mdi_pi_offline(mdi_pathinfo_t *pip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3364
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3365
	int	ret, client_held = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3366
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3367
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3368
	ret = i_mdi_pi_state_change(pip, MDI_PATHINFO_STATE_OFFLINE, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3370
	if (ret == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3371
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3372
		if (MDI_PI(pip)->pi_pm_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3373
			client_held = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3374
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3375
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3377
		if (client_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3378
			ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3379
			MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3380
			MDI_DEBUG(4, (CE_NOTE, ct->ct_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3381
			    "mdi_pi_offline i_mdi_pm_rele_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3382
			i_mdi_pm_rele_client(ct, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3383
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3384
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3385
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3387
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3388
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3389
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3390
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3391
 * i_mdi_pi_offline():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3392
 *		Offline a mdi_pathinfo node and call the vHCI driver's callback
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3393
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3394
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3395
i_mdi_pi_offline(mdi_pathinfo_t *pip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3396
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3397
	dev_info_t	*vdip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3398
	mdi_vhci_t	*vh = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3399
	mdi_client_t	*ct = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3400
	int		(*f)();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3401
	int		rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3402
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3403
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3404
	ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3405
	ASSERT(ct != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3406
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3407
	while (MDI_PI(pip)->pi_ref_cnt != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3408
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3409
		 * Give a chance for pending I/Os to complete.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3410
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3411
		MDI_DEBUG(1, (CE_NOTE, vdip, "!i_mdi_pi_offline: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3412
		    "%d cmds still pending on path: %p\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3413
		    MDI_PI(pip)->pi_ref_cnt, pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3414
		if (cv_timedwait(&MDI_PI(pip)->pi_ref_cv,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3415
		    &MDI_PI(pip)->pi_mutex,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3416
		    ddi_get_lbolt() + drv_usectohz(60 * 1000000)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3417
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3418
			 * The timeout time reached without ref_cnt being zero
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3419
			 * being signaled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3420
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3421
			MDI_DEBUG(1, (CE_NOTE, vdip, "!i_mdi_pi_offline: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3422
			    "Timeout reached on path %p without the cond\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3423
			    pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3424
			MDI_DEBUG(1, (CE_NOTE, vdip, "!i_mdi_pi_offline: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3425
			    "%d cmds still pending on path: %p\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3426
			    MDI_PI(pip)->pi_ref_cnt, pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3427
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3428
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3429
	vh = ct->ct_vhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3430
	vdip = vh->vh_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3432
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3433
	 * Notify vHCI that has registered this event
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3434
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3435
	ASSERT(vh->vh_ops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3436
	f = vh->vh_ops->vo_pi_state_change;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3437
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3438
	if (f != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3439
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3440
		if ((rv = (*f)(vdip, pip, MDI_PATHINFO_STATE_OFFLINE, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3441
		    flags)) != MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3442
			MDI_DEBUG(1, (CE_WARN, vdip, "!vo_path_offline failed "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3443
			    "vdip 0x%x, pip 0x%x", vdip, pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3444
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3445
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3446
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3447
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3448
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3449
	 * Set the mdi_pathinfo node state and clear the transient condition
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3450
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3451
	MDI_PI_SET_OFFLINE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3452
	cv_broadcast(&MDI_PI(pip)->pi_state_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3453
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3454
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3455
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3456
	if (rv == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3457
		if (ct->ct_unstable == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3458
			dev_info_t	*cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3460
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3461
			 * Onlining the mdi_pathinfo node will impact the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3462
			 * client state Update the client and dev_info node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3463
			 * state accordingly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3464
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3465
			i_mdi_client_update_state(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3466
			rv = NDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3467
			if (MDI_CLIENT_STATE(ct) == MDI_CLIENT_STATE_FAILED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3468
				if (cdip &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3469
				    (i_ddi_node_state(cdip) >=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3470
				    DS_INITIALIZED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3471
					MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3472
					rv = ndi_devi_offline(cdip, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3473
					MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3474
					if (rv != NDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3475
						/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3476
						 * ndi_devi_offline failed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3477
						 * Reset client flags to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3478
						 * online.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3479
						 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3480
						MDI_DEBUG(4, (CE_WARN, cdip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3481
						    "!ndi_devi_offline: failed "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3482
						    " Error: %x", rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3483
						MDI_CLIENT_SET_ONLINE(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3484
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3485
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3486
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3487
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3488
			 * Convert to MDI error code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3489
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3490
			switch (rv) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3491
			case NDI_SUCCESS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3492
				rv = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3493
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3494
			case NDI_BUSY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3495
				rv = MDI_BUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3496
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3497
			default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3498
				rv = MDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3499
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3500
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3501
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3502
		MDI_CLIENT_SET_REPORT_DEV_NEEDED(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3503
		i_mdi_report_path_state(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3504
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3505
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3506
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3507
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3508
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3509
	 * Change in the mdi_pathinfo node state will impact the client state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3510
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3511
	MDI_DEBUG(2, (CE_NOTE, NULL, "!i_mdi_pi_offline ct = %p pip = %p",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3512
	    ct, pip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3513
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3514
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3516
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3517
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3518
 * mdi_pi_get_addr():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3519
 *		Get the unit address associated with a mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3520
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3521
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3522
 *		char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3523
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3524
char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3525
mdi_pi_get_addr(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3526
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3527
	if (pip == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3528
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3529
82
0728ea41cce7 4953227 mdi_pi_get_addr() shouldn't skip the leading 'w'
cth
parents: 0
diff changeset
  3530
	return (MDI_PI(pip)->pi_addr);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3531
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3532
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3533
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3534
 * mdi_pi_get_client():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3535
 *		Get the client devinfo associated with a mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3536
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3537
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3538
 *		Handle to client device dev_info node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3539
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3540
dev_info_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3541
mdi_pi_get_client(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3542
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3543
	dev_info_t	*dip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3544
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3545
		dip = MDI_PI(pip)->pi_client->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3546
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3547
	return (dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3548
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3549
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3550
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3551
 * mdi_pi_get_phci():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3552
 *		Get the pHCI devinfo associated with the mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3553
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3554
 *		Handle to dev_info node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3555
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3556
dev_info_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3557
mdi_pi_get_phci(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3558
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3559
	dev_info_t	*dip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3560
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3561
		dip = MDI_PI(pip)->pi_phci->ph_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3562
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3563
	return (dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3564
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3565
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3566
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3567
 * mdi_pi_get_client_private():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3568
 *		Get the client private information associated with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3569
 *		mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3570
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3571
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3572
mdi_pi_get_client_private(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3573
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3574
	void *cprivate = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3575
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3576
		cprivate = MDI_PI(pip)->pi_cprivate;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3577
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3578
	return (cprivate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3579
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3580
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3581
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3582
 * mdi_pi_set_client_private():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3583
 *		Set the client private information in the mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3584
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3585
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3586
mdi_pi_set_client_private(mdi_pathinfo_t *pip, void *priv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3587
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3588
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3589
		MDI_PI(pip)->pi_cprivate = priv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3590
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3591
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3592
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3593
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3594
 * mdi_pi_get_phci_private():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3595
 *		Get the pHCI private information associated with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3596
 *		mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3597
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3598
caddr_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3599
mdi_pi_get_phci_private(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3600
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3601
	caddr_t	pprivate = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3602
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3603
		pprivate = MDI_PI(pip)->pi_pprivate;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3604
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3605
	return (pprivate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3606
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3608
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3609
 * mdi_pi_set_phci_private():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3610
 *		Set the pHCI private information in the mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3611
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3612
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3613
mdi_pi_set_phci_private(mdi_pathinfo_t *pip, caddr_t priv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3614
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3615
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3616
		MDI_PI(pip)->pi_pprivate = priv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3617
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3618
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3620
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3621
 * mdi_pi_get_state():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3622
 *		Get the mdi_pathinfo node state. Transient states are internal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3623
 *		and not provided to the users
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3624
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3625
mdi_pathinfo_state_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3626
mdi_pi_get_state(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3627
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3628
	mdi_pathinfo_state_t    state = MDI_PATHINFO_STATE_INIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3629
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3630
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3631
		if (MDI_PI_IS_TRANSIENT(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3632
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3633
			 * mdi_pathinfo is in state transition.  Return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3634
			 * last good state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3635
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3636
			state = MDI_PI_OLD_STATE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3637
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3638
			state = MDI_PI_STATE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3639
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3640
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3641
	return (state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3642
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3644
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3645
 * Note that the following function needs to be the new interface for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3646
 * mdi_pi_get_state when mpxio gets integrated to ON.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3647
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3648
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3649
mdi_pi_get_state2(mdi_pathinfo_t *pip, mdi_pathinfo_state_t *state,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3650
		uint32_t *ext_state)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3651
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3652
	*state = MDI_PATHINFO_STATE_INIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3653
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3654
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3655
		if (MDI_PI_IS_TRANSIENT(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3656
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3657
			 * mdi_pathinfo is in state transition.  Return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3658
			 * last good state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3659
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3660
			*state = MDI_PI_OLD_STATE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3661
			*ext_state = MDI_PI_OLD_EXT_STATE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3662
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3663
			*state = MDI_PI_STATE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3664
			*ext_state = MDI_PI_EXT_STATE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3665
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3666
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3667
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3668
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3670
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3671
 * mdi_pi_get_preferred:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3672
 *	Get the preferred path flag
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3673
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3674
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3675
mdi_pi_get_preferred(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3676
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3677
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3678
		return (MDI_PI(pip)->pi_preferred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3679
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3680
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3681
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3682
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3683
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3684
 * mdi_pi_set_preferred:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3685
 *	Set the preferred path flag
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3686
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3687
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3688
mdi_pi_set_preferred(mdi_pathinfo_t *pip, int preferred)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3689
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3690
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3691
		MDI_PI(pip)->pi_preferred = preferred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3692
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3693
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3694
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3696
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3697
 * mdi_pi_set_state():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3698
 *		Set the mdi_pathinfo node state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3699
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3700
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3701
mdi_pi_set_state(mdi_pathinfo_t *pip, mdi_pathinfo_state_t state)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3702
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3703
	uint32_t	ext_state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3705
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3706
		ext_state = MDI_PI(pip)->pi_state & MDI_PATHINFO_EXT_STATE_MASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3707
		MDI_PI(pip)->pi_state = state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3708
		MDI_PI(pip)->pi_state |= ext_state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3709
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3710
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3711
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3712
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3713
 * Property functions:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3714
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3715
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3716
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3717
i_map_nvlist_error_to_mdi(int val)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3718
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3719
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3720
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3721
	switch (val) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3722
	case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3723
		rv = DDI_PROP_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3724
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3725
	case EINVAL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3726
	case ENOTSUP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3727
		rv = DDI_PROP_INVAL_ARG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3728
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3729
	case ENOMEM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3730
		rv = DDI_PROP_NO_MEMORY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3731
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3732
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3733
		rv = DDI_PROP_NOT_FOUND;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3734
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3735
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3736
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3737
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3738
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3739
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3740
 * mdi_pi_get_next_prop():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3741
 * 		Property walk function.  The caller should hold mdi_pi_lock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3742
 *		and release by calling mdi_pi_unlock() at the end of walk to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3743
 *		get a consistent value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3744
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3745
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3746
nvpair_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3747
mdi_pi_get_next_prop(mdi_pathinfo_t *pip, nvpair_t *prev)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3748
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3749
	if ((pip == NULL) || (MDI_PI(pip)->pi_prop == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3750
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3751
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3752
	ASSERT(MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3753
	return (nvlist_next_nvpair(MDI_PI(pip)->pi_prop, prev));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3754
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3755
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3756
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3757
 * mdi_prop_remove():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3758
 * 		Remove the named property from the named list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3759
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3760
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3761
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3762
mdi_prop_remove(mdi_pathinfo_t *pip, char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3763
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3764
	if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3765
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3766
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3767
	ASSERT(!MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3768
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3769
	if (MDI_PI(pip)->pi_prop == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3770
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3771
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3772
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3773
	if (name) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3774
		(void) nvlist_remove_all(MDI_PI(pip)->pi_prop, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3775
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3776
		char		nvp_name[MAXNAMELEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3777
		nvpair_t	*nvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3778
		nvp = nvlist_next_nvpair(MDI_PI(pip)->pi_prop, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3779
		while (nvp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3780
			nvpair_t	*next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3781
			next = nvlist_next_nvpair(MDI_PI(pip)->pi_prop, nvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3782
			(void) snprintf(nvp_name, MAXNAMELEN, "%s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3783
			    nvpair_name(nvp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3784
			(void) nvlist_remove_all(MDI_PI(pip)->pi_prop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3785
			    nvp_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3786
			nvp = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3787
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3788
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3789
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3790
	return (DDI_PROP_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3791
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3792
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3793
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3794
 * mdi_prop_size():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3795
 * 		Get buffer size needed to pack the property data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3796
 * 		Caller should hold the mdi_pathinfo_t lock to get a consistent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3797
 *		buffer size.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3798
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3799
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3800
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3801
mdi_prop_size(mdi_pathinfo_t *pip, size_t *buflenp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3802
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3803
	int	rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3804
	size_t	bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3805
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3806
	*buflenp = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3807
	if ((pip == NULL) || (MDI_PI(pip)->pi_prop == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3808
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3809
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3810
	ASSERT(MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3811
	rv = nvlist_size(MDI_PI(pip)->pi_prop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3812
	    &bufsize, NV_ENCODE_NATIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3813
	*buflenp = bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3814
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3815
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3816
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3817
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3818
 * mdi_prop_pack():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3819
 * 		pack the property list.  The caller should hold the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3820
 *		mdi_pathinfo_t node to get a consistent data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3821
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3822
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3823
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3824
mdi_prop_pack(mdi_pathinfo_t *pip, char **bufp, uint_t buflen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3825
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3826
	int	rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3827
	size_t	bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3828
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3829
	if ((pip == NULL) || MDI_PI(pip)->pi_prop == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3830
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3831
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3832
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3833
	ASSERT(MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3834
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3835
	bufsize = buflen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3836
	rv = nvlist_pack(MDI_PI(pip)->pi_prop, bufp, (size_t *)&bufsize,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3837
	    NV_ENCODE_NATIVE, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3838
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3839
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3840
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3841
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3842
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3843
 * mdi_prop_update_byte():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3844
 *		Create/Update a byte property
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3845
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3846
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3847
mdi_prop_update_byte(mdi_pathinfo_t *pip, char *name, uchar_t data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3848
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3849
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3850
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3851
	if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3852
		return (DDI_PROP_INVAL_ARG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3853
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3854
	ASSERT(!MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3855
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3856
	if (MDI_PI(pip)->pi_prop == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3857
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3858
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3859
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3860
	rv = nvlist_add_byte(MDI_PI(pip)->pi_prop, name, data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3861
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3862
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3863
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3864
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3865
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3866
 * mdi_prop_update_byte_array():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3867
 *		Create/Update a byte array property
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3868
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3869
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3870
mdi_prop_update_byte_array(mdi_pathinfo_t *pip, char *name, uchar_t *data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3871
    uint_t nelements)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3872
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3873
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3874
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3875
	if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3876
		return (DDI_PROP_INVAL_ARG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3877
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3878
	ASSERT(!MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3879
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3880
	if (MDI_PI(pip)->pi_prop == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3881
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3882
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3883
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3884
	rv = nvlist_add_byte_array(MDI_PI(pip)->pi_prop, name, data, nelements);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3885
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3886
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3887
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3888
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3889
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3890
 * mdi_prop_update_int():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3891
 *		Create/Update a 32 bit integer property
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3892
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3893
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3894
mdi_prop_update_int(mdi_pathinfo_t *pip, char *name, int data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3895
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3896
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3897
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3898
	if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3899
		return (DDI_PROP_INVAL_ARG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3900
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3901
	ASSERT(!MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3902
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3903
	if (MDI_PI(pip)->pi_prop == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3904
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3905
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3906
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3907
	rv = nvlist_add_int32(MDI_PI(pip)->pi_prop, name, (int32_t)data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3908
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3909
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3910
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3911
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3912
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3913
 * mdi_prop_update_int64():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3914
 *		Create/Update a 64 bit integer property
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3915
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3916
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3917
mdi_prop_update_int64(mdi_pathinfo_t *pip, char *name, int64_t data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3918
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3919
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3920
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3921
	if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3922
		return (DDI_PROP_INVAL_ARG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3923
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3924
	ASSERT(!MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3925
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3926
	if (MDI_PI(pip)->pi_prop == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3927
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3928
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3929
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3930
	rv = nvlist_add_int64(MDI_PI(pip)->pi_prop, name, data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3931
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3932
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3933
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3934
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3935
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3936
 * mdi_prop_update_int_array():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3937
 *		Create/Update a int array property
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3938
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3939
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3940
mdi_prop_update_int_array(mdi_pathinfo_t *pip, char *name, int *data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3941
	    uint_t nelements)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3942
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3943
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3944
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3945
	if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3946
		return (DDI_PROP_INVAL_ARG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3947
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3948
	ASSERT(!MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3949
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3950
	if (MDI_PI(pip)->pi_prop == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3951
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3952
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3953
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3954
	rv = nvlist_add_int32_array(MDI_PI(pip)->pi_prop, name, (int32_t *)data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3955
	    nelements);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3956
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3957
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3958
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3959
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3960
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3961
 * mdi_prop_update_string():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3962
 *		Create/Update a string property
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3963
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3964
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3965
mdi_prop_update_string(mdi_pathinfo_t *pip, char *name, char *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3966
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3967
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3968
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3969
	if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3970
		return (DDI_PROP_INVAL_ARG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3971
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3972
	ASSERT(!MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3973
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3974
	if (MDI_PI(pip)->pi_prop == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3975
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3976
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3977
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3978
	rv = nvlist_add_string(MDI_PI(pip)->pi_prop, name, data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3979
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3980
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3981
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3982
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3983
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3984
 * mdi_prop_update_string_array():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3985
 *		Create/Update a string array property
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3986
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3987
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3988
mdi_prop_update_string_array(mdi_pathinfo_t *pip, char *name, char **data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3989
    uint_t nelements)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3990
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3991
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3992
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3993
	if (pip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3994
		return (DDI_PROP_INVAL_ARG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3995
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3996
	ASSERT(!MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3997
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3998
	if (MDI_PI(pip)->pi_prop == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3999
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4000
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4001
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4002
	rv = nvlist_add_string_array(MDI_PI(pip)->pi_prop, name, data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4003
	    nelements);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4004
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4005
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4006
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4007
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4008
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4009
 * mdi_prop_lookup_byte():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4010
 * 		Look for byte property identified by name.  The data returned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4011
 *		is the actual property and valid as long as mdi_pathinfo_t node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4012
 *		is alive.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4013
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4014
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4015
mdi_prop_lookup_byte(mdi_pathinfo_t *pip, char *name, uchar_t *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4016
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4017
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4018
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4019
	if ((pip == NULL) || (MDI_PI(pip)->pi_prop == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4020
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4021
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4022
	rv = nvlist_lookup_byte(MDI_PI(pip)->pi_prop, name, data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4023
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4024
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4025
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4026
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4027
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4028
 * mdi_prop_lookup_byte_array():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4029
 * 		Look for byte array property identified by name.  The data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4030
 *		returned is the actual property and valid as long as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4031
 *		mdi_pathinfo_t node is alive.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4032
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4033
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4034
mdi_prop_lookup_byte_array(mdi_pathinfo_t *pip, char *name, uchar_t **data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4035
    uint_t *nelements)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4036
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4037
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4039
	if ((pip == NULL) || (MDI_PI(pip)->pi_prop == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4040
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4041
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4042
	rv = nvlist_lookup_byte_array(MDI_PI(pip)->pi_prop, name, data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4043
	    nelements);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4044
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4045
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4046
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4047
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4048
 * mdi_prop_lookup_int():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4049
 * 		Look for int property identified by name.  The data returned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4050
 *		is the actual property and valid as long as mdi_pathinfo_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4051
 *		node is alive.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4052
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4053
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4054
mdi_prop_lookup_int(mdi_pathinfo_t *pip, char *name, int *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4055
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4056
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4057
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4058
	if ((pip == NULL) || (MDI_PI(pip)->pi_prop == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4059
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4060
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4061
	rv = nvlist_lookup_int32(MDI_PI(pip)->pi_prop, name, (int32_t *)data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4062
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4063
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4064
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4065
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4066
 * mdi_prop_lookup_int64():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4067
 * 		Look for int64 property identified by name.  The data returned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4068
 *		is the actual property and valid as long as mdi_pathinfo_t node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4069
 *		is alive.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4070
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4071
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4072
mdi_prop_lookup_int64(mdi_pathinfo_t *pip, char *name, int64_t *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4073
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4074
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4075
	if ((pip == NULL) || (MDI_PI(pip)->pi_prop == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4076
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4077
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4078
	rv = nvlist_lookup_int64(MDI_PI(pip)->pi_prop, name, data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4079
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4080
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4081
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4082
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4083
 * mdi_prop_lookup_int_array():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4084
 * 		Look for int array property identified by name.  The data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4085
 *		returned is the actual property and valid as long as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4086
 *		mdi_pathinfo_t node is alive.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4087
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4088
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4089
mdi_prop_lookup_int_array(mdi_pathinfo_t *pip, char *name, int **data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4090
    uint_t *nelements)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4091
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4092
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4093
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4094
	if ((pip == NULL) || (MDI_PI(pip)->pi_prop == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4095
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4096
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4097
	rv = nvlist_lookup_int32_array(MDI_PI(pip)->pi_prop, name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4098
	    (int32_t **)data, nelements);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4099
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4100
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4102
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4103
 * mdi_prop_lookup_string():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4104
 * 		Look for string property identified by name.  The data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4105
 *		returned is the actual property and valid as long as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4106
 *		mdi_pathinfo_t node is alive.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4107
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4108
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4109
mdi_prop_lookup_string(mdi_pathinfo_t *pip, char *name, char **data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4110
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4111
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4113
	if ((pip == NULL) || (MDI_PI(pip)->pi_prop == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4114
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4115
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4116
	rv = nvlist_lookup_string(MDI_PI(pip)->pi_prop, name, data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4117
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4118
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4119
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4120
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4121
 * mdi_prop_lookup_string_array():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4122
 * 		Look for string array property identified by name.  The data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4123
 *		returned is the actual property and valid as long as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4124
 *		mdi_pathinfo_t node is alive.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4125
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4126
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4127
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4128
mdi_prop_lookup_string_array(mdi_pathinfo_t *pip, char *name, char ***data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4129
    uint_t *nelements)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4130
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4131
	int rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4133
	if ((pip == NULL) || (MDI_PI(pip)->pi_prop == NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4134
		return (DDI_PROP_NOT_FOUND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4135
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4136
	rv = nvlist_lookup_string_array(MDI_PI(pip)->pi_prop, name, data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4137
	    nelements);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4138
	return (i_map_nvlist_error_to_mdi(rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4139
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4141
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4142
 * mdi_prop_free():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4143
 * 		Symmetrical function to ddi_prop_free(). nvlist_lookup_xx()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4144
 *		functions return the pointer to actual property data and not a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4145
 *		copy of it.  So the data returned is valid as long as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4146
 *		mdi_pathinfo_t node is valid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4147
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4148
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4149
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4150
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4151
mdi_prop_free(void *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4152
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4153
	return (DDI_PROP_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4154
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4156
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4157
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4158
i_mdi_report_path_state(mdi_client_t *ct, mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4159
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4160
	char		*phci_path, *ct_path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4161
	char		*ct_status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4162
	char		*status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4163
	dev_info_t	*dip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4164
	char		lb_buf[64];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4165
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4166
	ASSERT(MUTEX_HELD(&ct->ct_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4167
	if ((dip == NULL) || (ddi_get_instance(dip) == -1) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4168
	    (MDI_CLIENT_IS_REPORT_DEV_NEEDED(ct) == 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4169
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4170
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4171
	if (MDI_CLIENT_STATE(ct) == MDI_CLIENT_STATE_OPTIMAL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4172
		ct_status = "optimal";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4173
	} else if (MDI_CLIENT_STATE(ct) == MDI_CLIENT_STATE_DEGRADED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4174
		ct_status = "degraded";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4175
	} else if (MDI_CLIENT_STATE(ct) == MDI_CLIENT_STATE_FAILED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4176
		ct_status = "failed";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4177
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4178
		ct_status = "unknown";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4179
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4180
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4181
	if (MDI_PI_IS_OFFLINE(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4182
		status = "offline";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4183
	} else if (MDI_PI_IS_ONLINE(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4184
		status = "online";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4185
	} else if (MDI_PI_IS_STANDBY(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4186
		status = "standby";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4187
	} else if (MDI_PI_IS_FAULT(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4188
		status = "faulted";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4189
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4190
		status = "unknown";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4191
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4193
	if (ct->ct_lb == LOAD_BALANCE_LBA) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4194
		(void) snprintf(lb_buf, sizeof (lb_buf),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4195
		    "%s, region-size: %d", mdi_load_balance_lba,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4196
			ct->ct_lb_args->region_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4197
	} else if (ct->ct_lb == LOAD_BALANCE_NONE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4198
		(void) snprintf(lb_buf, sizeof (lb_buf),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4199
		    "%s", mdi_load_balance_none);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4200
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4201
		(void) snprintf(lb_buf, sizeof (lb_buf), "%s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4202
		    mdi_load_balance_rr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4203
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4204
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4205
	if (dip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4206
		ct_path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4207
		phci_path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4208
		cmn_err(CE_CONT, "?%s (%s%d) multipath status: %s, "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4209
		    "path %s (%s%d) to target address: %s is %s"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4210
		    " Load balancing: %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4211
		    ddi_pathname(dip, ct_path), ddi_driver_name(dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4212
		    ddi_get_instance(dip), ct_status,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4213
		    ddi_pathname(MDI_PI(pip)->pi_phci->ph_dip, phci_path),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4214
		    ddi_driver_name(MDI_PI(pip)->pi_phci->ph_dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4215
		    ddi_get_instance(MDI_PI(pip)->pi_phci->ph_dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4216
		    MDI_PI(pip)->pi_addr, status, lb_buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4217
		kmem_free(phci_path, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4218
		kmem_free(ct_path, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4219
		MDI_CLIENT_CLEAR_REPORT_DEV_NEEDED(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4220
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4221
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4222
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4223
#ifdef	DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4224
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4225
 * i_mdi_log():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4226
 *		Utility function for error message management
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4227
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4228
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4229
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4230
/*VARARGS3*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4231
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4232
i_mdi_log(int level, dev_info_t *dip, const char *fmt, ...)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4233
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4234
	char		buf[MAXNAMELEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4235
	char		name[MAXNAMELEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4236
	va_list		ap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4237
	int		log_only = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4238
	int		boot_only = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4239
	int		console_only = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4241
	if (dip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4242
		if (level == CE_PANIC || level == CE_WARN || level == CE_NOTE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4243
			(void) snprintf(name, MAXNAMELEN, "%s%d:\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4244
			    ddi_node_name(dip), ddi_get_instance(dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4245
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4246
			(void) snprintf(name, MAXNAMELEN, "%s%d:",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4247
			    ddi_node_name(dip), ddi_get_instance(dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4248
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4249
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4250
		name[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4251
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4253
	va_start(ap, fmt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4254
	(void) vsnprintf(buf, MAXNAMELEN, fmt, ap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4255
	va_end(ap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4257
	switch (buf[0]) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4258
	case '!':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4259
		log_only = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4260
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4261
	case '?':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4262
		boot_only = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4263
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4264
	case '^':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4265
		console_only = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4266
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4267
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4268
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4269
	switch (level) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4270
	case CE_NOTE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4271
		level = CE_CONT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4272
		/* FALLTHROUGH */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4273
	case CE_CONT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4274
	case CE_WARN:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4275
	case CE_PANIC:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4276
		if (boot_only) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4277
			cmn_err(level, "?%s\t%s", name, &buf[1]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4278
		} else if (console_only) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4279
			cmn_err(level, "^%s\t%s", name, &buf[1]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4280
		} else if (log_only) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4281
			cmn_err(level, "!%s\t%s", name, &buf[1]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4282
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4283
			cmn_err(level, "%s\t%s", name, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4284
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4285
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4286
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4287
		cmn_err(level, "%s\t%s", name, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4288
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4289
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4290
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4291
#endif	/* DEBUG */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4293
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4294
i_mdi_client_online(dev_info_t *ct_dip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4295
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4296
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4298
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4299
	 * Client online notification. Mark client state as online
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4300
	 * restore our binding with dev_info node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4301
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4302
	ct = i_devi_get_client(ct_dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4303
	ASSERT(ct != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4304
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4305
	MDI_CLIENT_SET_ONLINE(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4306
	/* catch for any memory leaks */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4307
	ASSERT((ct->ct_dip == NULL) || (ct->ct_dip == ct_dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4308
	ct->ct_dip = ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4310
	if (ct->ct_power_cnt == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4311
		(void) i_mdi_power_all_phci(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4313
	MDI_DEBUG(4, (CE_NOTE, ct_dip, "i_mdi_client_online "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4314
	    "i_mdi_pm_hold_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4315
	i_mdi_pm_hold_client(ct, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4316
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4317
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4318
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4319
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4320
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4321
i_mdi_phci_online(dev_info_t *ph_dip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4322
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4323
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4324
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4325
	/* pHCI online notification. Mark state accordingly */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4326
	ph = i_devi_get_phci(ph_dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4327
	ASSERT(ph != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4328
	MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4329
	MDI_PHCI_SET_ONLINE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4330
	MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4331
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4333
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4334
 * mdi_devi_online():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4335
 * 		Online notification from NDI framework on pHCI/client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4336
 *		device online.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4337
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4338
 *		NDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4339
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4340
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4341
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4342
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4343
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4344
mdi_devi_online(dev_info_t *dip, uint_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4345
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4346
	if (MDI_PHCI(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4347
		i_mdi_phci_online(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4348
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4350
	if (MDI_CLIENT(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4351
		i_mdi_client_online(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4352
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4353
	return (NDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4354
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4355
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4356
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4357
 * mdi_devi_offline():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4358
 * 		Offline notification from NDI framework on pHCI/Client device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4359
 *		offline.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4360
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4361
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4362
 *		NDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4363
 *		NDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4364
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4366
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4367
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4368
mdi_devi_offline(dev_info_t *dip, uint_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4369
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4370
	int		rv = NDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4372
	if (MDI_CLIENT(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4373
		rv = i_mdi_client_offline(dip, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4374
		if (rv != NDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4375
			return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4376
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4377
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4378
	if (MDI_PHCI(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4379
		rv = i_mdi_phci_offline(dip, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4380
		if ((rv != NDI_SUCCESS) && MDI_CLIENT(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4381
			/* set client back online */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4382
			i_mdi_client_online(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4383
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4384
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4385
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4386
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4387
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4389
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4390
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4391
i_mdi_phci_offline(dev_info_t *dip, uint_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4392
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4393
	int		rv = NDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4394
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4395
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4396
	mdi_pathinfo_t	*pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4397
	mdi_pathinfo_t	*next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4398
	mdi_pathinfo_t	*failed_pip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4399
	dev_info_t	*cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4400
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4401
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4402
	 * pHCI component offline notification
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4403
	 * Make sure that this pHCI instance is free to be offlined.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4404
	 * If it is OK to proceed, Offline and remove all the child
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4405
	 * mdi_pathinfo nodes.  This process automatically offlines
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4406
	 * corresponding client devices, for which this pHCI provides
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4407
	 * critical services.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4408
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4409
	MDI_DEBUG(2, (CE_NOTE, dip, "!mdi_phci_offline called %p\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4410
	    dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4412
	ph = i_devi_get_phci(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4413
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4414
		return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4415
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4416
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4417
	MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4418
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4419
	if (MDI_PHCI_IS_OFFLINE(ph)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4420
		MDI_DEBUG(1, (CE_WARN, dip, "!pHCI %p already offlined", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4421
		MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4422
		return (NDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4423
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4424
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4425
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4426
	 * Check to see if the pHCI can be offlined
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4427
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4428
	if (ph->ph_unstable) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4429
		MDI_DEBUG(1, (CE_WARN, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4430
		    "!One or more target devices are in transient "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4431
		    "state. This device can not be removed at "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4432
		    "this moment. Please try again later."));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4433
		MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4434
		return (NDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4435
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4436
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4437
	pip = ph->ph_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4438
	while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4439
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4440
		next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4441
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4442
		 * The mdi_pathinfo state is OK. Check the client state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4443
		 * If failover in progress fail the pHCI from offlining
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4444
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4445
		ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4446
		i_mdi_client_lock(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4447
		if ((MDI_CLIENT_IS_FAILOVER_IN_PROGRESS(ct)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4448
		    (ct->ct_unstable)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4449
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4450
			 * Failover is in progress, Fail the DR
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4451
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4452
			MDI_DEBUG(1, (CE_WARN, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4453
			    "!pHCI device (%s%d) is Busy. %s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4454
			    ddi_driver_name(dip), ddi_get_instance(dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4455
			    "This device can not be removed at "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4456
			    "this moment. Please try again later."));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4457
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4458
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4459
			MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4460
			return (NDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4461
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4462
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4463
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4464
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4465
		 * Check to see of we are removing the last path of this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4466
		 * client device...
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4467
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4468
		cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4469
		if (cdip && (i_ddi_node_state(cdip) >= DS_INITIALIZED) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4470
		    (i_mdi_client_compute_state(ct, ph) ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4471
		    MDI_CLIENT_STATE_FAILED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4472
			i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4473
			MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4474
			if (ndi_devi_offline(cdip, 0) != NDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4475
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4476
				 * ndi_devi_offline() failed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4477
				 * This pHCI provides the critical path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4478
				 * to one or more client devices.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4479
				 * Return busy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4480
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4481
				MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4482
				MDI_DEBUG(1, (CE_WARN, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4483
				    "!pHCI device (%s%d) is Busy. %s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4484
				    ddi_driver_name(dip), ddi_get_instance(dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4485
				    "This device can not be removed at "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4486
				    "this moment. Please try again later."));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4487
				failed_pip = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4488
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4489
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4490
				MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4491
				pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4492
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4493
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4494
			i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4495
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4496
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4497
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4498
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4499
	if (failed_pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4500
		pip = ph->ph_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4501
		while (pip != failed_pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4502
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4503
			next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4504
			ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4505
			i_mdi_client_lock(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4506
			cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4507
			switch (MDI_CLIENT_STATE(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4508
			case MDI_CLIENT_STATE_OPTIMAL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4509
			case MDI_CLIENT_STATE_DEGRADED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4510
				if (cdip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4511
					MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4512
					i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4513
					MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4514
					(void) ndi_devi_online(cdip, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4515
					MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4516
					pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4517
					continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4518
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4519
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4520
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4521
			case MDI_CLIENT_STATE_FAILED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4522
				if (cdip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4523
					MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4524
					i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4525
					MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4526
					(void) ndi_devi_offline(cdip, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4527
					MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4528
					pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4529
					continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4530
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4531
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4532
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4533
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4534
			i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4535
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4536
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4537
		MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4538
		return (NDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4539
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4540
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4541
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4542
	 * Mark the pHCI as offline
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4543
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4544
	MDI_PHCI_SET_OFFLINE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4545
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4546
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4547
	 * Mark the child mdi_pathinfo nodes as transient
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4548
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4549
	pip = ph->ph_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4550
	while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4551
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4552
		next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4553
		MDI_PI_SET_OFFLINING(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4554
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4555
		pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4556
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4557
	MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4558
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4559
	 * Give a chance for any pending commands to execute
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4560
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4561
	delay(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4562
	MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4563
	pip = ph->ph_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4564
	while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4565
		next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4566
		(void) i_mdi_pi_offline(pip, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4567
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4568
		ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4569
		if (!MDI_PI_IS_OFFLINE(pip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4570
			MDI_DEBUG(1, (CE_WARN, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4571
			    "!pHCI device (%s%d) is Busy. %s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4572
			    ddi_driver_name(dip), ddi_get_instance(dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4573
			    "This device can not be removed at "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4574
			    "this moment. Please try again later."));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4575
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4576
			MDI_PHCI_SET_ONLINE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4577
			MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4578
			return (NDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4579
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4580
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4581
		pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4582
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4583
	MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4585
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4586
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4587
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4588
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4589
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4590
i_mdi_client_offline(dev_info_t *dip, uint_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4591
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4592
	int		rv = NDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4593
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4595
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4596
	 * Client component to go offline.  Make sure that we are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4597
	 * not in failing over state and update client state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4598
	 * accordingly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4599
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4600
	MDI_DEBUG(2, (CE_NOTE, dip, "!i_mdi_client_offline called %p\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4601
	    dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4602
	ct = i_devi_get_client(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4603
	if (ct != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4604
		MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4605
		if (ct->ct_unstable) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4606
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4607
			 * One or more paths are in transient state,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4608
			 * Dont allow offline of a client device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4609
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4610
			MDI_DEBUG(1, (CE_WARN, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4611
			    "!One or more paths to this device is "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4612
			    "in transient state. This device can not "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4613
			    "be removed at this moment. "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4614
			    "Please try again later."));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4615
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4616
			return (NDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4617
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4618
		if (MDI_CLIENT_IS_FAILOVER_IN_PROGRESS(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4619
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4620
			 * Failover is in progress, Dont allow DR of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4621
			 * a client device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4622
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4623
			MDI_DEBUG(1, (CE_WARN, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4624
			    "!Client device (%s%d) is Busy. %s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4625
			    ddi_driver_name(dip), ddi_get_instance(dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4626
			    "This device can not be removed at "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4627
			    "this moment. Please try again later."));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4628
			MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4629
			return (NDI_BUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4630
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4631
		MDI_CLIENT_SET_OFFLINE(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4632
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4633
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4634
		 * Unbind our relationship with the dev_info node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4635
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4636
		if (flags & NDI_DEVI_REMOVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4637
			ct->ct_dip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4638
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4639
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4640
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4641
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4642
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4644
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4645
 * mdi_pre_attach():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4646
 *		Pre attach() notification handler
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4647
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4648
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4649
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4650
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4651
mdi_pre_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4652
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4653
	/* don't support old DDI_PM_RESUME */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4654
	if ((DEVI(dip)->devi_mdi_component != MDI_COMPONENT_NONE) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4655
	    (cmd == DDI_PM_RESUME))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4656
		return (DDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4658
	return (DDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4659
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4661
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4662
 * mdi_post_attach():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4663
 *		Post attach() notification handler
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4664
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4665
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4666
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4667
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4668
mdi_post_attach(dev_info_t *dip, ddi_attach_cmd_t cmd, int error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4669
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4670
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4671
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4672
	mdi_pathinfo_t	*pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4673
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4674
	if (MDI_PHCI(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4675
		ph = i_devi_get_phci(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4676
		ASSERT(ph != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4677
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4678
		MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4679
		switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4680
		case DDI_ATTACH:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4681
			MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4682
			    "!pHCI post_attach: called %p\n", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4683
			if (error == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4684
				MDI_PHCI_SET_ATTACH(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4685
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4686
				MDI_DEBUG(1, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4687
				    "!pHCI post_attach: failed error=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4688
				    error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4689
				MDI_PHCI_SET_DETACH(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4690
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4691
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4692
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4693
		case DDI_RESUME:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4694
			MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4695
			    "!pHCI post_resume: called %p\n", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4696
			if (error == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4697
				MDI_PHCI_SET_RESUME(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4698
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4699
				MDI_DEBUG(1, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4700
				    "!pHCI post_resume: failed error=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4701
				    error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4702
				MDI_PHCI_SET_SUSPEND(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4703
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4704
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4705
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4706
		MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4707
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4709
	if (MDI_CLIENT(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4710
		ct = i_devi_get_client(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4711
		ASSERT(ct != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4712
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4713
		MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4714
		switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4715
		case DDI_ATTACH:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4716
			MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4717
			    "!Client post_attach: called %p\n", ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4718
			if (error != DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4719
				MDI_DEBUG(1, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4720
				    "!Client post_attach: failed error=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4721
				    error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4722
				MDI_CLIENT_SET_DETACH(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4723
				MDI_DEBUG(4, (CE_WARN, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4724
				    "mdi_post_attach i_mdi_pm_reset_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4725
				i_mdi_pm_reset_client(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4726
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4727
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4728
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4729
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4730
			 * Client device has successfully attached.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4731
			 * Create kstats for any pathinfo structures
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4732
			 * initially associated with this client.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4733
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4734
			for (pip = ct->ct_path_head; pip != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4735
			    pip = (mdi_pathinfo_t *)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4736
			    MDI_PI(pip)->pi_client_link) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4737
				(void) i_mdi_pi_kstat_create(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4738
				i_mdi_report_path_state(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4739
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4740
			MDI_CLIENT_SET_ATTACH(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4741
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4742
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4743
		case DDI_RESUME:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4744
			MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4745
			    "!Client post_attach: called %p\n", ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4746
			if (error == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4747
				MDI_CLIENT_SET_RESUME(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4748
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4749
				MDI_DEBUG(1, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4750
				    "!Client post_resume: failed error=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4751
				    error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4752
				MDI_CLIENT_SET_SUSPEND(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4753
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4754
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4755
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4756
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4757
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4758
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4759
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4760
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4761
 * mdi_pre_detach():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4762
 *		Pre detach notification handler
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4763
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4764
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4765
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4766
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4767
mdi_pre_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4768
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4769
	int rv = DDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4770
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4771
	if (MDI_CLIENT(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4772
		(void) i_mdi_client_pre_detach(dip, cmd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4773
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4775
	if (MDI_PHCI(dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4776
		rv = i_mdi_phci_pre_detach(dip, cmd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4777
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4779
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4780
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4781
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4782
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4783
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4784
i_mdi_phci_pre_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4785
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4786
	int		rv = DDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4787
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4788
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4789
	mdi_pathinfo_t	*pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4790
	mdi_pathinfo_t	*failed_pip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4791
	mdi_pathinfo_t	*next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4792
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4793
	ph = i_devi_get_phci(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4794
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4795
		return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4796
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4797
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4798
	MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4799
	switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4800
	case DDI_DETACH:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4801
		MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4802
		    "!pHCI pre_detach: called %p\n", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4803
		if (!MDI_PHCI_IS_OFFLINE(ph)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4804
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4805
			 * mdi_pathinfo nodes are still attached to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4806
			 * this pHCI. Fail the detach for this pHCI.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4807
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4808
			MDI_DEBUG(2, (CE_WARN, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4809
			    "!pHCI pre_detach: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4810
			    "mdi_pathinfo nodes are still attached "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4811
			    "%p\n", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4812
			rv = DDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4813
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4814
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4815
		MDI_PHCI_SET_DETACH(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4816
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4817
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4818
	case DDI_SUSPEND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4819
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4820
		 * pHCI is getting suspended.  Since mpxio client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4821
		 * devices may not be suspended at this point, to avoid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4822
		 * a potential stack overflow, it is important to suspend
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4823
		 * client devices before pHCI can be suspended.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4824
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4825
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4826
		MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4827
		    "!pHCI pre_suspend: called %p\n", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4828
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4829
		 * Suspend all the client devices accessible through this pHCI
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4830
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4831
		pip = ph->ph_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4832
		while (pip != NULL && rv == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4833
			dev_info_t *cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4834
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4835
			next =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4836
			    (mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4837
			ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4838
			i_mdi_client_lock(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4839
			cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4840
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4841
			if ((MDI_CLIENT_IS_DETACHED(ct) == 0) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4842
			    MDI_CLIENT_IS_SUSPENDED(ct) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4843
				i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4844
				if ((rv = devi_detach(cdip, DDI_SUSPEND)) !=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4845
				    DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4846
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4847
					 * Suspend of one of the client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4848
					 * device has failed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4849
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4850
					MDI_DEBUG(1, (CE_WARN, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4851
					    "!Suspend of device (%s%d) failed.",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4852
					    ddi_driver_name(cdip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4853
					    ddi_get_instance(cdip)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4854
					failed_pip = pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4855
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4856
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4857
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4858
				i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4859
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4860
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4861
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4863
		if (rv == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4864
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4865
			 * Suspend of client devices is complete. Proceed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4866
			 * with pHCI suspend.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4867
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4868
			MDI_PHCI_SET_SUSPEND(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4869
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4870
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4871
			 * Revert back all the suspended client device states
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4872
			 * to converse.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4873
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4874
			pip = ph->ph_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4875
			while (pip != failed_pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4876
				dev_info_t *cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4877
				MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4878
				next =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4879
				    (mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4880
				ct = MDI_PI(pip)->pi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4881
				i_mdi_client_lock(ct, pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4882
				cdip = ct->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4883
				MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4884
				if (MDI_CLIENT_IS_SUSPENDED(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4885
					i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4886
					(void) devi_attach(cdip, DDI_RESUME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4887
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4888
					i_mdi_client_unlock(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4889
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4890
				pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4891
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4892
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4893
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4894
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4895
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4896
		rv = DDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4897
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4898
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4899
	MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4900
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4901
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4902
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4903
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4904
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4905
i_mdi_client_pre_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4906
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4907
	int		rv = DDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4908
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4909
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4910
	ct = i_devi_get_client(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4911
	if (ct == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4912
		return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4913
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4914
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4915
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4916
	switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4917
	case DDI_DETACH:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4918
		MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4919
		    "!Client pre_detach: called %p\n", ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4920
		MDI_CLIENT_SET_DETACH(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4921
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4922
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4923
	case DDI_SUSPEND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4924
		MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4925
		    "!Client pre_suspend: called %p\n", ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4926
		MDI_CLIENT_SET_SUSPEND(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4927
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4928
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4929
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4930
		rv = DDI_FAILURE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4931
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4932
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4933
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4934
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4935
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4936
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4937
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4938
 * mdi_post_detach():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4939
 *		Post detach notification handler
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4940
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4941
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4942
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4943
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4944
mdi_post_detach(dev_info_t *dip, ddi_detach_cmd_t cmd, int error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4945
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4946
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4947
	 * Detach/Suspend of mpxio component failed. Update our state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4948
	 * too
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4949
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4950
	if (MDI_PHCI(dip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4951
		i_mdi_phci_post_detach(dip, cmd, error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4952
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4953
	if (MDI_CLIENT(dip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4954
		i_mdi_client_post_detach(dip, cmd, error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4955
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4956
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4957
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4958
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4959
i_mdi_phci_post_detach(dev_info_t *dip, ddi_detach_cmd_t cmd, int error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4960
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4961
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4962
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4963
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4964
	 * Detach/Suspend of phci component failed. Update our state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4965
	 * too
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4966
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4967
	ph = i_devi_get_phci(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4968
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4969
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4970
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4971
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4972
	MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4973
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4974
	 * Detach of pHCI failed. Restore back converse
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4975
	 * state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4976
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4977
	switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4978
	case DDI_DETACH:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4979
		MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4980
		    "!pHCI post_detach: called %p\n", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4981
		if (error != DDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4982
			MDI_PHCI_SET_ATTACH(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4983
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4985
	case DDI_SUSPEND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4986
		MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4987
		    "!pHCI post_suspend: called %p\n", ph));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4988
		if (error != DDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4989
			MDI_PHCI_SET_RESUME(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4990
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4991
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4992
	MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4993
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4994
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4995
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4996
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4997
i_mdi_client_post_detach(dev_info_t *dip, ddi_detach_cmd_t cmd, int error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4998
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4999
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5001
	ct = i_devi_get_client(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5002
	if (ct == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5003
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5004
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5005
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5006
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5007
	 * Detach of Client failed. Restore back converse
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5008
	 * state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5009
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5010
	switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5011
	case DDI_DETACH:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5012
		MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5013
		    "!Client post_detach: called %p\n", ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5014
		if (DEVI_IS_ATTACHING(ct->ct_dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5015
			MDI_DEBUG(4, (CE_NOTE, dip, "i_mdi_client_post_detach "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5016
			    "i_mdi_pm_rele_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5017
			i_mdi_pm_rele_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5018
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5019
			MDI_DEBUG(4, (CE_NOTE, dip, "i_mdi_client_post_detach "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5020
			    "i_mdi_pm_reset_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5021
			i_mdi_pm_reset_client(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5022
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5023
		if (error != DDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5024
			MDI_CLIENT_SET_ATTACH(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5025
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5026
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5027
	case DDI_SUSPEND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5028
		MDI_DEBUG(2, (CE_NOTE, dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5029
		    "!Client post_suspend: called %p\n", ct));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5030
		if (error != DDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5031
			MDI_CLIENT_SET_RESUME(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5032
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5033
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5034
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5035
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5036
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5037
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5038
 * create and install per-path (client - pHCI) statistics
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5039
 * I/O stats supported: nread, nwritten, reads, and writes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5040
 * Error stats - hard errors, soft errors, & transport errors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5041
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5042
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5043
i_mdi_pi_kstat_create(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5044
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5045
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5046
	dev_info_t *client = MDI_PI(pip)->pi_client->ct_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5047
	dev_info_t *ppath = MDI_PI(pip)->pi_phci->ph_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5048
	char ksname[KSTAT_STRLEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5049
	mdi_pathinfo_t *cpip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5050
	const char *err_postfix = ",err";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5051
	kstat_t	*kiosp, *kerrsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5052
	struct pi_errs	*nsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5053
	struct mdi_pi_kstats *mdi_statp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5054
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5055
	ASSERT(client != NULL && ppath != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5056
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5057
	ASSERT(mutex_owned(&(MDI_PI(pip)->pi_client->ct_mutex)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5058
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5059
	if (MDI_PI(pip)->pi_kstats != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5060
		return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5061
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5062
	for (cpip = MDI_PI(pip)->pi_client->ct_path_head; cpip != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5063
	    cpip = (mdi_pathinfo_t *)(MDI_PI(cpip)->pi_client_link)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5064
		if (cpip == pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5065
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5066
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5067
		 * We have found a different path with same parent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5068
		 * kstats for a given client-pHCI are common
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5069
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5070
		if ((MDI_PI(cpip)->pi_phci->ph_dip == ppath) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5071
		    (MDI_PI(cpip)->pi_kstats != NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5072
			MDI_PI(cpip)->pi_kstats->pi_kstat_ref++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5073
			MDI_PI(pip)->pi_kstats = MDI_PI(cpip)->pi_kstats;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5074
			return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5075
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5076
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5077
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5078
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5079
	 * stats are named as follows: TGTx.HBAy, e.g. "ssd0.fp0"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5080
	 * clamp length of name against max length of error kstat name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5081
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5082
	if (snprintf(ksname, KSTAT_STRLEN, "%s%d.%s%d",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5083
	    ddi_driver_name(client), ddi_get_instance(client),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5084
	    ddi_driver_name(ppath), ddi_get_instance(ppath)) >
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5085
	    (KSTAT_STRLEN - strlen(err_postfix))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5086
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5087
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5088
	if ((kiosp = kstat_create("mdi", 0, ksname, "iopath",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5089
	    KSTAT_TYPE_IO, 1, 0)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5090
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5091
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5092
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5093
	(void) strcat(ksname, err_postfix);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5094
	kerrsp = kstat_create("mdi", 0, ksname, "iopath_errors",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5095
	    KSTAT_TYPE_NAMED,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5096
	    sizeof (struct pi_errs) / sizeof (kstat_named_t), 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5097
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5098
	if (kerrsp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5099
		kstat_delete(kiosp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5100
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5101
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5102
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5103
	nsp = (struct pi_errs *)kerrsp->ks_data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5104
	kstat_named_init(&nsp->pi_softerrs, "Soft Errors", KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5105
	kstat_named_init(&nsp->pi_harderrs, "Hard Errors", KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5106
	kstat_named_init(&nsp->pi_transerrs, "Transport Errors",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5107
	    KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5108
	kstat_named_init(&nsp->pi_icnt_busy, "Interconnect Busy",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5109
	    KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5110
	kstat_named_init(&nsp->pi_icnt_errors, "Interconnect Errors",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5111
	    KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5112
	kstat_named_init(&nsp->pi_phci_rsrc, "pHCI No Resources",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5113
	    KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5114
	kstat_named_init(&nsp->pi_phci_localerr, "pHCI Local Errors",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5115
	    KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5116
	kstat_named_init(&nsp->pi_phci_invstate, "pHCI Invalid State",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5117
	    KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5118
	kstat_named_init(&nsp->pi_failedfrom, "Failed From",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5119
	    KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5120
	kstat_named_init(&nsp->pi_failedto, "Failed To", KSTAT_DATA_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5121
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5122
	mdi_statp = kmem_alloc(sizeof (*mdi_statp), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5123
	mdi_statp->pi_kstat_ref = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5124
	mdi_statp->pi_kstat_iostats = kiosp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5125
	mdi_statp->pi_kstat_errstats = kerrsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5126
	kstat_install(kiosp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5127
	kstat_install(kerrsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5128
	MDI_PI(pip)->pi_kstats = mdi_statp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5129
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5130
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5132
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5133
 * destroy per-path properties
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5134
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5135
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5136
i_mdi_pi_kstat_destroy(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5137
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5138
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5139
	struct mdi_pi_kstats *mdi_statp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5141
	if ((mdi_statp = MDI_PI(pip)->pi_kstats) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5142
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5144
	MDI_PI(pip)->pi_kstats = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5146
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5147
	 * the kstat may be shared between multiple pathinfo nodes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5148
	 * decrement this pathinfo's usage, removing the kstats
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5149
	 * themselves when the last pathinfo reference is removed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5150
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5151
	ASSERT(mdi_statp->pi_kstat_ref > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5152
	if (--mdi_statp->pi_kstat_ref != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5153
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5155
	kstat_delete(mdi_statp->pi_kstat_iostats);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5156
	kstat_delete(mdi_statp->pi_kstat_errstats);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5157
	kmem_free(mdi_statp, sizeof (*mdi_statp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5158
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5160
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5161
 * update I/O paths KSTATS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5162
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5163
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5164
mdi_pi_kstat_iosupdate(mdi_pathinfo_t *pip, struct buf *bp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5165
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5166
	kstat_t *iostatp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5167
	size_t xfer_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5168
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5169
	ASSERT(pip != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5170
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5171
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5172
	 * I/O can be driven across a path prior to having path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5173
	 * statistics available, i.e. probe(9e).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5174
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5175
	if (bp != NULL && MDI_PI(pip)->pi_kstats != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5176
		iostatp = MDI_PI(pip)->pi_kstats->pi_kstat_iostats;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5177
		xfer_cnt = bp->b_bcount - bp->b_resid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5178
		if (bp->b_flags & B_READ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5179
			KSTAT_IO_PTR(iostatp)->reads++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5180
			KSTAT_IO_PTR(iostatp)->nread += xfer_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5181
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5182
			KSTAT_IO_PTR(iostatp)->writes++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5183
			KSTAT_IO_PTR(iostatp)->nwritten += xfer_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5184
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5185
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5186
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5188
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5189
 * disable the path to a particular pHCI (pHCI specified in the phci_path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5190
 * argument) for a particular client (specified in the client_path argument).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5191
 * Disabling a path means that MPxIO will not select the disabled path for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5192
 * routing any new I/O requests.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5193
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5194
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5195
mdi_pi_disable(dev_info_t *cdip, dev_info_t *pdip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5196
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5197
	return (i_mdi_pi_enable_disable(cdip, pdip, flags, MDI_DISABLE_OP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5198
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5199
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5200
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5201
 * Enable the path to a particular pHCI (pHCI specified in the phci_path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5202
 * argument) for a particular client (specified in the client_path argument).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5203
 * Enabling a path means that MPxIO may select the enabled path for routing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5204
 * future I/O requests, subject to other path state constraints.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5205
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5207
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5208
mdi_pi_enable(dev_info_t *cdip, dev_info_t *pdip, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5209
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5210
	return (i_mdi_pi_enable_disable(cdip, pdip, flags, MDI_ENABLE_OP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5211
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5212
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5214
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5215
 * Common routine for doing enable/disable.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5216
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5217
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5218
i_mdi_pi_enable_disable(dev_info_t *cdip, dev_info_t *pdip, int flags, int op)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5219
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5221
	mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5222
	mdi_vhci_t	*vh = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5223
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5224
	mdi_pathinfo_t	*next, *pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5225
	int		found_it;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5226
	int		(*f)() = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5227
	int		rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5228
	int		sync_flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5229
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5230
	ph = i_devi_get_phci(pdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5231
	MDI_DEBUG(5, (CE_NOTE, NULL, "!i_mdi_pi_enable_disable:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5232
		" Operation = %d pdip = %p cdip = %p\n", op, pdip, cdip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5233
	if (ph == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5234
		MDI_DEBUG(1, (CE_NOTE, NULL, "!i_mdi_pi_enable_disable:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5235
			" failed. ph = NULL operation = %d\n", op));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5236
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5237
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5239
	if ((op != MDI_ENABLE_OP) && (op != MDI_DISABLE_OP)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5240
		MDI_DEBUG(1, (CE_NOTE, NULL, "!i_mdi_pi_enable_disable:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5241
			" Invalid operation = %d\n", op));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5242
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5243
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5245
	sync_flag = (flags << 8) & 0xf00;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5247
	vh = ph->ph_vhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5248
	f = vh->vh_ops->vo_pi_state_change;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5250
	if (cdip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5251
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5252
		 * Need to mark the Phci as enabled/disabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5253
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5254
		MDI_DEBUG(3, (CE_NOTE, NULL, "!i_mdi_pi_enable_disable:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5255
		"Operation %d for the phci\n", op));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5256
		MDI_PHCI_LOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5257
		switch (flags) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5258
			case USER_DISABLE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5259
				if (op == MDI_DISABLE_OP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5260
					MDI_PHCI_SET_USER_DISABLE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5261
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5262
					MDI_PHCI_SET_USER_ENABLE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5263
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5264
			case DRIVER_DISABLE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5265
				if (op == MDI_DISABLE_OP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5266
					MDI_PHCI_SET_DRV_DISABLE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5267
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5268
					MDI_PHCI_SET_DRV_ENABLE(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5269
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5270
			case DRIVER_DISABLE_TRANSIENT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5271
				if (op == MDI_DISABLE_OP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5272
					MDI_PHCI_SET_DRV_DISABLE_TRANSIENT(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5273
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5274
					MDI_PHCI_SET_DRV_ENABLE_TRANSIENT(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5275
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5276
			default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5277
				MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5278
				MDI_DEBUG(1, (CE_NOTE, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5279
				"!i_mdi_pi_enable_disable:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5280
				" Invalid flag argument= %d\n", flags));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5281
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5282
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5283
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5284
		 * Phci has been disabled. Now try to enable/disable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5285
		 * path info's to each client.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5286
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5287
		pip = ph->ph_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5288
		while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5289
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5290
			 * Do a callback into the mdi consumer to let it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5291
			 * know that path is about to be enabled/disabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5292
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5293
			if (f != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5294
				rv = (*f)(vh->vh_dip, pip, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5295
					MDI_PI_EXT_STATE(pip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5296
					MDI_EXT_STATE_CHANGE | sync_flag |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5297
					op | MDI_BEFORE_STATE_CHANGE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5298
				if (rv != MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5299
				MDI_DEBUG(2, (CE_WARN, vh->vh_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5300
				"!vo_pi_state_change: failed rv = %x", rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5301
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5302
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5304
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5305
			next =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5306
				(mdi_pathinfo_t *)MDI_PI(pip)->pi_phci_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5307
			switch (flags) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5308
			case USER_DISABLE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5309
				if (op == MDI_DISABLE_OP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5310
					MDI_PI_SET_USER_DISABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5311
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5312
					MDI_PI_SET_USER_ENABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5313
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5314
			case DRIVER_DISABLE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5315
				if (op == MDI_DISABLE_OP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5316
					MDI_PI_SET_DRV_DISABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5317
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5318
					MDI_PI_SET_DRV_ENABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5319
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5320
			case DRIVER_DISABLE_TRANSIENT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5321
				if (op == MDI_DISABLE_OP && rv == MDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5322
					MDI_PI_SET_DRV_DISABLE_TRANS(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5323
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5324
					MDI_PI_SET_DRV_ENABLE_TRANS(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5325
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5326
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5327
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5328
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5329
			 * Do a callback into the mdi consumer to let it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5330
			 * know that path is now enabled/disabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5331
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5332
			if (f != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5333
				rv = (*f)(vh->vh_dip, pip, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5334
					MDI_PI_EXT_STATE(pip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5335
					MDI_EXT_STATE_CHANGE | sync_flag |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5336
					op | MDI_AFTER_STATE_CHANGE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5337
				if (rv != MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5338
				MDI_DEBUG(2, (CE_WARN, vh->vh_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5339
				"!vo_pi_state_change: failed rv = %x", rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5340
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5341
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5342
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5343
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5344
		MDI_PHCI_UNLOCK(ph);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5345
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5347
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5348
		 * Disable a specific client.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5349
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5350
		ct = i_devi_get_client(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5351
		if (ct == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5352
			MDI_DEBUG(1, (CE_NOTE, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5353
			"!i_mdi_pi_enable_disable:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5354
			" failed. ct = NULL operation = %d\n", op));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5355
			return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5356
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5357
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5358
		MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5359
		pip = ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5360
		found_it = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5361
		while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5362
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5363
			next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5364
			if (MDI_PI(pip)->pi_phci == ph) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5365
				MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5366
				found_it = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5367
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5368
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5369
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5370
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5371
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5372
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5373
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5374
		if (found_it == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5375
			MDI_DEBUG(1, (CE_NOTE, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5376
			"!i_mdi_pi_enable_disable:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5377
			" failed. Could not find corresponding pip\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5378
			return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5379
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5380
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5381
		 * Do a callback into the mdi consumer to let it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5382
		 * know that path is about to get enabled/disabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5383
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5384
		if (f != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5385
			rv = (*f)(vh->vh_dip, pip, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5386
				MDI_PI_EXT_STATE(pip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5387
				MDI_EXT_STATE_CHANGE | sync_flag |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5388
				op | MDI_BEFORE_STATE_CHANGE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5389
			if (rv != MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5390
				MDI_DEBUG(2, (CE_WARN, vh->vh_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5391
				"!vo_pi_state_change: failed rv = %x", rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5392
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5393
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5394
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5395
		switch (flags) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5396
			case USER_DISABLE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5397
				if (op == MDI_DISABLE_OP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5398
					MDI_PI_SET_USER_DISABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5399
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5400
					MDI_PI_SET_USER_ENABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5401
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5402
			case DRIVER_DISABLE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5403
				if (op == MDI_DISABLE_OP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5404
					MDI_PI_SET_DRV_DISABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5405
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5406
					MDI_PI_SET_DRV_ENABLE(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5407
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5408
			case DRIVER_DISABLE_TRANSIENT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5409
				if (op == MDI_DISABLE_OP && rv == MDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5410
					MDI_PI_SET_DRV_DISABLE_TRANS(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5411
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5412
					MDI_PI_SET_DRV_ENABLE_TRANS(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5413
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5414
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5415
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5416
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5417
		 * Do a callback into the mdi consumer to let it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5418
		 * know that path is now enabled/disabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5419
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5420
		if (f != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5421
			rv = (*f)(vh->vh_dip, pip, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5422
				MDI_PI_EXT_STATE(pip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5423
				MDI_EXT_STATE_CHANGE | sync_flag |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5424
				op | MDI_AFTER_STATE_CHANGE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5425
			if (rv != MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5426
				MDI_DEBUG(2, (CE_WARN, vh->vh_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5427
				"!vo_pi_state_change: failed rv = %x", rv));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5428
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5429
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5430
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5432
	MDI_DEBUG(5, (CE_NOTE, NULL, "!i_mdi_pi_enable_disable:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5433
		" Returning success pdip = %p cdip = %p\n", op, pdip, cdip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5434
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5435
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5436
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5437
/*ARGSUSED3*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5438
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5439
mdi_devi_config_one(dev_info_t *pdip, char *devnm, dev_info_t **cdipp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5440
    int flags, clock_t timeout)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5441
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5442
	mdi_pathinfo_t *pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5443
	dev_info_t *dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5444
	clock_t interval = drv_usectohz(100000);	/* 0.1 sec */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5445
	char *paddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5446
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5447
	MDI_DEBUG(2, (CE_NOTE, NULL, "configure device %s", devnm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5449
	if (!MDI_PHCI(pdip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5450
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5452
	paddr = strchr(devnm, '@');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5453
	if (paddr == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5454
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5455
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5456
	paddr++;	/* skip '@' */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5457
	pip = mdi_pi_find(pdip, NULL, paddr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5458
	while (pip == NULL && timeout > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5459
		if (interval > timeout)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5460
			interval = timeout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5461
		if (flags & NDI_DEVI_DEBUG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5462
			cmn_err(CE_CONT, "%s%d: %s timeout %ld %ld\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5463
			    ddi_driver_name(pdip), ddi_get_instance(pdip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5464
			    paddr, interval, timeout);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5465
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5466
		delay(interval);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5467
		timeout -= interval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5468
		interval += interval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5469
		pip = mdi_pi_find(pdip, NULL, paddr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5470
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5471
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5472
	if (pip == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5473
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5474
	dip = mdi_pi_get_client(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5475
	if (ndi_devi_online(dip, flags) != NDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5476
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5477
	*cdipp = dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5478
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5479
	/* TODO: holding should happen inside search functions */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5480
	ndi_hold_devi(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5481
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5482
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5483
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5484
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5485
 * Ensure phci powered up
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5486
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5487
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5488
i_mdi_pm_hold_pip(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5489
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5490
	dev_info_t	*ph_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5491
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5492
	ASSERT(pip != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5493
	ASSERT(MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5495
	if (MDI_PI(pip)->pi_pm_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5496
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5497
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5498
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5499
	ph_dip = mdi_pi_get_phci(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5500
	MDI_DEBUG(4, (CE_NOTE, ph_dip, "i_mdi_pm_hold_pip for %s%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5501
	    ddi_get_name(ph_dip), ddi_get_instance(ph_dip)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5502
	if (ph_dip == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5503
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5504
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5505
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5506
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5507
	MDI_DEBUG(4, (CE_NOTE, ph_dip, "kidsupcnt was %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5508
	    DEVI(ph_dip)->devi_pm_kidsupcnt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5509
	pm_hold_power(ph_dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5510
	MDI_DEBUG(4, (CE_NOTE, ph_dip, "kidsupcnt is %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5511
	    DEVI(ph_dip)->devi_pm_kidsupcnt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5512
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5513
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5514
	MDI_PI(pip)->pi_pm_held = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5515
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5516
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5517
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5518
 * Allow phci powered down
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5519
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5520
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5521
i_mdi_pm_rele_pip(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5522
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5523
	dev_info_t	*ph_dip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5524
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5525
	ASSERT(pip != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5526
	ASSERT(MUTEX_HELD(&MDI_PI(pip)->pi_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5527
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5528
	if (MDI_PI(pip)->pi_pm_held == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5529
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5530
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5531
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5532
	ph_dip = mdi_pi_get_phci(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5533
	ASSERT(ph_dip != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5534
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5535
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5536
	MDI_DEBUG(4, (CE_NOTE, ph_dip, "i_mdi_pm_rele_pip for %s%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5537
	    ddi_get_name(ph_dip), ddi_get_instance(ph_dip)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5538
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5539
	MDI_DEBUG(4, (CE_NOTE, ph_dip, "kidsupcnt was %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5540
	    DEVI(ph_dip)->devi_pm_kidsupcnt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5541
	pm_rele_power(ph_dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5542
	MDI_DEBUG(4, (CE_NOTE, ph_dip, "kidsupcnt is %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5543
	    DEVI(ph_dip)->devi_pm_kidsupcnt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5545
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5546
	MDI_PI(pip)->pi_pm_held = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5547
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5548
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5549
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5550
i_mdi_pm_hold_client(mdi_client_t *ct, int incr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5551
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5552
	ASSERT(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5553
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5554
	ct->ct_power_cnt += incr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5555
	MDI_DEBUG(4, (CE_NOTE, ct->ct_dip, "i_mdi_pm_hold_client "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5556
	    "ct_power_cnt = %d incr = %d\n", ct->ct_power_cnt, incr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5557
	ASSERT(ct->ct_power_cnt >= 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5558
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5559
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5560
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5561
i_mdi_rele_all_phci(mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5562
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5563
	mdi_pathinfo_t  *pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5564
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5565
	ASSERT(mutex_owned(&ct->ct_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5566
	pip = (mdi_pathinfo_t *)ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5567
	while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5568
		mdi_hold_path(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5569
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5570
		i_mdi_pm_rele_pip(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5571
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5572
		mdi_rele_path(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5573
		pip = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5574
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5575
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5576
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5577
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5578
i_mdi_pm_rele_client(mdi_client_t *ct, int decr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5579
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5580
	ASSERT(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5581
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5582
	if (i_ddi_node_state(ct->ct_dip) >= DS_READY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5583
		ct->ct_power_cnt -= decr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5584
		MDI_DEBUG(4, (CE_NOTE, ct->ct_dip, "i_mdi_pm_rele_client "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5585
		    "ct_power_cnt = %d decr = %d\n", ct->ct_power_cnt, decr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5586
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5587
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5588
	ASSERT(ct->ct_power_cnt >= 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5589
	if (ct->ct_power_cnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5590
		i_mdi_rele_all_phci(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5591
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5592
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5593
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5595
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5596
i_mdi_pm_reset_client(mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5597
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5598
	MDI_DEBUG(4, (CE_NOTE, ct->ct_dip, "i_mdi_pm_reset_client "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5599
	    "ct_power_cnt = %d\n", ct->ct_power_cnt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5600
	ct->ct_power_cnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5601
	i_mdi_rele_all_phci(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5602
	ct->ct_powercnt_reset = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5603
	ct->ct_powercnt_held = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5604
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5605
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5606
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5607
i_mdi_pm_hold_all_phci(mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5608
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5609
	mdi_pathinfo_t  *pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5610
	ASSERT(mutex_owned(&ct->ct_mutex));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5611
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5612
	pip = (mdi_pathinfo_t *)ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5613
	while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5614
		mdi_hold_path(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5615
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5616
		i_mdi_pm_hold_pip(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5617
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5618
		mdi_rele_path(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5619
		pip = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5620
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5621
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5623
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5624
i_mdi_power_one_phci(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5625
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5626
	int		ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5627
	dev_info_t	*ph_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5628
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5629
	MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5630
	i_mdi_pm_hold_pip(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5631
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5632
	ph_dip = mdi_pi_get_phci(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5633
	MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5635
	/* bring all components of phci to full power */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5636
	MDI_DEBUG(4, (CE_NOTE, ph_dip, "i_mdi_power_one_phci "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5637
	    "pm_powerup for %s%d\n", ddi_get_name(ph_dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5638
	    ddi_get_instance(ph_dip)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5639
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5640
	ret = pm_powerup(ph_dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5641
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5642
	if (ret == DDI_FAILURE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5643
		MDI_DEBUG(4, (CE_NOTE, ph_dip, "i_mdi_power_one_phci "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5644
		    "pm_powerup FAILED for %s%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5645
		    ddi_get_name(ph_dip), ddi_get_instance(ph_dip)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5646
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5647
		MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5648
		i_mdi_pm_rele_pip(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5649
		MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5650
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5651
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5652
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5653
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5654
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5655
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5656
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5657
i_mdi_power_all_phci(mdi_client_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5658
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5659
	mdi_pathinfo_t  *pip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5660
	int		succeeded = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5661
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5662
	pip = (mdi_pathinfo_t *)ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5663
	while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5664
		mdi_hold_path(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5665
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5666
		if (i_mdi_power_one_phci(pip) == MDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5667
			succeeded = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5668
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5669
		ASSERT(ct == MDI_PI(pip)->pi_client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5670
		MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5671
		mdi_rele_path(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5672
		pip = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5673
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5674
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5675
	return (succeeded ? MDI_SUCCESS : MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5676
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5677
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5678
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5679
 * mdi_bus_power():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5680
 *		1. Place the phci(s) into powered up state so that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5681
 *		   client can do power management
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5682
 *		2. Ensure phci powered up as client power managing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5683
 * Return Values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5684
 *		MDI_SUCCESS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5685
 *		MDI_FAILURE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5686
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5687
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5688
mdi_bus_power(dev_info_t *parent, void *impl_arg, pm_bus_power_op_t op,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5689
    void *arg, void *result)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5690
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5691
	int			ret = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5692
	pm_bp_child_pwrchg_t	*bpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5693
	mdi_client_t		*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5694
	dev_info_t		*cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5695
	pm_bp_has_changed_t	*bphc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5696
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5697
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5698
	 * BUS_POWER_NOINVOL not supported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5699
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5700
	if (op == BUS_POWER_NOINVOL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5701
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5702
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5703
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5704
	 * ignore other OPs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5705
	 * return quickly to save cou cycles on the ct processing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5706
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5707
	switch (op) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5708
	case BUS_POWER_PRE_NOTIFICATION:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5709
	case BUS_POWER_POST_NOTIFICATION:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5710
		bpc = (pm_bp_child_pwrchg_t *)arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5711
		cdip = bpc->bpc_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5712
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5713
	case BUS_POWER_HAS_CHANGED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5714
		bphc = (pm_bp_has_changed_t *)arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5715
		cdip = bphc->bphc_dip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5716
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5717
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5718
		return (pm_busop_bus_power(parent, impl_arg, op, arg, result));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5719
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5720
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5721
	ASSERT(MDI_CLIENT(cdip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5722
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5723
	ct = i_devi_get_client(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5724
	if (ct == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5725
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5726
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5727
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5728
	 * wait till the mdi_pathinfo node state change are processed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5729
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5730
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5731
	switch (op) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5732
	case BUS_POWER_PRE_NOTIFICATION:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5733
		MDI_DEBUG(4, (CE_NOTE, bpc->bpc_dip, "mdi_bus_power "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5734
		    "BUS_POWER_PRE_NOTIFICATION:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5735
		    "%s@%s, olevel=%d, nlevel=%d, comp=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5736
		    PM_NAME(bpc->bpc_dip), PM_ADDR(bpc->bpc_dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5737
		    bpc->bpc_olevel, bpc->bpc_nlevel, bpc->bpc_comp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5738
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5739
		/* serialize power level change per client */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5740
		while (MDI_CLIENT_IS_POWER_TRANSITION(ct))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5741
			cv_wait(&ct->ct_powerchange_cv, &ct->ct_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5742
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5743
		MDI_CLIENT_SET_POWER_TRANSITION(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5744
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5745
		if (ct->ct_power_cnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5746
			ret = i_mdi_power_all_phci(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5747
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5748
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5749
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5750
		 * if new_level > 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5751
		 *	- hold phci(s)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5752
		 *	- power up phci(s) if not already
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5753
		 * ignore power down
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5754
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5755
		if (bpc->bpc_nlevel > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5756
			if (!DEVI_IS_ATTACHING(ct->ct_dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5757
				MDI_DEBUG(4, (CE_NOTE, bpc->bpc_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5758
				    "mdi_bus_power i_mdi_pm_hold_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5759
				i_mdi_pm_hold_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5760
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5761
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5762
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5763
	case BUS_POWER_POST_NOTIFICATION:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5764
		MDI_DEBUG(4, (CE_NOTE, bpc->bpc_dip, "mdi_bus_power "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5765
		    "BUS_POWER_POST_NOTIFICATION:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5766
		    "%s@%s, olevel=%d, nlevel=%d, comp=%d result=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5767
		    PM_NAME(bpc->bpc_dip), PM_ADDR(bpc->bpc_dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5768
		    bpc->bpc_olevel, bpc->bpc_nlevel, bpc->bpc_comp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5769
		    *(int *)result));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5770
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5771
		if (*(int *)result == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5772
			if (bpc->bpc_nlevel > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5773
				MDI_CLIENT_SET_POWER_UP(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5774
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5775
				MDI_CLIENT_SET_POWER_DOWN(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5776
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5777
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5779
		/* release the hold we did in pre-notification */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5780
		if (bpc->bpc_nlevel > 0 && (*(int *)result != DDI_SUCCESS) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5781
		    !DEVI_IS_ATTACHING(ct->ct_dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5782
			MDI_DEBUG(4, (CE_NOTE, bpc->bpc_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5783
			    "mdi_bus_power i_mdi_pm_rele_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5784
			i_mdi_pm_rele_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5785
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5786
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5787
		if (bpc->bpc_nlevel == 0 && (*(int *)result == DDI_SUCCESS)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5788
			/* another thread might started attaching */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5789
			if (DEVI_IS_ATTACHING(ct->ct_dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5790
				MDI_DEBUG(4, (CE_NOTE, bpc->bpc_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5791
				    "mdi_bus_power i_mdi_pm_rele_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5792
				i_mdi_pm_rele_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5793
			/* detaching has been taken care in pm_post_unconfig */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5794
			} else if (!DEVI_IS_DETACHING(ct->ct_dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5795
				MDI_DEBUG(4, (CE_NOTE, bpc->bpc_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5796
				    "mdi_bus_power i_mdi_pm_reset_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5797
				i_mdi_pm_reset_client(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5798
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5799
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5800
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5801
		MDI_CLIENT_CLEAR_POWER_TRANSITION(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5802
		cv_broadcast(&ct->ct_powerchange_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5803
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5804
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5805
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5806
	/* need to do more */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5807
	case BUS_POWER_HAS_CHANGED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5808
		MDI_DEBUG(4, (CE_NOTE, bphc->bphc_dip, "mdi_bus_power "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5809
		    "BUS_POWER_HAS_CHANGED:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5810
		    "%s@%s, olevel=%d, nlevel=%d, comp=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5811
		    PM_NAME(bphc->bphc_dip), PM_ADDR(bphc->bphc_dip),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5812
		    bphc->bphc_olevel, bphc->bphc_nlevel, bphc->bphc_comp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5813
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5814
		if (bphc->bphc_nlevel > 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5815
		    bphc->bphc_nlevel > bphc->bphc_olevel) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5816
			if (ct->ct_power_cnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5817
				ret = i_mdi_power_all_phci(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5818
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5819
			MDI_DEBUG(4, (CE_NOTE, bphc->bphc_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5820
			    "mdi_bus_power i_mdi_pm_hold_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5821
			i_mdi_pm_hold_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5822
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5823
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5824
		if (bphc->bphc_nlevel == 0 && bphc->bphc_olevel != -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5825
			MDI_DEBUG(4, (CE_NOTE, bphc->bphc_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5826
			    "mdi_bus_power i_mdi_pm_rele_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5827
			i_mdi_pm_rele_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5828
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5829
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5830
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5831
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5832
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5833
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5834
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5835
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5836
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5837
i_mdi_pm_pre_config_one(dev_info_t *child)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5838
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5839
	int		ret = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5840
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5841
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5842
	ct = i_devi_get_client(child);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5843
	if (ct == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5844
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5845
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5846
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5847
	while (MDI_CLIENT_IS_POWER_TRANSITION(ct))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5848
		cv_wait(&ct->ct_powerchange_cv, &ct->ct_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5850
	if (!MDI_CLIENT_IS_FAILED(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5851
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5852
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5853
		    "i_mdi_pm_pre_config_one already configured\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5854
		return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5855
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5856
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5857
	if (ct->ct_powercnt_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5858
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5859
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5860
		    "i_mdi_pm_pre_config_one ALREADY held\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5861
		return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5862
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5863
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5864
	if (ct->ct_power_cnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5865
		ret = i_mdi_power_all_phci(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5866
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5867
	MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5868
	    "i_mdi_pm_pre_config_one i_mdi_pm_hold_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5869
	i_mdi_pm_hold_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5870
	ct->ct_powercnt_held = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5871
	ct->ct_powercnt_reset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5872
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5873
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5874
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5875
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5876
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5877
i_mdi_pm_pre_config(dev_info_t *parent, dev_info_t *child)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5878
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5879
	int			ret = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5880
	dev_info_t		*cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5881
	int			circ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5882
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5883
	ASSERT(MDI_VHCI(parent));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5884
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5885
	/* ndi_devi_config_one */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5886
	if (child) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5887
		return (i_mdi_pm_pre_config_one(child));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5888
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5889
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5890
	/* devi_config_common */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5891
	ndi_devi_enter(parent, &circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5892
	cdip = ddi_get_child(parent);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5893
	while (cdip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5894
		dev_info_t *next = ddi_get_next_sibling(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5895
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5896
		ret = i_mdi_pm_pre_config_one(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5897
		if (ret != MDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5898
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5899
		cdip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5900
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5901
	ndi_devi_exit(parent, circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5902
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5903
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5904
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5905
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5906
i_mdi_pm_pre_unconfig_one(dev_info_t *child, int *held, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5907
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5908
	int		ret = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5909
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5910
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5911
	ct = i_devi_get_client(child);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5912
	if (ct == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5913
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5914
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5915
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5916
	while (MDI_CLIENT_IS_POWER_TRANSITION(ct))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5917
		cv_wait(&ct->ct_powerchange_cv, &ct->ct_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5918
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5919
	if (i_ddi_node_state(ct->ct_dip) < DS_READY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5920
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5921
		    "i_mdi_pm_pre_unconfig node detached already\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5922
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5923
		return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5924
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5925
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5926
	if (MDI_CLIENT_IS_POWERED_DOWN(ct) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5927
	    (flags & NDI_AUTODETACH)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5928
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5929
		    "i_mdi_pm_pre_unconfig auto-modunload\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5930
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5931
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5932
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5933
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5934
	if (ct->ct_powercnt_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5935
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5936
		    "i_mdi_pm_pre_unconfig ct_powercnt_held\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5937
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5938
		*held = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5939
		return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5940
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5941
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5942
	if (ct->ct_power_cnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5943
		ret = i_mdi_power_all_phci(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5944
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5945
	MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5946
	    "i_mdi_pm_pre_unconfig i_mdi_pm_hold_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5947
	i_mdi_pm_hold_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5948
	ct->ct_powercnt_held = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5949
	ct->ct_powercnt_reset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5950
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5951
	if (ret == MDI_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5952
		*held = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5953
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5954
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5955
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5956
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5957
i_mdi_pm_pre_unconfig(dev_info_t *parent, dev_info_t *child, int *held,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5958
    int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5959
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5960
	int			ret = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5961
	dev_info_t		*cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5962
	int			circ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5964
	ASSERT(MDI_VHCI(parent));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5965
	*held = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5966
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5967
	/* ndi_devi_unconfig_one */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5968
	if (child) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5969
		return (i_mdi_pm_pre_unconfig_one(child, held, flags));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5970
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5971
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5972
	/* devi_unconfig_common */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5973
	ndi_devi_enter(parent, &circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5974
	cdip = ddi_get_child(parent);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5975
	while (cdip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5976
		dev_info_t *next = ddi_get_next_sibling(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5977
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5978
		ret = i_mdi_pm_pre_unconfig_one(cdip, held, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5979
		cdip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5980
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5981
	ndi_devi_exit(parent, circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5982
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5983
	if (*held)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5984
		ret = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5985
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5986
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5987
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5988
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5989
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5990
i_mdi_pm_post_config_one(dev_info_t *child)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5991
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5992
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5993
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5994
	ct = i_devi_get_client(child);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5995
	if (ct == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5996
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5997
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5998
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5999
	while (MDI_CLIENT_IS_POWER_TRANSITION(ct))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6000
		cv_wait(&ct->ct_powerchange_cv, &ct->ct_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6001
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6002
	if (ct->ct_powercnt_reset || !ct->ct_powercnt_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6003
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6004
		    "i_mdi_pm_post_config_one NOT held\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6005
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6006
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6007
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6008
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6009
	/* client has not been updated */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6010
	if (MDI_CLIENT_IS_FAILED(ct)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6011
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6012
		    "i_mdi_pm_post_config_one NOT configured\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6013
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6014
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6015
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6016
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6017
	/* another thread might have powered it down or detached it */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6018
	if ((MDI_CLIENT_IS_POWERED_DOWN(ct) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6019
	    !DEVI_IS_ATTACHING(ct->ct_dip)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6020
	    (i_ddi_node_state(ct->ct_dip) < DS_READY &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6021
	    !DEVI_IS_ATTACHING(ct->ct_dip))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6022
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6023
		    "i_mdi_pm_post_config i_mdi_pm_reset_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6024
		i_mdi_pm_reset_client(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6025
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6026
		mdi_pathinfo_t	*pip, *next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6027
		int	valid_path_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6028
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6029
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6030
		    "i_mdi_pm_post_config i_mdi_pm_rele_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6031
		pip = ct->ct_path_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6032
		while (pip != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6033
			MDI_PI_LOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6034
			next = (mdi_pathinfo_t *)MDI_PI(pip)->pi_client_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6035
			if ((MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_MASK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6036
				== MDI_PATHINFO_STATE_ONLINE ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6037
			    (MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_MASK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6038
				== MDI_PATHINFO_STATE_STANDBY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6039
				valid_path_count ++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6040
			MDI_PI_UNLOCK(pip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6041
			pip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6042
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6043
		i_mdi_pm_rele_client(ct, valid_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6044
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6045
	ct->ct_powercnt_held = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6046
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6047
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6048
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6049
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6050
i_mdi_pm_post_config(dev_info_t *parent, dev_info_t *child)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6051
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6052
	int		circ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6053
	dev_info_t	*cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6054
	ASSERT(MDI_VHCI(parent));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6055
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6056
	/* ndi_devi_config_one */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6057
	if (child) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6058
		i_mdi_pm_post_config_one(child);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6059
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6060
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6061
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6062
	/* devi_config_common */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6063
	ndi_devi_enter(parent, &circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6064
	cdip = ddi_get_child(parent);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6065
	while (cdip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6066
		dev_info_t *next = ddi_get_next_sibling(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6067
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6068
		i_mdi_pm_post_config_one(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6069
		cdip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6070
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6071
	ndi_devi_exit(parent, circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6072
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6073
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6074
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6075
i_mdi_pm_post_unconfig_one(dev_info_t *child)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6076
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6077
	mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6078
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6079
	ct = i_devi_get_client(child);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6080
	if (ct == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6081
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6082
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6083
	MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6084
	while (MDI_CLIENT_IS_POWER_TRANSITION(ct))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6085
		cv_wait(&ct->ct_powerchange_cv, &ct->ct_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6086
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6087
	if (!ct->ct_powercnt_held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6088
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6089
		    "i_mdi_pm_post_unconfig NOT held\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6090
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6091
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6092
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6093
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6094
	/* failure detaching or another thread just attached it */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6095
	if ((MDI_CLIENT_IS_POWERED_DOWN(ct) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6096
	    i_ddi_node_state(ct->ct_dip) == DS_READY) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6097
	    (i_ddi_node_state(ct->ct_dip) != DS_READY &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6098
	    !DEVI_IS_ATTACHING(ct->ct_dip))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6099
		MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6100
		    "i_mdi_pm_post_unconfig i_mdi_pm_reset_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6101
		i_mdi_pm_reset_client(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6102
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6104
	MDI_DEBUG(4, (CE_NOTE, child,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6105
	    "i_mdi_pm_post_unconfig not changed\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6106
	MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6107
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6108
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6109
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6110
i_mdi_pm_post_unconfig(dev_info_t *parent, dev_info_t *child, int held)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6111
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6112
	int			circ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6113
	dev_info_t		*cdip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6115
	ASSERT(MDI_VHCI(parent));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6116
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6117
	if (!held) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6118
		MDI_DEBUG(4, (CE_NOTE, parent,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6119
		    "i_mdi_pm_post_unconfig held = %d\n", held));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6120
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6121
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6122
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6123
	if (child) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6124
		i_mdi_pm_post_unconfig_one(child);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6125
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6126
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6128
	ndi_devi_enter(parent, &circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6129
	cdip = ddi_get_child(parent);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6130
	while (cdip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6131
		dev_info_t *next = ddi_get_next_sibling(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6133
		i_mdi_pm_post_unconfig_one(cdip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6134
		cdip = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6135
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6136
	ndi_devi_exit(parent, circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6137
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6138
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6139
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6140
mdi_power(dev_info_t *vdip, mdi_pm_op_t op, void *args, char *devnm, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6141
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6142
	int			circ, ret = MDI_SUCCESS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6143
	dev_info_t		*client_dip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6144
	mdi_client_t		*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6146
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6147
	 * Handling ndi_devi_config_one and ndi_devi_unconfig_one.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6148
	 * Power up pHCI for the named client device.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6149
	 * Note: Before the client is enumerated under vhci by phci,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6150
	 * client_dip can be NULL. Then proceed to power up all the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6151
	 * pHCIs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6152
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6153
	if (devnm != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6154
		ndi_devi_enter(vdip, &circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6155
		client_dip = ndi_devi_findchild(vdip, devnm);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6156
		ndi_devi_exit(vdip, circ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6157
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6159
	MDI_DEBUG(4, (CE_NOTE, vdip, "mdi_power op = %d\n", op));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6160
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6161
	switch (op) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6162
	case MDI_PM_PRE_CONFIG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6163
		ret = i_mdi_pm_pre_config(vdip, client_dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6165
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6166
	case MDI_PM_PRE_UNCONFIG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6167
		ret = i_mdi_pm_pre_unconfig(vdip, client_dip, (int *)args,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6168
		    flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6170
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6171
	case MDI_PM_POST_CONFIG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6172
		i_mdi_pm_post_config(vdip, client_dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6174
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6175
	case MDI_PM_POST_UNCONFIG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6176
		i_mdi_pm_post_unconfig(vdip, client_dip, *(int *)args);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6177
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6178
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6179
	case MDI_PM_HOLD_POWER:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6180
	case MDI_PM_RELE_POWER:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6181
		ASSERT(args);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6183
		client_dip = (dev_info_t *)args;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6184
		ASSERT(MDI_CLIENT(client_dip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6186
		ct = i_devi_get_client(client_dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6187
		MDI_CLIENT_LOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6189
		if (op == MDI_PM_HOLD_POWER) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6190
			if (ct->ct_power_cnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6191
				(void) i_mdi_power_all_phci(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6192
				MDI_DEBUG(4, (CE_NOTE, client_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6193
				    "mdi_power i_mdi_pm_hold_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6194
				i_mdi_pm_hold_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6195
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6196
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6197
			if (DEVI_IS_ATTACHING(ct->ct_dip)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6198
				MDI_DEBUG(4, (CE_NOTE, client_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6199
				    "mdi_power i_mdi_pm_rele_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6200
				i_mdi_pm_rele_client(ct, ct->ct_path_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6201
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6202
				MDI_DEBUG(4, (CE_NOTE, client_dip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6203
				    "mdi_power i_mdi_pm_reset_client\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6204
				i_mdi_pm_reset_client(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6205
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6206
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6208
		MDI_CLIENT_UNLOCK(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6209
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6210
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6211
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6212
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6214
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6215
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6217
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6218
mdi_component_is_vhci(dev_info_t *dip, const char **mdi_class)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6219
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6220
	mdi_vhci_t *vhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6222
	if (!MDI_VHCI(dip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6223
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6225
	if (mdi_class) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6226
		vhci = DEVI(dip)->devi_mdi_xhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6227
		ASSERT(vhci);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6228
		*mdi_class = vhci->vh_class;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6229
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6231
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6232
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6234
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6235
mdi_component_is_phci(dev_info_t *dip, const char **mdi_class)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6236
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6237
	mdi_phci_t *phci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6239
	if (!MDI_PHCI(dip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6240
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6242
	if (mdi_class) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6243
		phci = DEVI(dip)->devi_mdi_xhci;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6244
		ASSERT(phci);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6245
		*mdi_class = phci->ph_vhci->vh_class;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6246
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6247
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6248
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6249
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6250
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6251
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6252
mdi_component_is_client(dev_info_t *dip, const char **mdi_class)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6253
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6254
	mdi_client_t *client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6256
	if (!MDI_CLIENT(dip))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6257
		return (MDI_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6258
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6259
	if (mdi_class) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6260
		client = DEVI(dip)->devi_mdi_client;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6261
		ASSERT(client);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6262
		*mdi_class = client->ct_vhci->vh_class;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6263
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6265
	return (MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6266
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6267
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6268
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6269
mdi_client_get_vhci_private(dev_info_t *dip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6270
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6271
	ASSERT(mdi_component_is_client(dip, NULL) == MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6272
	if (mdi_component_is_client(dip, NULL) == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6273
		mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6274
		ct = i_devi_get_client(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6275
		return (ct->ct_vprivate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6276
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6277
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6278
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6280
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6281
mdi_client_set_vhci_private(dev_info_t *dip, void *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6282
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6283
	ASSERT(mdi_component_is_client(dip, NULL) == MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6284
	if (mdi_component_is_client(dip, NULL) == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6285
		mdi_client_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6286
		ct = i_devi_get_client(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6287
		ct->ct_vprivate = data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6288
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6289
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6290
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6291
 * mdi_pi_get_vhci_private():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6292
 *		Get the vhci private information associated with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6293
 *		mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6294
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6295
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6296
mdi_pi_get_vhci_private(mdi_pathinfo_t *pip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6297
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6298
	caddr_t	vprivate = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6299
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6300
		vprivate = MDI_PI(pip)->pi_vprivate;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6301
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6302
	return (vprivate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6303
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6304
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6305
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6306
 * mdi_pi_set_vhci_private():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6307
 *		Set the vhci private information in the mdi_pathinfo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6308
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6309
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6310
mdi_pi_set_vhci_private(mdi_pathinfo_t *pip, void *priv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6311
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6312
	if (pip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6313
		MDI_PI(pip)->pi_vprivate = priv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6314
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6315
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6316
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6317
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6318
 * mdi_phci_get_vhci_private():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6319
 *		Get the vhci private information associated with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6320
 *		mdi_phci node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6321
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6322
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6323
mdi_phci_get_vhci_private(dev_info_t *dip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6324
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6325
	ASSERT(mdi_component_is_phci(dip, NULL) == MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6326
	if (mdi_component_is_phci(dip, NULL) == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6327
		mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6328
		ph = i_devi_get_phci(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6329
		return (ph->ph_vprivate);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6330
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6331
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6332
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6334
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6335
 * mdi_phci_set_vhci_private():
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6336
 *		Set the vhci private information in the mdi_phci node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6337
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6338
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6339
mdi_phci_set_vhci_private(dev_info_t *dip, void *priv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6340
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6341
	ASSERT(mdi_component_is_phci(dip, NULL) == MDI_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6342
	if (mdi_component_is_phci(dip, NULL) == MDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6343
		mdi_phci_t	*ph;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6344
		ph = i_devi_get_phci(dip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6345
		ph->ph_vprivate = priv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6346
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  6347
}
878
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6348
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6349
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6350
 * List of vhci class names:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6351
 * A vhci class name must be in this list only if the corresponding vhci
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6352
 * driver intends to use the mdi provided bus config implementation
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6353
 * (i.e., mdi_vhci_bus_config()).
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6354
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6355
static char *vhci_class_list[] = { MDI_HCI_CLASS_SCSI, MDI_HCI_CLASS_IB };
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6356
#define	N_VHCI_CLASSES	(sizeof (vhci_class_list) / sizeof (char *))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6357
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6358
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6359
 * Built-in list of phci drivers for every vhci class.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6360
 * All phci drivers expect iscsi have root device support.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6361
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6362
static mdi_phci_driver_info_t scsi_phci_driver_list[] = {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6363
	{ "fp", 1 },
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6364
	{ "iscsi", 0 },
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6365
	{ "ibsrp", 1 }
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6366
	};
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6367
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6368
static mdi_phci_driver_info_t ib_phci_driver_list[] = { "tavor", 1 };
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6369
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6370
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6371
 * During boot time, the on-disk vhci cache for every vhci class is read
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6372
 * in the form of an nvlist and stored here.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6373
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6374
static nvlist_t *vhcache_nvl[N_VHCI_CLASSES];
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6375
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6376
/* nvpair names in vhci cache nvlist */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6377
#define	MDI_VHCI_CACHE_VERSION	1
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6378
#define	MDI_NVPNAME_VERSION	"version"
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6379
#define	MDI_NVPNAME_PHCIS	"phcis"
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6380
#define	MDI_NVPNAME_CTADDRMAP	"clientaddrmap"
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6381
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6382
typedef enum {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6383
	VHCACHE_NOT_REBUILT,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6384
	VHCACHE_PARTIALLY_BUILT,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6385
	VHCACHE_FULLY_BUILT
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6386
} vhcache_build_status_t;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6387
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6388
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6389
 * Given vhci class name, return its on-disk vhci cache filename.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6390
 * Memory for the returned filename which includes the full path is allocated
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6391
 * by this function.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6392
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6393
static char *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6394
vhclass2vhcache_filename(char *vhclass)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6395
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6396
	char *filename;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6397
	int len;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6398
	static char *fmt = "/etc/devices/mdi_%s_cache";
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6399
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6400
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6401
	 * fmt contains the on-disk vhci cache file name format;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6402
	 * for scsi_vhci the filename is "/etc/devices/mdi_scsi_vhci_cache".
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6403
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6404
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6405
	/* the -1 below is to account for "%s" in the format string */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6406
	len = strlen(fmt) + strlen(vhclass) - 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6407
	filename = kmem_alloc(len, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6408
	(void) snprintf(filename, len, fmt, vhclass);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6409
	ASSERT(len == (strlen(filename) + 1));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6410
	return (filename);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6411
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6412
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6413
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6414
 * initialize the vhci cache related data structures and read the on-disk
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6415
 * vhci cached data into memory.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6416
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6417
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6418
setup_vhci_cache(mdi_vhci_t *vh)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6419
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6420
	mdi_vhci_config_t *vhc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6421
	mdi_vhci_cache_t *vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6422
	int i;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6423
	nvlist_t *nvl = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6424
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6425
	vhc = kmem_zalloc(sizeof (mdi_vhci_config_t), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6426
	vh->vh_config = vhc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6427
	vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6428
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6429
	vhc->vhc_vhcache_filename = vhclass2vhcache_filename(vh->vh_class);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6430
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6431
	mutex_init(&vhc->vhc_lock, NULL, MUTEX_DEFAULT, NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6432
	cv_init(&vhc->vhc_cv, NULL, CV_DRIVER, NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6433
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6434
	rw_init(&vhcache->vhcache_lock, NULL, RW_DRIVER, NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6435
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6436
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6437
	 * Create string hash; same as mod_hash_create_strhash() except that
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6438
	 * we use NULL key destructor.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6439
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6440
	vhcache->vhcache_client_hash = mod_hash_create_extended(vh->vh_class,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6441
	    mdi_bus_config_cache_hash_size,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6442
	    mod_hash_null_keydtor, mod_hash_null_valdtor,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6443
	    mod_hash_bystr, NULL, mod_hash_strkey_cmp, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6444
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6445
	setup_phci_driver_list(vh);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6446
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6447
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6448
	 * The on-disk vhci cache is read during booting prior to the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6449
	 * lights-out period by mdi_read_devices_files().
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6450
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6451
	for (i = 0; i < N_VHCI_CLASSES; i++) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6452
		if (strcmp(vhci_class_list[i], vh->vh_class) == 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6453
			nvl = vhcache_nvl[i];
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6454
			vhcache_nvl[i] = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6455
			break;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6456
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6457
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6458
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6459
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6460
	 * this is to cover the case of some one manually causing unloading
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6461
	 * (or detaching) and reloading (or attaching) of a vhci driver.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6462
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6463
	if (nvl == NULL && modrootloaded)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6464
		nvl = read_on_disk_vhci_cache(vh->vh_class);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6465
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6466
	if (nvl != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6467
		rw_enter(&vhcache->vhcache_lock, RW_WRITER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6468
		if (mainnvl_to_vhcache(vhcache, nvl) == MDI_SUCCESS)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6469
			vhcache->vhcache_flags |= MDI_VHCI_CACHE_SETUP_DONE;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6470
		else  {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6471
			cmn_err(CE_WARN,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6472
			    "%s: data file corrupted, will recreate\n",
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6473
			    vhc->vhc_vhcache_filename);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6474
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6475
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6476
		nvlist_free(nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6477
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6478
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6479
	vhc->vhc_cbid = callb_add(stop_vhcache_flush_thread, vhc,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6480
	    CB_CL_UADMIN_PRE_VFS, "mdi_vhcache_flush");
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6481
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6482
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6483
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6484
 * free all vhci cache related resources
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6485
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6486
static int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6487
destroy_vhci_cache(mdi_vhci_t *vh)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6488
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6489
	mdi_vhci_config_t *vhc = vh->vh_config;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6490
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6491
	mdi_vhcache_phci_t *cphci, *cphci_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6492
	mdi_vhcache_client_t *cct, *cct_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6493
	mdi_vhcache_pathinfo_t *cpi, *cpi_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6494
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6495
	if (stop_vhcache_async_threads(vhc) != MDI_SUCCESS)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6496
		return (MDI_FAILURE);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6497
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6498
	kmem_free(vhc->vhc_vhcache_filename,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6499
	    strlen(vhc->vhc_vhcache_filename) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6500
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6501
	if (vhc->vhc_phci_driver_list)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6502
		free_phci_driver_list(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6503
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6504
	mod_hash_destroy_strhash(vhcache->vhcache_client_hash);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6505
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6506
	for (cphci = vhcache->vhcache_phci_head; cphci != NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6507
	    cphci = cphci_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6508
		cphci_next = cphci->cphci_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6509
		free_vhcache_phci(cphci);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6510
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6511
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6512
	for (cct = vhcache->vhcache_client_head; cct != NULL; cct = cct_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6513
		cct_next = cct->cct_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6514
		for (cpi = cct->cct_cpi_head; cpi != NULL; cpi = cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6515
			cpi_next = cpi->cpi_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6516
			free_vhcache_pathinfo(cpi);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6517
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6518
		free_vhcache_client(cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6519
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6520
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6521
	rw_destroy(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6522
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6523
	mutex_destroy(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6524
	cv_destroy(&vhc->vhc_cv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6525
	kmem_free(vhc, sizeof (mdi_vhci_config_t));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6526
	return (MDI_SUCCESS);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6527
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6528
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6529
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6530
 * Setup the list of phci drivers associated with the specified vhci class.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6531
 * MDI uses this information to rebuild bus config cache if in case the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6532
 * cache is not available or corrupted.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6533
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6534
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6535
setup_phci_driver_list(mdi_vhci_t *vh)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6536
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6537
	mdi_vhci_config_t *vhc = vh->vh_config;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6538
	mdi_phci_driver_info_t *driver_list;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6539
	char **driver_list1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6540
	uint_t ndrivers, ndrivers1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6541
	int i, j;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6542
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6543
	if (strcmp(vh->vh_class, MDI_HCI_CLASS_SCSI) == 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6544
		driver_list = scsi_phci_driver_list;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6545
		ndrivers = sizeof (scsi_phci_driver_list) /
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6546
		    sizeof (mdi_phci_driver_info_t);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6547
	} else if (strcmp(vh->vh_class, MDI_HCI_CLASS_IB) == 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6548
		driver_list = ib_phci_driver_list;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6549
		ndrivers = sizeof (ib_phci_driver_list) /
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6550
		    sizeof (mdi_phci_driver_info_t);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6551
	} else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6552
		driver_list = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6553
		ndrivers = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6554
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6555
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6556
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6557
	 * The driver.conf file of a vhci driver can specify additional
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6558
	 * phci drivers using a project private "phci-drivers" property.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6559
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6560
	if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, vh->vh_dip,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6561
	    DDI_PROP_DONTPASS, "phci-drivers", &driver_list1,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6562
	    &ndrivers1) != DDI_PROP_SUCCESS)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6563
		ndrivers1 = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6564
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6565
	vhc->vhc_nphci_drivers = ndrivers + ndrivers1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6566
	if (vhc->vhc_nphci_drivers == 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6567
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6568
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6569
	vhc->vhc_phci_driver_list = kmem_alloc(
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6570
	    sizeof (mdi_phci_driver_info_t) * vhc->vhc_nphci_drivers, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6571
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6572
	for (i = 0; i < ndrivers; i++) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6573
		vhc->vhc_phci_driver_list[i].phdriver_name =
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6574
		    i_ddi_strdup(driver_list[i].phdriver_name, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6575
		vhc->vhc_phci_driver_list[i].phdriver_root_support =
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6576
		    driver_list[i].phdriver_root_support;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6577
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6578
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6579
	for (j = 0; j < ndrivers1; j++, i++) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6580
		vhc->vhc_phci_driver_list[i].phdriver_name =
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6581
		    i_ddi_strdup(driver_list1[j], KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6582
		vhc->vhc_phci_driver_list[i].phdriver_root_support = 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6583
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6584
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6585
	if (ndrivers1)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6586
		ddi_prop_free(driver_list1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6587
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6588
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6589
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6590
 * Free the memory allocated for the phci driver list
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6591
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6592
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6593
free_phci_driver_list(mdi_vhci_config_t *vhc)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6594
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6595
	int i;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6596
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6597
	if (vhc->vhc_phci_driver_list == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6598
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6599
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6600
	for (i = 0; i < vhc->vhc_nphci_drivers; i++) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6601
		kmem_free(vhc->vhc_phci_driver_list[i].phdriver_name,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6602
		    strlen(vhc->vhc_phci_driver_list[i].phdriver_name) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6603
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6604
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6605
	kmem_free(vhc->vhc_phci_driver_list,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6606
	    sizeof (mdi_phci_driver_info_t) * vhc->vhc_nphci_drivers);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6607
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6608
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6609
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6610
 * Stop all vhci cache related async threads and free their resources.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6611
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6612
static int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6613
stop_vhcache_async_threads(mdi_vhci_config_t *vhc)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6614
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6615
	mdi_async_client_config_t *acc, *acc_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6616
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6617
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6618
	vhc->vhc_flags |= MDI_VHC_EXIT;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6619
	ASSERT(vhc->vhc_acc_thrcount >= 0);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6620
	cv_broadcast(&vhc->vhc_cv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6621
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6622
	while ((vhc->vhc_flags & MDI_VHC_VHCACHE_FLUSH_THREAD) ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6623
	    (vhc->vhc_flags & MDI_VHC_BUILD_VHCI_CACHE_THREAD) ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6624
	    vhc->vhc_acc_thrcount != 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6625
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6626
		delay(1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6627
		mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6628
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6629
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6630
	vhc->vhc_flags &= ~MDI_VHC_EXIT;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6631
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6632
	for (acc = vhc->vhc_acc_list_head; acc != NULL; acc = acc_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6633
		acc_next = acc->acc_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6634
		free_async_client_config(acc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6635
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6636
	vhc->vhc_acc_list_head = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6637
	vhc->vhc_acc_list_tail = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6638
	vhc->vhc_acc_count = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6639
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6640
	if (vhc->vhc_flags & MDI_VHC_VHCACHE_DIRTY) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6641
		vhc->vhc_flags &= ~MDI_VHC_VHCACHE_DIRTY;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6642
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6643
		if (flush_vhcache(vhc, 0) != MDI_SUCCESS) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6644
			vhcache_dirty(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6645
			return (MDI_FAILURE);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6646
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6647
	} else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6648
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6649
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6650
	if (callb_delete(vhc->vhc_cbid) != 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6651
		return (MDI_FAILURE);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6652
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6653
	return (MDI_SUCCESS);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6654
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6655
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6656
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6657
 * Stop vhci cache flush thread
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6658
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6659
/* ARGSUSED */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6660
static boolean_t
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6661
stop_vhcache_flush_thread(void *arg, int code)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6662
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6663
	mdi_vhci_config_t *vhc = (mdi_vhci_config_t *)arg;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6664
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6665
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6666
	vhc->vhc_flags |= MDI_VHC_EXIT;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6667
	cv_broadcast(&vhc->vhc_cv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6668
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6669
	while (vhc->vhc_flags & MDI_VHC_VHCACHE_FLUSH_THREAD) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6670
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6671
		delay(1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6672
		mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6673
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6674
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6675
	if (vhc->vhc_flags & MDI_VHC_VHCACHE_DIRTY) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6676
		vhc->vhc_flags &= ~MDI_VHC_VHCACHE_DIRTY;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6677
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6678
		(void) flush_vhcache(vhc, 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6679
	} else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6680
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6681
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6682
	return (B_TRUE);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6683
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6684
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6685
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6686
 * Enqueue the vhcache phci (cphci) at the tail of the list
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6687
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6688
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6689
enqueue_vhcache_phci(mdi_vhci_cache_t *vhcache, mdi_vhcache_phci_t *cphci)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6690
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6691
	cphci->cphci_next = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6692
	if (vhcache->vhcache_phci_head == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6693
		vhcache->vhcache_phci_head = cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6694
	else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6695
		vhcache->vhcache_phci_tail->cphci_next = cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6696
	vhcache->vhcache_phci_tail = cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6697
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6698
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6699
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6700
 * Enqueue the vhcache pathinfo (cpi) at the tail of the list
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6701
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6702
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6703
enqueue_tail_vhcache_pathinfo(mdi_vhcache_client_t *cct,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6704
    mdi_vhcache_pathinfo_t *cpi)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6705
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6706
	cpi->cpi_next = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6707
	if (cct->cct_cpi_head == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6708
		cct->cct_cpi_head = cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6709
	else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6710
		cct->cct_cpi_tail->cpi_next = cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6711
	cct->cct_cpi_tail = cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6712
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6713
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6714
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6715
 * Enqueue the vhcache pathinfo (cpi) at the correct location in the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6716
 * ordered list. All cpis which do not have MDI_CPI_HINT_PATH_DOES_NOT_EXIST
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6717
 * flag set come at the beginning of the list. All cpis which have this
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6718
 * flag set come at the end of the list.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6719
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6720
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6721
enqueue_vhcache_pathinfo(mdi_vhcache_client_t *cct,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6722
    mdi_vhcache_pathinfo_t *newcpi)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6723
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6724
	mdi_vhcache_pathinfo_t *cpi, *prev_cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6725
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6726
	if (cct->cct_cpi_head == NULL ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6727
	    (newcpi->cpi_flags & MDI_CPI_HINT_PATH_DOES_NOT_EXIST))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6728
		enqueue_tail_vhcache_pathinfo(cct, newcpi);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6729
	else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6730
		for (cpi = cct->cct_cpi_head, prev_cpi = NULL; cpi != NULL &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6731
		    !(cpi->cpi_flags & MDI_CPI_HINT_PATH_DOES_NOT_EXIST);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6732
		    prev_cpi = cpi, cpi = cpi->cpi_next)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6733
			;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6734
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6735
		if (prev_cpi == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6736
			cct->cct_cpi_head = newcpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6737
		else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6738
			prev_cpi->cpi_next = newcpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6739
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6740
		newcpi->cpi_next = cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6741
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6742
		if (cpi == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6743
			cct->cct_cpi_tail = newcpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6744
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6745
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6746
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6747
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6748
 * Enqueue the vhcache client (cct) at the tail of the list
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6749
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6750
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6751
enqueue_vhcache_client(mdi_vhci_cache_t *vhcache,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6752
    mdi_vhcache_client_t *cct)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6753
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6754
	cct->cct_next = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6755
	if (vhcache->vhcache_client_head == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6756
		vhcache->vhcache_client_head = cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6757
	else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6758
		vhcache->vhcache_client_tail->cct_next = cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6759
	vhcache->vhcache_client_tail = cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6760
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6761
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6762
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6763
free_string_array(char **str, int nelem)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6764
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6765
	int i;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6766
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6767
	if (str) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6768
		for (i = 0; i < nelem; i++) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6769
			if (str[i])
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6770
				kmem_free(str[i], strlen(str[i]) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6771
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6772
		kmem_free(str, sizeof (char *) * nelem);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6773
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6774
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6775
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6776
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6777
free_vhcache_phci(mdi_vhcache_phci_t *cphci)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6778
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6779
	kmem_free(cphci->cphci_path, strlen(cphci->cphci_path) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6780
	kmem_free(cphci, sizeof (*cphci));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6781
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6782
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6783
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6784
free_vhcache_pathinfo(mdi_vhcache_pathinfo_t *cpi)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6785
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6786
	kmem_free(cpi->cpi_addr, strlen(cpi->cpi_addr) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6787
	kmem_free(cpi, sizeof (*cpi));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6788
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6789
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6790
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6791
free_vhcache_client(mdi_vhcache_client_t *cct)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6792
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6793
	kmem_free(cct->cct_name_addr, strlen(cct->cct_name_addr) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6794
	kmem_free(cct, sizeof (*cct));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6795
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6796
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6797
static char *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6798
vhcache_mknameaddr(char *ct_name, char *ct_addr, int *ret_len)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6799
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6800
	char *name_addr;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6801
	int len;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6802
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6803
	len = strlen(ct_name) + strlen(ct_addr) + 2;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6804
	name_addr = kmem_alloc(len, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6805
	(void) snprintf(name_addr, len, "%s@%s", ct_name, ct_addr);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6806
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6807
	if (ret_len)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6808
		*ret_len = len;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6809
	return (name_addr);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6810
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6811
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6812
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6813
 * Copy the contents of paddrnvl to vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6814
 * paddrnvl nvlist contains path information for a vhci client.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6815
 * See the comment in mainnvl_to_vhcache() for the format of this nvlist.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6816
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6817
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6818
paddrnvl_to_vhcache(nvlist_t *nvl, mdi_vhcache_phci_t *cphci_list[],
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6819
    mdi_vhcache_client_t *cct)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6820
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6821
	nvpair_t *nvp = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6822
	mdi_vhcache_pathinfo_t *cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6823
	uint_t nelem;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6824
	uint32_t *val;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6825
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6826
	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6827
		ASSERT(nvpair_type(nvp) == DATA_TYPE_UINT32_ARRAY);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6828
		cpi = kmem_zalloc(sizeof (*cpi), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6829
		cpi->cpi_addr = i_ddi_strdup(nvpair_name(nvp), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6830
		(void) nvpair_value_uint32_array(nvp, &val, &nelem);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6831
		ASSERT(nelem == 2);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6832
		cpi->cpi_cphci = cphci_list[val[0]];
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6833
		cpi->cpi_flags = val[1];
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6834
		enqueue_tail_vhcache_pathinfo(cct, cpi);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6835
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6836
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6837
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6838
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6839
 * Copy the contents of caddrmapnvl to vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6840
 * caddrmapnvl nvlist contains vhci client address to phci client address
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6841
 * mappings. See the comment in mainnvl_to_vhcache() for the format of
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6842
 * this nvlist.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6843
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6844
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6845
caddrmapnvl_to_vhcache(mdi_vhci_cache_t *vhcache, nvlist_t *nvl,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6846
    mdi_vhcache_phci_t *cphci_list[])
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6847
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6848
	nvpair_t *nvp = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6849
	nvlist_t *paddrnvl;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6850
	mdi_vhcache_client_t *cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6851
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6852
	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6853
		ASSERT(nvpair_type(nvp) == DATA_TYPE_NVLIST);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6854
		cct = kmem_zalloc(sizeof (*cct), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6855
		cct->cct_name_addr = i_ddi_strdup(nvpair_name(nvp), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6856
		(void) nvpair_value_nvlist(nvp, &paddrnvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6857
		paddrnvl_to_vhcache(paddrnvl, cphci_list, cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6858
		/* the client must contain at least one path */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6859
		ASSERT(cct->cct_cpi_head != NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6860
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6861
		enqueue_vhcache_client(vhcache, cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6862
		(void) mod_hash_insert(vhcache->vhcache_client_hash,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6863
		    (mod_hash_key_t)cct->cct_name_addr, (mod_hash_val_t)cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6864
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6865
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6866
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6867
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6868
 * Copy the contents of the main nvlist to vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6869
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6870
 * VHCI busconfig cached data is stored in the form of a nvlist on the disk.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6871
 * The nvlist contains the mappings between the vhci client addresses and
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6872
 * their corresponding phci client addresses.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6873
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6874
 * The structure of the nvlist is as follows:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6875
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6876
 * Main nvlist:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6877
 *	NAME		TYPE		DATA
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6878
 *	version		int32		version number
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6879
 *	phcis		string array	array of phci paths
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6880
 *	clientaddrmap	nvlist_t	c2paddrs_nvl (see below)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6881
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6882
 * structure of c2paddrs_nvl:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6883
 *	NAME		TYPE		DATA
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6884
 *	caddr1		nvlist_t	paddrs_nvl1
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6885
 *	caddr2		nvlist_t	paddrs_nvl2
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6886
 *	...
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6887
 * where caddr1, caddr2, ... are vhci client name and addresses in the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6888
 * form of "<clientname>@<clientaddress>".
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6889
 * (for example: "ssd@2000002037cd9f72");
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6890
 * paddrs_nvl1, paddrs_nvl2, .. are nvlists that contain path information.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6891
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6892
 * structure of paddrs_nvl:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6893
 *	NAME		TYPE		DATA
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6894
 *	pi_addr1	uint32_array	(phci-id, cpi_flags)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6895
 *	pi_addr2	uint32_array	(phci-id, cpi_flags)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6896
 *	...
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6897
 * where pi_addr1, pi_addr2, ... are bus specific addresses of pathinfo nodes
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6898
 * (so called pi_addrs, for example: "w2100002037cd9f72,0");
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6899
 * phci-ids are integers that identify PHCIs to which the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6900
 * the bus specific address belongs to. These integers are used as an index
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6901
 * into to the phcis string array in the main nvlist to get the PHCI path.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6902
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6903
static int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6904
mainnvl_to_vhcache(mdi_vhci_cache_t *vhcache, nvlist_t *nvl)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6905
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6906
	char **phcis, **phci_namep;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6907
	uint_t nphcis;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6908
	mdi_vhcache_phci_t *cphci, **cphci_list;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6909
	nvlist_t *caddrmapnvl;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6910
	int32_t ver;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6911
	int i;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6912
	size_t cphci_list_size;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6913
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6914
	ASSERT(RW_WRITE_HELD(&vhcache->vhcache_lock));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6915
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6916
	if (nvlist_lookup_int32(nvl, MDI_NVPNAME_VERSION, &ver) != 0 ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6917
	    ver != MDI_VHCI_CACHE_VERSION)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6918
		return (MDI_FAILURE);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6919
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6920
	if (nvlist_lookup_string_array(nvl, MDI_NVPNAME_PHCIS, &phcis,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6921
	    &nphcis) != 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6922
		return (MDI_SUCCESS);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6923
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6924
	ASSERT(nphcis > 0);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6925
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6926
	cphci_list_size = sizeof (mdi_vhcache_phci_t *) * nphcis;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6927
	cphci_list = kmem_alloc(cphci_list_size, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6928
	for (i = 0, phci_namep = phcis; i < nphcis; i++, phci_namep++) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6929
		cphci = kmem_zalloc(sizeof (mdi_vhcache_phci_t), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6930
		cphci->cphci_path = i_ddi_strdup(*phci_namep, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6931
		enqueue_vhcache_phci(vhcache, cphci);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6932
		cphci_list[i] = cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6933
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6934
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6935
	ASSERT(vhcache->vhcache_phci_head != NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6936
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6937
	if (nvlist_lookup_nvlist(nvl, MDI_NVPNAME_CTADDRMAP, &caddrmapnvl) == 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6938
		caddrmapnvl_to_vhcache(vhcache, caddrmapnvl, cphci_list);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6939
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6940
	kmem_free(cphci_list, cphci_list_size);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6941
	return (MDI_SUCCESS);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6942
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6943
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6944
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6945
 * Build paddrnvl for the specified client using the information in the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6946
 * vhci cache and add it to the caddrmapnnvl.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6947
 * Returns 0 on success, errno on failure.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6948
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6949
static int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6950
vhcache_to_paddrnvl(mdi_vhci_cache_t *vhcache, mdi_vhcache_client_t *cct,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6951
    nvlist_t *caddrmapnvl)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6952
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6953
	mdi_vhcache_pathinfo_t *cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6954
	nvlist_t *nvl;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6955
	int err;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6956
	uint32_t val[2];
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6957
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6958
	ASSERT(RW_LOCK_HELD(&vhcache->vhcache_lock));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6959
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6960
	if ((err = nvlist_alloc(&nvl, 0, KM_SLEEP)) != 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6961
		return (err);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6962
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6963
	for (cpi = cct->cct_cpi_head; cpi != NULL; cpi = cpi->cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6964
		val[0] = cpi->cpi_cphci->cphci_id;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6965
		val[1] = cpi->cpi_flags;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6966
		if ((err = nvlist_add_uint32_array(nvl, cpi->cpi_addr, val, 2))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6967
		    != 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6968
			goto out;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6969
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6970
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6971
	err = nvlist_add_nvlist(caddrmapnvl, cct->cct_name_addr, nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6972
out:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6973
	nvlist_free(nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6974
	return (err);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6975
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6976
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6977
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6978
 * Build caddrmapnvl using the information in the vhci cache
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6979
 * and add it to the mainnvl.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6980
 * Returns 0 on success, errno on failure.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6981
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6982
static int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6983
vhcache_to_caddrmapnvl(mdi_vhci_cache_t *vhcache, nvlist_t *mainnvl)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6984
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6985
	mdi_vhcache_client_t *cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6986
	nvlist_t *nvl;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6987
	int err;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6988
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6989
	ASSERT(RW_LOCK_HELD(&vhcache->vhcache_lock));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6990
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6991
	if ((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)) != 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6992
		return (err);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6993
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6994
	for (cct = vhcache->vhcache_client_head; cct != NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6995
	    cct = cct->cct_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6996
		if ((err = vhcache_to_paddrnvl(vhcache, cct, nvl)) != 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6997
			goto out;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6998
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  6999
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7000
	err = nvlist_add_nvlist(mainnvl, MDI_NVPNAME_CTADDRMAP, nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7001
out:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7002
	nvlist_free(nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7003
	return (err);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7004
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7005
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7006
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7007
 * Build nvlist using the information in the vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7008
 * See the comment in mainnvl_to_vhcache() for the format of the nvlist.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7009
 * Returns nvl on success, NULL on failure.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7010
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7011
static nvlist_t *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7012
vhcache_to_mainnvl(mdi_vhci_cache_t *vhcache)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7013
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7014
	mdi_vhcache_phci_t *cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7015
	uint_t phci_count;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7016
	char **phcis;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7017
	nvlist_t *nvl;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7018
	int err, i;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7019
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7020
	if ((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP)) != 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7021
		nvl = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7022
		goto out;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7023
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7024
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7025
	if ((err = nvlist_add_int32(nvl, MDI_NVPNAME_VERSION,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7026
	    MDI_VHCI_CACHE_VERSION)) != 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7027
		goto out;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7028
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7029
	rw_enter(&vhcache->vhcache_lock, RW_READER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7030
	if (vhcache->vhcache_phci_head == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7031
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7032
		return (nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7033
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7034
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7035
	phci_count = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7036
	for (cphci = vhcache->vhcache_phci_head; cphci != NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7037
	    cphci = cphci->cphci_next)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7038
		cphci->cphci_id = phci_count++;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7039
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7040
	/* build phci pathname list */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7041
	phcis = kmem_alloc(sizeof (char *) * phci_count, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7042
	for (cphci = vhcache->vhcache_phci_head, i = 0; cphci != NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7043
	    cphci = cphci->cphci_next, i++)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7044
		phcis[i] = i_ddi_strdup(cphci->cphci_path, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7045
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7046
	err = nvlist_add_string_array(nvl, MDI_NVPNAME_PHCIS, phcis,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7047
	    phci_count);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7048
	free_string_array(phcis, phci_count);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7049
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7050
	if (err == 0 &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7051
	    (err = vhcache_to_caddrmapnvl(vhcache, nvl)) == 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7052
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7053
		return (nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7054
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7055
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7056
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7057
out:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7058
	if (nvl)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7059
		nvlist_free(nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7060
	return (NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7061
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7062
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7063
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7064
 * Lookup vhcache phci structure for the specified phci path.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7065
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7066
static mdi_vhcache_phci_t *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7067
lookup_vhcache_phci_by_name(mdi_vhci_cache_t *vhcache, char *phci_path)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7068
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7069
	mdi_vhcache_phci_t *cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7070
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7071
	ASSERT(RW_LOCK_HELD(&vhcache->vhcache_lock));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7072
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7073
	for (cphci = vhcache->vhcache_phci_head; cphci != NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7074
	    cphci = cphci->cphci_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7075
		if (strcmp(cphci->cphci_path, phci_path) == 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7076
			return (cphci);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7077
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7078
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7079
	return (NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7080
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7081
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7082
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7083
 * Lookup vhcache phci structure for the specified phci.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7084
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7085
static mdi_vhcache_phci_t *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7086
lookup_vhcache_phci_by_addr(mdi_vhci_cache_t *vhcache, mdi_phci_t *ph)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7087
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7088
	mdi_vhcache_phci_t *cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7089
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7090
	ASSERT(RW_LOCK_HELD(&vhcache->vhcache_lock));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7091
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7092
	for (cphci = vhcache->vhcache_phci_head; cphci != NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7093
	    cphci = cphci->cphci_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7094
		if (cphci->cphci_phci == ph)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7095
			return (cphci);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7096
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7097
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7098
	return (NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7099
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7100
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7101
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7102
 * Add the specified phci to the vhci cache if not already present.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7103
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7104
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7105
vhcache_phci_add(mdi_vhci_config_t *vhc, mdi_phci_t *ph)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7106
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7107
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7108
	mdi_vhcache_phci_t *cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7109
	char *pathname;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7110
	int cache_updated;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7111
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7112
	rw_enter(&vhcache->vhcache_lock, RW_WRITER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7113
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7114
	pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7115
	(void) ddi_pathname(ph->ph_dip, pathname);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7116
	if ((cphci = lookup_vhcache_phci_by_name(vhcache, pathname))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7117
	    != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7118
		cphci->cphci_phci = ph;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7119
		cache_updated = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7120
	} else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7121
		cphci = kmem_zalloc(sizeof (*cphci), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7122
		cphci->cphci_path = i_ddi_strdup(pathname, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7123
		cphci->cphci_phci = ph;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7124
		enqueue_vhcache_phci(vhcache, cphci);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7125
		cache_updated = 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7126
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7127
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7128
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7129
	kmem_free(pathname, MAXPATHLEN);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7130
	if (cache_updated)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7131
		vhcache_dirty(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7132
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7133
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7134
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7135
 * Remove the reference to the specified phci from the vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7136
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7137
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7138
vhcache_phci_remove(mdi_vhci_config_t *vhc, mdi_phci_t *ph)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7139
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7140
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7141
	mdi_vhcache_phci_t *cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7142
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7143
	rw_enter(&vhcache->vhcache_lock, RW_WRITER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7144
	if ((cphci = lookup_vhcache_phci_by_addr(vhcache, ph)) != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7145
		/* do not remove the actual mdi_vhcache_phci structure */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7146
		cphci->cphci_phci = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7147
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7148
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7149
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7150
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7151
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7152
init_vhcache_lookup_token(mdi_vhcache_lookup_token_t *dst,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7153
    mdi_vhcache_lookup_token_t *src)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7154
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7155
	if (src == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7156
		dst->lt_cct = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7157
		dst->lt_cct_lookup_time = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7158
	} else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7159
		dst->lt_cct = src->lt_cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7160
		dst->lt_cct_lookup_time = src->lt_cct_lookup_time;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7161
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7162
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7163
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7164
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7165
 * Look up vhcache client for the specified client.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7166
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7167
static mdi_vhcache_client_t *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7168
lookup_vhcache_client(mdi_vhci_cache_t *vhcache, char *ct_name, char *ct_addr,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7169
    mdi_vhcache_lookup_token_t *token)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7170
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7171
	mod_hash_val_t hv;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7172
	char *name_addr;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7173
	int len;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7174
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7175
	ASSERT(RW_LOCK_HELD(&vhcache->vhcache_lock));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7176
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7177
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7178
	 * If no vhcache clean occurred since the last lookup, we can
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7179
	 * simply return the cct from the last lookup operation.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7180
	 * It works because ccts are never freed except during the vhcache
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7181
	 * cleanup operation.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7182
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7183
	if (token != NULL &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7184
	    vhcache->vhcache_clean_time < token->lt_cct_lookup_time)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7185
		return (token->lt_cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7186
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7187
	name_addr = vhcache_mknameaddr(ct_name, ct_addr, &len);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7188
	if (mod_hash_find(vhcache->vhcache_client_hash,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7189
	    (mod_hash_key_t)name_addr, &hv) == 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7190
		if (token) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7191
			token->lt_cct = (mdi_vhcache_client_t *)hv;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7192
			token->lt_cct_lookup_time = lbolt64;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7193
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7194
	} else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7195
		if (token) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7196
			token->lt_cct = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7197
			token->lt_cct_lookup_time = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7198
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7199
		hv = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7200
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7201
	kmem_free(name_addr, len);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7202
	return ((mdi_vhcache_client_t *)hv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7203
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7204
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7205
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7206
 * Add the specified path to the vhci cache if not already present.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7207
 * Also add the vhcache client for the client corresponding to this path
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7208
 * if it doesn't already exist.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7209
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7210
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7211
vhcache_pi_add(mdi_vhci_config_t *vhc, struct mdi_pathinfo *pip)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7212
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7213
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7214
	mdi_vhcache_client_t *cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7215
	mdi_vhcache_pathinfo_t *cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7216
	mdi_phci_t *ph = pip->pi_phci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7217
	mdi_client_t *ct = pip->pi_client;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7218
	int cache_updated = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7219
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7220
	rw_enter(&vhcache->vhcache_lock, RW_WRITER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7221
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7222
	/* if vhcache client for this pip doesn't already exist, add it */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7223
	if ((cct = lookup_vhcache_client(vhcache, ct->ct_drvname, ct->ct_guid,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7224
	    NULL)) == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7225
		cct = kmem_zalloc(sizeof (*cct), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7226
		cct->cct_name_addr = vhcache_mknameaddr(ct->ct_drvname,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7227
		    ct->ct_guid, NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7228
		enqueue_vhcache_client(vhcache, cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7229
		(void) mod_hash_insert(vhcache->vhcache_client_hash,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7230
		    (mod_hash_key_t)cct->cct_name_addr, (mod_hash_val_t)cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7231
		cache_updated = 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7232
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7233
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7234
	for (cpi = cct->cct_cpi_head; cpi != NULL; cpi = cpi->cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7235
		if (cpi->cpi_cphci->cphci_phci == ph &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7236
		    strcmp(cpi->cpi_addr, pip->pi_addr) == 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7237
			cpi->cpi_pip = pip;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7238
			if (cpi->cpi_flags & MDI_CPI_HINT_PATH_DOES_NOT_EXIST) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7239
				cpi->cpi_flags &=
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7240
				    ~MDI_CPI_HINT_PATH_DOES_NOT_EXIST;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7241
				sort_vhcache_paths(cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7242
				cache_updated = 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7243
			}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7244
			break;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7245
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7246
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7247
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7248
	if (cpi == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7249
		cpi = kmem_zalloc(sizeof (*cpi), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7250
		cpi->cpi_addr = i_ddi_strdup(pip->pi_addr, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7251
		cpi->cpi_cphci = lookup_vhcache_phci_by_addr(vhcache, ph);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7252
		ASSERT(cpi->cpi_cphci != NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7253
		cpi->cpi_pip = pip;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7254
		enqueue_vhcache_pathinfo(cct, cpi);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7255
		cache_updated = 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7256
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7257
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7258
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7259
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7260
	if (cache_updated)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7261
		vhcache_dirty(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7262
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7263
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7264
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7265
 * Remove the reference to the specified path from the vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7266
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7267
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7268
vhcache_pi_remove(mdi_vhci_config_t *vhc, struct mdi_pathinfo *pip)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7269
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7270
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7271
	mdi_client_t *ct = pip->pi_client;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7272
	mdi_vhcache_client_t *cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7273
	mdi_vhcache_pathinfo_t *cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7274
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7275
	rw_enter(&vhcache->vhcache_lock, RW_WRITER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7276
	if ((cct = lookup_vhcache_client(vhcache, ct->ct_drvname, ct->ct_guid,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7277
	    NULL)) != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7278
		for (cpi = cct->cct_cpi_head; cpi != NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7279
		    cpi = cpi->cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7280
			if (cpi->cpi_pip == pip) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7281
				cpi->cpi_pip = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7282
				break;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7283
			}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7284
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7285
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7286
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7287
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7288
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7289
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7290
 * Flush the vhci cache to disk.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7291
 * Returns MDI_SUCCESS on success, MDI_FAILURE on failure.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7292
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7293
static int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7294
flush_vhcache(mdi_vhci_config_t *vhc, int force_flag)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7295
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7296
	nvlist_t *nvl;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7297
	int err;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7298
	int rv;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7299
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7300
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7301
	 * It is possible that the system may shutdown before
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7302
	 * i_ddi_io_initialized (during stmsboot for example). To allow for
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7303
	 * flushing the cache in this case do not check for
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7304
	 * i_ddi_io_initialized when force flag is set.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7305
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7306
	if (force_flag == 0 && !i_ddi_io_initialized())
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7307
		return (MDI_FAILURE);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7308
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7309
	if ((nvl = vhcache_to_mainnvl(&vhc->vhc_vhcache)) != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7310
		err = fwrite_nvlist(vhc->vhc_vhcache_filename, nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7311
		nvlist_free(nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7312
	} else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7313
		err = EFAULT;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7314
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7315
	rv = MDI_SUCCESS;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7316
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7317
	if (err != 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7318
		if (err == EROFS) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7319
			vhc->vhc_flags |= MDI_VHC_READONLY_FS;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7320
			vhc->vhc_flags &= ~(MDI_VHC_VHCACHE_FLUSH_ERROR |
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7321
			    MDI_VHC_VHCACHE_DIRTY);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7322
		} else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7323
			if (!(vhc->vhc_flags & MDI_VHC_VHCACHE_FLUSH_ERROR)) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7324
				cmn_err(CE_CONT, "%s: update failed\n",
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7325
				    vhc->vhc_vhcache_filename);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7326
				vhc->vhc_flags |= MDI_VHC_VHCACHE_FLUSH_ERROR;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7327
			}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7328
			rv = MDI_FAILURE;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7329
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7330
	} else if (vhc->vhc_flags & MDI_VHC_VHCACHE_FLUSH_ERROR) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7331
		cmn_err(CE_CONT,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7332
		    "%s: update now ok\n", vhc->vhc_vhcache_filename);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7333
		vhc->vhc_flags &= ~MDI_VHC_VHCACHE_FLUSH_ERROR;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7334
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7335
	mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7336
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7337
	return (rv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7338
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7339
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7340
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7341
 * Call flush_vhcache() to flush the vhci cache at the scheduled time.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7342
 * Exits itself if left idle for the idle timeout period.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7343
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7344
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7345
vhcache_flush_thread(void *arg)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7346
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7347
	mdi_vhci_config_t *vhc = (mdi_vhci_config_t *)arg;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7348
	clock_t idle_time, quit_at_ticks;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7349
	callb_cpr_t cprinfo;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7350
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7351
	/* number of seconds to sleep idle before exiting */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7352
	idle_time = mdi_vhcache_flush_daemon_idle_time * TICKS_PER_SECOND;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7353
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7354
	CALLB_CPR_INIT(&cprinfo, &vhc->vhc_lock, callb_generic_cpr,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7355
	    "mdi_vhcache_flush");
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7356
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7357
	for (; ; ) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7358
		while (!(vhc->vhc_flags & MDI_VHC_EXIT) &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7359
		    (vhc->vhc_flags & MDI_VHC_VHCACHE_DIRTY)) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7360
			if (ddi_get_lbolt() < vhc->vhc_flush_at_ticks) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7361
				CALLB_CPR_SAFE_BEGIN(&cprinfo);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7362
				(void) cv_timedwait(&vhc->vhc_cv,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7363
				    &vhc->vhc_lock, vhc->vhc_flush_at_ticks);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7364
				CALLB_CPR_SAFE_END(&cprinfo, &vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7365
			} else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7366
				vhc->vhc_flags &= ~MDI_VHC_VHCACHE_DIRTY;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7367
				mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7368
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7369
				if (flush_vhcache(vhc, 0) != MDI_SUCCESS)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7370
					vhcache_dirty(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7371
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7372
				mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7373
			}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7374
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7375
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7376
		quit_at_ticks = ddi_get_lbolt() + idle_time;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7377
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7378
		while (!(vhc->vhc_flags & MDI_VHC_EXIT) &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7379
		    !(vhc->vhc_flags & MDI_VHC_VHCACHE_DIRTY) &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7380
		    ddi_get_lbolt() < quit_at_ticks) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7381
			CALLB_CPR_SAFE_BEGIN(&cprinfo);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7382
			(void) cv_timedwait(&vhc->vhc_cv, &vhc->vhc_lock,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7383
			    quit_at_ticks);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7384
			CALLB_CPR_SAFE_END(&cprinfo, &vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7385
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7386
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7387
		if ((vhc->vhc_flags & MDI_VHC_EXIT) ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7388
		    !(vhc->vhc_flags & MDI_VHC_VHCACHE_DIRTY))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7389
			goto out;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7390
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7391
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7392
out:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7393
	vhc->vhc_flags &= ~MDI_VHC_VHCACHE_FLUSH_THREAD;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7394
	/* CALLB_CPR_EXIT releases the vhc->vhc_lock */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7395
	CALLB_CPR_EXIT(&cprinfo);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7396
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7397
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7398
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7399
 * Make vhci cache dirty and schedule flushing by vhcache flush thread.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7400
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7401
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7402
vhcache_dirty(mdi_vhci_config_t *vhc)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7403
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7404
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7405
	int create_thread;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7406
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7407
	rw_enter(&vhcache->vhcache_lock, RW_READER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7408
	/* do not flush cache until the cache is fully built */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7409
	if (!(vhcache->vhcache_flags & MDI_VHCI_CACHE_SETUP_DONE)) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7410
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7411
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7412
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7413
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7414
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7415
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7416
	if (vhc->vhc_flags & MDI_VHC_READONLY_FS) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7417
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7418
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7419
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7420
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7421
	vhc->vhc_flags |= MDI_VHC_VHCACHE_DIRTY;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7422
	vhc->vhc_flush_at_ticks = ddi_get_lbolt() +
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7423
	    mdi_vhcache_flush_delay * TICKS_PER_SECOND;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7424
	if (vhc->vhc_flags & MDI_VHC_VHCACHE_FLUSH_THREAD) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7425
		cv_broadcast(&vhc->vhc_cv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7426
		create_thread = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7427
	} else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7428
		vhc->vhc_flags |= MDI_VHC_VHCACHE_FLUSH_THREAD;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7429
		create_thread = 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7430
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7431
	mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7432
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7433
	if (create_thread)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7434
		(void) thread_create(NULL, 0, vhcache_flush_thread, vhc,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7435
		    0, &p0, TS_RUN, minclsyspri);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7436
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7437
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7438
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7439
 * phci bus config structure - one for for each phci bus config operation that
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7440
 * we initiate on behalf of a vhci.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7441
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7442
typedef struct mdi_phci_bus_config_s {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7443
	char *phbc_phci_path;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7444
	struct mdi_vhci_bus_config_s *phbc_vhbusconfig;	/* vhci bus config */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7445
	struct mdi_phci_bus_config_s *phbc_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7446
} mdi_phci_bus_config_t;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7447
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7448
/* vhci bus config structure - one for each vhci bus config operation */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7449
typedef struct mdi_vhci_bus_config_s {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7450
	ddi_bus_config_op_t vhbc_op;	/* bus config op */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7451
	major_t vhbc_op_major;		/* bus config op major */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7452
	uint_t vhbc_op_flags;		/* bus config op flags */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7453
	kmutex_t vhbc_lock;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7454
	kcondvar_t vhbc_cv;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7455
	int vhbc_thr_count;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7456
} mdi_vhci_bus_config_t;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7457
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7458
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7459
 * bus config the specified phci
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7460
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7461
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7462
bus_config_phci(void *arg)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7463
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7464
	mdi_phci_bus_config_t *phbc = (mdi_phci_bus_config_t *)arg;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7465
	mdi_vhci_bus_config_t *vhbc = phbc->phbc_vhbusconfig;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7466
	dev_info_t *ph_dip;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7467
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7468
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7469
	 * first configure all path components upto phci and then configure
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7470
	 * the phci children.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7471
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7472
	if ((ph_dip = e_ddi_hold_devi_by_path(phbc->phbc_phci_path, 0))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7473
	    != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7474
		if (vhbc->vhbc_op == BUS_CONFIG_DRIVER ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7475
		    vhbc->vhbc_op == BUS_UNCONFIG_DRIVER) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7476
			(void) ndi_devi_config_driver(ph_dip,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7477
			    vhbc->vhbc_op_flags,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7478
			    vhbc->vhbc_op_major);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7479
		} else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7480
			(void) ndi_devi_config(ph_dip,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7481
			    vhbc->vhbc_op_flags);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7482
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7483
		/* release the hold that e_ddi_hold_devi_by_path() placed */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7484
		ndi_rele_devi(ph_dip);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7485
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7486
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7487
	kmem_free(phbc->phbc_phci_path, strlen(phbc->phbc_phci_path) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7488
	kmem_free(phbc, sizeof (*phbc));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7489
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7490
	mutex_enter(&vhbc->vhbc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7491
	vhbc->vhbc_thr_count--;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7492
	if (vhbc->vhbc_thr_count == 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7493
		cv_broadcast(&vhbc->vhbc_cv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7494
	mutex_exit(&vhbc->vhbc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7495
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7496
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7497
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7498
 * Bus config all phcis associated with the vhci in parallel.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7499
 * op must be BUS_CONFIG_DRIVER or BUS_CONFIG_ALL.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7500
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7501
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7502
bus_config_all_phcis(mdi_vhci_cache_t *vhcache, uint_t flags,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7503
    ddi_bus_config_op_t op, major_t maj)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7504
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7505
	mdi_phci_bus_config_t *phbc_head = NULL, *phbc, *phbc_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7506
	mdi_vhci_bus_config_t *vhbc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7507
	mdi_vhcache_phci_t *cphci;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7508
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7509
	rw_enter(&vhcache->vhcache_lock, RW_READER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7510
	if (vhcache->vhcache_phci_head == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7511
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7512
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7513
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7514
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7515
	vhbc = kmem_zalloc(sizeof (*vhbc), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7516
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7517
	for (cphci = vhcache->vhcache_phci_head; cphci != NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7518
	    cphci = cphci->cphci_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7519
		phbc = kmem_zalloc(sizeof (*phbc), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7520
		phbc->phbc_phci_path = i_ddi_strdup(cphci->cphci_path,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7521
		    KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7522
		phbc->phbc_vhbusconfig = vhbc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7523
		phbc->phbc_next = phbc_head;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7524
		phbc_head = phbc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7525
		vhbc->vhbc_thr_count++;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7526
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7527
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7528
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7529
	vhbc->vhbc_op = op;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7530
	vhbc->vhbc_op_major = maj;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7531
	vhbc->vhbc_op_flags = NDI_NO_EVENT |
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7532
	    (flags & (NDI_CONFIG_REPROBE | NDI_DRV_CONF_REPROBE));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7533
	mutex_init(&vhbc->vhbc_lock, NULL, MUTEX_DEFAULT, NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7534
	cv_init(&vhbc->vhbc_cv, NULL, CV_DRIVER, NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7535
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7536
	/* now create threads to initiate bus config on all phcis in parallel */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7537
	for (phbc = phbc_head; phbc != NULL; phbc = phbc_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7538
		phbc_next = phbc->phbc_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7539
		if (mdi_mtc_off)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7540
			bus_config_phci((void *)phbc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7541
		else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7542
			(void) thread_create(NULL, 0, bus_config_phci, phbc,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7543
			    0, &p0, TS_RUN, minclsyspri);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7544
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7545
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7546
	mutex_enter(&vhbc->vhbc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7547
	/* wait until all threads exit */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7548
	while (vhbc->vhbc_thr_count > 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7549
		cv_wait(&vhbc->vhbc_cv, &vhbc->vhbc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7550
	mutex_exit(&vhbc->vhbc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7551
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7552
	mutex_destroy(&vhbc->vhbc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7553
	cv_destroy(&vhbc->vhbc_cv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7554
	kmem_free(vhbc, sizeof (*vhbc));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7555
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7556
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7557
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7558
 * Perform BUS_CONFIG_ONE on the specified child of the phci.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7559
 * The path includes the child component in addition to the phci path.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7560
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7561
static int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7562
bus_config_one_phci_child(char *path)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7563
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7564
	dev_info_t *ph_dip, *child;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7565
	char *devnm;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7566
	int rv = MDI_FAILURE;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7567
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7568
	/* extract the child component of the phci */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7569
	devnm = strrchr(path, '/');
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7570
	*devnm++ = '\0';
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7571
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7572
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7573
	 * first configure all path components upto phci and then
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7574
	 * configure the phci child.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7575
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7576
	if ((ph_dip = e_ddi_hold_devi_by_path(path, 0)) != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7577
		if (ndi_devi_config_one(ph_dip, devnm, &child, NDI_NO_EVENT) ==
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7578
		    NDI_SUCCESS) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7579
			/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7580
			 * release the hold that ndi_devi_config_one() placed
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7581
			 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7582
			ndi_rele_devi(child);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7583
			rv = MDI_SUCCESS;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7584
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7585
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7586
		/* release the hold that e_ddi_hold_devi_by_path() placed */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7587
		ndi_rele_devi(ph_dip);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7588
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7589
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7590
	devnm--;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7591
	*devnm = '/';
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7592
	return (rv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7593
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7594
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7595
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7596
 * Build a list of phci client paths for the specified vhci client.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7597
 * The list includes only those phci client paths which aren't configured yet.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7598
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7599
static mdi_phys_path_t *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7600
build_phclient_path_list(mdi_vhcache_client_t *cct, char *ct_name)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7601
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7602
	mdi_vhcache_pathinfo_t *cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7603
	mdi_phys_path_t *pp_head = NULL, *pp_tail = NULL, *pp;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7604
	int config_path, len;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7605
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7606
	for (cpi = cct->cct_cpi_head; cpi != NULL; cpi = cpi->cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7607
		/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7608
		 * include only those paths that aren't configured.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7609
		 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7610
		config_path = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7611
		if (cpi->cpi_pip == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7612
			config_path = 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7613
		else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7614
			MDI_PI_LOCK(cpi->cpi_pip);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7615
			if (MDI_PI_IS_INIT(cpi->cpi_pip))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7616
				config_path = 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7617
			MDI_PI_UNLOCK(cpi->cpi_pip);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7618
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7619
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7620
		if (config_path) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7621
			pp = kmem_alloc(sizeof (*pp), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7622
			len = strlen(cpi->cpi_cphci->cphci_path) +
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7623
			    strlen(ct_name) + strlen(cpi->cpi_addr) + 3;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7624
			pp->phys_path = kmem_alloc(len, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7625
			(void) snprintf(pp->phys_path, len, "%s/%s@%s",
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7626
			    cpi->cpi_cphci->cphci_path, ct_name,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7627
			    cpi->cpi_addr);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7628
			pp->phys_path_next = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7629
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7630
			if (pp_head == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7631
				pp_head = pp;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7632
			else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7633
				pp_tail->phys_path_next = pp;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7634
			pp_tail = pp;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7635
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7636
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7637
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7638
	return (pp_head);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7639
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7640
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7641
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7642
 * Free the memory allocated for phci client path list.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7643
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7644
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7645
free_phclient_path_list(mdi_phys_path_t *pp_head)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7646
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7647
	mdi_phys_path_t *pp, *pp_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7648
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7649
	for (pp = pp_head; pp != NULL; pp = pp_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7650
		pp_next = pp->phys_path_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7651
		kmem_free(pp->phys_path, strlen(pp->phys_path) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7652
		kmem_free(pp, sizeof (*pp));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7653
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7654
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7655
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7656
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7657
 * Allocated async client structure and initialize with the specified values.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7658
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7659
static mdi_async_client_config_t *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7660
alloc_async_client_config(char *ct_name, char *ct_addr,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7661
    mdi_phys_path_t *pp_head, mdi_vhcache_lookup_token_t *tok)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7662
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7663
	mdi_async_client_config_t *acc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7664
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7665
	acc = kmem_alloc(sizeof (*acc), KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7666
	acc->acc_ct_name = i_ddi_strdup(ct_name, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7667
	acc->acc_ct_addr = i_ddi_strdup(ct_addr, KM_SLEEP);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7668
	acc->acc_phclient_path_list_head = pp_head;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7669
	init_vhcache_lookup_token(&acc->acc_token, tok);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7670
	acc->acc_next = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7671
	return (acc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7672
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7673
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7674
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7675
 * Free the memory allocated for the async client structure and their members.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7676
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7677
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7678
free_async_client_config(mdi_async_client_config_t *acc)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7679
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7680
	if (acc->acc_phclient_path_list_head)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7681
		free_phclient_path_list(acc->acc_phclient_path_list_head);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7682
	kmem_free(acc->acc_ct_name, strlen(acc->acc_ct_name) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7683
	kmem_free(acc->acc_ct_addr, strlen(acc->acc_ct_addr) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7684
	kmem_free(acc, sizeof (*acc));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7685
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7686
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7687
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7688
 * Sort vhcache pathinfos (cpis) of the specified client.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7689
 * All cpis which do not have MDI_CPI_HINT_PATH_DOES_NOT_EXIST
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7690
 * flag set come at the beginning of the list. All cpis which have this
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7691
 * flag set come at the end of the list.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7692
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7693
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7694
sort_vhcache_paths(mdi_vhcache_client_t *cct)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7695
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7696
	mdi_vhcache_pathinfo_t *cpi, *cpi_next, *cpi_head;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7697
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7698
	cpi_head = cct->cct_cpi_head;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7699
	cct->cct_cpi_head = cct->cct_cpi_tail = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7700
	for (cpi = cpi_head; cpi != NULL; cpi = cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7701
		cpi_next = cpi->cpi_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7702
		enqueue_vhcache_pathinfo(cct, cpi);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7703
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7704
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7705
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7706
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7707
 * Verify whether MDI_CPI_HINT_PATH_DOES_NOT_EXIST flag setting is correct for
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7708
 * every vhcache pathinfo of the specified client. If not adjust the flag
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7709
 * setting appropriately.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7710
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7711
 * Note that MDI_CPI_HINT_PATH_DOES_NOT_EXIST flag is persisted in the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7712
 * on-disk vhci cache. So every time this flag is updated the cache must be
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7713
 * flushed.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7714
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7715
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7716
adjust_sort_vhcache_paths(mdi_vhci_config_t *vhc, char *ct_name, char *ct_addr,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7717
    mdi_vhcache_lookup_token_t *tok)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7718
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7719
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7720
	mdi_vhcache_client_t *cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7721
	mdi_vhcache_pathinfo_t *cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7722
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7723
	rw_enter(&vhcache->vhcache_lock, RW_READER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7724
	if ((cct = lookup_vhcache_client(vhcache, ct_name, ct_addr, tok))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7725
	    == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7726
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7727
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7728
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7729
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7730
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7731
	 * to avoid unnecessary on-disk cache updates, first check if an
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7732
	 * update is really needed. If no update is needed simply return.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7733
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7734
	for (cpi = cct->cct_cpi_head; cpi != NULL; cpi = cpi->cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7735
		if ((cpi->cpi_pip != NULL &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7736
		    (cpi->cpi_flags & MDI_CPI_HINT_PATH_DOES_NOT_EXIST)) ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7737
		    (cpi->cpi_pip == NULL &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7738
		    !(cpi->cpi_flags & MDI_CPI_HINT_PATH_DOES_NOT_EXIST))) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7739
			break;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7740
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7741
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7742
	if (cpi == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7743
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7744
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7745
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7746
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7747
	if (rw_tryupgrade(&vhcache->vhcache_lock) == 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7748
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7749
		rw_enter(&vhcache->vhcache_lock, RW_WRITER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7750
		if ((cct = lookup_vhcache_client(vhcache, ct_name, ct_addr,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7751
		    tok)) == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7752
			rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7753
			return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7754
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7755
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7756
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7757
	for (cpi = cct->cct_cpi_head; cpi != NULL; cpi = cpi->cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7758
		if (cpi->cpi_pip != NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7759
			cpi->cpi_flags &= ~MDI_CPI_HINT_PATH_DOES_NOT_EXIST;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7760
		else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7761
			cpi->cpi_flags |= MDI_CPI_HINT_PATH_DOES_NOT_EXIST;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7762
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7763
	sort_vhcache_paths(cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7764
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7765
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7766
	vhcache_dirty(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7767
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7768
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7769
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7770
 * Configure all specified paths of the client.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7771
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7772
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7773
config_client_paths_sync(mdi_vhci_config_t *vhc, char *ct_name, char *ct_addr,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7774
    mdi_phys_path_t *pp_head, mdi_vhcache_lookup_token_t *tok)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7775
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7776
	mdi_phys_path_t *pp;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7777
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7778
	for (pp = pp_head; pp != NULL; pp = pp->phys_path_next)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7779
		(void) bus_config_one_phci_child(pp->phys_path);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7780
	adjust_sort_vhcache_paths(vhc, ct_name, ct_addr, tok);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7781
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7782
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7783
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7784
 * Dequeue elements from vhci async client config list and bus configure
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7785
 * their corresponding phci clients.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7786
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7787
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7788
config_client_paths_thread(void *arg)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7789
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7790
	mdi_vhci_config_t *vhc = (mdi_vhci_config_t *)arg;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7791
	mdi_async_client_config_t *acc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7792
	clock_t quit_at_ticks;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7793
	clock_t idle_time = mdi_async_config_idle_time * TICKS_PER_SECOND;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7794
	callb_cpr_t cprinfo;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7795
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7796
	CALLB_CPR_INIT(&cprinfo, &vhc->vhc_lock, callb_generic_cpr,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7797
	    "mdi_config_client_paths");
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7798
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7799
	for (; ; ) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7800
		quit_at_ticks = ddi_get_lbolt() + idle_time;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7801
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7802
		mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7803
		while (!(vhc->vhc_flags & MDI_VHC_EXIT) &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7804
		    vhc->vhc_acc_list_head == NULL &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7805
		    ddi_get_lbolt() < quit_at_ticks) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7806
			CALLB_CPR_SAFE_BEGIN(&cprinfo);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7807
			(void) cv_timedwait(&vhc->vhc_cv, &vhc->vhc_lock,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7808
			    quit_at_ticks);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7809
			CALLB_CPR_SAFE_END(&cprinfo, &vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7810
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7811
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7812
		if ((vhc->vhc_flags & MDI_VHC_EXIT) ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7813
		    vhc->vhc_acc_list_head == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7814
			goto out;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7815
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7816
		acc = vhc->vhc_acc_list_head;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7817
		vhc->vhc_acc_list_head = acc->acc_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7818
		if (vhc->vhc_acc_list_head == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7819
			vhc->vhc_acc_list_tail = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7820
		vhc->vhc_acc_count--;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7821
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7822
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7823
		config_client_paths_sync(vhc, acc->acc_ct_name,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7824
		    acc->acc_ct_addr, acc->acc_phclient_path_list_head,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7825
		    &acc->acc_token);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7826
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7827
		free_async_client_config(acc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7828
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7829
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7830
out:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7831
	vhc->vhc_acc_thrcount--;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7832
	/* CALLB_CPR_EXIT releases the vhc->vhc_lock */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7833
	CALLB_CPR_EXIT(&cprinfo);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7834
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7835
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7836
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7837
 * Arrange for all the phci client paths (pp_head) for the specified client
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7838
 * to be bus configured asynchronously by a thread.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7839
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7840
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7841
config_client_paths_async(mdi_vhci_config_t *vhc, char *ct_name, char *ct_addr,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7842
    mdi_phys_path_t *pp_head, mdi_vhcache_lookup_token_t *tok)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7843
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7844
	mdi_async_client_config_t *acc, *newacc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7845
	int create_thread;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7846
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7847
	if (pp_head == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7848
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7849
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7850
	if (mdi_mtc_off) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7851
		config_client_paths_sync(vhc, ct_name, ct_addr, pp_head, tok);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7852
		free_phclient_path_list(pp_head);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7853
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7854
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7855
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7856
	newacc = alloc_async_client_config(ct_name, ct_addr, pp_head, tok);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7857
	ASSERT(newacc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7858
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7859
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7860
	for (acc = vhc->vhc_acc_list_head; acc != NULL; acc = acc->acc_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7861
		if (strcmp(ct_name, acc->acc_ct_name) == 0 &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7862
		    strcmp(ct_addr, acc->acc_ct_addr) == 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7863
			free_async_client_config(newacc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7864
			mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7865
			return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7866
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7867
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7868
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7869
	if (vhc->vhc_acc_list_head == NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7870
		vhc->vhc_acc_list_head = newacc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7871
	else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7872
		vhc->vhc_acc_list_tail->acc_next = newacc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7873
	vhc->vhc_acc_list_tail = newacc;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7874
	vhc->vhc_acc_count++;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7875
	if (vhc->vhc_acc_count <= vhc->vhc_acc_thrcount) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7876
		cv_broadcast(&vhc->vhc_cv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7877
		create_thread = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7878
	} else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7879
		vhc->vhc_acc_thrcount++;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7880
		create_thread = 1;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7881
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7882
	mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7883
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7884
	if (create_thread)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7885
		(void) thread_create(NULL, 0, config_client_paths_thread, vhc,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7886
		    0, &p0, TS_RUN, minclsyspri);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7887
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7888
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7889
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7890
 * Return number of online paths for the specified client.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7891
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7892
static int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7893
nonline_paths(mdi_vhcache_client_t *cct)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7894
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7895
	mdi_vhcache_pathinfo_t *cpi;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7896
	int online_count = 0;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7897
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7898
	for (cpi = cct->cct_cpi_head; cpi != NULL; cpi = cpi->cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7899
		if (cpi->cpi_pip != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7900
			MDI_PI_LOCK(cpi->cpi_pip);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7901
			if (cpi->cpi_pip->pi_state == MDI_PATHINFO_STATE_ONLINE)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7902
				online_count++;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7903
			MDI_PI_UNLOCK(cpi->cpi_pip);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7904
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7905
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7906
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7907
	return (online_count);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7908
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7909
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7910
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7911
 * Bus configure all paths for the specified vhci client.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7912
 * If at least one path for the client is already online, the remaining paths
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7913
 * will be configured asynchronously. Otherwise, it synchronously configures
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7914
 * the paths until at least one path is online and then rest of the paths
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7915
 * will be configured asynchronously.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7916
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7917
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7918
config_client_paths(mdi_vhci_config_t *vhc, char *ct_name, char *ct_addr)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7919
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7920
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7921
	mdi_phys_path_t *pp_head, *pp;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7922
	mdi_vhcache_client_t *cct;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7923
	mdi_vhcache_lookup_token_t tok;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7924
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7925
	ASSERT(RW_LOCK_HELD(&vhcache->vhcache_lock));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7926
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7927
	init_vhcache_lookup_token(&tok, NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7928
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7929
	if (ct_name == NULL || ct_addr == NULL ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7930
	    (cct = lookup_vhcache_client(vhcache, ct_name, ct_addr, &tok))
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7931
	    == NULL ||
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7932
	    (pp_head = build_phclient_path_list(cct, ct_name)) == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7933
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7934
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7935
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7936
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7937
	/* if at least one path is online, configure the rest asynchronously */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7938
	if (nonline_paths(cct) > 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7939
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7940
		config_client_paths_async(vhc, ct_name, ct_addr, pp_head, &tok);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7941
		return;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7942
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7943
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7944
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7945
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7946
	for (pp = pp_head; pp != NULL; pp = pp->phys_path_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7947
		if (bus_config_one_phci_child(pp->phys_path) == MDI_SUCCESS) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7948
			rw_enter(&vhcache->vhcache_lock, RW_READER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7949
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7950
			if ((cct = lookup_vhcache_client(vhcache, ct_name,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7951
			    ct_addr, &tok)) == NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7952
				rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7953
				goto out;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7954
			}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7955
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7956
			if (nonline_paths(cct) > 0 &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7957
			    pp->phys_path_next != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7958
				rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7959
				config_client_paths_async(vhc, ct_name, ct_addr,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7960
				    pp->phys_path_next, &tok);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7961
				pp->phys_path_next = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7962
				goto out;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7963
			}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7964
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7965
			rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7966
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7967
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7968
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7969
	adjust_sort_vhcache_paths(vhc, ct_name, ct_addr, &tok);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7970
out:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7971
	free_phclient_path_list(pp_head);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7972
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7973
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7974
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7975
single_threaded_vhconfig_enter(mdi_vhci_config_t *vhc)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7976
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7977
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7978
	while (vhc->vhc_flags & MDI_VHC_SINGLE_THREADED)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7979
		cv_wait(&vhc->vhc_cv, &vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7980
	vhc->vhc_flags |= MDI_VHC_SINGLE_THREADED;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7981
	mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7982
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7983
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7984
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7985
single_threaded_vhconfig_exit(mdi_vhci_config_t *vhc)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7986
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7987
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7988
	vhc->vhc_flags &= ~MDI_VHC_SINGLE_THREADED;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7989
	cv_broadcast(&vhc->vhc_cv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7990
	mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7991
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7992
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7993
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7994
 * Attach the phci driver instances associated with the vhci:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7995
 * If root is mounted attach all phci driver instances.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7996
 * If root is not mounted, attach the instances of only those phci
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7997
 * drivers that have the root support.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7998
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  7999
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8000
attach_phci_drivers(mdi_vhci_config_t *vhc, int root_mounted)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8001
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8002
	int  i;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8003
	major_t m;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8004
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8005
	for (i = 0; i < vhc->vhc_nphci_drivers; i++) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8006
		if (root_mounted == 0 &&
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8007
		    vhc->vhc_phci_driver_list[i].phdriver_root_support == 0)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8008
			continue;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8009
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8010
		m = ddi_name_to_major(
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8011
		    vhc->vhc_phci_driver_list[i].phdriver_name);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8012
		if (m != (major_t)-1) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8013
			if (ddi_hold_installed_driver(m) != NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8014
				ddi_rele_driver(m);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8015
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8016
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8017
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8018
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8019
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8020
 * Build vhci cache:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8021
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8022
 * Attach phci driver instances and then drive BUS_CONFIG_ALL on
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8023
 * the phci driver instances. During this process the cache gets built.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8024
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8025
 * Cache is built fully if the root is mounted (i.e., root_mounted is nonzero).
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8026
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8027
 * If the root is not mounted, phci drivers that do not have root support
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8028
 * are not attached. As a result the cache is built partially. The entries
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8029
 * in the cache reflect only those phci drivers that have root support.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8030
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8031
static vhcache_build_status_t
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8032
build_vhci_cache(mdi_vhci_config_t *vhc, int root_mounted)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8033
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8034
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8035
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8036
	rw_enter(&vhcache->vhcache_lock, RW_READER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8037
	if (vhcache->vhcache_flags & MDI_VHCI_CACHE_SETUP_DONE) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8038
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8039
		return (VHCACHE_NOT_REBUILT);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8040
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8041
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8042
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8043
	attach_phci_drivers(vhc, root_mounted);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8044
	bus_config_all_phcis(vhcache, NDI_DRV_CONF_REPROBE | NDI_NO_EVENT,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8045
	    BUS_CONFIG_ALL, (major_t)-1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8046
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8047
	if (root_mounted) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8048
		rw_enter(&vhcache->vhcache_lock, RW_WRITER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8049
		vhcache->vhcache_flags |= MDI_VHCI_CACHE_SETUP_DONE;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8050
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8051
		vhcache_dirty(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8052
		return (VHCACHE_FULLY_BUILT);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8053
	} else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8054
		return (VHCACHE_PARTIALLY_BUILT);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8055
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8056
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8057
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8058
 * Wait until the root is mounted and then build the vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8059
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8060
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8061
build_vhci_cache_thread(void *arg)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8062
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8063
	mdi_vhci_config_t *vhc = (mdi_vhci_config_t *)arg;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8064
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8065
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8066
	while (!modrootloaded && !(vhc->vhc_flags & MDI_VHC_EXIT)) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8067
		(void) cv_timedwait(&vhc->vhc_cv, &vhc->vhc_lock,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8068
		    ddi_get_lbolt() + 10 * TICKS_PER_SECOND);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8069
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8070
	if (vhc->vhc_flags & MDI_VHC_EXIT)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8071
		goto out;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8072
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8073
	mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8074
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8075
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8076
	 * Now that the root is mounted. So build_vhci_cache() will build
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8077
	 * the full cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8078
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8079
	(void) build_vhci_cache(vhc, 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8080
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8081
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8082
out:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8083
	vhc->vhc_flags &= ~MDI_VHC_BUILD_VHCI_CACHE_THREAD;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8084
	mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8085
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8086
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8087
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8088
 * Build vhci cache - a wrapper for build_vhci_cache().
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8089
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8090
 * In a normal case on-disk vhci cache is read and setup during booting.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8091
 * But if the on-disk vhci cache is not there or deleted or corrupted then
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8092
 * this function sets up the vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8093
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8094
 * The cache is built fully if the root is mounted.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8095
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8096
 * If the root is not mounted, initially the cache is built reflecting only
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8097
 * those driver entries that have the root support. A separate thread is
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8098
 * created to handle the creation of full cache. This thread will wait
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8099
 * until the root is mounted and then rebuilds the cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8100
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8101
static int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8102
e_build_vhci_cache(mdi_vhci_config_t *vhc)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8103
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8104
	vhcache_build_status_t rv;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8105
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8106
	single_threaded_vhconfig_enter(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8107
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8108
	mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8109
	if (vhc->vhc_flags & MDI_VHC_BUILD_VHCI_CACHE_THREAD) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8110
		if (modrootloaded) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8111
			cv_broadcast(&vhc->vhc_cv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8112
			/* wait until build vhci cache thread exits */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8113
			while (vhc->vhc_flags & MDI_VHC_BUILD_VHCI_CACHE_THREAD)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8114
				cv_wait(&vhc->vhc_cv, &vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8115
			rv = VHCACHE_FULLY_BUILT;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8116
		} else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8117
			/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8118
			 * The presense of MDI_VHC_BUILD_VHCI_CACHE_THREAD
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8119
			 * flag indicates that the cache has already been
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8120
			 * partially built.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8121
			 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8122
			rv = VHCACHE_PARTIALLY_BUILT;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8123
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8124
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8125
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8126
		single_threaded_vhconfig_exit(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8127
		return (rv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8128
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8129
	mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8130
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8131
	rv = build_vhci_cache(vhc, modrootloaded);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8132
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8133
	if (rv == VHCACHE_PARTIALLY_BUILT) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8134
		/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8135
		 * create a thread; this thread will wait until the root is
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8136
		 * mounted and then fully rebuilds the cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8137
		 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8138
		mutex_enter(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8139
		vhc->vhc_flags |= MDI_VHC_BUILD_VHCI_CACHE_THREAD;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8140
		mutex_exit(&vhc->vhc_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8141
		(void) thread_create(NULL, 0, build_vhci_cache_thread,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8142
		    vhc, 0, &p0, TS_RUN, minclsyspri);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8143
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8144
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8145
	single_threaded_vhconfig_exit(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8146
	return (rv);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8147
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8148
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8149
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8150
 * Generic vhci bus config implementation:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8151
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8152
 * Parameters
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8153
 *	vdip	vhci dip
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8154
 *	flags	bus config flags
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8155
 *	op	bus config operation
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8156
 *	The remaining parameters are bus config operation specific
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8157
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8158
 * for BUS_CONFIG_ONE
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8159
 *	arg	pointer to name@addr
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8160
 *	child	upon successful return from this function, *child will be
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8161
 *		set to the configured and held devinfo child node of vdip.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8162
 *	ct_addr	pointer to client address (i.e. GUID)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8163
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8164
 * for BUS_CONFIG_DRIVER
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8165
 *	arg	major number of the driver
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8166
 *	child and ct_addr parameters are ignored
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8167
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8168
 * for BUS_CONFIG_ALL
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8169
 *	arg, child, and ct_addr parameters are ignored
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8170
 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8171
 * Note that for the rest of the bus config operations, this function simply
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8172
 * calls the framework provided default bus config routine.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8173
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8174
int
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8175
mdi_vhci_bus_config(dev_info_t *vdip, uint_t flags, ddi_bus_config_op_t op,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8176
    void *arg, dev_info_t **child, char *ct_addr)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8177
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8178
	mdi_vhci_t *vh = i_devi_get_vhci(vdip);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8179
	mdi_vhci_config_t *vhc = vh->vh_config;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8180
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8181
	vhcache_build_status_t rv = VHCACHE_NOT_REBUILT;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8182
	char *cp;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8183
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8184
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8185
	 * While bus configuring phcis, the phci driver interactions with MDI
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8186
	 * cause child nodes to be enumerated under the vhci node for which
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8187
	 * they need to ndi_devi_enter the vhci node.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8188
	 *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8189
	 * Unfortunately, to avoid the deadlock, we ourself can not wait for
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8190
	 * for the bus config operations on phcis to finish while holding the
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8191
	 * ndi_devi_enter lock. To avoid this deadlock, skip bus configs on
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8192
	 * phcis and call the default framework provided bus config function
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8193
	 * if we are called with ndi_devi_enter lock held.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8194
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8195
	if (DEVI_BUSY_OWNED(vdip)) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8196
		MDI_DEBUG(2, (CE_NOTE, vdip,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8197
		    "!MDI: vhci bus config: vhci dip is busy owned\n"));
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8198
		goto default_bus_config;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8199
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8200
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8201
	rw_enter(&vhcache->vhcache_lock, RW_READER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8202
	if (!(vhcache->vhcache_flags & MDI_VHCI_CACHE_SETUP_DONE)) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8203
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8204
		rv = e_build_vhci_cache(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8205
		rw_enter(&vhcache->vhcache_lock, RW_READER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8206
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8207
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8208
	switch (op) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8209
	case BUS_CONFIG_ONE:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8210
		/* extract node name */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8211
		cp = (char *)arg;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8212
		while (*cp != '\0' && *cp != '@')
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8213
			cp++;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8214
		if (*cp == '@') {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8215
			*cp = '\0';
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8216
			config_client_paths(vhc, (char *)arg, ct_addr);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8217
			/* config_client_paths() releases the cache_lock */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8218
			*cp = '@';
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8219
		} else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8220
			rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8221
		break;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8222
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8223
	case BUS_CONFIG_DRIVER:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8224
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8225
		if (rv == VHCACHE_NOT_REBUILT)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8226
			bus_config_all_phcis(vhcache, flags, op,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8227
			    (major_t)(uintptr_t)arg);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8228
		break;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8229
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8230
	case BUS_CONFIG_ALL:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8231
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8232
		if (rv == VHCACHE_NOT_REBUILT)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8233
			bus_config_all_phcis(vhcache, flags, op, -1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8234
		break;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8235
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8236
	default:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8237
		rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8238
		break;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8239
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8240
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8241
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8242
default_bus_config:
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8243
	/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8244
	 * All requested child nodes are enumerated under the vhci.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8245
	 * Now configure them.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8246
	 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8247
	if (ndi_busop_bus_config(vdip, flags, op, arg, child, 0) ==
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8248
	    NDI_SUCCESS) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8249
		return (MDI_SUCCESS);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8250
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8251
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8252
	return (MDI_FAILURE);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8253
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8254
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8255
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8256
 * Read the on-disk vhci cache into an nvlist for the specified vhci class.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8257
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8258
static nvlist_t *
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8259
read_on_disk_vhci_cache(char *vhci_class)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8260
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8261
	nvlist_t *nvl;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8262
	int err;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8263
	char *filename;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8264
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8265
	filename = vhclass2vhcache_filename(vhci_class);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8266
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8267
	if ((err = fread_nvlist(filename, &nvl)) == 0) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8268
		kmem_free(filename, strlen(filename) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8269
		return (nvl);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8270
	} else if (err == EIO)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8271
		cmn_err(CE_WARN, "%s: I/O error, will recreate\n", filename);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8272
	else if (err == EINVAL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8273
		cmn_err(CE_WARN,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8274
		    "%s: data file corrupted, will recreate\n", filename);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8275
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8276
	kmem_free(filename, strlen(filename) + 1);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8277
	return (NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8278
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8279
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8280
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8281
 * Read on-disk vhci cache into nvlists for all vhci classes.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8282
 * Called during booting by i_ddi_read_devices_files().
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8283
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8284
void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8285
mdi_read_devices_files(void)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8286
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8287
	int i;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8288
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8289
	for (i = 0; i < N_VHCI_CLASSES; i++)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8290
		vhcache_nvl[i] = read_on_disk_vhci_cache(vhci_class_list[i]);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8291
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8292
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8293
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8294
 * Remove all stale entries from vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8295
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8296
static void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8297
clean_vhcache(mdi_vhci_config_t *vhc)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8298
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8299
	mdi_vhci_cache_t *vhcache = &vhc->vhc_vhcache;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8300
	mdi_vhcache_phci_t *cphci, *cphci_head, *cphci_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8301
	mdi_vhcache_client_t *cct, *cct_head, *cct_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8302
	mdi_vhcache_pathinfo_t *cpi, *cpi_head, *cpi_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8303
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8304
	rw_enter(&vhcache->vhcache_lock, RW_WRITER);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8305
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8306
	cct_head = vhcache->vhcache_client_head;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8307
	vhcache->vhcache_client_head = vhcache->vhcache_client_tail = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8308
	for (cct = cct_head; cct != NULL; cct = cct_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8309
		cct_next = cct->cct_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8310
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8311
		cpi_head = cct->cct_cpi_head;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8312
		cct->cct_cpi_head = cct->cct_cpi_tail = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8313
		for (cpi = cpi_head; cpi != NULL; cpi = cpi_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8314
			cpi_next = cpi->cpi_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8315
			if (cpi->cpi_pip != NULL) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8316
				ASSERT(cpi->cpi_cphci->cphci_phci != NULL);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8317
				enqueue_tail_vhcache_pathinfo(cct, cpi);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8318
			} else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8319
				free_vhcache_pathinfo(cpi);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8320
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8321
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8322
		if (cct->cct_cpi_head != NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8323
			enqueue_vhcache_client(vhcache, cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8324
		else {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8325
			(void) mod_hash_destroy(vhcache->vhcache_client_hash,
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8326
			    (mod_hash_key_t)cct->cct_name_addr);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8327
			free_vhcache_client(cct);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8328
		}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8329
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8330
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8331
	cphci_head = vhcache->vhcache_phci_head;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8332
	vhcache->vhcache_phci_head = vhcache->vhcache_phci_tail = NULL;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8333
	for (cphci = cphci_head; cphci != NULL; cphci = cphci_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8334
		cphci_next = cphci->cphci_next;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8335
		if (cphci->cphci_phci != NULL)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8336
			enqueue_vhcache_phci(vhcache, cphci);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8337
		else
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8338
			free_vhcache_phci(cphci);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8339
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8340
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8341
	vhcache->vhcache_clean_time = lbolt64;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8342
	rw_exit(&vhcache->vhcache_lock);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8343
	vhcache_dirty(vhc);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8344
}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8345
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8346
/*
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8347
 * Remove all stale entries from vhci cache.
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8348
 * Called by i_ddi_clean_devices_files() during the execution of devfsadm -C
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8349
 */
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8350
void
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8351
mdi_clean_vhcache(void)
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8352
{
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8353
	mdi_vhci_t *vh;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8354
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8355
	mutex_enter(&mdi_mutex);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8356
	for (vh = mdi_vhci_head; vh != NULL; vh = vh->vh_next) {
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8357
		vh->vh_refcnt++;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8358
		mutex_exit(&mdi_mutex);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8359
		clean_vhcache(vh->vh_config);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8360
		mutex_enter(&mdi_mutex);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8361
		vh->vh_refcnt--;
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8362
	}
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8363
	mutex_exit(&mdi_mutex);
964ddd439490 PSARC 2005/583 VHCI Driven Device Enumeration
ramat
parents: 82
diff changeset
  8364
}