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