1227652Sgrehan/*- 2252707Sbryanv * Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org> 3227652Sgrehan * All rights reserved. 4227652Sgrehan * 5227652Sgrehan * Redistribution and use in source and binary forms, with or without 6227652Sgrehan * modification, are permitted provided that the following conditions 7227652Sgrehan * are met: 8227652Sgrehan * 1. Redistributions of source code must retain the above copyright 9227652Sgrehan * notice unmodified, this list of conditions, and the following 10227652Sgrehan * disclaimer. 11227652Sgrehan * 2. Redistributions in binary form must reproduce the above copyright 12227652Sgrehan * notice, this list of conditions and the following disclaimer in the 13227652Sgrehan * documentation and/or other materials provided with the distribution. 14227652Sgrehan * 15227652Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16227652Sgrehan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17227652Sgrehan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18227652Sgrehan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19227652Sgrehan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20227652Sgrehan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21227652Sgrehan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22227652Sgrehan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23227652Sgrehan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24227652Sgrehan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25227652Sgrehan * 26227652Sgrehan * $FreeBSD: releng/11.0/sys/dev/virtio/virtqueue.h 268480 2014-07-10 05:26:01Z bryanv $ 27227652Sgrehan */ 28227652Sgrehan 29227652Sgrehan#ifndef _VIRTIO_VIRTQUEUE_H 30227652Sgrehan#define _VIRTIO_VIRTQUEUE_H 31227652Sgrehan 32227652Sgrehanstruct virtqueue; 33227652Sgrehanstruct sglist; 34227652Sgrehan 35227652Sgrehan/* Device callback for a virtqueue interrupt. */ 36252702Sbryanvtypedef void virtqueue_intr_t(void *); 37227652Sgrehan 38255109Sbryanv/* 39255109Sbryanv * Hint on how long the next interrupt should be postponed. This is 40255109Sbryanv * only used when the EVENT_IDX feature is negotiated. 41255109Sbryanv */ 42255109Sbryanvtypedef enum { 43255109Sbryanv VQ_POSTPONE_SHORT, 44255109Sbryanv VQ_POSTPONE_LONG, 45255109Sbryanv VQ_POSTPONE_EMPTIED /* Until all available desc are used. */ 46255109Sbryanv} vq_postpone_t; 47255109Sbryanv 48227652Sgrehan#define VIRTQUEUE_MAX_NAME_SZ 32 49227652Sgrehan 50227652Sgrehan/* One for each virtqueue the device wishes to allocate. */ 51227652Sgrehanstruct vq_alloc_info { 52227652Sgrehan char vqai_name[VIRTQUEUE_MAX_NAME_SZ]; 53227652Sgrehan int vqai_maxindirsz; 54227652Sgrehan virtqueue_intr_t *vqai_intr; 55227652Sgrehan void *vqai_intr_arg; 56227652Sgrehan struct virtqueue **vqai_vq; 57227652Sgrehan}; 58227652Sgrehan 59227652Sgrehan#define VQ_ALLOC_INFO_INIT(_i,_nsegs,_intr,_arg,_vqp,_str,...) do { \ 60227652Sgrehan snprintf((_i)->vqai_name, VIRTQUEUE_MAX_NAME_SZ, _str, \ 61227652Sgrehan ##__VA_ARGS__); \ 62227652Sgrehan (_i)->vqai_maxindirsz = (_nsegs); \ 63227652Sgrehan (_i)->vqai_intr = (_intr); \ 64227652Sgrehan (_i)->vqai_intr_arg = (_arg); \ 65227652Sgrehan (_i)->vqai_vq = (_vqp); \ 66227652Sgrehan} while (0) 67227652Sgrehan 68227652Sgrehanuint64_t virtqueue_filter_features(uint64_t features); 69227652Sgrehan 70227652Sgrehanint virtqueue_alloc(device_t dev, uint16_t queue, uint16_t size, 71227652Sgrehan int align, vm_paddr_t highaddr, struct vq_alloc_info *info, 72227652Sgrehan struct virtqueue **vqp); 73227652Sgrehanvoid *virtqueue_drain(struct virtqueue *vq, int *last); 74227652Sgrehanvoid virtqueue_free(struct virtqueue *vq); 75227652Sgrehanint virtqueue_reinit(struct virtqueue *vq, uint16_t size); 76227652Sgrehan 77252702Sbryanvint virtqueue_intr_filter(struct virtqueue *vq); 78252702Sbryanvvoid virtqueue_intr(struct virtqueue *vq); 79227652Sgrehanint virtqueue_enable_intr(struct virtqueue *vq); 80255109Sbryanvint virtqueue_postpone_intr(struct virtqueue *vq, vq_postpone_t hint); 81227652Sgrehanvoid virtqueue_disable_intr(struct virtqueue *vq); 82227652Sgrehan 83227652Sgrehan/* Get physical address of the virtqueue ring. */ 84227652Sgrehanvm_paddr_t virtqueue_paddr(struct virtqueue *vq); 85227652Sgrehan 86227652Sgrehanint virtqueue_full(struct virtqueue *vq); 87227652Sgrehanint virtqueue_empty(struct virtqueue *vq); 88227652Sgrehanint virtqueue_size(struct virtqueue *vq); 89268480Sbryanvint virtqueue_nfree(struct virtqueue *vq); 90227652Sgrehanint virtqueue_nused(struct virtqueue *vq); 91227652Sgrehanvoid virtqueue_notify(struct virtqueue *vq); 92227652Sgrehanvoid virtqueue_dump(struct virtqueue *vq); 93227652Sgrehan 94227652Sgrehanint virtqueue_enqueue(struct virtqueue *vq, void *cookie, 95227652Sgrehan struct sglist *sg, int readable, int writable); 96227652Sgrehanvoid *virtqueue_dequeue(struct virtqueue *vq, uint32_t *len); 97227652Sgrehanvoid *virtqueue_poll(struct virtqueue *vq, uint32_t *len); 98227652Sgrehan 99227652Sgrehan#endif /* _VIRTIO_VIRTQUEUE_H */ 100