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