/*
* 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.
*/
#include "safestore.h"
#include "safestore_impl.h"
#include "sd_trace.h"
typedef struct safestore_modules_s {
int ss_initialized;
void ss_ram_init();
void ss_ram_deinit();
/* CSTYLED */
/**#
* initialize the safestore subsystem and all safestore
* modules by calling all safestore modules' initialization functions
*
* NOTE: This function must be called with the _sdbc_config_lock held
*
* @param none
* @return void
*
*/
void
sst_init()
{
/*
* initialize the ss modules we know about
* this results in calls to sst_register_mod()
*/
if (ss_initialized != SS_INITTED) {
ss_ram_init();
}
}
/* CSTYLED */
/**#
* deinitialize the safestore subsystem and all safestore modules
* by calling all safestore modules' deinitialization functions
*
* NOTE: This function must be called with the _sdbc_config_lock held
*
* @param none
* @return void
*
*/
void
{
if (ss_initialized == SS_INITTED) {
ss_initialized = 0;
}
}
/* BEGIN CSTYLED */
/**#
* called by a safestore module to register its ops table
* for use by clients
*
* @param ss_ops structure of safestore functions
* @return void
*
* @see safestore_ops_t{}
*/
void
{
ss_modules = new;
}
/* BEGIN CSTYLED */
/**#
* called by a safestore module to unregister its ops table
* @param ss_ops structure of safestore functions
*
* @return void
*
* @see safestore_ops_t{}
*/
void
{
int found = 0;
if (!prev)
else
++found;
break;
}
}
if (!found)
"ss module %p not found", (void *)ss_ops);
}
/* BEGIN CSTYLED */
/**#
* open a safestore module for use by a client
* @param ss_type specifies a valid media type and transport type.
* the first module found that supports these reqested type
* is used. may contain more than one media type or transport
* type if client has no preference among several types.
* more than one ss_type may be specified in the call if
* client has an ordered preference.
*
* @return safestore_ops_t * pointer to a valid safestore ops structure
* if the request is satisfied.
* NULL otherwise
*
* @see safestore_ops_t{}
* @see SS_M_RAM
* @see SS_M_NV_SINGLENODE
* @see SS_M_NV_DUALNODE_NOMIRROR
* @see SS_M_NV_DUALNODE_MIRROR
* @see SS_T_STE
* @see SS_T_RPC
* @see SS_T_NONE
*/
{
return (NULL);
do {
return (ssm->ssm_module);
}
}
return (NULL);
}
/* BEGIN CSTYLED */
/**#
* close a safestore module. called when client no longer wishes to use
* a safestore module
*
* @param ssp points to a safestore_ops_t obtained from a previous call
* to sst_open()
*
* @return SS_OK if successful
* SS_ERR otherwise
*/
/*ARGSUSED*/
int
{
return (SS_OK);
}
/*
* _sdbc_writeq_configure - configure the given writeq
* Allocate the lock and sv we need to maintain waiters
*
*/
int
{
int i;
wrq->wq_slp_top = 0;
wrq->wq_slp_index = 0;
wrq->wq_slp_inq = 0;
for (i = 0; i < SD_WR_SLP_Q_MAX; i++) {
}
return (0);
}
/*
* _sdbc_writeq_deconfigure - deconfigure the given writeq
* Deallocate the lock and sv if present.
*
*/
void
{
int i;
if (wrq) {
for (i = 0; i < SD_WR_SLP_Q_MAX; i++) {
}
}
}
{
int i;
int aged = 0;
if (_sd_wblk_sync && (q->wq_inq == 0))
return (NULL); /* do sync write if queue empty */
if (need <= 0) {
return (NULL);
}
mutex_enter(&(q->wq_qlock));
if (!_sd_wblk_sync) {
unsigned stime;
/*
* Try to keep requests ordered so large requests
* are not starved. We can queue 255 write requests,
* After That go into write-through.
*/
if (q->wq_slp_inq < SD_WR_SLP_Q_MAX) {
q->wq_slp_inq++;
/* give preference to aged requests */
if (aged) {
WQ_SVWAIT_TOP(q, need);
} else {
WQ_SVWAIT_BOTTOM(q, need);
}
aged++;
} else {
mutex_exit(&(q->wq_qlock));
return (NULL);
}
(void) (*stall)++;
goto retry_wr_get;
}
} else {
ss_wr_cctl_t *, wctl);
for (i = 1; i < need; ++i) {
ss_wr_cctl_t *, wctl);
}
}
mutex_exit(&(q->wq_qlock));
return (ret);
}
/*
* ss_release_write - put a write block back in the writeq.
*
* ARGUMENTS:
* wctl - Write control block to be release.
* q - write q to put the wctl
*
* RETURNS: NONE
*/
void
{
ss_wr_cctl_t *, wctl);
#if defined(_SD_DEBUG)
}
#endif
mutex_enter(&q->wq_qlock);
q->wq_inq++;
if (WQ_NEED_SIG(q)) {
q->wq_slp_inq--;
WQ_SVSIG(q);
}
mutex_exit(&q->wq_qlock);
}