/*
* 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.
*/
/* lint -w2 */
&mod_miscops, "RSMOPS module",
};
};
static int rsmops_threads_started = 0;
int
_init(void)
{
int err;
return (err);
}
int
_fini(void)
{
int err;
if (rsmops_drv_head) {
/* Somebody is still registered with us - we cannot unload */
return (EBUSY);
}
if (rsmops_threads_started) {
/*
* Some threads have been started. We do not have any
* well-supported way of checking whether they have all
* exited. For now, fail attempt to unload if we have
* ever started any threads. This is overkill, but ...
*/
return (EBUSY);
}
return (err);
}
int
{
}
static void
{
/* p_drv->ctrl_cnt has already been increased by the time we get here */
/* call the driver with the thread */
/* thread has returned */
}
/* This is expected to be called from the driver's init function */
int
{
rsmops_drv_t *p;
/* The driver is up-rev than me. Fail attempt to register */
return (RSMERR_BAD_DRIVER_VERSION);
}
/*
* RSM_VERSION: Since this is the first version, there cannot be any
* down-rev drivers - this will be an issue in the future
*/
return (RSMERR_BAD_DRIVER_VERSION);
/* First, search that this driver is not already registered */
while (*pp_tail) {
== 0) {
return (RSMERR_DRIVER_NAME_IN_USE);
}
}
p->ctrl_cnt = 0;
if (p->drv.rsm_thread_entry_pt) {
/* thread entry point is defined - we need to create a thread */
extern pri_t minclsyspri;
p->ctrl_cnt++; /* bump up the count right now */
} else
*pp_tail = p;
return (RSM_SUCCESS);
}
/*
* This is expected to be called from the driver's fini function
* if this function returns EBUSY, the driver is supposed to fail
* its own fini operation
*/
int
{
rsmops_drv_t *p;
/* Search for the driver */
while (*pp_tail) {
continue;
}
/* check ref count - if somebody is using it, return EBUSY */
return (RSMERR_CTLRS_REGISTERED);
}
/* Nobody is using it - we can allow the unregister to happen */
p = *pp_tail;
/* Stomp the guy out of our linked list */
/* release the memory */
kmem_free(p, sizeof (rsmops_drv_t));
return (RSM_SUCCESS);
}
/* Could not find the guy */
return (RSMERR_DRIVER_NOT_REGISTERED);
}
/* Should be called holding the rsmops_lock mutex */
static rsmops_drv_t *
{
/* the name is of the form "sci", "wci" etc */
return (p_rsmops_list);
}
}
return (NULL);
}
/* Should be called holding the rsmops_lock mutex */
static rsmops_ctrl_t *
{
rsmops_ctrl_t *p;
return (NULL);
return (p);
}
return (NULL);
}
/* Should be called holding the rsmops_lock mutex */
static rsmops_ctrl_t *
{
rsmops_ctrl_t *p;
if (p->handle == cntlr_handle)
return (p);
}
}
return (NULL);
}
static vnode_t *
int
{
int error;
int (*rsm_get_controller_handler)
/* check if the controller is already registered */
/*
* controller is not registered. We should try to load it
* First check if the driver is registered
*/
/* Cannot find the driver. Try to load him */
return (RSMERR_CTLR_NOT_PRESENT);
}
/*
* Cannot find yet - maybe the driver we loaded
* was not a RSMPI driver at all. We'll just
* fail this call.
*/
return (RSMERR_CTLR_NOT_PRESENT);
}
}
/*
* controller is not registered.
* try to do a VOP_OPEN to force it to get registered
*/
}
return (RSMERR_CTLR_NOT_PRESENT);
}
}
} else {
}
/*
* Increase the refcnt right now, so that attempts to deregister
* while we are using this entry will fail
*/
version);
if (error != RSM_SUCCESS) {
/* We failed - drop the refcnt back */
/*
* Even though we had released the global lock, we can
* guarantee that p_ctrl is still meaningful (and has not
* been deregistered, freed whatever) because we were holding
* refcnt on it. So, it is okay to just use p_ctrl here
* after re-acquiring the global lock
*/
} else {
/*
* Initialize the controller handle field
*/
return (RSMERR_CTLR_NOT_PRESENT);
}
}
return (error);
}
int
{
int error;
return (RSMERR_CTLR_NOT_PRESENT);
}
/* Found the appropriate driver. Forward the call to it */
if (error == RSM_SUCCESS) {
}
return (error);
}
/* This is expected to be called from the driver's attach function */
int
{
return (RSMERR_NAME_TOO_LONG);
/* Check if the driver is registered with us */
/*
* Hey! Driver is not registered, but we are getting a
* controller ??
*/
return (RSMERR_DRIVER_NOT_REGISTERED);
}
/* Check if the controller is already registered with us */
if (p_ctrl) {
/* already registered */
return (RSMERR_CTLR_ALREADY_REGISTERED);
}
/* WAIT: sanity check - verify that the dip matches up to name,number */
/* bump up controller count on the driver */
/* Now link to head of list */
return (RSM_SUCCESS);
}
/*
* This is expected to be called from the driver's detach function
* if this function returns EBUSY, the driver is supposed to fail
* his own detach operation
*/
int
{
/* Check if the driver is registered with us */
/* Hey! Driver is not registered */
return (RSMERR_DRIVER_NOT_REGISTERED);
}
/* Search for the controller in the list */
/* Found the controller. Check if it is busy */
/* Controller is busy - handles outstanding */
return (RSMERR_CTLR_IN_USE);
}
/* unlink it out */
/* bump down controller count on the driver */
return (RSM_SUCCESS);
}
}
/* Could not find the right controller */
return (RSMERR_CTLR_NOT_REGISTERED);
}
/*
* This opens and closes the appropriate device with minor number -
* hopefully, it will cause the driver to attach and register a controller
* with us
*/
static vnode_t *
{
int ret;
return (NULL);
}
return (NULL);
}
if (ret == 0) {
return (vp);
} else {
return (NULL);
}
}
/*
* Attributes for controller identified by the handle are returned
* via *attrp. Modifications of attributes is prohibited by client!
*/
int
{
return (RSMERR_BAD_CTLR_HNDL);
/* find controller */
/* can't supply attributes for invalid controller */
return (RSMERR_BAD_CTLR_HNDL);
}
return (RSM_SUCCESS);
}