1*7eea693dSMark Johnson /* 2*7eea693dSMark Johnson * CDDL HEADER START 3*7eea693dSMark Johnson * 4*7eea693dSMark Johnson * The contents of this file are subject to the terms of the 5*7eea693dSMark Johnson * Common Development and Distribution License (the "License"). 6*7eea693dSMark Johnson * You may not use this file except in compliance with the License. 7*7eea693dSMark Johnson * 8*7eea693dSMark Johnson * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7eea693dSMark Johnson * or http://www.opensolaris.org/os/licensing. 10*7eea693dSMark Johnson * See the License for the specific language governing permissions 11*7eea693dSMark Johnson * and limitations under the License. 12*7eea693dSMark Johnson * 13*7eea693dSMark Johnson * When distributing Covered Code, include this CDDL HEADER in each 14*7eea693dSMark Johnson * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7eea693dSMark Johnson * If applicable, add the following below this CDDL HEADER, with the 16*7eea693dSMark Johnson * fields enclosed by brackets "[]" replaced with your own identifying 17*7eea693dSMark Johnson * information: Portions Copyright [yyyy] [name of copyright owner] 18*7eea693dSMark Johnson * 19*7eea693dSMark Johnson * CDDL HEADER END 20*7eea693dSMark Johnson */ 21*7eea693dSMark Johnson 22*7eea693dSMark Johnson /* 23*7eea693dSMark Johnson * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24*7eea693dSMark Johnson * Use is subject to license terms. 25*7eea693dSMark Johnson */ 26*7eea693dSMark Johnson 27*7eea693dSMark Johnson #ifndef _SYS_XPVTAP_H 28*7eea693dSMark Johnson #define _SYS_XPVTAP_H 29*7eea693dSMark Johnson 30*7eea693dSMark Johnson 31*7eea693dSMark Johnson #ifdef __cplusplus 32*7eea693dSMark Johnson extern "C" { 33*7eea693dSMark Johnson #endif 34*7eea693dSMark Johnson 35*7eea693dSMark Johnson #include <sys/types.h> 36*7eea693dSMark Johnson 37*7eea693dSMark Johnson /* Notification from user app that it has pushed responses */ 38*7eea693dSMark Johnson #define XPVTAP_IOCTL_RESP_PUSH 1 39*7eea693dSMark Johnson 40*7eea693dSMark Johnson /* Number of bytes the user app should mmap for the gref pages */ 41*7eea693dSMark Johnson #define XPVTAP_GREF_BUFSIZE \ 42*7eea693dSMark Johnson (BLKIF_RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGESIZE) 43*7eea693dSMark Johnson 44*7eea693dSMark Johnson 45*7eea693dSMark Johnson #ifdef _KERNEL 46*7eea693dSMark Johnson 47*7eea693dSMark Johnson #include <xen/io/blk_common.h> 48*7eea693dSMark Johnson 49*7eea693dSMark Johnson 50*7eea693dSMark Johnson #define XPVTAP_GREF_REQADDR(base, id) (caddr_t) \ 51*7eea693dSMark Johnson ((uintptr_t)base + (id * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGESIZE)) 52*7eea693dSMark Johnson 53*7eea693dSMark Johnson /* structure used to keep track of resources */ 54*7eea693dSMark Johnson typedef struct xpvtap_rs_s { 55*7eea693dSMark Johnson /* 56*7eea693dSMark Johnson * Bounds of resource allocation. We will start allocating at rs_min 57*7eea693dSMark Johnson * and rollover at rs_max+1 (rs_max is included). e.g. for rs_min=0 58*7eea693dSMark Johnson * and rs_max=7, we will have 8 total resources which can be alloced. 59*7eea693dSMark Johnson */ 60*7eea693dSMark Johnson uint_t rs_min; 61*7eea693dSMark Johnson uint_t rs_max; 62*7eea693dSMark Johnson 63*7eea693dSMark Johnson /* 64*7eea693dSMark Johnson * rs_free points to an array of 64-bit values used to track resource 65*7eea693dSMark Johnson * allocation. rs_free_size is the free buffer size in bytes. 66*7eea693dSMark Johnson */ 67*7eea693dSMark Johnson uint64_t *rs_free; 68*7eea693dSMark Johnson uint_t rs_free_size; 69*7eea693dSMark Johnson 70*7eea693dSMark Johnson /* 71*7eea693dSMark Johnson * last tracks the last alloc'd resource. This allows us to do a round 72*7eea693dSMark Johnson * robin allocation. 73*7eea693dSMark Johnson */ 74*7eea693dSMark Johnson uint_t rs_last; 75*7eea693dSMark Johnson 76*7eea693dSMark Johnson /* 77*7eea693dSMark Johnson * set when flushing all allocated resources. We'll know the lock 78*7eea693dSMark Johnson * is held. 79*7eea693dSMark Johnson */ 80*7eea693dSMark Johnson boolean_t rs_flushing; 81*7eea693dSMark Johnson 82*7eea693dSMark Johnson kmutex_t rs_mutex; 83*7eea693dSMark Johnson } xpvtap_rs_t; 84*7eea693dSMark Johnson typedef struct xpvtap_rs_s *xpvtap_rs_hdl_t; 85*7eea693dSMark Johnson 86*7eea693dSMark Johnson /* track if user app has the device open, and sleep waiting for close */ 87*7eea693dSMark Johnson typedef struct xpvtap_open_s { 88*7eea693dSMark Johnson kmutex_t bo_mutex; 89*7eea693dSMark Johnson boolean_t bo_opened; 90*7eea693dSMark Johnson kcondvar_t bo_exit_cv; 91*7eea693dSMark Johnson } xpvtap_open_t; 92*7eea693dSMark Johnson 93*7eea693dSMark Johnson /* 94*7eea693dSMark Johnson * ring between driver and user app. requests are forwared from the 95*7eea693dSMark Johnson * guest to the user app on this ring. reponses from the user app come in 96*7eea693dSMark Johnson * on this ring are then are forwarded to the guest. 97*7eea693dSMark Johnson */ 98*7eea693dSMark Johnson typedef struct xpvtap_user_ring_s { 99*7eea693dSMark Johnson /* ring state */ 100*7eea693dSMark Johnson blkif_front_ring_t ur_ring; 101*7eea693dSMark Johnson 102*7eea693dSMark Johnson /* 103*7eea693dSMark Johnson * pointer to allocated memory for the ring which is shared between 104*7eea693dSMark Johnson * the driver and the app. 105*7eea693dSMark Johnson */ 106*7eea693dSMark Johnson blkif_sring_t *ur_sring; 107*7eea693dSMark Johnson 108*7eea693dSMark Johnson /* umem cookie for free'ing up the umem */ 109*7eea693dSMark Johnson ddi_umem_cookie_t ur_cookie; 110*7eea693dSMark Johnson 111*7eea693dSMark Johnson RING_IDX ur_prod_polled; 112*7eea693dSMark Johnson } xpvtap_user_ring_t; 113*7eea693dSMark Johnson 114*7eea693dSMark Johnson /* 115*7eea693dSMark Johnson * track the requests that come in from the guest. we need to track the 116*7eea693dSMark Johnson * requests for two reasons. first, we need to know how many grefs we need 117*7eea693dSMark Johnson * to unmap when the app sends the response. second, since we use the ID in 118*7eea693dSMark Johnson * the request to index into um_guest_pages (tells the app where the segments 119*7eea693dSMark Johnson * are mapped), we need to have a mapping between the the ID we sent in the 120*7eea693dSMark Johnson * request to the app and the ID we got from the guest request. The response 121*7eea693dSMark Johnson * to the guest needs to have the later. 122*7eea693dSMark Johnson */ 123*7eea693dSMark Johnson typedef struct xpvtap_user_map_s { 124*7eea693dSMark Johnson /* address space of the user app. grab this in open */ 125*7eea693dSMark Johnson struct as *um_as; 126*7eea693dSMark Johnson 127*7eea693dSMark Johnson /* state to track request IDs we can send to the user app */ 128*7eea693dSMark Johnson xpvtap_rs_hdl_t um_rs; 129*7eea693dSMark Johnson 130*7eea693dSMark Johnson /* 131*7eea693dSMark Johnson * base user app VA of the mapped grefs. this VA space is large enough 132*7eea693dSMark Johnson * to map the max pages per request * max outstanding requests. 133*7eea693dSMark Johnson */ 134*7eea693dSMark Johnson caddr_t um_guest_pages; 135*7eea693dSMark Johnson size_t um_guest_size; 136*7eea693dSMark Johnson 137*7eea693dSMark Johnson /* 138*7eea693dSMark Johnson * have we locked down the gref buffer's ptes and registered 139*7eea693dSMark Johnson * them with segmf. This needs to happen after the user app 140*7eea693dSMark Johnson * has mmaped the gref buf. 141*7eea693dSMark Johnson */ 142*7eea693dSMark Johnson boolean_t um_registered; 143*7eea693dSMark Johnson 144*7eea693dSMark Johnson /* 145*7eea693dSMark Johnson * array of outstanding requests to the user app. Index into this 146*7eea693dSMark Johnson * array using the ID in the user app request. 147*7eea693dSMark Johnson */ 148*7eea693dSMark Johnson blkif_request_t *um_outstanding_reqs; 149*7eea693dSMark Johnson } xpvtap_user_map_t; 150*7eea693dSMark Johnson 151*7eea693dSMark Johnson /* thread start, wake, exit state */ 152*7eea693dSMark Johnson typedef struct xpvtap_user_thread_s { 153*7eea693dSMark Johnson kmutex_t ut_mutex; 154*7eea693dSMark Johnson kcondvar_t ut_wake_cv; 155*7eea693dSMark Johnson volatile boolean_t ut_wake; 156*7eea693dSMark Johnson volatile boolean_t ut_exit; 157*7eea693dSMark Johnson kcondvar_t ut_exit_done_cv; 158*7eea693dSMark Johnson volatile boolean_t ut_exit_done; 159*7eea693dSMark Johnson ddi_taskq_t *ut_taskq; 160*7eea693dSMark Johnson } xpvtap_user_thread_t; 161*7eea693dSMark Johnson 162*7eea693dSMark Johnson /* driver state */ 163*7eea693dSMark Johnson typedef struct xpvtap_state_s { 164*7eea693dSMark Johnson dev_info_t *bt_dip; 165*7eea693dSMark Johnson int bt_instance; 166*7eea693dSMark Johnson 167*7eea693dSMark Johnson /* ring between the guest and xpvtap */ 168*7eea693dSMark Johnson blk_ring_t bt_guest_ring; 169*7eea693dSMark Johnson 170*7eea693dSMark Johnson /* ring between xpvtap and the user app */ 171*7eea693dSMark Johnson xpvtap_user_ring_t bt_user_ring; 172*7eea693dSMark Johnson 173*7eea693dSMark Johnson xpvtap_user_map_t bt_map; 174*7eea693dSMark Johnson xpvtap_user_thread_t bt_thread; 175*7eea693dSMark Johnson struct pollhead bt_pollhead; 176*7eea693dSMark Johnson xpvtap_open_t bt_open; 177*7eea693dSMark Johnson } xpvtap_state_t; 178*7eea693dSMark Johnson 179*7eea693dSMark Johnson #endif /* _KERNEL */ 180*7eea693dSMark Johnson 181*7eea693dSMark Johnson #ifdef __cplusplus 182*7eea693dSMark Johnson } 183*7eea693dSMark Johnson #endif 184*7eea693dSMark Johnson 185*7eea693dSMark Johnson #endif /* _SYS_XPVTAP_H */ 186