Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_virtio_block.c
Show First 20 Lines • Show All 210 Lines • ▼ Show 20 Lines | 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 (legacy) */ | ||||
VTBLK_S_HOSTCAPS, /* our capabilities (modern) */ | |||||
true, /* Enable legacy */ | |||||
true, /* Enable modern */ | |||||
2, /* PCI BAR# for modern */ | |||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
pci_vtblk_pause, /* pause blockif threads */ | pci_vtblk_pause, /* pause blockif threads */ | ||||
pci_vtblk_resume, /* resume blockif threads */ | pci_vtblk_resume, /* resume blockif threads */ | ||||
pci_vtblk_snapshot, /* save / restore device state */ | pci_vtblk_snapshot, /* save / restore device state */ | ||||
#endif | #endif | ||||
}; | }; | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 252 Lines • ▼ Show 20 Lines | for (i = 0; i < VTBLK_RINGSZ; i++) { | ||||
struct pci_vtblk_ioreq *io = &sc->vbsc_ios[i]; | struct pci_vtblk_ioreq *io = &sc->vbsc_ios[i]; | ||||
io->io_req.br_callback = pci_vtblk_done; | io->io_req.br_callback = pci_vtblk_done; | ||||
io->io_req.br_param = io; | io->io_req.br_param = io; | ||||
io->io_sc = sc; | io->io_sc = sc; | ||||
io->io_idx = i; | io->io_idx = i; | ||||
} | } | ||||
bcopy(&vtblk_vi_consts, &sc->vbsc_consts, sizeof (vtblk_vi_consts)); | bcopy(&vtblk_vi_consts, &sc->vbsc_consts, sizeof (vtblk_vi_consts)); | ||||
if (blockif_candelete(sc->bc)) | if (blockif_candelete(sc->bc)) { | ||||
sc->vbsc_consts.vc_hv_caps |= VTBLK_F_DISCARD; | sc->vbsc_consts.vc_hv_caps_legacy |= VTBLK_F_DISCARD; | ||||
sc->vbsc_consts.vc_hv_caps_modern |= VTBLK_F_DISCARD; | |||||
} | |||||
pthread_mutex_init(&sc->vsc_mtx, NULL); | pthread_mutex_init(&sc->vsc_mtx, NULL); | ||||
/* init virtio softc and virtqueues */ | /* init virtio softc and virtqueues */ | ||||
vi_softc_linkup(&sc->vbsc_vs, &sc->vbsc_consts, sc, pi, &sc->vbsc_vq); | vi_softc_linkup(&sc->vbsc_vs, &sc->vbsc_consts, sc, pi, &sc->vbsc_vq); | ||||
sc->vbsc_vs.vs_mtx = &sc->vsc_mtx; | sc->vbsc_vs.vs_mtx = &sc->vsc_mtx; | ||||
sc->vbsc_vq.vq_qsize = VTBLK_RINGSZ; | sc->vbsc_vq.vq_qsize = VTBLK_RINGSZ; | ||||
Show All 38 Lines | pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | ||||
sc->vbsc_cfg.max_discard_seg = VTBLK_MAX_DISCARD_SEG; | sc->vbsc_cfg.max_discard_seg = VTBLK_MAX_DISCARD_SEG; | ||||
sc->vbsc_cfg.discard_sector_alignment = MAX(sectsz, sts) / VTBLK_BSIZE; | sc->vbsc_cfg.discard_sector_alignment = MAX(sectsz, sts) / VTBLK_BSIZE; | ||||
/* | /* | ||||
* Should we move some of this into virtio.c? Could | * Should we move some of this into virtio.c? Could | ||||
* have the device, class, and subdev_0 as fields in | * have the device, class, and subdev_0 as fields in | ||||
* the virtio constants structure. | * the virtio constants structure. | ||||
*/ | */ | ||||
pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_BLOCK); | pci_set_cfgdata16(pi, PCIR_DEVICE, sc->vbsc_consts.vc_en_legacy ? | ||||
VIRTIO_DEV_BLOCK : vi_get_modern_pci_devid(VIRTIO_ID_BLOCK)); | |||||
pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); | pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); | ||||
pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE); | pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE); | ||||
pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_ID_BLOCK); | pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_ID_BLOCK); | ||||
pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); | pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); | ||||
if (vi_intr_init(&sc->vbsc_vs, 1, fbsdrun_virtio_msix())) { | if (vi_intr_init(&sc->vbsc_vs, 1, fbsdrun_virtio_msix())) { | ||||
blockif_close(sc->bc); | blockif_close(sc->bc); | ||||
free(sc); | free(sc); | ||||
return (1); | return (1); | ||||
} | } | ||||
vi_set_io_bar(&sc->vbsc_vs, 0); | vi_setup_pci_bar(&sc->vbsc_vs); | ||||
blockif_register_resize_callback(sc->bc, pci_vtblk_resized, sc); | blockif_register_resize_callback(sc->bc, pci_vtblk_resized, sc); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
pci_vtblk_cfgwrite(void *vsc, int offset, int size, uint32_t value) | pci_vtblk_cfgwrite(void *vsc, int offset, int size, uint32_t value) | ||||
{ | { | ||||
Show All 12 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_legacy_config = blockif_legacy_config, | .pe_legacy_config = blockif_legacy_config, | ||||
.pe_cfgwrite = vi_pci_cfgwrite, | |||||
.pe_cfgread = vi_pci_cfgread, | |||||
.pe_barwrite = vi_pci_write, | .pe_barwrite = vi_pci_write, | ||||
.pe_barread = vi_pci_read, | .pe_barread = vi_pci_read, | ||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
.pe_snapshot = vi_pci_snapshot, | .pe_snapshot = vi_pci_snapshot, | ||||
#endif | #endif | ||||
}; | }; | ||||
PCI_EMUL_SET(pci_de_vblk); | PCI_EMUL_SET(pci_de_vblk); |