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 | |||||