xref: /titanic_41/usr/src/uts/common/avs/ns/rdc/rdc.c (revision 3270659f55e0928d6edec3d26217cc29398a8149)
1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte /*
22*3270659fSSrikanth, Ramana  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23fcf3ce44SJohn Forte  * Use is subject to license terms.
24fcf3ce44SJohn Forte  */
25fcf3ce44SJohn Forte 
26fcf3ce44SJohn Forte #define	_RDC_
27fcf3ce44SJohn Forte #include <sys/types.h>
28fcf3ce44SJohn Forte #include <sys/ksynch.h>
29fcf3ce44SJohn Forte #include <sys/kmem.h>
30fcf3ce44SJohn Forte #include <sys/errno.h>
31fcf3ce44SJohn Forte #include <sys/conf.h>
32fcf3ce44SJohn Forte #include <sys/cmn_err.h>
33fcf3ce44SJohn Forte #include <sys/modctl.h>
34fcf3ce44SJohn Forte #include <sys/cred.h>
35fcf3ce44SJohn Forte #include <sys/ddi.h>
36fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h>
37fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_k.h>
38fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h>
39fcf3ce44SJohn Forte 
40fcf3ce44SJohn Forte #include <sys/nsc_thread.h>
41fcf3ce44SJohn Forte #ifdef DS_DDICT
42fcf3ce44SJohn Forte #include "../contract.h"
43fcf3ce44SJohn Forte #endif
44fcf3ce44SJohn Forte #include <sys/nsctl/nsctl.h>
45fcf3ce44SJohn Forte #include <sys/nsctl/nsvers.h>
46fcf3ce44SJohn Forte 
47fcf3ce44SJohn Forte #include <sys/sdt.h>		/* dtrace is S10 or later */
48fcf3ce44SJohn Forte 
49fcf3ce44SJohn Forte #include "rdc.h"
50fcf3ce44SJohn Forte #include "rdc_io.h"
51fcf3ce44SJohn Forte #include "rdc_bitmap.h"
52fcf3ce44SJohn Forte #include "rdc_ioctl.h"
53fcf3ce44SJohn Forte #include "rdcsrv.h"
54fcf3ce44SJohn Forte #include "rdc_diskq.h"
55fcf3ce44SJohn Forte 
56fcf3ce44SJohn Forte #define	DIDINIT		0x01
57fcf3ce44SJohn Forte #define	DIDNODES	0x02
58fcf3ce44SJohn Forte #define	DIDCONFIG	0x04
59fcf3ce44SJohn Forte 
60fcf3ce44SJohn Forte static int rdcopen(dev_t *devp, int flag, int otyp, cred_t *crp);
61fcf3ce44SJohn Forte static int rdcclose(dev_t dev, int flag, int otyp, cred_t *crp);
62fcf3ce44SJohn Forte static int rdcprint(dev_t dev, char *str);
63fcf3ce44SJohn Forte static int rdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp,
64fcf3ce44SJohn Forte 	int *rvp);
65fcf3ce44SJohn Forte static int rdcattach(dev_info_t *dip, ddi_attach_cmd_t cmd);
66fcf3ce44SJohn Forte static int rdcdetach(dev_info_t *dip, ddi_detach_cmd_t cmd);
67fcf3ce44SJohn Forte static int rdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
68fcf3ce44SJohn Forte 	void **result);
69fcf3ce44SJohn Forte #ifdef	DEBUG
70fcf3ce44SJohn Forte static int rdc_clrkstat(void *);
71fcf3ce44SJohn Forte #endif
72fcf3ce44SJohn Forte 
73fcf3ce44SJohn Forte /*
74fcf3ce44SJohn Forte  * kstat interface
75fcf3ce44SJohn Forte  */
76fcf3ce44SJohn Forte static kstat_t *sndr_kstats;
77fcf3ce44SJohn Forte 
78fcf3ce44SJohn Forte int sndr_info_stats_update(kstat_t *ksp, int rw);
79fcf3ce44SJohn Forte 
80fcf3ce44SJohn Forte static sndr_m_stats_t sndr_info_stats = {
81fcf3ce44SJohn Forte 	{RDC_MKSTAT_MAXSETS,			KSTAT_DATA_ULONG},
82fcf3ce44SJohn Forte 	{RDC_MKSTAT_MAXFBAS,			KSTAT_DATA_ULONG},
83fcf3ce44SJohn Forte 	{RDC_MKSTAT_RPC_TIMEOUT,		KSTAT_DATA_ULONG},
84fcf3ce44SJohn Forte 	{RDC_MKSTAT_HEALTH_THRES,		KSTAT_DATA_ULONG},
85fcf3ce44SJohn Forte 	{RDC_MKSTAT_BITMAP_WRITES,		KSTAT_DATA_ULONG},
86fcf3ce44SJohn Forte 	{RDC_MKSTAT_CLNT_COTS_CALLS,		KSTAT_DATA_ULONG},
87fcf3ce44SJohn Forte 	{RDC_MKSTAT_CLNT_CLTS_CALLS,		KSTAT_DATA_ULONG},
88fcf3ce44SJohn Forte 	{RDC_MKSTAT_SVC_COTS_CALLS,		KSTAT_DATA_ULONG},
89fcf3ce44SJohn Forte 	{RDC_MKSTAT_SVC_CLTS_CALLS,		KSTAT_DATA_ULONG},
90fcf3ce44SJohn Forte 	{RDC_MKSTAT_BITMAP_REF_DELAY,		KSTAT_DATA_ULONG}
91fcf3ce44SJohn Forte };
92fcf3ce44SJohn Forte 
93fcf3ce44SJohn Forte int rdc_info_stats_update(kstat_t *ksp, int rw);
94fcf3ce44SJohn Forte 
95fcf3ce44SJohn Forte static rdc_info_stats_t rdc_info_stats = {
96fcf3ce44SJohn Forte 	{RDC_IKSTAT_FLAGS,		KSTAT_DATA_ULONG},
97fcf3ce44SJohn Forte 	{RDC_IKSTAT_SYNCFLAGS,		KSTAT_DATA_ULONG},
98fcf3ce44SJohn Forte 	{RDC_IKSTAT_BMPFLAGS,		KSTAT_DATA_ULONG},
99fcf3ce44SJohn Forte 	{RDC_IKSTAT_SYNCPOS,		KSTAT_DATA_ULONG},
100fcf3ce44SJohn Forte 	{RDC_IKSTAT_VOLSIZE,		KSTAT_DATA_ULONG},
101fcf3ce44SJohn Forte 	{RDC_IKSTAT_BITSSET,		KSTAT_DATA_ULONG},
102fcf3ce44SJohn Forte 	{RDC_IKSTAT_AUTOSYNC,		KSTAT_DATA_ULONG},
103fcf3ce44SJohn Forte 	{RDC_IKSTAT_MAXQFBAS,		KSTAT_DATA_ULONG},
104fcf3ce44SJohn Forte 	{RDC_IKSTAT_MAXQITEMS,		KSTAT_DATA_ULONG},
105fcf3ce44SJohn Forte 	{RDC_IKSTAT_FILE,		KSTAT_DATA_STRING},
106fcf3ce44SJohn Forte 	{RDC_IKSTAT_SECFILE,		KSTAT_DATA_STRING},
107fcf3ce44SJohn Forte 	{RDC_IKSTAT_BITMAP,		KSTAT_DATA_STRING},
108fcf3ce44SJohn Forte 	{RDC_IKSTAT_PRIMARY_HOST,	KSTAT_DATA_STRING},
109fcf3ce44SJohn Forte 	{RDC_IKSTAT_SECONDARY_HOST,	KSTAT_DATA_STRING},
110fcf3ce44SJohn Forte 	{RDC_IKSTAT_TYPE_FLAG,		KSTAT_DATA_ULONG},
111fcf3ce44SJohn Forte 	{RDC_IKSTAT_BMP_SIZE,		KSTAT_DATA_ULONG},
112fcf3ce44SJohn Forte 	{RDC_IKSTAT_DISK_STATUS,	KSTAT_DATA_ULONG},
113fcf3ce44SJohn Forte 	{RDC_IKSTAT_IF_DOWN,		KSTAT_DATA_ULONG},
114fcf3ce44SJohn Forte 	{RDC_IKSTAT_IF_RPC_VERSION,	KSTAT_DATA_ULONG},
115fcf3ce44SJohn Forte 	{RDC_IKSTAT_ASYNC_BLOCK_HWM,	KSTAT_DATA_ULONG},
116fcf3ce44SJohn Forte 	{RDC_IKSTAT_ASYNC_ITEM_HWM,	KSTAT_DATA_ULONG},
117fcf3ce44SJohn Forte 	{RDC_IKSTAT_ASYNC_THROTTLE_DELAY,	KSTAT_DATA_ULONG},
118fcf3ce44SJohn Forte 	{RDC_IKSTAT_ASYNC_ITEMS,	KSTAT_DATA_ULONG},
119fcf3ce44SJohn Forte 	{RDC_IKSTAT_ASYNC_BLOCKS,	KSTAT_DATA_ULONG},
120fcf3ce44SJohn Forte 	{RDC_IKSTAT_QUEUE_TYPE,		KSTAT_DATA_CHAR}
121fcf3ce44SJohn Forte };
122fcf3ce44SJohn Forte 
123fcf3ce44SJohn Forte static struct cb_ops rdc_cb_ops = {
124fcf3ce44SJohn Forte 	rdcopen,
125fcf3ce44SJohn Forte 	rdcclose,
126fcf3ce44SJohn Forte 	nulldev,		/* no strategy */
127fcf3ce44SJohn Forte 	rdcprint,
128fcf3ce44SJohn Forte 	nodev,			/* no dump */
129fcf3ce44SJohn Forte 	nodev,			/* no read */
130fcf3ce44SJohn Forte 	nodev,			/* no write */
131fcf3ce44SJohn Forte 	rdcioctl,
132fcf3ce44SJohn Forte 	nodev,			/* no devmap */
133fcf3ce44SJohn Forte 	nodev,			/* no mmap */
134fcf3ce44SJohn Forte 	nodev,			/* no segmap */
135fcf3ce44SJohn Forte 	nochpoll,
136fcf3ce44SJohn Forte 	ddi_prop_op,
137fcf3ce44SJohn Forte 	NULL,			/* not STREAMS */
138fcf3ce44SJohn Forte 	D_NEW | D_MP | D_64BIT,
139fcf3ce44SJohn Forte 	CB_REV,
140fcf3ce44SJohn Forte 	nodev,			/* no aread */
141fcf3ce44SJohn Forte 	nodev,			/* no awrite */
142fcf3ce44SJohn Forte };
143fcf3ce44SJohn Forte 
144fcf3ce44SJohn Forte static struct dev_ops rdc_ops = {
145fcf3ce44SJohn Forte 	DEVO_REV,
146fcf3ce44SJohn Forte 	0,
147fcf3ce44SJohn Forte 	rdcgetinfo,
148fcf3ce44SJohn Forte 	nulldev,		/* identify */
149fcf3ce44SJohn Forte 	nulldev,		/* probe */
150fcf3ce44SJohn Forte 	rdcattach,
151fcf3ce44SJohn Forte 	rdcdetach,
152fcf3ce44SJohn Forte 	nodev,			/* no reset */
153fcf3ce44SJohn Forte 	&rdc_cb_ops,
154fcf3ce44SJohn Forte 	(struct bus_ops *)NULL
155fcf3ce44SJohn Forte };
156fcf3ce44SJohn Forte 
157fcf3ce44SJohn Forte static struct modldrv rdc_ldrv = {
158fcf3ce44SJohn Forte 	&mod_driverops,
159fcf3ce44SJohn Forte 	"nws:Remote Mirror:" ISS_VERSION_STR,
160fcf3ce44SJohn Forte 	&rdc_ops
161fcf3ce44SJohn Forte };
162fcf3ce44SJohn Forte 
163fcf3ce44SJohn Forte static struct modlinkage rdc_modlinkage = {
164fcf3ce44SJohn Forte 	MODREV_1,
165fcf3ce44SJohn Forte 	&rdc_ldrv,
166fcf3ce44SJohn Forte 	NULL
167fcf3ce44SJohn Forte };
168fcf3ce44SJohn Forte 
169fcf3ce44SJohn Forte const	int sndr_major_rev = ISS_VERSION_MAJ;
170fcf3ce44SJohn Forte const	int sndr_minor_rev = ISS_VERSION_MIN;
171fcf3ce44SJohn Forte const	int sndr_micro_rev = ISS_VERSION_MIC;
172fcf3ce44SJohn Forte const	int sndr_baseline_rev = ISS_VERSION_NUM;
173fcf3ce44SJohn Forte static	char sndr_version[16];
174fcf3ce44SJohn Forte 
175fcf3ce44SJohn Forte static void *rdc_dip;
176fcf3ce44SJohn Forte 
177fcf3ce44SJohn Forte extern int _rdc_init_dev();
178fcf3ce44SJohn Forte extern void _rdc_deinit_dev();
179fcf3ce44SJohn Forte extern void rdc_link_down_free();
180fcf3ce44SJohn Forte 
181fcf3ce44SJohn Forte int rdc_bitmap_mode;
182fcf3ce44SJohn Forte int rdc_auto_sync;
183fcf3ce44SJohn Forte int rdc_max_sets;
184fcf3ce44SJohn Forte extern int rdc_health_thres;
185fcf3ce44SJohn Forte 
186fcf3ce44SJohn Forte kmutex_t rdc_sync_mutex;
187fcf3ce44SJohn Forte rdc_sync_event_t rdc_sync_event;
188fcf3ce44SJohn Forte clock_t rdc_sync_event_timeout;
189fcf3ce44SJohn Forte 
190fcf3ce44SJohn Forte static void
rdc_sync_event_init()191fcf3ce44SJohn Forte rdc_sync_event_init()
192fcf3ce44SJohn Forte {
193fcf3ce44SJohn Forte 	mutex_init(&rdc_sync_mutex, NULL, MUTEX_DRIVER, NULL);
194fcf3ce44SJohn Forte 	mutex_init(&rdc_sync_event.mutex, NULL, MUTEX_DRIVER, NULL);
195fcf3ce44SJohn Forte 	cv_init(&rdc_sync_event.cv, NULL, CV_DRIVER, NULL);
196fcf3ce44SJohn Forte 	cv_init(&rdc_sync_event.done_cv, NULL, CV_DRIVER, NULL);
197fcf3ce44SJohn Forte 	rdc_sync_event.master[0] = 0;
198fcf3ce44SJohn Forte 	rdc_sync_event.lbolt = (clock_t)0;
199fcf3ce44SJohn Forte 	rdc_sync_event_timeout = RDC_SYNC_EVENT_TIMEOUT;
200fcf3ce44SJohn Forte }
201fcf3ce44SJohn Forte 
202fcf3ce44SJohn Forte 
203fcf3ce44SJohn Forte static void
rdc_sync_event_destroy()204fcf3ce44SJohn Forte rdc_sync_event_destroy()
205fcf3ce44SJohn Forte {
206fcf3ce44SJohn Forte 	mutex_destroy(&rdc_sync_mutex);
207fcf3ce44SJohn Forte 	mutex_destroy(&rdc_sync_event.mutex);
208fcf3ce44SJohn Forte 	cv_destroy(&rdc_sync_event.cv);
209fcf3ce44SJohn Forte 	cv_destroy(&rdc_sync_event.done_cv);
210fcf3ce44SJohn Forte }
211fcf3ce44SJohn Forte 
212fcf3ce44SJohn Forte 
213fcf3ce44SJohn Forte 
214fcf3ce44SJohn Forte int
_init(void)215fcf3ce44SJohn Forte _init(void)
216fcf3ce44SJohn Forte {
217fcf3ce44SJohn Forte 	return (mod_install(&rdc_modlinkage));
218fcf3ce44SJohn Forte }
219fcf3ce44SJohn Forte 
220fcf3ce44SJohn Forte int
_fini(void)221fcf3ce44SJohn Forte _fini(void)
222fcf3ce44SJohn Forte {
223fcf3ce44SJohn Forte 	return (mod_remove(&rdc_modlinkage));
224fcf3ce44SJohn Forte }
225fcf3ce44SJohn Forte 
226fcf3ce44SJohn Forte int
_info(struct modinfo * modinfop)227fcf3ce44SJohn Forte _info(struct modinfo *modinfop)
228fcf3ce44SJohn Forte {
229fcf3ce44SJohn Forte 	return (mod_info(&rdc_modlinkage, modinfop));
230fcf3ce44SJohn Forte }
231fcf3ce44SJohn Forte 
232fcf3ce44SJohn Forte static int
rdcattach(dev_info_t * dip,ddi_attach_cmd_t cmd)233fcf3ce44SJohn Forte rdcattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
234fcf3ce44SJohn Forte {
235fcf3ce44SJohn Forte 	intptr_t flags;
236fcf3ce44SJohn Forte 	int instance;
237fcf3ce44SJohn Forte 	int i;
238fcf3ce44SJohn Forte 
239fcf3ce44SJohn Forte 	/*CONSTCOND*/
240fcf3ce44SJohn Forte 	ASSERT(sizeof (u_longlong_t) == 8);
241fcf3ce44SJohn Forte 
242fcf3ce44SJohn Forte 	if (cmd != DDI_ATTACH)
243fcf3ce44SJohn Forte 		return (DDI_FAILURE);
244fcf3ce44SJohn Forte 
245fcf3ce44SJohn Forte 	(void) strncpy(sndr_version, _VERSION_, sizeof (sndr_version));
246fcf3ce44SJohn Forte 
247fcf3ce44SJohn Forte 	instance = ddi_get_instance(dip);
248fcf3ce44SJohn Forte 	rdc_dip = dip;
249fcf3ce44SJohn Forte 
250fcf3ce44SJohn Forte 	flags = 0;
251fcf3ce44SJohn Forte 
252fcf3ce44SJohn Forte 	rdc_sync_event_init();
253fcf3ce44SJohn Forte 
254fcf3ce44SJohn Forte 	/*
255fcf3ce44SJohn Forte 	 * rdc_max_sets must be set before calling _rdc_load().
256fcf3ce44SJohn Forte 	 */
257fcf3ce44SJohn Forte 
258fcf3ce44SJohn Forte 	rdc_max_sets = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
259fcf3ce44SJohn Forte 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "rdc_max_sets", 64);
260fcf3ce44SJohn Forte 
261fcf3ce44SJohn Forte 	if (_rdc_init_dev()) {
262*3270659fSSrikanth, Ramana 		cmn_err(CE_WARN, "!rdc: _rdc_init_dev failed");
263fcf3ce44SJohn Forte 		goto out;
264fcf3ce44SJohn Forte 	}
265fcf3ce44SJohn Forte 	flags |= DIDINIT;
266fcf3ce44SJohn Forte 
267fcf3ce44SJohn Forte 	if (_rdc_load() != 0) {
268*3270659fSSrikanth, Ramana 		cmn_err(CE_WARN, "!rdc: _rdc_load failed");
269fcf3ce44SJohn Forte 		goto out;
270fcf3ce44SJohn Forte 	}
271fcf3ce44SJohn Forte 
272fcf3ce44SJohn Forte 	if (_rdc_configure()) {
273*3270659fSSrikanth, Ramana 		cmn_err(CE_WARN, "!rdc: _rdc_configure failed");
274fcf3ce44SJohn Forte 		goto out;
275fcf3ce44SJohn Forte 	}
276fcf3ce44SJohn Forte 	flags |= DIDCONFIG;
277fcf3ce44SJohn Forte 
278fcf3ce44SJohn Forte 	if (ddi_create_minor_node(dip, "rdc", S_IFCHR, instance, DDI_PSEUDO, 0)
279fcf3ce44SJohn Forte 	    != DDI_SUCCESS) {
280*3270659fSSrikanth, Ramana 		cmn_err(CE_WARN, "!rdc: could not create node.");
281fcf3ce44SJohn Forte 		goto out;
282fcf3ce44SJohn Forte 	}
283fcf3ce44SJohn Forte 	flags |= DIDNODES;
284fcf3ce44SJohn Forte 
285fcf3ce44SJohn Forte 	rdc_bitmap_mode = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
286fcf3ce44SJohn Forte 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
287fcf3ce44SJohn Forte 	    "rdc_bitmap_mode", 0);
288fcf3ce44SJohn Forte 
289fcf3ce44SJohn Forte 	switch (rdc_bitmap_mode) {
290fcf3ce44SJohn Forte 	case RDC_BMP_AUTO:		/* 0 */
291fcf3ce44SJohn Forte 		break;
292fcf3ce44SJohn Forte 	case RDC_BMP_ALWAYS:		/* 1 */
293fcf3ce44SJohn Forte 		break;
294fcf3ce44SJohn Forte 	case RDC_BMP_NEVER:		/* 2 */
295*3270659fSSrikanth, Ramana 		cmn_err(CE_NOTE, "!SNDR bitmap mode override");
296fcf3ce44SJohn Forte 		cmn_err(CE_CONT,
297*3270659fSSrikanth, Ramana 		    "!SNDR: bitmaps will only be written on shutdown\n");
298fcf3ce44SJohn Forte 		break;
299fcf3ce44SJohn Forte 	default:			/* unknown */
300fcf3ce44SJohn Forte 		cmn_err(CE_NOTE,
301*3270659fSSrikanth, Ramana 		    "!SNDR: unknown bitmap mode %d - autodetecting mode",
302fcf3ce44SJohn Forte 		    rdc_bitmap_mode);
303fcf3ce44SJohn Forte 		rdc_bitmap_mode = RDC_BMP_AUTO;
304fcf3ce44SJohn Forte 		break;
305fcf3ce44SJohn Forte 	}
306fcf3ce44SJohn Forte 
307fcf3ce44SJohn Forte 	rdc_bitmap_init();
308fcf3ce44SJohn Forte 
309fcf3ce44SJohn Forte 	rdc_auto_sync = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
310fcf3ce44SJohn Forte 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
311fcf3ce44SJohn Forte 	    "rdc_auto_sync", 0);
312fcf3ce44SJohn Forte 
313fcf3ce44SJohn Forte 	i = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
314fcf3ce44SJohn Forte 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
315fcf3ce44SJohn Forte 	    "rdc_health_thres", RDC_HEALTH_THRESHOLD);
316fcf3ce44SJohn Forte 	if (i >= RDC_MIN_HEALTH_THRES)
317fcf3ce44SJohn Forte 		rdc_health_thres = i;
318fcf3ce44SJohn Forte 	else
319*3270659fSSrikanth, Ramana 		cmn_err(CE_WARN, "!value rdc_heath_thres from rdc.conf ignored "
320fcf3ce44SJohn Forte 		    "as it is smaller than the min value of %d",
321fcf3ce44SJohn Forte 		    RDC_MIN_HEALTH_THRES);
322fcf3ce44SJohn Forte 
323fcf3ce44SJohn Forte 	ddi_set_driver_private(dip, (caddr_t)flags);
324fcf3ce44SJohn Forte 	ddi_report_dev(dip);
325fcf3ce44SJohn Forte 
326fcf3ce44SJohn Forte 	sndr_kstats = kstat_create(RDC_KSTAT_MODULE, 0,
327fcf3ce44SJohn Forte 	    RDC_KSTAT_MINFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
328fcf3ce44SJohn Forte 	    sizeof (sndr_m_stats_t) / sizeof (kstat_named_t),
329fcf3ce44SJohn Forte 	    KSTAT_FLAG_VIRTUAL);
330fcf3ce44SJohn Forte 
331fcf3ce44SJohn Forte 	if (sndr_kstats) {
332fcf3ce44SJohn Forte 		sndr_kstats->ks_data = &sndr_info_stats;
333fcf3ce44SJohn Forte 		sndr_kstats->ks_update = sndr_info_stats_update;
334fcf3ce44SJohn Forte 		sndr_kstats->ks_private = &rdc_k_info[0];
335fcf3ce44SJohn Forte 		kstat_install(sndr_kstats);
336fcf3ce44SJohn Forte 	} else
337*3270659fSSrikanth, Ramana 			cmn_err(CE_WARN, "!SNDR: module kstats failed");
338fcf3ce44SJohn Forte 
339fcf3ce44SJohn Forte 	return (DDI_SUCCESS);
340fcf3ce44SJohn Forte 
341fcf3ce44SJohn Forte out:
342fcf3ce44SJohn Forte 	DTRACE_PROBE(rdc_attach_failed);
343fcf3ce44SJohn Forte 	ddi_set_driver_private(dip, (caddr_t)flags);
344fcf3ce44SJohn Forte 	(void) rdcdetach(dip, DDI_DETACH);
345fcf3ce44SJohn Forte 	return (DDI_FAILURE);
346fcf3ce44SJohn Forte }
347fcf3ce44SJohn Forte 
348fcf3ce44SJohn Forte static int
rdcdetach(dev_info_t * dip,ddi_detach_cmd_t cmd)349fcf3ce44SJohn Forte rdcdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
350fcf3ce44SJohn Forte {
351fcf3ce44SJohn Forte 	rdc_k_info_t *krdc;
352fcf3ce44SJohn Forte 	rdc_u_info_t *urdc;
353fcf3ce44SJohn Forte 	int rdcd;
354fcf3ce44SJohn Forte 	intptr_t flags;
355fcf3ce44SJohn Forte 
356fcf3ce44SJohn Forte 
357fcf3ce44SJohn Forte 	if (cmd != DDI_DETACH) {
358fcf3ce44SJohn Forte 		DTRACE_PROBE(rdc_detach_unknown_cmd);
359fcf3ce44SJohn Forte 		return (DDI_FAILURE);
360fcf3ce44SJohn Forte 	}
361fcf3ce44SJohn Forte 
362fcf3ce44SJohn Forte 	if (rdc_k_info == NULL || rdc_u_info == NULL)
363fcf3ce44SJohn Forte 		goto cleanup;
364fcf3ce44SJohn Forte 
365fcf3ce44SJohn Forte 	mutex_enter(&rdc_conf_lock);
366fcf3ce44SJohn Forte 
367fcf3ce44SJohn Forte 	for (rdcd = 0; rdcd < rdc_max_sets; rdcd++) {
368fcf3ce44SJohn Forte 		krdc = &rdc_k_info[rdcd];
369fcf3ce44SJohn Forte 		urdc = &rdc_u_info[rdcd];
370fcf3ce44SJohn Forte 
371fcf3ce44SJohn Forte 		if (IS_ENABLED(urdc) || krdc->devices) {
372fcf3ce44SJohn Forte #ifdef DEBUG
373fcf3ce44SJohn Forte 			cmn_err(CE_WARN,
374fcf3ce44SJohn Forte 			    "!rdc: cannot detach, rdcd %d still in use", rdcd);
375fcf3ce44SJohn Forte #endif
376fcf3ce44SJohn Forte 			mutex_exit(&rdc_conf_lock);
377fcf3ce44SJohn Forte 			DTRACE_PROBE(rdc_detach_err_busy);
378fcf3ce44SJohn Forte 			return (DDI_FAILURE);
379fcf3ce44SJohn Forte 		}
380fcf3ce44SJohn Forte 	}
381fcf3ce44SJohn Forte 
382fcf3ce44SJohn Forte 	mutex_exit(&rdc_conf_lock);
383fcf3ce44SJohn Forte 
384fcf3ce44SJohn Forte cleanup:
385fcf3ce44SJohn Forte 	flags = (intptr_t)ddi_get_driver_private(dip);
386fcf3ce44SJohn Forte 
387fcf3ce44SJohn Forte 	if (flags & DIDNODES)
388fcf3ce44SJohn Forte 		ddi_remove_minor_node(dip, NULL);
389fcf3ce44SJohn Forte 
390fcf3ce44SJohn Forte 	if (sndr_kstats) {
391fcf3ce44SJohn Forte 		kstat_delete(sndr_kstats);
392fcf3ce44SJohn Forte 	}
393fcf3ce44SJohn Forte 	if (flags & DIDINIT)
394fcf3ce44SJohn Forte 		_rdc_deinit_dev();
395fcf3ce44SJohn Forte 
396fcf3ce44SJohn Forte 	if (flags & DIDCONFIG) {
397fcf3ce44SJohn Forte 		(void) _rdc_deconfigure();
398fcf3ce44SJohn Forte 		(void) _rdc_unload();
399fcf3ce44SJohn Forte 		rdcsrv_unload();
400fcf3ce44SJohn Forte 	}
401fcf3ce44SJohn Forte 
402fcf3ce44SJohn Forte 	rdc_sync_event_destroy();
403fcf3ce44SJohn Forte 	rdc_link_down_free();
404fcf3ce44SJohn Forte 
405fcf3ce44SJohn Forte 	rdc_dip = NULL;
406fcf3ce44SJohn Forte 	return (DDI_SUCCESS);
407fcf3ce44SJohn Forte }
408fcf3ce44SJohn Forte 
409fcf3ce44SJohn Forte /* ARGSUSED */
410fcf3ce44SJohn Forte static int
rdcgetinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)411fcf3ce44SJohn Forte rdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
412fcf3ce44SJohn Forte {
413fcf3ce44SJohn Forte 	int rc = DDI_FAILURE;
414fcf3ce44SJohn Forte 
415fcf3ce44SJohn Forte 	switch (infocmd) {
416fcf3ce44SJohn Forte 
417fcf3ce44SJohn Forte 	case DDI_INFO_DEVT2DEVINFO:
418fcf3ce44SJohn Forte 		*result = rdc_dip;
419fcf3ce44SJohn Forte 		rc = DDI_SUCCESS;
420fcf3ce44SJohn Forte 		break;
421fcf3ce44SJohn Forte 
422fcf3ce44SJohn Forte 	case DDI_INFO_DEVT2INSTANCE:
423fcf3ce44SJohn Forte 		/* We only have a single instance */
424fcf3ce44SJohn Forte 		*result = 0;
425fcf3ce44SJohn Forte 		rc = DDI_SUCCESS;
426fcf3ce44SJohn Forte 		break;
427fcf3ce44SJohn Forte 
428fcf3ce44SJohn Forte 	default:
429fcf3ce44SJohn Forte 		break;
430fcf3ce44SJohn Forte 	}
431fcf3ce44SJohn Forte 
432fcf3ce44SJohn Forte 	return (rc);
433fcf3ce44SJohn Forte }
434fcf3ce44SJohn Forte 
435fcf3ce44SJohn Forte 
436fcf3ce44SJohn Forte /* ARGSUSED */
437fcf3ce44SJohn Forte 
438fcf3ce44SJohn Forte static int
rdcopen(dev_t * devp,int flag,int otyp,cred_t * crp)439fcf3ce44SJohn Forte rdcopen(dev_t *devp, int flag, int otyp, cred_t *crp)
440fcf3ce44SJohn Forte {
441fcf3ce44SJohn Forte 	return (0);
442fcf3ce44SJohn Forte }
443fcf3ce44SJohn Forte 
444fcf3ce44SJohn Forte 
445fcf3ce44SJohn Forte /* ARGSUSED */
446fcf3ce44SJohn Forte 
447fcf3ce44SJohn Forte static int
rdcclose(dev_t dev,int flag,int otyp,cred_t * crp)448fcf3ce44SJohn Forte rdcclose(dev_t dev, int flag, int otyp, cred_t *crp)
449fcf3ce44SJohn Forte {
450fcf3ce44SJohn Forte 	return (0);
451fcf3ce44SJohn Forte }
452fcf3ce44SJohn Forte 
453fcf3ce44SJohn Forte /* ARGSUSED */
454fcf3ce44SJohn Forte 
455fcf3ce44SJohn Forte static int
rdcprint(dev_t dev,char * str)456fcf3ce44SJohn Forte rdcprint(dev_t dev, char *str)
457fcf3ce44SJohn Forte {
458fcf3ce44SJohn Forte 	int instance = 0;
459fcf3ce44SJohn Forte 
460*3270659fSSrikanth, Ramana 	cmn_err(CE_WARN, "!rdc%d: %s", instance, str);
461fcf3ce44SJohn Forte 	return (0);
462fcf3ce44SJohn Forte }
463fcf3ce44SJohn Forte 
464fcf3ce44SJohn Forte 
465fcf3ce44SJohn Forte static int
convert_ioctl_args(int cmd,intptr_t arg,int mode,_rdc_ioctl_t * args)466fcf3ce44SJohn Forte convert_ioctl_args(int cmd, intptr_t arg, int mode, _rdc_ioctl_t *args)
467fcf3ce44SJohn Forte {
468fcf3ce44SJohn Forte 	_rdc_ioctl32_t args32;
469fcf3ce44SJohn Forte 
470fcf3ce44SJohn Forte 	if (ddi_copyin((void *)arg, &args32, sizeof (_rdc_ioctl32_t), mode))
471fcf3ce44SJohn Forte 		return (EFAULT);
472fcf3ce44SJohn Forte 
473fcf3ce44SJohn Forte 	bzero((void *)args, sizeof (_rdc_ioctl_t));
474fcf3ce44SJohn Forte 
475fcf3ce44SJohn Forte 	switch (cmd) {
476fcf3ce44SJohn Forte 	case RDC_CONFIG:
477fcf3ce44SJohn Forte 		args->arg0 = (uint32_t)args32.arg0; /* _rdc_config_t * */
478fcf3ce44SJohn Forte 		args->arg1 = (uint32_t)args32.arg1; /* pointer */
479fcf3ce44SJohn Forte 		args->arg2 = (uint32_t)args32.arg2; /* size */
480fcf3ce44SJohn Forte 		args->ustatus = (spcs_s_info_t)args32.ustatus;
481fcf3ce44SJohn Forte 		break;
482fcf3ce44SJohn Forte 
483fcf3ce44SJohn Forte 	case RDC_STATUS:
484fcf3ce44SJohn Forte 		args->arg0 = (uint32_t)args32.arg0; /* pointer */
485fcf3ce44SJohn Forte 		args->ustatus = (spcs_s_info_t)args32.ustatus;
486fcf3ce44SJohn Forte 		break;
487fcf3ce44SJohn Forte 
488fcf3ce44SJohn Forte 	case RDC_ENABLE_SVR:
489fcf3ce44SJohn Forte 		args->arg0 = (uint32_t)args32.arg0; /* _rdc_svc_args *  */
490fcf3ce44SJohn Forte 		break;
491fcf3ce44SJohn Forte 
492fcf3ce44SJohn Forte 	case RDC_VERSION:
493fcf3ce44SJohn Forte 		args->arg0 = (uint32_t)args32.arg0; /* _rdc_version_t *  */
494fcf3ce44SJohn Forte 		args->ustatus = (spcs_s_info_t)args32.ustatus;
495fcf3ce44SJohn Forte 		break;
496fcf3ce44SJohn Forte 
497fcf3ce44SJohn Forte 	case RDC_SYNC_EVENT:
498fcf3ce44SJohn Forte 		args->arg0 = (uint32_t)args32.arg0; /* char *  */
499fcf3ce44SJohn Forte 		args->arg1 = (uint32_t)args32.arg1; /* char *  */
500fcf3ce44SJohn Forte 		args->ustatus = (spcs_s_info_t)args32.ustatus;
501fcf3ce44SJohn Forte 		break;
502fcf3ce44SJohn Forte 
503fcf3ce44SJohn Forte 	case RDC_LINK_DOWN:
504fcf3ce44SJohn Forte 		args->arg0 = (uint32_t)args32.arg0; /* char *  */
505fcf3ce44SJohn Forte 		args->ustatus = (spcs_s_info_t)args32.ustatus;
506fcf3ce44SJohn Forte 		break;
507fcf3ce44SJohn Forte 	case RDC_POOL_CREATE:
508fcf3ce44SJohn Forte 		args->arg0 = (uint32_t)args32.arg0; /* svcpool_args *  */
509fcf3ce44SJohn Forte 		break;
510fcf3ce44SJohn Forte 	case RDC_POOL_WAIT:
511fcf3ce44SJohn Forte 		args->arg0 = (uint32_t)args32.arg0; /* int */
512fcf3ce44SJohn Forte 		break;
513fcf3ce44SJohn Forte 	case RDC_POOL_RUN:
514fcf3ce44SJohn Forte 		args->arg0 = (uint32_t)args32.arg0; /* int */
515fcf3ce44SJohn Forte 		break;
516fcf3ce44SJohn Forte 
517fcf3ce44SJohn Forte 	default:
518fcf3ce44SJohn Forte 		return (EINVAL);
519fcf3ce44SJohn Forte 	}
520fcf3ce44SJohn Forte 
521fcf3ce44SJohn Forte 	return (0);
522fcf3ce44SJohn Forte }
523fcf3ce44SJohn Forte 
524fcf3ce44SJohn Forte 
525fcf3ce44SJohn Forte /*
526fcf3ce44SJohn Forte  * Yet another standard thing that is not standard ...
527fcf3ce44SJohn Forte  */
528fcf3ce44SJohn Forte #ifndef	offsetof
529fcf3ce44SJohn Forte #define	offsetof(s, m)	((size_t)(&((s *)0)->m))
530fcf3ce44SJohn Forte #endif
531fcf3ce44SJohn Forte 
532fcf3ce44SJohn Forte /*
533fcf3ce44SJohn Forte  * Build a 32bit rdc_set structure and copyout to the user level.
534fcf3ce44SJohn Forte  */
535fcf3ce44SJohn Forte int
rdc_status_copy32(const void * arg,void * usetp,size_t size,int mode)536fcf3ce44SJohn Forte rdc_status_copy32(const void *arg, void *usetp, size_t size, int mode)
537fcf3ce44SJohn Forte {
538fcf3ce44SJohn Forte 	rdc_u_info_t *urdc = (rdc_u_info_t *)arg;
539fcf3ce44SJohn Forte 	struct rdc_set32 set32;
540fcf3ce44SJohn Forte 	size_t tailsize;
541fcf3ce44SJohn Forte #ifdef DEBUG
542fcf3ce44SJohn Forte 	size_t tailsize32;
543fcf3ce44SJohn Forte #endif
544fcf3ce44SJohn Forte 
545fcf3ce44SJohn Forte 	bzero(&set32, sizeof (set32));
546fcf3ce44SJohn Forte 
547fcf3ce44SJohn Forte 	tailsize = sizeof (struct rdc_addr32) -
548fcf3ce44SJohn Forte 	    offsetof(struct rdc_addr32, intf);
549fcf3ce44SJohn Forte 
550fcf3ce44SJohn Forte 	/* primary address structure, avoiding netbuf */
551fcf3ce44SJohn Forte 	bcopy(&urdc->primary.intf[0], &set32.primary.intf[0], tailsize);
552fcf3ce44SJohn Forte 
553fcf3ce44SJohn Forte 	/* secondary address structure, avoiding netbuf */
554fcf3ce44SJohn Forte 	bcopy(&urdc->secondary.intf[0], &set32.secondary.intf[0], tailsize);
555fcf3ce44SJohn Forte 
556fcf3ce44SJohn Forte 	/*
557fcf3ce44SJohn Forte 	 * the rest, avoiding netconfig
558fcf3ce44SJohn Forte 	 * note: the tail must be the same size in both structures
559fcf3ce44SJohn Forte 	 */
560fcf3ce44SJohn Forte 	tailsize = sizeof (struct rdc_set) - offsetof(struct rdc_set, flags);
561fcf3ce44SJohn Forte #ifdef DEBUG
562fcf3ce44SJohn Forte 	/*
563fcf3ce44SJohn Forte 	 * ASSERT is calling for debug reason, and tailsize32 is only declared
564fcf3ce44SJohn Forte 	 * for ASSERT, put them under debug to avoid lint warning.
565fcf3ce44SJohn Forte 	 */
566fcf3ce44SJohn Forte 	tailsize32 = sizeof (struct rdc_set32) -
567fcf3ce44SJohn Forte 	    offsetof(struct rdc_set32, flags);
568fcf3ce44SJohn Forte 	ASSERT(tailsize == tailsize32);
569fcf3ce44SJohn Forte #endif
570fcf3ce44SJohn Forte 
571fcf3ce44SJohn Forte 	bcopy(&urdc->flags, &set32.flags, tailsize);
572fcf3ce44SJohn Forte 
573fcf3ce44SJohn Forte 	/* copyout to user level */
574fcf3ce44SJohn Forte 	return (ddi_copyout(&set32, usetp, size, mode));
575fcf3ce44SJohn Forte }
576fcf3ce44SJohn Forte 
577fcf3ce44SJohn Forte 
578fcf3ce44SJohn Forte /*
579fcf3ce44SJohn Forte  * Status ioctl.
580fcf3ce44SJohn Forte  */
581fcf3ce44SJohn Forte static int
rdcstatus(_rdc_ioctl_t * args,int mode)582fcf3ce44SJohn Forte rdcstatus(_rdc_ioctl_t *args, int mode)
583fcf3ce44SJohn Forte {
584fcf3ce44SJohn Forte 	int (*copyout)(const void *, void *, size_t, int);
585fcf3ce44SJohn Forte 	rdc_u_info_t *urdc;
586fcf3ce44SJohn Forte 	rdc_k_info_t *krdc;
587fcf3ce44SJohn Forte 	disk_queue *dqp;
588fcf3ce44SJohn Forte 	char *usetp;			/* pointer to user rdc_set structure */
589fcf3ce44SJohn Forte 	size_t size;			/* sizeof user rdc_set structure */
590fcf3ce44SJohn Forte 	int32_t *maxsetsp;		/* address of status->maxsets; */
591fcf3ce44SJohn Forte 	int nset, max, i, j;
592fcf3ce44SJohn Forte 
593fcf3ce44SJohn Forte 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
594fcf3ce44SJohn Forte 		struct rdc_status32 status32;
595fcf3ce44SJohn Forte 
596fcf3ce44SJohn Forte 		if (ddi_copyin((void *)args->arg0, &status32,
597fcf3ce44SJohn Forte 		    sizeof (status32), mode)) {
598fcf3ce44SJohn Forte 			return (EFAULT);
599fcf3ce44SJohn Forte 		}
600fcf3ce44SJohn Forte 
601fcf3ce44SJohn Forte 		usetp = ((char *)args->arg0) +
602fcf3ce44SJohn Forte 		    offsetof(struct rdc_status32, rdc_set);
603fcf3ce44SJohn Forte 		maxsetsp = (int32_t *)((char *)args->arg0 +
604fcf3ce44SJohn Forte 		    offsetof(struct rdc_status32, maxsets));
605fcf3ce44SJohn Forte 		nset = status32.nset;
606fcf3ce44SJohn Forte 
607fcf3ce44SJohn Forte 		size = sizeof (struct rdc_set32);
608fcf3ce44SJohn Forte 		copyout = rdc_status_copy32;
609fcf3ce44SJohn Forte 	} else {
610fcf3ce44SJohn Forte 		struct rdc_status status;
611fcf3ce44SJohn Forte 
612fcf3ce44SJohn Forte 		if (ddi_copyin((void *)args->arg0, &status,
613fcf3ce44SJohn Forte 		    sizeof (status), mode)) {
614fcf3ce44SJohn Forte 			return (EFAULT);
615fcf3ce44SJohn Forte 		}
616fcf3ce44SJohn Forte 
617fcf3ce44SJohn Forte 		usetp = ((char *)args->arg0) +
618fcf3ce44SJohn Forte 		    offsetof(struct rdc_status, rdc_set);
619fcf3ce44SJohn Forte 		maxsetsp = (int32_t *)((char *)args->arg0 +
620fcf3ce44SJohn Forte 		    offsetof(struct rdc_status, maxsets));
621fcf3ce44SJohn Forte 		nset = status.nset;
622fcf3ce44SJohn Forte 
623fcf3ce44SJohn Forte 		size = sizeof (struct rdc_set);
624fcf3ce44SJohn Forte 		copyout = ddi_copyout;
625fcf3ce44SJohn Forte 	}
626fcf3ce44SJohn Forte 
627fcf3ce44SJohn Forte 	max = min(nset, rdc_max_sets);
628fcf3ce44SJohn Forte 
629fcf3ce44SJohn Forte 	for (i = 0, j = 0; i < max; i++) {
630fcf3ce44SJohn Forte 		urdc = &rdc_u_info[i];
631fcf3ce44SJohn Forte 		krdc = &rdc_k_info[i];
632fcf3ce44SJohn Forte 
633fcf3ce44SJohn Forte 		if (!IS_ENABLED(urdc))
634fcf3ce44SJohn Forte 			continue;
635fcf3ce44SJohn Forte 
636fcf3ce44SJohn Forte 		/*
637fcf3ce44SJohn Forte 		 * sneak out qstate in urdc->flags
638fcf3ce44SJohn Forte 		 * this is harmless because it's value is not used
639fcf3ce44SJohn Forte 		 * in urdc->flags. the real qstate is kept in
640fcf3ce44SJohn Forte 		 * group->diskq->disk_hdr.h.state
641fcf3ce44SJohn Forte 		 */
642fcf3ce44SJohn Forte 		if (RDC_IS_DISKQ(krdc->group)) {
643fcf3ce44SJohn Forte 			dqp = &krdc->group->diskq;
644fcf3ce44SJohn Forte 			if (IS_QSTATE(dqp, RDC_QNOBLOCK))
645fcf3ce44SJohn Forte 				urdc->flags |= RDC_QNOBLOCK;
646fcf3ce44SJohn Forte 		}
647fcf3ce44SJohn Forte 
648fcf3ce44SJohn Forte 		j++;
649fcf3ce44SJohn Forte 		if ((*copyout)(urdc, usetp, size, mode) != 0)
650fcf3ce44SJohn Forte 			return (EFAULT);
651fcf3ce44SJohn Forte 
652fcf3ce44SJohn Forte 		urdc->flags &= ~RDC_QNOBLOCK; /* clear qstate */
653fcf3ce44SJohn Forte 		usetp += size;
654fcf3ce44SJohn Forte 	}
655fcf3ce44SJohn Forte 
656fcf3ce44SJohn Forte 	/* copyout rdc_max_sets value */
657fcf3ce44SJohn Forte 
658fcf3ce44SJohn Forte 	if (ddi_copyout(&rdc_max_sets, maxsetsp, sizeof (*maxsetsp), mode) != 0)
659fcf3ce44SJohn Forte 		return (EFAULT);
660fcf3ce44SJohn Forte 
661fcf3ce44SJohn Forte 	/* copyout number of sets manipulated */
662fcf3ce44SJohn Forte 
663fcf3ce44SJohn Forte 	/*CONSTCOND*/
664fcf3ce44SJohn Forte 	ASSERT(offsetof(struct rdc_status32, nset) == 0);
665fcf3ce44SJohn Forte 	/*CONSTCOND*/
666fcf3ce44SJohn Forte 	ASSERT(offsetof(struct rdc_status, nset) == 0);
667fcf3ce44SJohn Forte 
668fcf3ce44SJohn Forte 	return (ddi_copyout(&j, (void *)args->arg0, sizeof (int), mode));
669fcf3ce44SJohn Forte }
670fcf3ce44SJohn Forte 
671fcf3ce44SJohn Forte 
672fcf3ce44SJohn Forte /* ARGSUSED */
673fcf3ce44SJohn Forte 
674fcf3ce44SJohn Forte static int
rdcioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * crp,int * rvp)675fcf3ce44SJohn Forte rdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
676fcf3ce44SJohn Forte {
677fcf3ce44SJohn Forte 	spcs_s_info_t kstatus = NULL;
678fcf3ce44SJohn Forte 	_rdc_ioctl_t args;
679fcf3ce44SJohn Forte 	int error;
680fcf3ce44SJohn Forte 	int rc = 0;
681fcf3ce44SJohn Forte 
682fcf3ce44SJohn Forte 	if (cmd != RDC_STATUS) {
683fcf3ce44SJohn Forte 		if ((error = drv_priv(crp)) != 0)
684fcf3ce44SJohn Forte 			return (error);
685fcf3ce44SJohn Forte 	}
686fcf3ce44SJohn Forte #ifdef	DEBUG
687fcf3ce44SJohn Forte 	if (cmd == RDC_ASYNC6) {
688fcf3ce44SJohn Forte 		rc = rdc_async6((void *)arg, mode, rvp);
689fcf3ce44SJohn Forte 		return (rc);
690fcf3ce44SJohn Forte 	}
691fcf3ce44SJohn Forte 
692fcf3ce44SJohn Forte 	if (cmd == RDC_CLRKSTAT) {
693fcf3ce44SJohn Forte 		rc = rdc_clrkstat((void *)arg);
694fcf3ce44SJohn Forte 		return (rc);
695fcf3ce44SJohn Forte 	}
696fcf3ce44SJohn Forte 
697fcf3ce44SJohn Forte 	if (cmd == RDC_STALL0) {
698fcf3ce44SJohn Forte 		if (((int)arg > 1) || ((int)arg < 0))
699fcf3ce44SJohn Forte 			return (EINVAL);
700fcf3ce44SJohn Forte 		rdc_stallzero((int)arg);
701fcf3ce44SJohn Forte 		return (0);
702fcf3ce44SJohn Forte 	}
703fcf3ce44SJohn Forte 	if (cmd == RDC_READGEN) {
704fcf3ce44SJohn Forte 		rc = rdc_readgen((void *)arg, mode, rvp);
705fcf3ce44SJohn Forte 		return (rc);
706fcf3ce44SJohn Forte 	}
707fcf3ce44SJohn Forte #endif
708fcf3ce44SJohn Forte 	if (cmd == RDC_BITMAPOP) {
709fcf3ce44SJohn Forte 		rdc_bitmap_op_t bmop;
710fcf3ce44SJohn Forte 		rdc_bitmap_op32_t bmop32;
711fcf3ce44SJohn Forte 
712fcf3ce44SJohn Forte 		if (ddi_model_convert_from(mode & FMODELS)
713fcf3ce44SJohn Forte 		    == DDI_MODEL_ILP32) {
714fcf3ce44SJohn Forte 			if (ddi_copyin((void *)arg, &bmop32, sizeof (bmop32),
715fcf3ce44SJohn Forte 			    mode))
716fcf3ce44SJohn Forte 				return (EFAULT);
717fcf3ce44SJohn Forte 			bmop.offset = bmop32.offset;
718fcf3ce44SJohn Forte 			bmop.op = bmop32.op;
719fcf3ce44SJohn Forte 			(void) strncpy(bmop.sechost, bmop32.sechost,
720fcf3ce44SJohn Forte 			    MAX_RDC_HOST_SIZE);
721fcf3ce44SJohn Forte 			(void) strncpy(bmop.secfile, bmop32.secfile,
722fcf3ce44SJohn Forte 			    NSC_MAXPATH);
723fcf3ce44SJohn Forte 			bmop.len = bmop32.len;
724fcf3ce44SJohn Forte 			bmop.addr = (unsigned long)bmop32.addr;
725fcf3ce44SJohn Forte 		} else {
726fcf3ce44SJohn Forte 			if (ddi_copyin((void *)arg, &bmop, sizeof (bmop),
727fcf3ce44SJohn Forte 			    mode))
728fcf3ce44SJohn Forte 				return (EFAULT);
729fcf3ce44SJohn Forte 		}
730fcf3ce44SJohn Forte 		rc = rdc_bitmapset(bmop.op, bmop.sechost, bmop.secfile,
731fcf3ce44SJohn Forte 		    (void *)bmop.addr, bmop.len, bmop.offset, mode);
732fcf3ce44SJohn Forte 		return (rc);
733fcf3ce44SJohn Forte 	}
734fcf3ce44SJohn Forte 
735fcf3ce44SJohn Forte 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
736fcf3ce44SJohn Forte 		if ((rc = convert_ioctl_args(cmd, arg, mode, &args)) != 0)
737fcf3ce44SJohn Forte 			return (rc);
738fcf3ce44SJohn Forte 	} else {
739fcf3ce44SJohn Forte 		if (ddi_copyin((void *)arg, &args,
740fcf3ce44SJohn Forte 		    sizeof (_rdc_ioctl_t), mode)) {
741fcf3ce44SJohn Forte 			return (EFAULT);
742fcf3ce44SJohn Forte 		}
743fcf3ce44SJohn Forte 	}
744fcf3ce44SJohn Forte 
745fcf3ce44SJohn Forte 	kstatus = spcs_s_kcreate();
746fcf3ce44SJohn Forte 	if (!kstatus) {
747fcf3ce44SJohn Forte 		return (ENOMEM);
748fcf3ce44SJohn Forte 	}
749fcf3ce44SJohn Forte 
750fcf3ce44SJohn Forte 
751fcf3ce44SJohn Forte 	switch (cmd) {
752fcf3ce44SJohn Forte 
753fcf3ce44SJohn Forte 	case RDC_POOL_CREATE: {
754fcf3ce44SJohn Forte 		struct svcpool_args p;
755fcf3ce44SJohn Forte 
756fcf3ce44SJohn Forte 		if (ddi_copyin((void *)arg, &p, sizeof (p), mode)) {
757fcf3ce44SJohn Forte 			spcs_s_kfree(kstatus);
758fcf3ce44SJohn Forte 			return (EFAULT);
759fcf3ce44SJohn Forte 		}
760fcf3ce44SJohn Forte 		error = svc_pool_create(&p);
761fcf3ce44SJohn Forte 
762fcf3ce44SJohn Forte 		break;
763fcf3ce44SJohn Forte 	}
764fcf3ce44SJohn Forte 	case RDC_POOL_WAIT: {
765fcf3ce44SJohn Forte 		int id;
766fcf3ce44SJohn Forte 
767fcf3ce44SJohn Forte 		if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
768fcf3ce44SJohn Forte 			spcs_s_kfree(kstatus);
769fcf3ce44SJohn Forte 			return (EFAULT);
770fcf3ce44SJohn Forte 		}
771fcf3ce44SJohn Forte 
772fcf3ce44SJohn Forte 		error = svc_wait(id);
773fcf3ce44SJohn Forte 		break;
774fcf3ce44SJohn Forte 	}
775fcf3ce44SJohn Forte 	case RDC_POOL_RUN: {
776fcf3ce44SJohn Forte 		int id;
777fcf3ce44SJohn Forte 
778fcf3ce44SJohn Forte 		if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
779fcf3ce44SJohn Forte 			spcs_s_kfree(kstatus);
780fcf3ce44SJohn Forte 			return (EFAULT);
781fcf3ce44SJohn Forte 		}
782fcf3ce44SJohn Forte 		error = svc_do_run(id);
783fcf3ce44SJohn Forte 		break;
784fcf3ce44SJohn Forte 	}
785fcf3ce44SJohn Forte 	case RDC_ENABLE_SVR:
786fcf3ce44SJohn Forte 		{
787fcf3ce44SJohn Forte 			STRUCT_DECL(rdc_svc_args, parms);
788fcf3ce44SJohn Forte 
789fcf3ce44SJohn Forte 			STRUCT_INIT(parms, mode);
790fcf3ce44SJohn Forte 			/* Only used by sndrd which does not use unistat */
791fcf3ce44SJohn Forte 
792fcf3ce44SJohn Forte 			if (ddi_copyin((void *)args.arg0, STRUCT_BUF(parms),
793fcf3ce44SJohn Forte 			    STRUCT_SIZE(parms), mode)) {
794fcf3ce44SJohn Forte 				spcs_s_kfree(kstatus);
795fcf3ce44SJohn Forte 				return (EFAULT);
796fcf3ce44SJohn Forte 			}
797fcf3ce44SJohn Forte 			rc = rdc_start_server(STRUCT_BUF(parms), mode);
798fcf3ce44SJohn Forte 		}
799fcf3ce44SJohn Forte 		break;
800fcf3ce44SJohn Forte 
801fcf3ce44SJohn Forte 	case RDC_STATUS:
802fcf3ce44SJohn Forte 		rc = rdcstatus(&args, mode);
803fcf3ce44SJohn Forte 		break;
804fcf3ce44SJohn Forte 
805fcf3ce44SJohn Forte 	case RDC_CONFIG:
806fcf3ce44SJohn Forte 		rc = _rdc_config((void *)args.arg0, mode, kstatus, rvp);
807fcf3ce44SJohn Forte 		spcs_s_copyoutf(&kstatus, args.ustatus);
808fcf3ce44SJohn Forte 		return (rc);
809fcf3ce44SJohn Forte 
810fcf3ce44SJohn Forte 	case RDC_VERSION:
811fcf3ce44SJohn Forte 		{
812fcf3ce44SJohn Forte 			STRUCT_DECL(rdc_version, parms);
813fcf3ce44SJohn Forte 
814fcf3ce44SJohn Forte 			STRUCT_INIT(parms, mode);
815fcf3ce44SJohn Forte 
816fcf3ce44SJohn Forte 			STRUCT_FSET(parms, major, sndr_major_rev);
817fcf3ce44SJohn Forte 			STRUCT_FSET(parms, minor, sndr_minor_rev);
818fcf3ce44SJohn Forte 			STRUCT_FSET(parms, micro, sndr_micro_rev);
819fcf3ce44SJohn Forte 			STRUCT_FSET(parms, baseline, sndr_baseline_rev);
820fcf3ce44SJohn Forte 
821fcf3ce44SJohn Forte 			if (ddi_copyout(STRUCT_BUF(parms), (void *)args.arg0,
822fcf3ce44SJohn Forte 			    STRUCT_SIZE(parms), mode)) {
823fcf3ce44SJohn Forte 				spcs_s_kfree(kstatus);
824fcf3ce44SJohn Forte 				return (EFAULT);
825fcf3ce44SJohn Forte 			}
826fcf3ce44SJohn Forte 			break;
827fcf3ce44SJohn Forte 		}
828fcf3ce44SJohn Forte 
829fcf3ce44SJohn Forte 	case RDC_LINK_DOWN:
830fcf3ce44SJohn Forte 		/* char *host from user */
831fcf3ce44SJohn Forte 		rc = _rdc_link_down((void *)args.arg0, mode, kstatus, rvp);
832fcf3ce44SJohn Forte 		spcs_s_copyoutf(&kstatus, args.ustatus);
833fcf3ce44SJohn Forte 
834fcf3ce44SJohn Forte 		return (rc);
835fcf3ce44SJohn Forte 
836fcf3ce44SJohn Forte 	case RDC_SYNC_EVENT:
837fcf3ce44SJohn Forte 		rc = _rdc_sync_event_wait((void *)args.arg0, (void *)args.arg1,
838fcf3ce44SJohn Forte 		    mode, kstatus, rvp);
839fcf3ce44SJohn Forte 		spcs_s_copyoutf(&kstatus, args.ustatus);
840fcf3ce44SJohn Forte 
841fcf3ce44SJohn Forte 		return (rc);
842fcf3ce44SJohn Forte 
843fcf3ce44SJohn Forte 
844fcf3ce44SJohn Forte 	default:
845fcf3ce44SJohn Forte 		rc = EINVAL;
846fcf3ce44SJohn Forte 		break;
847fcf3ce44SJohn Forte 	}
848fcf3ce44SJohn Forte 
849fcf3ce44SJohn Forte 	spcs_s_kfree(kstatus);
850fcf3ce44SJohn Forte 	return (rc);
851fcf3ce44SJohn Forte }
852fcf3ce44SJohn Forte 
853fcf3ce44SJohn Forte int
sndr_info_stats_update(kstat_t * ksp,int rw)854fcf3ce44SJohn Forte sndr_info_stats_update(kstat_t *ksp, int rw)
855fcf3ce44SJohn Forte {
856fcf3ce44SJohn Forte 	extern int rdc_rpc_tmout;
857fcf3ce44SJohn Forte 	extern int rdc_health_thres;
858fcf3ce44SJohn Forte 	extern int rdc_bitmap_delay;
859fcf3ce44SJohn Forte 	extern long rdc_clnt_count;
860fcf3ce44SJohn Forte 	extern long rdc_svc_count;
861fcf3ce44SJohn Forte 	sndr_m_stats_t	*info_stats;
862fcf3ce44SJohn Forte 	rdc_k_info_t	*krdc;
863fcf3ce44SJohn Forte 
864fcf3ce44SJohn Forte 	info_stats = (sndr_m_stats_t *)(ksp->ks_data);
865fcf3ce44SJohn Forte 	krdc = (rdc_k_info_t *)(ksp->ks_private);
866fcf3ce44SJohn Forte 
867fcf3ce44SJohn Forte 	/* no writes currently allowed */
868fcf3ce44SJohn Forte 
869fcf3ce44SJohn Forte 	if (rw == KSTAT_WRITE) {
870fcf3ce44SJohn Forte 		return (EACCES);
871fcf3ce44SJohn Forte 	}
872fcf3ce44SJohn Forte 
873fcf3ce44SJohn Forte 	/* default to READ */
874fcf3ce44SJohn Forte 	info_stats->m_maxsets.value.ul = rdc_max_sets;
875fcf3ce44SJohn Forte 	info_stats->m_maxfbas.value.ul = krdc->maxfbas;
876fcf3ce44SJohn Forte 	info_stats->m_rpc_timeout.value.ul = rdc_rpc_tmout;
877fcf3ce44SJohn Forte 	info_stats->m_health_thres.value.ul = rdc_health_thres;
878fcf3ce44SJohn Forte 	info_stats->m_bitmap_writes.value.ul = krdc->bitmap_write;
879fcf3ce44SJohn Forte 	info_stats->m_bitmap_ref_delay.value.ul = rdc_bitmap_delay;
880fcf3ce44SJohn Forte 
881fcf3ce44SJohn Forte 	/* clts counters not implemented yet */
882fcf3ce44SJohn Forte 	info_stats->m_clnt_cots_calls.value.ul = rdc_clnt_count;
883fcf3ce44SJohn Forte 	info_stats->m_clnt_clts_calls.value.ul = 0;
884fcf3ce44SJohn Forte 	info_stats->m_svc_cots_calls.value.ul = rdc_svc_count;
885fcf3ce44SJohn Forte 	info_stats->m_svc_clts_calls.value.ul = 0;
886fcf3ce44SJohn Forte 
887fcf3ce44SJohn Forte 	return (0);
888fcf3ce44SJohn Forte }
889fcf3ce44SJohn Forte 
890fcf3ce44SJohn Forte /*
891fcf3ce44SJohn Forte  * copy tailsize-1 bytes of tail of s to s1.
892fcf3ce44SJohn Forte  */
893fcf3ce44SJohn Forte void
rdc_str_tail_cpy(char * s1,char * s,size_t tailsize)894fcf3ce44SJohn Forte rdc_str_tail_cpy(char *s1, char *s, size_t tailsize)
895fcf3ce44SJohn Forte {
896fcf3ce44SJohn Forte 	/* To avoid un-terminated string, max size is 16 - 1 */
897fcf3ce44SJohn Forte 	ssize_t offset = strlen(s) - (tailsize - 1);
898fcf3ce44SJohn Forte 
899fcf3ce44SJohn Forte 	offset = (offset > 0) ? offset : 0;
900fcf3ce44SJohn Forte 
901fcf3ce44SJohn Forte 	/* ensure it's null terminated */
902fcf3ce44SJohn Forte 	(void) strlcpy(s1, (const char *)(s + offset), tailsize);
903fcf3ce44SJohn Forte }
904fcf3ce44SJohn Forte 
905fcf3ce44SJohn Forte int
rdc_info_stats_update(kstat_t * ksp,int rw)906fcf3ce44SJohn Forte rdc_info_stats_update(kstat_t *ksp, int rw)
907fcf3ce44SJohn Forte {
908fcf3ce44SJohn Forte 	rdc_info_stats_t	*rdc_info_stats;
909fcf3ce44SJohn Forte 	rdc_k_info_t		*krdc;
910fcf3ce44SJohn Forte 	rdc_u_info_t		*urdc;
911fcf3ce44SJohn Forte 
912fcf3ce44SJohn Forte 	rdc_info_stats = (rdc_info_stats_t *)(ksp->ks_data);
913fcf3ce44SJohn Forte 	krdc = (rdc_k_info_t *)(ksp->ks_private);
914fcf3ce44SJohn Forte 	urdc = &rdc_u_info[krdc->index];
915fcf3ce44SJohn Forte 
916fcf3ce44SJohn Forte 	/* no writes currently allowed */
917fcf3ce44SJohn Forte 
918fcf3ce44SJohn Forte 	if (rw == KSTAT_WRITE) {
919fcf3ce44SJohn Forte 		return (EACCES);
920fcf3ce44SJohn Forte 	}
921fcf3ce44SJohn Forte 
922fcf3ce44SJohn Forte 	/* default to READ */
923fcf3ce44SJohn Forte 	rdc_info_stats->s_flags.value.ul = urdc->flags;
924fcf3ce44SJohn Forte 	rdc_info_stats->s_syncflags.value.ul =
925fcf3ce44SJohn Forte 	    urdc->sync_flags;
926fcf3ce44SJohn Forte 	rdc_info_stats->s_bmpflags.value.ul =
927fcf3ce44SJohn Forte 	    urdc->bmap_flags;
928fcf3ce44SJohn Forte 	rdc_info_stats->s_syncpos.value.ul =
929fcf3ce44SJohn Forte 	    urdc->sync_pos;
930fcf3ce44SJohn Forte 	rdc_info_stats->s_volsize.value.ul =
931fcf3ce44SJohn Forte 	    urdc->volume_size;
932fcf3ce44SJohn Forte 	rdc_info_stats->s_bits_set.value.ul =
933fcf3ce44SJohn Forte 	    urdc->bits_set;
934fcf3ce44SJohn Forte 	rdc_info_stats->s_autosync.value.ul =
935fcf3ce44SJohn Forte 	    urdc->autosync;
936fcf3ce44SJohn Forte 	rdc_info_stats->s_maxqfbas.value.ul =
937fcf3ce44SJohn Forte 	    urdc->maxqfbas;
938fcf3ce44SJohn Forte 	rdc_info_stats->s_maxqitems.value.ul =
939fcf3ce44SJohn Forte 	    urdc->maxqitems;
940fcf3ce44SJohn Forte 
941fcf3ce44SJohn Forte 	kstat_named_setstr(&rdc_info_stats->s_primary_vol,
942fcf3ce44SJohn Forte 	    urdc->primary.file);
943fcf3ce44SJohn Forte 
944fcf3ce44SJohn Forte 	kstat_named_setstr(&rdc_info_stats->s_secondary_vol,
945fcf3ce44SJohn Forte 	    urdc->secondary.file);
946fcf3ce44SJohn Forte 
947fcf3ce44SJohn Forte 	if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
948fcf3ce44SJohn Forte 		kstat_named_setstr(&rdc_info_stats->s_bitmap,
949fcf3ce44SJohn Forte 		    urdc->primary.bitmap);
950fcf3ce44SJohn Forte 	} else {
951fcf3ce44SJohn Forte 		kstat_named_setstr(&rdc_info_stats->s_bitmap,
952fcf3ce44SJohn Forte 		    urdc->secondary.bitmap);
953fcf3ce44SJohn Forte 	}
954fcf3ce44SJohn Forte 
955fcf3ce44SJohn Forte 	kstat_named_setstr(&rdc_info_stats->s_primary_intf,
956fcf3ce44SJohn Forte 	    urdc->primary.intf);
957fcf3ce44SJohn Forte 
958fcf3ce44SJohn Forte 	kstat_named_setstr(&rdc_info_stats->s_secondary_intf,
959fcf3ce44SJohn Forte 	    urdc->secondary.intf);
960fcf3ce44SJohn Forte 
961fcf3ce44SJohn Forte 	rdc_info_stats->s_type_flag.value.ul = krdc->type_flag;
962fcf3ce44SJohn Forte 	rdc_info_stats->s_bitmap_size.value.ul = krdc->bitmap_size;
963fcf3ce44SJohn Forte 	rdc_info_stats->s_disk_status.value.ul = krdc->disk_status;
964fcf3ce44SJohn Forte 
965fcf3ce44SJohn Forte 	if (krdc->intf) {
966fcf3ce44SJohn Forte 		rdc_info_stats->s_if_if_down.value.ul = krdc->intf->if_down;
967fcf3ce44SJohn Forte 		rdc_info_stats->s_if_rpc_version.value.ul =
968fcf3ce44SJohn Forte 		    krdc->intf->rpc_version;
969fcf3ce44SJohn Forte 	}
970fcf3ce44SJohn Forte 
971fcf3ce44SJohn Forte 	/* the type can change without disable/re-enable so... */
972fcf3ce44SJohn Forte 	bzero(rdc_info_stats->s_aqueue_type.value.c, KSTAT_DATA_CHAR_LEN);
973fcf3ce44SJohn Forte 	if (RDC_IS_MEMQ(krdc->group)) {
974fcf3ce44SJohn Forte 		(void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "memory");
975fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_blk_hwm.value.ul =
976fcf3ce44SJohn Forte 		    krdc->group->ra_queue.blocks_hwm;
977fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_itm_hwm.value.ul =
978fcf3ce44SJohn Forte 		    krdc->group->ra_queue.nitems_hwm;
979fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_throttle.value.ul =
980fcf3ce44SJohn Forte 		    krdc->group->ra_queue.throttle_delay;
981fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_items.value.ul =
982fcf3ce44SJohn Forte 		    krdc->group->ra_queue.nitems;
983fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_blocks.value.ul =
984fcf3ce44SJohn Forte 		    krdc->group->ra_queue.blocks;
985fcf3ce44SJohn Forte 
986fcf3ce44SJohn Forte 	} else if (RDC_IS_DISKQ(krdc->group)) {
987fcf3ce44SJohn Forte 		disk_queue *q = &krdc->group->diskq;
988fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_blk_hwm.value.ul =
989fcf3ce44SJohn Forte 		    krdc->group->diskq.blocks_hwm;
990fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_itm_hwm.value.ul =
991fcf3ce44SJohn Forte 		    krdc->group->diskq.nitems_hwm;
992fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_throttle.value.ul =
993fcf3ce44SJohn Forte 		    krdc->group->diskq.throttle_delay;
994fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_items.value.ul = QNITEMS(q);
995fcf3ce44SJohn Forte 		rdc_info_stats->s_aqueue_blocks.value.ul = QBLOCKS(q);
996fcf3ce44SJohn Forte 		(void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "disk");
997fcf3ce44SJohn Forte 	}
998fcf3ce44SJohn Forte 
999fcf3ce44SJohn Forte 	return (0);
1000fcf3ce44SJohn Forte }
1001fcf3ce44SJohn Forte 
1002fcf3ce44SJohn Forte void
rdc_kstat_create(int index)1003fcf3ce44SJohn Forte rdc_kstat_create(int index)
1004fcf3ce44SJohn Forte {
1005fcf3ce44SJohn Forte 	int j = index;
1006fcf3ce44SJohn Forte 	rdc_k_info_t *krdc = &rdc_k_info[index];
1007fcf3ce44SJohn Forte 	rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
1008fcf3ce44SJohn Forte 	size_t varsize;
1009fcf3ce44SJohn Forte 
1010fcf3ce44SJohn Forte 	if (!krdc->set_kstats) {
1011fcf3ce44SJohn Forte 		krdc->set_kstats = kstat_create(RDC_KSTAT_MODULE, j,
1012fcf3ce44SJohn Forte 		    RDC_KSTAT_INFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
1013fcf3ce44SJohn Forte 		    sizeof (rdc_info_stats_t) / sizeof (kstat_named_t),
1014fcf3ce44SJohn Forte 		    KSTAT_FLAG_VIRTUAL);
1015fcf3ce44SJohn Forte #ifdef DEBUG
1016fcf3ce44SJohn Forte 		if (!krdc->set_kstats)
1017*3270659fSSrikanth, Ramana 			cmn_err(CE_NOTE, "!krdc:u_kstat null");
1018fcf3ce44SJohn Forte #endif
1019fcf3ce44SJohn Forte 
1020fcf3ce44SJohn Forte 		if (krdc->set_kstats) {
1021fcf3ce44SJohn Forte 			/* calculate exact size of KSTAT_DATA_STRINGs */
1022fcf3ce44SJohn Forte 			varsize = strlen(urdc->primary.file) + 1
1023fcf3ce44SJohn Forte 			    + strlen(urdc->secondary.file) + 1
1024fcf3ce44SJohn Forte 			    + strlen(urdc->primary.intf) + 1
1025fcf3ce44SJohn Forte 			    + strlen(urdc->secondary.intf) + 1;
1026fcf3ce44SJohn Forte 			if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
1027fcf3ce44SJohn Forte 				varsize += strlen(urdc->primary.bitmap) + 1;
1028fcf3ce44SJohn Forte 			} else {
1029fcf3ce44SJohn Forte 				varsize += strlen(urdc->secondary.bitmap) + 1;
1030fcf3ce44SJohn Forte 			}
1031fcf3ce44SJohn Forte 
1032fcf3ce44SJohn Forte 			krdc->set_kstats->ks_data_size += varsize;
1033fcf3ce44SJohn Forte 			krdc->set_kstats->ks_data = &rdc_info_stats;
1034fcf3ce44SJohn Forte 			krdc->set_kstats->ks_update = rdc_info_stats_update;
1035fcf3ce44SJohn Forte 			krdc->set_kstats->ks_private = &rdc_k_info[j];
1036fcf3ce44SJohn Forte 			kstat_install(krdc->set_kstats);
1037fcf3ce44SJohn Forte 		} else
1038*3270659fSSrikanth, Ramana 			cmn_err(CE_WARN, "!SNDR: k-kstats failed");
1039fcf3ce44SJohn Forte 	}
1040fcf3ce44SJohn Forte 
1041fcf3ce44SJohn Forte 	krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, j, NULL,
1042fcf3ce44SJohn Forte 	    "disk", KSTAT_TYPE_IO, 1, 0);
1043fcf3ce44SJohn Forte 	if (krdc->io_kstats) {
1044fcf3ce44SJohn Forte 		krdc->io_kstats->ks_lock = &krdc->kstat_mutex;
1045fcf3ce44SJohn Forte 		kstat_install(krdc->io_kstats);
1046fcf3ce44SJohn Forte 	}
1047fcf3ce44SJohn Forte 	krdc->bmp_kstats = kstat_create("sndrbmp", j, NULL,
1048fcf3ce44SJohn Forte 	    "disk", KSTAT_TYPE_IO, 1, 0);
1049fcf3ce44SJohn Forte 	if (krdc->bmp_kstats) {
1050fcf3ce44SJohn Forte 		krdc->bmp_kstats->ks_lock = &krdc->bmp_kstat_mutex;
1051fcf3ce44SJohn Forte 		kstat_install(krdc->bmp_kstats);
1052fcf3ce44SJohn Forte 	}
1053fcf3ce44SJohn Forte }
1054fcf3ce44SJohn Forte 
1055fcf3ce44SJohn Forte void
rdc_kstat_delete(int index)1056fcf3ce44SJohn Forte rdc_kstat_delete(int index)
1057fcf3ce44SJohn Forte {
1058fcf3ce44SJohn Forte 	rdc_k_info_t *krdc = &rdc_k_info[index];
1059fcf3ce44SJohn Forte 
1060fcf3ce44SJohn Forte 	if (krdc->set_kstats) {
1061fcf3ce44SJohn Forte 		kstat_delete(krdc->set_kstats);
1062fcf3ce44SJohn Forte 		krdc->set_kstats = NULL;
1063fcf3ce44SJohn Forte 	}
1064fcf3ce44SJohn Forte 
1065fcf3ce44SJohn Forte 	if (krdc->io_kstats) {
1066fcf3ce44SJohn Forte 		kstat_delete(krdc->io_kstats);
1067fcf3ce44SJohn Forte 		krdc->io_kstats = NULL;
1068fcf3ce44SJohn Forte 	}
1069fcf3ce44SJohn Forte 	if (krdc->bmp_kstats) {
1070fcf3ce44SJohn Forte 		kstat_delete(krdc->bmp_kstats);
1071fcf3ce44SJohn Forte 		krdc->bmp_kstats = NULL;
1072fcf3ce44SJohn Forte 	}
1073fcf3ce44SJohn Forte }
1074fcf3ce44SJohn Forte 
1075fcf3ce44SJohn Forte #ifdef	DEBUG
1076fcf3ce44SJohn Forte /*
1077fcf3ce44SJohn Forte  * Reset the io_kstat structure of the krdc specified
1078fcf3ce44SJohn Forte  * by the arg index.
1079fcf3ce44SJohn Forte  */
1080fcf3ce44SJohn Forte static int
rdc_clrkstat(void * arg)1081fcf3ce44SJohn Forte rdc_clrkstat(void *arg)
1082fcf3ce44SJohn Forte {
1083fcf3ce44SJohn Forte 	int index;
1084fcf3ce44SJohn Forte 	rdc_k_info_t *krdc;
1085fcf3ce44SJohn Forte 
1086fcf3ce44SJohn Forte 	index = (int)(unsigned long)arg;
1087fcf3ce44SJohn Forte 	if ((index < 0) || (index >= rdc_max_sets)) {
1088fcf3ce44SJohn Forte 		return (EINVAL);
1089fcf3ce44SJohn Forte 	}
1090fcf3ce44SJohn Forte 	krdc = &rdc_k_info[index];
1091fcf3ce44SJohn Forte 	if (krdc->io_kstats) {
1092fcf3ce44SJohn Forte 		kstat_delete(krdc->io_kstats);
1093fcf3ce44SJohn Forte 		krdc->io_kstats = NULL;
1094fcf3ce44SJohn Forte 	} else {
1095fcf3ce44SJohn Forte 		return (EINVAL);
1096fcf3ce44SJohn Forte 	}
1097fcf3ce44SJohn Forte 	krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, index, NULL,
1098fcf3ce44SJohn Forte 	    "disk", KSTAT_TYPE_IO, 1, 0);
1099fcf3ce44SJohn Forte 	if (krdc->io_kstats) {
1100fcf3ce44SJohn Forte 		krdc->io_kstats->ks_lock = &krdc->kstat_mutex;
1101fcf3ce44SJohn Forte 		kstat_install(krdc->io_kstats);
1102fcf3ce44SJohn Forte 	} else {
1103fcf3ce44SJohn Forte 		return (EINVAL);
1104fcf3ce44SJohn Forte 	}
1105fcf3ce44SJohn Forte 	/*
1106fcf3ce44SJohn Forte 	 * clear the high water marks and throttle.
1107fcf3ce44SJohn Forte 	 */
1108fcf3ce44SJohn Forte 	if (krdc->group) {
1109fcf3ce44SJohn Forte 		krdc->group->ra_queue.nitems_hwm = 0;
1110fcf3ce44SJohn Forte 		krdc->group->ra_queue.blocks_hwm = 0;
1111fcf3ce44SJohn Forte 		krdc->group->ra_queue.throttle_delay = 0;
1112fcf3ce44SJohn Forte 	}
1113fcf3ce44SJohn Forte 	return (0);
1114fcf3ce44SJohn Forte }
1115fcf3ce44SJohn Forte #endif
1116