fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
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 *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
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 *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
b2514ea1e4c90e705852a2668ed730087a89f38cDan McDonald *
b2514ea1e4c90e705852a2668ed730087a89f38cDan McDonald * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Storage Volume Character and Block Driver (SV)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This driver implements a simplistic /dev/{r}dsk/ interface to a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * specified disk volume that is otherwise managed by the Prism
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * software. The SV driver layers itself onto the underlying disk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device driver by changing function pointers in the cb_ops
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CONFIGURATION:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1. Configure the driver using the svadm utility.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 2. Access the device as before through /dev/rdsk/c?t?d?s?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LIMITATIONS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This driver should NOT be used to share a device between another
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DataServices user interface module (e.g., STE) and a user accessing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the device through the block device in O_WRITE mode. This is because
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * writes through the block device are asynchronous (due to the page
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cache) and so consistency between the block device user and the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * STE user cannot be guaranteed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Data is copied between system struct buf(9s) and nsc_vec_t. This is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wasteful and slow.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/debug.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/varargs.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/file.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/open.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cred.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/buf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/uio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef DS_DDICT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/pathname.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/aio_req.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/dkio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/vtoc.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/modctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
5c5f137104b2d56181283389fa902220f2023809Richard Lowe#include <sys/sysmacros.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sunddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sunldi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsctl/nsvers.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsc_thread.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/unistat/spcs_s.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/unistat/spcs_s_k.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/unistat/spcs_errors.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DS_DDICT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "../contract.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "../nsctl.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sdt.h> /* dtrace is S10 or later */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sv.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sv_impl.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sv_efi.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define MAX_EINTR_COUNT 1000
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sv_mod_status
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define SV_PREVENT_UNLOAD 1
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define SV_ALLOW_UNLOAD 2
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const int sv_major_rev = ISS_VERSION_MAJ; /* Major number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const int sv_minor_rev = ISS_VERSION_MIN; /* Minor number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const int sv_micro_rev = ISS_VERSION_MIC; /* Micro number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const int sv_baseline_rev = ISS_VERSION_NUM; /* Baseline number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DKIOCPARTITION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CRC32 polynomial table needed for computing the checksums
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in an EFI vtoc.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const uint32_t sv_crc32_table[256] = { CRC32_TABLE };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic clock_t sv_config_time; /* Time of successful {en,dis}able */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_debug; /* Set non-zero for debug to syslog */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_mod_status; /* Set to prevent modunload */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic dev_info_t *sv_dip; /* Single DIP for driver */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kmutex_t sv_mutex; /* Protect global lists, etc. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_mem_t *sv_mem; /* nsctl memory allocator token */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Per device and per major state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef _SunOS_5_6
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define UNSAFE_ENTER()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define UNSAFE_EXIT()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define UNSAFE_ENTER() mutex_enter(&unsafe_driver)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define UNSAFE_EXIT() mutex_exit(&unsafe_driver)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* hash table of major dev structures */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic sv_maj_t *sv_majors[SV_MAJOR_HASH_CNT] = {0};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic sv_dev_t *sv_devs; /* array of per device structures */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_max_devices; /* SV version of nsc_max_devices() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_ndevices; /* number of SV enabled devices */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Threading.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint sv_threads_max = 1024; /* maximum # to dynamically alloc */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint sv_threads = 32; /* # to pre-allocate (see sv.conf) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint sv_threads_extra = 0; /* addl # we would have alloc'ed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nstset_t *sv_tset; /* the threadset pointer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_threads_hysteresis = 4; /* hysteresis for threadset resizing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_threads_dev = 2; /* # of threads to alloc per device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_threads_inc = 8; /* increment for changing the set */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_threads_needed; /* number of threads needed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_no_threads; /* number of nsc_create errors */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_max_nlive; /* max number of threads running */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsctl fd callbacks.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int svattach_fd(blind_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int svdetach_fd(blind_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_def_t sv_fd_def[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { "Attach", (uintptr_t)svattach_fd, },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { "Detach", (uintptr_t)svdetach_fd, },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { 0, 0, }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cb_ops functions.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int svopen(dev_t *, int, int, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int svclose(dev_t, int, int, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int svioctl(dev_t, int, intptr_t, int, cred_t *, int *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int svprint(dev_t, char *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * These next functions are layered into the underlying driver's devops.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_lyr_open(dev_t *, int, int, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_lyr_close(dev_t, int, int, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_lyr_strategy(struct buf *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_lyr_read(dev_t, struct uio *, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_lyr_write(dev_t, struct uio *, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_lyr_aread(dev_t, struct aio_req *, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_lyr_awrite(dev_t, struct aio_req *, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_lyr_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct cb_ops sv_cb_ops = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svopen, /* open */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svclose, /* close */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nulldev, /* strategy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svprint,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* dump */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* read */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* write */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svioctl,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* devmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* mmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* segmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nochpoll, /* poll */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_prop_op,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* NOT a stream */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte D_NEW | D_MP | D_64BIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CB_REV,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* aread */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* awrite */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev_ops functions.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_attach(dev_info_t *, ddi_attach_cmd_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sv_detach(dev_info_t *, ddi_detach_cmd_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct dev_ops sv_ops = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DEVO_REV,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_getinfo,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nulldev, /* identify */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nulldev, /* probe */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_attach,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_detach,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* reset */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &sv_cb_ops,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (struct bus_ops *)0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Module linkage.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern struct mod_ops mod_driverops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modldrv modldrv = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &mod_driverops,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nws:Storage Volume:" ISS_VERSION_STR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &sv_ops
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modlinkage modlinkage = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODREV_1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &modldrv,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_init(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&sv_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((error = mod_install(&modlinkage)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!sv (revision %d.%d.%d.%d, %s, %s)\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_major_rev, sv_minor_rev, sv_micro_rev, sv_baseline_rev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ISS_VERSION_STR, BUILD_DATE_STR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_micro_rev) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!sv (revision %d.%d.%d, %s, %s)\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_major_rev, sv_minor_rev, sv_micro_rev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ISS_VERSION_STR, BUILD_DATE_STR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!sv (revision %d.%d, %s, %s)\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_major_rev, sv_minor_rev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ISS_VERSION_STR, BUILD_DATE_STR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_fini(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((error = mod_remove(&modlinkage)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_info(struct modinfo *modinfop)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (mod_info(&modlinkage, modinfop));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Locking & State.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sv_mutex protects config information - sv_maj_t and sv_dev_t lists;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * threadset creation and sizing; sv_ndevices.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we need to hold both sv_mutex and sv_lock, then the sv_mutex
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * must be acquired first.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sv_lock protects the sv_dev_t structure for an individual device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sv_olock protects the otyp/open members of the sv_dev_t. If we need
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to hold both sv_lock and sv_olock, then the sv_lock must be acquired
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * first.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_reserve/nsc_release are used in NSC_MULTI mode to allow multiple
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * I/O operations to a device simultaneously, as above.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All nsc_open/nsc_close/nsc_reserve/nsc_release operations that occur
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with sv_lock write-locked must be done with (sv_state == SV_PENDING)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and (sv_pending == curthread) so that any recursion through
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sv_lyr_open/sv_lyr_close can be detected.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_init_devs(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&sv_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_max_devices > 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_max_devices = nsc_max_devices();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_max_devices <= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* nsctl is not attached (nskernd not running) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 0)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!sv: nsc_max_devices = 0\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EAGAIN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_devs = nsc_kmem_zalloc((sv_max_devices * sizeof (*sv_devs)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP, sv_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_devs == NULL) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!sv: could not allocate sv_devs array");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < sv_max_devices; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&sv_devs[i].sv_olock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_init(&sv_devs[i].sv_lock, NULL, RW_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 0)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!sv: sv_init_devs successful\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_ATTACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dip = dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_create_minor_node(dip, "sv", S_IFCHR,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana 0, DDI_PSEUDO, 0) != DDI_SUCCESS)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_mem = nsc_register_mem("SV", NSC_MEM_LOCAL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_mem == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_init_devs();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0 && rc != EAGAIN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_report_dev(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_threads = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "sv_threads", sv_threads);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 0)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!sv: sv_threads=%d\n", sv_threads);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_threads > sv_threads_max)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_threads_max = sv_threads;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefailed:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE(sv_attach_failed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sv_detach(dip, DDI_DETACH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_DETACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check that everything is disabled.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_mod_status == SV_PREVENT_UNLOAD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE(sv_detach_err_prevent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; sv_devs && i < sv_max_devices; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = &sv_devs[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_state != SV_DISABLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE(sv_detach_err_busy);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; sv_devs && i < sv_max_devices; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&sv_devs[i].sv_olock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&sv_devs[i].sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_devs) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(sv_devs,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (sv_max_devices * sizeof (*sv_devs)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_devs = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_max_devices = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_mem) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_unregister_mem(sv_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_mem = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove all minor nodes.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_remove_minor_node(dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dip = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic sv_maj_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_getmajor(const dev_t dev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t **insert, *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte major_t umaj = getmajor(dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See if the hash table entry, or one of the hash chains
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is already allocated for this major number
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((maj = sv_majors[SV_MAJOR_HASH(umaj)]) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_major == umaj)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (maj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while ((maj = maj->sm_next) != 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the sv_mutex is held, there is design flaw, as the only non-mutex
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * held callers can be sv_enable() or sv_dev_to_sv()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return an error, instead of panicing the system
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (MUTEX_HELD(&sv_mutex)) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!sv: could not allocate sv_maj_t");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine where to allocate a new element in the hash table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte insert = &(sv_majors[SV_MAJOR_HASH(umaj)]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (maj = *insert; maj; maj = maj->sm_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Did another thread beat us to it? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_major == umaj)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (maj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Find a NULL insert point? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_next == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte insert = &maj->sm_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Located the new insert point
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *insert = nsc_kmem_zalloc(sizeof (*maj), KM_NOSLEEP, sv_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((maj = *insert) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_major = umaj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!sv: could not allocate sv_maj_t");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (maj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (infocmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_INFO_DEVT2DEVINFO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *result = sv_dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = DDI_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_INFO_DEVT2INSTANCE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We only have a single instance.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *result = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = DDI_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Hashing of devices onto major device structures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Individual device structures are hashed onto one of the sm_hash[]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * buckets in the relevant major device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Hash insertion and deletion -must- be done with sv_mutex held. Hash
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * searching does not require the mutex because of the sm_seq member.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sm_seq is incremented on each insertion (-after- hash chain pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * manipulation) and each deletion (-before- hash chain pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * manipulation). When searching the hash chain, the seq number is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * checked before accessing each device structure, if the seq number has
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * changed, then we restart the search from the top of the hash chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we restart more than SV_HASH_RETRY times, we take sv_mutex and search
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the hash chain (we are guaranteed that this search cannot be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * interrupted).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define SV_HASH_RETRY 16
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic sv_dev_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_dev_to_sv(const dev_t dev, sv_maj_t **majpp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte minor_t umin = getminor(dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t **hb, *next, *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int seq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int try;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get major hash table */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj = sv_getmajor(dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (majpp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *majpp = maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_inuse == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_to_sv_end,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t, dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hb = &(maj->sm_hash[SV_MINOR_HASH(umin)]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte try = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteretry:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (try > SV_HASH_RETRY)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte seq = maj->sm_seq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (svp = *hb; svp; svp = next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = svp->sv_hash;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_membar_stld(); /* preserve register load order */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_seq != seq) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dev_to_sv_retry, dev_t, dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte try++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto retry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_dev == dev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (try > SV_HASH_RETRY)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Must be called with sv_mutex held.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_get_state(const dev_t udev, sv_dev_t **svpp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t **hb, **insert, *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte minor_t umin;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get major hash table */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((maj = sv_getmajor(udev)) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Determine which minor hash table */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte umin = getminor(udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hb = &(maj->sm_hash[SV_MINOR_HASH(umin)]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* look for clash */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte insert = hb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (svp = *hb; svp; svp = svp->sv_hash) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_dev == udev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_hash == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte insert = &svp->sv_hash;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_get_state_enabled,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (SV_EENABLED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* look for spare sv_devs slot */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < sv_max_devices; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = &sv_devs[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_state == SV_DISABLE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i >= sv_max_devices) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_get_state_noslots,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (SV_ENOSLOTS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_state = SV_PENDING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_pending = curthread;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *insert = svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_hash = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_seq++; /* must be after the store to the hash chain */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *svpp = svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We do not know the size of the underlying device at
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this stage, so initialise "nblocks" property to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zero, and update it whenever we succeed in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_reserve'ing the underlying nsc_fd_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_nblocks = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove a device structure from it's hash chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Must be called with sv_mutex held.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_rm_hash(sv_dev_t *svp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t **svpp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get major hash table */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((maj = sv_getmajor(svp->sv_dev)) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* remove svp from hash chain */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svpp = &(maj->sm_hash[SV_MINOR_HASH(getminor(svp->sv_dev))]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (*svpp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*svpp == svp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * increment of sm_seq must be before the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * removal from the hash chain
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_seq++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *svpp = svp->sv_hash;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svpp = &(*svpp)->sv_hash;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_hash = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free (disable) a device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Must be called with sv_lock(RW_WRITER) and sv_mutex held, and will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * perform the exits during its processing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_free(sv_dev_t *svp, const int error)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct cb_ops *cb_ops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get major hash table */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((maj = sv_getmajor(svp->sv_dev)) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_state = SV_PENDING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_pending = curthread;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close the fd's before removing from the hash or swapping
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * back the cb_ops pointers so that the cache flushes before new
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * io can come in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_fd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nsc_close(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_fd = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_rm_hash(svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (error != SV_ESDOPEN &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error != SV_ELYROPEN && --maj->sm_inuse == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_dev_ops)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops = maj->sm_dev_ops->devo_cb_ops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cb_ops && maj->sm_strategy != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_strategy = maj->sm_strategy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_close = maj->sm_close;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_ioctl = maj->sm_ioctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_write = maj->sm_write;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_open = maj->sm_open;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_read = maj->sm_read;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_flag = maj->sm_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_awrite)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_awrite = maj->sm_awrite;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_aread)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_aread = maj->sm_aread;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * corbin XXX
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Leave backing device ops in maj->sm_*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to handle any requests that might come
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in during the disable. This could be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a problem however if the backing device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * driver is changed while we process these
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * requests.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * maj->sm_strategy = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * maj->sm_awrite = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * maj->sm_write = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * maj->sm_ioctl = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * maj->sm_close = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * maj->sm_aread = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * maj->sm_read = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * maj->sm_open = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * maj->sm_flag = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_dev_ops) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_dev_ops = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_lh) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cred_t *crp = ddi_get_cred();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close the protective layered driver open using the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sun Private layered driver i/f.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ldi_close(svp->sv_lh, FREAD|FWRITE, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_lh = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_timestamp = nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_state = SV_DISABLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_pending = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reserve the device, taking into account the possibility that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the reserve might have to be retried.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_reserve(nsc_fd_t *fd, int flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int eintr_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte eintr_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_reserve(fd, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == EINTR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ++eintr_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while ((rc == EINTR) && (eintr_count < MAX_EINTR_COUNT));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_enable(const caddr_t path, const int flag,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const dev_t udev, spcs_s_info_t kstatus)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct dev_ops *dev_ops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct cb_ops *cb_ops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cred_t *crp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ldi_ident_t li;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (udev == (dev_t)-1 || udev == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_enable_err_baddev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (SV_EBADDEV);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((flag & ~(NSC_CACHE|NSC_DEVICE)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(sv_enable_err_amode, dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (SV_EAMODE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get major hash table */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((maj = sv_getmajor(udev)) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (SV_EBADDEV);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_get_state(udev, &svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_enable_err_state, dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&svp->sv_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get real fd used for io
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_dev = udev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_flag = flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * OR in NSC_DEVICE to ensure that nskern grabs the real strategy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * function pointer before sv swaps them out.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_fd = nsc_open(path, (svp->sv_flag | NSC_DEVICE),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sv_fd_def, (blind_t)udev, &rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_fd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (kstatus)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, rc);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_enable_err_fd, dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sv_free(svp, SV_ESDOPEN));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform a layered driver open using the Sun Private layered
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * driver i/f to ensure that the cb_ops structure for the driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is not detached out from under us whilst sv is enabled.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte crp = ddi_get_cred();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_lh = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = ldi_ident_from_dev(svp->sv_dev, &li)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ldi_open_by_dev(&svp->sv_dev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte OTYP_BLK, FREAD|FWRITE, crp, &svp->sv_lh, li);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (kstatus)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, rc);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_enable_err_lyr_open, dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sv_free(svp, SV_ELYROPEN));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Do layering if required - must happen after nsc_open().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_inuse++ == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_dev_ops = nsc_get_devops(getmajor(udev));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->sm_dev_ops == NULL ||
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana maj->sm_dev_ops->devo_cb_ops == NULL) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_enable_err_load, dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sv_free(svp, SV_ELOAD));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_ops = maj->sm_dev_ops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops = dev_ops->devo_cb_ops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cb_ops->cb_strategy == NULL ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_strategy == nodev ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_strategy == nulldev) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_enable_err_nostrategy, dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sv_free(svp, SV_ELOAD));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cb_ops->cb_strategy == sv_lyr_strategy) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_enable_err_svstrategy, dev_t, udev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sv_free(svp, SV_ESTRATEGY));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_strategy = cb_ops->cb_strategy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_close = cb_ops->cb_close;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_ioctl = cb_ops->cb_ioctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_write = cb_ops->cb_write;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_open = cb_ops->cb_open;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_read = cb_ops->cb_read;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_flag = cb_ops->cb_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_flag = cb_ops->cb_flag | D_MP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_strategy = sv_lyr_strategy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_close = sv_lyr_close;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_ioctl = sv_lyr_ioctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_write = sv_lyr_write;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_open = sv_lyr_open;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_read = sv_lyr_read;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check that the driver has async I/O entry points
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * before changing them.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dev_ops->devo_rev < 3 || cb_ops->cb_rev < 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_awrite = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_aread = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_awrite = cb_ops->cb_awrite;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->sm_aread = cb_ops->cb_aread;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_awrite = sv_lyr_awrite;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_ops->cb_aread = sv_lyr_aread;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bug 4645743
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prevent sv from ever unloading after it has interposed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on a major device because there is a race between
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sv removing its layered entry points from the target
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev_ops, a client coming in and accessing the driver,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and the kernel modunloading the sv text.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * To allow unload, do svboot -u, which only happens in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pkgrm time.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&sv_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_mod_status = SV_PREVENT_UNLOAD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_timestamp = nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_state = SV_ENABLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_pending = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_ndevices++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nblocks = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_reserve(svp->sv_fd, NSC_READ|NSC_MULTI|NSC_PCATCH) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nblocks = svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "!sv: rdev 0x%lx, nblocks %" NSC_SZFMT "\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_dev, nblocks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_prepare_unload()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_mod_status == SV_PREVENT_UNLOAD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((sv_ndevices != 0) || (sv_tset != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EBUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_mod_status = SV_ALLOW_UNLOAD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(SV_WAIT_UNLOAD * drv_usectohz(1000000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesvattach_fd(blind_t arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t dev = (dev_t)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp = sv_dev_to_sv(dev, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 0)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!svattach_fd(%p, %p)\n", arg, (void *)svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!svattach_fd: no state (arg %p)", arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = nsc_partsize(svp->sv_fd, &svp->sv_nblocks)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!svattach_fd: nsc_partsize() failed, rc %d", rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_nblocks = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = nsc_maxfbas(svp->sv_fd, 0, &svp->sv_maxfbas)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!svattach_fd: nsc_maxfbas() failed, rc %d", rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_maxfbas = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!svattach_fd(%p): size %" NSC_SZFMT ", "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "maxfbas %" NSC_SZFMT "\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte arg, svp->sv_nblocks, svp->sv_maxfbas);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesvdetach_fd(blind_t arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t dev = (dev_t)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp = sv_dev_to_sv(dev, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 0)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!svdetach_fd(%p, %p)\n", arg, (void *)svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* svp can be NULL during disable of an sv */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_maxfbas = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_nblocks = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Side effect: if called with (guard != 0), then expects both sv_mutex
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and sv_lock(RW_WRITER) to be held, and will release them before returning.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_disable(dev_t dev, spcs_s_info_t kstatus)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp = sv_dev_to_sv(dev, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(sv_disable_err_nodev, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (SV_ENODEV);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&svp->sv_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_fd == NULL || svp->sv_state != SV_ENABLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(sv_disable_err_disabled, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (SV_EDISABLED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_ndevices--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sv_free(svp, 0));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_lyr_open(dev_t *devp, int flag, int otyp, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_buf_t *tmph;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*fn)();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t odev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = sv_dev_to_sv(*devp, &maj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_state == SV_PENDING &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_pending == curthread) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is a recursive open from a call to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ddi_lyr_open_by_devt and so we just want
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to pass it straight through to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * underlying driver.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE2(sv_lyr_open_recursive,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *, svp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t, *devp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&svp->sv_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte odev = *devp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj && (fn = maj->sm_open) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(maj->sm_flag & D_MP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_ENTER();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = (*fn)(devp, flag, otyp, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_EXIT();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = (*fn)(devp, flag, otyp, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Re-acquire svp if the driver changed *devp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*devp != odev) {
b2514ea1e4c90e705852a2668ed730087a89f38cDan McDonald if (svp != NULL)
b2514ea1e4c90e705852a2668ed730087a89f38cDan McDonald rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = sv_dev_to_sv(*devp, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&svp->sv_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ENODEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp && ret != 0 && svp->sv_state == SV_ENABLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Underlying DDI open failed, but we have this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device SV enabled. If we can read some data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from the device, fake a successful open (this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * probably means that this device is RDC'd and we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are getting the data from the secondary node).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The reserve must be done with NSC_TRY|NSC_NOWAIT to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ensure that it does not deadlock if this open is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * coming from nskernd:get_bsize().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_reserve(svp->sv_fd,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana NSC_TRY | NSC_NOWAIT | NSC_MULTI | NSC_PCATCH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmph = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_alloc_buf(svp->sv_fd, 0, 1, NSC_READ, &tmph);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc <= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* success */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmph) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nsc_free_buf(tmph);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmph = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Count the number of layered opens that we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fake since we have to fake a matching number
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of closes (OTYP_LYR open/close calls must be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * paired).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0 && otyp == OTYP_LYR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&svp->sv_olock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_openlcnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&svp->sv_olock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_lyr_close(dev_t dev, int flag, int otyp, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*fn)();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = sv_dev_to_sv(dev, &maj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_state == SV_PENDING &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_pending == curthread) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is a recursive open from a call to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ddi_lyr_close and so we just want
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to pass it straight through to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * underlying driver.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE2(sv_lyr_close_recursive, sv_dev_t *, svp,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana dev_t, dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&svp->sv_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (otyp == OTYP_LYR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&svp->sv_olock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_openlcnt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Consume sufficient layered closes to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * account for the opens that we faked
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * whilst the device was failed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_openlcnt--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&svp->sv_olock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_lyr_close_end, dev_t, dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&svp->sv_olock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj && (fn = maj->sm_close) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(maj->sm_flag & D_MP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_ENTER();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = (*fn)(dev, flag, otyp, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_EXIT();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = (*fn)(dev, flag, otyp, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ENODEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Convert the specified dev_t into a locked and enabled sv_dev_t, or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic sv_dev_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_find_enabled(const dev_t dev, sv_maj_t **majpp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((svp = sv_dev_to_sv(dev, majpp)) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&svp->sv_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_state == SV_ENABLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* locked and enabled */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * State was changed while waiting on the lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wait for a stable state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_find_enabled_retry, dev_t, dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_lyr_uio(dev_t dev, uio_t *uiop, cred_t *crp, int rw)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*fn)();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = sv_find_enabled(dev, &maj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rw == NSC_READ)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fn = maj->sm_read;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fn = maj->sm_write;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fn != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(maj->sm_flag & D_MP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_ENTER();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*fn)(dev, uiop, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_EXIT();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*fn)(dev, uiop, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENODEV);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(RW_READ_HELD(&svp->sv_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_flag == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * guard access mode
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - prevent user level access to the device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_lyr_uio_err_guard, uio_t *, uiop);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EPERM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH)) != 0) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_lyr_uio_err_rsrv, uio_t *, uiop);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rw == NSC_READ)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_uread(svp->sv_fd, uiop, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_uwrite(svp->sv_fd, uiop, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteout:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_lyr_read(dev_t dev, uio_t *uiop, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sv_lyr_uio(dev, uiop, crp, NSC_READ));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_lyr_write(dev_t dev, uio_t *uiop, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sv_lyr_uio(dev, uiop, crp, NSC_WRITE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_lyr_aread(dev_t dev, struct aio_req *aio, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (aphysio(sv_lyr_strategy,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte anocancel, dev, B_READ, minphys, aio));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_lyr_awrite(dev_t dev, struct aio_req *aio, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (aphysio(sv_lyr_strategy,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte anocancel, dev, B_WRITE, minphys, aio));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set up an array containing the list of raw path names
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The array for the paths is svl and the size of the array is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in size.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are more layered devices than will fit in the array,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the number of extra layered devices is returned. Otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zero is return.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * svn : array for paths
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * size : size of the array
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Output (extra):
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zero : All paths fit in array
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * >0 : Number of defined layered devices don't fit in array
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_list(void *ptr, const int size, int *extra, const int ilp32)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_name32_t *svn32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_name_t *svn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int *mode, *nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i, index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *path;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *extra = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svn32 = ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svn = ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < sv_max_devices; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = &sv_devs[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&svp->sv_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_state != SV_ENABLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*extra) != 0 || ptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Another overflow entry */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*extra)++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nblocks = &svn32->svn_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode = &svn32->svn_mode;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte path = svn32->svn_path;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svn32->svn_timestamp = (uint32_t)svp->sv_timestamp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svn32++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nblocks = &svn->svn_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode = &svn->svn_mode;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte path = svn->svn_path;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svn->svn_timestamp = svp->sv_timestamp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svn++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(path, nsc_pathname(svp->sv_fd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *nblocks = svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *mode = svp->sv_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*nblocks == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 3)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!sv_list: need to reserve\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana if (sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *nblocks = svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (++index >= size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Out of space */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*extra)++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (index < size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NULL terminated list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svn32->svn_path[0] = '\0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svn->svn_path[0] = '\0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_thread_tune(int threads)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int incr = (threads > 0) ? 1 : -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int change = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int nthreads;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&sv_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_threads_extra) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* keep track of any additional threads requested */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (threads > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_threads_extra += threads;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte threads = -threads;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (threads >= sv_threads_extra) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte threads -= sv_threads_extra;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_threads_extra = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fall through to while loop */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_threads_extra -= threads;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (threads > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * do not increase the number of threads beyond
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sv_threads_max when doing dynamic thread tuning
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nthreads = nst_nthread(sv_tset);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((nthreads + threads) > sv_threads_max) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_threads_extra = nthreads + threads - sv_threads_max;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte threads = sv_threads_max - nthreads;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (threads <= 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (threads < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte threads = -threads;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (threads--) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nthreads = nst_nthread(sv_tset);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_threads_needed += incr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_threads_needed >= nthreads)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte change += nst_add_thread(sv_tset, sv_threads_inc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if ((sv_threads_needed <
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (nthreads - (sv_threads_inc + sv_threads_hysteresis))) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((nthreads - sv_threads_inc) >= sv_threads))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte change -= nst_del_thread(sv_tset, sv_threads_inc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (change) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sv_thread_tune: threads needed %d, nthreads %d, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nthreads change %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_threads_needed, nst_nthread(sv_tset), change);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesvopen(dev_t *devp, int flag, int otyp, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_init_devs();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesvclose(dev_t dev, int flag, int otyp, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const int secs = HZ * 5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const int ticks = HZ / 10;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int loops = secs / ticks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (sv_ndevices <= 0 && sv_tset != NULL && loops > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nst_nlive(sv_tset) <= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nst_destroy(sv_tset);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_tset = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* threads still active - wait for them to exit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(ticks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte loops--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (loops <= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* do not write to console when non-DEBUG */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "sv:svclose: threads still active "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "after %d sec - leaking thread set", secs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesvioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvalp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char itmp1[12], itmp2[12]; /* temp char array for editing ints */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_info_t kstatus; /* Kernel version of spcs status */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_info_t ustatus; /* Address of user version of spcs status */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_list32_t svl32; /* 32 bit Initial structure for SVIOC_LIST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_version_t svv; /* Version structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_conf_t svc; /* User config structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_list_t svl; /* Initial structure for SVIOC_LIST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *usvn; /* Address of user sv_name_t */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *svn = NULL; /* Array for SVIOC_LIST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t phash; /* pathname hash */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = 0; /* Return code -- errno */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int size; /* Number of items in array */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int bytes; /* Byte size of array */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ilp32; /* Convert data structures for ilp32 userland */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *rvalp = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If sv_mod_status is 0 or SV_PREVENT_UNLOAD, then it will continue.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * else it means it previously was SV_PREVENT_UNLOAD, and now it's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SV_ALLOW_UNLOAD, expecting the driver to eventually unload.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SV_ALLOW_UNLOAD is final state, so no need to grab sv_mutex.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_mod_status == SV_ALLOW_UNLOAD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cmd != SVIOC_LIST) && ((rc = drv_priv(crp)) != 0))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstatus = spcs_s_kcreate();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!kstatus) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_ioctl_err_kcreate, dev_t, dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilp32 = (ddi_model_convert_from((mode & FMODELS)) == DDI_MODEL_ILP32);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case SVIOC_ENABLE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_conf32_t svc32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &svc32,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svc32), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_error = (spcs_s_info_t)svc32.svc_error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(svc.svc_path, svc32.svc_path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_flag = svc32.svc_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_major = svc32.svc_major;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_minor = svc32.svc_minor;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &svc,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svc), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* force to raw access */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_flag = NSC_DEVICE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_tset == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_tset == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_tset = nst_init("sv_thr", sv_threads);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_tset == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sv: could not allocate %d threads",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_threads);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_enable(svc.svc_path, svc.svc_flag,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana makedevice(svc.svc_major, svc.svc_minor), kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_config_time = nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_thread_tune(sv_threads_dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE3(sv_ioctl_end, dev_t, dev, int, *rvalp, int, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (spcs_s_ocopyoutf(&kstatus, svc.svc_error, rc));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case SVIOC_DISABLE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_conf32_t svc32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &svc32,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svc32), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_error = (spcs_s_info_t)svc32.svc_error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_major = svc32.svc_major;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_minor = svc32.svc_minor;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(svc.svc_path, svc32.svc_path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_flag = svc32.svc_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &svc,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svc), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svc.svc_major == (major_t)-1 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_minor == (minor_t)-1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * User level could not find the minor device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node, so do this the slow way by searching
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the entire sv config for a matching pathname.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phash = nsc_strhash(svc.svc_path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < sv_max_devices; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = &sv_devs[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_state == SV_DISABLE ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_fd == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nsc_fdpathcmp(svp->sv_fd, phash,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_path) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_major = getmajor(svp->sv_dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_minor = getminor(svp->sv_dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svc.svc_major == (major_t)-1 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svc.svc_minor == (minor_t)-1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (spcs_s_ocopyoutf(&kstatus,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana svc.svc_error, SV_ENODEV));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_disable(makedevice(svc.svc_major, svc.svc_minor),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_config_time = nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_thread_tune(-sv_threads_dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sv_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE3(sv_ioctl_2, dev_t, dev, int, *rvalp, int, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (spcs_s_ocopyoutf(&kstatus, svc.svc_error, rc));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case SVIOC_LIST:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &svl32,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svl32), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ustatus = (spcs_s_info_t)svl32.svl_error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size = svl32.svl_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte usvn = (void *)(unsigned long)svl32.svl_names;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &svl,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svl), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ustatus = svl.svl_error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size = svl.svl_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte usvn = svl.svl_names;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Do some boundary checking */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((size < 0) || (size > sv_max_devices)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Array size is out of range */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (spcs_s_ocopyoutf(&kstatus, ustatus,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana SV_EARRBOUNDS, "0",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana spcs_s_inttostring(sv_max_devices, itmp1,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (itmp1), 0),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana spcs_s_inttostring(size, itmp2,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (itmp2), 0)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bytes = size * sizeof (sv_name32_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bytes = size * sizeof (sv_name_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Allocate memory for the array of structures */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bytes != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svn = kmem_zalloc(bytes, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!svn) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (spcs_s_ocopyoutf(&kstatus,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ustatus, ENOMEM));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_list(svn, size, rvalp, ilp32);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svn != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(svn, bytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (spcs_s_ocopyoutf(&kstatus, ustatus, rc));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svl32.svl_timestamp = (uint32_t)sv_config_time;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svl32.svl_maxdevs = (int32_t)sv_max_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Return the list structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(&svl32, (void *)arg,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svl32), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svn != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(svn, bytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svl.svl_timestamp = sv_config_time;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svl.svl_maxdevs = sv_max_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Return the list structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(&svl, (void *)arg,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svl), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svn != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(svn, bytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Return the array */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svn != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(svn, usvn, bytes, mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(svn, bytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(svn, bytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE3(sv_ioctl_3, dev_t, dev, int, *rvalp, int, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (spcs_s_ocopyoutf(&kstatus, ustatus, 0));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case SVIOC_VERSION:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_version32_t svv32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &svv32,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svv32), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svv32.svv_major_rev = sv_major_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svv32.svv_minor_rev = sv_minor_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svv32.svv_micro_rev = sv_micro_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svv32.svv_baseline_rev = sv_baseline_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(&svv32, (void *)arg,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svv32), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ustatus = (spcs_s_info_t)svv32.svv_error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &svv,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svv), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svv.svv_major_rev = sv_major_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svv.svv_minor_rev = sv_minor_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svv.svv_micro_rev = sv_micro_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svv.svv_baseline_rev = sv_baseline_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(&svv, (void *)arg,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana sizeof (svv), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ustatus = svv.svv_error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE3(sv_ioctl_4, dev_t, dev, int, *rvalp, int, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (spcs_s_ocopyoutf(&kstatus, ustatus, 0));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case SVIOC_UNLOAD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_prepare_unload();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana if (ddi_copyout(&rc, (void *)arg, sizeof (rc), mode) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_kfree(kstatus);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE3(sv_ioctl_4, dev_t, dev, int, *rvalp, int, EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesvprint(dev_t dev, char *str)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int instance = ddi_get_instance(sv_dip);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!%s%d: %s", ddi_get_name(sv_dip), instance, str);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sv_lyr_strategy(struct buf *bp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t buf_addr; /* pointer to linear buffer in bp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_buf_t *bufh = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_buf_t *hndl = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_vec_t *v;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t fba_req, fba_len; /* FBA lengths */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t fba_off; /* FBA offset */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t tocopy, nbytes; /* byte lengths */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rw, rc; /* flags and return codes */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*fn)();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 5)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!_sv_lyr_strategy(%p)\n", (void *)bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = sv_find_enabled(bp->b_edev, &maj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj && (fn = maj->sm_strategy) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(maj->sm_flag & D_MP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_ENTER();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*fn)(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_EXIT();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*fn)(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, ENODEV);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte biodone(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(RW_READ_HELD(&svp->sv_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp->sv_flag == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * guard access mode
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - prevent user level access to the device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_lyr_strategy_err_guard, struct buf *, bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, EPERM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH)) != 0) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_lyr_strategy_err_rsrv, struct buf *, bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == EINTR)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!nsc_reserve() returned EINTR");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bp->b_lblkno >= (diskaddr_t)svp->sv_nblocks) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_lyr_strategy_eof, struct buf *, bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bp->b_flags & B_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* return EOF, not an error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_resid = bp->b_bcount;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Preallocate a handle once per call to strategy.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If this fails, then the nsc_alloc_buf() will allocate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a temporary handle per allocation/free pair.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_alloch_start, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bufh = nsc_alloc_handle(svp->sv_fd, NULL, NULL, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_alloch_end, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bufh && (bufh->sb_flag & NSC_HACTIVE) != 0) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_lyr_strategy_err_hactive, struct buf *, bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sv: allocated active handle (bufh %p, flags %x)",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (void *)bufh, bufh->sb_flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fba_req = FBA_LEN(bp->b_bcount);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fba_req + bp->b_lblkno > (diskaddr_t)svp->sv_nblocks)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fba_req = (nsc_size_t)(svp->sv_nblocks - bp->b_lblkno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw = (bp->b_flags & B_READ) ? NSC_READ : NSC_WRITE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp_mapin(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_resid = bp->b_bcount;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf_addr = bp->b_un.b_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fba_off = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fba_req - requested size of transfer in FBAs after
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * truncation to device extent, and allowing for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * possible non-FBA bounded final chunk.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fba_off - offset of start of chunk from start of bp in FBAs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fba_len - size of this chunk in FBAs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteloop:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fba_len = min(fba_req, svp->sv_maxfbas);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hndl = bufh;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE4(sv_dbg_allocb_start,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *, svp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t, (uint64_t)(bp->b_lblkno + fba_off),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t, (uint64_t)fba_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int, rw);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_alloc_buf(svp->sv_fd, (nsc_off_t)(bp->b_lblkno + fba_off),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana fba_len, rw, &hndl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_allocb_end, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc > 0) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_lyr_strategy_err_alloc, struct buf *, bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (hndl != bufh)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nsc_free_buf(hndl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hndl = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tocopy = min(FBA_SIZE(fba_len), bp->b_resid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte v = hndl->sb_vec;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rw == NSC_WRITE && FBA_OFF(tocopy) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Not overwriting all of the last FBA, so read in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * old contents now before we overwrite it with the new
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE2(sv_dbg_read_start, sv_dev_t *, svp,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana uint64_t, (uint64_t)(hndl->sb_pos + hndl->sb_len - 1));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_read(hndl, (hndl->sb_pos + hndl->sb_len - 1), 1, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_read_end, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_bcopy_start, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (tocopy > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nbytes = min(tocopy, (nsc_size_t)v->sv_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bp->b_flags & B_READ)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) bcopy(v->sv_addr, buf_addr, nbytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) bcopy(buf_addr, v->sv_addr, nbytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_resid -= nbytes;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf_addr += nbytes;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tocopy -= nbytes;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte v++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_bcopy_end, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((bp->b_flags & B_READ) == 0) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE3(sv_dbg_write_start, sv_dev_t *, svp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t, (uint64_t)hndl->sb_pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t, (uint64_t)hndl->sb_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_write(hndl, hndl->sb_pos, hndl->sb_len, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_write_end, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Adjust FBA offset and requested (ie. remaining) length,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * loop if more data to transfer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fba_off += fba_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fba_req -= fba_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fba_req > 0) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_freeb_start, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_free_buf(hndl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_freeb_end, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(sv_lyr_strategy_err_free,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana struct buf *, bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hndl = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc <= 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto loop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedone:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (hndl != NULL) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_freeb_start, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_free_buf(hndl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_freeb_end, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(sv_lyr_strategy_err_free,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana struct buf *, bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hndl = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bufh)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nsc_free_handle(bufh);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_rlse_start, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_dbg_rlse_end, sv_dev_t *, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteout:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 5) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!_sv_lyr_strategy: bp %p, bufh %p, bp->b_error %d\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)bp, (void *)bufh, bp->b_error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE2(sv_lyr_strategy_end, struct buf *, bp, int, bp->b_error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte biodone(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_async_strategy(blind_t arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp = (struct buf *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sv_lyr_strategy(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_lyr_strategy(struct buf *bp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsthread_t *tp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int nlive;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If B_ASYNC was part of the DDI we could use it as a hint to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not create a thread for synchronous i/o.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_dev_to_sv(bp->b_edev, NULL) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* not sv enabled - just pass through */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(sv_lyr_strategy_notsv, struct buf *, bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sv_lyr_strategy(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 4) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!sv_lyr_strategy: nthread %d nlive %d\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nst_nthread(sv_tset), nst_nlive(sv_tset));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are only guard devices enabled there
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * won't be a threadset, so don't try and use it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_tset != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp = nst_create(sv_tset, sv_async_strategy, (blind_t)bp, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * out of threads, so fall back to synchronous io.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sv_lyr_strategy: thread alloc failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(sv_lyr_strategy_no_thread,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana struct buf *, bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sv_lyr_strategy(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_no_threads++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlive = nst_nlive(sv_tset);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nlive > sv_max_nlive) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_debug > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sv_lyr_strategy: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "new max nlive %d (nthread %d)\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlive, nst_nthread(sv_tset));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_max_nlive = nlive;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * re-write the size of the current partition
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_fix_dkiocgvtoc(const intptr_t arg, const int mode, sv_dev_t *svp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t offset;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ilp32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int pnum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilp32 = (ddi_model_convert_from((mode & FMODELS)) == DDI_MODEL_ILP32);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nskern_partition(svp->sv_dev, &pnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pnum < 0 || pnum >= V_NUMPAR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sv_gvtoc: unable to determine partition number "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "for dev %lx", svp->sv_dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilp32) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int32_t p_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SunOS_5_6
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset = offsetof(struct vtoc, v_part);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset += sizeof (struct partition) * pnum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset += offsetof(struct partition, p_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset = offsetof(struct vtoc32, v_part);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset += sizeof (struct partition32) * pnum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset += offsetof(struct partition32, p_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p_size = (int32_t)svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (p_size == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_reserve(svp->sv_fd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NSC_MULTI|NSC_PCATCH) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p_size = (int32_t)svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EINTR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc == 0) && ddi_copyout(&p_size, (void *)(arg + offset),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (p_size), mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte long p_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset = offsetof(struct vtoc, v_part);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset += sizeof (struct partition) * pnum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset += offsetof(struct partition, p_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p_size = (long)svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (p_size == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_reserve(svp->sv_fd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NSC_MULTI|NSC_PCATCH) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p_size = (long)svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EINTR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc == 0) && ddi_copyout(&p_size, (void *)(arg + offset),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (p_size), mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DKIOCPARTITION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * re-write the size of the current partition
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * arg is dk_efi_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dk_efi_t->dki_data = (void *)(uintptr_t)efi.dki_data_64;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dk_efi_t->dki_data --> efi_gpt_t (label header)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dk_efi_t->dki_data + 1 --> efi_gpe_t[] (array of partitions)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * efi_gpt_t->efi_gpt_PartitionEntryArrayCRC32 --> CRC32 of array of parts
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * efi_gpt_t->efi_gpt_HeaderCRC32 --> CRC32 of header itself
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This assumes that sizeof (efi_gpt_t) is the same as the size of a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * logical block on the disk.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Everything is little endian (i.e. disk format).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_fix_dkiocgetefi(const intptr_t arg, const int mode, sv_dev_t *svp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dk_efi_t efi;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte efi_gpt_t gpt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte efi_gpe_t *gpe = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t sgpe;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t p_size; /* virtual partition size from nsctl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t crc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int unparts; /* number of parts in user's array */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int pnum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nskern_partition(svp->sv_dev, &pnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pnum < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sv_efi: unable to determine partition number for dev %lx",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp->sv_dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &efi, sizeof (efi), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte efi.dki_data = (void *)(uintptr_t)efi.dki_data_64;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (efi.dki_length < sizeof (gpt) + sizeof (gpe)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)efi.dki_data, &gpt, sizeof (gpt), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((unparts = LE_32(gpt.efi_gpt_NumberOfPartitionEntries)) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unparts = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (pnum >= unparts) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sv_efi: partition# beyond end of user array (%d >= %d)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pnum, unparts);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sgpe = sizeof (*gpe) * unparts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gpe = kmem_alloc(sgpe, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)(efi.dki_data + 1), gpe, sgpe, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p_size = svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (p_size == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p_size = (diskaddr_t)svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EINTR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gpe[pnum].efi_gpe_EndingLBA = LE_64(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LE_64(gpe[pnum].efi_gpe_StartingLBA) + p_size - 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gpt.efi_gpt_PartitionEntryArrayCRC32 = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CRC32(crc, gpe, sgpe, -1U, sv_crc32_table);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gpt.efi_gpt_PartitionEntryArrayCRC32 = LE_32(~crc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gpt.efi_gpt_HeaderCRC32 = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CRC32(crc, &gpt, sizeof (gpt), -1U, sv_crc32_table);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gpt.efi_gpt_HeaderCRC32 = LE_32(~crc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc == 0) && ddi_copyout(&gpt, efi.dki_data, sizeof (gpt), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc == 0) && ddi_copyout(gpe, efi.dki_data + 1, sgpe, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteout:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (gpe) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(gpe, sgpe);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Re-write the size of the partition specified by p_partno
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note that if a DKIOCPARTITION is issued to an fd opened against a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-sv'd device, but p_partno requests the size for a different
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device that is sv'd, this function will *not* be called as sv is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not interposed on the original device (the fd).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It would not be easy to change this as we cannot get the partition
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * number for the non-sv'd device, so cannot compute the dev_t of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (sv'd) p_partno device, and so cannot find out if it is sv'd or get
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * its size from nsctl.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See also the "Bug 4755783" comment in sv_lyr_ioctl().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_fix_dkiocpartition(const intptr_t arg, const int mode, sv_dev_t *svp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct partition64 p64;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *nsvp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte diskaddr_t p_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte minor_t nminor;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int pnum, rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t ndev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nskern_partition(svp->sv_dev, &pnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, &p64, sizeof (p64), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (p64.p_partno != pnum) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* switch to requested partition, not the current one */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nminor = getminor(svp->sv_dev) + (p64.p_partno - pnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ndev = makedevice(getmajor(svp->sv_dev), nminor);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsvp = sv_find_enabled(ndev, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nsvp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* not sv device - just return */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = nsvp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p_size = svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (p_size == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_reserve(svp->sv_fd, NSC_MULTI|NSC_PCATCH) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p_size = (diskaddr_t)svp->sv_nblocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_release(svp->sv_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EINTR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nsvp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&nsvp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc == 0) && ddi_copyout(&p_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)(arg + offsetof(struct partition64, p_size)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (p_size), mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* DKIOCPARTITION */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesv_lyr_ioctl(const dev_t dev, const int cmd, const intptr_t arg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const int mode, cred_t *crp, int *rvalp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_dev_t *svp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sv_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*fn)();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fn = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If sv_mod_status is 0 or SV_PREVENT_UNLOAD, then it will continue.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * else it means it previously was SV_PREVENT_UNLOAD, and now it's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SV_ALLOW_UNLOAD, expecting the driver to eventually unload.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SV_ALLOW_UNLOAD is final state, so no need to grab sv_mutex.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sv_mod_status == SV_ALLOW_UNLOAD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = sv_find_enabled(dev, &maj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nskernd_isdaemon()) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is nskernd which always needs to see
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the underlying disk device accurately.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So just pass the ioctl straight through
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the underlying driver as though the device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * was not sv enabled.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE2(sv_lyr_ioctl_nskernd, sv_dev_t *, svp,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana dev_t, dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte svp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(RW_READ_HELD(&svp->sv_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We now have a locked and enabled SV device, or a non-SV device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DKIOCGVTOC, DKIOCSVTOC, DKIOCPARTITION, DKIOCGETEFI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and DKIOCSETEFI are intercepted and faked up as some
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * i/o providers emulate volumes of a different size to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the underlying volume.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Setting the size by rewriting the vtoc is not permitted.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DKIOCSVTOC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DKIOCPARTITION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DKIOCSETEFI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* not intercepted -- allow ioctl through */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE2(sv_lyr_ioctl_svtoc, dev_t, dev, int, EPERM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EPERM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Pass through the real ioctl command.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj && (fn = maj->sm_ioctl) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(maj->sm_flag & D_MP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_ENTER();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*fn)(dev, cmd, arg, mode, crp, rvalp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UNSAFE_EXIT();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*fn)(dev, cmd, arg, mode, crp, rvalp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ENODEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bug 4755783
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fix up the size of the current partition to allow
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for the virtual volume to be a different size to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * physical volume (e.g. for II compact dependent shadows).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note that this only attempts to fix up the current partition
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - the one that the ioctl was issued against. There could be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * other sv'd partitions in the same vtoc, but we cannot tell
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so we don't attempt to fix them up.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp != NULL && rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DKIOCGVTOC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_fix_dkiocgvtoc(arg, mode, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DKIOCPARTITION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DKIOCGETEFI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_fix_dkiocgetefi(arg, mode, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DKIOCPARTITION:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sv_fix_dkiocpartition(arg, mode, svp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* DKIOCPARTITION */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&svp->sv_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}