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/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/debug.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef DS_DDICT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/vnode.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/open.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/file.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cred.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/uio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef DS_DDICT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/pathname.h> /* for lookupname */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sunddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sunldi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ns/solaris/nsc_thread.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DS_DDICT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "../contract.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "../nsctl.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "nskernd.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct raw_maj {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct raw_maj *next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte major_t major;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct dev_ops *devops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strategy_fn_t strategy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*open)(dev_t *, int, int, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*close)(dev_t, int, int, cred_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*ioctl)(dev_t, int, intptr_t, int, cred_t *, int *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} raw_maj_t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct raw_dev {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ldi_handle_t lh; /* Solaris layered driver handle */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct vnode *vp; /* vnode of device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t size; /* size of device in blocks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_maj_t *major; /* pointer to major structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *path; /* pathname -- kmem_alloc'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int plen; /* length of kmem_alloc for pathname */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t rdev; /* device number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char in_use; /* flag */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int partition; /* partition number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} raw_dev_t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fd_hwm = 0; /* first never used entry in _nsc_raw_files */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic raw_dev_t *_nsc_raw_files;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic raw_maj_t *_nsc_raw_majors;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortekmutex_t _nsc_raw_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint _nsc_raw_flags = 0; /* required by nsctl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_raw_maxdevs; /* local copy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _raw_strategy(struct buf *); /* forward decl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic dev_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteldi_get_dev_t_from_path(char *path)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vnode_t *vp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t rdev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Validate parameters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (path == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Lookup path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lookupname(path, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Validate resulting vnode */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vp) && (vp->v_type == VCHR))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdev = vp->v_rdev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdev = (dev_t)NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Release vnode */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte VN_RELE(vp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rdev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_init_raw(int maxdevs)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_raw_files =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(sizeof (*_nsc_raw_files) * maxdevs, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_nsc_raw_files)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_raw_maxdevs = maxdevs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_raw_majors = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&_nsc_raw_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_deinit_raw(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_maj_t *maj = _nsc_raw_majors;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_maj_t *next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Free the memory allocated for strategy pointers */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (maj != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = maj->next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(maj, sizeof (*maj));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj = next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(_nsc_raw_files, sizeof (*_nsc_raw_files) * _nsc_raw_maxdevs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_raw_files = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_raw_maxdevs = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* must be called with the _nsc_raw_lock held */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic raw_maj_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_get_maj_info(major_t umaj)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_maj_t *maj = _nsc_raw_majors;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&_nsc_raw_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Walk through the linked list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (maj != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->major == umaj) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Found major number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj = maj->next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct dev_ops *ops = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const int maxtry = 5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int try = maxtry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The earlier ldi_open call has locked the driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for this major number into memory, so just index into
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the devopsp array to get the dev_ops pointer which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * must be valid.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ops = devopsp[umaj];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ops == NULL || ops->devo_cb_ops == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nskern: cannot find dev_ops for major %d", umaj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nsc_raw: held driver (%d) after %d attempts",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte umaj, (maxtry - try));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* DEBUG */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj = kmem_zalloc(sizeof (raw_maj_t), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!maj) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->strategy = ops->devo_cb_ops->cb_strategy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->ioctl = ops->devo_cb_ops->cb_ioctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->close = ops->devo_cb_ops->cb_close;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->open = ops->devo_cb_ops->cb_open;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->major = umaj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->devops = ops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->strategy == NULL ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->strategy == nodev ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->strategy == nulldev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nskern: no strategy function for "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "disk driver (major %d)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte umaj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(maj, sizeof (*maj));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maj->next = _nsc_raw_majors;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_raw_majors = maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (maj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_get_strategy returns the strategy function associated with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the major number umaj. NULL is returned if no strategy is found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestrategy_fn_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_get_strategy(major_t umaj)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strategy_fn_t strategy = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (maj = _nsc_raw_majors; maj != NULL; maj = maj->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->major == umaj) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Found major number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strategy = maj->strategy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (strategy);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_get_devops(major_t umaj)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_maj_t *maj;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *devops = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (maj = _nsc_raw_majors; maj != NULL; maj = maj->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (maj->major == umaj) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devops = maj->devops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (devops);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _raw_open
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Multiple opens, single close.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_open(char *path, int flag, blind_t *cdp, void *iodev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct cred *cred;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_dev_t *cdi = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *spath;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t rdev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc, cd, the_cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int plen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ldi_ident_t li;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (proc_nskernd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "nskern: no nskernd daemon running!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_nsc_raw_maxdevs == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "nskern: _raw_open() before _nsc_init_raw()!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte plen = strlen(path) + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spath = kmem_alloc(plen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (spath == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nskern: unable to alloc memory in _raw_open()");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(spath, path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Lookup the vnode to extract the dev_t info,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then release the vnode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rdev = ldi_get_dev_t_from_path(path)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(spath, plen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See if this device is already opened
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte the_cd = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cd = 0, cdi = _nsc_raw_files; cd < fd_hwm; cd++, cdi++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rdev == cdi->rdev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte the_cd = cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (the_cd == -1 && !cdi->in_use)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte the_cd = cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (the_cd == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd_hwm < _nsc_raw_maxdevs)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte the_cd = fd_hwm++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "_raw_open: too many open devices");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(spath, plen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi = &_nsc_raw_files[the_cd];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->in_use) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* already set up - just return */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cdp = (blind_t)cdi->rdev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(spath, plen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->partition = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->size = (uint64_t)0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->rdev = rdev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->path = spath;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->plen = plen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cred = ddi_get_cred();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Layered driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We use xxx_open_by_dev() since this guarantees that a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * specfs vnode is created and used, not a standard filesystem
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * vnode. This is necessary since in a cluster PXFS will block
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * vnode operations during switchovers, so we have to use the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * underlying specfs vnode not the PXFS vnode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = ldi_ident_from_dev(cdi->rdev, &li)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ldi_open_by_dev(&cdi->rdev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte OTYP_BLK, FREAD|FWRITE, cred, &cdi->lh, li);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->lh = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * grab the major_t related information
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->major = _raw_get_maj_info(getmajor(rdev));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->major == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Out of memory */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "_raw_open: cannot alloc major number structure");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ENOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cdp = (blind_t)cdi->rdev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->in_use++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefailed:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->lh)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ldi_close(cdi->lh, FWRITE|FREAD, cred);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(cdi, sizeof (*cdi));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(spath, plen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte__raw_get_cd(dev_t fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_nsc_raw_maxdevs != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cd = 0; cd < fd_hwm; cd++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd == _nsc_raw_files[cd].rdev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _raw_close
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Multiple opens, single close.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_close(dev_t fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct cred *cred;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_dev_t *cdi;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi = &_nsc_raw_files[cd];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cred = ddi_get_cred();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ldi_close(cdi->lh, FREAD|FWRITE, cred);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(cdi->path, cdi->plen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(cdi, sizeof (*cdi));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_nsc_raw_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_uread(dev_t fd, uio_t *uiop, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (physio(_raw_strategy, 0, fd, B_READ, minphys, uiop));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_uwrite(dev_t fd, uio_t *uiop, cred_t *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (physio(_raw_strategy, 0, fd, B_WRITE, minphys, uiop));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_strategy(struct buf *bp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd = __raw_get_cd(bp->b_edev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cd == -1 || _nsc_raw_files[cd].major == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bioerror(bp, ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte biodone(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return ((*_nsc_raw_files[cd].major->strategy)(bp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_partsize(dev_t fd, nsc_size_t *rvalp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *rvalp = (nsc_size_t)_nsc_raw_files[cd].size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return largest i/o size.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_size_t nsc_rawmaxfbas = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_maxfbas(dev_t dev, int flag, nsc_size_t *ptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag == NSC_CACHEBLK)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ptr = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nsc_rawmaxfbas == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp = getrbuf(KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_bcount = 4096 * 512;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte minphys(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_rawmaxfbas = FBA_NUM(bp->b_bcount);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freerbuf(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ptr = nsc_rawmaxfbas;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Control device or system.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_control(dev_t dev, int cmd, int *ptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "unrecognised nsc_control: %x", cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL); /* no control commands understood */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_get_bsize(dev_t dev, uint64_t *bsizep, int *partitionp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DKIOCPARTITION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct partition64 *p64 = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct dk_cinfo *dki_info = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct dev_ops *ops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct cred *cred;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct vtoc *vtoc = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_info_t *dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_dev_t *cdi;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc, cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *partitionp = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *bsizep = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd = __raw_get_cd(dev)) == -1 || !_nsc_raw_files[cd].in_use)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi = &_nsc_raw_files[cd];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ops = cdi->major->devops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ops == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*ops->devo_getinfo)(NULL, DDI_INFO_DEVT2DEVINFO,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)dev, (void **)&dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != DDI_SUCCESS || dip == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!ddi_prop_exists(DDI_DEV_T_ANY, dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, DDI_KERNEL_IOCTL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cred = ddi_get_cred();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = FKIOCTL | FREAD | FWRITE | DATAMODEL_NATIVE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dki_info = kmem_alloc(sizeof (*dki_info), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* DKIOCINFO */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*cdi->major->ioctl)(dev, DKIOCINFO,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (intptr_t)dki_info, flags, cred, &rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* return partition number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *partitionp = (int)dki_info->dki_partition;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vtoc = kmem_alloc(sizeof (*vtoc), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* DKIOCGVTOC */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*cdi->major->ioctl)(dev, DKIOCGVTOC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (intptr_t)vtoc, flags, cred, &rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* DKIOCGVTOC failed, but there might be an EFI label */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DKIOCPARTITION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* do we have an EFI partition table? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p64 = kmem_alloc(sizeof (*p64), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p64->p_partno = (uint_t)*partitionp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* DKIOCPARTITION */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*cdi->major->ioctl)(dev, DKIOCPARTITION,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (intptr_t)p64, flags, cred, &rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* found EFI, return size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *bsizep = (uint64_t)p64->p_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* both DKIOCGVTOC and DKIOCPARTITION failed - error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vtoc->v_sanity != VTOC_SANE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (vtoc->v_version != V_VERSION && vtoc->v_version != 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (dki_info->dki_partition > V_NUMPAR)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *bsizep = (uint64_t)vtoc->v_part[(int)dki_info->dki_partition].p_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteout:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dki_info) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dki_info, sizeof (*dki_info));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vtoc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vtoc, sizeof (*vtoc));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DKIOCPARTITION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (p64) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(p64, sizeof (*p64));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Ugly, ugly, ugly.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Some volume managers (Veritas) don't support layered ioctls
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (no FKIOCTL support, no DDI_KERNEL_IOCTL property defined) AND
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * do not support the properties for bdev_Size()/bdev_size().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the underlying driver has specified DDI_KERNEL_IOCTL, then we use
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the FKIOCTL technique. Otherwise ...
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The only reliable way to get the partition size, is to bounce the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * command through user land (nskernd).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Then, SunCluster PXFS blocks access at the vnode level to device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nodes during failover / switchover, so a read_vtoc() function call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from user land deadlocks. So, we end up coming back into the kernel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to go directly to the underlying device driver - that's what
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nskern_bsize() is doing below.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There has to be a better way ...
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_init_dev(dev_t fd, uint64_t *sizep, int *partitionp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nskernd *nsk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc, cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* try the in-kernel way */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _raw_get_bsize(fd, sizep, partitionp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fallback to the the slow way */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk = kmem_zalloc(sizeof (*nsk), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk->command = NSKERND_BSIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk->data1 = (uint64_t)0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk->data2 = (uint64_t)fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(nsk->char1, _nsc_raw_files[cd].path, NSC_MAXPATH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nskernd_get(nsk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *partitionp = (int)nsk->data2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *sizep = nsk->data1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nsk, sizeof (*nsk));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc < 0 ? EIO : 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_raw_attach_io(dev_t fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_raw_init_dev(fd, &_nsc_raw_files[cd].size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &_nsc_raw_files[cd].partition));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the comment above _raw_init_dev().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenskern_bsize(struct nscioc_bsize *bsize, int *rvp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct cred *cred;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte raw_dev_t *cdi;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int errno = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *rvp = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bsize == NULL || rvp == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cd = __raw_get_cd(bsize->raw_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cd == -1 || !_nsc_raw_files[cd].in_use)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi = &_nsc_raw_files[cd];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cred = ddi_get_cred();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ddi_mmap_get_model() returns the model for this user thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which is what we want - get_udatamodel() is not public.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flag = FREAD | FWRITE | ddi_mmap_get_model();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bsize->efi == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* DKIOCINFO */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = (*cdi->major->ioctl)(bsize->raw_fd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DKIOCINFO, (intptr_t)bsize->dki_info, flag, cred, rvp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* DKIOCGVTOC */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = (*cdi->major->ioctl)(bsize->raw_fd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DKIOCGVTOC, (intptr_t)bsize->vtoc, flag, cred, rvp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DKIOCPARTITION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* do we have an EFI partition table? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = (*cdi->major->ioctl)(bsize->raw_fd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DKIOCPARTITION, (intptr_t)bsize->p64, flag, cred, rvp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Private function for sv to use.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenskern_partition(dev_t fd, int *partitionp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd, rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd = __raw_get_cd(fd)) == -1 || !_nsc_raw_files[cd].in_use)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*partitionp = _nsc_raw_files[cd].partition) != -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _raw_init_dev(fd, &size, partitionp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0 || *partitionp < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_def_t _nsc_raw_def[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Open", (uintptr_t)_raw_open, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Close", (uintptr_t)_raw_close, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Attach", (uintptr_t)_raw_attach_io, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "UserRead", (uintptr_t)_raw_uread, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "UserWrite", (uintptr_t)_raw_uwrite, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PartSize", (uintptr_t)_raw_partsize, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "MaxFbas", (uintptr_t)_raw_maxfbas, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Control", (uintptr_t)_raw_control, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Provide", NSC_DEVICE, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};