/*
* 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.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* STREAMS Administrative Driver
*
* Currently only handles autopush and module name verification.
*/
#include <sys/sysmacros.h>
static void apush_ioctl(), apush_iocdata();
static void vml_ioctl(), vml_iocdata();
static int valid_major(major_t);
};
};
};
};
/*
* Module linkage information for the kernel.
*/
&mod_driverops, /* Type of module. This one is a pseudo driver */
"STREAMS Administrative Driver 'sad'",
&sad_ops, /* driver ops */
};
};
int
_init(void)
{
return (mod_install(&modlinkage));
}
int
_fini(void)
{
return (mod_remove(&modlinkage));
}
int
{
}
static int
{
if (cmd != DDI_ATTACH)
return (DDI_FAILURE);
if (instance != 0)
return (DDI_FAILURE);
return (DDI_FAILURE);
}
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/* ARGSUSED */
static int
{
int error;
switch (infocmd) {
case DDI_INFO_DEVT2DEVINFO:
error = DDI_FAILURE;
} else {
error = DDI_SUCCESS;
}
break;
case DDI_INFO_DEVT2INSTANCE:
*result = (void *)0;
error = DDI_SUCCESS;
break;
default:
error = DDI_FAILURE;
}
return (error);
}
/*
* sadopen() -
* Allocate a sad device. Only one
* open at a time allowed per device.
*/
/* ARGSUSED */
static int
int flag, /* file open flags */
int sflag, /* stream open flags */
{
int i;
if (sflag) /* no longer called from clone driver */
return (EINVAL);
/* Only privileged process can access ADMINDEV */
int err;
if (err != 0)
return (err);
}
/*
* Both USRMIN and ADMMIN are clone interfaces.
*/
break;
return (ENXIO);
}
case USRMIN: /* mere mortal */
break;
case ADMMIN: /* privileged user */
break;
default:
return (EINVAL);
}
/*
* NOTE: should the ADMMIN or USRMIN minors change
* then so should the offset of 2 below
* Both USRMIN and ADMMIN are clone interfaces and
* therefore their minor numbers (0 and 1) are reserved.
*/
return (0);
}
/*
* sadclose() -
* Clean up the data structures.
*/
/* ARGSUSED */
static int
int flag, /* file open flags */
{
return (0);
}
/*
* sadwput() -
* Write side put procedure.
*/
static int
{
case M_FLUSH:
} else
break;
case M_IOCTL:
break;
case SAD_VML:
break;
default:
break;
}
break;
case M_IOCDATA:
break;
case SAD_VML:
break;
default:
"sadwput: invalid ioc_cmd in case M_IOCDATA: %d",
break;
}
break;
default:
break;
} /* switch (db_type) */
return (0);
}
/*
* apush_ioctl() -
* Handle the M_IOCTL messages associated with
* the autopush feature.
*/
static void
{
return;
}
return;
}
break;
}
/* FALLTHRU */
else
break;
default:
ASSERT(0);
break;
} /* switch (ioc_cmd) */
}
/*
* apush_iocdata() -
* Handle the M_IOCDATA messages associated with
* the autopush feature.
*/
static void
{
int i, ret;
return;
}
/*
* sap needed only if mp->b_cont is set. figure out the
* size of the expected sap structure and make sure
* enough data was supplied.
*/
else
return;
}
}
/* currently we only support one SAD_SAP command */
"apush_iocdata: cp_private bad in SAD_SAP: %p",
(void *)csp->cp_private);
return;
}
default:
return;
case SAP_ONE:
case SAP_RANGE:
case SAP_ALL:
/* allocate and initialize a new config */
ap = sad_ap_alloc();
/* sanity check the request */
return;
}
/* check for overlapping configs */
/* already configured */
return;
}
/* add the new config to our hash */
return;
case SAP_CLEAR:
/* sanity check the request */
return;
}
/* search for a matching config */
/* no config found */
return;
}
/*
* If we matched a SAP_RANGE config
* the minor passed in must match the
* beginning of the range exactly.
*/
return;
}
/*
* If we matched a SAP_ALL config
* the minor passed in must be 0.
*/
return;
}
/*
* make sure someone else hasn't already
* removed this config from the hash.
*/
return;
}
/* remove the config from the hash and return */
/*
* Release thrice, once for sad_ap_find_by_dev(),
* once for sad_ap_find(), and once to free.
*/
return;
} /* switch (sap_cmd) */
/*NOTREACHED*/
switch ((long)csp->cp_private) {
case GETSTRUCT:
/* sanity check the request */
return;
}
/* search for a matching config */
/* no config found */
return;
}
/* copy out the contents of the config */
for (; i < MAXAPUSH; i++)
/* release our hold on the config */
/* copyout the results */
else
NULL);
return;
case GETRESULT:
return;
default:
"apush_iocdata: cp_private bad case SAD_GAP: %p",
(void *)csp->cp_private);
return;
} /* switch (cp_private) */
/*NOTREACHED*/
default: /* can't happen */
ASSERT(0);
return;
} /* switch (cp_cmd) */
}
/*
* vml_ioctl() -
* Handle the M_IOCTL message associated with a request
* to validate a module list.
*/
static void
{
return;
}
}
/*
* vml_iocdata() -
* Handle the M_IOCDATA messages associated with
* a request to validate a module list.
*/
static void
{
long i;
int nmods;
return;
}
switch ((long)csp->cp_private) {
case GETSTRUCT:
if (nmods <= 0) {
break;
}
break;
case GETLIST:
return;
}
}
break;
default:
(void *)csp->cp_private);
break;
} /* switch (cp_private) */
}
/*
* Validate a major number and also verify if
* it is a STREAMS device.
* Return values: 0 if a valid STREAMS dev
* error code otherwise
*/
static int
{
int ret = 0;
return (EINVAL);
/*
* attempt to load the driver 'major' and verify that
* it is a STREAMS driver.
*/
return (EINVAL);
if (!STREAMSTAB(major))
return (ret);
}