1 /* 2 * Copyright (c) 2010 Minoura Makoto. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 /* 27 * Part of the file derived from `Virtio PCI Card Specification v0.8.6 DRAFT' 28 * Appendix A. 29 */ 30 31 /* 32 * An interface for efficient virtio implementation. 33 * 34 * This header is BSD licensed so anyone can use the definitions 35 * to implement compatible drivers/servers. 36 * 37 * Copyright 2007, 2009, IBM Corporation 38 * All rights reserved. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. Neither the name of IBM nor the names of its contributors 49 * may be used to endorse or promote products derived from this software 50 * without specific prior written permission. 51 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 52 * ``AS IS'' ANDANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * SUCH DAMAGE. 62 */ 63 64 /* 65 * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 66 */ 67 68 #ifndef __VIRTIOVAR_H__ 69 #define __VIRTIOVAR_H__ 70 71 #include <sys/types.h> 72 #include <sys/dditypes.h> 73 #include <sys/cmn_err.h> 74 #include <sys/list.h> 75 76 #ifdef DEBUG 77 #define dev_debug(dip, fmt, arg...) \ 78 dev_err(dip, fmt, ##arg) 79 #else 80 #define dev_debug(dip, fmt, arg...) 81 #endif 82 83 struct vq_entry { 84 list_node_t qe_list; 85 struct virtqueue *qe_queue; 86 uint16_t qe_index; /* index in vq_desc array */ 87 /* followings are used only when it is the `head' entry */ 88 struct vq_entry *qe_next; 89 struct vring_desc *qe_desc; 90 ddi_dma_cookie_t qe_indirect_dma_cookie; 91 ddi_dma_handle_t qe_indirect_dma_handle; 92 ddi_acc_handle_t qe_indirect_dma_acch; 93 struct vring_desc *qe_indirect_descs; 94 unsigned int qe_indirect_next; 95 }; 96 97 struct virtqueue { 98 struct virtio_softc *vq_owner; 99 unsigned int vq_num; /* queue size (# of entries) */ 100 unsigned int vq_indirect_num; 101 int vq_index; /* queue number (0, 1, ...) */ 102 103 /* vring pointers (KVA) */ 104 struct vring_desc *vq_descs; 105 struct vring_avail *vq_avail; 106 struct vring_used *vq_used; 107 108 /* virtqueue allocation info */ 109 void *vq_vaddr; 110 int vq_availoffset; 111 int vq_usedoffset; 112 ddi_dma_cookie_t vq_dma_cookie; 113 ddi_dma_handle_t vq_dma_handle; 114 ddi_acc_handle_t vq_dma_acch; 115 116 int vq_maxsegsize; 117 118 /* free entry management */ 119 struct vq_entry *vq_entries; 120 list_t vq_freelist; 121 kmutex_t vq_freelist_lock; 122 int vq_used_entries; 123 124 /* enqueue/dequeue status */ 125 uint16_t vq_avail_idx; 126 kmutex_t vq_avail_lock; 127 uint16_t vq_used_idx; 128 kmutex_t vq_used_lock; 129 }; 130 131 struct virtio_softc { 132 dev_info_t *sc_dev; 133 134 uint_t sc_intr_prio; 135 136 ddi_acc_handle_t sc_ioh; 137 caddr_t sc_io_addr; 138 int sc_config_offset; 139 140 uint32_t sc_features; 141 142 int sc_nvqs; /* set by the user */ 143 144 ddi_intr_handle_t *sc_intr_htable; 145 int sc_intr_num; 146 boolean_t sc_intr_config; 147 int sc_intr_cap; 148 }; 149 150 struct virtio_int_handler { 151 ddi_intr_handler_t *vh_func; 152 void *vh_priv; 153 }; 154 155 /* public interface */ 156 uint32_t virtio_negotiate_features(struct virtio_softc *, uint32_t); 157 size_t virtio_show_features(uint32_t features, char *buffer, size_t len); 158 boolean_t virtio_has_feature(struct virtio_softc *sc, uint32_t feature); 159 void virtio_set_status(struct virtio_softc *sc, unsigned int); 160 #define virtio_device_reset(sc) virtio_set_status((sc), 0) 161 162 uint8_t virtio_read_device_config_1(struct virtio_softc *sc, 163 unsigned int index); 164 uint16_t virtio_read_device_config_2(struct virtio_softc *sc, 165 unsigned int index); 166 uint32_t virtio_read_device_config_4(struct virtio_softc *sc, 167 unsigned int index); 168 uint64_t virtio_read_device_config_8(struct virtio_softc *sc, 169 unsigned int index); 170 void virtio_write_device_config_1(struct virtio_softc *sc, 171 unsigned int index, uint8_t value); 172 void virtio_write_device_config_2(struct virtio_softc *sc, 173 unsigned int index, uint16_t value); 174 void virtio_write_device_config_4(struct virtio_softc *sc, 175 unsigned int index, uint32_t value); 176 void virtio_write_device_config_8(struct virtio_softc *sc, 177 unsigned int index, uint64_t value); 178 179 struct virtqueue *virtio_alloc_vq(struct virtio_softc *sc, 180 unsigned int index, unsigned int size, 181 unsigned int indirect_num, const char *name); 182 void virtio_free_vq(struct virtqueue *); 183 void virtio_reset(struct virtio_softc *); 184 struct vq_entry *vq_alloc_entry(struct virtqueue *vq); 185 void vq_free_entry(struct virtqueue *vq, struct vq_entry *qe); 186 uint_t vq_num_used(struct virtqueue *vq); 187 unsigned int virtio_ve_indirect_available(struct vq_entry *qe); 188 189 void virtio_stop_vq_intr(struct virtqueue *); 190 void virtio_start_vq_intr(struct virtqueue *); 191 192 void virtio_ve_add_cookie(struct vq_entry *qe, ddi_dma_handle_t dma_handle, 193 ddi_dma_cookie_t dma_cookie, unsigned int ncookies, boolean_t write); 194 void virtio_ve_add_indirect_buf(struct vq_entry *qe, uint64_t paddr, 195 uint32_t len, boolean_t write); 196 void virtio_ve_set(struct vq_entry *qe, uint64_t paddr, uint32_t len, 197 boolean_t write); 198 199 void virtio_push_chain(struct vq_entry *qe, boolean_t sync); 200 struct vq_entry *virtio_pull_chain(struct virtqueue *vq, uint32_t *len); 201 void virtio_free_chain(struct vq_entry *ve); 202 void virtio_sync_vq(struct virtqueue *vq); 203 204 int virtio_register_ints(struct virtio_softc *sc, 205 struct virtio_int_handler *config_handler, 206 struct virtio_int_handler vq_handlers[]); 207 void virtio_release_ints(struct virtio_softc *sc); 208 int virtio_enable_ints(struct virtio_softc *sc); 209 210 #endif /* __VIRTIOVAR_H__ */ 211