Home | History | Annotate | Download | only in sys
      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 #ifndef	__xpv
     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_SECTOR_SIZE	"sector-size"		/* backend prop: uint */
     56 #define	XBP_SECTORS	"sectors"		/* backend prop: uint64 */
     57 #define	XBP_INFO	"info"			/* backend prop: uint */
     58 #define	XBP_FB		"feature-barrier"	/* backend prop: boolean int */
     59 
     60 /*
     61  * Xenbus property interfaces, initialized by frontend disk driver
     62  */
     63 #define	XBP_RING_REF	"ring-ref"		/* frontend prop: long */
     64 #define	XBP_EVENT_CHAN	"event-channel"		/* frontend prop: long */
     65 #define	XBP_PROTOCOL	"protocol"		/* frontend prop: string */
     66 
     67 /*
     68  * Xenbus CDROM property interfaces, used by backend and frontend
     69  *
     70  * XBP_MEDIA_REQ_SUP
     71  *	- Backend xenbus property located at:
     72  *		backend/vbd/<domU_id>/<domU_dev>/media-req-sup
     73  *	- Set by the backend, consumed by the frontend.
     74  *	- Cosumed by the frontend.
     75  *	- A boolean integer property indicating backend support
     76  *	  for the XBP_MEDIA_REQ property.
     77  *
     78  * XBP_MEDIA_REQ
     79  *	- Frontend xenbus property located at:
     80  *		/local/domain/<domU_id>/device/vbd/<domU_dev>/media-req
     81  *	- Set and consumed by both the frontend and backend.
     82  *	- Possible values:
     83  *		XBV_MEDIA_REQ_NONE, XBV_MEDIA_REQ_LOCK, and XBV_MEDIA_REQ_EJECT
     84  *	- Only applies to CDROM devices.
     85  *
     86  * XBV_MEDIA_REQ_NONE
     87  * 	- XBP_MEDIA_REQ property valud
     88  *	- Set and consumed by both the frontend and backend.
     89  *	- Indicates that there are no currently outstanding media requet
     90  *	  operations.
     91  *
     92  * XBV_MEDIA_REQ_LOCK
     93  * 	- XBP_MEDIA_REQ property valud
     94  *	- Set by the frontend, consumed by the backend.
     95  *	- Indicates to the backend that the currenct media is locked
     96  *	  and changes to the media (via xm block-configure for example)
     97  *	  should not be allowed.
     98  *
     99  * XBV_MEDIA_REQ_EJECT
    100  * 	- XBP_MEDIA_REQ property valud
    101  *	- Set by the frontend, consumed by the backend.
    102  *	- Indicates to the backend that the currenct media should be ejected.
    103  *	  This means that the backend should close it's connection to
    104  *	  the frontend device, close it's current backing store device/file,
    105  *	  and then set the media-req property to XBV_MEDIA_REQ_NONE.  (to
    106  *	  indicate that the eject operation is complete.)
    107  */
    108 #define	XBP_MEDIA_REQ_SUP	"media-req-sup"	/* backend prop: boolean int */
    109 #define	XBP_MEDIA_REQ		"media-req"	/* frontend prop: str */
    110 #define	XBV_MEDIA_REQ_NONE	"none"		/* frontend prop val */
    111 #define	XBV_MEDIA_REQ_LOCK	"lock"		/* frontend prop val */
    112 #define	XBV_MEDIA_REQ_EJECT	"eject"		/* frontend prop val */
    113 
    114 /*
    115  * Xen device class codes
    116  */
    117 typedef enum {
    118 	XEN_INVAL = -1,
    119 	XEN_CONSOLE = 0,
    120 	XEN_VNET,
    121 	XEN_VBLK,
    122 	XEN_XENBUS,
    123 	XEN_DOMCAPS,
    124 	XEN_BALLOON,
    125 	XEN_EVTCHN,
    126 	XEN_PRIVCMD,
    127 	XEN_BLKTAP,
    128 	XEN_LASTCLASS
    129 } xendev_devclass_t;
    130 
    131 /*
    132  * Hotplug request sent to userland event handler.
    133  */
    134 typedef enum {
    135 	XEN_HP_ADD,
    136 	XEN_HP_REMOVE
    137 } xendev_hotplug_cmd_t;
    138 
    139 /*
    140  * Hotplug status.
    141  *
    142  * In fact, the Xen tools can write any arbitrary string into the
    143  * hotplug-status node. We represent the known values here - anything
    144  * else will be 'Unrecognized'.
    145  */
    146 typedef enum {
    147 	Unrecognized,
    148 	Connected
    149 } xendev_hotplug_state_t;
    150 
    151 struct xendev_ppd {
    152 	kmutex_t		xd_evt_lk;
    153 	int			xd_evtchn;
    154 	struct intrspec		xd_ispec;
    155 
    156 	xendev_devclass_t	xd_devclass;
    157 	domid_t			xd_domain;
    158 	int			xd_vdevnum;
    159 
    160 	kmutex_t		xd_ndi_lk;
    161 	struct xenbus_device	xd_xsdev;
    162 	struct xenbus_watch	xd_hp_watch;
    163 	struct xenbus_watch	xd_bepath_watch;
    164 	ddi_callback_id_t	xd_oe_ehid;
    165 	ddi_callback_id_t	xd_hp_ehid;
    166 	ddi_taskq_t		*xd_oe_taskq;
    167 	ddi_taskq_t		*xd_hp_taskq;
    168 	ddi_taskq_t		*xd_xb_watch_taskq;
    169 	list_t			xd_xb_watches;
    170 };
    171 
    172 #define	XS_OE_STATE	"SUNW,xendev:otherend_state"
    173 #define	XS_HP_STATE	"SUNW,xendev:hotplug_state"
    174 
    175 /*
    176  * A device with xd_vdevnum == VDEV_NOXS does not participate in
    177  * xenstore.
    178  */
    179 #define	VDEV_NOXS	(-1)
    180 
    181 void	xendev_enum_class(dev_info_t *, xendev_devclass_t);
    182 void	xendev_enum_all(dev_info_t *, boolean_t);
    183 xendev_devclass_t	xendev_nodename_to_devclass(char *);
    184 int	xendev_devclass_ipl(xendev_devclass_t);
    185 struct intrspec *xendev_get_ispec(dev_info_t *, uint_t);
    186 void	xvdi_suspend(dev_info_t *);
    187 int	xvdi_resume(dev_info_t *);
    188 int	xvdi_alloc_evtchn(dev_info_t *);
    189 int	xvdi_bind_evtchn(dev_info_t *, evtchn_port_t);
    190 void	xvdi_free_evtchn(dev_info_t *);
    191 int	xvdi_add_event_handler(dev_info_t *, char *,
    192 	void (*)(dev_info_t *, ddi_eventcookie_t, void *, void *),
    193 	void *arg);
    194 void	xvdi_remove_event_handler(dev_info_t *, char *);
    195 int	xvdi_get_evtchn(dev_info_t *);
    196 int	xvdi_get_vdevnum(dev_info_t *);
    197 char	*xvdi_get_xsname(dev_info_t *);
    198 char	*xvdi_get_oename(dev_info_t *);
    199 domid_t	xvdi_get_oeid(dev_info_t *);
    200 void	xvdi_dev_error(dev_info_t *, int, char *);
    201 void	xvdi_fatal_error(dev_info_t *, int, char *);
    202 void	xvdi_notify_oe(dev_info_t *);
    203 int	xvdi_post_event(dev_info_t *, xendev_hotplug_cmd_t);
    204 struct  xenbus_device *xvdi_get_xsd(dev_info_t *);
    205 int	xvdi_switch_state(dev_info_t *, xenbus_transaction_t, XenbusState);
    206 dev_info_t	*xvdi_create_dev(dev_info_t *, xendev_devclass_t,
    207     domid_t, int);
    208 int	xvdi_init_dev(dev_info_t *);
    209 void	xvdi_uninit_dev(dev_info_t *);
    210 dev_info_t	*xvdi_find_dev(dev_info_t *, xendev_devclass_t, domid_t, int);
    211 
    212 extern int xvdi_add_xb_watch_handler(dev_info_t *, const char *,
    213     const char *, xvdi_xb_watch_cb_t cb, void *);
    214 extern void xvdi_remove_xb_watch_handlers(dev_info_t *);
    215 
    216 /*
    217  * common ring interfaces
    218  */
    219 
    220 /*
    221  * we need the pad between ring index
    222  * and the real ring containing requests/responses,
    223  * so that we can map comif_sring_t structure to
    224  * any xxxif_sring_t structure defined via macros in ring.h
    225  */
    226 #define	SRINGPAD		48
    227 
    228 typedef struct comif_sring {
    229 	RING_IDX req_prod, req_event;
    230 	RING_IDX rsp_prod, rsp_event;
    231 	uint8_t  pad[SRINGPAD];
    232 	/*
    233 	 * variable length
    234 	 * stores real request/response entries
    235 	 * entry size is fixed per ring
    236 	 */
    237 	char ring[1];
    238 } comif_sring_t;
    239 
    240 typedef struct comif_ring_fe {
    241 	/*
    242 	 * keep the member names as defined in ring.h
    243 	 * in order to make use of the pre-defined macros
    244 	 */
    245 	RING_IDX req_prod_pvt;
    246 	RING_IDX rsp_cons;
    247 	unsigned int nr_ents;
    248 	comif_sring_t *sring;
    249 } comif_ring_fe_t;
    250 
    251 typedef struct comif_ring_be {
    252 	/*
    253 	 * keep the member names as defined in ring.h
    254 	 * in order to make use of the pre-defined macros
    255 	 */
    256 	RING_IDX rsp_prod_pvt;
    257 	RING_IDX req_cons;
    258 	unsigned int nr_ents;
    259 	comif_sring_t  *sring;
    260 } comif_ring_be_t;
    261 
    262 typedef union comif_ring {
    263 	comif_ring_fe_t fr;
    264 	comif_ring_be_t br;
    265 } comif_ring_t;
    266 
    267 typedef struct xendev_req {
    268 	unsigned long next;
    269 	void *req;
    270 } xendev_req_t;
    271 
    272 typedef struct xendev_ring {
    273 	ddi_dma_handle_t xr_dma_hdl;
    274 	ddi_acc_handle_t xr_acc_hdl;
    275 	grant_handle_t xr_grant_hdl;
    276 	caddr_t xr_vaddr;
    277 	paddr_t xr_paddr;
    278 	grant_ref_t xr_gref;
    279 	int xr_entry_size;
    280 	int xr_frontend;
    281 	comif_ring_t xr_sring;
    282 } xendev_ring_t;
    283 
    284 int	xvdi_alloc_ring(dev_info_t *, size_t, size_t, grant_ref_t *,
    285 	xendev_ring_t **);
    286 void	xvdi_free_ring(xendev_ring_t *);
    287 int	xvdi_map_ring(dev_info_t *, size_t, size_t, grant_ref_t,
    288 	xendev_ring_t **);
    289 void	xvdi_unmap_ring(xendev_ring_t *);
    290 uint_t	xvdi_ring_avail_slots(xendev_ring_t *);
    291 int	xvdi_ring_has_unconsumed_requests(xendev_ring_t *);
    292 int	xvdi_ring_has_incomp_request(xendev_ring_t *);
    293 int	xvdi_ring_has_unconsumed_responses(xendev_ring_t *);
    294 void*	xvdi_ring_get_request(xendev_ring_t *);
    295 int	xvdi_ring_push_request(xendev_ring_t *);
    296 void*	xvdi_ring_get_response(xendev_ring_t *);
    297 int	xvdi_ring_push_response(xendev_ring_t *);
    298 
    299 #ifdef	__cplusplus
    300 }
    301 #endif
    302 
    303 #endif	/* _SYS_XENDEV_H */
    304