root/usr/src/uts/common/xen/io/xdb.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_XDB_H
#define _SYS_XDB_H

#ifdef __cplusplus
extern "C" {
#endif

#define XDB_DBG_ALL     0xf
#define XDB_DBG_IO      0x1
#define XDB_DBG_INFO    0x2
#define XDB_DBPRINT(lvl, fmt) { if (xdb_debug & lvl) cmn_err fmt; }

/*
 * Info of the exported blk device
 */
#define XDB_DEV_RO      (1 << 0) /* backend and frontend are read-only */
#define XDB_DEV_BE_LOFI (1 << 1) /* backend device is a lofi device */
#define XDB_DEV_BE_RMB  (1 << 2) /* backend device is removable */
#define XDB_DEV_BE_CD   (1 << 3) /* backend device is cdrom */
#define XDB_DEV_FE_CD   (1 << 4) /* frontend device is cdrom */

#define XDB_IS_RO(vdp)          ((vdp)->xs_type & XDB_DEV_RO)
#define XDB_IS_BE_LOFI(vdp)     ((vdp)->xs_type & XDB_DEV_BE_LOFI)
#define XDB_IS_BE_RMB(vdp)      ((vdp)->xs_type & XDB_DEV_BE_RMB)
#define XDB_IS_BE_CD(vdp)       ((vdp)->xs_type & XDB_DEV_BE_CD)
#define XDB_IS_FE_CD(vdp)       ((vdp)->xs_type & XDB_DEV_FE_CD)

/*
 * Other handy macrosx
 */
#define XDB_MINOR2INST(m)       (int)(m)
#define XDB_INST2MINOR(i)       (minor_t)(i)
#define XDB_INST2SOFTS(instance)                        \
        ((xdb_t *)ddi_get_soft_state(xdb_statep, (instance)))
#define XDB_MAX_IO_PAGES(v) ((v)->xs_nentry * BLKIF_MAX_SEGMENTS_PER_REQUEST)
/* get kva of a mapped-in page coresponding to (xreq-index, seg) pair */
#define XDB_IOPAGE_VA(_pagebase, _xreqidx, _seg)        \
        ((_pagebase) + ((_xreqidx)                      \
        * BLKIF_MAX_SEGMENTS_PER_REQUEST                \
        + (_seg)) * PAGESIZE)
#define XDB_XREQ2BP(xreq) (&(xreq)->xr_buf)
#define XDB_BP2XREQ(bp) \
        ((xdb_request_t *)((char *)(bp) - offsetof(xdb_request_t, xr_buf)))

/* describe one blkif segment */
typedef struct xdb_seg {
        uint8_t fs; /* start sector # within this page (segment) */
        uint8_t ls; /* end sector # within this page (segment) */
} xdb_seg_t;

typedef struct xdb xdb_t;

/* one blkif_request_t matches one xdb_request_t */
typedef struct xdb_request {
        /* buf associated with this I/O request */
        buf_t           xr_buf;
        /* softstate instance associated with this I/O request */
        xdb_t           *xr_vdp;
        /* the next segment we're going to process */
        int             xr_curseg;
        /* index of this xdb_request_t in vdp->xs_req */
        int             xr_idx;
        /* next index for a statical linked list */
        int             xr_next;
        /* 'id' copied from blkif_request_t */
        uint64_t        xr_id;
        /* 'operation' copied from blkif_request_t */
        uint8_t         xr_op;
        /* how many pages(segments) in this I/O request */
        uint8_t         xr_buf_pages;
        /* all segments of this I/O request */
        xdb_seg_t       xr_segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        /* all grant table handles used in this I/O request */
        grant_handle_t  xr_page_hdls[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        struct page     xr_plist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        struct page     *xr_pplist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
} xdb_request_t;

/* Soft state data structure for each backend vbd */
struct xdb {
        /* devinfo node pointer of this xdb */
        dev_info_t      *xs_dip;
        /* coresponding frontend domain id */
        domid_t         xs_peer;
        /* read-only, removable, cdrom? */
        uint32_t        xs_type;
        /* # of total sectors */
        uint64_t        xs_sectors;
        /* sector size if existed */
        uint_t          xs_sec_size;
        /* blkif I/O request ring buffer */
        xendev_ring_t   *xs_ring;
        /* handle to access the ring buffer */
        ddi_acc_handle_t xs_ring_hdl;
        ldi_ident_t     xs_ldi_li;
        ldi_handle_t    xs_ldi_hdl;
        /* base kva for mapped-in I/O page from frontend domain */
        caddr_t         xs_iopage_va;
        /* mutex lock for I/O related code path */
        kmutex_t        xs_iomutex;
        /*
         * mutex lock for event handling related code path
         * need to be grabbed before xs_iomutex
         */
        kmutex_t        xs_cbmutex;
        /* # of on-going I/O buf in backend domain */
        uint_t          xs_ionum;
        /* task thread for pushing buf to underlying target driver */
        ddi_taskq_t     *xs_iotaskq;
        /* cv used in I/O code path, protected by xs_iomutex */
        kcondvar_t      xs_iocv;
        kcondvar_t      xs_ionumcv;
        /*
         * head and tail of linked list for I/O bufs need to be pushed to
         * underlying target driver
         */
        buf_t           *xs_f_iobuf;
        buf_t           *xs_l_iobuf;
        /* head of free list of xdb_request_t */
        int             xs_free_req;
        /* pre-allocated xdb_request_t pool */
        xdb_request_t   *xs_req;
        kstat_t         *xs_kstats;
        uint64_t        xs_stat_req_reads;
        uint64_t        xs_stat_req_writes;
        uint64_t        xs_stat_req_barriers;
        uint64_t        xs_stat_req_flushes;
        enum blkif_protocol xs_blk_protocol;
        size_t          xs_nentry;
        size_t          xs_entrysize;

        /* Protected by xs_cbmutex */
        boolean_t       xs_hp_connected;        /* hot plug scripts have run */
        boolean_t       xs_fe_initialised;      /* frontend is initialized */
        char                    *xs_lofi_path;
        char                    *xs_params_path;
        struct xenbus_watch     *xs_watch_params;
        struct xenbus_watch     *xs_watch_media_req;
        ddi_taskq_t             *xs_watch_taskq;
        int                     xs_watch_taskq_count;

        /* Protected by xs_cbmutex and xs_iomutex */
        boolean_t       xs_if_connected;        /* connected to frontend */

        /* Protected by xs_iomutex */
        boolean_t       xs_send_buf;

#ifdef DEBUG
        uint64_t *page_addrs; /* for debug aid */
#endif /* DEBUG */
};

#ifdef __cplusplus
}
#endif

#endif  /* _SYS_XDB_H */