fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdcopen(dev_t *devp, int flag, int otyp, cred_t *crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdcclose(dev_t dev, int flag, int otyp, cred_t *crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdcattach(dev_info_t *dip, ddi_attach_cmd_t cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdcdetach(dev_info_t *dip, ddi_detach_cmd_t cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdc_clrkstat(void *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * kstat interface
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {RDC_IKSTAT_ASYNC_THROTTLE_DELAY, KSTAT_DATA_ULONG},
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&rdc_sync_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&rdc_sync_event.mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&rdc_sync_event.cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&rdc_sync_event.done_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*CONSTCOND*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(sndr_version, _VERSION_, sizeof (sndr_version));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_max_sets must be set before calling _rdc_load().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_max_sets = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "rdc_max_sets", 64);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc: _rdc_init_dev failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_rdc_load() != 0) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc: _rdc_load failed");
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc: _rdc_configure failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_create_minor_node(dip, "rdc", S_IFCHR, instance, DDI_PSEUDO, 0)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc: could not create node.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_bitmap_mode = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_bitmap_mode", 0);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!SNDR bitmap mode override");
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!SNDR: bitmaps will only be written on shutdown\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default: /* unknown */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!SNDR: unknown bitmap mode %d - autodetecting mode",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_auto_sync = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rdc_auto_sync", 0);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!value rdc_heath_thres from rdc.conf ignored "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "as it is smaller than the min value of %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte RDC_KSTAT_MINFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (sndr_m_stats_t) / sizeof (kstat_named_t),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: module kstats failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!rdc: cannot detach, rdcd %d still in use", rdcd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We only have a single instance */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdcopen(dev_t *devp, int flag, int otyp, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdcclose(dev_t dev, int flag, int otyp, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc%d: %s", instance, str);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteconvert_ioctl_args(int cmd, intptr_t arg, int mode, _rdc_ioctl_t *args)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &args32, sizeof (_rdc_ioctl32_t), mode))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte args->arg0 = (uint32_t)args32.arg0; /* _rdc_config_t * */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte args->arg1 = (uint32_t)args32.arg1; /* pointer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte args->arg0 = (uint32_t)args32.arg0; /* pointer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte args->arg0 = (uint32_t)args32.arg0; /* _rdc_svc_args * */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte args->arg0 = (uint32_t)args32.arg0; /* _rdc_version_t * */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte args->arg0 = (uint32_t)args32.arg0; /* svcpool_args * */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Build a 32bit rdc_set structure and copyout to the user level.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_status_copy32(const void *arg, void *usetp, size_t size, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* primary address structure, avoiding netbuf */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&urdc->primary.intf[0], &set32.primary.intf[0], tailsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* secondary address structure, avoiding netbuf */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&urdc->secondary.intf[0], &set32.secondary.intf[0], tailsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the rest, avoiding netconfig
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * note: the tail must be the same size in both structures
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tailsize = sizeof (struct rdc_set) - offsetof(struct rdc_set, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ASSERT is calling for debug reason, and tailsize32 is only declared
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for ASSERT, put them under debug to avoid lint warning.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copyout to user level */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Status ioctl.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*copyout)(const void *, void *, size_t, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *usetp; /* pointer to user rdc_set structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int32_t *maxsetsp; /* address of status->maxsets; */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0, j = 0; i < max; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sneak out qstate in urdc->flags
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this is harmless because it's value is not used
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in urdc->flags. the real qstate is kept in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * group->diskq->disk_hdr.h.state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copyout rdc_max_sets value */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(&rdc_max_sets, maxsetsp, sizeof (*maxsetsp), mode) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copyout number of sets manipulated */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*CONSTCOND*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(offsetof(struct rdc_status32, nset) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*CONSTCOND*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ddi_copyout(&j, (void *)args->arg0, sizeof (int), mode));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &bmop32, sizeof (bmop32),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &bmop, sizeof (bmop),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = rdc_bitmapset(bmop.op, bmop.sechost, bmop.secfile,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = convert_ioctl_args(cmd, arg, mode, &args)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &p, sizeof (p), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Only used by sndrd which does not use unistat */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)args.arg0, STRUCT_BUF(parms),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _rdc_config((void *)args.arg0, mode, kstatus, rvp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(STRUCT_BUF(parms), (void *)args.arg0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* char *host from user */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _rdc_link_down((void *)args.arg0, mode, kstatus, rvp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _rdc_sync_event_wait((void *)args.arg0, (void *)args.arg1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* no writes currently allowed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* default to READ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info_stats->m_rpc_timeout.value.ul = rdc_rpc_tmout;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info_stats->m_health_thres.value.ul = rdc_health_thres;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info_stats->m_bitmap_writes.value.ul = krdc->bitmap_write;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info_stats->m_bitmap_ref_delay.value.ul = rdc_bitmap_delay;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* clts counters not implemented yet */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info_stats->m_clnt_cots_calls.value.ul = rdc_clnt_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info_stats->m_svc_cots_calls.value.ul = rdc_svc_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copy tailsize-1 bytes of tail of s to s1.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_str_tail_cpy(char *s1, char *s, size_t tailsize)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* To avoid un-terminated string, max size is 16 - 1 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ensure it's null terminated */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strlcpy(s1, (const char *)(s + offset), tailsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_info_stats = (rdc_info_stats_t *)(ksp->ks_data);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* no writes currently allowed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* default to READ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_setstr(&rdc_info_stats->s_primary_vol,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_setstr(&rdc_info_stats->s_secondary_vol,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_setstr(&rdc_info_stats->s_primary_intf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_setstr(&rdc_info_stats->s_secondary_intf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_info_stats->s_type_flag.value.ul = krdc->type_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_info_stats->s_bitmap_size.value.ul = krdc->bitmap_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_info_stats->s_disk_status.value.ul = krdc->disk_status;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_info_stats->s_if_if_down.value.ul = krdc->intf->if_down;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* the type can change without disable/re-enable so... */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(rdc_info_stats->s_aqueue_type.value.c, KSTAT_DATA_CHAR_LEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "memory");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_info_stats->s_aqueue_items.value.ul = QNITEMS(q);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_info_stats->s_aqueue_blocks.value.ul = QBLOCKS(q);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "disk");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->set_kstats = kstat_create(RDC_KSTAT_MODULE, j,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte RDC_KSTAT_INFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rdc_info_stats_t) / sizeof (kstat_named_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* calculate exact size of KSTAT_DATA_STRINGs */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->set_kstats->ks_update = rdc_info_stats_update;
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: k-kstats failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, j, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->bmp_kstats = kstat_create("sndrbmp", j, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->bmp_kstats->ks_lock = &krdc->bmp_kstat_mutex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reset the io_kstat structure of the krdc specified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by the arg index.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, index, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * clear the high water marks and throttle.