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 /* 235084Sjohnlev * Copyright 2007 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> 34*5741Smrj #ifdef XPV_HVM_DRIVER 35*5741Smrj #include <public/io/ring.h> 36*5741Smrj #include <public/event_channel.h> 37*5741Smrj #include <public/grant_table.h> 38*5741Smrj #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 1005084Sjohnlev void xendev_enum_class(dev_info_t *, xendev_devclass_t); 1015084Sjohnlev void xendev_enum_all(dev_info_t *, boolean_t); 1025084Sjohnlev xendev_devclass_t xendev_nodename_to_devclass(char *); 1035084Sjohnlev int xendev_devclass_ipl(xendev_devclass_t); 1045084Sjohnlev struct intrspec *xendev_get_ispec(dev_info_t *, uint_t); 1055084Sjohnlev void xvdi_suspend(dev_info_t *); 1065084Sjohnlev int xvdi_resume(dev_info_t *); 1075084Sjohnlev int xvdi_alloc_evtchn(dev_info_t *); 1085084Sjohnlev int xvdi_bind_evtchn(dev_info_t *, evtchn_port_t); 1095084Sjohnlev void xvdi_free_evtchn(dev_info_t *); 1105084Sjohnlev int xvdi_add_event_handler(dev_info_t *, char *, 1115084Sjohnlev void (*)(dev_info_t *, ddi_eventcookie_t, void *, void *)); 1125084Sjohnlev void xvdi_remove_event_handler(dev_info_t *, char *); 1135084Sjohnlev int xvdi_get_evtchn(dev_info_t *); 1145084Sjohnlev int xvdi_get_vdevnum(dev_info_t *); 1155084Sjohnlev char *xvdi_get_xsname(dev_info_t *); 1165084Sjohnlev char *xvdi_get_oename(dev_info_t *); 1175084Sjohnlev domid_t xvdi_get_oeid(dev_info_t *); 1185084Sjohnlev void xvdi_dev_error(dev_info_t *, int, char *); 1195084Sjohnlev void xvdi_fatal_error(dev_info_t *, int, char *); 1205084Sjohnlev void xvdi_notify_oe(dev_info_t *); 1215084Sjohnlev int xvdi_post_event(dev_info_t *, xendev_hotplug_cmd_t); 1225084Sjohnlev struct xenbus_device *xvdi_get_xsd(dev_info_t *); 1235084Sjohnlev int xvdi_switch_state(dev_info_t *, xenbus_transaction_t, XenbusState); 1245084Sjohnlev dev_info_t *xvdi_create_dev(dev_info_t *, xendev_devclass_t, 1255084Sjohnlev domid_t, int); 1265084Sjohnlev int xvdi_init_dev(dev_info_t *); 1275084Sjohnlev void xvdi_uninit_dev(dev_info_t *); 1285084Sjohnlev dev_info_t *xvdi_find_dev(dev_info_t *, xendev_devclass_t, domid_t, int); 1295084Sjohnlev 1305084Sjohnlev /* 1315084Sjohnlev * common ring interfaces 1325084Sjohnlev */ 1335084Sjohnlev 1345084Sjohnlev /* 1355084Sjohnlev * we need the pad between ring index 1365084Sjohnlev * and the real ring containing requests/responses, 1375084Sjohnlev * so that we can map comif_sring_t structure to 1385084Sjohnlev * any xxxif_sring_t structure defined via macros in ring.h 1395084Sjohnlev */ 1405084Sjohnlev #define SRINGPAD 48 1415084Sjohnlev 1425084Sjohnlev typedef struct comif_sring { 1435084Sjohnlev RING_IDX req_prod, req_event; 1445084Sjohnlev RING_IDX rsp_prod, rsp_event; 1455084Sjohnlev uint8_t pad[SRINGPAD]; 1465084Sjohnlev /* 1475084Sjohnlev * variable length 1485084Sjohnlev * stores real request/response entries 1495084Sjohnlev * entry size is fixed per ring 1505084Sjohnlev */ 1515084Sjohnlev char ring[1]; 1525084Sjohnlev } comif_sring_t; 1535084Sjohnlev 1545084Sjohnlev typedef struct comif_ring_fe { 1555084Sjohnlev /* 1565084Sjohnlev * keep the member names as defined in ring.h 1575084Sjohnlev * in order to make use of the pre-defined macros 1585084Sjohnlev */ 1595084Sjohnlev RING_IDX req_prod_pvt; 1605084Sjohnlev RING_IDX rsp_cons; 1615084Sjohnlev unsigned int nr_ents; 1625084Sjohnlev comif_sring_t *sring; 1635084Sjohnlev } comif_ring_fe_t; 1645084Sjohnlev 1655084Sjohnlev typedef struct comif_ring_be { 1665084Sjohnlev /* 1675084Sjohnlev * keep the member names as defined in ring.h 1685084Sjohnlev * in order to make use of the pre-defined macros 1695084Sjohnlev */ 1705084Sjohnlev RING_IDX rsp_prod_pvt; 1715084Sjohnlev RING_IDX req_cons; 1725084Sjohnlev unsigned int nr_ents; 1735084Sjohnlev comif_sring_t *sring; 1745084Sjohnlev } comif_ring_be_t; 1755084Sjohnlev 1765084Sjohnlev typedef union comif_ring { 1775084Sjohnlev comif_ring_fe_t fr; 1785084Sjohnlev comif_ring_be_t br; 1795084Sjohnlev } comif_ring_t; 1805084Sjohnlev 1815084Sjohnlev typedef struct xendev_req { 1825084Sjohnlev unsigned long next; 1835084Sjohnlev void *req; 1845084Sjohnlev } xendev_req_t; 1855084Sjohnlev 1865084Sjohnlev typedef struct xendev_ring { 1875084Sjohnlev ddi_dma_handle_t xr_dma_hdl; 1885084Sjohnlev ddi_acc_handle_t xr_acc_hdl; 1895084Sjohnlev grant_handle_t xr_grant_hdl; 1905084Sjohnlev caddr_t xr_vaddr; 1915084Sjohnlev paddr_t xr_paddr; 1925084Sjohnlev grant_ref_t xr_gref; 1935084Sjohnlev int xr_entry_size; 1945084Sjohnlev int xr_frontend; 1955084Sjohnlev comif_ring_t xr_sring; 1965084Sjohnlev } xendev_ring_t; 1975084Sjohnlev 1985084Sjohnlev int xvdi_alloc_ring(dev_info_t *, size_t, size_t, grant_ref_t *, 1995084Sjohnlev xendev_ring_t **); 2005084Sjohnlev void xvdi_free_ring(xendev_ring_t *); 2015084Sjohnlev int xvdi_map_ring(dev_info_t *, size_t, size_t, grant_ref_t, 2025084Sjohnlev xendev_ring_t **); 2035084Sjohnlev void xvdi_unmap_ring(xendev_ring_t *); 2045084Sjohnlev uint_t xvdi_ring_avail_slots(xendev_ring_t *); 2055084Sjohnlev int xvdi_ring_has_unconsumed_requests(xendev_ring_t *); 2065084Sjohnlev int xvdi_ring_has_incomp_request(xendev_ring_t *); 2075084Sjohnlev int xvdi_ring_has_unconsumed_responses(xendev_ring_t *); 2085084Sjohnlev void* xvdi_ring_get_request(xendev_ring_t *); 2095084Sjohnlev int xvdi_ring_push_request(xendev_ring_t *); 2105084Sjohnlev void* xvdi_ring_get_response(xendev_ring_t *); 2115084Sjohnlev int xvdi_ring_push_response(xendev_ring_t *); 2125084Sjohnlev 2135084Sjohnlev #ifdef __cplusplus 2145084Sjohnlev } 2155084Sjohnlev #endif 2165084Sjohnlev 2175084Sjohnlev #endif /* _SYS_XENDEV_H */ 218