xdf.h revision ee56d0c81901bbe996dc0aa42265e53824979adf
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_XDF_H
#define _SYS_XDF_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* VBDs have standard 512 byte blocks
*/
#define XB_BSHIFT 9
/* Number of sectors per segement */
/* sectors are number 0 through XB_NUM_SECTORS_PER_SEG - 1 */
/*
* Slice for absolute disk transaction.
*
* Hack Alert. XB_SLICE_NONE is a magic value that can be written into the
* b_private field of buf structures passed to xdf_strategy(). When present
* it indicates that the I/O is using an absolute offset. (ie, the I/O is
* not bound to any one partition.) This magic value is currently used by
* the pv_cmdk driver. This hack is shamelessly stolen from the sun4v vdc
* driver, another virtual disk device driver. (Although in the case of
* vdc the hack is less egregious since it is self contained within the
* vdc driver, where as here it is used as an interface between the pv_cmdk
* driver and the xdf driver.)
*/
#define XB_SLICE_NONE 0xFF
/*
* blkif status
*/
typedef enum xdf_state {
/*
* initial state
*/
XD_UNKNOWN = 0,
/*
* ring and evtchn alloced, xenbus state changed to
* XenbusStateInitialised, wait for backend to connect
*/
XD_INIT = 1,
/*
* backend and frontend xenbus state has changed to
* XenbusStateConnected. IO is now allowed, but we are not still
* fully initialized.
*/
XD_CONNECTED = 2,
/*
* We're fully initialized and allowing regular IO.
*/
XD_READY = 3,
/*
* vbd interface close request received from backend, no more I/O
* requestis allowed to be put into ring buffer, while interrupt handler
* is allowed to run to finish any outstanding I/O request, disconnect
* process is kicked off by changing xenbus state to XenbusStateClosed
*/
XD_CLOSING = 4,
/*
* disconnection process finished, both backend and frontend's
* xenbus state has been changed to XenbusStateClosed, can be detached
*/
XD_CLOSED = 5,
/*
* We're either being suspended or resuming from a suspend. If we're
* in the process of suspending, we block all new IO, but but allow
* existing IO to drain.
*/
XD_SUSPEND = 6
} xdf_state_t;
/*
* 16 partitions + fdisk
*/
#define XDF_PSHIFT 6
#define XDF_MINOR(i, m) (((i) << XDF_PSHIFT) | (m))
#define XDF_INST(m) ((m) >> XDF_PSHIFT)
/*
* one blkif_request_t will have one corresponding ge_slot_t
* where we save those grant table refs used in this blkif_request_t
*
* the id of this ge_slot_t will also be put into 'id' field in
* each blkif_request_t when sent out to the ring buffer.
*/
typedef struct ge_slot {
int gs_isread;
int gs_ngrefs;
} ge_slot_t;
/*
* vbd I/O request
*
* An instance of this structure is bound to each buf passed to
* the driver's strategy by setting the pointer into bp->av_back.
* The id of this vreq will also be put into 'id' field in each
* blkif_request_t when sent out to the ring buffer for one DMA
* window of this buf.
*
* there could be more than one DMA window, each of which will be
* mapped to one blkif_request_t/ge_slot_t. Ge_slot_t contains all grant
* table entry information for this buf. The ge_slot_t for current DMA
* window is pointed to by v_gs in vreq.
*
* So, grant table entries will only be alloc'ed when the DMA window is
* about to be transferred via blkif_request_t to the ring buffer. And
* they will be freed right after the blkif_response_t is seen. By this
* means, we can make use of grant table entries more efficiently.
*/
typedef struct v_req {
int v_status;
} v_req_t;
/*
* Status set and checked in vreq->v_status by vreq_setup()
*
* These flags will help us to continue the vreq setup work from last failure
* point, instead of starting from scratch after each failure.
*/
#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
/*
* virtual block device per-instance softstate
*/
typedef struct xdf {
char *xdf_addr;
struct gnttab_free_callback xdf_gnt_callback;
char *xdf_flush_mem;
char *xdf_cache_flush_block;
int xdf_evtchn;
enum dkio_state xdf_mstate;
struct buf *xdf_ready_bp;
struct buf *xdf_ready_tq_bp;
#ifdef DEBUG
int xdf_dmacallback_num;
#endif
} xdf_t;
/*
* VBD I/O requests must be aligned on a 512-byte boundary and specify
* a transfer size which is a mutiple of 512-bytes
*/
#define ALIGNED_XFER(bp) \
/* wrap pa_to_ma() for xdf to run in dom0 */
{ \
} else { \
} \
}
#ifdef DEBUG
#else
#define SETDMACBON(vbd)
#define SETDMACBOFF(vbd)
#endif /* DEBUG */
#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
#if defined(XPV_HVM_DRIVER)
extern int xdf_lb_getinfo(dev_info_t *, int, void *, void *);
void *);
extern dev_info_t *xdf_hvm_hold(const char *);
extern int xdf_kstat_create(dev_info_t *, char *, int);
extern void xdf_kstat_delete(dev_info_t *);
#endif /* XPV_HVM_DRIVER */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_XDF_H */