mirror of
https://github.com/openbsd/src.git
synced 2024-12-21 23:18:00 -08:00
virtio: Refactor attach logic
virtio 1.x requires that all queue setup, including the queue interrupt vector, is done before setting the queue_enable register to 1. This conflicts with how we do things right now: * We implicitly make queue setup in virtio_alloc_vq(), which is called from the child driver attach functions. This also sets queue_enable=1. * Later, we allocate the interrupts and set the queue interrupt vectors in the second half of the virtio transport attach functions. This is a violation of a MUST from the standard and causes problems with some hypervisors, in particular those that have no virtio 0.9 support, which has no such ordering requirements. To fix this: * Move the interrupt allocation to a new virtio_attach_finish() function. This does all queue setup, including the interrupt vectors. * Don't call virtio_setup_queue() in virtio_alloc_vq() anymore. * We can also move the setting of the DRIVER_OK flag into this function. virtio_attach_finish() must be called before using any virtqueue or writing any virtio config register. While there, * also streamline the attach error handling in all drivers. * skip initially setting sc_config_change to NULL, the softc is initialized to 0. ok jan@ tested by bluhm@
This commit is contained in:
parent
7aa20da420
commit
77d0f8231d
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: virtio_mmio.c,v 1.20 2024/12/03 19:14:40 sf Exp $ */
|
||||
/* $OpenBSD: virtio_mmio.c,v 1.21 2024/12/20 22:18:27 sf Exp $ */
|
||||
/* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */
|
||||
|
||||
/*
|
||||
@ -98,6 +98,7 @@ void virtio_mmio_write_device_config_8(struct virtio_softc *, int, uint64_t);
|
||||
uint16_t virtio_mmio_read_queue_size(struct virtio_softc *, uint16_t);
|
||||
void virtio_mmio_setup_queue(struct virtio_softc *, struct virtqueue *, uint64_t);
|
||||
void virtio_mmio_setup_intrs(struct virtio_softc *);
|
||||
int virtio_mmio_attach_finish(struct virtio_softc *, struct virtio_attach_args *);
|
||||
int virtio_mmio_get_status(struct virtio_softc *);
|
||||
void virtio_mmio_set_status(struct virtio_softc *, int);
|
||||
int virtio_mmio_negotiate_features(struct virtio_softc *,
|
||||
@ -119,6 +120,11 @@ struct virtio_mmio_softc {
|
||||
uint32_t sc_version;
|
||||
};
|
||||
|
||||
struct virtio_mmio_attach_args {
|
||||
struct virtio_attach_args vma_va;
|
||||
struct fdt_attach_args *vma_fa;
|
||||
};
|
||||
|
||||
const struct cfattach virtio_mmio_ca = {
|
||||
sizeof(struct virtio_mmio_softc),
|
||||
virtio_mmio_match,
|
||||
@ -151,6 +157,7 @@ const struct virtio_ops virtio_mmio_ops = {
|
||||
virtio_mmio_get_status,
|
||||
virtio_mmio_set_status,
|
||||
virtio_mmio_negotiate_features,
|
||||
virtio_mmio_attach_finish,
|
||||
virtio_mmio_intr,
|
||||
virtio_mmio_intr_barrier,
|
||||
};
|
||||
@ -250,7 +257,7 @@ virtio_mmio_attach(struct device *parent, struct device *self, void *aux)
|
||||
struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)self;
|
||||
struct virtio_softc *vsc = &sc->sc_sc;
|
||||
uint32_t id, magic;
|
||||
struct virtio_attach_args va = { 0 };
|
||||
struct virtio_mmio_attach_args vma = { { 0 }, faa };
|
||||
|
||||
if (faa->fa_nreg < 1) {
|
||||
printf(": no register data\n");
|
||||
@ -299,38 +306,45 @@ virtio_mmio_attach(struct device *parent, struct device *self, void *aux)
|
||||
virtio_mmio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
|
||||
virtio_mmio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);
|
||||
|
||||
va.va_devid = id;
|
||||
va.va_nintr = 1;
|
||||
vma.vma_va.va_devid = id;
|
||||
vma.vma_va.va_nintr = 1;
|
||||
vsc->sc_child = NULL;
|
||||
config_found(self, &va, NULL);
|
||||
config_found(self, &vma, NULL);
|
||||
if (vsc->sc_child == NULL) {
|
||||
printf("%s: no matching child driver; not configured\n",
|
||||
vsc->sc_dev.dv_xname);
|
||||
goto fail_1;
|
||||
goto fail;
|
||||
}
|
||||
if (vsc->sc_child == VIRTIO_CHILD_ERROR) {
|
||||
printf("%s: virtio configuration failed\n",
|
||||
vsc->sc_dev.dv_xname);
|
||||
goto fail_1;
|
||||
}
|
||||
|
||||
sc->sc_ih = fdt_intr_establish(faa->fa_node, vsc->sc_ipl,
|
||||
virtio_mmio_intr, sc, vsc->sc_dev.dv_xname);
|
||||
if (sc->sc_ih == NULL) {
|
||||
printf("%s: couldn't establish interrupt\n",
|
||||
vsc->sc_dev.dv_xname);
|
||||
goto fail_2;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail_2:
|
||||
config_detach(vsc->sc_child, 0);
|
||||
fail_1:
|
||||
/* no mmio_mapreg_unmap() or mmio_intr_unmap() */
|
||||
fail:
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
|
||||
}
|
||||
|
||||
int
|
||||
virtio_mmio_attach_finish(struct virtio_softc *vsc,
|
||||
struct virtio_attach_args *va)
|
||||
{
|
||||
struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc;
|
||||
struct virtio_mmio_attach_args *vma =
|
||||
(struct virtio_mmio_attach_args *)va;
|
||||
|
||||
sc->sc_ih = fdt_intr_establish(vma->vma_fa->fa_node, vsc->sc_ipl,
|
||||
virtio_mmio_intr, sc, vsc->sc_dev.dv_xname);
|
||||
if (sc->sc_ih == NULL) {
|
||||
printf("%s: couldn't establish interrupt\n",
|
||||
vsc->sc_dev.dv_xname);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
virtio_mmio_detach(struct device *self, int flags)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: virtio_pci.c,v 1.47 2024/12/03 19:14:40 sf Exp $ */
|
||||
/* $OpenBSD: virtio_pci.c,v 1.48 2024/12/20 22:18:27 sf Exp $ */
|
||||
/* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */
|
||||
|
||||
/*
|
||||
@ -74,6 +74,7 @@ void virtio_pci_write_device_config_8(struct virtio_softc *, int, uint64_t);
|
||||
uint16_t virtio_pci_read_queue_size(struct virtio_softc *, uint16_t);
|
||||
void virtio_pci_setup_queue(struct virtio_softc *, struct virtqueue *, uint64_t);
|
||||
void virtio_pci_setup_intrs(struct virtio_softc *);
|
||||
int virtio_pci_attach_finish(struct virtio_softc *, struct virtio_attach_args *);
|
||||
int virtio_pci_get_status(struct virtio_softc *);
|
||||
void virtio_pci_set_status(struct virtio_softc *, int);
|
||||
int virtio_pci_negotiate_features(struct virtio_softc *, const struct virtio_feature_name *);
|
||||
@ -175,6 +176,7 @@ const struct virtio_ops virtio_pci_ops = {
|
||||
virtio_pci_get_status,
|
||||
virtio_pci_set_status,
|
||||
virtio_pci_negotiate_features,
|
||||
virtio_pci_attach_finish,
|
||||
virtio_pci_poll_intr,
|
||||
virtio_pci_intr_barrier,
|
||||
};
|
||||
@ -592,8 +594,6 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux)
|
||||
pcitag_t tag = pa->pa_tag;
|
||||
int revision, ret = ENODEV;
|
||||
pcireg_t id;
|
||||
char const *intrstr;
|
||||
pci_intr_handle_t ih;
|
||||
struct virtio_pci_attach_args vpa = { { 0 }, pa };
|
||||
|
||||
revision = PCI_REVISION(pa->pa_class);
|
||||
@ -645,13 +645,13 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux)
|
||||
}
|
||||
if (ret != 0) {
|
||||
printf(": Cannot attach (%d)\n", ret);
|
||||
goto fail_0;
|
||||
goto free;
|
||||
}
|
||||
|
||||
sc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI;
|
||||
sc->sc_irq_type = IRQ_NO_MSIX;
|
||||
if (virtio_pci_adjust_config_region(sc) != 0)
|
||||
goto fail_0;
|
||||
goto err;
|
||||
|
||||
virtio_device_reset(vsc);
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
|
||||
@ -664,25 +664,47 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux)
|
||||
if (vsc->sc_child == NULL) {
|
||||
printf("%s: no matching child driver; not configured\n",
|
||||
vsc->sc_dev.dv_xname);
|
||||
goto fail_1;
|
||||
goto err;
|
||||
}
|
||||
if (vsc->sc_child == VIRTIO_CHILD_ERROR) {
|
||||
printf("%s: virtio configuration failed\n",
|
||||
vsc->sc_dev.dv_xname);
|
||||
goto fail_1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (virtio_pci_setup_msix(sc, &vpa, 0) == 0) {
|
||||
return;
|
||||
|
||||
err:
|
||||
/* no pci_mapreg_unmap() or pci_intr_unmap() */
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
|
||||
free:
|
||||
free(sc->sc_intr, M_DEVBUF, sc->sc_nintr * sizeof(*sc->sc_intr));
|
||||
}
|
||||
|
||||
int
|
||||
virtio_pci_attach_finish(struct virtio_softc *vsc,
|
||||
struct virtio_attach_args *va)
|
||||
{
|
||||
struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
|
||||
struct virtio_pci_attach_args *vpa =
|
||||
(struct virtio_pci_attach_args *)va;
|
||||
pci_intr_handle_t ih;
|
||||
pci_chipset_tag_t pc = vpa->vpa_pa->pa_pc;
|
||||
char const *intrstr;
|
||||
|
||||
if (virtio_pci_setup_msix(sc, vpa, 0) == 0) {
|
||||
sc->sc_irq_type = IRQ_MSIX_PER_VQ;
|
||||
intrstr = "msix per-VQ";
|
||||
} else if (virtio_pci_setup_msix(sc, &vpa, 1) == 0) {
|
||||
} else if (virtio_pci_setup_msix(sc, vpa, 1) == 0) {
|
||||
sc->sc_irq_type = IRQ_MSIX_SHARED;
|
||||
intrstr = "msix shared";
|
||||
} else {
|
||||
int (*ih_func)(void *) = virtio_pci_legacy_intr;
|
||||
if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
|
||||
printf("%s: couldn't map interrupt\n", vsc->sc_dev.dv_xname);
|
||||
goto fail_2;
|
||||
if (pci_intr_map_msi(vpa->vpa_pa, &ih) != 0 &&
|
||||
pci_intr_map(vpa->vpa_pa, &ih) != 0) {
|
||||
printf("%s: couldn't map interrupt\n",
|
||||
vsc->sc_dev.dv_xname);
|
||||
return -EIO;
|
||||
}
|
||||
intrstr = pci_intr_string(pc, ih);
|
||||
/*
|
||||
@ -696,25 +718,17 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux)
|
||||
vsc->sc_ipl | IPL_MPSAFE, ih_func, sc,
|
||||
vsc->sc_child->dv_xname);
|
||||
if (sc->sc_intr[0].ih == NULL) {
|
||||
printf("%s: couldn't establish interrupt", vsc->sc_dev.dv_xname);
|
||||
printf("%s: couldn't establish interrupt",
|
||||
vsc->sc_dev.dv_xname);
|
||||
if (intrstr != NULL)
|
||||
printf(" at %s", intrstr);
|
||||
printf("\n");
|
||||
goto fail_2;
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
virtio_pci_setup_intrs(vsc);
|
||||
|
||||
printf("%s: %s\n", vsc->sc_dev.dv_xname, intrstr);
|
||||
|
||||
return;
|
||||
|
||||
fail_2:
|
||||
config_detach(vsc->sc_child, 0);
|
||||
fail_1:
|
||||
/* no pci_mapreg_unmap() or pci_intr_unmap() */
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
|
||||
fail_0:
|
||||
free(sc->sc_intr, M_DEVBUF, sc->sc_nintr * sizeof(*sc->sc_intr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: if_vio.c,v 1.61 2024/12/03 19:14:40 sf Exp $ */
|
||||
/* $OpenBSD: if_vio.c,v 1.62 2024/12/20 22:18:27 sf Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
|
||||
@ -597,6 +597,7 @@ vio_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct vio_softc *sc = (struct vio_softc *)self;
|
||||
struct virtio_softc *vsc = (struct virtio_softc *)parent;
|
||||
struct virtio_attach_args *va = aux;
|
||||
int i, tx_max_segments;
|
||||
struct ifnet *ifp = &sc->sc_ac.ac_if;
|
||||
|
||||
@ -610,7 +611,6 @@ vio_attach(struct device *parent, struct device *self, void *aux)
|
||||
|
||||
vsc->sc_child = self;
|
||||
vsc->sc_ipl = IPL_NET | IPL_MPSAFE;
|
||||
vsc->sc_config_change = NULL;
|
||||
vsc->sc_driver_features = VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS |
|
||||
VIRTIO_NET_F_CTRL_VQ | VIRTIO_NET_F_CTRL_RX |
|
||||
VIRTIO_NET_F_MRG_RXBUF | VIRTIO_NET_F_CSUM |
|
||||
@ -623,7 +623,8 @@ vio_attach(struct device *parent, struct device *self, void *aux)
|
||||
vsc->sc_driver_features |= VIRTIO_NET_F_GUEST_TSO4;
|
||||
vsc->sc_driver_features |= VIRTIO_NET_F_GUEST_TSO6;
|
||||
|
||||
virtio_negotiate_features(vsc, virtio_net_feature_names);
|
||||
if (virtio_negotiate_features(vsc, virtio_net_feature_names) != 0)
|
||||
goto err;
|
||||
|
||||
sc->sc_nqueues = 1;
|
||||
vsc->sc_nvqs = 2 * sc->sc_nqueues;
|
||||
@ -756,7 +757,9 @@ vio_attach(struct device *parent, struct device *self, void *aux)
|
||||
timeout_set(&sc->sc_txtick, vio_txtick, sc);
|
||||
timeout_set(&sc->sc_rxtick, vio_rxtick, sc);
|
||||
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
|
||||
if (virtio_attach_finish(vsc, va) != 0)
|
||||
goto err;
|
||||
|
||||
if_attach(ifp);
|
||||
ether_ifattach(ifp);
|
||||
vio_link_state(ifp);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: vioblk.c,v 1.43 2024/08/27 18:44:12 sf Exp $ */
|
||||
/* $OpenBSD: vioblk.c,v 1.44 2024/12/20 22:18:27 sf Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Stefan Fritsch.
|
||||
@ -170,12 +170,12 @@ vioblk_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct vioblk_softc *sc = (struct vioblk_softc *)self;
|
||||
struct virtio_softc *vsc = (struct virtio_softc *)parent;
|
||||
struct virtio_attach_args *va = aux;
|
||||
struct scsibus_attach_args saa;
|
||||
int qsize;
|
||||
|
||||
vsc->sc_vqs = &sc->sc_vq[0];
|
||||
vsc->sc_nvqs = 1;
|
||||
vsc->sc_config_change = NULL;
|
||||
if (vsc->sc_child)
|
||||
panic("already attached to something else");
|
||||
vsc->sc_child = self;
|
||||
@ -184,7 +184,8 @@ vioblk_attach(struct device *parent, struct device *self, void *aux)
|
||||
vsc->sc_driver_features = VIRTIO_BLK_F_RO | VIRTIO_F_NOTIFY_ON_EMPTY |
|
||||
VIRTIO_BLK_F_SIZE_MAX | VIRTIO_BLK_F_SEG_MAX | VIRTIO_BLK_F_FLUSH;
|
||||
|
||||
virtio_negotiate_features(vsc, vioblk_feature_names);
|
||||
if (virtio_negotiate_features(vsc, vioblk_feature_names) != 0)
|
||||
goto err;
|
||||
|
||||
if (virtio_has_feature(vsc, VIRTIO_BLK_F_SIZE_MAX)) {
|
||||
uint32_t size_max = virtio_read_device_config_4(vsc,
|
||||
@ -252,10 +253,11 @@ vioblk_attach(struct device *parent, struct device *self, void *aux)
|
||||
saa.saa_quirks = 0;
|
||||
saa.saa_wwpn = saa.saa_wwnn = 0;
|
||||
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
|
||||
if (virtio_attach_finish(vsc, va) != 0)
|
||||
goto err;
|
||||
config_found(self, &saa, scsiprint);
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
vsc->sc_child = VIRTIO_CHILD_ERROR;
|
||||
return;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: viocon.c,v 1.15 2024/08/27 18:44:12 sf Exp $ */
|
||||
/* $OpenBSD: viocon.c,v 1.16 2024/12/20 22:18:27 sf Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2015 Stefan Fritsch <sf@sfritsch.de>
|
||||
@ -179,7 +179,6 @@ viocon_attach(struct device *parent, struct device *self, void *aux)
|
||||
panic("already attached to something else");
|
||||
vsc->sc_child = self;
|
||||
vsc->sc_ipl = IPL_TTY;
|
||||
vsc->sc_config_change = NULL;
|
||||
sc->sc_virtio = vsc;
|
||||
sc->sc_max_ports = maxports;
|
||||
|
||||
@ -193,7 +192,8 @@ viocon_attach(struct device *parent, struct device *self, void *aux)
|
||||
}
|
||||
|
||||
vsc->sc_driver_features = VIRTIO_CONSOLE_F_SIZE;
|
||||
virtio_negotiate_features(vsc, viocon_feature_names);
|
||||
if (virtio_negotiate_features(vsc, viocon_feature_names) != 0)
|
||||
goto err;
|
||||
|
||||
printf("\n");
|
||||
DPRINTF("%s: softc: %p\n", __func__, sc);
|
||||
@ -201,10 +201,11 @@ viocon_attach(struct device *parent, struct device *self, void *aux)
|
||||
printf("\n%s: viocon_port_create failed\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
if (virtio_attach_finish(vsc, va) != 0)
|
||||
goto err;
|
||||
viocon_rx_fill(sc->sc_ports[0]);
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
vsc->sc_child = VIRTIO_CHILD_ERROR;
|
||||
free(vsc->sc_vqs, M_DEVBUF, 2 * (maxports + 1) * sizeof(struct virtqueue));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: viogpu.c,v 1.10 2024/11/04 15:43:10 sf Exp $ */
|
||||
/* $OpenBSD: viogpu.c,v 1.11 2024/12/20 22:18:27 sf Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021-2023 joshua stein <jcs@openbsd.org>
|
||||
@ -150,6 +150,7 @@ viogpu_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct viogpu_softc *sc = (struct viogpu_softc *)self;
|
||||
struct virtio_softc *vsc = (struct virtio_softc *)parent;
|
||||
struct virtio_attach_args *va = aux;
|
||||
struct wsemuldisplaydev_attach_args waa;
|
||||
struct rasops_info *ri = &sc->sc_ri;
|
||||
uint32_t defattr;
|
||||
@ -161,10 +162,11 @@ viogpu_attach(struct device *parent, struct device *self, void *aux)
|
||||
}
|
||||
vsc->sc_child = self;
|
||||
|
||||
virtio_negotiate_features(vsc, viogpu_feature_names);
|
||||
if (virtio_negotiate_features(vsc, viogpu_feature_names) != 0)
|
||||
goto err;
|
||||
if (!vsc->sc_version_1) {
|
||||
printf(": requires virtio version 1\n");
|
||||
return;
|
||||
goto err;
|
||||
}
|
||||
|
||||
vsc->sc_ipl = IPL_TTY;
|
||||
@ -175,13 +177,13 @@ viogpu_attach(struct device *parent, struct device *self, void *aux)
|
||||
vsc->sc_vqs = sc->sc_vqs;
|
||||
if (virtio_alloc_vq(vsc, &sc->sc_vqs[VQCTRL], VQCTRL, 1, "control")) {
|
||||
printf(": alloc_vq failed\n");
|
||||
return;
|
||||
goto err;
|
||||
}
|
||||
sc->sc_vqs[VQCTRL].vq_done = viogpu_vq_done;
|
||||
|
||||
if (virtio_alloc_vq(vsc, &sc->sc_vqs[VQCURS], VQCURS, 1, "cursor")) {
|
||||
printf(": alloc_vq failed\n");
|
||||
return;
|
||||
goto err;
|
||||
}
|
||||
vsc->sc_nvqs = nitems(sc->sc_vqs);
|
||||
|
||||
@ -191,7 +193,7 @@ viogpu_attach(struct device *parent, struct device *self, void *aux)
|
||||
sc->sc_dma_size, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
|
||||
&sc->sc_dma_map) != 0) {
|
||||
printf(": create failed");
|
||||
goto err;
|
||||
goto errdma;
|
||||
}
|
||||
if (bus_dmamem_alloc(vsc->sc_dmat, sc->sc_dma_size, 16, 0,
|
||||
&sc->sc_dma_seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0) {
|
||||
@ -209,7 +211,8 @@ viogpu_attach(struct device *parent, struct device *self, void *aux)
|
||||
goto unmap;
|
||||
}
|
||||
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
|
||||
if (virtio_attach_finish(vsc, va) != 0)
|
||||
goto unmap;
|
||||
|
||||
if (viogpu_get_display_info(sc) != 0)
|
||||
goto unmap;
|
||||
@ -302,8 +305,10 @@ free:
|
||||
bus_dmamem_free(vsc->sc_dmat, &sc->sc_dma_seg, 1);
|
||||
destroy:
|
||||
bus_dmamap_destroy(vsc->sc_dmat, sc->sc_dma_map);
|
||||
err:
|
||||
errdma:
|
||||
printf(": DMA setup failed\n");
|
||||
err:
|
||||
vsc->sc_child = VIRTIO_CHILD_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: viomb.c,v 1.12 2024/08/27 18:44:12 sf Exp $ */
|
||||
/* $OpenBSD: viomb.c,v 1.13 2024/12/20 22:18:27 sf Exp $ */
|
||||
/* $NetBSD: viomb.c,v 1.1 2011/10/30 12:12:21 hannken Exp $ */
|
||||
|
||||
/*
|
||||
@ -135,6 +135,7 @@ viomb_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct viomb_softc *sc = (struct viomb_softc *)self;
|
||||
struct virtio_softc *vsc = (struct virtio_softc *)parent;
|
||||
struct virtio_attach_args *va = aux;
|
||||
int i;
|
||||
|
||||
if (vsc->sc_child != NULL) {
|
||||
@ -219,8 +220,10 @@ viomb_attach(struct device *parent, struct device *self, void *aux)
|
||||
sensordev_install(&sc->sc_sensdev);
|
||||
|
||||
printf("\n");
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
|
||||
if (virtio_attach_finish(vsc, va) != 0)
|
||||
goto err_dmamap;
|
||||
return;
|
||||
|
||||
err_dmamap:
|
||||
bus_dmamap_destroy(vsc->sc_dmat, sc->sc_req.bl_dmamap);
|
||||
err:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: viornd.c,v 1.11 2024/08/27 18:44:12 sf Exp $ */
|
||||
/* $OpenBSD: viornd.c,v 1.12 2024/12/20 22:18:27 sf Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Stefan Fritsch <sf@sfritsch.de>
|
||||
@ -83,18 +83,19 @@ viornd_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct viornd_softc *sc = (struct viornd_softc *)self;
|
||||
struct virtio_softc *vsc = (struct virtio_softc *)parent;
|
||||
struct virtio_attach_args *va = aux;
|
||||
unsigned int shift;
|
||||
|
||||
vsc->sc_vqs = &sc->sc_vq;
|
||||
vsc->sc_nvqs = 1;
|
||||
vsc->sc_config_change = NULL;
|
||||
if (vsc->sc_child != NULL)
|
||||
panic("already attached to something else");
|
||||
vsc->sc_child = self;
|
||||
vsc->sc_ipl = IPL_NET;
|
||||
sc->sc_virtio = vsc;
|
||||
|
||||
virtio_negotiate_features(vsc, NULL);
|
||||
if (virtio_negotiate_features(vsc, NULL) != 0)
|
||||
goto err;
|
||||
|
||||
if (sc->sc_dev.dv_cfdata->cf_flags & VIORND_ONESHOT) {
|
||||
sc->sc_interval = 0;
|
||||
@ -136,7 +137,8 @@ viornd_attach(struct device *parent, struct device *self, void *aux)
|
||||
timeout_add(&sc->sc_tick, 1);
|
||||
|
||||
printf("\n");
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
|
||||
if (virtio_attach_finish(vsc, va) != 0)
|
||||
goto err2;
|
||||
return;
|
||||
err2:
|
||||
bus_dmamap_destroy(vsc->sc_dmat, sc->sc_dmamap);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: vioscsi.c,v 1.34 2024/08/27 18:44:12 sf Exp $ */
|
||||
/* $OpenBSD: vioscsi.c,v 1.35 2024/12/20 22:18:27 sf Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Google Inc.
|
||||
*
|
||||
@ -105,6 +105,7 @@ vioscsi_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct virtio_softc *vsc = (struct virtio_softc *)parent;
|
||||
struct vioscsi_softc *sc = (struct vioscsi_softc *)self;
|
||||
struct virtio_attach_args *va = aux;
|
||||
struct scsibus_attach_args saa;
|
||||
int i, rv;
|
||||
|
||||
@ -120,7 +121,8 @@ vioscsi_attach(struct device *parent, struct device *self, void *aux)
|
||||
vsc->sc_vqs = sc->sc_vqs;
|
||||
vsc->sc_nvqs = nitems(sc->sc_vqs);
|
||||
|
||||
virtio_negotiate_features(vsc, NULL);
|
||||
if (virtio_negotiate_features(vsc, NULL) != 0)
|
||||
goto err;
|
||||
uint32_t cmd_per_lun = virtio_read_device_config_4(vsc,
|
||||
VIRTIO_SCSI_CONFIG_CMD_PER_LUN);
|
||||
uint32_t seg_max = virtio_read_device_config_4(vsc,
|
||||
@ -166,7 +168,8 @@ vioscsi_attach(struct device *parent, struct device *self, void *aux)
|
||||
saa.saa_quirks = saa.saa_flags = 0;
|
||||
saa.saa_wwpn = saa.saa_wwnn = 0;
|
||||
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
|
||||
if (virtio_attach_finish(vsc, va) != 0)
|
||||
goto err;
|
||||
config_found(self, &saa, scsiprint);
|
||||
return;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: virtio.c,v 1.35 2024/12/03 19:14:40 sf Exp $ */
|
||||
/* $OpenBSD: virtio.c,v 1.36 2024/12/20 22:18:27 sf Exp $ */
|
||||
/* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */
|
||||
|
||||
/*
|
||||
@ -154,6 +154,25 @@ virtio_reset(struct virtio_softc *sc)
|
||||
sc->sc_active_features = 0;
|
||||
}
|
||||
|
||||
int
|
||||
virtio_attach_finish(struct virtio_softc *sc, struct virtio_attach_args *va)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
ret = sc->sc_ops->attach_finish(sc, va);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
sc->sc_ops->setup_intrs(sc);
|
||||
for (i = 0; i < sc->sc_nvqs; i++) {
|
||||
struct virtqueue *vq = &sc->sc_vqs[i];
|
||||
|
||||
virtio_setup_queue(sc, vq, vq->vq_dmamap->dm_segs[0].ds_addr);
|
||||
}
|
||||
virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
virtio_reinit_start(struct virtio_softc *sc)
|
||||
{
|
||||
@ -162,6 +181,7 @@ virtio_reinit_start(struct virtio_softc *sc)
|
||||
virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
|
||||
virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);
|
||||
virtio_negotiate_features(sc, NULL);
|
||||
sc->sc_ops->setup_intrs(sc);
|
||||
for (i = 0; i < sc->sc_nvqs; i++) {
|
||||
int n;
|
||||
struct virtqueue *vq = &sc->sc_vqs[i];
|
||||
@ -175,7 +195,6 @@ virtio_reinit_start(struct virtio_softc *sc)
|
||||
virtio_init_vq(sc, vq);
|
||||
virtio_setup_queue(sc, vq, vq->vq_dmamap->dm_segs[0].ds_addr);
|
||||
}
|
||||
sc->sc_ops->setup_intrs(sc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -421,7 +440,6 @@ virtio_alloc_vq(struct virtio_softc *sc, struct virtqueue *vq, int index,
|
||||
}
|
||||
|
||||
virtio_init_vq(sc, vq);
|
||||
virtio_setup_queue(sc, vq, vq->vq_dmamap->dm_segs[0].ds_addr);
|
||||
|
||||
#if VIRTIO_DEBUG
|
||||
printf("\nallocated %u byte for virtqueue %d for %s, size %d\n",
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: virtiovar.h,v 1.25 2024/12/03 19:14:40 sf Exp $ */
|
||||
/* $OpenBSD: virtiovar.h,v 1.26 2024/12/20 22:18:27 sf Exp $ */
|
||||
/* $NetBSD: virtiovar.h,v 1.1 2011/10/30 12:12:21 hannken Exp $ */
|
||||
|
||||
/*
|
||||
@ -161,6 +161,7 @@ struct virtio_ops {
|
||||
int (*get_status)(struct virtio_softc *);
|
||||
void (*set_status)(struct virtio_softc *, int);
|
||||
int (*neg_features)(struct virtio_softc *, const struct virtio_feature_name *);
|
||||
int (*attach_finish)(struct virtio_softc *, struct virtio_attach_args *);
|
||||
int (*poll_intr)(void *);
|
||||
void (*intr_barrier)(struct virtio_softc *);
|
||||
};
|
||||
@ -220,6 +221,7 @@ virtio_has_feature(struct virtio_softc *sc, uint64_t fbit)
|
||||
int virtio_alloc_vq(struct virtio_softc*, struct virtqueue*, int, int,
|
||||
const char*);
|
||||
int virtio_free_vq(struct virtio_softc*, struct virtqueue*);
|
||||
int virtio_attach_finish(struct virtio_softc *, struct virtio_attach_args *);
|
||||
void virtio_reset(struct virtio_softc *);
|
||||
void virtio_reinit_start(struct virtio_softc *);
|
||||
void virtio_reinit_end(struct virtio_softc *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: vmmci.c,v 1.12 2024/08/26 19:37:54 sf Exp $ */
|
||||
/* $OpenBSD: vmmci.c,v 1.13 2024/12/20 22:18:27 sf Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Reyk Floeter <reyk@openbsd.org>
|
||||
@ -89,6 +89,7 @@ vmmci_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct vmmci_softc *sc = (struct vmmci_softc *)self;
|
||||
struct virtio_softc *vsc = (struct virtio_softc *)parent;
|
||||
struct virtio_attach_args *va = aux;
|
||||
|
||||
if (vsc->sc_child != NULL)
|
||||
panic("already attached to something else");
|
||||
@ -101,7 +102,8 @@ vmmci_attach(struct device *parent, struct device *self, void *aux)
|
||||
|
||||
vsc->sc_driver_features = VMMCI_F_TIMESYNC | VMMCI_F_ACK |
|
||||
VMMCI_F_SYNCRTC;
|
||||
virtio_negotiate_features(vsc, NULL);
|
||||
if (virtio_negotiate_features(vsc, NULL) != 0)
|
||||
goto err;
|
||||
|
||||
if (virtio_has_feature(vsc, VMMCI_F_TIMESYNC)) {
|
||||
strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
|
||||
@ -115,7 +117,12 @@ vmmci_attach(struct device *parent, struct device *self, void *aux)
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
|
||||
if (virtio_attach_finish(vsc, va) != 0)
|
||||
goto err;
|
||||
return;
|
||||
|
||||
err:
|
||||
vsc->sc_child = VIRTIO_CHILD_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
Reference in New Issue
Block a user