diff options
| author | Warner Losh <imp@FreeBSD.org> | 2017-11-14 05:05:16 +0000 |
|---|---|---|
| committer | Warner Losh <imp@FreeBSD.org> | 2017-11-14 05:05:16 +0000 |
| commit | 4e3b274457f7dd43f8f9b6d7a36a8c4d18624859 (patch) | |
| tree | a37b7a1e81df9ab1bf0b0ad7b682b49e07fdf128 /sys/dev/nvme/nvme_sim.c | |
| parent | d505913c91e23bf1e7c2d4cd40e7ccec5e6967e8 (diff) | |
Notes
Diffstat (limited to 'sys/dev/nvme/nvme_sim.c')
| -rw-r--r-- | sys/dev/nvme/nvme_sim.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c index 94169055919c1..87532f9d9ab7e 100644 --- a/sys/dev/nvme/nvme_sim.c +++ b/sys/dev/nvme/nvme_sim.c @@ -44,6 +44,9 @@ __FBSDID("$FreeBSD$"); #include <cam/cam_xpt_internal.h> // Yes, this is wrong. #include <cam/cam_debug.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> + #include "nvme_private.h" #define ccb_accb_ptr spriv_ptr0 @@ -122,6 +125,22 @@ nvme_sim_nvmeio(struct cam_sim *sim, union ccb *ccb) ccb->ccb_h.status |= CAM_SIM_QUEUED; } +static uint32_t +nvme_link_kBps(struct nvme_controller *ctrlr) +{ + uint32_t speed, lanes, link[] = { 1, 250000, 500000, 985000, 1970000 }; + + speed = pcie_link_status(ctrlr->dev) & PCIEM_LINK_STA_SPEED; + lanes = (pcie_link_status(ctrlr->dev) & PCIEM_LINK_STA_WIDTH) >> 4; + /* + * Failsafe on link speed indicator. If it is insane report the number of + * lanes as the speed. Not 100% accurate, but may be diagnostic. + */ + if (speed >= nitems(link)) + speed = 0; + return link[speed] * lanes; +} + static void nvme_sim_action(struct cam_sim *sim, union ccb *ccb) { @@ -179,15 +198,15 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb) cpi->maxio = nvme_ns_get_max_io_xfer_size(ns); cpi->initiator_id = 0; cpi->bus_id = cam_sim_bus(sim); - cpi->base_transfer_speed = 4000000; /* 4 GB/s 4 lanes pcie 3 */ + cpi->base_transfer_speed = nvme_link_kBps(ctrlr); strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); strlcpy(cpi->hba_vid, "NVMe", HBA_IDLEN); strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); cpi->transport = XPORT_NVME; /* XXX XPORT_PCIE ? */ - cpi->transport_version = 1; /* XXX Get PCIe spec ? */ + cpi->transport_version = nvme_mmio_read_4(ctrlr, vs); cpi->protocol = PROTO_NVME; - cpi->protocol_version = NVME_REV_1; /* Groks all 1.x NVMe cards */ + cpi->protocol_version = nvme_mmio_read_4(ctrlr, vs); cpi->xport_specific.nvme.nsid = ns->id; cpi->ccb_h.status = CAM_REQ_CMP; break; @@ -197,20 +216,24 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb) struct ccb_trans_settings *cts; struct ccb_trans_settings_nvme *nvmep; struct ccb_trans_settings_nvme *nvmex; + device_t dev; + dev = ctrlr->dev; cts = &ccb->cts; nvmex = &cts->xport_specific.nvme; nvmep = &cts->proto_specific.nvme; - nvmex->valid = CTS_NVME_VALID_SPEC; - nvmex->spec_major = 1; /* XXX read from card */ - nvmex->spec_minor = 2; - nvmex->spec_tiny = 0; + nvmex->valid = CTS_NVME_VALID_SPEC | CTS_NVME_VALID_LINK; + nvmex->spec = nvme_mmio_read_4(ctrlr, vs); + nvmex->speed = pcie_link_status(dev) & PCIEM_LINK_STA_SPEED; + nvmex->lanes = (pcie_link_status(dev) & PCIEM_LINK_STA_WIDTH) >> 4; + nvmex->max_speed = pcie_link_caps(dev) & PCIEM_LINK_CAP_MAX_SPEED; + nvmex->max_lanes = (pcie_link_caps(dev) & PCIEM_LINK_CAP_MAX_WIDTH) >> 4; + + /* XXX these should be something else maybe ? */ + nvmep->valid = 1; + nvmep->spec = nvmex->spec; - nvmep->valid = CTS_NVME_VALID_SPEC; - nvmep->spec_major = 1; /* XXX read from card */ - nvmep->spec_minor = 2; - nvmep->spec_tiny = 0; cts->transport = XPORT_NVME; cts->protocol = PROTO_NVME; cts->ccb_h.status = CAM_REQ_CMP; |
