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