Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Begin to detangle virtio from its PCI attachment



details:   https://anonhg.NetBSD.org/src/rev/4e771d30ebaf
branches:  trunk
changeset: 319547:4e771d30ebaf
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Sat Jun 02 22:43:15 2018 +0000

description:
Begin to detangle virtio from its PCI attachment

diffstat:

 sys/dev/pci/virtio.c     |  459 +++---------------------------------
 sys/dev/pci/virtio_pci.c |  583 ++++++++++++++++++++++++++++++++++++++++++++--
 sys/dev/pci/virtiovar.h  |   32 +-
 3 files changed, 621 insertions(+), 453 deletions(-)

diffs (truncated from 1358 to 300 lines):

diff -r 8975792b6e17 -r 4e771d30ebaf sys/dev/pci/virtio.c
--- a/sys/dev/pci/virtio.c      Sat Jun 02 22:30:19 2018 +0000
+++ b/sys/dev/pci/virtio.c      Sat Jun 02 22:43:15 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: virtio.c,v 1.30 2018/02/14 14:04:48 uwe Exp $  */
+/*     $NetBSD: virtio.c,v 1.31 2018/06/02 22:43:15 jakllsch Exp $     */
 
 /*
  * Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.30 2018/02/14 14:04:48 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.31 2018/06/02 22:43:15 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -48,300 +48,15 @@
 
 #define MINSEG_INDIRECT                2 /* use indirect if nsegs >= this value */
 
-static int     virtio_intr(void *arg);
-static int     virtio_msix_queue_intr(void *);
-static int     virtio_msix_config_intr(void *);
-static int     virtio_setup_msix_vectors(struct virtio_softc *);
-static int     virtio_setup_msix_interrupts(struct virtio_softc *,
-                   struct pci_attach_args *);
-static int     virtio_setup_intx_interrupt(struct virtio_softc *,
-                   struct pci_attach_args *);
-static int     virtio_setup_interrupts(struct virtio_softc *);
-static void    virtio_free_interrupts(struct virtio_softc *);
-static void    virtio_soft_intr(void *arg);
 static void    virtio_init_vq(struct virtio_softc *,
                    struct virtqueue *, const bool);
 
-
-/* we use the legacy virtio spec, so the pci registers are host native
- * byte order, not pci (i.e. LE) byte order */
-static inline uint16_t
-nbo_bus_space_read_2(bus_space_tag_t space, bus_space_handle_t handle,
-         bus_size_t offset)
-{
-       return le16toh(bus_space_read_2(space, handle, offset));
-}
-
-static inline uint32_t
-nbo_bus_space_read_4(bus_space_tag_t space, bus_space_handle_t handle,
-       bus_size_t offset)
-{
-       return le32toh(bus_space_read_4(space, handle, offset));
-}
-
-static void
-nbo_bus_space_write_2(bus_space_tag_t space, bus_space_handle_t handle,
-       bus_size_t offset, uint16_t value)
-{
-       bus_space_write_2(space, handle, offset, htole16(value));
-}
-
-static void
-nbo_bus_space_write_4(bus_space_tag_t space, bus_space_handle_t handle,
-       bus_size_t offset, uint32_t value)
-{
-       bus_space_write_4(space, handle, offset, htole32(value));
-}
-
-/* some functions access registers at 4 byte offset for little/high halves */
-#if BYTE_ORDER == BIG_ENDIAN
-#define REG_HI_OFF     0
-#define REG_LO_OFF     4
-#else
-#define REG_HI_OFF     4
-#define REG_LO_OFF     0
-#endif
-
 void
 virtio_set_status(struct virtio_softc *sc, int status)
 {
-       int old = 0;
-
-       if (status != 0)
-               old = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
-                                      VIRTIO_CONFIG_DEVICE_STATUS);
-       bus_space_write_1(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_DEVICE_STATUS,
-                         status|old);
-}
-
-#define VIRTIO_MSIX_CONFIG_VECTOR_INDEX        0
-#define VIRTIO_MSIX_QUEUE_VECTOR_INDEX 1
-
-static int
-virtio_setup_msix_vectors(struct virtio_softc *sc)
-{
-       int offset, vector, ret, qid;
-
-       offset = VIRTIO_CONFIG_MSI_CONFIG_VECTOR;
-       vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
-
-       nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector);
-       ret = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset);
-       aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
-           vector, ret);
-       if (ret != vector)
-               return -1;
-
-       for (qid = 0; qid < sc->sc_nvqs; qid++) {
-               offset = VIRTIO_CONFIG_QUEUE_SELECT;
-               nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, qid);
-
-               offset = VIRTIO_CONFIG_MSI_QUEUE_VECTOR;
-               vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
-
-               nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector);
-               ret = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset);
-               aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
-                   vector, ret);
-               if (ret != vector)
-                       return -1;
-       }
-
-       return 0;
-}
-
-static int
-virtio_setup_msix_interrupts(struct virtio_softc *sc,
-    struct pci_attach_args *pa)
-{
-       device_t self = sc->sc_dev;
-       pci_chipset_tag_t pc = pa->pa_pc;
-       char intrbuf[PCI_INTRSTR_LEN];
-       char const *intrstr;
-       int idx;
-
-       idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
-       if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE)
-               pci_intr_setattr(pc, &sc->sc_ihp[idx], PCI_INTR_MPSAFE, true);
-
-       sc->sc_ihs[idx] = pci_intr_establish_xname(pc, sc->sc_ihp[idx],
-           sc->sc_ipl, virtio_msix_config_intr, sc, device_xname(sc->sc_dev));
-       if (sc->sc_ihs[idx] == NULL) {
-               aprint_error_dev(self, "couldn't establish MSI-X for config\n");
-               goto error;
-       }
-
-       idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
-       if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE)
-               pci_intr_setattr(pc, &sc->sc_ihp[idx], PCI_INTR_MPSAFE, true);
-
-       sc->sc_ihs[idx] = pci_intr_establish_xname(pc, sc->sc_ihp[idx],
-           sc->sc_ipl, virtio_msix_queue_intr, sc, device_xname(sc->sc_dev));
-       if (sc->sc_ihs[idx] == NULL) {
-               aprint_error_dev(self, "couldn't establish MSI-X for queues\n");
-               goto error;
-       }
-
-       if (virtio_setup_msix_vectors(sc) != 0) {
-               aprint_error_dev(self, "couldn't setup MSI-X vectors\n");
-               goto error;
-       }
-
-       idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
-       intrstr = pci_intr_string(pc, sc->sc_ihp[idx], intrbuf, sizeof(intrbuf));
-       aprint_normal_dev(self, "config interrupting at %s\n", intrstr);
-       idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
-       intrstr = pci_intr_string(pc, sc->sc_ihp[idx], intrbuf, sizeof(intrbuf));
-       aprint_normal_dev(self, "queues interrupting at %s\n", intrstr);
-
-       return 0;
-
-error:
-       idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
-       if (sc->sc_ihs[idx] != NULL)
-               pci_intr_disestablish(sc->sc_pc, sc->sc_ihs[idx]);
-       idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
-       if (sc->sc_ihs[idx] != NULL)
-               pci_intr_disestablish(sc->sc_pc, sc->sc_ihs[idx]);
-
-       return -1;
+       sc->sc_ops->set_status(sc, status);
 }
 
-static int
-virtio_setup_intx_interrupt(struct virtio_softc *sc,
-    struct pci_attach_args *pa)
-{
-       device_t self = sc->sc_dev;
-       pci_chipset_tag_t pc = pa->pa_pc;
-       char intrbuf[PCI_INTRSTR_LEN];
-       char const *intrstr;
-
-       if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE)
-               pci_intr_setattr(pc, &sc->sc_ihp[0], PCI_INTR_MPSAFE, true);
-
-       sc->sc_ihs[0] = pci_intr_establish_xname(pc, sc->sc_ihp[0],
-           sc->sc_ipl, virtio_intr, sc, device_xname(sc->sc_dev));
-       if (sc->sc_ihs[0] == NULL) {
-               aprint_error_dev(self, "couldn't establish INTx\n");
-               return -1;
-       }
-
-       intrstr = pci_intr_string(pc, sc->sc_ihp[0], intrbuf, sizeof(intrbuf));
-       aprint_normal_dev(self, "interrupting at %s\n", intrstr);
-
-       return 0;
-}
-
-static int
-virtio_setup_interrupts(struct virtio_softc *sc)
-{
-       device_t self = sc->sc_dev;
-       pci_chipset_tag_t pc = sc->sc_pa.pa_pc;
-       int error;
-       int nmsix;
-       int counts[PCI_INTR_TYPE_SIZE];
-       pci_intr_type_t max_type;
-
-       nmsix = pci_msix_count(sc->sc_pa.pa_pc, sc->sc_pa.pa_tag);
-       aprint_debug_dev(self, "pci_msix_count=%d\n", nmsix);
-
-       /* We need at least two: one for config and the other for queues */
-       if ((sc->sc_flags & VIRTIO_F_PCI_INTR_MSIX) == 0 || nmsix < 2) {
-               /* Try INTx only */
-               max_type = PCI_INTR_TYPE_INTX;
-               counts[PCI_INTR_TYPE_INTX] = 1;
-       } else {
-               /* Try MSI-X first and INTx second */
-               max_type = PCI_INTR_TYPE_MSIX;
-               counts[PCI_INTR_TYPE_MSIX] = 2;
-               counts[PCI_INTR_TYPE_MSI] = 0;
-               counts[PCI_INTR_TYPE_INTX] = 1;
-       }
-
- retry:
-       error = pci_intr_alloc(&sc->sc_pa, &sc->sc_ihp, counts, max_type);
-       if (error != 0) {
-               aprint_error_dev(self, "couldn't map interrupt\n");
-               return -1;
-       }
-
-       if (pci_intr_type(pc, sc->sc_ihp[0]) == PCI_INTR_TYPE_MSIX) {
-               sc->sc_ihs = kmem_alloc(sizeof(*sc->sc_ihs) * 2,
-                   KM_SLEEP);
-
-               error = virtio_setup_msix_interrupts(sc, &sc->sc_pa);
-               if (error != 0) {
-                       kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * 2);
-                       pci_intr_release(pc, sc->sc_ihp, 2);
-
-                       /* Retry INTx */
-                       max_type = PCI_INTR_TYPE_INTX;
-                       counts[PCI_INTR_TYPE_INTX] = 1;
-                       goto retry;
-               }
-
-               sc->sc_ihs_num = 2;
-               sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_MSI;
-       } else if (pci_intr_type(pc, sc->sc_ihp[0]) == PCI_INTR_TYPE_INTX) {
-               sc->sc_ihs = kmem_alloc(sizeof(*sc->sc_ihs) * 1,
-                   KM_SLEEP);
-
-               error = virtio_setup_intx_interrupt(sc, &sc->sc_pa);
-               if (error != 0) {
-                       kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * 1);
-                       pci_intr_release(pc, sc->sc_ihp, 1);
-                       return -1;
-               }
-
-               sc->sc_ihs_num = 1;
-               sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI;
-       }
-
-       KASSERT(sc->sc_soft_ih == NULL);
-       if (sc->sc_flags & VIRTIO_F_PCI_INTR_SOFTINT) {
-               u_int flags = SOFTINT_NET;
-               if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE)
-                       flags |= SOFTINT_MPSAFE;
-
-               sc->sc_soft_ih = softint_establish(flags, virtio_soft_intr, sc);
-               if (sc->sc_soft_ih == NULL) {
-                       virtio_free_interrupts(sc);
-                       aprint_error_dev(sc->sc_dev,
-                           "failed to establish soft interrupt\n");
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-static void
-virtio_free_interrupts(struct virtio_softc *sc)
-{
-       for (int i = 0; i < sc->sc_ihs_num; i++) {
-               if (sc->sc_ihs[i] == NULL)
-                       continue;
-               pci_intr_disestablish(sc->sc_pc, sc->sc_ihs[i]);
-               sc->sc_ihs[i] = NULL;
-       }
-



Home | Main Index | Thread Index | Old Index