root/usr/src/uts/common/io/scsi/targets/sd_xbuf.h
/*
 * 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
 * or http://www.opensolaris.org/os/licensing.
 * 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 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_SCSI_TARGETS_SD_XBUF_H
#define _SYS_SCSI_TARGETS_SD_XBUF_H

#ifdef  __cplusplus
extern "C" {
#endif

#if     defined(_KERNEL) || defined(_KMEMUSER)

#include <sys/note.h>
#include <sys/taskq.h>


#if (defined(__fibre))
/*
 * These #defines are to avoid namespace collisions that occur because this
 * code is currently used to compile two seperate driver modules: sd and ssd.
 * All function names need to be treated this way (even if declared static)
 * in order to allow the debugger to resolve the names properly.
 * It is anticipated that in the near future the ssd module will be obsoleted,
 * at which time this ugliness should go away.
 */
#define ddi_xbuf_attr_create            ssd_ddi_xbuf_attr_create
#define ddi_xbuf_attr_destroy           ssd_ddi_xbuf_attr_destroy
#define ddi_xbuf_attr_register_devinfo  ssd_ddi_xbuf_attr_register_devinfo
#define ddi_xbuf_attr_unregister_devinfo        \
                                        ssd_ddi_xbuf_attr_unregister_devinfo
#define ddi_xbuf_qstrategy              ssd_ddi_xbuf_qstrategy
#define ddi_xbuf_done                   ssd_ddi_xbuf_done
#define ddi_xbuf_get                    ssd_ddi_xbuf_get
#define xbuf_iostart                    ssd_xbuf_iostart
#define xbuf_dispatch                   ssd_xbuf_dispatch
#define xbuf_restart_callback           ssd_xbuf_restart_callback
#define xbuf_tq                         ssd_xbuf_tq
#define xbuf_attr_tq_minalloc           ssd_xbuf_attr_tq_minalloc
#define xbuf_attr_tq_maxalloc           ssd_xbuf_attr_tq_maxalloc
#define xbuf_mutex                      ssd_xbuf_mutex
#define xbuf_refcount                   ssd_xbuf_refcount

#define ddi_xbuf_dispatch               ssd_ddi_xbuf_dispatch

#define ddi_xbuf_flushq                 ssd_ddi_xbuf_flushq
#define ddi_xbuf_attr_setup_brk         ssd_ddi_xbuf_attr_setup_brk

#endif


typedef void *          ddi_xbuf_t;


/*
 * Primary attribute struct for buf extensions.
 */
struct __ddi_xbuf_attr {
        kmutex_t        xa_mutex;
        size_t          xa_allocsize;
        uint32_t        xa_pending;     /* call to xbuf_iostart() is iminent */
        uint32_t        xa_active_limit;
        uint32_t        xa_active_count;
        uint32_t        xa_active_lowater;
        struct buf      *xa_headp;      /* FIFO buf queue head ptr */
        struct buf      *xa_tailp;      /* FIFO buf queue tail ptr */
        kmutex_t        xa_reserve_mutex;
        uint32_t        xa_reserve_limit;
        uint32_t        xa_reserve_count;
        void            *xa_reserve_headp;
        void            (*xa_strategy)(struct buf *, ddi_xbuf_t, void *);
        void            *xa_attr_arg;
        timeout_id_t    xa_timeid;
        taskq_t         *xa_tq;
        struct buf      *xa_flush_headp;
        struct buf      *xa_flush_tailp;
        size_t          xa_brksize;
};


typedef struct __ddi_xbuf_attr  *ddi_xbuf_attr_t;

#define DDII

DDII   ddi_xbuf_attr_t ddi_xbuf_attr_create(size_t xsize,
        void (*xa_strategy)(struct buf *bp, ddi_xbuf_t xp, void *attr_arg),
        void *attr_arg, uint32_t active_limit, uint32_t reserve_limit,
        major_t major, int flags);
DDII   void ddi_xbuf_attr_destroy(ddi_xbuf_attr_t xap);
DDII   void ddi_xbuf_attr_register_devinfo(ddi_xbuf_attr_t xbuf_attr,
        dev_info_t *dip);
DDII   void ddi_xbuf_attr_unregister_devinfo(ddi_xbuf_attr_t xbuf_attr,
        dev_info_t *dip);
DDII   int ddi_xbuf_qstrategy(struct buf *bp, ddi_xbuf_attr_t xap);
DDII   int ddi_xbuf_done(struct buf *bp, ddi_xbuf_attr_t xap);
DDII   ddi_xbuf_t ddi_xbuf_get(struct buf *bp, ddi_xbuf_attr_t xap);
DDII   void ddi_xbuf_dispatch(ddi_xbuf_attr_t xap);
DDII   void ddi_xbuf_flushq(ddi_xbuf_attr_t xap, int (*funcp)(struct buf *));
DDII   int ddi_xbuf_attr_setup_brk(ddi_xbuf_attr_t xap, size_t size);


/*
 * The buf extension facility utilizes an internal pool of threads to perform
 * callbacks into the given xa_strategy routines.  Clients of the facility
 * do not need to be concerned with the management of these threads as this is
 * handled by the framework.  However clients may recommend certain operational
 * parameters for the framework to consider in performing its thread mangement
 * by specifying one of the following flags to ddi_xbuf_attr_create():
 *
 * DDI_XBUF_QTHREAD_SYSTEM: This should be specified when the client driver
 * provides an xa_strategy routine that is "well behaved", ie, does not
 * block for memory, shared resources, or device states that may take a long
 * or indeterminate amount of time to satisfy. The 'major' argument to
 * ddi_xbuf_attr_create() may be zero if this flag is specified. (?)
 *
 * DDI_XBUF_QTHREAD_DRIVER: This should be specified when the client driver
 * performs blocking operations within its xa_strategy routine that would
 * make it unsuitable for being called from a shared system thread.  The
 * 'major' argument to ddi_xbuf_attr_create() must be the return value of
 * ddi_driver_major() when this flag is specified.
 *
 * DDI_XBUF_QTHREAD_PRIVATE: This should be specified when the client driver
 * would prefer to have a dedicated thread for a given ddi_xbuf_attr_t
 * instantiation. The 'major' argument to ddi_xbuf_attr_create() must be
 * the return value of ddi_driver_major() when this flag is specified. Note
 * that this option ought to be used judiciously in order to avoid excessive
 * consumption of system resources, especially if the client driver has a
 * large number of ddi_xbuf_attr_t instantiations.
 *
 * Note that the above flags are mutually exclusive.  Also note that the
 * behaviors specified by these flags are merely advisory to the framework,
 * and the framework is still free to implement its internal thread management
 * policies as necessary and that these policies are opaque to drivers.
 */

#define DDI_XBUF_QTHREAD_SYSTEM         0x01
#define DDI_XBUF_QTHREAD_DRIVER         0x02
#define DDI_XBUF_QTHREAD_PRIVATE        0x04


#endif  /* defined(_KERNEL) || defined(_KMEMUSER) */


#ifdef  __cplusplus
}
#endif


#endif  /* _SYS_SCSI_TARGETS_SD_XBUF_H */