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