git: f102ae715949 - stable/13 - nvme_sim: Only report PCI related stats when we can

From: Alexander Motin <mav_at_FreeBSD.org>
Date: Fri, 21 Jan 2022 02:27:08 UTC
The branch stable/13 has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=f102ae715949b99e3b9ac296517005e440adf713

commit f102ae715949b99e3b9ac296517005e440adf713
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2021-12-06 17:23:23 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2022-01-21 02:07:31 +0000

    nvme_sim: Only report PCI related stats when we can
    
    For AHCI attached devices, we report the location and identification
    information of the AHCI controller that we're attached to. We also
    don't reprot link speed in that case, since we can't get to the PCIe
    config space registers to find that out.
    
    Sponsored by:           Netflix
    Reviewed by:            mav
    Differential Revision:  https://reviews.freebsd.org/D33287
    
    (cherry picked from commit 8f07932272c4b34804bc575c4f8bffecd15cd4ef)
---
 sys/dev/nvme/nvme_sim.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c
index 06e645ebdf90..9a191d3042be 100644
--- a/sys/dev/nvme/nvme_sim.c
+++ b/sys/dev/nvme/nvme_sim.c
@@ -172,6 +172,13 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb)
 		struct ccb_pathinq	*cpi = &ccb->cpi;
 		device_t		dev = ctrlr->dev;
 
+		/*
+		 * For devices that are reported as children of the AHCI
+		 * controller, which has no access to the config space for this
+		 * controller, report the AHCI controller's data.
+		 */
+		if (ctrlr->quirks & QUIRK_AHCI)
+			dev = device_get_parent(dev);
 		cpi->version_num = 1;
 		cpi->hba_inquiry = 0;
 		cpi->target_sprt = 0;
@@ -219,17 +226,20 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb)
 		nvmex = &cts->xport_specific.nvme;
 		nvmep = &cts->proto_specific.nvme;
 
-		status = pcie_read_config(dev, PCIER_LINK_STA, 2);
-		caps = pcie_read_config(dev, PCIER_LINK_CAP, 2);
-		flags = pcie_read_config(dev, PCIER_FLAGS, 2);
 		nvmex->spec = nvme_mmio_read_4(ctrlr, vs);
 		nvmex->valid = CTS_NVME_VALID_SPEC;
-		if ((flags & PCIEM_FLAGS_TYPE) == PCIEM_TYPE_ENDPOINT) {
-			nvmex->valid |= CTS_NVME_VALID_LINK;
-			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;
+		if ((ctrlr->quirks & QUIRK_AHCI) == 0) {
+			/* AHCI redirect makes it impossible to query */
+			status = pcie_read_config(dev, PCIER_LINK_STA, 2);
+			caps = pcie_read_config(dev, PCIER_LINK_CAP, 2);
+			flags = pcie_read_config(dev, PCIER_FLAGS, 2);
+			if ((flags & PCIEM_FLAGS_TYPE) == PCIEM_TYPE_ENDPOINT) {
+				nvmex->valid |= CTS_NVME_VALID_LINK;
+				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;
+			}
 		}
 
 		/* XXX these should be something else maybe ? */