Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Functionize the same code related to ctrl vq in ...
details: https://anonhg.NetBSD.org/src/rev/d309379cc431
branches: trunk
changeset: 447509:d309379cc431
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Mon Jan 14 14:52:57 2019 +0000
description:
Functionize the same code related to ctrl vq in vioif(4)
diffstat:
sys/dev/pci/if_vioif.c | 256 ++++++++++++++++++++++++++----------------------
1 files changed, 140 insertions(+), 116 deletions(-)
diffs (truncated from 348 to 300 lines):
diff -r f5c79eb5ef40 -r d309379cc431 sys/dev/pci/if_vioif.c
--- a/sys/dev/pci/if_vioif.c Mon Jan 14 14:35:52 2019 +0000
+++ b/sys/dev/pci/if_vioif.c Mon Jan 14 14:52:57 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vioif.c,v 1.43 2019/01/14 14:35:52 yamaguchi Exp $ */
+/* $NetBSD: if_vioif.c,v 1.44 2019/01/14 14:52:57 yamaguchi Exp $ */
/*
* Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.43 2019/01/14 14:35:52 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.44 2019/01/14 14:52:57 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -171,6 +171,11 @@
uint16_t id;
} __packed;
+struct vioif_ctrl_cmdspec {
+ bus_dmamap_t dmamap;
+ void *buf;
+ bus_size_t bufsize;
+};
/*
* if_vioifvar.h:
@@ -222,6 +227,7 @@
} ctrlq_inuse;
kcondvar_t ctrlq_wait;
kmutex_t ctrlq_wait_lock;
+ struct lwp *ctrlq_owner;
struct virtio_net_ctrl_cmd *ctrlq_cmd;
struct virtio_net_ctrl_status *ctrlq_status;
@@ -1279,33 +1285,96 @@
* Control vq
*/
/* issue a VIRTIO_NET_CTRL_RX class command and wait for completion */
-static int
-vioif_ctrl_rx(struct vioif_softc *sc, int cmd, bool onoff)
+static void
+vioif_ctrl_acquire(struct vioif_softc *sc)
{
- struct virtio_softc *vsc = sc->sc_virtio;
struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
- struct virtqueue *vq = ctrlq->ctrlq_vq;
- int r, slot;
-
- if (!sc->sc_has_ctrl)
- return ENOTSUP;
mutex_enter(&ctrlq->ctrlq_wait_lock);
while (ctrlq->ctrlq_inuse != FREE)
cv_wait(&ctrlq->ctrlq_wait, &ctrlq->ctrlq_wait_lock);
ctrlq->ctrlq_inuse = INUSE;
+ ctrlq->ctrlq_owner = curlwp;
mutex_exit(&ctrlq->ctrlq_wait_lock);
+}
+
+static void
+vioif_ctrl_release(struct vioif_softc *sc)
+{
+ struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
+
+ KASSERT(ctrlq->ctrlq_inuse != FREE);
+ KASSERT(ctrlq->ctrlq_owner == curlwp);
+
+ mutex_enter(&ctrlq->ctrlq_wait_lock);
+ ctrlq->ctrlq_inuse = FREE;
+ cv_signal(&ctrlq->ctrlq_wait);
+ mutex_exit(&ctrlq->ctrlq_wait_lock);
+}
+
+static int
+vioif_ctrl_load_cmdspec(struct vioif_softc *sc,
+ struct vioif_ctrl_cmdspec *specs, int nspecs)
+{
+ struct virtio_softc *vsc = sc->sc_virtio;
+ int i, r, loaded;
- ctrlq->ctrlq_cmd->class = VIRTIO_NET_CTRL_RX;
+ loaded = 0;
+ for (i = 0; i < nspecs; i++) {
+ r = bus_dmamap_load(virtio_dmat(vsc),
+ specs[i].dmamap, specs[i].buf, specs[i].bufsize,
+ NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
+ if (r) {
+ printf("%s: control command dmamap load failed, "
+ "error code %d\n", device_xname(sc->sc_dev), r);
+ goto err;
+ }
+ loaded++;
+
+ }
+
+ return r;
+
+err:
+ for (i = 0; i < loaded; i++) {
+ bus_dmamap_unload(virtio_dmat(vsc), specs[i].dmamap);
+ }
+
+ return r;
+}
+
+static void
+vioif_ctrl_unload_cmdspec(struct vioif_softc *sc,
+ struct vioif_ctrl_cmdspec *specs, int nspecs)
+{
+ struct virtio_softc *vsc = sc->sc_virtio;
+ int i;
+
+ for (i = 0; i < nspecs; i++) {
+ bus_dmamap_unload(virtio_dmat(vsc), specs[i].dmamap);
+ }
+}
+
+static int
+vioif_ctrl_send_command(struct vioif_softc *sc, uint8_t class, uint8_t cmd,
+ struct vioif_ctrl_cmdspec *specs, int nspecs)
+{
+ struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
+ struct virtqueue *vq = ctrlq->ctrlq_vq;
+ struct virtio_softc *vsc = sc->sc_virtio;
+ int i, r, slot;
+
+ ctrlq->ctrlq_cmd->class = class;
ctrlq->ctrlq_cmd->command = cmd;
- ctrlq->ctrlq_rx->onoff = onoff;
bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_cmd_dmamap,
0, sizeof(struct virtio_net_ctrl_cmd),
BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_rx_dmamap,
- 0, sizeof(struct virtio_net_ctrl_rx),
- BUS_DMASYNC_PREWRITE);
+ for (i = 0; i < nspecs; i++) {
+ bus_dmamap_sync(virtio_dmat(vsc), specs[i].dmamap,
+ 0, specs[i].bufsize,
+ BUS_DMASYNC_PREWRITE);
+ }
bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_status_dmamap,
0, sizeof(struct virtio_net_ctrl_status),
BUS_DMASYNC_PREREAD);
@@ -1313,11 +1382,13 @@
r = virtio_enqueue_prep(vsc, vq, &slot);
if (r != 0)
panic("%s: control vq busy!?", device_xname(sc->sc_dev));
- r = virtio_enqueue_reserve(vsc, vq, slot, 3);
+ r = virtio_enqueue_reserve(vsc, vq, slot, nspecs + 2);
if (r != 0)
panic("%s: control vq busy!?", device_xname(sc->sc_dev));
virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_cmd_dmamap, true);
- virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_rx_dmamap, true);
+ for (i = 0; i < nspecs; i++) {
+ virtio_enqueue(vsc, vq, slot, specs[i].dmamap, true);
+ }
virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_status_dmamap, false);
virtio_enqueue_commit(vsc, vq, slot, true);
@@ -1331,9 +1402,11 @@
bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_cmd_dmamap, 0,
sizeof(struct virtio_net_ctrl_cmd),
BUS_DMASYNC_POSTWRITE);
- bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_rx_dmamap, 0,
- sizeof(struct virtio_net_ctrl_rx),
- BUS_DMASYNC_POSTWRITE);
+ for (i = 0; i < nspecs; i++) {
+ bus_dmamap_sync(virtio_dmat(vsc), specs[i].dmamap, 0,
+ specs[i].bufsize,
+ BUS_DMASYNC_POSTWRITE);
+ }
bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_status_dmamap, 0,
sizeof(struct virtio_net_ctrl_status),
BUS_DMASYNC_POSTREAD);
@@ -1346,11 +1419,30 @@
r = EIO;
}
- mutex_enter(&ctrlq->ctrlq_wait_lock);
- ctrlq->ctrlq_inuse = FREE;
- cv_signal(&ctrlq->ctrlq_wait);
- mutex_exit(&ctrlq->ctrlq_wait_lock);
+ return r;
+}
+
+static int
+vioif_ctrl_rx(struct vioif_softc *sc, int cmd, bool onoff)
+{
+ struct virtio_net_ctrl_rx *rx = sc->sc_ctrlq.ctrlq_rx;
+ struct vioif_ctrl_cmdspec specs[1];
+ int r;
+ if (!sc->sc_has_ctrl)
+ return ENOTSUP;
+
+ vioif_ctrl_acquire(sc);
+
+ rx->onoff = onoff;
+ specs[0].dmamap = sc->sc_ctrlq.ctrlq_rx_dmamap;
+ specs[0].buf = rx;
+ specs[0].bufsize = sizeof(*rx);
+
+ r = vioif_ctrl_send_command(sc, VIRTIO_NET_CTRL_RX, cmd,
+ specs, __arraycount(specs));
+
+ vioif_ctrl_release(sc);
return r;
}
@@ -1379,109 +1471,41 @@
vioif_set_rx_filter(struct vioif_softc *sc)
{
/* filter already set in ctrlq->ctrlq_mac_tbl */
- struct virtio_softc *vsc = sc->sc_virtio;
- struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
- struct virtqueue *vq = ctrlq->ctrlq_vq;
- int r, slot;
+ struct virtio_net_ctrl_mac_tbl *mac_tbl_uc, *mac_tbl_mc;
+ struct vioif_ctrl_cmdspec specs[2];
+ int nspecs = __arraycount(specs);
+ int r;
+
+ mac_tbl_uc = sc->sc_ctrlq.ctrlq_mac_tbl_uc;
+ mac_tbl_mc = sc->sc_ctrlq.ctrlq_mac_tbl_mc;
if (!sc->sc_has_ctrl)
return ENOTSUP;
- mutex_enter(&ctrlq->ctrlq_wait_lock);
- while (ctrlq->ctrlq_inuse != FREE)
- cv_wait(&ctrlq->ctrlq_wait, &ctrlq->ctrlq_wait_lock);
- ctrlq->ctrlq_inuse = INUSE;
- mutex_exit(&ctrlq->ctrlq_wait_lock);
-
- ctrlq->ctrlq_cmd->class = VIRTIO_NET_CTRL_MAC;
- ctrlq->ctrlq_cmd->command = VIRTIO_NET_CTRL_MAC_TABLE_SET;
+ vioif_ctrl_acquire(sc);
- r = bus_dmamap_load(virtio_dmat(vsc), ctrlq->ctrlq_tbl_uc_dmamap,
- ctrlq->ctrlq_mac_tbl_uc,
- (sizeof(struct virtio_net_ctrl_mac_tbl)
- + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_uc->nentries),
- NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
- if (r) {
- printf("%s: control command dmamap load failed, "
- "error code %d\n", device_xname(sc->sc_dev), r);
- goto out;
- }
- r = bus_dmamap_load(virtio_dmat(vsc), ctrlq->ctrlq_tbl_mc_dmamap,
- ctrlq->ctrlq_mac_tbl_mc,
- (sizeof(struct virtio_net_ctrl_mac_tbl)
- + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_mc->nentries),
- NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
- if (r) {
- printf("%s: control command dmamap load failed, "
- "error code %d\n", device_xname(sc->sc_dev), r);
- bus_dmamap_unload(virtio_dmat(vsc), ctrlq->ctrlq_tbl_uc_dmamap);
- goto out;
- }
+ specs[0].dmamap = sc->sc_ctrlq.ctrlq_tbl_uc_dmamap;
+ specs[0].buf = mac_tbl_uc;
+ specs[0].bufsize = sizeof(*mac_tbl_uc)
+ + (ETHER_ADDR_LEN * mac_tbl_uc->nentries);
- bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_cmd_dmamap,
- 0, sizeof(struct virtio_net_ctrl_cmd),
- BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_tbl_uc_dmamap, 0,
- (sizeof(struct virtio_net_ctrl_mac_tbl)
- + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_uc->nentries),
- BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_tbl_mc_dmamap, 0,
- (sizeof(struct virtio_net_ctrl_mac_tbl)
- + ETHER_ADDR_LEN * ctrlq->ctrlq_mac_tbl_mc->nentries),
- BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(virtio_dmat(vsc), ctrlq->ctrlq_status_dmamap,
- 0, sizeof(struct virtio_net_ctrl_status),
- BUS_DMASYNC_PREREAD);
-
- r = virtio_enqueue_prep(vsc, vq, &slot);
- if (r != 0)
- panic("%s: control vq busy!?", device_xname(sc->sc_dev));
- r = virtio_enqueue_reserve(vsc, vq, slot, 4);
- if (r != 0)
- panic("%s: control vq busy!?", device_xname(sc->sc_dev));
- virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_cmd_dmamap, true);
- virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_tbl_uc_dmamap, true);
- virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_tbl_mc_dmamap, true);
- virtio_enqueue(vsc, vq, slot, ctrlq->ctrlq_status_dmamap, false);
- virtio_enqueue_commit(vsc, vq, slot, true);
+ specs[1].dmamap = sc->sc_ctrlq.ctrlq_tbl_mc_dmamap;
+ specs[1].buf = mac_tbl_mc;
+ specs[1].bufsize = sizeof(*mac_tbl_mc)
+ + (ETHER_ADDR_LEN * mac_tbl_mc->nentries);
Home |
Main Index |
Thread Index |
Old Index