Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_virtio_scsi.c
Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
#include <cam/ctl/ctl_io.h> | #include <cam/ctl/ctl_io.h> | ||||
#include <cam/ctl/ctl_backend.h> | #include <cam/ctl/ctl_backend.h> | ||||
#include <cam/ctl/ctl_ioctl.h> | #include <cam/ctl/ctl_ioctl.h> | ||||
#include <cam/ctl/ctl_util.h> | #include <cam/ctl/ctl_util.h> | ||||
#include <cam/ctl/ctl_scsi_all.h> | #include <cam/ctl/ctl_scsi_all.h> | ||||
#include <camlib.h> | #include <camlib.h> | ||||
#include "bhyverun.h" | #include "bhyverun.h" | ||||
#include "config.h" | |||||
#include "debug.h" | #include "debug.h" | ||||
#include "pci_emul.h" | #include "pci_emul.h" | ||||
#include "virtio.h" | #include "virtio.h" | ||||
#include "iov.h" | #include "iov.h" | ||||
#define VTSCSI_RINGSZ 64 | #define VTSCSI_RINGSZ 64 | ||||
#define VTSCSI_REQUESTQ 1 | #define VTSCSI_REQUESTQ 1 | ||||
#define VTSCSI_THR_PER_Q 16 | #define VTSCSI_THR_PER_Q 16 | ||||
▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | static int pci_vtscsi_an_handle(struct pci_vtscsi_softc *, | ||||
struct pci_vtscsi_ctrl_an *); | struct pci_vtscsi_ctrl_an *); | ||||
static int pci_vtscsi_request_handle(struct pci_vtscsi_queue *, struct iovec *, | static int pci_vtscsi_request_handle(struct pci_vtscsi_queue *, struct iovec *, | ||||
int, struct iovec *, int); | int, struct iovec *, int); | ||||
static void pci_vtscsi_controlq_notify(void *, struct vqueue_info *); | static void pci_vtscsi_controlq_notify(void *, struct vqueue_info *); | ||||
static void pci_vtscsi_eventq_notify(void *, struct vqueue_info *); | static void pci_vtscsi_eventq_notify(void *, struct vqueue_info *); | ||||
static void pci_vtscsi_requestq_notify(void *, struct vqueue_info *); | static void pci_vtscsi_requestq_notify(void *, struct vqueue_info *); | ||||
static int pci_vtscsi_init_queue(struct pci_vtscsi_softc *, | static int pci_vtscsi_init_queue(struct pci_vtscsi_softc *, | ||||
struct pci_vtscsi_queue *, int); | struct pci_vtscsi_queue *, int); | ||||
static int pci_vtscsi_init(struct vmctx *, struct pci_devinst *, char *); | static int pci_vtscsi_init(struct vmctx *, struct pci_devinst *, nvlist_t *); | ||||
static struct virtio_consts vtscsi_vi_consts = { | static struct virtio_consts vtscsi_vi_consts = { | ||||
"vtscsi", /* our name */ | "vtscsi", /* our name */ | ||||
VTSCSI_MAXQ, /* we support 2+n virtqueues */ | VTSCSI_MAXQ, /* we support 2+n virtqueues */ | ||||
sizeof(struct pci_vtscsi_config), /* config reg size */ | sizeof(struct pci_vtscsi_config), /* config reg size */ | ||||
pci_vtscsi_reset, /* reset */ | pci_vtscsi_reset, /* reset */ | ||||
NULL, /* device-wide qnotify */ | NULL, /* device-wide qnotify */ | ||||
pci_vtscsi_cfgread, /* read virtio config */ | pci_vtscsi_cfgread, /* read virtio config */ | ||||
▲ Show 20 Lines • Show All 404 Lines • ▼ Show 20 Lines | for (i = 0; i < VTSCSI_THR_PER_Q; i++) { | ||||
pthread_set_name_np(worker->vsw_thread, tname); | pthread_set_name_np(worker->vsw_thread, tname); | ||||
LIST_INSERT_HEAD(&queue->vsq_workers, worker, vsw_link); | LIST_INSERT_HEAD(&queue->vsq_workers, worker, vsw_link); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
pci_vtscsi_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | pci_vtscsi_legacy_config(nvlist_t *nvl, const char *opts) | ||||
{ | { | ||||
struct pci_vtscsi_softc *sc; | char *cp, *devname; | ||||
char *opt, *optname; | |||||
const char *devname; | |||||
int i, optidx = 0; | |||||
sc = calloc(1, sizeof(struct pci_vtscsi_softc)); | cp = strchr(opts, ','); | ||||
devname = "/dev/cam/ctl"; | if (cp == NULL) { | ||||
while ((opt = strsep(&opts, ",")) != NULL) { | set_config_value_node(nvl, "dev", opts); | ||||
optname = strsep(&opt, "="); | return (0); | ||||
if (opt == NULL && optidx == 0) { | |||||
if (optname[0] != 0) | |||||
devname = optname; | |||||
} else if (strcmp(optname, "dev") == 0 && opt != NULL) { | |||||
devname = opt; | |||||
} else if (strcmp(optname, "iid") == 0 && opt != NULL) { | |||||
sc->vss_iid = strtoul(opt, NULL, 10); | |||||
} else { | |||||
EPRINTLN("Invalid option %s", optname); | |||||
free(sc); | |||||
return (1); | |||||
} | } | ||||
optidx++; | devname = strndup(opts, cp - opts); | ||||
set_config_value_node(nvl, "dev", devname); | |||||
free(devname); | |||||
return (pci_parse_legacy_config(nvl, cp + 1)); | |||||
} | } | ||||
static int | |||||
pci_vtscsi_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | |||||
{ | |||||
struct pci_vtscsi_softc *sc; | |||||
const char *devname, *value;; | |||||
int i; | |||||
sc = calloc(1, sizeof(struct pci_vtscsi_softc)); | |||||
value = get_config_value_node(nvl, "iid"); | |||||
if (value != NULL) | |||||
sc->vss_iid = strtoul(value, NULL, 10); | |||||
devname = get_config_value_node(nvl, "dev"); | |||||
if (devname == NULL) | |||||
devname = "/dev/cam/ctl"; | |||||
sc->vss_ctl_fd = open(devname, O_RDWR); | sc->vss_ctl_fd = open(devname, O_RDWR); | ||||
if (sc->vss_ctl_fd < 0) { | if (sc->vss_ctl_fd < 0) { | ||||
WPRINTF(("cannot open %s: %s", devname, strerror(errno))); | WPRINTF(("cannot open %s: %s", devname, strerror(errno))); | ||||
free(sc); | free(sc); | ||||
return (1); | return (1); | ||||
} | } | ||||
vi_softc_linkup(&sc->vss_vs, &vtscsi_vi_consts, sc, pi, sc->vss_vq); | vi_softc_linkup(&sc->vss_vs, &vtscsi_vi_consts, sc, pi, sc->vss_vq); | ||||
Show All 39 Lines |