Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_virtio_block.c
Show All 33 Lines | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/linker_set.h> | #include <sys/linker_set.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||
#include <sys/disk.h> | #include <sys/disk.h> | ||||
#include <machine/vmm_snapshot.h> | |||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <strings.h> | #include <strings.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | struct pci_vtblk_softc { | ||||
char vbsc_ident[VTBLK_BLK_ID_BYTES]; | char vbsc_ident[VTBLK_BLK_ID_BYTES]; | ||||
struct pci_vtblk_ioreq vbsc_ios[VTBLK_RINGSZ]; | struct pci_vtblk_ioreq vbsc_ios[VTBLK_RINGSZ]; | ||||
}; | }; | ||||
static void pci_vtblk_reset(void *); | static void pci_vtblk_reset(void *); | ||||
static void pci_vtblk_notify(void *, struct vqueue_info *); | static void pci_vtblk_notify(void *, struct vqueue_info *); | ||||
static int pci_vtblk_cfgread(void *, int, int, uint32_t *); | static int pci_vtblk_cfgread(void *, int, int, uint32_t *); | ||||
static int pci_vtblk_cfgwrite(void *, int, int, uint32_t); | static int pci_vtblk_cfgwrite(void *, int, int, uint32_t); | ||||
#ifdef BHYVE_SNAPSHOT | |||||
static void pci_vtblk_pause(void *); | |||||
static void pci_vtblk_resume(void *); | |||||
static int pci_vtblk_snapshot(void *, struct vm_snapshot_meta *); | |||||
#endif | |||||
static struct virtio_consts vtblk_vi_consts = { | static struct virtio_consts vtblk_vi_consts = { | ||||
"vtblk", /* our name */ | "vtblk", /* our name */ | ||||
1, /* we support 1 virtqueue */ | 1, /* we support 1 virtqueue */ | ||||
sizeof(struct vtblk_config), /* config reg size */ | sizeof(struct vtblk_config), /* config reg size */ | ||||
pci_vtblk_reset, /* reset */ | pci_vtblk_reset, /* reset */ | ||||
pci_vtblk_notify, /* device-wide qnotify */ | pci_vtblk_notify, /* device-wide qnotify */ | ||||
pci_vtblk_cfgread, /* read PCI config */ | pci_vtblk_cfgread, /* read PCI config */ | ||||
pci_vtblk_cfgwrite, /* write PCI config */ | pci_vtblk_cfgwrite, /* write PCI config */ | ||||
NULL, /* apply negotiated features */ | NULL, /* apply negotiated features */ | ||||
VTBLK_S_HOSTCAPS, /* our capabilities */ | VTBLK_S_HOSTCAPS, /* our capabilities */ | ||||
#ifdef BHYVE_SNAPSHOT | |||||
pci_vtblk_pause, /* pause blockif threads */ | |||||
pci_vtblk_resume, /* resume blockif threads */ | |||||
pci_vtblk_snapshot, /* save / restore device state */ | |||||
#endif | |||||
}; | }; | ||||
static void | static void | ||||
pci_vtblk_reset(void *vsc) | pci_vtblk_reset(void *vsc) | ||||
{ | { | ||||
struct pci_vtblk_softc *sc = vsc; | struct pci_vtblk_softc *sc = vsc; | ||||
DPRINTF(("vtblk: device reset requested !")); | DPRINTF(("vtblk: device reset requested !")); | ||||
vi_reset_dev(&sc->vbsc_vs); | vi_reset_dev(&sc->vbsc_vs); | ||||
} | } | ||||
#ifdef BHYVE_SNAPSHOT | |||||
static void | static void | ||||
pci_vtblk_pause(void *vsc) | |||||
{ | |||||
struct pci_vtblk_softc *sc = vsc; | |||||
DPRINTF(("vtblk: device pause requested !\n")); | |||||
blockif_pause(sc->bc); | |||||
} | |||||
static void | |||||
pci_vtblk_resume(void *vsc) | |||||
{ | |||||
struct pci_vtblk_softc *sc = vsc; | |||||
DPRINTF(("vtblk: device resume requested !\n")); | |||||
blockif_resume(sc->bc); | |||||
} | |||||
static int | |||||
pci_vtblk_snapshot(void *vsc, struct vm_snapshot_meta *meta) | |||||
{ | |||||
int ret; | |||||
struct pci_vtblk_softc *sc = vsc; | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->vbsc_cfg, meta, ret, done); | |||||
SNAPSHOT_BUF_OR_LEAVE(sc->vbsc_ident, sizeof(sc->vbsc_ident), | |||||
meta, ret, done); | |||||
done: | |||||
return (ret); | |||||
} | |||||
#endif | |||||
static void | |||||
pci_vtblk_done(struct blockif_req *br, int err) | pci_vtblk_done(struct blockif_req *br, int err) | ||||
{ | { | ||||
struct pci_vtblk_ioreq *io = br->br_param; | struct pci_vtblk_ioreq *io = br->br_param; | ||||
struct pci_vtblk_softc *sc = io->io_sc; | struct pci_vtblk_softc *sc = io->io_sc; | ||||
/* convert errno into a virtio block error return */ | /* convert errno into a virtio block error return */ | ||||
if (err == EOPNOTSUPP || err == ENOSYS) | if (err == EOPNOTSUPP || err == ENOSYS) | ||||
*io->io_status = VTBLK_S_UNSUPP; | *io->io_status = VTBLK_S_UNSUPP; | ||||
▲ Show 20 Lines • Show All 230 Lines • ▼ Show 20 Lines | pci_vtblk_cfgread(void *vsc, int offset, int size, uint32_t *retval) | ||||
memcpy(retval, ptr, size); | memcpy(retval, ptr, size); | ||||
return (0); | return (0); | ||||
} | } | ||||
struct pci_devemu pci_de_vblk = { | struct pci_devemu pci_de_vblk = { | ||||
.pe_emu = "virtio-blk", | .pe_emu = "virtio-blk", | ||||
.pe_init = pci_vtblk_init, | .pe_init = pci_vtblk_init, | ||||
.pe_barwrite = vi_pci_write, | .pe_barwrite = vi_pci_write, | ||||
.pe_barread = vi_pci_read | .pe_barread = vi_pci_read, | ||||
#ifdef BHYVE_SNAPSHOT | |||||
.pe_snapshot = vi_pci_snapshot, | |||||
#endif | |||||
}; | }; | ||||
PCI_EMUL_SET(pci_de_vblk); | PCI_EMUL_SET(pci_de_vblk); |