svn commit: r335166 - in stable/11/sys: cam cam/nvme dev/nvme
Alexander Motin
mav at FreeBSD.org
Thu Jun 14 18:18:56 UTC 2018
Author: mav
Date: Thu Jun 14 18:18:55 2018
New Revision: 335166
URL: https://svnweb.freebsd.org/changeset/base/335166
Log:
MFC r325794, r325838 (by imp):
Provide link speed data in XPT_GET_TRAN_SETTINGS. Provide full version
information for that and XPT_PATH_INQ. Provide macros to encode/decode
major/minor versions. Read the link speed and lane count to compute
the base_transfer_speed for XPT_PATH_INQ.
Modified:
stable/11/sys/cam/cam_ccb.h
stable/11/sys/cam/nvme/nvme_all.h
stable/11/sys/cam/nvme/nvme_xpt.c
stable/11/sys/dev/nvme/nvme.h
stable/11/sys/dev/nvme/nvme_sim.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/cam/cam_ccb.h
==============================================================================
--- stable/11/sys/cam/cam_ccb.h Thu Jun 14 17:50:29 2018 (r335165)
+++ stable/11/sys/cam/cam_ccb.h Thu Jun 14 18:18:55 2018 (r335166)
@@ -1003,11 +1003,15 @@ struct ccb_trans_settings_nvme
u_int valid; /* Which fields to honor */
#define CTS_NVME_VALID_SPEC 0x01
#define CTS_NVME_VALID_CAPS 0x02
- u_int spec_major; /* Major version of spec supported */
- u_int spec_minor; /* Minor verison of spec supported */
- u_int spec_tiny; /* Tiny version of spec supported */
- u_int max_xfer; /* Max transfer size (0 -> unlimited */
- u_int caps;
+#define CTS_NVME_VALID_LINK 0x04
+ uint32_t spec; /* NVMe spec implemented -- same as vs register */
+ uint32_t max_xfer; /* Max transfer size (0 -> unlimited */
+ uint32_t caps;
+ uint8_t lanes; /* Number of PCIe lanes */
+ uint8_t speed; /* PCIe generation for each lane */
+ uint8_t max_lanes; /* Number of PCIe lanes */
+ uint8_t max_speed; /* PCIe generation for each lane */
+ u_int pad; /* Padding to keep ABI */
};
/* Get/Set transfer rate/width/disconnection/tag queueing settings */
Modified: stable/11/sys/cam/nvme/nvme_all.h
==============================================================================
--- stable/11/sys/cam/nvme/nvme_all.h Thu Jun 14 17:50:29 2018 (r335165)
+++ stable/11/sys/cam/nvme/nvme_all.h Thu Jun 14 18:18:55 2018 (r335166)
@@ -33,8 +33,6 @@
struct ccb_nvmeio;
-#define NVME_REV_1 1 /* Supports NVMe 1.2 or earlier */
-
void nvme_ns_cmd(struct ccb_nvmeio *nvmeio, uint8_t cmd, uint32_t nsid,
uint32_t cdw10, uint32_t cdw11, uint32_t cdw12, uint32_t cdw13,
uint32_t cdw14, uint32_t cdw15);
Modified: stable/11/sys/cam/nvme/nvme_xpt.c
==============================================================================
--- stable/11/sys/cam/nvme/nvme_xpt.c Thu Jun 14 17:50:29 2018 (r335165)
+++ stable/11/sys/cam/nvme/nvme_xpt.c Thu Jun 14 18:18:55 2018 (r335166)
@@ -639,12 +639,14 @@ nvme_announce_periph(struct cam_periph *periph)
static void
nvme_proto_announce(struct cam_ed *device)
{
+
nvme_print_ident(device->nvme_cdata, device->nvme_data);
}
static void
nvme_proto_denounce(struct cam_ed *device)
{
+
nvme_print_ident(device->nvme_cdata, device->nvme_data);
}
Modified: stable/11/sys/dev/nvme/nvme.h
==============================================================================
--- stable/11/sys/dev/nvme/nvme.h Thu Jun 14 17:50:29 2018 (r335165)
+++ stable/11/sys/dev/nvme/nvme.h Thu Jun 14 18:18:55 2018 (r335166)
@@ -42,6 +42,13 @@
#define NVME_BIO_TEST _IOWR('n', 101, struct nvme_io_test)
/*
+ * Macros to deal with NVME revisions, as defined VS register
+ */
+#define NVME_REV(x, y) (((x) << 16) | ((y) << 8))
+#define NVME_MAJOR(r) (((r) >> 16) & 0xffff)
+#define NVME_MINOR(r) (((r) >> 8) & 0xff)
+
+/*
* Use to mark a command to apply to all namespaces, or to retrieve global
* log pages.
*/
Modified: stable/11/sys/dev/nvme/nvme_sim.c
==============================================================================
--- stable/11/sys/dev/nvme/nvme_sim.c Thu Jun 14 17:50:29 2018 (r335165)
+++ stable/11/sys/dev/nvme/nvme_sim.c Thu Jun 14 18:18:55 2018 (r335166)
@@ -125,6 +125,24 @@ nvme_sim_nvmeio(struct cam_sim *sim, union ccb *ccb)
nvme_ctrlr_submit_admin_request(ctrlr, req);
}
+static uint32_t
+nvme_link_kBps(struct nvme_controller *ctrlr)
+{
+ uint32_t speed, lanes, link[] = { 1, 250000, 500000, 985000, 1970000 };
+ uint32_t status;
+
+ status = pcie_read_config(ctrlr->dev, PCIER_LINK_STA, 2);
+ speed = status & PCIEM_LINK_STA_SPEED;
+ lanes = (status & 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)
{
@@ -183,15 +201,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);
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
strncpy(cpi->hba_vid, "NVMe", HBA_IDLEN);
strncpy(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->xport_specific.nvme.domain = pci_get_domain(dev);
cpi->xport_specific.nvme.bus = pci_get_bus(dev);
@@ -206,20 +224,27 @@ 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;
+ uint32_t status, caps;
+ 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;
+ status = pcie_read_config(dev, PCIER_LINK_STA, 2);
+ caps = pcie_read_config(dev, PCIER_LINK_CAP, 2);
+ nvmex->valid = CTS_NVME_VALID_SPEC | CTS_NVME_VALID_LINK;
+ nvmex->spec = nvme_mmio_read_4(ctrlr, vs);
+ nvmex->speed = status & PCIEM_LINK_STA_SPEED;
+ nvmex->lanes = (status & PCIEM_LINK_STA_WIDTH) >> 4;
+ nvmex->max_speed = caps & PCIEM_LINK_CAP_MAX_SPEED;
+ nvmex->max_lanes = (caps & PCIEM_LINK_CAP_MAX_WIDTH) >> 4;
- nvmep->valid = CTS_NVME_VALID_SPEC;
- nvmep->spec_major = 1; /* XXX read from card */
- nvmep->spec_minor = 2;
- nvmep->spec_tiny = 0;
+ /* XXX these should be something else maybe ? */
+ nvmep->valid = 1;
+ nvmep->spec = nvmex->spec;
+
cts->transport = XPORT_NVME;
cts->protocol = PROTO_NVME;
cts->ccb_h.status = CAM_REQ_CMP;
More information about the svn-src-all
mailing list