From owner-svn-src-head@freebsd.org Tue Nov 14 05:05:18 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 71462D1F3C6; Tue, 14 Nov 2017 05:05:18 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C570D6EF3E; Tue, 14 Nov 2017 05:05:17 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vAE55G86042613; Tue, 14 Nov 2017 05:05:16 GMT (envelope-from imp@FreeBSD.org) Received: (from imp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vAE55Gjl042608; Tue, 14 Nov 2017 05:05:16 GMT (envelope-from imp@FreeBSD.org) Message-Id: <201711140505.vAE55Gjl042608@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: imp set sender to imp@FreeBSD.org using -f From: Warner Losh Date: Tue, 14 Nov 2017 05:05:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r325794 - in head/sys: cam cam/nvme dev/nvme X-SVN-Group: head X-SVN-Commit-Author: imp X-SVN-Commit-Paths: in head/sys: cam cam/nvme dev/nvme X-SVN-Commit-Revision: 325794 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Nov 2017 05:05:18 -0000 Author: imp Date: Tue Nov 14 05:05:16 2017 New Revision: 325794 URL: https://svnweb.freebsd.org/changeset/base/325794 Log: 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. Sponsored by: Netflix Modified: head/sys/cam/cam_ccb.h head/sys/cam/nvme/nvme_all.h head/sys/cam/nvme/nvme_xpt.c head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_sim.c Modified: head/sys/cam/cam_ccb.h ============================================================================== --- head/sys/cam/cam_ccb.h Tue Nov 14 05:05:05 2017 (r325793) +++ head/sys/cam/cam_ccb.h Tue Nov 14 05:05:16 2017 (r325794) @@ -1016,11 +1016,14 @@ 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 */ }; #include Modified: head/sys/cam/nvme/nvme_all.h ============================================================================== --- head/sys/cam/nvme/nvme_all.h Tue Nov 14 05:05:05 2017 (r325793) +++ head/sys/cam/nvme/nvme_all.h Tue Nov 14 05:05:16 2017 (r325794) @@ -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: head/sys/cam/nvme/nvme_xpt.c ============================================================================== --- head/sys/cam/nvme/nvme_xpt.c Tue Nov 14 05:05:05 2017 (r325793) +++ head/sys/cam/nvme/nvme_xpt.c Tue Nov 14 05:05:16 2017 (r325794) @@ -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: head/sys/dev/nvme/nvme.h ============================================================================== --- head/sys/dev/nvme/nvme.h Tue Nov 14 05:05:05 2017 (r325793) +++ head/sys/dev/nvme/nvme.h Tue Nov 14 05:05:16 2017 (r325794) @@ -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: head/sys/dev/nvme/nvme_sim.c ============================================================================== --- head/sys/dev/nvme/nvme_sim.c Tue Nov 14 05:05:05 2017 (r325793) +++ head/sys/dev/nvme/nvme_sim.c Tue Nov 14 05:05:16 2017 (r325794) @@ -44,6 +44,9 @@ __FBSDID("$FreeBSD$"); #include // Yes, this is wrong. #include +#include +#include + #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; - 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;