/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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.
*/
/*
* Device Strategy
*/
/*
* Object Management
*/
int *can_merge);
&mod_miscops, /* Type of module */
"Device Strategy Objects"
};
&modlmisc,
};
int
_init(void)
{
return (mod_install(&modlinkage));
}
int
_fini(void)
{
return (mod_remove(&modlinkage));
}
int
{
}
/*
* Common Flow Control functions
*/
/*
* Local static data
*/
#ifdef FLC_DEBUG
static int flc_malloc_intr = 0;
#endif /* FLC_DEBUG */
void *lkarg);
static struct flc_obj *
{
if (!flcobjp)
return (NULL);
}
static int
{
return (DDI_SUCCESS);
}
static int
{
if (fcdp->ds_queobjp)
if (fcdp->ds_tgcomobjp) {
}
return (0);
}
/*ARGSUSED*/
static int
{
if (!flc_kstat)
return (0);
}
}
return (0);
}
static int
{
}
return (0);
}
/*
* Single Command per Device
*/
/*
* Local Function Prototypes
*/
static int dsngl_restart();
0, 0
};
struct flc_obj *
{
}
static int
{
if (!in_bp)
return (0);
}
return (0);
}
}
return (0);
}
return (0);
}
static int
{
if (in_bp) {
} else {
}
}
}
for (;;) {
return (0);
}
return (0);
}
}
static int
{
return (-1);
}
/*
* Multiple Commands per Device
*/
/*
* Local Function Prototypes
*/
static int dmult_restart();
0, 0
};
struct flc_obj *
{
}
/*
* Some of the object management functions QUE_ADD() and QUE_DEL()
* do not accquire lock.
* They depend on dmult_enque(), dmult_deque() to do all locking.
* If this changes we have to grab locks in qmerge_add() and qmerge_del().
*/
static int
{
if (!in_bp)
return (0);
}
return (0);
}
}
return (0);
}
return (0);
}
static int
{
if (in_bp) {
} else {
}
}
}
for (;;) {
#ifdef FLC_DEBUG
#endif
return (0);
}
return (0);
}
}
static int
{
return (-1);
}
/*
* Duplexed Commands per Device: Read Queue and Write Queue
*/
/*
* Local Function Prototypes
*/
static int duplx_restart();
void *lkarg);
0, 0
};
struct flc_obj *
{
if (!flcobjp)
return (NULL);
return (NULL);
}
return (flcobjp);
}
static int
{
}
if (fcdp->ds_tgcomobjp) {
}
return (0);
}
static int
{
/* queues point to each other for round robin */
return (DDI_SUCCESS);
}
static int
{
if (in_bp) {
}
else
} else {
}
for (;;) {
return (0);
}
}
return (0);
}
}
static int
{
else
} else {
}
}
for (;;) {
/* if needed, try to pull request off a queue */
return (0);
}
}
return (0);
}
}
static int
{
return (-1);
}
/*
* Tagged queueing flow control
*/
/*
* Local Function Prototypes
*/
0, 0
};
struct flc_obj *
{
}
/*
* Common Queue functions
*/
/*
* Local static data
*/
#ifdef Q_DEBUG
#endif /* Q_DEBUG */
/*
* Local Function Prototypes
*/
static struct que_obj *
{
if (!queobjp)
return (NULL);
}
static int
{
return (DDI_SUCCESS);
}
static int
{
return (0);
}
static struct buf *
{
if (bp) {
}
return (bp);
}
/*
* Qmerge
* Local Function Prototypes
*/
static int qmerge_add(), qmerge_free();
0, 0
};
/* fields in diskhd */
/*
* qmerge implements a two priority queue, the low priority queue holding ASYNC
* write requests, while the rest are queued in the high priority sync queue.
* Requests on the async queue would be merged if possible.
* By default qmerge2wayscan is 1, indicating an elevator algorithm. When
* this variable is set to zero, it has the following side effects.
* 1. We assume fairness is the number one issue.
* 2. The next request to be picked indicates current head position.
*
* qmerge_sync2async indicates the ratio of scans of high prioriy
* sync queue to low priority async queue.
*
* When qmerge variables have the following values it defaults to qsort
*
* qmerge1pri = 1, qmerge2wayscan = 0, qmerge_max_merge = 0
*
*/
static int qmerge1pri = 0;
static int qmerge_merge = 0;
/*
* Local static data
*/
struct que_obj *
{
if (!queobjp)
return (NULL);
}
static int
{
return (0);
}
static int
{
return (0);
return (1);
else
return (0);
}
static void
{
int forward;
qmerge_merge++;
if (!forward) {
}
}
static void
{
/*
* The ioctl used by the format utility requires that bp->av_back be
* preserved.
*/
if (!qmerge1pri &&
} else {
}
if (*async_bpp) {
}
}
return;
}
do {
}
}
return;
}
}
} else {
highest_bp = bp1;
do {
}
}
return;
highest_bp = bp1;
}
}
}
/*
* dmult_enque() holds dmultp->ds_mutex lock, so we dont grab
* lock here. If dmult_enque() changes we will have to visit
* this function again
*/
static int
{
}
static int
{
do {
}
return (0);
}
static struct buf *
{
int flags;
return (NULL);
}
if (flags & QNEAR_ASYNCONLY) {
return (NULL);
private = 0;
} else if (flags & QNEAR_BACKWARD) {
flags &= ~QNEAR_BACKWARD;
private = 0;
}
if (qmerge2wayscan) {
flags |= QNEAR_BACKWARD;
} else {
private = 0;
}
} else if (qmerge2wayscan == 0) {
}
} else if (flags & QNEAR_ASYNCALSO) {
if (flags & QNEAR_BACKWARD) {
goto begin_nextbp;
}
} else {
}
} else {
}
} else {
if (qmerge2wayscan) {
flags |= QNEAR_BACKWARD;
goto begin_nextbp;
} else {
flags &= ~QNEAR_ASYNCALSO;
SYNC2ASYNC(qfp) =
(void *)qmerge_sync2async;
goto begin_nextbp;
}
}
} else {
}
} else {
}
}
return (NULL);
flags &= ~QNEAR_ASYNCALSO;
} else {
flags |= QNEAR_ASYNCONLY;
}
}
} else {
return (NULL);
private = 0;
flags &= ~QNEAR_BACKWARD;
if (*async_bpp)
flags |= QNEAR_ASYNCONLY;
} else if (flags & QNEAR_BACKWARD) {
flags &= ~QNEAR_BACKWARD;
if (cnt > 0) {
cnt--;
} else {
if (*async_bpp)
flags |= QNEAR_ASYNCALSO;
SYNC2ASYNC(qfp) =
(void *)qmerge_sync2async;
}
private = 0;
}
private = 0;
if (qmerge2wayscan) {
flags |= QNEAR_BACKWARD;
} else {
if (cnt > 0) {
cnt--;
} else {
if (*async_bpp)
flags |= QNEAR_ASYNCALSO;
SYNC2ASYNC(qfp) =
(void *)qmerge_sync2async;
}
}
} else if (qmerge2wayscan == 0) {
}
}
if (flags & QNEAR_BACKWARD) {
*can_merge = 0;
} else {
*can_merge = 0;
}
} else {
*can_merge = 0;
}
}
return (bp);
}
static struct buf *
{
return (NULL);
}
alloc_mergebp = 1;
if (alloc_mergebp) {
return (bp);
}
alloc_mergebp = 0;
}
}
return (bp_merge);
}
/*
* FIFO Queue functions
*/
/*
* Local Function Prototypes
*/
static int qfifo_add();
0, 0
};
/*
* Local static data
*/
struct que_obj *
{
}
static int
{
else
return (0);
}
/*
* One-Way-Scan Queue functions
*/
/*
* Local Function Prototypes
*/
static int qsort_add();
0, 0
};
/*
* Local static data
*/
struct que_obj *
{
}
static int
{
return (0);
}
static void
{
return;
}
return;
}
}
break;
}
}
static struct buf *
{
return (NULL);
}
}
return (bp);
}
/*
* Tagged queueing
*/
/*
* Local Function Prototypes
*/
0, 0
};
/*
* Local static data
*/
struct que_obj *
{
}