17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
217836SJohn.Forte@Sun.COM /*
22*9093SRamana.Srikanth@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237836SJohn.Forte@Sun.COM * Use is subject to license terms.
247836SJohn.Forte@Sun.COM */
257836SJohn.Forte@Sun.COM
267836SJohn.Forte@Sun.COM #define _RDC_
277836SJohn.Forte@Sun.COM #include <sys/types.h>
287836SJohn.Forte@Sun.COM #include <sys/ksynch.h>
297836SJohn.Forte@Sun.COM #include <sys/kmem.h>
307836SJohn.Forte@Sun.COM #include <sys/errno.h>
317836SJohn.Forte@Sun.COM #include <sys/conf.h>
327836SJohn.Forte@Sun.COM #include <sys/cmn_err.h>
337836SJohn.Forte@Sun.COM #include <sys/modctl.h>
347836SJohn.Forte@Sun.COM #include <sys/cred.h>
357836SJohn.Forte@Sun.COM #include <sys/ddi.h>
367836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s.h>
377836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s_k.h>
387836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_errors.h>
397836SJohn.Forte@Sun.COM
407836SJohn.Forte@Sun.COM #include <sys/nsc_thread.h>
417836SJohn.Forte@Sun.COM #ifdef DS_DDICT
427836SJohn.Forte@Sun.COM #include "../contract.h"
437836SJohn.Forte@Sun.COM #endif
447836SJohn.Forte@Sun.COM #include <sys/nsctl/nsctl.h>
457836SJohn.Forte@Sun.COM #include <sys/nsctl/nsvers.h>
467836SJohn.Forte@Sun.COM
477836SJohn.Forte@Sun.COM #include <sys/sdt.h> /* dtrace is S10 or later */
487836SJohn.Forte@Sun.COM
497836SJohn.Forte@Sun.COM #include "rdc.h"
507836SJohn.Forte@Sun.COM #include "rdc_io.h"
517836SJohn.Forte@Sun.COM #include "rdc_bitmap.h"
527836SJohn.Forte@Sun.COM #include "rdc_ioctl.h"
537836SJohn.Forte@Sun.COM #include "rdcsrv.h"
547836SJohn.Forte@Sun.COM #include "rdc_diskq.h"
557836SJohn.Forte@Sun.COM
567836SJohn.Forte@Sun.COM #define DIDINIT 0x01
577836SJohn.Forte@Sun.COM #define DIDNODES 0x02
587836SJohn.Forte@Sun.COM #define DIDCONFIG 0x04
597836SJohn.Forte@Sun.COM
607836SJohn.Forte@Sun.COM static int rdcopen(dev_t *devp, int flag, int otyp, cred_t *crp);
617836SJohn.Forte@Sun.COM static int rdcclose(dev_t dev, int flag, int otyp, cred_t *crp);
627836SJohn.Forte@Sun.COM static int rdcprint(dev_t dev, char *str);
637836SJohn.Forte@Sun.COM static int rdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp,
647836SJohn.Forte@Sun.COM int *rvp);
657836SJohn.Forte@Sun.COM static int rdcattach(dev_info_t *dip, ddi_attach_cmd_t cmd);
667836SJohn.Forte@Sun.COM static int rdcdetach(dev_info_t *dip, ddi_detach_cmd_t cmd);
677836SJohn.Forte@Sun.COM static int rdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
687836SJohn.Forte@Sun.COM void **result);
697836SJohn.Forte@Sun.COM #ifdef DEBUG
707836SJohn.Forte@Sun.COM static int rdc_clrkstat(void *);
717836SJohn.Forte@Sun.COM #endif
727836SJohn.Forte@Sun.COM
737836SJohn.Forte@Sun.COM /*
747836SJohn.Forte@Sun.COM * kstat interface
757836SJohn.Forte@Sun.COM */
767836SJohn.Forte@Sun.COM static kstat_t *sndr_kstats;
777836SJohn.Forte@Sun.COM
787836SJohn.Forte@Sun.COM int sndr_info_stats_update(kstat_t *ksp, int rw);
797836SJohn.Forte@Sun.COM
807836SJohn.Forte@Sun.COM static sndr_m_stats_t sndr_info_stats = {
817836SJohn.Forte@Sun.COM {RDC_MKSTAT_MAXSETS, KSTAT_DATA_ULONG},
827836SJohn.Forte@Sun.COM {RDC_MKSTAT_MAXFBAS, KSTAT_DATA_ULONG},
837836SJohn.Forte@Sun.COM {RDC_MKSTAT_RPC_TIMEOUT, KSTAT_DATA_ULONG},
847836SJohn.Forte@Sun.COM {RDC_MKSTAT_HEALTH_THRES, KSTAT_DATA_ULONG},
857836SJohn.Forte@Sun.COM {RDC_MKSTAT_BITMAP_WRITES, KSTAT_DATA_ULONG},
867836SJohn.Forte@Sun.COM {RDC_MKSTAT_CLNT_COTS_CALLS, KSTAT_DATA_ULONG},
877836SJohn.Forte@Sun.COM {RDC_MKSTAT_CLNT_CLTS_CALLS, KSTAT_DATA_ULONG},
887836SJohn.Forte@Sun.COM {RDC_MKSTAT_SVC_COTS_CALLS, KSTAT_DATA_ULONG},
897836SJohn.Forte@Sun.COM {RDC_MKSTAT_SVC_CLTS_CALLS, KSTAT_DATA_ULONG},
907836SJohn.Forte@Sun.COM {RDC_MKSTAT_BITMAP_REF_DELAY, KSTAT_DATA_ULONG}
917836SJohn.Forte@Sun.COM };
927836SJohn.Forte@Sun.COM
937836SJohn.Forte@Sun.COM int rdc_info_stats_update(kstat_t *ksp, int rw);
947836SJohn.Forte@Sun.COM
957836SJohn.Forte@Sun.COM static rdc_info_stats_t rdc_info_stats = {
967836SJohn.Forte@Sun.COM {RDC_IKSTAT_FLAGS, KSTAT_DATA_ULONG},
977836SJohn.Forte@Sun.COM {RDC_IKSTAT_SYNCFLAGS, KSTAT_DATA_ULONG},
987836SJohn.Forte@Sun.COM {RDC_IKSTAT_BMPFLAGS, KSTAT_DATA_ULONG},
997836SJohn.Forte@Sun.COM {RDC_IKSTAT_SYNCPOS, KSTAT_DATA_ULONG},
1007836SJohn.Forte@Sun.COM {RDC_IKSTAT_VOLSIZE, KSTAT_DATA_ULONG},
1017836SJohn.Forte@Sun.COM {RDC_IKSTAT_BITSSET, KSTAT_DATA_ULONG},
1027836SJohn.Forte@Sun.COM {RDC_IKSTAT_AUTOSYNC, KSTAT_DATA_ULONG},
1037836SJohn.Forte@Sun.COM {RDC_IKSTAT_MAXQFBAS, KSTAT_DATA_ULONG},
1047836SJohn.Forte@Sun.COM {RDC_IKSTAT_MAXQITEMS, KSTAT_DATA_ULONG},
1057836SJohn.Forte@Sun.COM {RDC_IKSTAT_FILE, KSTAT_DATA_STRING},
1067836SJohn.Forte@Sun.COM {RDC_IKSTAT_SECFILE, KSTAT_DATA_STRING},
1077836SJohn.Forte@Sun.COM {RDC_IKSTAT_BITMAP, KSTAT_DATA_STRING},
1087836SJohn.Forte@Sun.COM {RDC_IKSTAT_PRIMARY_HOST, KSTAT_DATA_STRING},
1097836SJohn.Forte@Sun.COM {RDC_IKSTAT_SECONDARY_HOST, KSTAT_DATA_STRING},
1107836SJohn.Forte@Sun.COM {RDC_IKSTAT_TYPE_FLAG, KSTAT_DATA_ULONG},
1117836SJohn.Forte@Sun.COM {RDC_IKSTAT_BMP_SIZE, KSTAT_DATA_ULONG},
1127836SJohn.Forte@Sun.COM {RDC_IKSTAT_DISK_STATUS, KSTAT_DATA_ULONG},
1137836SJohn.Forte@Sun.COM {RDC_IKSTAT_IF_DOWN, KSTAT_DATA_ULONG},
1147836SJohn.Forte@Sun.COM {RDC_IKSTAT_IF_RPC_VERSION, KSTAT_DATA_ULONG},
1157836SJohn.Forte@Sun.COM {RDC_IKSTAT_ASYNC_BLOCK_HWM, KSTAT_DATA_ULONG},
1167836SJohn.Forte@Sun.COM {RDC_IKSTAT_ASYNC_ITEM_HWM, KSTAT_DATA_ULONG},
1177836SJohn.Forte@Sun.COM {RDC_IKSTAT_ASYNC_THROTTLE_DELAY, KSTAT_DATA_ULONG},
1187836SJohn.Forte@Sun.COM {RDC_IKSTAT_ASYNC_ITEMS, KSTAT_DATA_ULONG},
1197836SJohn.Forte@Sun.COM {RDC_IKSTAT_ASYNC_BLOCKS, KSTAT_DATA_ULONG},
1207836SJohn.Forte@Sun.COM {RDC_IKSTAT_QUEUE_TYPE, KSTAT_DATA_CHAR}
1217836SJohn.Forte@Sun.COM };
1227836SJohn.Forte@Sun.COM
1237836SJohn.Forte@Sun.COM static struct cb_ops rdc_cb_ops = {
1247836SJohn.Forte@Sun.COM rdcopen,
1257836SJohn.Forte@Sun.COM rdcclose,
1267836SJohn.Forte@Sun.COM nulldev, /* no strategy */
1277836SJohn.Forte@Sun.COM rdcprint,
1287836SJohn.Forte@Sun.COM nodev, /* no dump */
1297836SJohn.Forte@Sun.COM nodev, /* no read */
1307836SJohn.Forte@Sun.COM nodev, /* no write */
1317836SJohn.Forte@Sun.COM rdcioctl,
1327836SJohn.Forte@Sun.COM nodev, /* no devmap */
1337836SJohn.Forte@Sun.COM nodev, /* no mmap */
1347836SJohn.Forte@Sun.COM nodev, /* no segmap */
1357836SJohn.Forte@Sun.COM nochpoll,
1367836SJohn.Forte@Sun.COM ddi_prop_op,
1377836SJohn.Forte@Sun.COM NULL, /* not STREAMS */
1387836SJohn.Forte@Sun.COM D_NEW | D_MP | D_64BIT,
1397836SJohn.Forte@Sun.COM CB_REV,
1407836SJohn.Forte@Sun.COM nodev, /* no aread */
1417836SJohn.Forte@Sun.COM nodev, /* no awrite */
1427836SJohn.Forte@Sun.COM };
1437836SJohn.Forte@Sun.COM
1447836SJohn.Forte@Sun.COM static struct dev_ops rdc_ops = {
1457836SJohn.Forte@Sun.COM DEVO_REV,
1467836SJohn.Forte@Sun.COM 0,
1477836SJohn.Forte@Sun.COM rdcgetinfo,
1487836SJohn.Forte@Sun.COM nulldev, /* identify */
1497836SJohn.Forte@Sun.COM nulldev, /* probe */
1507836SJohn.Forte@Sun.COM rdcattach,
1517836SJohn.Forte@Sun.COM rdcdetach,
1527836SJohn.Forte@Sun.COM nodev, /* no reset */
1537836SJohn.Forte@Sun.COM &rdc_cb_ops,
1547836SJohn.Forte@Sun.COM (struct bus_ops *)NULL
1557836SJohn.Forte@Sun.COM };
1567836SJohn.Forte@Sun.COM
1577836SJohn.Forte@Sun.COM static struct modldrv rdc_ldrv = {
1587836SJohn.Forte@Sun.COM &mod_driverops,
1597836SJohn.Forte@Sun.COM "nws:Remote Mirror:" ISS_VERSION_STR,
1607836SJohn.Forte@Sun.COM &rdc_ops
1617836SJohn.Forte@Sun.COM };
1627836SJohn.Forte@Sun.COM
1637836SJohn.Forte@Sun.COM static struct modlinkage rdc_modlinkage = {
1647836SJohn.Forte@Sun.COM MODREV_1,
1657836SJohn.Forte@Sun.COM &rdc_ldrv,
1667836SJohn.Forte@Sun.COM NULL
1677836SJohn.Forte@Sun.COM };
1687836SJohn.Forte@Sun.COM
1697836SJohn.Forte@Sun.COM const int sndr_major_rev = ISS_VERSION_MAJ;
1707836SJohn.Forte@Sun.COM const int sndr_minor_rev = ISS_VERSION_MIN;
1717836SJohn.Forte@Sun.COM const int sndr_micro_rev = ISS_VERSION_MIC;
1727836SJohn.Forte@Sun.COM const int sndr_baseline_rev = ISS_VERSION_NUM;
1737836SJohn.Forte@Sun.COM static char sndr_version[16];
1747836SJohn.Forte@Sun.COM
1757836SJohn.Forte@Sun.COM static void *rdc_dip;
1767836SJohn.Forte@Sun.COM
1777836SJohn.Forte@Sun.COM extern int _rdc_init_dev();
1787836SJohn.Forte@Sun.COM extern void _rdc_deinit_dev();
1797836SJohn.Forte@Sun.COM extern void rdc_link_down_free();
1807836SJohn.Forte@Sun.COM
1817836SJohn.Forte@Sun.COM int rdc_bitmap_mode;
1827836SJohn.Forte@Sun.COM int rdc_auto_sync;
1837836SJohn.Forte@Sun.COM int rdc_max_sets;
1847836SJohn.Forte@Sun.COM extern int rdc_health_thres;
1857836SJohn.Forte@Sun.COM
1867836SJohn.Forte@Sun.COM kmutex_t rdc_sync_mutex;
1877836SJohn.Forte@Sun.COM rdc_sync_event_t rdc_sync_event;
1887836SJohn.Forte@Sun.COM clock_t rdc_sync_event_timeout;
1897836SJohn.Forte@Sun.COM
1907836SJohn.Forte@Sun.COM static void
rdc_sync_event_init()1917836SJohn.Forte@Sun.COM rdc_sync_event_init()
1927836SJohn.Forte@Sun.COM {
1937836SJohn.Forte@Sun.COM mutex_init(&rdc_sync_mutex, NULL, MUTEX_DRIVER, NULL);
1947836SJohn.Forte@Sun.COM mutex_init(&rdc_sync_event.mutex, NULL, MUTEX_DRIVER, NULL);
1957836SJohn.Forte@Sun.COM cv_init(&rdc_sync_event.cv, NULL, CV_DRIVER, NULL);
1967836SJohn.Forte@Sun.COM cv_init(&rdc_sync_event.done_cv, NULL, CV_DRIVER, NULL);
1977836SJohn.Forte@Sun.COM rdc_sync_event.master[0] = 0;
1987836SJohn.Forte@Sun.COM rdc_sync_event.lbolt = (clock_t)0;
1997836SJohn.Forte@Sun.COM rdc_sync_event_timeout = RDC_SYNC_EVENT_TIMEOUT;
2007836SJohn.Forte@Sun.COM }
2017836SJohn.Forte@Sun.COM
2027836SJohn.Forte@Sun.COM
2037836SJohn.Forte@Sun.COM static void
rdc_sync_event_destroy()2047836SJohn.Forte@Sun.COM rdc_sync_event_destroy()
2057836SJohn.Forte@Sun.COM {
2067836SJohn.Forte@Sun.COM mutex_destroy(&rdc_sync_mutex);
2077836SJohn.Forte@Sun.COM mutex_destroy(&rdc_sync_event.mutex);
2087836SJohn.Forte@Sun.COM cv_destroy(&rdc_sync_event.cv);
2097836SJohn.Forte@Sun.COM cv_destroy(&rdc_sync_event.done_cv);
2107836SJohn.Forte@Sun.COM }
2117836SJohn.Forte@Sun.COM
2127836SJohn.Forte@Sun.COM
2137836SJohn.Forte@Sun.COM
2147836SJohn.Forte@Sun.COM int
_init(void)2157836SJohn.Forte@Sun.COM _init(void)
2167836SJohn.Forte@Sun.COM {
2177836SJohn.Forte@Sun.COM return (mod_install(&rdc_modlinkage));
2187836SJohn.Forte@Sun.COM }
2197836SJohn.Forte@Sun.COM
2207836SJohn.Forte@Sun.COM int
_fini(void)2217836SJohn.Forte@Sun.COM _fini(void)
2227836SJohn.Forte@Sun.COM {
2237836SJohn.Forte@Sun.COM return (mod_remove(&rdc_modlinkage));
2247836SJohn.Forte@Sun.COM }
2257836SJohn.Forte@Sun.COM
2267836SJohn.Forte@Sun.COM int
_info(struct modinfo * modinfop)2277836SJohn.Forte@Sun.COM _info(struct modinfo *modinfop)
2287836SJohn.Forte@Sun.COM {
2297836SJohn.Forte@Sun.COM return (mod_info(&rdc_modlinkage, modinfop));
2307836SJohn.Forte@Sun.COM }
2317836SJohn.Forte@Sun.COM
2327836SJohn.Forte@Sun.COM static int
rdcattach(dev_info_t * dip,ddi_attach_cmd_t cmd)2337836SJohn.Forte@Sun.COM rdcattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2347836SJohn.Forte@Sun.COM {
2357836SJohn.Forte@Sun.COM intptr_t flags;
2367836SJohn.Forte@Sun.COM int instance;
2377836SJohn.Forte@Sun.COM int i;
2387836SJohn.Forte@Sun.COM
2397836SJohn.Forte@Sun.COM /*CONSTCOND*/
2407836SJohn.Forte@Sun.COM ASSERT(sizeof (u_longlong_t) == 8);
2417836SJohn.Forte@Sun.COM
2427836SJohn.Forte@Sun.COM if (cmd != DDI_ATTACH)
2437836SJohn.Forte@Sun.COM return (DDI_FAILURE);
2447836SJohn.Forte@Sun.COM
2457836SJohn.Forte@Sun.COM (void) strncpy(sndr_version, _VERSION_, sizeof (sndr_version));
2467836SJohn.Forte@Sun.COM
2477836SJohn.Forte@Sun.COM instance = ddi_get_instance(dip);
2487836SJohn.Forte@Sun.COM rdc_dip = dip;
2497836SJohn.Forte@Sun.COM
2507836SJohn.Forte@Sun.COM flags = 0;
2517836SJohn.Forte@Sun.COM
2527836SJohn.Forte@Sun.COM rdc_sync_event_init();
2537836SJohn.Forte@Sun.COM
2547836SJohn.Forte@Sun.COM /*
2557836SJohn.Forte@Sun.COM * rdc_max_sets must be set before calling _rdc_load().
2567836SJohn.Forte@Sun.COM */
2577836SJohn.Forte@Sun.COM
2587836SJohn.Forte@Sun.COM rdc_max_sets = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2597836SJohn.Forte@Sun.COM DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "rdc_max_sets", 64);
2607836SJohn.Forte@Sun.COM
2617836SJohn.Forte@Sun.COM if (_rdc_init_dev()) {
262*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc: _rdc_init_dev failed");
2637836SJohn.Forte@Sun.COM goto out;
2647836SJohn.Forte@Sun.COM }
2657836SJohn.Forte@Sun.COM flags |= DIDINIT;
2667836SJohn.Forte@Sun.COM
2677836SJohn.Forte@Sun.COM if (_rdc_load() != 0) {
268*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc: _rdc_load failed");
2697836SJohn.Forte@Sun.COM goto out;
2707836SJohn.Forte@Sun.COM }
2717836SJohn.Forte@Sun.COM
2727836SJohn.Forte@Sun.COM if (_rdc_configure()) {
273*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc: _rdc_configure failed");
2747836SJohn.Forte@Sun.COM goto out;
2757836SJohn.Forte@Sun.COM }
2767836SJohn.Forte@Sun.COM flags |= DIDCONFIG;
2777836SJohn.Forte@Sun.COM
2787836SJohn.Forte@Sun.COM if (ddi_create_minor_node(dip, "rdc", S_IFCHR, instance, DDI_PSEUDO, 0)
279*9093SRamana.Srikanth@Sun.COM != DDI_SUCCESS) {
280*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc: could not create node.");
2817836SJohn.Forte@Sun.COM goto out;
2827836SJohn.Forte@Sun.COM }
2837836SJohn.Forte@Sun.COM flags |= DIDNODES;
2847836SJohn.Forte@Sun.COM
2857836SJohn.Forte@Sun.COM rdc_bitmap_mode = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2867836SJohn.Forte@Sun.COM DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
2877836SJohn.Forte@Sun.COM "rdc_bitmap_mode", 0);
2887836SJohn.Forte@Sun.COM
2897836SJohn.Forte@Sun.COM switch (rdc_bitmap_mode) {
2907836SJohn.Forte@Sun.COM case RDC_BMP_AUTO: /* 0 */
2917836SJohn.Forte@Sun.COM break;
2927836SJohn.Forte@Sun.COM case RDC_BMP_ALWAYS: /* 1 */
2937836SJohn.Forte@Sun.COM break;
2947836SJohn.Forte@Sun.COM case RDC_BMP_NEVER: /* 2 */
295*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!SNDR bitmap mode override");
2967836SJohn.Forte@Sun.COM cmn_err(CE_CONT,
297*9093SRamana.Srikanth@Sun.COM "!SNDR: bitmaps will only be written on shutdown\n");
2987836SJohn.Forte@Sun.COM break;
2997836SJohn.Forte@Sun.COM default: /* unknown */
3007836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
301*9093SRamana.Srikanth@Sun.COM "!SNDR: unknown bitmap mode %d - autodetecting mode",
302*9093SRamana.Srikanth@Sun.COM rdc_bitmap_mode);
3037836SJohn.Forte@Sun.COM rdc_bitmap_mode = RDC_BMP_AUTO;
3047836SJohn.Forte@Sun.COM break;
3057836SJohn.Forte@Sun.COM }
3067836SJohn.Forte@Sun.COM
3077836SJohn.Forte@Sun.COM rdc_bitmap_init();
3087836SJohn.Forte@Sun.COM
3097836SJohn.Forte@Sun.COM rdc_auto_sync = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
3107836SJohn.Forte@Sun.COM DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
3117836SJohn.Forte@Sun.COM "rdc_auto_sync", 0);
3127836SJohn.Forte@Sun.COM
3137836SJohn.Forte@Sun.COM i = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
3147836SJohn.Forte@Sun.COM DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
3157836SJohn.Forte@Sun.COM "rdc_health_thres", RDC_HEALTH_THRESHOLD);
3167836SJohn.Forte@Sun.COM if (i >= RDC_MIN_HEALTH_THRES)
3177836SJohn.Forte@Sun.COM rdc_health_thres = i;
3187836SJohn.Forte@Sun.COM else
319*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!value rdc_heath_thres from rdc.conf ignored "
3207836SJohn.Forte@Sun.COM "as it is smaller than the min value of %d",
3217836SJohn.Forte@Sun.COM RDC_MIN_HEALTH_THRES);
3227836SJohn.Forte@Sun.COM
3237836SJohn.Forte@Sun.COM ddi_set_driver_private(dip, (caddr_t)flags);
3247836SJohn.Forte@Sun.COM ddi_report_dev(dip);
3257836SJohn.Forte@Sun.COM
3267836SJohn.Forte@Sun.COM sndr_kstats = kstat_create(RDC_KSTAT_MODULE, 0,
3277836SJohn.Forte@Sun.COM RDC_KSTAT_MINFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
3287836SJohn.Forte@Sun.COM sizeof (sndr_m_stats_t) / sizeof (kstat_named_t),
3297836SJohn.Forte@Sun.COM KSTAT_FLAG_VIRTUAL);
3307836SJohn.Forte@Sun.COM
3317836SJohn.Forte@Sun.COM if (sndr_kstats) {
3327836SJohn.Forte@Sun.COM sndr_kstats->ks_data = &sndr_info_stats;
3337836SJohn.Forte@Sun.COM sndr_kstats->ks_update = sndr_info_stats_update;
3347836SJohn.Forte@Sun.COM sndr_kstats->ks_private = &rdc_k_info[0];
3357836SJohn.Forte@Sun.COM kstat_install(sndr_kstats);
3367836SJohn.Forte@Sun.COM } else
337*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!SNDR: module kstats failed");
3387836SJohn.Forte@Sun.COM
3397836SJohn.Forte@Sun.COM return (DDI_SUCCESS);
3407836SJohn.Forte@Sun.COM
3417836SJohn.Forte@Sun.COM out:
3427836SJohn.Forte@Sun.COM DTRACE_PROBE(rdc_attach_failed);
3437836SJohn.Forte@Sun.COM ddi_set_driver_private(dip, (caddr_t)flags);
3447836SJohn.Forte@Sun.COM (void) rdcdetach(dip, DDI_DETACH);
3457836SJohn.Forte@Sun.COM return (DDI_FAILURE);
3467836SJohn.Forte@Sun.COM }
3477836SJohn.Forte@Sun.COM
3487836SJohn.Forte@Sun.COM static int
rdcdetach(dev_info_t * dip,ddi_detach_cmd_t cmd)3497836SJohn.Forte@Sun.COM rdcdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
3507836SJohn.Forte@Sun.COM {
3517836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
3527836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
3537836SJohn.Forte@Sun.COM int rdcd;
3547836SJohn.Forte@Sun.COM intptr_t flags;
3557836SJohn.Forte@Sun.COM
3567836SJohn.Forte@Sun.COM
3577836SJohn.Forte@Sun.COM if (cmd != DDI_DETACH) {
3587836SJohn.Forte@Sun.COM DTRACE_PROBE(rdc_detach_unknown_cmd);
3597836SJohn.Forte@Sun.COM return (DDI_FAILURE);
3607836SJohn.Forte@Sun.COM }
3617836SJohn.Forte@Sun.COM
3627836SJohn.Forte@Sun.COM if (rdc_k_info == NULL || rdc_u_info == NULL)
3637836SJohn.Forte@Sun.COM goto cleanup;
3647836SJohn.Forte@Sun.COM
3657836SJohn.Forte@Sun.COM mutex_enter(&rdc_conf_lock);
3667836SJohn.Forte@Sun.COM
3677836SJohn.Forte@Sun.COM for (rdcd = 0; rdcd < rdc_max_sets; rdcd++) {
3687836SJohn.Forte@Sun.COM krdc = &rdc_k_info[rdcd];
3697836SJohn.Forte@Sun.COM urdc = &rdc_u_info[rdcd];
3707836SJohn.Forte@Sun.COM
3717836SJohn.Forte@Sun.COM if (IS_ENABLED(urdc) || krdc->devices) {
3727836SJohn.Forte@Sun.COM #ifdef DEBUG
3737836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
3747836SJohn.Forte@Sun.COM "!rdc: cannot detach, rdcd %d still in use", rdcd);
3757836SJohn.Forte@Sun.COM #endif
3767836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
3777836SJohn.Forte@Sun.COM DTRACE_PROBE(rdc_detach_err_busy);
3787836SJohn.Forte@Sun.COM return (DDI_FAILURE);
3797836SJohn.Forte@Sun.COM }
3807836SJohn.Forte@Sun.COM }
3817836SJohn.Forte@Sun.COM
3827836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
3837836SJohn.Forte@Sun.COM
3847836SJohn.Forte@Sun.COM cleanup:
3857836SJohn.Forte@Sun.COM flags = (intptr_t)ddi_get_driver_private(dip);
3867836SJohn.Forte@Sun.COM
3877836SJohn.Forte@Sun.COM if (flags & DIDNODES)
3887836SJohn.Forte@Sun.COM ddi_remove_minor_node(dip, NULL);
3897836SJohn.Forte@Sun.COM
3907836SJohn.Forte@Sun.COM if (sndr_kstats) {
3917836SJohn.Forte@Sun.COM kstat_delete(sndr_kstats);
3927836SJohn.Forte@Sun.COM }
3937836SJohn.Forte@Sun.COM if (flags & DIDINIT)
3947836SJohn.Forte@Sun.COM _rdc_deinit_dev();
3957836SJohn.Forte@Sun.COM
3967836SJohn.Forte@Sun.COM if (flags & DIDCONFIG) {
3977836SJohn.Forte@Sun.COM (void) _rdc_deconfigure();
3987836SJohn.Forte@Sun.COM (void) _rdc_unload();
3997836SJohn.Forte@Sun.COM rdcsrv_unload();
4007836SJohn.Forte@Sun.COM }
4017836SJohn.Forte@Sun.COM
4027836SJohn.Forte@Sun.COM rdc_sync_event_destroy();
4037836SJohn.Forte@Sun.COM rdc_link_down_free();
4047836SJohn.Forte@Sun.COM
4057836SJohn.Forte@Sun.COM rdc_dip = NULL;
4067836SJohn.Forte@Sun.COM return (DDI_SUCCESS);
4077836SJohn.Forte@Sun.COM }
4087836SJohn.Forte@Sun.COM
4097836SJohn.Forte@Sun.COM /* ARGSUSED */
4107836SJohn.Forte@Sun.COM static int
rdcgetinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)4117836SJohn.Forte@Sun.COM rdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
4127836SJohn.Forte@Sun.COM {
4137836SJohn.Forte@Sun.COM int rc = DDI_FAILURE;
4147836SJohn.Forte@Sun.COM
4157836SJohn.Forte@Sun.COM switch (infocmd) {
4167836SJohn.Forte@Sun.COM
4177836SJohn.Forte@Sun.COM case DDI_INFO_DEVT2DEVINFO:
4187836SJohn.Forte@Sun.COM *result = rdc_dip;
4197836SJohn.Forte@Sun.COM rc = DDI_SUCCESS;
4207836SJohn.Forte@Sun.COM break;
4217836SJohn.Forte@Sun.COM
4227836SJohn.Forte@Sun.COM case DDI_INFO_DEVT2INSTANCE:
4237836SJohn.Forte@Sun.COM /* We only have a single instance */
4247836SJohn.Forte@Sun.COM *result = 0;
4257836SJohn.Forte@Sun.COM rc = DDI_SUCCESS;
4267836SJohn.Forte@Sun.COM break;
4277836SJohn.Forte@Sun.COM
4287836SJohn.Forte@Sun.COM default:
4297836SJohn.Forte@Sun.COM break;
4307836SJohn.Forte@Sun.COM }
4317836SJohn.Forte@Sun.COM
4327836SJohn.Forte@Sun.COM return (rc);
4337836SJohn.Forte@Sun.COM }
4347836SJohn.Forte@Sun.COM
4357836SJohn.Forte@Sun.COM
4367836SJohn.Forte@Sun.COM /* ARGSUSED */
4377836SJohn.Forte@Sun.COM
4387836SJohn.Forte@Sun.COM static int
rdcopen(dev_t * devp,int flag,int otyp,cred_t * crp)4397836SJohn.Forte@Sun.COM rdcopen(dev_t *devp, int flag, int otyp, cred_t *crp)
4407836SJohn.Forte@Sun.COM {
4417836SJohn.Forte@Sun.COM return (0);
4427836SJohn.Forte@Sun.COM }
4437836SJohn.Forte@Sun.COM
4447836SJohn.Forte@Sun.COM
4457836SJohn.Forte@Sun.COM /* ARGSUSED */
4467836SJohn.Forte@Sun.COM
4477836SJohn.Forte@Sun.COM static int
rdcclose(dev_t dev,int flag,int otyp,cred_t * crp)4487836SJohn.Forte@Sun.COM rdcclose(dev_t dev, int flag, int otyp, cred_t *crp)
4497836SJohn.Forte@Sun.COM {
4507836SJohn.Forte@Sun.COM return (0);
4517836SJohn.Forte@Sun.COM }
4527836SJohn.Forte@Sun.COM
4537836SJohn.Forte@Sun.COM /* ARGSUSED */
4547836SJohn.Forte@Sun.COM
4557836SJohn.Forte@Sun.COM static int
rdcprint(dev_t dev,char * str)4567836SJohn.Forte@Sun.COM rdcprint(dev_t dev, char *str)
4577836SJohn.Forte@Sun.COM {
4587836SJohn.Forte@Sun.COM int instance = 0;
4597836SJohn.Forte@Sun.COM
460*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc%d: %s", instance, str);
4617836SJohn.Forte@Sun.COM return (0);
4627836SJohn.Forte@Sun.COM }
4637836SJohn.Forte@Sun.COM
4647836SJohn.Forte@Sun.COM
4657836SJohn.Forte@Sun.COM static int
convert_ioctl_args(int cmd,intptr_t arg,int mode,_rdc_ioctl_t * args)4667836SJohn.Forte@Sun.COM convert_ioctl_args(int cmd, intptr_t arg, int mode, _rdc_ioctl_t *args)
4677836SJohn.Forte@Sun.COM {
4687836SJohn.Forte@Sun.COM _rdc_ioctl32_t args32;
4697836SJohn.Forte@Sun.COM
4707836SJohn.Forte@Sun.COM if (ddi_copyin((void *)arg, &args32, sizeof (_rdc_ioctl32_t), mode))
4717836SJohn.Forte@Sun.COM return (EFAULT);
4727836SJohn.Forte@Sun.COM
4737836SJohn.Forte@Sun.COM bzero((void *)args, sizeof (_rdc_ioctl_t));
4747836SJohn.Forte@Sun.COM
4757836SJohn.Forte@Sun.COM switch (cmd) {
4767836SJohn.Forte@Sun.COM case RDC_CONFIG:
4777836SJohn.Forte@Sun.COM args->arg0 = (uint32_t)args32.arg0; /* _rdc_config_t * */
4787836SJohn.Forte@Sun.COM args->arg1 = (uint32_t)args32.arg1; /* pointer */
4797836SJohn.Forte@Sun.COM args->arg2 = (uint32_t)args32.arg2; /* size */
4807836SJohn.Forte@Sun.COM args->ustatus = (spcs_s_info_t)args32.ustatus;
4817836SJohn.Forte@Sun.COM break;
4827836SJohn.Forte@Sun.COM
4837836SJohn.Forte@Sun.COM case RDC_STATUS:
4847836SJohn.Forte@Sun.COM args->arg0 = (uint32_t)args32.arg0; /* pointer */
4857836SJohn.Forte@Sun.COM args->ustatus = (spcs_s_info_t)args32.ustatus;
4867836SJohn.Forte@Sun.COM break;
4877836SJohn.Forte@Sun.COM
4887836SJohn.Forte@Sun.COM case RDC_ENABLE_SVR:
4897836SJohn.Forte@Sun.COM args->arg0 = (uint32_t)args32.arg0; /* _rdc_svc_args * */
4907836SJohn.Forte@Sun.COM break;
4917836SJohn.Forte@Sun.COM
4927836SJohn.Forte@Sun.COM case RDC_VERSION:
4937836SJohn.Forte@Sun.COM args->arg0 = (uint32_t)args32.arg0; /* _rdc_version_t * */
4947836SJohn.Forte@Sun.COM args->ustatus = (spcs_s_info_t)args32.ustatus;
4957836SJohn.Forte@Sun.COM break;
4967836SJohn.Forte@Sun.COM
4977836SJohn.Forte@Sun.COM case RDC_SYNC_EVENT:
4987836SJohn.Forte@Sun.COM args->arg0 = (uint32_t)args32.arg0; /* char * */
4997836SJohn.Forte@Sun.COM args->arg1 = (uint32_t)args32.arg1; /* char * */
5007836SJohn.Forte@Sun.COM args->ustatus = (spcs_s_info_t)args32.ustatus;
5017836SJohn.Forte@Sun.COM break;
5027836SJohn.Forte@Sun.COM
5037836SJohn.Forte@Sun.COM case RDC_LINK_DOWN:
5047836SJohn.Forte@Sun.COM args->arg0 = (uint32_t)args32.arg0; /* char * */
5057836SJohn.Forte@Sun.COM args->ustatus = (spcs_s_info_t)args32.ustatus;
5067836SJohn.Forte@Sun.COM break;
5077836SJohn.Forte@Sun.COM case RDC_POOL_CREATE:
5087836SJohn.Forte@Sun.COM args->arg0 = (uint32_t)args32.arg0; /* svcpool_args * */
5097836SJohn.Forte@Sun.COM break;
5107836SJohn.Forte@Sun.COM case RDC_POOL_WAIT:
5117836SJohn.Forte@Sun.COM args->arg0 = (uint32_t)args32.arg0; /* int */
5127836SJohn.Forte@Sun.COM break;
5137836SJohn.Forte@Sun.COM case RDC_POOL_RUN:
5147836SJohn.Forte@Sun.COM args->arg0 = (uint32_t)args32.arg0; /* int */
5157836SJohn.Forte@Sun.COM break;
5167836SJohn.Forte@Sun.COM
5177836SJohn.Forte@Sun.COM default:
5187836SJohn.Forte@Sun.COM return (EINVAL);
5197836SJohn.Forte@Sun.COM }
5207836SJohn.Forte@Sun.COM
5217836SJohn.Forte@Sun.COM return (0);
5227836SJohn.Forte@Sun.COM }
5237836SJohn.Forte@Sun.COM
5247836SJohn.Forte@Sun.COM
5257836SJohn.Forte@Sun.COM /*
5267836SJohn.Forte@Sun.COM * Yet another standard thing that is not standard ...
5277836SJohn.Forte@Sun.COM */
5287836SJohn.Forte@Sun.COM #ifndef offsetof
5297836SJohn.Forte@Sun.COM #define offsetof(s, m) ((size_t)(&((s *)0)->m))
5307836SJohn.Forte@Sun.COM #endif
5317836SJohn.Forte@Sun.COM
5327836SJohn.Forte@Sun.COM /*
5337836SJohn.Forte@Sun.COM * Build a 32bit rdc_set structure and copyout to the user level.
5347836SJohn.Forte@Sun.COM */
5357836SJohn.Forte@Sun.COM int
rdc_status_copy32(const void * arg,void * usetp,size_t size,int mode)5367836SJohn.Forte@Sun.COM rdc_status_copy32(const void *arg, void *usetp, size_t size, int mode)
5377836SJohn.Forte@Sun.COM {
5387836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = (rdc_u_info_t *)arg;
5397836SJohn.Forte@Sun.COM struct rdc_set32 set32;
5407836SJohn.Forte@Sun.COM size_t tailsize;
5417836SJohn.Forte@Sun.COM #ifdef DEBUG
5427836SJohn.Forte@Sun.COM size_t tailsize32;
5437836SJohn.Forte@Sun.COM #endif
5447836SJohn.Forte@Sun.COM
5457836SJohn.Forte@Sun.COM bzero(&set32, sizeof (set32));
5467836SJohn.Forte@Sun.COM
5477836SJohn.Forte@Sun.COM tailsize = sizeof (struct rdc_addr32) -
548*9093SRamana.Srikanth@Sun.COM offsetof(struct rdc_addr32, intf);
5497836SJohn.Forte@Sun.COM
5507836SJohn.Forte@Sun.COM /* primary address structure, avoiding netbuf */
5517836SJohn.Forte@Sun.COM bcopy(&urdc->primary.intf[0], &set32.primary.intf[0], tailsize);
5527836SJohn.Forte@Sun.COM
5537836SJohn.Forte@Sun.COM /* secondary address structure, avoiding netbuf */
5547836SJohn.Forte@Sun.COM bcopy(&urdc->secondary.intf[0], &set32.secondary.intf[0], tailsize);
5557836SJohn.Forte@Sun.COM
5567836SJohn.Forte@Sun.COM /*
5577836SJohn.Forte@Sun.COM * the rest, avoiding netconfig
5587836SJohn.Forte@Sun.COM * note: the tail must be the same size in both structures
5597836SJohn.Forte@Sun.COM */
5607836SJohn.Forte@Sun.COM tailsize = sizeof (struct rdc_set) - offsetof(struct rdc_set, flags);
5617836SJohn.Forte@Sun.COM #ifdef DEBUG
5627836SJohn.Forte@Sun.COM /*
5637836SJohn.Forte@Sun.COM * ASSERT is calling for debug reason, and tailsize32 is only declared
5647836SJohn.Forte@Sun.COM * for ASSERT, put them under debug to avoid lint warning.
5657836SJohn.Forte@Sun.COM */
5667836SJohn.Forte@Sun.COM tailsize32 = sizeof (struct rdc_set32) -
567*9093SRamana.Srikanth@Sun.COM offsetof(struct rdc_set32, flags);
5687836SJohn.Forte@Sun.COM ASSERT(tailsize == tailsize32);
5697836SJohn.Forte@Sun.COM #endif
5707836SJohn.Forte@Sun.COM
5717836SJohn.Forte@Sun.COM bcopy(&urdc->flags, &set32.flags, tailsize);
5727836SJohn.Forte@Sun.COM
5737836SJohn.Forte@Sun.COM /* copyout to user level */
5747836SJohn.Forte@Sun.COM return (ddi_copyout(&set32, usetp, size, mode));
5757836SJohn.Forte@Sun.COM }
5767836SJohn.Forte@Sun.COM
5777836SJohn.Forte@Sun.COM
5787836SJohn.Forte@Sun.COM /*
5797836SJohn.Forte@Sun.COM * Status ioctl.
5807836SJohn.Forte@Sun.COM */
5817836SJohn.Forte@Sun.COM static int
rdcstatus(_rdc_ioctl_t * args,int mode)5827836SJohn.Forte@Sun.COM rdcstatus(_rdc_ioctl_t *args, int mode)
5837836SJohn.Forte@Sun.COM {
5847836SJohn.Forte@Sun.COM int (*copyout)(const void *, void *, size_t, int);
5857836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
5867836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
5877836SJohn.Forte@Sun.COM disk_queue *dqp;
5887836SJohn.Forte@Sun.COM char *usetp; /* pointer to user rdc_set structure */
5897836SJohn.Forte@Sun.COM size_t size; /* sizeof user rdc_set structure */
5907836SJohn.Forte@Sun.COM int32_t *maxsetsp; /* address of status->maxsets; */
5917836SJohn.Forte@Sun.COM int nset, max, i, j;
5927836SJohn.Forte@Sun.COM
5937836SJohn.Forte@Sun.COM if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
5947836SJohn.Forte@Sun.COM struct rdc_status32 status32;
5957836SJohn.Forte@Sun.COM
5967836SJohn.Forte@Sun.COM if (ddi_copyin((void *)args->arg0, &status32,
5977836SJohn.Forte@Sun.COM sizeof (status32), mode)) {
5987836SJohn.Forte@Sun.COM return (EFAULT);
5997836SJohn.Forte@Sun.COM }
6007836SJohn.Forte@Sun.COM
6017836SJohn.Forte@Sun.COM usetp = ((char *)args->arg0) +
6027836SJohn.Forte@Sun.COM offsetof(struct rdc_status32, rdc_set);
6037836SJohn.Forte@Sun.COM maxsetsp = (int32_t *)((char *)args->arg0 +
6047836SJohn.Forte@Sun.COM offsetof(struct rdc_status32, maxsets));
6057836SJohn.Forte@Sun.COM nset = status32.nset;
6067836SJohn.Forte@Sun.COM
6077836SJohn.Forte@Sun.COM size = sizeof (struct rdc_set32);
6087836SJohn.Forte@Sun.COM copyout = rdc_status_copy32;
6097836SJohn.Forte@Sun.COM } else {
6107836SJohn.Forte@Sun.COM struct rdc_status status;
6117836SJohn.Forte@Sun.COM
6127836SJohn.Forte@Sun.COM if (ddi_copyin((void *)args->arg0, &status,
6137836SJohn.Forte@Sun.COM sizeof (status), mode)) {
6147836SJohn.Forte@Sun.COM return (EFAULT);
6157836SJohn.Forte@Sun.COM }
6167836SJohn.Forte@Sun.COM
6177836SJohn.Forte@Sun.COM usetp = ((char *)args->arg0) +
6187836SJohn.Forte@Sun.COM offsetof(struct rdc_status, rdc_set);
6197836SJohn.Forte@Sun.COM maxsetsp = (int32_t *)((char *)args->arg0 +
6207836SJohn.Forte@Sun.COM offsetof(struct rdc_status, maxsets));
6217836SJohn.Forte@Sun.COM nset = status.nset;
6227836SJohn.Forte@Sun.COM
6237836SJohn.Forte@Sun.COM size = sizeof (struct rdc_set);
6247836SJohn.Forte@Sun.COM copyout = ddi_copyout;
6257836SJohn.Forte@Sun.COM }
6267836SJohn.Forte@Sun.COM
6277836SJohn.Forte@Sun.COM max = min(nset, rdc_max_sets);
6287836SJohn.Forte@Sun.COM
6297836SJohn.Forte@Sun.COM for (i = 0, j = 0; i < max; i++) {
6307836SJohn.Forte@Sun.COM urdc = &rdc_u_info[i];
6317836SJohn.Forte@Sun.COM krdc = &rdc_k_info[i];
6327836SJohn.Forte@Sun.COM
6337836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc))
6347836SJohn.Forte@Sun.COM continue;
6357836SJohn.Forte@Sun.COM
6367836SJohn.Forte@Sun.COM /*
6377836SJohn.Forte@Sun.COM * sneak out qstate in urdc->flags
6387836SJohn.Forte@Sun.COM * this is harmless because it's value is not used
6397836SJohn.Forte@Sun.COM * in urdc->flags. the real qstate is kept in
6407836SJohn.Forte@Sun.COM * group->diskq->disk_hdr.h.state
6417836SJohn.Forte@Sun.COM */
6427836SJohn.Forte@Sun.COM if (RDC_IS_DISKQ(krdc->group)) {
6437836SJohn.Forte@Sun.COM dqp = &krdc->group->diskq;
6447836SJohn.Forte@Sun.COM if (IS_QSTATE(dqp, RDC_QNOBLOCK))
6457836SJohn.Forte@Sun.COM urdc->flags |= RDC_QNOBLOCK;
6467836SJohn.Forte@Sun.COM }
6477836SJohn.Forte@Sun.COM
6487836SJohn.Forte@Sun.COM j++;
6497836SJohn.Forte@Sun.COM if ((*copyout)(urdc, usetp, size, mode) != 0)
6507836SJohn.Forte@Sun.COM return (EFAULT);
6517836SJohn.Forte@Sun.COM
6527836SJohn.Forte@Sun.COM urdc->flags &= ~RDC_QNOBLOCK; /* clear qstate */
6537836SJohn.Forte@Sun.COM usetp += size;
6547836SJohn.Forte@Sun.COM }
6557836SJohn.Forte@Sun.COM
6567836SJohn.Forte@Sun.COM /* copyout rdc_max_sets value */
6577836SJohn.Forte@Sun.COM
6587836SJohn.Forte@Sun.COM if (ddi_copyout(&rdc_max_sets, maxsetsp, sizeof (*maxsetsp), mode) != 0)
6597836SJohn.Forte@Sun.COM return (EFAULT);
6607836SJohn.Forte@Sun.COM
6617836SJohn.Forte@Sun.COM /* copyout number of sets manipulated */
6627836SJohn.Forte@Sun.COM
6637836SJohn.Forte@Sun.COM /*CONSTCOND*/
6647836SJohn.Forte@Sun.COM ASSERT(offsetof(struct rdc_status32, nset) == 0);
6657836SJohn.Forte@Sun.COM /*CONSTCOND*/
6667836SJohn.Forte@Sun.COM ASSERT(offsetof(struct rdc_status, nset) == 0);
6677836SJohn.Forte@Sun.COM
6687836SJohn.Forte@Sun.COM return (ddi_copyout(&j, (void *)args->arg0, sizeof (int), mode));
6697836SJohn.Forte@Sun.COM }
6707836SJohn.Forte@Sun.COM
6717836SJohn.Forte@Sun.COM
6727836SJohn.Forte@Sun.COM /* ARGSUSED */
6737836SJohn.Forte@Sun.COM
6747836SJohn.Forte@Sun.COM static int
rdcioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * crp,int * rvp)6757836SJohn.Forte@Sun.COM rdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
6767836SJohn.Forte@Sun.COM {
6777836SJohn.Forte@Sun.COM spcs_s_info_t kstatus = NULL;
6787836SJohn.Forte@Sun.COM _rdc_ioctl_t args;
6797836SJohn.Forte@Sun.COM int error;
6807836SJohn.Forte@Sun.COM int rc = 0;
6817836SJohn.Forte@Sun.COM
6827836SJohn.Forte@Sun.COM if (cmd != RDC_STATUS) {
6837836SJohn.Forte@Sun.COM if ((error = drv_priv(crp)) != 0)
6847836SJohn.Forte@Sun.COM return (error);
6857836SJohn.Forte@Sun.COM }
6867836SJohn.Forte@Sun.COM #ifdef DEBUG
6877836SJohn.Forte@Sun.COM if (cmd == RDC_ASYNC6) {
6887836SJohn.Forte@Sun.COM rc = rdc_async6((void *)arg, mode, rvp);
6897836SJohn.Forte@Sun.COM return (rc);
6907836SJohn.Forte@Sun.COM }
6917836SJohn.Forte@Sun.COM
6927836SJohn.Forte@Sun.COM if (cmd == RDC_CLRKSTAT) {
6937836SJohn.Forte@Sun.COM rc = rdc_clrkstat((void *)arg);
6947836SJohn.Forte@Sun.COM return (rc);
6957836SJohn.Forte@Sun.COM }
6967836SJohn.Forte@Sun.COM
6977836SJohn.Forte@Sun.COM if (cmd == RDC_STALL0) {
6987836SJohn.Forte@Sun.COM if (((int)arg > 1) || ((int)arg < 0))
6997836SJohn.Forte@Sun.COM return (EINVAL);
7007836SJohn.Forte@Sun.COM rdc_stallzero((int)arg);
7017836SJohn.Forte@Sun.COM return (0);
7027836SJohn.Forte@Sun.COM }
7037836SJohn.Forte@Sun.COM if (cmd == RDC_READGEN) {
7047836SJohn.Forte@Sun.COM rc = rdc_readgen((void *)arg, mode, rvp);
7057836SJohn.Forte@Sun.COM return (rc);
7067836SJohn.Forte@Sun.COM }
7077836SJohn.Forte@Sun.COM #endif
7087836SJohn.Forte@Sun.COM if (cmd == RDC_BITMAPOP) {
7097836SJohn.Forte@Sun.COM rdc_bitmap_op_t bmop;
7107836SJohn.Forte@Sun.COM rdc_bitmap_op32_t bmop32;
7117836SJohn.Forte@Sun.COM
7127836SJohn.Forte@Sun.COM if (ddi_model_convert_from(mode & FMODELS)
7137836SJohn.Forte@Sun.COM == DDI_MODEL_ILP32) {
7147836SJohn.Forte@Sun.COM if (ddi_copyin((void *)arg, &bmop32, sizeof (bmop32),
7157836SJohn.Forte@Sun.COM mode))
7167836SJohn.Forte@Sun.COM return (EFAULT);
7177836SJohn.Forte@Sun.COM bmop.offset = bmop32.offset;
7187836SJohn.Forte@Sun.COM bmop.op = bmop32.op;
7197836SJohn.Forte@Sun.COM (void) strncpy(bmop.sechost, bmop32.sechost,
7207836SJohn.Forte@Sun.COM MAX_RDC_HOST_SIZE);
7217836SJohn.Forte@Sun.COM (void) strncpy(bmop.secfile, bmop32.secfile,
7227836SJohn.Forte@Sun.COM NSC_MAXPATH);
7237836SJohn.Forte@Sun.COM bmop.len = bmop32.len;
7247836SJohn.Forte@Sun.COM bmop.addr = (unsigned long)bmop32.addr;
7257836SJohn.Forte@Sun.COM } else {
7267836SJohn.Forte@Sun.COM if (ddi_copyin((void *)arg, &bmop, sizeof (bmop),
7277836SJohn.Forte@Sun.COM mode))
7287836SJohn.Forte@Sun.COM return (EFAULT);
7297836SJohn.Forte@Sun.COM }
7307836SJohn.Forte@Sun.COM rc = rdc_bitmapset(bmop.op, bmop.sechost, bmop.secfile,
7317836SJohn.Forte@Sun.COM (void *)bmop.addr, bmop.len, bmop.offset, mode);
7327836SJohn.Forte@Sun.COM return (rc);
7337836SJohn.Forte@Sun.COM }
7347836SJohn.Forte@Sun.COM
7357836SJohn.Forte@Sun.COM if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
7367836SJohn.Forte@Sun.COM if ((rc = convert_ioctl_args(cmd, arg, mode, &args)) != 0)
7377836SJohn.Forte@Sun.COM return (rc);
7387836SJohn.Forte@Sun.COM } else {
7397836SJohn.Forte@Sun.COM if (ddi_copyin((void *)arg, &args,
7407836SJohn.Forte@Sun.COM sizeof (_rdc_ioctl_t), mode)) {
7417836SJohn.Forte@Sun.COM return (EFAULT);
7427836SJohn.Forte@Sun.COM }
7437836SJohn.Forte@Sun.COM }
7447836SJohn.Forte@Sun.COM
7457836SJohn.Forte@Sun.COM kstatus = spcs_s_kcreate();
7467836SJohn.Forte@Sun.COM if (!kstatus) {
7477836SJohn.Forte@Sun.COM return (ENOMEM);
7487836SJohn.Forte@Sun.COM }
7497836SJohn.Forte@Sun.COM
7507836SJohn.Forte@Sun.COM
7517836SJohn.Forte@Sun.COM switch (cmd) {
7527836SJohn.Forte@Sun.COM
7537836SJohn.Forte@Sun.COM case RDC_POOL_CREATE: {
7547836SJohn.Forte@Sun.COM struct svcpool_args p;
7557836SJohn.Forte@Sun.COM
7567836SJohn.Forte@Sun.COM if (ddi_copyin((void *)arg, &p, sizeof (p), mode)) {
7577836SJohn.Forte@Sun.COM spcs_s_kfree(kstatus);
7587836SJohn.Forte@Sun.COM return (EFAULT);
7597836SJohn.Forte@Sun.COM }
7607836SJohn.Forte@Sun.COM error = svc_pool_create(&p);
7617836SJohn.Forte@Sun.COM
7627836SJohn.Forte@Sun.COM break;
7637836SJohn.Forte@Sun.COM }
7647836SJohn.Forte@Sun.COM case RDC_POOL_WAIT: {
7657836SJohn.Forte@Sun.COM int id;
7667836SJohn.Forte@Sun.COM
7677836SJohn.Forte@Sun.COM if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
7687836SJohn.Forte@Sun.COM spcs_s_kfree(kstatus);
7697836SJohn.Forte@Sun.COM return (EFAULT);
7707836SJohn.Forte@Sun.COM }
7717836SJohn.Forte@Sun.COM
7727836SJohn.Forte@Sun.COM error = svc_wait(id);
7737836SJohn.Forte@Sun.COM break;
7747836SJohn.Forte@Sun.COM }
7757836SJohn.Forte@Sun.COM case RDC_POOL_RUN: {
7767836SJohn.Forte@Sun.COM int id;
7777836SJohn.Forte@Sun.COM
7787836SJohn.Forte@Sun.COM if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
7797836SJohn.Forte@Sun.COM spcs_s_kfree(kstatus);
7807836SJohn.Forte@Sun.COM return (EFAULT);
7817836SJohn.Forte@Sun.COM }
7827836SJohn.Forte@Sun.COM error = svc_do_run(id);
7837836SJohn.Forte@Sun.COM break;
7847836SJohn.Forte@Sun.COM }
7857836SJohn.Forte@Sun.COM case RDC_ENABLE_SVR:
7867836SJohn.Forte@Sun.COM {
7877836SJohn.Forte@Sun.COM STRUCT_DECL(rdc_svc_args, parms);
7887836SJohn.Forte@Sun.COM
7897836SJohn.Forte@Sun.COM STRUCT_INIT(parms, mode);
7907836SJohn.Forte@Sun.COM /* Only used by sndrd which does not use unistat */
7917836SJohn.Forte@Sun.COM
7927836SJohn.Forte@Sun.COM if (ddi_copyin((void *)args.arg0, STRUCT_BUF(parms),
7937836SJohn.Forte@Sun.COM STRUCT_SIZE(parms), mode)) {
7947836SJohn.Forte@Sun.COM spcs_s_kfree(kstatus);
7957836SJohn.Forte@Sun.COM return (EFAULT);
7967836SJohn.Forte@Sun.COM }
7977836SJohn.Forte@Sun.COM rc = rdc_start_server(STRUCT_BUF(parms), mode);
7987836SJohn.Forte@Sun.COM }
7997836SJohn.Forte@Sun.COM break;
8007836SJohn.Forte@Sun.COM
8017836SJohn.Forte@Sun.COM case RDC_STATUS:
8027836SJohn.Forte@Sun.COM rc = rdcstatus(&args, mode);
8037836SJohn.Forte@Sun.COM break;
8047836SJohn.Forte@Sun.COM
8057836SJohn.Forte@Sun.COM case RDC_CONFIG:
8067836SJohn.Forte@Sun.COM rc = _rdc_config((void *)args.arg0, mode, kstatus, rvp);
8077836SJohn.Forte@Sun.COM spcs_s_copyoutf(&kstatus, args.ustatus);
8087836SJohn.Forte@Sun.COM return (rc);
8097836SJohn.Forte@Sun.COM
8107836SJohn.Forte@Sun.COM case RDC_VERSION:
8117836SJohn.Forte@Sun.COM {
8127836SJohn.Forte@Sun.COM STRUCT_DECL(rdc_version, parms);
8137836SJohn.Forte@Sun.COM
8147836SJohn.Forte@Sun.COM STRUCT_INIT(parms, mode);
8157836SJohn.Forte@Sun.COM
8167836SJohn.Forte@Sun.COM STRUCT_FSET(parms, major, sndr_major_rev);
8177836SJohn.Forte@Sun.COM STRUCT_FSET(parms, minor, sndr_minor_rev);
8187836SJohn.Forte@Sun.COM STRUCT_FSET(parms, micro, sndr_micro_rev);
8197836SJohn.Forte@Sun.COM STRUCT_FSET(parms, baseline, sndr_baseline_rev);
8207836SJohn.Forte@Sun.COM
8217836SJohn.Forte@Sun.COM if (ddi_copyout(STRUCT_BUF(parms), (void *)args.arg0,
822*9093SRamana.Srikanth@Sun.COM STRUCT_SIZE(parms), mode)) {
8237836SJohn.Forte@Sun.COM spcs_s_kfree(kstatus);
8247836SJohn.Forte@Sun.COM return (EFAULT);
8257836SJohn.Forte@Sun.COM }
8267836SJohn.Forte@Sun.COM break;
8277836SJohn.Forte@Sun.COM }
8287836SJohn.Forte@Sun.COM
8297836SJohn.Forte@Sun.COM case RDC_LINK_DOWN:
8307836SJohn.Forte@Sun.COM /* char *host from user */
8317836SJohn.Forte@Sun.COM rc = _rdc_link_down((void *)args.arg0, mode, kstatus, rvp);
8327836SJohn.Forte@Sun.COM spcs_s_copyoutf(&kstatus, args.ustatus);
8337836SJohn.Forte@Sun.COM
8347836SJohn.Forte@Sun.COM return (rc);
8357836SJohn.Forte@Sun.COM
8367836SJohn.Forte@Sun.COM case RDC_SYNC_EVENT:
8377836SJohn.Forte@Sun.COM rc = _rdc_sync_event_wait((void *)args.arg0, (void *)args.arg1,
8387836SJohn.Forte@Sun.COM mode, kstatus, rvp);
8397836SJohn.Forte@Sun.COM spcs_s_copyoutf(&kstatus, args.ustatus);
8407836SJohn.Forte@Sun.COM
8417836SJohn.Forte@Sun.COM return (rc);
8427836SJohn.Forte@Sun.COM
8437836SJohn.Forte@Sun.COM
8447836SJohn.Forte@Sun.COM default:
8457836SJohn.Forte@Sun.COM rc = EINVAL;
8467836SJohn.Forte@Sun.COM break;
8477836SJohn.Forte@Sun.COM }
8487836SJohn.Forte@Sun.COM
8497836SJohn.Forte@Sun.COM spcs_s_kfree(kstatus);
8507836SJohn.Forte@Sun.COM return (rc);
8517836SJohn.Forte@Sun.COM }
8527836SJohn.Forte@Sun.COM
8537836SJohn.Forte@Sun.COM int
sndr_info_stats_update(kstat_t * ksp,int rw)8547836SJohn.Forte@Sun.COM sndr_info_stats_update(kstat_t *ksp, int rw)
8557836SJohn.Forte@Sun.COM {
8567836SJohn.Forte@Sun.COM extern int rdc_rpc_tmout;
8577836SJohn.Forte@Sun.COM extern int rdc_health_thres;
8587836SJohn.Forte@Sun.COM extern int rdc_bitmap_delay;
8597836SJohn.Forte@Sun.COM extern long rdc_clnt_count;
8607836SJohn.Forte@Sun.COM extern long rdc_svc_count;
8617836SJohn.Forte@Sun.COM sndr_m_stats_t *info_stats;
8627836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
8637836SJohn.Forte@Sun.COM
8647836SJohn.Forte@Sun.COM info_stats = (sndr_m_stats_t *)(ksp->ks_data);
8657836SJohn.Forte@Sun.COM krdc = (rdc_k_info_t *)(ksp->ks_private);
8667836SJohn.Forte@Sun.COM
8677836SJohn.Forte@Sun.COM /* no writes currently allowed */
8687836SJohn.Forte@Sun.COM
8697836SJohn.Forte@Sun.COM if (rw == KSTAT_WRITE) {
8707836SJohn.Forte@Sun.COM return (EACCES);
8717836SJohn.Forte@Sun.COM }
8727836SJohn.Forte@Sun.COM
8737836SJohn.Forte@Sun.COM /* default to READ */
8747836SJohn.Forte@Sun.COM info_stats->m_maxsets.value.ul = rdc_max_sets;
8757836SJohn.Forte@Sun.COM info_stats->m_maxfbas.value.ul = krdc->maxfbas;
8767836SJohn.Forte@Sun.COM info_stats->m_rpc_timeout.value.ul = rdc_rpc_tmout;
8777836SJohn.Forte@Sun.COM info_stats->m_health_thres.value.ul = rdc_health_thres;
8787836SJohn.Forte@Sun.COM info_stats->m_bitmap_writes.value.ul = krdc->bitmap_write;
8797836SJohn.Forte@Sun.COM info_stats->m_bitmap_ref_delay.value.ul = rdc_bitmap_delay;
8807836SJohn.Forte@Sun.COM
8817836SJohn.Forte@Sun.COM /* clts counters not implemented yet */
8827836SJohn.Forte@Sun.COM info_stats->m_clnt_cots_calls.value.ul = rdc_clnt_count;
8837836SJohn.Forte@Sun.COM info_stats->m_clnt_clts_calls.value.ul = 0;
8847836SJohn.Forte@Sun.COM info_stats->m_svc_cots_calls.value.ul = rdc_svc_count;
8857836SJohn.Forte@Sun.COM info_stats->m_svc_clts_calls.value.ul = 0;
8867836SJohn.Forte@Sun.COM
8877836SJohn.Forte@Sun.COM return (0);
8887836SJohn.Forte@Sun.COM }
8897836SJohn.Forte@Sun.COM
8907836SJohn.Forte@Sun.COM /*
8917836SJohn.Forte@Sun.COM * copy tailsize-1 bytes of tail of s to s1.
8927836SJohn.Forte@Sun.COM */
8937836SJohn.Forte@Sun.COM void
rdc_str_tail_cpy(char * s1,char * s,size_t tailsize)8947836SJohn.Forte@Sun.COM rdc_str_tail_cpy(char *s1, char *s, size_t tailsize)
8957836SJohn.Forte@Sun.COM {
8967836SJohn.Forte@Sun.COM /* To avoid un-terminated string, max size is 16 - 1 */
8977836SJohn.Forte@Sun.COM ssize_t offset = strlen(s) - (tailsize - 1);
8987836SJohn.Forte@Sun.COM
8997836SJohn.Forte@Sun.COM offset = (offset > 0) ? offset : 0;
9007836SJohn.Forte@Sun.COM
9017836SJohn.Forte@Sun.COM /* ensure it's null terminated */
9027836SJohn.Forte@Sun.COM (void) strlcpy(s1, (const char *)(s + offset), tailsize);
9037836SJohn.Forte@Sun.COM }
9047836SJohn.Forte@Sun.COM
9057836SJohn.Forte@Sun.COM int
rdc_info_stats_update(kstat_t * ksp,int rw)9067836SJohn.Forte@Sun.COM rdc_info_stats_update(kstat_t *ksp, int rw)
9077836SJohn.Forte@Sun.COM {
9087836SJohn.Forte@Sun.COM rdc_info_stats_t *rdc_info_stats;
9097836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
9107836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
9117836SJohn.Forte@Sun.COM
9127836SJohn.Forte@Sun.COM rdc_info_stats = (rdc_info_stats_t *)(ksp->ks_data);
9137836SJohn.Forte@Sun.COM krdc = (rdc_k_info_t *)(ksp->ks_private);
9147836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
9157836SJohn.Forte@Sun.COM
9167836SJohn.Forte@Sun.COM /* no writes currently allowed */
9177836SJohn.Forte@Sun.COM
9187836SJohn.Forte@Sun.COM if (rw == KSTAT_WRITE) {
9197836SJohn.Forte@Sun.COM return (EACCES);
9207836SJohn.Forte@Sun.COM }
9217836SJohn.Forte@Sun.COM
9227836SJohn.Forte@Sun.COM /* default to READ */
9237836SJohn.Forte@Sun.COM rdc_info_stats->s_flags.value.ul = urdc->flags;
9247836SJohn.Forte@Sun.COM rdc_info_stats->s_syncflags.value.ul =
9257836SJohn.Forte@Sun.COM urdc->sync_flags;
9267836SJohn.Forte@Sun.COM rdc_info_stats->s_bmpflags.value.ul =
9277836SJohn.Forte@Sun.COM urdc->bmap_flags;
9287836SJohn.Forte@Sun.COM rdc_info_stats->s_syncpos.value.ul =
9297836SJohn.Forte@Sun.COM urdc->sync_pos;
9307836SJohn.Forte@Sun.COM rdc_info_stats->s_volsize.value.ul =
9317836SJohn.Forte@Sun.COM urdc->volume_size;
9327836SJohn.Forte@Sun.COM rdc_info_stats->s_bits_set.value.ul =
9337836SJohn.Forte@Sun.COM urdc->bits_set;
9347836SJohn.Forte@Sun.COM rdc_info_stats->s_autosync.value.ul =
9357836SJohn.Forte@Sun.COM urdc->autosync;
9367836SJohn.Forte@Sun.COM rdc_info_stats->s_maxqfbas.value.ul =
9377836SJohn.Forte@Sun.COM urdc->maxqfbas;
9387836SJohn.Forte@Sun.COM rdc_info_stats->s_maxqitems.value.ul =
9397836SJohn.Forte@Sun.COM urdc->maxqitems;
9407836SJohn.Forte@Sun.COM
9417836SJohn.Forte@Sun.COM kstat_named_setstr(&rdc_info_stats->s_primary_vol,
942*9093SRamana.Srikanth@Sun.COM urdc->primary.file);
9437836SJohn.Forte@Sun.COM
9447836SJohn.Forte@Sun.COM kstat_named_setstr(&rdc_info_stats->s_secondary_vol,
945*9093SRamana.Srikanth@Sun.COM urdc->secondary.file);
9467836SJohn.Forte@Sun.COM
9477836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
9487836SJohn.Forte@Sun.COM kstat_named_setstr(&rdc_info_stats->s_bitmap,
949*9093SRamana.Srikanth@Sun.COM urdc->primary.bitmap);
9507836SJohn.Forte@Sun.COM } else {
9517836SJohn.Forte@Sun.COM kstat_named_setstr(&rdc_info_stats->s_bitmap,
952*9093SRamana.Srikanth@Sun.COM urdc->secondary.bitmap);
9537836SJohn.Forte@Sun.COM }
9547836SJohn.Forte@Sun.COM
9557836SJohn.Forte@Sun.COM kstat_named_setstr(&rdc_info_stats->s_primary_intf,
956*9093SRamana.Srikanth@Sun.COM urdc->primary.intf);
9577836SJohn.Forte@Sun.COM
9587836SJohn.Forte@Sun.COM kstat_named_setstr(&rdc_info_stats->s_secondary_intf,
959*9093SRamana.Srikanth@Sun.COM urdc->secondary.intf);
9607836SJohn.Forte@Sun.COM
9617836SJohn.Forte@Sun.COM rdc_info_stats->s_type_flag.value.ul = krdc->type_flag;
9627836SJohn.Forte@Sun.COM rdc_info_stats->s_bitmap_size.value.ul = krdc->bitmap_size;
9637836SJohn.Forte@Sun.COM rdc_info_stats->s_disk_status.value.ul = krdc->disk_status;
9647836SJohn.Forte@Sun.COM
9657836SJohn.Forte@Sun.COM if (krdc->intf) {
9667836SJohn.Forte@Sun.COM rdc_info_stats->s_if_if_down.value.ul = krdc->intf->if_down;
9677836SJohn.Forte@Sun.COM rdc_info_stats->s_if_rpc_version.value.ul =
9687836SJohn.Forte@Sun.COM krdc->intf->rpc_version;
9697836SJohn.Forte@Sun.COM }
9707836SJohn.Forte@Sun.COM
9717836SJohn.Forte@Sun.COM /* the type can change without disable/re-enable so... */
9727836SJohn.Forte@Sun.COM bzero(rdc_info_stats->s_aqueue_type.value.c, KSTAT_DATA_CHAR_LEN);
9737836SJohn.Forte@Sun.COM if (RDC_IS_MEMQ(krdc->group)) {
9747836SJohn.Forte@Sun.COM (void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "memory");
9757836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_blk_hwm.value.ul =
976*9093SRamana.Srikanth@Sun.COM krdc->group->ra_queue.blocks_hwm;
9777836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_itm_hwm.value.ul =
978*9093SRamana.Srikanth@Sun.COM krdc->group->ra_queue.nitems_hwm;
9797836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_throttle.value.ul =
980*9093SRamana.Srikanth@Sun.COM krdc->group->ra_queue.throttle_delay;
9817836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_items.value.ul =
982*9093SRamana.Srikanth@Sun.COM krdc->group->ra_queue.nitems;
9837836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_blocks.value.ul =
984*9093SRamana.Srikanth@Sun.COM krdc->group->ra_queue.blocks;
9857836SJohn.Forte@Sun.COM
9867836SJohn.Forte@Sun.COM } else if (RDC_IS_DISKQ(krdc->group)) {
9877836SJohn.Forte@Sun.COM disk_queue *q = &krdc->group->diskq;
9887836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_blk_hwm.value.ul =
989*9093SRamana.Srikanth@Sun.COM krdc->group->diskq.blocks_hwm;
9907836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_itm_hwm.value.ul =
991*9093SRamana.Srikanth@Sun.COM krdc->group->diskq.nitems_hwm;
9927836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_throttle.value.ul =
993*9093SRamana.Srikanth@Sun.COM krdc->group->diskq.throttle_delay;
9947836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_items.value.ul = QNITEMS(q);
9957836SJohn.Forte@Sun.COM rdc_info_stats->s_aqueue_blocks.value.ul = QBLOCKS(q);
9967836SJohn.Forte@Sun.COM (void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "disk");
9977836SJohn.Forte@Sun.COM }
9987836SJohn.Forte@Sun.COM
9997836SJohn.Forte@Sun.COM return (0);
10007836SJohn.Forte@Sun.COM }
10017836SJohn.Forte@Sun.COM
10027836SJohn.Forte@Sun.COM void
rdc_kstat_create(int index)10037836SJohn.Forte@Sun.COM rdc_kstat_create(int index)
10047836SJohn.Forte@Sun.COM {
10057836SJohn.Forte@Sun.COM int j = index;
10067836SJohn.Forte@Sun.COM rdc_k_info_t *krdc = &rdc_k_info[index];
10077836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
10087836SJohn.Forte@Sun.COM size_t varsize;
10097836SJohn.Forte@Sun.COM
10107836SJohn.Forte@Sun.COM if (!krdc->set_kstats) {
10117836SJohn.Forte@Sun.COM krdc->set_kstats = kstat_create(RDC_KSTAT_MODULE, j,
10127836SJohn.Forte@Sun.COM RDC_KSTAT_INFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
10137836SJohn.Forte@Sun.COM sizeof (rdc_info_stats_t) / sizeof (kstat_named_t),
10147836SJohn.Forte@Sun.COM KSTAT_FLAG_VIRTUAL);
10157836SJohn.Forte@Sun.COM #ifdef DEBUG
10167836SJohn.Forte@Sun.COM if (!krdc->set_kstats)
1017*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!krdc:u_kstat null");
10187836SJohn.Forte@Sun.COM #endif
10197836SJohn.Forte@Sun.COM
10207836SJohn.Forte@Sun.COM if (krdc->set_kstats) {
10217836SJohn.Forte@Sun.COM /* calculate exact size of KSTAT_DATA_STRINGs */
10227836SJohn.Forte@Sun.COM varsize = strlen(urdc->primary.file) + 1
1023*9093SRamana.Srikanth@Sun.COM + strlen(urdc->secondary.file) + 1
1024*9093SRamana.Srikanth@Sun.COM + strlen(urdc->primary.intf) + 1
1025*9093SRamana.Srikanth@Sun.COM + strlen(urdc->secondary.intf) + 1;
10267836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
10277836SJohn.Forte@Sun.COM varsize += strlen(urdc->primary.bitmap) + 1;
10287836SJohn.Forte@Sun.COM } else {
10297836SJohn.Forte@Sun.COM varsize += strlen(urdc->secondary.bitmap) + 1;
10307836SJohn.Forte@Sun.COM }
10317836SJohn.Forte@Sun.COM
10327836SJohn.Forte@Sun.COM krdc->set_kstats->ks_data_size += varsize;
10337836SJohn.Forte@Sun.COM krdc->set_kstats->ks_data = &rdc_info_stats;
10347836SJohn.Forte@Sun.COM krdc->set_kstats->ks_update = rdc_info_stats_update;
10357836SJohn.Forte@Sun.COM krdc->set_kstats->ks_private = &rdc_k_info[j];
10367836SJohn.Forte@Sun.COM kstat_install(krdc->set_kstats);
10377836SJohn.Forte@Sun.COM } else
1038*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!SNDR: k-kstats failed");
10397836SJohn.Forte@Sun.COM }
10407836SJohn.Forte@Sun.COM
10417836SJohn.Forte@Sun.COM krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, j, NULL,
1042*9093SRamana.Srikanth@Sun.COM "disk", KSTAT_TYPE_IO, 1, 0);
10437836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
10447836SJohn.Forte@Sun.COM krdc->io_kstats->ks_lock = &krdc->kstat_mutex;
10457836SJohn.Forte@Sun.COM kstat_install(krdc->io_kstats);
10467836SJohn.Forte@Sun.COM }
10477836SJohn.Forte@Sun.COM krdc->bmp_kstats = kstat_create("sndrbmp", j, NULL,
1048*9093SRamana.Srikanth@Sun.COM "disk", KSTAT_TYPE_IO, 1, 0);
10497836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
10507836SJohn.Forte@Sun.COM krdc->bmp_kstats->ks_lock = &krdc->bmp_kstat_mutex;
10517836SJohn.Forte@Sun.COM kstat_install(krdc->bmp_kstats);
10527836SJohn.Forte@Sun.COM }
10537836SJohn.Forte@Sun.COM }
10547836SJohn.Forte@Sun.COM
10557836SJohn.Forte@Sun.COM void
rdc_kstat_delete(int index)10567836SJohn.Forte@Sun.COM rdc_kstat_delete(int index)
10577836SJohn.Forte@Sun.COM {
10587836SJohn.Forte@Sun.COM rdc_k_info_t *krdc = &rdc_k_info[index];
10597836SJohn.Forte@Sun.COM
10607836SJohn.Forte@Sun.COM if (krdc->set_kstats) {
10617836SJohn.Forte@Sun.COM kstat_delete(krdc->set_kstats);
10627836SJohn.Forte@Sun.COM krdc->set_kstats = NULL;
10637836SJohn.Forte@Sun.COM }
10647836SJohn.Forte@Sun.COM
10657836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
10667836SJohn.Forte@Sun.COM kstat_delete(krdc->io_kstats);
10677836SJohn.Forte@Sun.COM krdc->io_kstats = NULL;
10687836SJohn.Forte@Sun.COM }
10697836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
10707836SJohn.Forte@Sun.COM kstat_delete(krdc->bmp_kstats);
10717836SJohn.Forte@Sun.COM krdc->bmp_kstats = NULL;
10727836SJohn.Forte@Sun.COM }
10737836SJohn.Forte@Sun.COM }
10747836SJohn.Forte@Sun.COM
10757836SJohn.Forte@Sun.COM #ifdef DEBUG
10767836SJohn.Forte@Sun.COM /*
10777836SJohn.Forte@Sun.COM * Reset the io_kstat structure of the krdc specified
10787836SJohn.Forte@Sun.COM * by the arg index.
10797836SJohn.Forte@Sun.COM */
10807836SJohn.Forte@Sun.COM static int
rdc_clrkstat(void * arg)10817836SJohn.Forte@Sun.COM rdc_clrkstat(void *arg)
10827836SJohn.Forte@Sun.COM {
10837836SJohn.Forte@Sun.COM int index;
10847836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
10857836SJohn.Forte@Sun.COM
10867836SJohn.Forte@Sun.COM index = (int)(unsigned long)arg;
10877836SJohn.Forte@Sun.COM if ((index < 0) || (index >= rdc_max_sets)) {
10887836SJohn.Forte@Sun.COM return (EINVAL);
10897836SJohn.Forte@Sun.COM }
10907836SJohn.Forte@Sun.COM krdc = &rdc_k_info[index];
10917836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
10927836SJohn.Forte@Sun.COM kstat_delete(krdc->io_kstats);
10937836SJohn.Forte@Sun.COM krdc->io_kstats = NULL;
10947836SJohn.Forte@Sun.COM } else {
10957836SJohn.Forte@Sun.COM return (EINVAL);
10967836SJohn.Forte@Sun.COM }
10977836SJohn.Forte@Sun.COM krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, index, NULL,
1098*9093SRamana.Srikanth@Sun.COM "disk", KSTAT_TYPE_IO, 1, 0);
10997836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
11007836SJohn.Forte@Sun.COM krdc->io_kstats->ks_lock = &krdc->kstat_mutex;
11017836SJohn.Forte@Sun.COM kstat_install(krdc->io_kstats);
11027836SJohn.Forte@Sun.COM } else {
11037836SJohn.Forte@Sun.COM return (EINVAL);
11047836SJohn.Forte@Sun.COM }
11057836SJohn.Forte@Sun.COM /*
11067836SJohn.Forte@Sun.COM * clear the high water marks and throttle.
11077836SJohn.Forte@Sun.COM */
11087836SJohn.Forte@Sun.COM if (krdc->group) {
11097836SJohn.Forte@Sun.COM krdc->group->ra_queue.nitems_hwm = 0;
11107836SJohn.Forte@Sun.COM krdc->group->ra_queue.blocks_hwm = 0;
11117836SJohn.Forte@Sun.COM krdc->group->ra_queue.throttle_delay = 0;
11127836SJohn.Forte@Sun.COM }
11137836SJohn.Forte@Sun.COM return (0);
11147836SJohn.Forte@Sun.COM }
11157836SJohn.Forte@Sun.COM #endif
1116