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 /* 236175Sjohnlev * 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 315084Sjohnlev #include <sys/hypervisor.h> 325084Sjohnlev #include <sys/taskq.h> 335741Smrj #ifdef XPV_HVM_DRIVER 345741Smrj #include <public/io/ring.h> 355741Smrj #include <public/event_channel.h> 365741Smrj #include <public/grant_table.h> 375741Smrj #endif 385084Sjohnlev #include <xen/sys/xenbus_impl.h> 395084Sjohnlev 405084Sjohnlev #ifdef __cplusplus 415084Sjohnlev extern "C" { 425084Sjohnlev #endif 435084Sjohnlev 445084Sjohnlev /* 455084Sjohnlev * Xen device class codes 465084Sjohnlev */ 475084Sjohnlev typedef enum { 485084Sjohnlev XEN_INVAL = -1, 495084Sjohnlev XEN_CONSOLE = 0, 505084Sjohnlev XEN_VNET, 515084Sjohnlev XEN_VBLK, 525084Sjohnlev XEN_XENBUS, 535084Sjohnlev XEN_DOMCAPS, 545084Sjohnlev XEN_BALLOON, 555084Sjohnlev XEN_EVTCHN, 565084Sjohnlev XEN_PRIVCMD, 57*7756SMark.Johnson@Sun.COM XEN_BLKTAP, 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 { 82*7756SMark.Johnson@Sun.COM kmutex_t xd_evt_lk; 835084Sjohnlev int xd_evtchn; 845084Sjohnlev struct intrspec xd_ispec; 85*7756SMark.Johnson@Sun.COM 865084Sjohnlev xendev_devclass_t xd_devclass; 875084Sjohnlev domid_t xd_domain; 885084Sjohnlev int xd_vdevnum; 89*7756SMark.Johnson@Sun.COM 90*7756SMark.Johnson@Sun.COM kmutex_t xd_ndi_lk; 915084Sjohnlev struct xenbus_device xd_xsdev; 925084Sjohnlev struct xenbus_watch xd_hp_watch; 935084Sjohnlev struct xenbus_watch xd_bepath_watch; 945084Sjohnlev ddi_callback_id_t xd_oe_ehid; 955084Sjohnlev ddi_callback_id_t xd_hp_ehid; 965084Sjohnlev ddi_taskq_t *xd_oe_taskq; 975084Sjohnlev ddi_taskq_t *xd_hp_taskq; 985084Sjohnlev }; 995084Sjohnlev 1005084Sjohnlev #define XS_OE_STATE "SUNW,xendev:otherend_state" 1015084Sjohnlev #define XS_HP_STATE "SUNW,xendev:hotplug_state" 1025084Sjohnlev 1036175Sjohnlev /* 1046175Sjohnlev * A device with xd_vdevnum == VDEV_NOXS does not participate in 1056175Sjohnlev * xenstore. 1066175Sjohnlev */ 1076175Sjohnlev #define VDEV_NOXS (-1) 1086175Sjohnlev 1095084Sjohnlev void xendev_enum_class(dev_info_t *, xendev_devclass_t); 1105084Sjohnlev void xendev_enum_all(dev_info_t *, boolean_t); 1115084Sjohnlev xendev_devclass_t xendev_nodename_to_devclass(char *); 1125084Sjohnlev int xendev_devclass_ipl(xendev_devclass_t); 1135084Sjohnlev struct intrspec *xendev_get_ispec(dev_info_t *, uint_t); 1145084Sjohnlev void xvdi_suspend(dev_info_t *); 1155084Sjohnlev int xvdi_resume(dev_info_t *); 1165084Sjohnlev int xvdi_alloc_evtchn(dev_info_t *); 1175084Sjohnlev int xvdi_bind_evtchn(dev_info_t *, evtchn_port_t); 1185084Sjohnlev void xvdi_free_evtchn(dev_info_t *); 1195084Sjohnlev int xvdi_add_event_handler(dev_info_t *, char *, 120*7756SMark.Johnson@Sun.COM void (*)(dev_info_t *, ddi_eventcookie_t, void *, void *), 121*7756SMark.Johnson@Sun.COM void *arg); 1225084Sjohnlev void xvdi_remove_event_handler(dev_info_t *, char *); 1235084Sjohnlev int xvdi_get_evtchn(dev_info_t *); 1245084Sjohnlev int xvdi_get_vdevnum(dev_info_t *); 1255084Sjohnlev char *xvdi_get_xsname(dev_info_t *); 1265084Sjohnlev char *xvdi_get_oename(dev_info_t *); 1275084Sjohnlev domid_t xvdi_get_oeid(dev_info_t *); 1285084Sjohnlev void xvdi_dev_error(dev_info_t *, int, char *); 1295084Sjohnlev void xvdi_fatal_error(dev_info_t *, int, char *); 1305084Sjohnlev void xvdi_notify_oe(dev_info_t *); 1315084Sjohnlev int xvdi_post_event(dev_info_t *, xendev_hotplug_cmd_t); 1325084Sjohnlev struct xenbus_device *xvdi_get_xsd(dev_info_t *); 1335084Sjohnlev int xvdi_switch_state(dev_info_t *, xenbus_transaction_t, XenbusState); 1345084Sjohnlev dev_info_t *xvdi_create_dev(dev_info_t *, xendev_devclass_t, 1355084Sjohnlev domid_t, int); 1365084Sjohnlev int xvdi_init_dev(dev_info_t *); 1375084Sjohnlev void xvdi_uninit_dev(dev_info_t *); 1385084Sjohnlev dev_info_t *xvdi_find_dev(dev_info_t *, xendev_devclass_t, domid_t, int); 1395084Sjohnlev 1405084Sjohnlev /* 1415084Sjohnlev * common ring interfaces 1425084Sjohnlev */ 1435084Sjohnlev 1445084Sjohnlev /* 1455084Sjohnlev * we need the pad between ring index 1465084Sjohnlev * and the real ring containing requests/responses, 1475084Sjohnlev * so that we can map comif_sring_t structure to 1485084Sjohnlev * any xxxif_sring_t structure defined via macros in ring.h 1495084Sjohnlev */ 1505084Sjohnlev #define SRINGPAD 48 1515084Sjohnlev 1525084Sjohnlev typedef struct comif_sring { 1535084Sjohnlev RING_IDX req_prod, req_event; 1545084Sjohnlev RING_IDX rsp_prod, rsp_event; 1555084Sjohnlev uint8_t pad[SRINGPAD]; 1565084Sjohnlev /* 1575084Sjohnlev * variable length 1585084Sjohnlev * stores real request/response entries 1595084Sjohnlev * entry size is fixed per ring 1605084Sjohnlev */ 1615084Sjohnlev char ring[1]; 1625084Sjohnlev } comif_sring_t; 1635084Sjohnlev 1645084Sjohnlev typedef struct comif_ring_fe { 1655084Sjohnlev /* 1665084Sjohnlev * keep the member names as defined in ring.h 1675084Sjohnlev * in order to make use of the pre-defined macros 1685084Sjohnlev */ 1695084Sjohnlev RING_IDX req_prod_pvt; 1705084Sjohnlev RING_IDX rsp_cons; 1715084Sjohnlev unsigned int nr_ents; 1725084Sjohnlev comif_sring_t *sring; 1735084Sjohnlev } comif_ring_fe_t; 1745084Sjohnlev 1755084Sjohnlev typedef struct comif_ring_be { 1765084Sjohnlev /* 1775084Sjohnlev * keep the member names as defined in ring.h 1785084Sjohnlev * in order to make use of the pre-defined macros 1795084Sjohnlev */ 1805084Sjohnlev RING_IDX rsp_prod_pvt; 1815084Sjohnlev RING_IDX req_cons; 1825084Sjohnlev unsigned int nr_ents; 1835084Sjohnlev comif_sring_t *sring; 1845084Sjohnlev } comif_ring_be_t; 1855084Sjohnlev 1865084Sjohnlev typedef union comif_ring { 1875084Sjohnlev comif_ring_fe_t fr; 1885084Sjohnlev comif_ring_be_t br; 1895084Sjohnlev } comif_ring_t; 1905084Sjohnlev 1915084Sjohnlev typedef struct xendev_req { 1925084Sjohnlev unsigned long next; 1935084Sjohnlev void *req; 1945084Sjohnlev } xendev_req_t; 1955084Sjohnlev 1965084Sjohnlev typedef struct xendev_ring { 1975084Sjohnlev ddi_dma_handle_t xr_dma_hdl; 1985084Sjohnlev ddi_acc_handle_t xr_acc_hdl; 1995084Sjohnlev grant_handle_t xr_grant_hdl; 2005084Sjohnlev caddr_t xr_vaddr; 2015084Sjohnlev paddr_t xr_paddr; 2025084Sjohnlev grant_ref_t xr_gref; 2035084Sjohnlev int xr_entry_size; 2045084Sjohnlev int xr_frontend; 2055084Sjohnlev comif_ring_t xr_sring; 2065084Sjohnlev } xendev_ring_t; 2075084Sjohnlev 2085084Sjohnlev int xvdi_alloc_ring(dev_info_t *, size_t, size_t, grant_ref_t *, 2095084Sjohnlev xendev_ring_t **); 2105084Sjohnlev void xvdi_free_ring(xendev_ring_t *); 2115084Sjohnlev int xvdi_map_ring(dev_info_t *, size_t, size_t, grant_ref_t, 2125084Sjohnlev xendev_ring_t **); 2135084Sjohnlev void xvdi_unmap_ring(xendev_ring_t *); 2145084Sjohnlev uint_t xvdi_ring_avail_slots(xendev_ring_t *); 2155084Sjohnlev int xvdi_ring_has_unconsumed_requests(xendev_ring_t *); 2165084Sjohnlev int xvdi_ring_has_incomp_request(xendev_ring_t *); 2175084Sjohnlev int xvdi_ring_has_unconsumed_responses(xendev_ring_t *); 2185084Sjohnlev void* xvdi_ring_get_request(xendev_ring_t *); 2195084Sjohnlev int xvdi_ring_push_request(xendev_ring_t *); 2205084Sjohnlev void* xvdi_ring_get_response(xendev_ring_t *); 2215084Sjohnlev int xvdi_ring_push_response(xendev_ring_t *); 2225084Sjohnlev 2235084Sjohnlev #ifdef __cplusplus 2245084Sjohnlev } 2255084Sjohnlev #endif 2265084Sjohnlev 2275084Sjohnlev #endif /* _SYS_XENDEV_H */ 228