15084Sjohnlev /* 25084Sjohnlev * CDDL HEADER START 35084Sjohnlev * 45084Sjohnlev * The contents of this file are subject to the terms of the 55084Sjohnlev * Common Development and Distribution License (the "License"). 65084Sjohnlev * You may not use this file except in compliance with the License. 75084Sjohnlev * 85084Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95084Sjohnlev * or http://www.opensolaris.org/os/licensing. 105084Sjohnlev * See the License for the specific language governing permissions 115084Sjohnlev * and limitations under the License. 125084Sjohnlev * 135084Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each 145084Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155084Sjohnlev * If applicable, add the following below this CDDL HEADER, with the 165084Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying 175084Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner] 185084Sjohnlev * 195084Sjohnlev * CDDL HEADER END 205084Sjohnlev */ 215084Sjohnlev 225084Sjohnlev /* 23*6175Sjohnlev * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 245084Sjohnlev * Use is subject to license terms. 255084Sjohnlev */ 265084Sjohnlev 275084Sjohnlev #ifndef _SYS_XENDEV_H 285084Sjohnlev #define _SYS_XENDEV_H 295084Sjohnlev 305084Sjohnlev #pragma ident "%Z%%M% %I% %E% SMI" 315084Sjohnlev 325084Sjohnlev #include <sys/hypervisor.h> 335084Sjohnlev #include <sys/taskq.h> 345741Smrj #ifdef XPV_HVM_DRIVER 355741Smrj #include <public/io/ring.h> 365741Smrj #include <public/event_channel.h> 375741Smrj #include <public/grant_table.h> 385741Smrj #endif 395084Sjohnlev #include <xen/sys/xenbus_impl.h> 405084Sjohnlev 415084Sjohnlev #ifdef __cplusplus 425084Sjohnlev extern "C" { 435084Sjohnlev #endif 445084Sjohnlev 455084Sjohnlev /* 465084Sjohnlev * Xen device class codes 475084Sjohnlev */ 485084Sjohnlev typedef enum { 495084Sjohnlev XEN_INVAL = -1, 505084Sjohnlev XEN_CONSOLE = 0, 515084Sjohnlev XEN_VNET, 525084Sjohnlev XEN_VBLK, 535084Sjohnlev XEN_XENBUS, 545084Sjohnlev XEN_DOMCAPS, 555084Sjohnlev XEN_BALLOON, 565084Sjohnlev XEN_EVTCHN, 575084Sjohnlev XEN_PRIVCMD, 585084Sjohnlev XEN_LASTCLASS 595084Sjohnlev } xendev_devclass_t; 605084Sjohnlev 615084Sjohnlev /* 625084Sjohnlev * Hotplug request sent to userland event handler. 635084Sjohnlev */ 645084Sjohnlev typedef enum { 655084Sjohnlev XEN_HP_ADD, 665084Sjohnlev XEN_HP_REMOVE 675084Sjohnlev } xendev_hotplug_cmd_t; 685084Sjohnlev 695084Sjohnlev /* 705084Sjohnlev * Hotplug status. 715084Sjohnlev * 725084Sjohnlev * In fact, the Xen tools can write any arbitrary string into the 735084Sjohnlev * hotplug-status node. We represent the known values here - anything 745084Sjohnlev * else will be 'Unrecognized'. 755084Sjohnlev */ 765084Sjohnlev typedef enum { 775084Sjohnlev Unrecognized, 785084Sjohnlev Connected 795084Sjohnlev } xendev_hotplug_state_t; 805084Sjohnlev 815084Sjohnlev struct xendev_ppd { 825084Sjohnlev int xd_evtchn; 835084Sjohnlev struct intrspec xd_ispec; 845084Sjohnlev xendev_devclass_t xd_devclass; 855084Sjohnlev domid_t xd_domain; 865084Sjohnlev int xd_vdevnum; 875084Sjohnlev struct xenbus_device xd_xsdev; 885084Sjohnlev struct xenbus_watch xd_hp_watch; 895084Sjohnlev struct xenbus_watch xd_bepath_watch; 905084Sjohnlev kmutex_t xd_lk; 915084Sjohnlev ddi_callback_id_t xd_oe_ehid; 925084Sjohnlev ddi_callback_id_t xd_hp_ehid; 935084Sjohnlev ddi_taskq_t *xd_oe_taskq; 945084Sjohnlev ddi_taskq_t *xd_hp_taskq; 955084Sjohnlev }; 965084Sjohnlev 975084Sjohnlev #define XS_OE_STATE "SUNW,xendev:otherend_state" 985084Sjohnlev #define XS_HP_STATE "SUNW,xendev:hotplug_state" 995084Sjohnlev 100*6175Sjohnlev /* 101*6175Sjohnlev * A device with xd_vdevnum == VDEV_NOXS does not participate in 102*6175Sjohnlev * xenstore. 103*6175Sjohnlev */ 104*6175Sjohnlev #define VDEV_NOXS (-1) 105*6175Sjohnlev 1065084Sjohnlev void xendev_enum_class(dev_info_t *, xendev_devclass_t); 1075084Sjohnlev void xendev_enum_all(dev_info_t *, boolean_t); 1085084Sjohnlev xendev_devclass_t xendev_nodename_to_devclass(char *); 1095084Sjohnlev int xendev_devclass_ipl(xendev_devclass_t); 1105084Sjohnlev struct intrspec *xendev_get_ispec(dev_info_t *, uint_t); 1115084Sjohnlev void xvdi_suspend(dev_info_t *); 1125084Sjohnlev int xvdi_resume(dev_info_t *); 1135084Sjohnlev int xvdi_alloc_evtchn(dev_info_t *); 1145084Sjohnlev int xvdi_bind_evtchn(dev_info_t *, evtchn_port_t); 1155084Sjohnlev void xvdi_free_evtchn(dev_info_t *); 1165084Sjohnlev int xvdi_add_event_handler(dev_info_t *, char *, 1175084Sjohnlev void (*)(dev_info_t *, ddi_eventcookie_t, void *, void *)); 1185084Sjohnlev void xvdi_remove_event_handler(dev_info_t *, char *); 1195084Sjohnlev int xvdi_get_evtchn(dev_info_t *); 1205084Sjohnlev int xvdi_get_vdevnum(dev_info_t *); 1215084Sjohnlev char *xvdi_get_xsname(dev_info_t *); 1225084Sjohnlev char *xvdi_get_oename(dev_info_t *); 1235084Sjohnlev domid_t xvdi_get_oeid(dev_info_t *); 1245084Sjohnlev void xvdi_dev_error(dev_info_t *, int, char *); 1255084Sjohnlev void xvdi_fatal_error(dev_info_t *, int, char *); 1265084Sjohnlev void xvdi_notify_oe(dev_info_t *); 1275084Sjohnlev int xvdi_post_event(dev_info_t *, xendev_hotplug_cmd_t); 1285084Sjohnlev struct xenbus_device *xvdi_get_xsd(dev_info_t *); 1295084Sjohnlev int xvdi_switch_state(dev_info_t *, xenbus_transaction_t, XenbusState); 1305084Sjohnlev dev_info_t *xvdi_create_dev(dev_info_t *, xendev_devclass_t, 1315084Sjohnlev domid_t, int); 1325084Sjohnlev int xvdi_init_dev(dev_info_t *); 1335084Sjohnlev void xvdi_uninit_dev(dev_info_t *); 1345084Sjohnlev dev_info_t *xvdi_find_dev(dev_info_t *, xendev_devclass_t, domid_t, int); 1355084Sjohnlev 1365084Sjohnlev /* 1375084Sjohnlev * common ring interfaces 1385084Sjohnlev */ 1395084Sjohnlev 1405084Sjohnlev /* 1415084Sjohnlev * we need the pad between ring index 1425084Sjohnlev * and the real ring containing requests/responses, 1435084Sjohnlev * so that we can map comif_sring_t structure to 1445084Sjohnlev * any xxxif_sring_t structure defined via macros in ring.h 1455084Sjohnlev */ 1465084Sjohnlev #define SRINGPAD 48 1475084Sjohnlev 1485084Sjohnlev typedef struct comif_sring { 1495084Sjohnlev RING_IDX req_prod, req_event; 1505084Sjohnlev RING_IDX rsp_prod, rsp_event; 1515084Sjohnlev uint8_t pad[SRINGPAD]; 1525084Sjohnlev /* 1535084Sjohnlev * variable length 1545084Sjohnlev * stores real request/response entries 1555084Sjohnlev * entry size is fixed per ring 1565084Sjohnlev */ 1575084Sjohnlev char ring[1]; 1585084Sjohnlev } comif_sring_t; 1595084Sjohnlev 1605084Sjohnlev typedef struct comif_ring_fe { 1615084Sjohnlev /* 1625084Sjohnlev * keep the member names as defined in ring.h 1635084Sjohnlev * in order to make use of the pre-defined macros 1645084Sjohnlev */ 1655084Sjohnlev RING_IDX req_prod_pvt; 1665084Sjohnlev RING_IDX rsp_cons; 1675084Sjohnlev unsigned int nr_ents; 1685084Sjohnlev comif_sring_t *sring; 1695084Sjohnlev } comif_ring_fe_t; 1705084Sjohnlev 1715084Sjohnlev typedef struct comif_ring_be { 1725084Sjohnlev /* 1735084Sjohnlev * keep the member names as defined in ring.h 1745084Sjohnlev * in order to make use of the pre-defined macros 1755084Sjohnlev */ 1765084Sjohnlev RING_IDX rsp_prod_pvt; 1775084Sjohnlev RING_IDX req_cons; 1785084Sjohnlev unsigned int nr_ents; 1795084Sjohnlev comif_sring_t *sring; 1805084Sjohnlev } comif_ring_be_t; 1815084Sjohnlev 1825084Sjohnlev typedef union comif_ring { 1835084Sjohnlev comif_ring_fe_t fr; 1845084Sjohnlev comif_ring_be_t br; 1855084Sjohnlev } comif_ring_t; 1865084Sjohnlev 1875084Sjohnlev typedef struct xendev_req { 1885084Sjohnlev unsigned long next; 1895084Sjohnlev void *req; 1905084Sjohnlev } xendev_req_t; 1915084Sjohnlev 1925084Sjohnlev typedef struct xendev_ring { 1935084Sjohnlev ddi_dma_handle_t xr_dma_hdl; 1945084Sjohnlev ddi_acc_handle_t xr_acc_hdl; 1955084Sjohnlev grant_handle_t xr_grant_hdl; 1965084Sjohnlev caddr_t xr_vaddr; 1975084Sjohnlev paddr_t xr_paddr; 1985084Sjohnlev grant_ref_t xr_gref; 1995084Sjohnlev int xr_entry_size; 2005084Sjohnlev int xr_frontend; 2015084Sjohnlev comif_ring_t xr_sring; 2025084Sjohnlev } xendev_ring_t; 2035084Sjohnlev 2045084Sjohnlev int xvdi_alloc_ring(dev_info_t *, size_t, size_t, grant_ref_t *, 2055084Sjohnlev xendev_ring_t **); 2065084Sjohnlev void xvdi_free_ring(xendev_ring_t *); 2075084Sjohnlev int xvdi_map_ring(dev_info_t *, size_t, size_t, grant_ref_t, 2085084Sjohnlev xendev_ring_t **); 2095084Sjohnlev void xvdi_unmap_ring(xendev_ring_t *); 2105084Sjohnlev uint_t xvdi_ring_avail_slots(xendev_ring_t *); 2115084Sjohnlev int xvdi_ring_has_unconsumed_requests(xendev_ring_t *); 2125084Sjohnlev int xvdi_ring_has_incomp_request(xendev_ring_t *); 2135084Sjohnlev int xvdi_ring_has_unconsumed_responses(xendev_ring_t *); 2145084Sjohnlev void* xvdi_ring_get_request(xendev_ring_t *); 2155084Sjohnlev int xvdi_ring_push_request(xendev_ring_t *); 2165084Sjohnlev void* xvdi_ring_get_response(xendev_ring_t *); 2175084Sjohnlev int xvdi_ring_push_response(xendev_ring_t *); 2185084Sjohnlev 2195084Sjohnlev #ifdef __cplusplus 2205084Sjohnlev } 2215084Sjohnlev #endif 2225084Sjohnlev 2235084Sjohnlev #endif /* _SYS_XENDEV_H */ 224