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_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