#ifndef _SYS_XDF_H
#define _SYS_XDF_H
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/cmlb.h>
#include <sys/dkio.h>
#include <sys/gnttab.h>
#include <xen/sys/xendev.h>
#ifdef __cplusplus
extern "C" {
#endif
#define XB_BSIZE DEV_BSIZE
#define XB_BMASK (XB_BSIZE - 1)
#define XB_BSHIFT 9
#define XB_DTOB(bn, vdp) ((bn) * (vdp)->xdf_xdev_secsize)
#define XB_MAX_SEGLEN (8 * XB_BSIZE)
#define XB_SEGOFFSET (XB_MAX_SEGLEN - 1)
#define XB_MAX_XFER (XB_MAX_SEGLEN * BLKIF_MAX_SEGMENTS_PER_REQUEST)
#define XB_MAXPHYS (XB_MAX_XFER * BLKIF_RING_SIZE)
#define XB_NUM_SECTORS_PER_SEG (PAGESIZE / XB_BSIZE)
#define XB_LAST_SECTOR_IN_SEG (XB_NUM_SECTORS_PER_SEG - 1)
#define XB_SLICE_NONE 0xFF
typedef enum xdf_state {
XD_UNKNOWN = 0,
XD_INIT = 1,
XD_CONNECTED = 2,
XD_READY = 3,
XD_CLOSING = 4,
XD_CLOSED = 5,
XD_SUSPEND = 6
} xdf_state_t;
#define XDF_PSHIFT 6
#define XDF_PMASK ((1 << XDF_PSHIFT) - 1)
#define XDF_PEXT (1 << XDF_PSHIFT)
#define XDF_MINOR(i, m) (((i) << XDF_PSHIFT) | (m))
#define XDF_INST(m) ((m) >> XDF_PSHIFT)
#define XDF_PART(m) ((m) & XDF_PMASK)
typedef struct ge_slot {
list_node_t gs_vreq_link;
struct v_req *gs_vreq;
domid_t gs_oeid;
int gs_isread;
grant_ref_t gs_ghead;
int gs_ngrefs;
grant_ref_t gs_ge[BLKIF_MAX_SEGMENTS_PER_REQUEST];
} ge_slot_t;
typedef struct v_req {
list_node_t v_link;
list_t v_gs;
int v_status;
buf_t *v_buf;
uint_t v_ndmacs;
uint_t v_dmaw;
uint_t v_ndmaws;
uint_t v_nslots;
uint64_t v_blkno;
ddi_dma_handle_t v_memdmahdl;
ddi_acc_handle_t v_align;
ddi_dma_handle_t v_dmahdl;
ddi_dma_cookie_t v_dmac;
caddr_t v_abuf;
uint8_t v_flush_diskcache;
boolean_t v_runq;
} v_req_t;
#define VREQ_INIT 0x0
#define VREQ_INIT_DONE 0x1
#define VREQ_DMAHDL_ALLOCED 0x2
#define VREQ_MEMDMAHDL_ALLOCED 0x3
#define VREQ_DMAMEM_ALLOCED 0x4
#define VREQ_DMABUF_BOUND 0x5
#define VREQ_GS_ALLOCED 0x6
#define VREQ_DMAWIN_DONE 0x7
typedef struct xdf {
dev_info_t *xdf_dip;
char *xdf_addr;
ddi_iblock_cookie_t xdf_ibc;
domid_t xdf_peer;
xendev_ring_t *xdf_xb_ring;
ddi_acc_handle_t xdf_xb_ring_hdl;
list_t xdf_vreq_act;
buf_t *xdf_f_act;
buf_t *xdf_l_act;
buf_t *xdf_i_act;
xdf_state_t xdf_state;
boolean_t xdf_suspending;
ulong_t xdf_vd_open[OTYPCNT];
ulong_t xdf_vd_lyropen[XDF_PEXT];
ulong_t xdf_connect_req;
kthread_t *xdf_connect_thread;
ulong_t xdf_vd_exclopen;
kmutex_t xdf_iostat_lk;
kmutex_t xdf_dev_lk;
kmutex_t xdf_cb_lk;
kcondvar_t xdf_dev_cv;
uint_t xdf_dinfo;
diskaddr_t xdf_xdev_nblocks;
uint_t xdf_xdev_secsize;
cmlb_geom_t xdf_pgeom;
boolean_t xdf_pgeom_set;
boolean_t xdf_pgeom_fixed;
kstat_t *xdf_xdev_iostat;
cmlb_handle_t xdf_vd_lbl;
ddi_softintr_t xdf_softintr_id;
timeout_id_t xdf_timeout_id;
struct gnttab_free_callback xdf_gnt_callback;
boolean_t xdf_feature_barrier;
boolean_t xdf_flush_supported;
boolean_t xdf_media_req_supported;
boolean_t xdf_wce;
boolean_t xdf_cmlb_reattach;
char *xdf_flush_mem;
char *xdf_cache_flush_block;
int xdf_evtchn;
enum dkio_state xdf_mstate;
kcondvar_t xdf_mstate_cv;
kcondvar_t xdf_hp_status_cv;
struct buf *xdf_ready_bp;
ddi_taskq_t *xdf_ready_tq;
kthread_t *xdf_ready_tq_thread;
struct buf *xdf_ready_tq_bp;
ddi_devid_t xdf_tgt_devid;
#ifdef DEBUG
int xdf_dmacallback_num;
kthread_t *xdf_oe_change_thread;
#endif
} xdf_t;
#define ALIGNED_XFER(bp) \
((((uintptr_t)((bp)->b_un.b_addr) & XB_BMASK) == 0) && \
(((bp)->b_bcount & XB_BMASK) == 0))
#define U_INVAL(u) (((u)->uio_loffset & (offset_t)(XB_BMASK)) || \
((u)->uio_iov->iov_len & (offset_t)(XB_BMASK)))
#define PATOMA(addr) (DOMAIN_IS_INITDOMAIN(xen_info) ? addr : pa_to_ma(addr))
#define XD_IS_RO(vbd) VOID2BOOLEAN((vbd)->xdf_dinfo & VDISK_READONLY)
#define XD_IS_CD(vbd) VOID2BOOLEAN((vbd)->xdf_dinfo & VDISK_CDROM)
#define XD_IS_RM(vbd) VOID2BOOLEAN((vbd)->xdf_dinfo & VDISK_REMOVABLE)
#define IS_READ(bp) VOID2BOOLEAN((bp)->b_flags & B_READ)
#define IS_ERROR(bp) VOID2BOOLEAN((bp)->b_flags & B_ERROR)
#define XDF_UPDATE_IO_STAT(vdp, bp) \
{ \
kstat_io_t *kip = KSTAT_IO_PTR((vdp)->xdf_xdev_iostat); \
size_t n_done = (bp)->b_bcount - (bp)->b_resid; \
if ((bp)->b_flags & B_READ) { \
kip->reads++; \
kip->nread += n_done; \
} else { \
kip->writes++; \
kip->nwritten += n_done; \
} \
}
#ifdef DEBUG
#define DPRINTF(flag, args) {if (xdf_debug & (flag)) prom_printf args; }
#define SETDMACBON(vbd) {(vbd)->xdf_dmacallback_num++; }
#define SETDMACBOFF(vbd) {(vbd)->xdf_dmacallback_num--; }
#define ISDMACBON(vbd) ((vbd)->xdf_dmacallback_num > 0)
#else
#define DPRINTF(flag, args)
#define SETDMACBON(vbd)
#define SETDMACBOFF(vbd)
#define ISDMACBON(vbd)
#endif
#define DDI_DBG 0x1
#define DMA_DBG 0x2
#define INTR_DBG 0x8
#define IO_DBG 0x10
#define IOCTL_DBG 0x20
#define SUSRES_DBG 0x40
#define LBL_DBG 0x80
#ifdef XPV_HVM_DRIVER
extern int xdf_lb_getinfo(dev_info_t *, int, void *, void *);
extern int xdf_lb_rdwr(dev_info_t *, uchar_t, void *, diskaddr_t, size_t,
void *);
extern void xdfmin(struct buf *bp);
extern dev_info_t *xdf_hvm_hold(const char *);
extern boolean_t xdf_hvm_connect(dev_info_t *);
extern int xdf_hvm_setpgeom(dev_info_t *, cmlb_geom_t *);
extern boolean_t xdf_is_cd(dev_info_t *);
extern boolean_t xdf_is_rm(dev_info_t *);
extern boolean_t xdf_media_req_supported(dev_info_t *);
#endif
#ifdef __cplusplus
}
#endif
#endif