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