xpvtap.h revision 7eea693d6b672899726e75993fddc4e95b52647f
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_XPVTAP_H
#define _SYS_XPVTAP_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
/* Notification from user app that it has pushed responses */
#define XPVTAP_IOCTL_RESP_PUSH 1
/* Number of bytes the user app should mmap for the gref pages */
#define XPVTAP_GREF_BUFSIZE \
(BLKIF_RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGESIZE)
#ifdef _KERNEL
#include <xen/io/blk_common.h>
#define XPVTAP_GREF_REQADDR(base, id) (caddr_t) \
((uintptr_t)base + (id * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGESIZE))
/* structure used to keep track of resources */
typedef struct xpvtap_rs_s {
/*
* Bounds of resource allocation. We will start allocating at rs_min
* and rollover at rs_max+1 (rs_max is included). e.g. for rs_min=0
* and rs_max=7, we will have 8 total resources which can be alloced.
*/
uint_t rs_min;
uint_t rs_max;
/*
* rs_free points to an array of 64-bit values used to track resource
* allocation. rs_free_size is the free buffer size in bytes.
*/
uint64_t *rs_free;
uint_t rs_free_size;
/*
* last tracks the last alloc'd resource. This allows us to do a round
* robin allocation.
*/
uint_t rs_last;
/*
* set when flushing all allocated resources. We'll know the lock
* is held.
*/
boolean_t rs_flushing;
kmutex_t rs_mutex;
} xpvtap_rs_t;
typedef struct xpvtap_rs_s *xpvtap_rs_hdl_t;
/* track if user app has the device open, and sleep waiting for close */
typedef struct xpvtap_open_s {
kmutex_t bo_mutex;
boolean_t bo_opened;
kcondvar_t bo_exit_cv;
} xpvtap_open_t;
/*
* ring between driver and user app. requests are forwared from the
* guest to the user app on this ring. reponses from the user app come in
* on this ring are then are forwarded to the guest.
*/
typedef struct xpvtap_user_ring_s {
/* ring state */
blkif_front_ring_t ur_ring;
/*
* pointer to allocated memory for the ring which is shared between
* the driver and the app.
*/
blkif_sring_t *ur_sring;
/* umem cookie for free'ing up the umem */
ddi_umem_cookie_t ur_cookie;
RING_IDX ur_prod_polled;
} xpvtap_user_ring_t;
/*
* track the requests that come in from the guest. we need to track the
* requests for two reasons. first, we need to know how many grefs we need
* to unmap when the app sends the response. second, since we use the ID in
* the request to index into um_guest_pages (tells the app where the segments
* are mapped), we need to have a mapping between the the ID we sent in the
* request to the app and the ID we got from the guest request. The response
* to the guest needs to have the later.
*/
typedef struct xpvtap_user_map_s {
/* address space of the user app. grab this in open */
struct as *um_as;
/* state to track request IDs we can send to the user app */
xpvtap_rs_hdl_t um_rs;
/*
* base user app VA of the mapped grefs. this VA space is large enough
* to map the max pages per request * max outstanding requests.
*/
caddr_t um_guest_pages;
size_t um_guest_size;
/*
* have we locked down the gref buffer's ptes and registered
* them with segmf. This needs to happen after the user app
* has mmaped the gref buf.
*/
boolean_t um_registered;
/*
* array of outstanding requests to the user app. Index into this
* array using the ID in the user app request.
*/
blkif_request_t *um_outstanding_reqs;
} xpvtap_user_map_t;
/* thread start, wake, exit state */
typedef struct xpvtap_user_thread_s {
kmutex_t ut_mutex;
kcondvar_t ut_wake_cv;
volatile boolean_t ut_wake;
volatile boolean_t ut_exit;
kcondvar_t ut_exit_done_cv;
volatile boolean_t ut_exit_done;
ddi_taskq_t *ut_taskq;
} xpvtap_user_thread_t;
/* driver state */
typedef struct xpvtap_state_s {
dev_info_t *bt_dip;
int bt_instance;
/* ring between the guest and xpvtap */
blk_ring_t bt_guest_ring;
/* ring between xpvtap and the user app */
xpvtap_user_ring_t bt_user_ring;
xpvtap_user_map_t bt_map;
xpvtap_user_thread_t bt_thread;
struct pollhead bt_pollhead;
xpvtap_open_t bt_open;
} xpvtap_state_t;
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_XPVTAP_H */