/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef DS_DDICT
#endif
#ifndef DS_DDICT
#endif
#ifdef DS_DDICT
#include "../contract.h"
#endif
#include "../nsctl.h"
#include "nskernd.h"
typedef struct raw_maj {
} raw_maj_t;
typedef struct raw_dev {
} raw_dev_t;
static dev_t
{
/* Validate parameters */
return (NULL);
/* Lookup path */
return (NULL);
/* Validate resulting vnode */
else
/* Release vnode */
if (vp)
return (rdev);
}
int
{
if (!_nsc_raw_files)
return (ENOMEM);
return (0);
}
void
_nsc_deinit_raw(void)
{
/* Free the memory allocated for strategy pointers */
}
_nsc_raw_maxdevs = 0;
}
/* must be called with the _nsc_raw_lock held */
static raw_maj_t *
{
/* Walk through the linked list */
/* Found major number */
break;
}
}
#ifdef DEBUG
#endif
/*
* The earlier ldi_open call has locked the driver
* for this major number into memory, so just index into
* the devopsp array to get the dev_ops pointer which
* must be valid.
*/
"nskern: cannot find dev_ops for major %d", umaj);
return (NULL);
}
#ifdef DEBUG
"nsc_raw: held driver (%d) after %d attempts",
#endif /* DEBUG */
if (!maj) {
return (NULL);
}
"nskern: no strategy function for "
"disk driver (major %d)",
umaj);
return (NULL);
}
}
return (maj);
}
/*
* nsc_get_strategy returns the strategy function associated with
* the major number umaj. NULL is returned if no strategy is found.
*/
{
/* Found major number */
break;
}
}
return (strategy);
}
void *
{
break;
}
}
return (devops);
}
/*
* _raw_open
*
* Multiple opens, single close.
*/
/* ARGSUSED */
static int
{
char *spath;
int plen;
if (proc_nskernd == NULL) {
return (ENXIO);
}
if (_nsc_raw_maxdevs == 0) {
return (ENXIO);
}
"nskern: unable to alloc memory in _raw_open()");
return (ENOMEM);
}
/*
* Lookup the vnode to extract the dev_t info,
* then release the vnode.
*/
return (ENXIO);
}
/*
* See if this device is already opened
*/
the_cd = -1;
break;
}
if (the_cd == -1) {
if (fd_hwm < _nsc_raw_maxdevs)
else {
return (EIO);
}
}
/* already set up - just return */
return (0);
}
cred = ddi_get_cred();
/*
* Layered driver
*
* We use xxx_open_by_dev() since this guarantees that a
* specfs vnode is created and used, not a standard filesystem
* vnode. This is necessary since in a cluster PXFS will block
* vnode operations during switchovers, so we have to use the
* underlying specfs vnode not the PXFS vnode.
*
*/
}
if (rc != 0) {
goto failed;
}
/*
* grab the major_t related information
*/
/* Out of memory */
"_raw_open: cannot alloc major number structure");
goto failed;
}
return (rc);
return (rc);
}
static int
{
int cd;
if (_nsc_raw_maxdevs != 0) {
return (cd);
}
}
return (-1);
}
/*
* _raw_close
*
* Multiple opens, single close.
*/
static int
{
int rc;
int cd;
return (EIO);
}
cred = ddi_get_cred();
if (rc != 0) {
return (rc);
}
return (0);
}
/* ARGSUSED */
static int
{
}
/* ARGSUSED */
static int
{
}
static int
{
return (NULL);
}
}
static int
{
int cd;
return (EIO);
return (0);
}
/*
* Return largest i/o size.
*/
/* ARGSUSED */
static int
{
if (flag == NSC_CACHEBLK)
*ptr = 1;
else {
if (nsc_rawmaxfbas == 0) {
}
*ptr = nsc_rawmaxfbas;
}
return (0);
}
/*
* Control device or system.
*/
/* ARGSUSED */
static int
{
#ifdef DEBUG
#endif
return (EINVAL); /* no control commands understood */
}
static int
{
#ifdef DKIOCPARTITION
#endif
int flags;
int rval;
*partitionp = -1;
*bsizep = 0;
return (-1);
return (-1);
}
return (-1);
}
return (-1);
}
cred = ddi_get_cred();
/* DKIOCINFO */
if (rc != 0) {
goto out;
}
/* return partition number */
/* DKIOCGVTOC */
if (rc) {
/* DKIOCGVTOC failed, but there might be an EFI label */
rc = -1;
#ifdef DKIOCPARTITION
/* do we have an EFI partition table? */
/* DKIOCPARTITION */
if (rc == 0) {
/* found EFI, return size */
} else {
/* both DKIOCGVTOC and DKIOCPARTITION failed - error */
rc = -1;
}
#endif
goto out;
}
rc = -1;
goto out;
}
rc = 0;
out:
if (dki_info) {
}
if (vtoc) {
}
#ifdef DKIOCPARTITION
if (p64) {
}
#endif
return (rc);
}
/*
* Ugly, ugly, ugly.
*
* Some volume managers (Veritas) don't support layered ioctls
* (no FKIOCTL support, no DDI_KERNEL_IOCTL property defined) AND
* do not support the properties for bdev_Size()/bdev_size().
*
* If the underlying driver has specified DDI_KERNEL_IOCTL, then we use
* the FKIOCTL technique. Otherwise ...
*
* The only reliable way to get the partition size, is to bounce the
* command through user land (nskernd).
*
* Then, SunCluster PXFS blocks access at the vnode level to device
* nodes during failover / switchover, so a read_vtoc() function call
* from user land deadlocks. So, we end up coming back into the kernel
* to go directly to the underlying device driver - that's what
* nskern_bsize() is doing below.
*
* There has to be a better way ...
*/
static int
{
return (EIO);
/* try the in-kernel way */
if (rc == 0) {
return (0);
}
/* fallback to the the slow way */
if (rc == 0) {
}
}
static int
{
int cd;
return (EIO);
}
/*
* See the comment above _raw_init_dev().
*/
int
{
int errno = 0;
int flag;
int cd;
*rvp = 0;
return (EINVAL);
return (EIO);
cred = ddi_get_cred();
/*
* ddi_mmap_get_model() returns the model for this user thread
* which is what we want - get_udatamodel() is not public.
*/
/* DKIOCINFO */
if (errno) {
return (errno);
}
/* DKIOCGVTOC */
if (errno) {
return (errno);
}
} else {
#ifdef DKIOCPARTITION
/* do we have an EFI partition table? */
if (errno) {
return (errno);
}
#endif
}
return (0);
}
/*
* Private function for sv to use.
*/
int
{
return (EIO);
return (0);
}
if (rc != 0 || *partitionp < 0) {
return (EIO);
}
return (0);
}
"Provide", NSC_DEVICE, 0,
0, 0, 0
};