xref: /titanic_50/usr/src/uts/common/io/virtio/virtiovar.h (revision 9f9b7953c22ba8b0f8372bd791fc6ecc63c69409)
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 	int			sc_int_type;
149 };
150 
151 struct virtio_int_handler {
152 	ddi_intr_handler_t *vh_func;
153 	void *vh_priv;
154 };
155 
156 /* public interface */
157 uint32_t virtio_negotiate_features(struct virtio_softc *, uint32_t);
158 size_t virtio_show_features(uint32_t features, char *buffer, size_t len);
159 boolean_t virtio_has_feature(struct virtio_softc *sc, uint32_t feature);
160 void virtio_set_status(struct virtio_softc *sc, unsigned int);
161 #define	virtio_device_reset(sc)	virtio_set_status((sc), 0)
162 
163 uint8_t virtio_read_device_config_1(struct virtio_softc *sc,
164 		unsigned int index);
165 uint16_t virtio_read_device_config_2(struct virtio_softc *sc,
166 		unsigned int index);
167 uint32_t virtio_read_device_config_4(struct virtio_softc *sc,
168 		unsigned int index);
169 uint64_t virtio_read_device_config_8(struct virtio_softc *sc,
170 		unsigned int index);
171 void virtio_write_device_config_1(struct virtio_softc *sc,
172 		unsigned int index, uint8_t value);
173 void virtio_write_device_config_2(struct virtio_softc *sc,
174 		unsigned int index, uint16_t value);
175 void virtio_write_device_config_4(struct virtio_softc *sc,
176 		unsigned int index, uint32_t value);
177 void virtio_write_device_config_8(struct virtio_softc *sc,
178 		unsigned int index, uint64_t value);
179 
180 struct virtqueue *virtio_alloc_vq(struct virtio_softc *sc,
181 		unsigned int index, unsigned int size,
182 		unsigned int indirect_num, const char *name);
183 void virtio_free_vq(struct virtqueue *);
184 void virtio_reset(struct virtio_softc *);
185 struct vq_entry *vq_alloc_entry(struct virtqueue *vq);
186 void vq_free_entry(struct virtqueue *vq, struct vq_entry *qe);
187 uint_t vq_num_used(struct virtqueue *vq);
188 unsigned int virtio_ve_indirect_available(struct vq_entry *qe);
189 
190 void virtio_stop_vq_intr(struct virtqueue *);
191 void virtio_start_vq_intr(struct virtqueue *);
192 
193 void virtio_ve_add_cookie(struct vq_entry *qe, ddi_dma_handle_t dma_handle,
194     ddi_dma_cookie_t dma_cookie, unsigned int ncookies, boolean_t write);
195 void virtio_ve_add_indirect_buf(struct vq_entry *qe, uint64_t paddr,
196     uint32_t len, boolean_t write);
197 void virtio_ve_set(struct vq_entry *qe, uint64_t paddr, uint32_t len,
198 		boolean_t write);
199 
200 void virtio_push_chain(struct vq_entry *qe, boolean_t sync);
201 struct vq_entry *virtio_pull_chain(struct virtqueue *vq, uint32_t *len);
202 void virtio_free_chain(struct vq_entry *ve);
203 void virtio_sync_vq(struct virtqueue *vq);
204 
205 int virtio_register_ints(struct virtio_softc *sc,
206 		struct virtio_int_handler *config_handler,
207 		struct virtio_int_handler vq_handlers[]);
208 void virtio_release_ints(struct virtio_softc *sc);
209 int virtio_enable_ints(struct virtio_softc *sc);
210 
211 #endif /* __VIRTIOVAR_H__ */
212