Sun Feb 7 09:26:17 2021 UTC ()
Trailing whitespace


(skrll)
diff -r1.47 -r1.48 src/sys/dev/pci/virtio.c

cvs diff -r1.47 -r1.48 src/sys/dev/pci/virtio.c (expand / switch to unified diff)

--- src/sys/dev/pci/virtio.c 2021/02/05 20:45:38 1.47
+++ src/sys/dev/pci/virtio.c 2021/02/07 09:26:17 1.48
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: virtio.c,v 1.47 2021/02/05 20:45:38 reinoud Exp $ */ 1/* $NetBSD: virtio.c,v 1.48 2021/02/07 09:26:17 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 2020 The NetBSD Foundation, Inc.
5 * Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg. 5 * Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
6 * Copyright (c) 2010 Minoura Makoto. 6 * Copyright (c) 2010 Minoura Makoto.
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -18,27 +18,27 @@ @@ -18,27 +18,27 @@
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30#include <sys/cdefs.h> 30#include <sys/cdefs.h>
31__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.47 2021/02/05 20:45:38 reinoud Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.48 2021/02/07 09:26:17 skrll Exp $");
32 32
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/systm.h> 34#include <sys/systm.h>
35#include <sys/kernel.h> 35#include <sys/kernel.h>
36#include <sys/atomic.h> 36#include <sys/atomic.h>
37#include <sys/bus.h> 37#include <sys/bus.h>
38#include <sys/device.h> 38#include <sys/device.h>
39#include <sys/kmem.h> 39#include <sys/kmem.h>
40#include <sys/module.h> 40#include <sys/module.h>
41 41
42#define VIRTIO_PRIVATE 42#define VIRTIO_PRIVATE
43 43
44#include <dev/pci/virtioreg.h> /* XXX: move to non-pci */ 44#include <dev/pci/virtioreg.h> /* XXX: move to non-pci */
@@ -639,27 +639,27 @@ virtio_init_vq(struct virtio_softc *sc,  @@ -639,27 +639,27 @@ virtio_init_vq(struct virtio_softc *sc,
639 639
640 /* enqueue/dequeue status */ 640 /* enqueue/dequeue status */
641 vq->vq_avail_idx = 0; 641 vq->vq_avail_idx = 0;
642 vq->vq_used_idx = 0; 642 vq->vq_used_idx = 0;
643 vq->vq_queued = 0; 643 vq->vq_queued = 0;
644 if (!reinit) { 644 if (!reinit) {
645 mutex_init(&vq->vq_aring_lock, MUTEX_SPIN, sc->sc_ipl); 645 mutex_init(&vq->vq_aring_lock, MUTEX_SPIN, sc->sc_ipl);
646 mutex_init(&vq->vq_uring_lock, MUTEX_SPIN, sc->sc_ipl); 646 mutex_init(&vq->vq_uring_lock, MUTEX_SPIN, sc->sc_ipl);
647 } 647 }
648 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE); 648 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE);
649 vq_sync_uring(sc, vq, BUS_DMASYNC_PREREAD); 649 vq_sync_uring(sc, vq, BUS_DMASYNC_PREREAD);
650 vq->vq_queued++; 650 vq->vq_queued++;
651} 651}
652  652
653/* 653/*
654 * Allocate/free a vq. 654 * Allocate/free a vq.
655 */ 655 */
656int 656int
657virtio_alloc_vq(struct virtio_softc *sc, struct virtqueue *vq, int index, 657virtio_alloc_vq(struct virtio_softc *sc, struct virtqueue *vq, int index,
658 int maxsegsize, int maxnsegs, const char *name) 658 int maxsegsize, int maxnsegs, const char *name)
659{ 659{
660 int vq_size, allocsize1, allocsize2, allocsize3, allocsize = 0; 660 int vq_size, allocsize1, allocsize2, allocsize3, allocsize = 0;
661 int rsegs, r, hdrlen; 661 int rsegs, r, hdrlen;
662#define VIRTQUEUE_ALIGN(n) (((n)+(VIRTIO_PAGE_SIZE-1))& \ 662#define VIRTQUEUE_ALIGN(n) (((n)+(VIRTIO_PAGE_SIZE-1))& \
663 ~(VIRTIO_PAGE_SIZE-1)) 663 ~(VIRTIO_PAGE_SIZE-1))
664 664
665 /* Make sure callers allocate vqs in order */ 665 /* Make sure callers allocate vqs in order */
@@ -854,27 +854,27 @@ vq_free_entry(struct virtqueue *vq, stru @@ -854,27 +854,27 @@ vq_free_entry(struct virtqueue *vq, stru
854 * Typical usage: 854 * Typical usage:
855 * <queue size> number of followings are stored in arrays 855 * <queue size> number of followings are stored in arrays
856 * - command blocks (in dmamem) should be pre-allocated and mapped 856 * - command blocks (in dmamem) should be pre-allocated and mapped
857 * - dmamaps for command blocks should be pre-allocated and loaded 857 * - dmamaps for command blocks should be pre-allocated and loaded
858 * - dmamaps for payload should be pre-allocated 858 * - dmamaps for payload should be pre-allocated
859 * r = virtio_enqueue_prep(sc, vq, &slot); // allocate a slot 859 * r = virtio_enqueue_prep(sc, vq, &slot); // allocate a slot
860 * if (r) // currently 0 or EAGAIN 860 * if (r) // currently 0 or EAGAIN
861 * return r; 861 * return r;
862 * r = bus_dmamap_load(dmat, dmamap_payload[slot], data, count, ..); 862 * r = bus_dmamap_load(dmat, dmamap_payload[slot], data, count, ..);
863 * if (r) { 863 * if (r) {
864 * virtio_enqueue_abort(sc, vq, slot); 864 * virtio_enqueue_abort(sc, vq, slot);
865 * return r; 865 * return r;
866 * } 866 * }
867 * r = virtio_enqueue_reserve(sc, vq, slot,  867 * r = virtio_enqueue_reserve(sc, vq, slot,
868 * dmamap_payload[slot]->dm_nsegs+1); 868 * dmamap_payload[slot]->dm_nsegs+1);
869 * // ^ +1 for command 869 * // ^ +1 for command
870 * if (r) { // currently 0 or EAGAIN 870 * if (r) { // currently 0 or EAGAIN
871 * bus_dmamap_unload(dmat, dmamap_payload[slot]); 871 * bus_dmamap_unload(dmat, dmamap_payload[slot]);
872 * return r; // do not call abort() 872 * return r; // do not call abort()
873 * } 873 * }
874 * <setup and prepare commands> 874 * <setup and prepare commands>
875 * bus_dmamap_sync(dmat, dmamap_cmd[slot],... BUS_DMASYNC_PREWRITE); 875 * bus_dmamap_sync(dmat, dmamap_cmd[slot],... BUS_DMASYNC_PREWRITE);
876 * bus_dmamap_sync(dmat, dmamap_payload[slot],...); 876 * bus_dmamap_sync(dmat, dmamap_payload[slot],...);
877 * virtio_enqueue(sc, vq, slot, dmamap_cmd[slot], false); 877 * virtio_enqueue(sc, vq, slot, dmamap_cmd[slot], false);
878 * virtio_enqueue(sc, vq, slot, dmamap_payload[slot], iswrite); 878 * virtio_enqueue(sc, vq, slot, dmamap_payload[slot], iswrite);
879 * virtio_enqueue_commit(sc, vq, slot, true); 879 * virtio_enqueue_commit(sc, vq, slot, true);
880 */ 880 */
@@ -1149,27 +1149,27 @@ virtio_dequeue_commit(struct virtio_soft @@ -1149,27 +1149,27 @@ virtio_dequeue_commit(struct virtio_soft
1149 s = virtio_rw16(sc, vd[s].next); 1149 s = virtio_rw16(sc, vd[s].next);
1150 vq_free_entry(vq, qe); 1150 vq_free_entry(vq, qe);
1151 qe = &vq->vq_entries[s]; 1151 qe = &vq->vq_entries[s];
1152 } 1152 }
1153 vq_free_entry(vq, qe); 1153 vq_free_entry(vq, qe);
1154 1154
1155 return 0; 1155 return 0;
1156} 1156}
1157 1157
1158/* 1158/*
1159 * Attach a child, fill all the members. 1159 * Attach a child, fill all the members.
1160 */ 1160 */
1161void 1161void
1162virtio_child_attach_start(struct virtio_softc *sc, device_t child, int ipl,  1162virtio_child_attach_start(struct virtio_softc *sc, device_t child, int ipl,
1163 struct virtqueue *vqs, 1163 struct virtqueue *vqs,
1164 virtio_callback config_change, 1164 virtio_callback config_change,
1165 virtio_callback intr_hand, 1165 virtio_callback intr_hand,
1166 int req_flags, int req_features, const char *feat_bits) 1166 int req_flags, int req_features, const char *feat_bits)
1167{ 1167{
1168 char buf[1024]; 1168 char buf[1024];
1169 1169
1170 sc->sc_child = child; 1170 sc->sc_child = child;
1171 sc->sc_ipl = ipl; 1171 sc->sc_ipl = ipl;
1172 sc->sc_vqs = vqs; 1172 sc->sc_vqs = vqs;
1173 sc->sc_config_change = config_change; 1173 sc->sc_config_change = config_change;
1174 sc->sc_intrhand = intr_hand; 1174 sc->sc_intrhand = intr_hand;
1175 sc->sc_flags = req_flags; 1175 sc->sc_flags = req_flags;
@@ -1197,27 +1197,27 @@ int @@ -1197,27 +1197,27 @@ int
1197virtio_child_attach_finish(struct virtio_softc *sc) 1197virtio_child_attach_finish(struct virtio_softc *sc)
1198{ 1198{
1199 int r; 1199 int r;
1200 1200
1201 sc->sc_finished_called = true; 1201 sc->sc_finished_called = true;
1202 r = sc->sc_ops->setup_interrupts(sc); 1202 r = sc->sc_ops->setup_interrupts(sc);
1203 if (r != 0) { 1203 if (r != 0) {
1204 aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n"); 1204 aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n");
1205 goto fail; 1205 goto fail;
1206 } 1206 }
1207 1207
1208 KASSERT(sc->sc_soft_ih == NULL); 1208 KASSERT(sc->sc_soft_ih == NULL);
1209 if (sc->sc_flags & VIRTIO_F_INTR_SOFTINT) { 1209 if (sc->sc_flags & VIRTIO_F_INTR_SOFTINT) {
1210 u_int flags = SOFTINT_NET;  1210 u_int flags = SOFTINT_NET;
1211 if (sc->sc_flags & VIRTIO_F_INTR_MPSAFE) 1211 if (sc->sc_flags & VIRTIO_F_INTR_MPSAFE)
1212 flags |= SOFTINT_MPSAFE; 1212 flags |= SOFTINT_MPSAFE;
1213 1213
1214 sc->sc_soft_ih = softint_establish(flags, virtio_soft_intr, sc); 1214 sc->sc_soft_ih = softint_establish(flags, virtio_soft_intr, sc);
1215 if (sc->sc_soft_ih == NULL) { 1215 if (sc->sc_soft_ih == NULL) {
1216 sc->sc_ops->free_interrupts(sc); 1216 sc->sc_ops->free_interrupts(sc);
1217 aprint_error_dev(sc->sc_dev, 1217 aprint_error_dev(sc->sc_dev,
1218 "failed to establish soft interrupt\n"); 1218 "failed to establish soft interrupt\n");
1219 goto fail; 1219 goto fail;
1220 } 1220 }
1221 } 1221 }
1222 1222
1223 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK); 1223 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
@@ -1313,41 +1313,41 @@ virtio_attach_failed(struct virtio_softc @@ -1313,41 +1313,41 @@ virtio_attach_failed(struct virtio_softc
1313 return 0; 1313 return 0;
1314} 1314}
1315 1315
1316void 1316void
1317virtio_print_device_type(device_t self, int id, int revision) 1317virtio_print_device_type(device_t self, int id, int revision)
1318{ 1318{
1319 aprint_normal_dev(self, "%s device (rev. 0x%02x)\n", 1319 aprint_normal_dev(self, "%s device (rev. 0x%02x)\n",
1320 (id < NDEVNAMES ? virtio_device_name[id] : "Unknown"), 1320 (id < NDEVNAMES ? virtio_device_name[id] : "Unknown"),
1321 revision); 1321 revision);
1322} 1322}
1323 1323
1324 1324
1325MODULE(MODULE_CLASS_DRIVER, virtio, NULL); 1325MODULE(MODULE_CLASS_DRIVER, virtio, NULL);
1326  1326
1327#ifdef _MODULE 1327#ifdef _MODULE
1328#include "ioconf.c" 1328#include "ioconf.c"
1329#endif 1329#endif
1330  1330
1331static int 1331static int
1332virtio_modcmd(modcmd_t cmd, void *opaque) 1332virtio_modcmd(modcmd_t cmd, void *opaque)
1333{ 1333{
1334 int error = 0; 1334 int error = 0;
1335  1335
1336#ifdef _MODULE 1336#ifdef _MODULE
1337 switch (cmd) { 1337 switch (cmd) {
1338 case MODULE_CMD_INIT: 1338 case MODULE_CMD_INIT:
1339 error = config_init_component(cfdriver_ioconf_virtio,  1339 error = config_init_component(cfdriver_ioconf_virtio,
1340 cfattach_ioconf_virtio, cfdata_ioconf_virtio);  1340 cfattach_ioconf_virtio, cfdata_ioconf_virtio);
1341 break; 1341 break;
1342 case MODULE_CMD_FINI: 1342 case MODULE_CMD_FINI:
1343 error = config_fini_component(cfdriver_ioconf_virtio,  1343 error = config_fini_component(cfdriver_ioconf_virtio,
1344 cfattach_ioconf_virtio, cfdata_ioconf_virtio); 1344 cfattach_ioconf_virtio, cfdata_ioconf_virtio);
1345 break; 1345 break;
1346 default: 1346 default:
1347 error = ENOTTY; 1347 error = ENOTTY;
1348 break; 1348 break;
1349 } 1349 }
1350#endif 1350#endif
1351  1351
1352 return error;  1352 return error;
1353} 1353}