xref: /illumos-gate/usr/src/uts/common/xen/sys/xendev.h (revision d656abb5804319b33c85955a73ee450ef7ff9739)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_XENDEV_H
28 #define	_SYS_XENDEV_H
29 
30 
31 #include <sys/hypervisor.h>
32 #include <sys/taskq.h>
33 #ifdef	XPV_HVM_DRIVER
34 #include <public/io/ring.h>
35 #include <public/event_channel.h>
36 #include <public/grant_table.h>
37 #endif
38 #include <xen/sys/xenbus_impl.h>
39 
40 #ifdef	__cplusplus
41 extern "C" {
42 #endif
43 
44 /*
45  * Xenbus property interfaces, initialized by framework
46  */
47 #define	XBP_HP_STATUS		"hotplug-status"	/* backend prop: str */
48 #define	XBV_HP_STATUS_CONN	"connected"		/* backend prop val */
49 #define	XBP_DEV_TYPE		"device-type"		/* backend prop: str */
50 #define	XBV_DEV_TYPE_CD		"cdrom"			/* backend prop val */
51 
52 /*
53  * Xenbus property interfaces, initialized by backend disk driver
54  */
55 #define	XBP_SECTORS	"sectors"		/* backend prop: uint64 */
56 #define	XBP_INFO	"info"			/* backend prop: uint */
57 #define	XBP_FB		"feature-barrier"	/* backend prop: boolean int */
58 
59 /*
60  * Xenbus property interfaces, initialized by frontend disk driver
61  */
62 #define	XBP_RING_REF	"ring-ref"		/* frontend prop: long */
63 #define	XBP_EVENT_CHAN	"event-channel"		/* frontend prop: long */
64 #define	XBP_PROTOCOL	"protocol"		/* frontend prop: string */
65 
66 /*
67  * Xenbus CDROM property interfaces, used by backend and frontend
68  *
69  * XBP_MEDIA_REQ_SUP
70  *	- Backend xenbus property located at:
71  *		backend/vbd/<domU_id>/<domU_dev>/media-req-sup
72  *	- Set by the backend, consumed by the frontend.
73  *	- Cosumed by the frontend.
74  *	- A boolean integer property indicating backend support
75  *	  for the XBP_MEDIA_REQ property.
76  *
77  * XBP_MEDIA_REQ
78  *	- Frontend xenbus property located at:
79  *		/local/domain/<domU_id>/device/vbd/<domU_dev>/media-req
80  *	- Set and consumed by both the frontend and backend.
81  *	- Possible values:
82  *		XBV_MEDIA_REQ_NONE, XBV_MEDIA_REQ_LOCK, and XBV_MEDIA_REQ_EJECT
83  *	- Only applies to CDROM devices.
84  *
85  * XBV_MEDIA_REQ_NONE
86  * 	- XBP_MEDIA_REQ property valud
87  *	- Set and consumed by both the frontend and backend.
88  *	- Indicates that there are no currently outstanding media requet
89  *	  operations.
90  *
91  * XBV_MEDIA_REQ_LOCK
92  * 	- XBP_MEDIA_REQ property valud
93  *	- Set by the frontend, consumed by the backend.
94  *	- Indicates to the backend that the currenct media is locked
95  *	  and changes to the media (via xm block-configure for example)
96  *	  should not be allowed.
97  *
98  * XBV_MEDIA_REQ_EJECT
99  * 	- XBP_MEDIA_REQ property valud
100  *	- Set by the frontend, consumed by the backend.
101  *	- Indicates to the backend that the currenct media should be ejected.
102  *	  This means that the backend should close it's connection to
103  *	  the frontend device, close it's current backing store device/file,
104  *	  and then set the media-req property to XBV_MEDIA_REQ_NONE.  (to
105  *	  indicate that the eject operation is complete.)
106  */
107 #define	XBP_MEDIA_REQ_SUP	"media-req-sup"	/* backend prop: boolean int */
108 #define	XBP_MEDIA_REQ		"media-req"	/* frontend prop: str */
109 #define	XBV_MEDIA_REQ_NONE	"none"		/* frontend prop val */
110 #define	XBV_MEDIA_REQ_LOCK	"lock"		/* frontend prop val */
111 #define	XBV_MEDIA_REQ_EJECT	"eject"		/* frontend prop val */
112 
113 /*
114  * Xen device class codes
115  */
116 typedef enum {
117 	XEN_INVAL = -1,
118 	XEN_CONSOLE = 0,
119 	XEN_VNET,
120 	XEN_VBLK,
121 	XEN_XENBUS,
122 	XEN_DOMCAPS,
123 	XEN_BALLOON,
124 	XEN_EVTCHN,
125 	XEN_PRIVCMD,
126 	XEN_BLKTAP,
127 	XEN_LASTCLASS
128 } xendev_devclass_t;
129 
130 /*
131  * Hotplug request sent to userland event handler.
132  */
133 typedef enum {
134 	XEN_HP_ADD,
135 	XEN_HP_REMOVE
136 } xendev_hotplug_cmd_t;
137 
138 /*
139  * Hotplug status.
140  *
141  * In fact, the Xen tools can write any arbitrary string into the
142  * hotplug-status node. We represent the known values here - anything
143  * else will be 'Unrecognized'.
144  */
145 typedef enum {
146 	Unrecognized,
147 	Connected
148 } xendev_hotplug_state_t;
149 
150 struct xendev_ppd {
151 	kmutex_t		xd_evt_lk;
152 	int			xd_evtchn;
153 	struct intrspec		xd_ispec;
154 
155 	xendev_devclass_t	xd_devclass;
156 	domid_t			xd_domain;
157 	int			xd_vdevnum;
158 
159 	kmutex_t		xd_ndi_lk;
160 	struct xenbus_device	xd_xsdev;
161 	struct xenbus_watch	xd_hp_watch;
162 	struct xenbus_watch	xd_bepath_watch;
163 	ddi_callback_id_t	xd_oe_ehid;
164 	ddi_callback_id_t	xd_hp_ehid;
165 	ddi_taskq_t		*xd_oe_taskq;
166 	ddi_taskq_t		*xd_hp_taskq;
167 	ddi_taskq_t		*xd_xb_watch_taskq;
168 	list_t			xd_xb_watches;
169 };
170 
171 #define	XS_OE_STATE	"SUNW,xendev:otherend_state"
172 #define	XS_HP_STATE	"SUNW,xendev:hotplug_state"
173 
174 /*
175  * A device with xd_vdevnum == VDEV_NOXS does not participate in
176  * xenstore.
177  */
178 #define	VDEV_NOXS	(-1)
179 
180 void	xendev_enum_class(dev_info_t *, xendev_devclass_t);
181 void	xendev_enum_all(dev_info_t *, boolean_t);
182 xendev_devclass_t	xendev_nodename_to_devclass(char *);
183 int	xendev_devclass_ipl(xendev_devclass_t);
184 struct intrspec *xendev_get_ispec(dev_info_t *, uint_t);
185 void	xvdi_suspend(dev_info_t *);
186 int	xvdi_resume(dev_info_t *);
187 int	xvdi_alloc_evtchn(dev_info_t *);
188 int	xvdi_bind_evtchn(dev_info_t *, evtchn_port_t);
189 void	xvdi_free_evtchn(dev_info_t *);
190 int	xvdi_add_event_handler(dev_info_t *, char *,
191 	void (*)(dev_info_t *, ddi_eventcookie_t, void *, void *),
192 	void *arg);
193 void	xvdi_remove_event_handler(dev_info_t *, char *);
194 int	xvdi_get_evtchn(dev_info_t *);
195 int	xvdi_get_vdevnum(dev_info_t *);
196 char	*xvdi_get_xsname(dev_info_t *);
197 char	*xvdi_get_oename(dev_info_t *);
198 domid_t	xvdi_get_oeid(dev_info_t *);
199 void	xvdi_dev_error(dev_info_t *, int, char *);
200 void	xvdi_fatal_error(dev_info_t *, int, char *);
201 void	xvdi_notify_oe(dev_info_t *);
202 int	xvdi_post_event(dev_info_t *, xendev_hotplug_cmd_t);
203 struct  xenbus_device *xvdi_get_xsd(dev_info_t *);
204 int	xvdi_switch_state(dev_info_t *, xenbus_transaction_t, XenbusState);
205 dev_info_t	*xvdi_create_dev(dev_info_t *, xendev_devclass_t,
206     domid_t, int);
207 int	xvdi_init_dev(dev_info_t *);
208 void	xvdi_uninit_dev(dev_info_t *);
209 dev_info_t	*xvdi_find_dev(dev_info_t *, xendev_devclass_t, domid_t, int);
210 
211 extern int xvdi_add_xb_watch_handler(dev_info_t *, const char *,
212     const char *, xvdi_xb_watch_cb_t cb, void *);
213 extern void xvdi_remove_xb_watch_handlers(dev_info_t *);
214 
215 /*
216  * common ring interfaces
217  */
218 
219 /*
220  * we need the pad between ring index
221  * and the real ring containing requests/responses,
222  * so that we can map comif_sring_t structure to
223  * any xxxif_sring_t structure defined via macros in ring.h
224  */
225 #define	SRINGPAD		48
226 
227 typedef struct comif_sring {
228 	RING_IDX req_prod, req_event;
229 	RING_IDX rsp_prod, rsp_event;
230 	uint8_t  pad[SRINGPAD];
231 	/*
232 	 * variable length
233 	 * stores real request/response entries
234 	 * entry size is fixed per ring
235 	 */
236 	char ring[1];
237 } comif_sring_t;
238 
239 typedef struct comif_ring_fe {
240 	/*
241 	 * keep the member names as defined in ring.h
242 	 * in order to make use of the pre-defined macros
243 	 */
244 	RING_IDX req_prod_pvt;
245 	RING_IDX rsp_cons;
246 	unsigned int nr_ents;
247 	comif_sring_t *sring;
248 } comif_ring_fe_t;
249 
250 typedef struct comif_ring_be {
251 	/*
252 	 * keep the member names as defined in ring.h
253 	 * in order to make use of the pre-defined macros
254 	 */
255 	RING_IDX rsp_prod_pvt;
256 	RING_IDX req_cons;
257 	unsigned int nr_ents;
258 	comif_sring_t  *sring;
259 } comif_ring_be_t;
260 
261 typedef union comif_ring {
262 	comif_ring_fe_t fr;
263 	comif_ring_be_t br;
264 } comif_ring_t;
265 
266 typedef struct xendev_req {
267 	unsigned long next;
268 	void *req;
269 } xendev_req_t;
270 
271 typedef struct xendev_ring {
272 	ddi_dma_handle_t xr_dma_hdl;
273 	ddi_acc_handle_t xr_acc_hdl;
274 	grant_handle_t xr_grant_hdl;
275 	caddr_t xr_vaddr;
276 	paddr_t xr_paddr;
277 	grant_ref_t xr_gref;
278 	int xr_entry_size;
279 	int xr_frontend;
280 	comif_ring_t xr_sring;
281 } xendev_ring_t;
282 
283 int	xvdi_alloc_ring(dev_info_t *, size_t, size_t, grant_ref_t *,
284 	xendev_ring_t **);
285 void	xvdi_free_ring(xendev_ring_t *);
286 int	xvdi_map_ring(dev_info_t *, size_t, size_t, grant_ref_t,
287 	xendev_ring_t **);
288 void	xvdi_unmap_ring(xendev_ring_t *);
289 uint_t	xvdi_ring_avail_slots(xendev_ring_t *);
290 int	xvdi_ring_has_unconsumed_requests(xendev_ring_t *);
291 int	xvdi_ring_has_incomp_request(xendev_ring_t *);
292 int	xvdi_ring_has_unconsumed_responses(xendev_ring_t *);
293 void*	xvdi_ring_get_request(xendev_ring_t *);
294 int	xvdi_ring_push_request(xendev_ring_t *);
295 void*	xvdi_ring_get_response(xendev_ring_t *);
296 int	xvdi_ring_push_response(xendev_ring_t *);
297 
298 #ifdef	__cplusplus
299 }
300 #endif
301 
302 #endif	/* _SYS_XENDEV_H */
303