virtio.c revision 1.7.2.8 1 /* $NetBSD: virtio.c,v 1.7.2.8 2017/08/28 17:52:25 skrll Exp $ */
2
3 /*
4 * Copyright (c) 2010 Minoura Makoto.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.7.2.8 2017/08/28 17:52:25 skrll Exp $");
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/atomic.h>
35 #include <sys/bus.h>
36 #include <sys/device.h>
37 #include <sys/kmem.h>
38 #include <sys/module.h>
39
40 #include <dev/pci/pcidevs.h>
41 #include <dev/pci/pcireg.h>
42 #include <dev/pci/pcivar.h>
43
44 #define VIRTIO_PRIVATE
45
46 #include <dev/pci/virtioreg.h> /* XXX: move to non-pci */
47 #include <dev/pci/virtiovar.h> /* XXX: move to non-pci */
48
49 #define MINSEG_INDIRECT 2 /* use indirect if nsegs >= this value */
50
51 static int virtio_intr(void *arg);
52 static int virtio_msix_queue_intr(void *);
53 static int virtio_msix_config_intr(void *);
54 static int virtio_setup_msix_vectors(struct virtio_softc *);
55 static int virtio_setup_msix_interrupts(struct virtio_softc *,
56 struct pci_attach_args *);
57 static int virtio_setup_intx_interrupt(struct virtio_softc *,
58 struct pci_attach_args *);
59 static int virtio_setup_interrupts(struct virtio_softc *);
60 static void virtio_free_interrupts(struct virtio_softc *);
61 static void virtio_soft_intr(void *arg);
62 static void virtio_init_vq(struct virtio_softc *,
63 struct virtqueue *, const bool);
64
65
66 /* we use the legacy virtio spec, so the pci registers are host native
67 * byte order, not pci (i.e. LE) byte order */
68 static inline uint16_t
69 nbo_bus_space_read_2(bus_space_tag_t space, bus_space_handle_t handle,
70 bus_size_t offset)
71 {
72 return le16toh(bus_space_read_2(space, handle, offset));
73 }
74
75 static inline uint32_t
76 nbo_bus_space_read_4(bus_space_tag_t space, bus_space_handle_t handle,
77 bus_size_t offset)
78 {
79 return le32toh(bus_space_read_4(space, handle, offset));
80 }
81
82 static void
83 nbo_bus_space_write_2(bus_space_tag_t space, bus_space_handle_t handle,
84 bus_size_t offset, uint16_t value)
85 {
86 bus_space_write_2(space, handle, offset, htole16(value));
87 }
88
89 static void
90 nbo_bus_space_write_4(bus_space_tag_t space, bus_space_handle_t handle,
91 bus_size_t offset, uint32_t value)
92 {
93 bus_space_write_4(space, handle, offset, htole32(value));
94 }
95
96 /* some functions access registers at 4 byte offset for little/high halves */
97 #if BYTE_ORDER == BIG_ENDIAN
98 #define REG_HI_OFF 0
99 #define REG_LO_OFF 4
100 #else
101 #define REG_HI_OFF 4
102 #define REG_LO_OFF 0
103 #endif
104
105 void
106 virtio_set_status(struct virtio_softc *sc, int status)
107 {
108 int old = 0;
109
110 if (status != 0)
111 old = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
112 VIRTIO_CONFIG_DEVICE_STATUS);
113 bus_space_write_1(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_DEVICE_STATUS,
114 status|old);
115 }
116
117 #define VIRTIO_MSIX_CONFIG_VECTOR_INDEX 0
118 #define VIRTIO_MSIX_QUEUE_VECTOR_INDEX 1
119
120 static int
121 virtio_setup_msix_vectors(struct virtio_softc *sc)
122 {
123 int offset, vector, ret, qid;
124
125 offset = VIRTIO_CONFIG_MSI_CONFIG_VECTOR;
126 vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
127
128 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector);
129 ret = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset);
130 aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
131 vector, ret);
132 if (ret != vector)
133 return -1;
134
135 for (qid = 0; qid < sc->sc_nvqs; qid++) {
136 offset = VIRTIO_CONFIG_QUEUE_SELECT;
137 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, qid);
138
139 offset = VIRTIO_CONFIG_MSI_QUEUE_VECTOR;
140 vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
141
142 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector);
143 ret = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset);
144 aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
145 vector, ret);
146 if (ret != vector)
147 return -1;
148 }
149
150 return 0;
151 }
152
153 static int
154 virtio_setup_msix_interrupts(struct virtio_softc *sc,
155 struct pci_attach_args *pa)
156 {
157 device_t self = sc->sc_dev;
158 pci_chipset_tag_t pc = pa->pa_pc;
159 char intrbuf[PCI_INTRSTR_LEN];
160 char const *intrstr;
161 int idx;
162
163 idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
164 if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE)
165 pci_intr_setattr(pc, &sc->sc_ihp[idx], PCI_INTR_MPSAFE, true);
166
167 sc->sc_ihs[idx] = pci_intr_establish_xname(pc, sc->sc_ihp[idx],
168 sc->sc_ipl, virtio_msix_config_intr, sc, device_xname(sc->sc_dev));
169 if (sc->sc_ihs[idx] == NULL) {
170 aprint_error_dev(self, "couldn't establish MSI-X for config\n");
171 goto error;
172 }
173
174 idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
175 if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE)
176 pci_intr_setattr(pc, &sc->sc_ihp[idx], PCI_INTR_MPSAFE, true);
177
178 sc->sc_ihs[idx] = pci_intr_establish_xname(pc, sc->sc_ihp[idx],
179 sc->sc_ipl, virtio_msix_queue_intr, sc, device_xname(sc->sc_dev));
180 if (sc->sc_ihs[idx] == NULL) {
181 aprint_error_dev(self, "couldn't establish MSI-X for queues\n");
182 goto error;
183 }
184
185 if (virtio_setup_msix_vectors(sc) != 0) {
186 aprint_error_dev(self, "couldn't setup MSI-X vectors\n");
187 goto error;
188 }
189
190 idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
191 intrstr = pci_intr_string(pc, sc->sc_ihp[idx], intrbuf, sizeof(intrbuf));
192 aprint_normal_dev(self, "config interrupting at %s\n", intrstr);
193 idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
194 intrstr = pci_intr_string(pc, sc->sc_ihp[idx], intrbuf, sizeof(intrbuf));
195 aprint_normal_dev(self, "queues interrupting at %s\n", intrstr);
196
197 return 0;
198
199 error:
200 idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
201 if (sc->sc_ihs[idx] != NULL)
202 pci_intr_disestablish(sc->sc_pc, sc->sc_ihs[idx]);
203 idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
204 if (sc->sc_ihs[idx] != NULL)
205 pci_intr_disestablish(sc->sc_pc, sc->sc_ihs[idx]);
206
207 return -1;
208 }
209
210 static int
211 virtio_setup_intx_interrupt(struct virtio_softc *sc,
212 struct pci_attach_args *pa)
213 {
214 device_t self = sc->sc_dev;
215 pci_chipset_tag_t pc = pa->pa_pc;
216 char intrbuf[PCI_INTRSTR_LEN];
217 char const *intrstr;
218
219 if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE)
220 pci_intr_setattr(pc, &sc->sc_ihp[0], PCI_INTR_MPSAFE, true);
221
222 sc->sc_ihs[0] = pci_intr_establish_xname(pc, sc->sc_ihp[0],
223 sc->sc_ipl, virtio_intr, sc, device_xname(sc->sc_dev));
224 if (sc->sc_ihs[0] == NULL) {
225 aprint_error_dev(self, "couldn't establish INTx\n");
226 return -1;
227 }
228
229 intrstr = pci_intr_string(pc, sc->sc_ihp[0], intrbuf, sizeof(intrbuf));
230 aprint_normal_dev(self, "interrupting at %s\n", intrstr);
231
232 return 0;
233 }
234
235 static int
236 virtio_setup_interrupts(struct virtio_softc *sc)
237 {
238 device_t self = sc->sc_dev;
239 pci_chipset_tag_t pc = sc->sc_pa.pa_pc;
240 int error;
241 int nmsix;
242 int counts[PCI_INTR_TYPE_SIZE];
243 pci_intr_type_t max_type;
244
245 nmsix = pci_msix_count(sc->sc_pa.pa_pc, sc->sc_pa.pa_tag);
246 aprint_debug_dev(self, "pci_msix_count=%d\n", nmsix);
247
248 /* We need at least two: one for config and the other for queues */
249 if ((sc->sc_flags & VIRTIO_F_PCI_INTR_MSIX) == 0 || nmsix < 2) {
250 /* Try INTx only */
251 max_type = PCI_INTR_TYPE_INTX;
252 counts[PCI_INTR_TYPE_INTX] = 1;
253 } else {
254 /* Try MSI-X first and INTx second */
255 max_type = PCI_INTR_TYPE_MSIX;
256 counts[PCI_INTR_TYPE_MSIX] = 2;
257 counts[PCI_INTR_TYPE_MSI] = 0;
258 counts[PCI_INTR_TYPE_INTX] = 1;
259 }
260
261 retry:
262 error = pci_intr_alloc(&sc->sc_pa, &sc->sc_ihp, counts, max_type);
263 if (error != 0) {
264 aprint_error_dev(self, "couldn't map interrupt\n");
265 return -1;
266 }
267
268 if (pci_intr_type(pc, sc->sc_ihp[0]) == PCI_INTR_TYPE_MSIX) {
269 sc->sc_ihs = kmem_alloc(sizeof(*sc->sc_ihs) * 2,
270 KM_SLEEP);
271
272 error = virtio_setup_msix_interrupts(sc, &sc->sc_pa);
273 if (error != 0) {
274 kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * 2);
275 pci_intr_release(pc, sc->sc_ihp, 2);
276
277 /* Retry INTx */
278 max_type = PCI_INTR_TYPE_INTX;
279 counts[PCI_INTR_TYPE_INTX] = 1;
280 goto retry;
281 }
282
283 sc->sc_ihs_num = 2;
284 sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_MSI;
285 } else if (pci_intr_type(pc, sc->sc_ihp[0]) == PCI_INTR_TYPE_INTX) {
286 sc->sc_ihs = kmem_alloc(sizeof(*sc->sc_ihs) * 1,
287 KM_SLEEP);
288
289 error = virtio_setup_intx_interrupt(sc, &sc->sc_pa);
290 if (error != 0) {
291 kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * 1);
292 pci_intr_release(pc, sc->sc_ihp, 1);
293 return -1;
294 }
295
296 sc->sc_ihs_num = 1;
297 sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI;
298 }
299
300 KASSERT(sc->sc_soft_ih == NULL);
301 if (sc->sc_flags & VIRTIO_F_PCI_INTR_SOFTINT) {
302 u_int flags = SOFTINT_NET;
303 if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE)
304 flags |= SOFTINT_MPSAFE;
305
306 sc->sc_soft_ih = softint_establish(flags, virtio_soft_intr, sc);
307 if (sc->sc_soft_ih == NULL) {
308 virtio_free_interrupts(sc);
309 aprint_error_dev(sc->sc_dev,
310 "failed to establish soft interrupt\n");
311 return -1;
312 }
313 }
314
315 return 0;
316 }
317
318 static void
319 virtio_free_interrupts(struct virtio_softc *sc)
320 {
321 for (int i = 0; i < sc->sc_ihs_num; i++) {
322 if (sc->sc_ihs[i] == NULL)
323 continue;
324 pci_intr_disestablish(sc->sc_pc, sc->sc_ihs[i]);
325 sc->sc_ihs[i] = NULL;
326 }
327
328 if (sc->sc_ihs_num > 0)
329 pci_intr_release(sc->sc_pc, sc->sc_ihp, sc->sc_ihs_num);
330
331 if (sc->sc_soft_ih) {
332 softint_disestablish(sc->sc_soft_ih);
333 sc->sc_soft_ih = NULL;
334 }
335
336 if (sc->sc_ihs != NULL) {
337 kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * sc->sc_ihs_num);
338 sc->sc_ihs = NULL;
339 }
340 sc->sc_ihs_num = 0;
341 }
342
343
344
345 /*
346 * Reset the device.
347 */
348 /*
349 * To reset the device to a known state, do following:
350 * virtio_reset(sc); // this will stop the device activity
351 * <dequeue finished requests>; // virtio_dequeue() still can be called
352 * <revoke pending requests in the vqs if any>;
353 * virtio_reinit_begin(sc); // dequeue prohibitted
354 * newfeatures = virtio_negotiate_features(sc, requestedfeatures);
355 * <some other initialization>;
356 * virtio_reinit_end(sc); // device activated; enqueue allowed
357 * Once attached, feature negotiation can only be allowed after virtio_reset.
358 */
359 void
360 virtio_reset(struct virtio_softc *sc)
361 {
362 virtio_device_reset(sc);
363 }
364
365 void
366 virtio_reinit_start(struct virtio_softc *sc)
367 {
368 int i;
369
370 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
371 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);
372 for (i = 0; i < sc->sc_nvqs; i++) {
373 int n;
374 struct virtqueue *vq = &sc->sc_vqs[i];
375 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
376 VIRTIO_CONFIG_QUEUE_SELECT,
377 vq->vq_index);
378 n = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh,
379 VIRTIO_CONFIG_QUEUE_SIZE);
380 if (n == 0) /* vq disappeared */
381 continue;
382 if (n != vq->vq_num) {
383 panic("%s: virtqueue size changed, vq index %d\n",
384 device_xname(sc->sc_dev),
385 vq->vq_index);
386 }
387 virtio_init_vq(sc, vq, true);
388 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
389 VIRTIO_CONFIG_QUEUE_ADDRESS,
390 (vq->vq_dmamap->dm_segs[0].ds_addr
391 / VIRTIO_PAGE_SIZE));
392 }
393
394 /* MSI-X should have more than one handles where INTx has just one */
395 if (sc->sc_ihs_num > 1) {
396 if (virtio_setup_msix_vectors(sc) != 0) {
397 aprint_error_dev(sc->sc_dev,
398 "couldn't setup MSI-X vectors\n");
399 return;
400 }
401 }
402 }
403
404 void
405 virtio_reinit_end(struct virtio_softc *sc)
406 {
407 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
408 }
409
410 /*
411 * Feature negotiation.
412 */
413 uint32_t
414 virtio_negotiate_features(struct virtio_softc *sc, uint32_t guest_features)
415 {
416 uint32_t r;
417
418 if (!(device_cfdata(sc->sc_dev)->cf_flags & 1) &&
419 !(device_cfdata(sc->sc_child)->cf_flags & 1)) /* XXX */
420 guest_features |= VIRTIO_F_RING_INDIRECT_DESC;
421 r = nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh,
422 VIRTIO_CONFIG_DEVICE_FEATURES);
423 r &= guest_features;
424 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
425 VIRTIO_CONFIG_GUEST_FEATURES, r);
426 sc->sc_features = r;
427 if (r & VIRTIO_F_RING_INDIRECT_DESC)
428 sc->sc_indirect = true;
429 else
430 sc->sc_indirect = false;
431
432 return r;
433 }
434
435 /*
436 * Device configuration registers.
437 */
438 uint8_t
439 virtio_read_device_config_1(struct virtio_softc *sc, int index)
440 {
441 return bus_space_read_1(sc->sc_iot, sc->sc_ioh,
442 sc->sc_config_offset + index);
443 }
444
445 uint16_t
446 virtio_read_device_config_2(struct virtio_softc *sc, int index)
447 {
448 return nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh,
449 sc->sc_config_offset + index);
450 }
451
452 uint32_t
453 virtio_read_device_config_4(struct virtio_softc *sc, int index)
454 {
455 return nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh,
456 sc->sc_config_offset + index);
457 }
458
459 uint64_t
460 virtio_read_device_config_8(struct virtio_softc *sc, int index)
461 {
462 uint64_t r;
463
464 r = nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh,
465 sc->sc_config_offset + index + REG_HI_OFF);
466 r <<= 32;
467 r |= nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh,
468 sc->sc_config_offset + index + REG_LO_OFF);
469
470 return r;
471 }
472
473 void
474 virtio_write_device_config_1(struct virtio_softc *sc,
475 int index, uint8_t value)
476 {
477 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
478 sc->sc_config_offset + index, value);
479 }
480
481 void
482 virtio_write_device_config_2(struct virtio_softc *sc,
483 int index, uint16_t value)
484 {
485 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
486 sc->sc_config_offset + index, value);
487 }
488
489 void
490 virtio_write_device_config_4(struct virtio_softc *sc,
491 int index, uint32_t value)
492 {
493 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
494 sc->sc_config_offset + index, value);
495 }
496
497 void
498 virtio_write_device_config_8(struct virtio_softc *sc,
499 int index, uint64_t value)
500 {
501 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
502 sc->sc_config_offset + index + REG_LO_OFF,
503 value & 0xffffffff);
504 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
505 sc->sc_config_offset + index + REG_HI_OFF,
506 value >> 32);
507 }
508
509 /*
510 * Interrupt handler.
511 */
512 static int
513 virtio_intr(void *arg)
514 {
515 struct virtio_softc *sc = arg;
516 int isr, r = 0;
517
518 /* check and ack the interrupt */
519 isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
520 VIRTIO_CONFIG_ISR_STATUS);
521 if (isr == 0)
522 return 0;
523 if ((isr & VIRTIO_CONFIG_ISR_CONFIG_CHANGE) &&
524 (sc->sc_config_change != NULL))
525 r = (sc->sc_config_change)(sc);
526 if (sc->sc_intrhand != NULL) {
527 if (sc->sc_soft_ih != NULL)
528 softint_schedule(sc->sc_soft_ih);
529 else
530 r |= (sc->sc_intrhand)(sc);
531 }
532
533 return r;
534 }
535
536 static int
537 virtio_msix_queue_intr(void *arg)
538 {
539 struct virtio_softc *sc = arg;
540 int r = 0;
541
542 if (sc->sc_intrhand != NULL) {
543 if (sc->sc_soft_ih != NULL)
544 softint_schedule(sc->sc_soft_ih);
545 else
546 r |= (sc->sc_intrhand)(sc);
547 }
548
549 return r;
550 }
551
552 static int
553 virtio_msix_config_intr(void *arg)
554 {
555 struct virtio_softc *sc = arg;
556 int r = 0;
557
558 if (sc->sc_config_change != NULL)
559 r = (sc->sc_config_change)(sc);
560 return r;
561 }
562
563 static void
564 virtio_soft_intr(void *arg)
565 {
566 struct virtio_softc *sc = arg;
567
568 KASSERT(sc->sc_intrhand != NULL);
569
570 (sc->sc_intrhand)(sc);
571 }
572
573 /*
574 * dmamap sync operations for a virtqueue.
575 */
576 static inline void
577 vq_sync_descs(struct virtio_softc *sc, struct virtqueue *vq, int ops)
578 {
579 /* availoffset == sizeof(vring_desc)*vq_num */
580 bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap, 0, vq->vq_availoffset,
581 ops);
582 }
583
584 static inline void
585 vq_sync_aring(struct virtio_softc *sc, struct virtqueue *vq, int ops)
586 {
587 bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap,
588 vq->vq_availoffset,
589 offsetof(struct vring_avail, ring)
590 + vq->vq_num * sizeof(uint16_t),
591 ops);
592 }
593
594 static inline void
595 vq_sync_uring(struct virtio_softc *sc, struct virtqueue *vq, int ops)
596 {
597 bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap,
598 vq->vq_usedoffset,
599 offsetof(struct vring_used, ring)
600 + vq->vq_num * sizeof(struct vring_used_elem),
601 ops);
602 }
603
604 static inline void
605 vq_sync_indirect(struct virtio_softc *sc, struct virtqueue *vq, int slot,
606 int ops)
607 {
608 int offset = vq->vq_indirectoffset
609 + sizeof(struct vring_desc) * vq->vq_maxnsegs * slot;
610
611 bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap,
612 offset, sizeof(struct vring_desc) * vq->vq_maxnsegs,
613 ops);
614 }
615
616 /*
617 * Can be used as sc_intrhand.
618 */
619 /*
620 * Scan vq, bus_dmamap_sync for the vqs (not for the payload),
621 * and calls (*vq_done)() if some entries are consumed.
622 */
623 int
624 virtio_vq_intr(struct virtio_softc *sc)
625 {
626 struct virtqueue *vq;
627 int i, r = 0;
628
629 for (i = 0; i < sc->sc_nvqs; i++) {
630 vq = &sc->sc_vqs[i];
631 if (vq->vq_queued) {
632 vq->vq_queued = 0;
633 vq_sync_aring(sc, vq, BUS_DMASYNC_POSTWRITE);
634 }
635 vq_sync_uring(sc, vq, BUS_DMASYNC_POSTREAD);
636 membar_consumer();
637 if (vq->vq_used_idx != vq->vq_used->idx) {
638 if (vq->vq_done)
639 r |= (vq->vq_done)(vq);
640 }
641 }
642
643 return r;
644 }
645
646 /*
647 * Start/stop vq interrupt. No guarantee.
648 */
649 void
650 virtio_stop_vq_intr(struct virtio_softc *sc, struct virtqueue *vq)
651 {
652 vq->vq_avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
653 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE);
654 vq->vq_queued++;
655 }
656
657 void
658 virtio_start_vq_intr(struct virtio_softc *sc, struct virtqueue *vq)
659 {
660 vq->vq_avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
661 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE);
662 vq->vq_queued++;
663 }
664
665 /*
666 * Initialize vq structure.
667 */
668 static void
669 virtio_init_vq(struct virtio_softc *sc, struct virtqueue *vq,
670 const bool reinit)
671 {
672 int i, j;
673 int vq_size = vq->vq_num;
674
675 memset(vq->vq_vaddr, 0, vq->vq_bytesize);
676
677 /* build the indirect descriptor chain */
678 if (vq->vq_indirect != NULL) {
679 struct vring_desc *vd;
680
681 for (i = 0; i < vq_size; i++) {
682 vd = vq->vq_indirect;
683 vd += vq->vq_maxnsegs * i;
684 for (j = 0; j < vq->vq_maxnsegs-1; j++) {
685 vd[j].next = j + 1;
686 }
687 }
688 }
689
690 /* free slot management */
691 SIMPLEQ_INIT(&vq->vq_freelist);
692 for (i = 0; i < vq_size; i++) {
693 SIMPLEQ_INSERT_TAIL(&vq->vq_freelist,
694 &vq->vq_entries[i], qe_list);
695 vq->vq_entries[i].qe_index = i;
696 }
697 if (!reinit)
698 mutex_init(&vq->vq_freelist_lock, MUTEX_SPIN, sc->sc_ipl);
699
700 /* enqueue/dequeue status */
701 vq->vq_avail_idx = 0;
702 vq->vq_used_idx = 0;
703 vq->vq_queued = 0;
704 if (!reinit) {
705 mutex_init(&vq->vq_aring_lock, MUTEX_SPIN, sc->sc_ipl);
706 mutex_init(&vq->vq_uring_lock, MUTEX_SPIN, sc->sc_ipl);
707 }
708 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE);
709 vq_sync_uring(sc, vq, BUS_DMASYNC_PREREAD);
710 vq->vq_queued++;
711 }
712
713 /*
714 * Allocate/free a vq.
715 */
716 int
717 virtio_alloc_vq(struct virtio_softc *sc, struct virtqueue *vq, int index,
718 int maxsegsize, int maxnsegs, const char *name)
719 {
720 int vq_size, allocsize1, allocsize2, allocsize3, allocsize = 0;
721 int rsegs, r;
722 #define VIRTQUEUE_ALIGN(n) (((n)+(VIRTIO_PAGE_SIZE-1))& \
723 ~(VIRTIO_PAGE_SIZE-1))
724
725 /* Make sure callers allocate vqs in order */
726 KASSERT(sc->sc_nvqs == index);
727
728 memset(vq, 0, sizeof(*vq));
729
730 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
731 VIRTIO_CONFIG_QUEUE_SELECT, index);
732 vq_size = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh,
733 VIRTIO_CONFIG_QUEUE_SIZE);
734 if (vq_size == 0) {
735 aprint_error_dev(sc->sc_dev,
736 "virtqueue not exist, index %d for %s\n",
737 index, name);
738 goto err;
739 }
740 /* allocsize1: descriptor table + avail ring + pad */
741 allocsize1 = VIRTQUEUE_ALIGN(sizeof(struct vring_desc)*vq_size
742 + sizeof(uint16_t)*(2+vq_size));
743 /* allocsize2: used ring + pad */
744 allocsize2 = VIRTQUEUE_ALIGN(sizeof(uint16_t)*2
745 + sizeof(struct vring_used_elem)*vq_size);
746 /* allocsize3: indirect table */
747 if (sc->sc_indirect && maxnsegs >= MINSEG_INDIRECT)
748 allocsize3 = sizeof(struct vring_desc) * maxnsegs * vq_size;
749 else
750 allocsize3 = 0;
751 allocsize = allocsize1 + allocsize2 + allocsize3;
752
753 /* alloc and map the memory */
754 r = bus_dmamem_alloc(sc->sc_dmat, allocsize, VIRTIO_PAGE_SIZE, 0,
755 &vq->vq_segs[0], 1, &rsegs, BUS_DMA_NOWAIT);
756 if (r != 0) {
757 aprint_error_dev(sc->sc_dev,
758 "virtqueue %d for %s allocation failed, "
759 "error code %d\n", index, name, r);
760 goto err;
761 }
762 r = bus_dmamem_map(sc->sc_dmat, &vq->vq_segs[0], 1, allocsize,
763 &vq->vq_vaddr, BUS_DMA_NOWAIT);
764 if (r != 0) {
765 aprint_error_dev(sc->sc_dev,
766 "virtqueue %d for %s map failed, "
767 "error code %d\n", index, name, r);
768 goto err;
769 }
770 r = bus_dmamap_create(sc->sc_dmat, allocsize, 1, allocsize, 0,
771 BUS_DMA_NOWAIT, &vq->vq_dmamap);
772 if (r != 0) {
773 aprint_error_dev(sc->sc_dev,
774 "virtqueue %d for %s dmamap creation failed, "
775 "error code %d\n", index, name, r);
776 goto err;
777 }
778 r = bus_dmamap_load(sc->sc_dmat, vq->vq_dmamap,
779 vq->vq_vaddr, allocsize, NULL, BUS_DMA_NOWAIT);
780 if (r != 0) {
781 aprint_error_dev(sc->sc_dev,
782 "virtqueue %d for %s dmamap load failed, "
783 "error code %d\n", index, name, r);
784 goto err;
785 }
786
787 /* set the vq address */
788 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
789 VIRTIO_CONFIG_QUEUE_ADDRESS,
790 (vq->vq_dmamap->dm_segs[0].ds_addr
791 / VIRTIO_PAGE_SIZE));
792
793 /* remember addresses and offsets for later use */
794 vq->vq_owner = sc;
795 vq->vq_num = vq_size;
796 vq->vq_index = index;
797 vq->vq_desc = vq->vq_vaddr;
798 vq->vq_availoffset = sizeof(struct vring_desc)*vq_size;
799 vq->vq_avail = (void*)(((char*)vq->vq_desc) + vq->vq_availoffset);
800 vq->vq_usedoffset = allocsize1;
801 vq->vq_used = (void*)(((char*)vq->vq_desc) + vq->vq_usedoffset);
802 if (allocsize3 > 0) {
803 vq->vq_indirectoffset = allocsize1 + allocsize2;
804 vq->vq_indirect = (void*)(((char*)vq->vq_desc)
805 + vq->vq_indirectoffset);
806 }
807 vq->vq_bytesize = allocsize;
808 vq->vq_maxsegsize = maxsegsize;
809 vq->vq_maxnsegs = maxnsegs;
810
811 /* free slot management */
812 vq->vq_entries = kmem_zalloc(sizeof(struct vq_entry)*vq_size,
813 KM_NOSLEEP);
814 if (vq->vq_entries == NULL) {
815 r = ENOMEM;
816 goto err;
817 }
818
819 virtio_init_vq(sc, vq, false);
820
821 aprint_verbose_dev(sc->sc_dev,
822 "allocated %u byte for virtqueue %d for %s, "
823 "size %d\n", allocsize, index, name, vq_size);
824 if (allocsize3 > 0)
825 aprint_verbose_dev(sc->sc_dev,
826 "using %d byte (%d entries) "
827 "indirect descriptors\n",
828 allocsize3, maxnsegs * vq_size);
829
830 sc->sc_nvqs++;
831
832 return 0;
833
834 err:
835 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
836 VIRTIO_CONFIG_QUEUE_ADDRESS, 0);
837 if (vq->vq_dmamap)
838 bus_dmamap_destroy(sc->sc_dmat, vq->vq_dmamap);
839 if (vq->vq_vaddr)
840 bus_dmamem_unmap(sc->sc_dmat, vq->vq_vaddr, allocsize);
841 if (vq->vq_segs[0].ds_addr)
842 bus_dmamem_free(sc->sc_dmat, &vq->vq_segs[0], 1);
843 memset(vq, 0, sizeof(*vq));
844
845 return -1;
846 }
847
848 int
849 virtio_free_vq(struct virtio_softc *sc, struct virtqueue *vq)
850 {
851 struct vq_entry *qe;
852 int i = 0;
853
854 /* device must be already deactivated */
855 /* confirm the vq is empty */
856 SIMPLEQ_FOREACH(qe, &vq->vq_freelist, qe_list) {
857 i++;
858 }
859 if (i != vq->vq_num) {
860 printf("%s: freeing non-empty vq, index %d\n",
861 device_xname(sc->sc_dev), vq->vq_index);
862 return EBUSY;
863 }
864
865 /* tell device that there's no virtqueue any longer */
866 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
867 VIRTIO_CONFIG_QUEUE_SELECT, vq->vq_index);
868 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
869 VIRTIO_CONFIG_QUEUE_ADDRESS, 0);
870
871 kmem_free(vq->vq_entries, sizeof(*vq->vq_entries) * vq->vq_num);
872 bus_dmamap_unload(sc->sc_dmat, vq->vq_dmamap);
873 bus_dmamap_destroy(sc->sc_dmat, vq->vq_dmamap);
874 bus_dmamem_unmap(sc->sc_dmat, vq->vq_vaddr, vq->vq_bytesize);
875 bus_dmamem_free(sc->sc_dmat, &vq->vq_segs[0], 1);
876 mutex_destroy(&vq->vq_freelist_lock);
877 mutex_destroy(&vq->vq_uring_lock);
878 mutex_destroy(&vq->vq_aring_lock);
879 memset(vq, 0, sizeof(*vq));
880
881 sc->sc_nvqs--;
882
883 return 0;
884 }
885
886 /*
887 * Free descriptor management.
888 */
889 static struct vq_entry *
890 vq_alloc_entry(struct virtqueue *vq)
891 {
892 struct vq_entry *qe;
893
894 mutex_enter(&vq->vq_freelist_lock);
895 if (SIMPLEQ_EMPTY(&vq->vq_freelist)) {
896 mutex_exit(&vq->vq_freelist_lock);
897 return NULL;
898 }
899 qe = SIMPLEQ_FIRST(&vq->vq_freelist);
900 SIMPLEQ_REMOVE_HEAD(&vq->vq_freelist, qe_list);
901 mutex_exit(&vq->vq_freelist_lock);
902
903 return qe;
904 }
905
906 static void
907 vq_free_entry(struct virtqueue *vq, struct vq_entry *qe)
908 {
909 mutex_enter(&vq->vq_freelist_lock);
910 SIMPLEQ_INSERT_TAIL(&vq->vq_freelist, qe, qe_list);
911 mutex_exit(&vq->vq_freelist_lock);
912
913 return;
914 }
915
916 /*
917 * Enqueue several dmamaps as a single request.
918 */
919 /*
920 * Typical usage:
921 * <queue size> number of followings are stored in arrays
922 * - command blocks (in dmamem) should be pre-allocated and mapped
923 * - dmamaps for command blocks should be pre-allocated and loaded
924 * - dmamaps for payload should be pre-allocated
925 * r = virtio_enqueue_prep(sc, vq, &slot); // allocate a slot
926 * if (r) // currently 0 or EAGAIN
927 * return r;
928 * r = bus_dmamap_load(dmat, dmamap_payload[slot], data, count, ..);
929 * if (r) {
930 * virtio_enqueue_abort(sc, vq, slot);
931 * return r;
932 * }
933 * r = virtio_enqueue_reserve(sc, vq, slot,
934 * dmamap_payload[slot]->dm_nsegs+1);
935 * // ^ +1 for command
936 * if (r) { // currently 0 or EAGAIN
937 * bus_dmamap_unload(dmat, dmamap_payload[slot]);
938 * return r; // do not call abort()
939 * }
940 * <setup and prepare commands>
941 * bus_dmamap_sync(dmat, dmamap_cmd[slot],... BUS_DMASYNC_PREWRITE);
942 * bus_dmamap_sync(dmat, dmamap_payload[slot],...);
943 * virtio_enqueue(sc, vq, slot, dmamap_cmd[slot], false);
944 * virtio_enqueue(sc, vq, slot, dmamap_payload[slot], iswrite);
945 * virtio_enqueue_commit(sc, vq, slot, true);
946 */
947
948 /*
949 * enqueue_prep: allocate a slot number
950 */
951 int
952 virtio_enqueue_prep(struct virtio_softc *sc, struct virtqueue *vq, int *slotp)
953 {
954 struct vq_entry *qe1;
955
956 KASSERT(slotp != NULL);
957
958 qe1 = vq_alloc_entry(vq);
959 if (qe1 == NULL)
960 return EAGAIN;
961 /* next slot is not allocated yet */
962 qe1->qe_next = -1;
963 *slotp = qe1->qe_index;
964
965 return 0;
966 }
967
968 /*
969 * enqueue_reserve: allocate remaining slots and build the descriptor chain.
970 */
971 int
972 virtio_enqueue_reserve(struct virtio_softc *sc, struct virtqueue *vq,
973 int slot, int nsegs)
974 {
975 int indirect;
976 struct vq_entry *qe1 = &vq->vq_entries[slot];
977
978 KASSERT(qe1->qe_next == -1);
979 KASSERT(1 <= nsegs && nsegs <= vq->vq_num);
980
981 if ((vq->vq_indirect != NULL) &&
982 (nsegs >= MINSEG_INDIRECT) &&
983 (nsegs <= vq->vq_maxnsegs))
984 indirect = 1;
985 else
986 indirect = 0;
987 qe1->qe_indirect = indirect;
988
989 if (indirect) {
990 struct vring_desc *vd;
991 int i;
992
993 vd = &vq->vq_desc[qe1->qe_index];
994 vd->addr = vq->vq_dmamap->dm_segs[0].ds_addr
995 + vq->vq_indirectoffset;
996 vd->addr += sizeof(struct vring_desc)
997 * vq->vq_maxnsegs * qe1->qe_index;
998 vd->len = sizeof(struct vring_desc) * nsegs;
999 vd->flags = VRING_DESC_F_INDIRECT;
1000
1001 vd = vq->vq_indirect;
1002 vd += vq->vq_maxnsegs * qe1->qe_index;
1003 qe1->qe_desc_base = vd;
1004
1005 for (i = 0; i < nsegs-1; i++) {
1006 vd[i].flags = VRING_DESC_F_NEXT;
1007 }
1008 vd[i].flags = 0;
1009 qe1->qe_next = 0;
1010
1011 return 0;
1012 } else {
1013 struct vring_desc *vd;
1014 struct vq_entry *qe;
1015 int i, s;
1016
1017 vd = &vq->vq_desc[0];
1018 qe1->qe_desc_base = vd;
1019 qe1->qe_next = qe1->qe_index;
1020 s = slot;
1021 for (i = 0; i < nsegs - 1; i++) {
1022 qe = vq_alloc_entry(vq);
1023 if (qe == NULL) {
1024 vd[s].flags = 0;
1025 virtio_enqueue_abort(sc, vq, slot);
1026 return EAGAIN;
1027 }
1028 vd[s].flags = VRING_DESC_F_NEXT;
1029 vd[s].next = qe->qe_index;
1030 s = qe->qe_index;
1031 }
1032 vd[s].flags = 0;
1033
1034 return 0;
1035 }
1036 }
1037
1038 /*
1039 * enqueue: enqueue a single dmamap.
1040 */
1041 int
1042 virtio_enqueue(struct virtio_softc *sc, struct virtqueue *vq, int slot,
1043 bus_dmamap_t dmamap, bool write)
1044 {
1045 struct vq_entry *qe1 = &vq->vq_entries[slot];
1046 struct vring_desc *vd = qe1->qe_desc_base;
1047 int i;
1048 int s = qe1->qe_next;
1049
1050 KASSERT(s >= 0);
1051 KASSERT(dmamap->dm_nsegs > 0);
1052
1053 for (i = 0; i < dmamap->dm_nsegs; i++) {
1054 vd[s].addr = dmamap->dm_segs[i].ds_addr;
1055 vd[s].len = dmamap->dm_segs[i].ds_len;
1056 if (!write)
1057 vd[s].flags |= VRING_DESC_F_WRITE;
1058 s = vd[s].next;
1059 }
1060 qe1->qe_next = s;
1061
1062 return 0;
1063 }
1064
1065 int
1066 virtio_enqueue_p(struct virtio_softc *sc, struct virtqueue *vq, int slot,
1067 bus_dmamap_t dmamap, bus_addr_t start, bus_size_t len,
1068 bool write)
1069 {
1070 struct vq_entry *qe1 = &vq->vq_entries[slot];
1071 struct vring_desc *vd = qe1->qe_desc_base;
1072 int s = qe1->qe_next;
1073
1074 KASSERT(s >= 0);
1075 KASSERT(dmamap->dm_nsegs == 1); /* XXX */
1076 KASSERT((dmamap->dm_segs[0].ds_len > start) &&
1077 (dmamap->dm_segs[0].ds_len >= start + len));
1078
1079 vd[s].addr = dmamap->dm_segs[0].ds_addr + start;
1080 vd[s].len = len;
1081 if (!write)
1082 vd[s].flags |= VRING_DESC_F_WRITE;
1083 qe1->qe_next = vd[s].next;
1084
1085 return 0;
1086 }
1087
1088 /*
1089 * enqueue_commit: add it to the aring.
1090 */
1091 int
1092 virtio_enqueue_commit(struct virtio_softc *sc, struct virtqueue *vq, int slot,
1093 bool notifynow)
1094 {
1095 struct vq_entry *qe1;
1096
1097 if (slot < 0) {
1098 mutex_enter(&vq->vq_aring_lock);
1099 goto notify;
1100 }
1101 vq_sync_descs(sc, vq, BUS_DMASYNC_PREWRITE);
1102 qe1 = &vq->vq_entries[slot];
1103 if (qe1->qe_indirect)
1104 vq_sync_indirect(sc, vq, slot, BUS_DMASYNC_PREWRITE);
1105 mutex_enter(&vq->vq_aring_lock);
1106 vq->vq_avail->ring[(vq->vq_avail_idx++) % vq->vq_num] = slot;
1107
1108 notify:
1109 if (notifynow) {
1110 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE);
1111 vq_sync_uring(sc, vq, BUS_DMASYNC_PREREAD);
1112 membar_producer();
1113 vq->vq_avail->idx = vq->vq_avail_idx;
1114 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE);
1115 membar_producer();
1116 vq->vq_queued++;
1117 vq_sync_uring(sc, vq, BUS_DMASYNC_POSTREAD);
1118 membar_consumer();
1119 if (!(vq->vq_used->flags & VRING_USED_F_NO_NOTIFY))
1120 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
1121 VIRTIO_CONFIG_QUEUE_NOTIFY,
1122 vq->vq_index);
1123 }
1124 mutex_exit(&vq->vq_aring_lock);
1125
1126 return 0;
1127 }
1128
1129 /*
1130 * enqueue_abort: rollback.
1131 */
1132 int
1133 virtio_enqueue_abort(struct virtio_softc *sc, struct virtqueue *vq, int slot)
1134 {
1135 struct vq_entry *qe = &vq->vq_entries[slot];
1136 struct vring_desc *vd;
1137 int s;
1138
1139 if (qe->qe_next < 0) {
1140 vq_free_entry(vq, qe);
1141 return 0;
1142 }
1143
1144 s = slot;
1145 vd = &vq->vq_desc[0];
1146 while (vd[s].flags & VRING_DESC_F_NEXT) {
1147 s = vd[s].next;
1148 vq_free_entry(vq, qe);
1149 qe = &vq->vq_entries[s];
1150 }
1151 vq_free_entry(vq, qe);
1152 return 0;
1153 }
1154
1155 /*
1156 * Dequeue a request.
1157 */
1158 /*
1159 * dequeue: dequeue a request from uring; dmamap_sync for uring is
1160 * already done in the interrupt handler.
1161 */
1162 int
1163 virtio_dequeue(struct virtio_softc *sc, struct virtqueue *vq,
1164 int *slotp, int *lenp)
1165 {
1166 uint16_t slot, usedidx;
1167 struct vq_entry *qe;
1168
1169 if (vq->vq_used_idx == vq->vq_used->idx)
1170 return ENOENT;
1171 mutex_enter(&vq->vq_uring_lock);
1172 usedidx = vq->vq_used_idx++;
1173 mutex_exit(&vq->vq_uring_lock);
1174 usedidx %= vq->vq_num;
1175 slot = vq->vq_used->ring[usedidx].id;
1176 qe = &vq->vq_entries[slot];
1177
1178 if (qe->qe_indirect)
1179 vq_sync_indirect(sc, vq, slot, BUS_DMASYNC_POSTWRITE);
1180
1181 if (slotp)
1182 *slotp = slot;
1183 if (lenp)
1184 *lenp = vq->vq_used->ring[usedidx].len;
1185
1186 return 0;
1187 }
1188
1189 /*
1190 * dequeue_commit: complete dequeue; the slot is recycled for future use.
1191 * if you forget to call this the slot will be leaked.
1192 */
1193 int
1194 virtio_dequeue_commit(struct virtio_softc *sc, struct virtqueue *vq, int slot)
1195 {
1196 struct vq_entry *qe = &vq->vq_entries[slot];
1197 struct vring_desc *vd = &vq->vq_desc[0];
1198 int s = slot;
1199
1200 while (vd[s].flags & VRING_DESC_F_NEXT) {
1201 s = vd[s].next;
1202 vq_free_entry(vq, qe);
1203 qe = &vq->vq_entries[s];
1204 }
1205 vq_free_entry(vq, qe);
1206
1207 return 0;
1208 }
1209
1210 /*
1211 * Attach a child, fill all the members.
1212 */
1213 void
1214 virtio_child_attach_start(struct virtio_softc *sc, device_t child, int ipl,
1215 struct virtqueue *vqs,
1216 virtio_callback config_change,
1217 virtio_callback intr_hand,
1218 int req_flags, int req_features, const char *feat_bits)
1219 {
1220 char buf[256];
1221 int features;
1222
1223 sc->sc_child = child;
1224 sc->sc_ipl = ipl;
1225 sc->sc_vqs = vqs;
1226 sc->sc_config_change = config_change;
1227 sc->sc_intrhand = intr_hand;
1228 sc->sc_flags = req_flags;
1229
1230 features = virtio_negotiate_features(sc, req_features);
1231 snprintb(buf, sizeof(buf), feat_bits, features);
1232 aprint_normal(": Features: %s\n", buf);
1233 aprint_naive("\n");
1234 }
1235
1236 int
1237 virtio_child_attach_finish(struct virtio_softc *sc)
1238 {
1239 int r;
1240
1241 r = virtio_setup_interrupts(sc);
1242 if (r != 0) {
1243 aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n");
1244 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
1245 return 1;
1246 }
1247
1248 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
1249
1250 return 0;
1251 }
1252
1253 void
1254 virtio_child_detach(struct virtio_softc *sc)
1255 {
1256 sc->sc_child = NULL;
1257 sc->sc_vqs = NULL;
1258
1259 virtio_device_reset(sc);
1260
1261 virtio_free_interrupts(sc);
1262 }
1263
1264 void
1265 virtio_child_attach_failed(struct virtio_softc *sc)
1266 {
1267 virtio_child_detach(sc);
1268
1269 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
1270
1271 sc->sc_child = VIRTIO_CHILD_FAILED;
1272 }
1273
1274 bus_dma_tag_t
1275 virtio_dmat(struct virtio_softc *sc)
1276 {
1277 return sc->sc_dmat;
1278 }
1279
1280 device_t
1281 virtio_child(struct virtio_softc *sc)
1282 {
1283 return sc->sc_child;
1284 }
1285
1286 int
1287 virtio_intrhand(struct virtio_softc *sc)
1288 {
1289 return (sc->sc_intrhand)(sc);
1290 }
1291
1292 uint32_t
1293 virtio_features(struct virtio_softc *sc)
1294 {
1295 return sc->sc_features;
1296 }
1297
1298 MODULE(MODULE_CLASS_DRIVER, virtio, "pci");
1299
1300 #ifdef _MODULE
1301 #include "ioconf.c"
1302 #endif
1303
1304 static int
1305 virtio_modcmd(modcmd_t cmd, void *opaque)
1306 {
1307 int error = 0;
1308
1309 #ifdef _MODULE
1310 switch (cmd) {
1311 case MODULE_CMD_INIT:
1312 error = config_init_component(cfdriver_ioconf_virtio,
1313 cfattach_ioconf_virtio, cfdata_ioconf_virtio);
1314 break;
1315 case MODULE_CMD_FINI:
1316 error = config_fini_component(cfdriver_ioconf_virtio,
1317 cfattach_ioconf_virtio, cfdata_ioconf_virtio);
1318 break;
1319 default:
1320 error = ENOTTY;
1321 break;
1322 }
1323 #endif
1324
1325 return error;
1326 }
1327