summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/xen/io/xdb.h
blob: 2173ca6ad965a254696cc91c7e26c27c27bad18a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * 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 */