From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
To: linux-pci@vger.kernel.org
Cc: "Mariusz Tkaczyk" <mariusz.tkaczyk@linux.intel.com>,
"Lukas Wunner" <lukas@wunner.de>,
"Christoph Hellwig" <hch@lst.de>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Stuart Hayes" <stuart.w.hayes@gmail.com>,
"Arnd Bergmann" <arnd@arndb.de>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Dan Williams" <dan.j.williams@intel.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Keith Busch" <kbusch@kernel.org>,
"Marek Behun" <marek.behun@nic.cz>, "Pavel Machek" <pavel@ucw.cz>,
"Randy Dunlap" <rdunlap@infradead.org>,
"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>
Subject: [PATCH v4 3/3] PCI/NPEM: Add _DSM PCIe SSD status LED management
Date: Thu, 11 Jul 2024 10:30:09 +0200 [thread overview]
Message-ID: <20240711083009.5580-4-mariusz.tkaczyk@linux.intel.com> (raw)
In-Reply-To: <20240711083009.5580-1-mariusz.tkaczyk@linux.intel.com>
Device Specific Method PCIe SSD Status LED Management (_DSM) defined in
PCI Firmware Spec r3.3 sec 4.7 provides a way to manage LEDs via ACPI.
The design is similar to NPEM defined in PCIe Base Specification r6.1
sec 6.28:
- both standards are indication oriented,
- _DSM supported bits are corresponding to NPEM capability
register bits
- _DSM control bits are corresponding to NPEM control register
bits.
_DSM does not support enclosure specific indications and special NPEM
commands NPEM_ENABLE and NPEM_RESET.
_DSM is implemented as a second op in NPEM driver. The standard used
in background is not presented to user. The interface is accessed same
as NPEM.
According to spec, _DSM has higher priority and availability of _DSM
in not limited to devices with NPEM support. It is followed in
implementation.
Link: https://members.pcisig.com/wg/PCI-SIG/document/14025
Link: https://members.pcisig.com/wg/PCI-SIG/document/15350
Suggested-by: Lukas Wunner <lukas@wunner.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Tested-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
drivers/pci/npem.c | 147 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 144 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/npem.c b/drivers/pci/npem.c
index 3aa0b6e94cbd..fb427e68d107 100644
--- a/drivers/pci/npem.c
+++ b/drivers/pci/npem.c
@@ -11,6 +11,14 @@
* PCIe Base Specification r6.1 sec 6.28
* PCIe Base Specification r6.1 sec 7.9.19
*
+ * _DSM Definitions for PCIe SSD Status LED
+ * PCI Firmware Specification, r3.3 sec 4.7
+ *
+ * Two backends are supported to manipulate indications: Direct NPEM register
+ * access (npem_ops) and indirect access through the ACPI _DSM (dsm_ops).
+ * _DSM is used if supported, else NPEM.
+ *
+ * Copyright (c) 2021-2022 Dell Inc.
* Copyright (c) 2023-2024 Intel Corporation
* Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
*/
@@ -55,6 +63,21 @@ static const struct indication npem_indications[] = {
{0, NULL}
};
+/* _DSM PCIe SSD LED States are corresponding to NPEM register values */
+static const struct indication dsm_indications[] = {
+ {PCI_NPEM_IND_OK, "enclosure:ok"},
+ {PCI_NPEM_IND_LOCATE, "enclosure:locate"},
+ {PCI_NPEM_IND_FAIL, "enclosure:fail"},
+ {PCI_NPEM_IND_REBUILD, "enclosure:rebuild"},
+ {PCI_NPEM_IND_PFA, "enclosure:pfa"},
+ {PCI_NPEM_IND_HOTSPARE, "enclosure:hotspare"},
+ {PCI_NPEM_IND_ICA, "enclosure:ica"},
+ {PCI_NPEM_IND_IFA, "enclosure:ifa"},
+ {PCI_NPEM_IND_IDT, "enclosure:idt"},
+ {PCI_NPEM_IND_DISABLED, "enclosure:disabled"},
+ {0, NULL}
+};
+
#define for_each_indication(ind, inds) \
for (ind = inds; ind->bit; ind++)
@@ -252,6 +275,120 @@ static bool npem_has_dsm(struct pci_dev *pdev)
BIT(GET_STATE_DSM) | BIT(SET_STATE_DSM));
}
+struct dsm_output {
+ u16 status;
+ u8 function_specific_err;
+ u8 vendor_specific_err;
+ u32 state;
+};
+
+/**
+ * dsm_evaluate() - send DSM PCIe SSD Status LED command
+ * @pdev: PCI device
+ * @dsm_func: DSM LED Function
+ * @output: buffer to copy DSM Response
+ * @value_to_set: value for SET_STATE_DSM function
+ *
+ * To not bother caller with ACPI context, the returned _DSM Output Buffer is
+ * copied.
+ */
+static int dsm_evaluate(struct pci_dev *pdev, u64 dsm_func,
+ struct dsm_output *output, u32 value_to_set)
+{
+ acpi_handle handle = ACPI_HANDLE(&pdev->dev);
+ union acpi_object *out_obj, arg3[2];
+ union acpi_object *arg3_p = NULL;
+
+ if (dsm_func == SET_STATE_DSM) {
+ arg3[0].type = ACPI_TYPE_PACKAGE;
+ arg3[0].package.count = 1;
+ arg3[0].package.elements = &arg3[1];
+
+ arg3[1].type = ACPI_TYPE_BUFFER;
+ arg3[1].buffer.length = 4;
+ arg3[1].buffer.pointer = (u8 *)&value_to_set;
+
+ arg3_p = arg3;
+ }
+
+ out_obj = acpi_evaluate_dsm_typed(handle, &dsm_guid, 0x1, dsm_func,
+ arg3_p, ACPI_TYPE_BUFFER);
+ if (!out_obj)
+ return -EIO;
+
+ if (out_obj->buffer.length < sizeof(struct dsm_output)) {
+ ACPI_FREE(out_obj);
+ return -EIO;
+ }
+
+ memcpy(output, out_obj->buffer.pointer, sizeof(struct dsm_output));
+
+ ACPI_FREE(out_obj);
+ return 0;
+}
+
+static int dsm_get(struct pci_dev *pdev, u64 dsm_func, u32 *buf)
+{
+ struct dsm_output output;
+ int ret = dsm_evaluate(pdev, dsm_func, &output, 0);
+
+ if (ret)
+ return ret;
+
+ if (output.status != 0)
+ return -EIO;
+
+ *buf = output.state;
+ return 0;
+}
+
+static int dsm_get_active_indications(struct npem *npem, u32 *buf)
+{
+ int ret = dsm_get(npem->dev, GET_STATE_DSM, buf);
+
+ /* Filter out not supported indications in response */
+ *buf &= npem->supported_indications;
+ return ret;
+}
+
+static int dsm_set_active_indications(struct npem *npem, u32 value)
+{
+ struct dsm_output output;
+ int ret = dsm_evaluate(npem->dev, SET_STATE_DSM, &output, value);
+
+ if (ret)
+ return ret;
+
+ switch (output.status) {
+ case 4:
+ /*
+ * Not all bits are set. If this bit is set, the platform
+ * disregarded some or all of the request state changes. OSPM
+ * should check the resulting PCIe SSD Status LED States to see
+ * what, if anything, has changed.
+ *
+ * PCI Firmware Specification, r3.3 Table 4-19.
+ */
+ if (output.function_specific_err != 1)
+ return -EIO;
+ fallthrough;
+ case 0:
+ break;
+ default:
+ return -EIO;
+ }
+
+ npem->active_indications = output.state;
+
+ return 0;
+}
+
+static const struct npem_ops dsm_ops = {
+ .inds = dsm_indications,
+ .get_active_indications = dsm_get_active_indications,
+ .set_active_indications = dsm_set_active_indications,
+};
+
static int npem_initialize_active_indications(struct npem *npem)
{
int ret;
@@ -439,11 +576,15 @@ void pci_npem_create(struct pci_dev *dev)
* OS should use the DSM for LED control if it is available
* PCI Firmware Spec r3.3 sec 4.7.
*/
- return;
+ ret = dsm_get(dev, GET_SUPPORTED_STATES_DSM, &cap);
+ if (ret)
+ return;
+
+ ops = &dsm_ops;
}
ret = pci_npem_init(dev, ops, pos, cap);
if (ret)
- pci_err(dev, "Failed to register PCIe Enclosure Management driver, err: %d\n",
- ret);
+ pci_err(dev, "Failed to register %s PCIe Enclosure Management driver, err: %d\n",
+ (ops == &dsm_ops ? "_DSM" : "Native"), ret);
}
--
2.35.3
next prev parent reply other threads:[~2024-07-11 8:30 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-11 8:30 [PATCH v4 0/3] PCIe Enclosure LED Management Mariusz Tkaczyk
2024-07-11 8:30 ` [PATCH v4 1/3] leds: Init leds class earlier Mariusz Tkaczyk
2024-07-11 8:49 ` Ilpo Järvinen
2024-07-11 8:30 ` [PATCH v4 2/3] PCI/NPEM: Add Native PCIe Enclosure Management support Mariusz Tkaczyk
2024-07-11 8:46 ` Ilpo Järvinen
2024-07-26 7:29 ` Marek Behún
2024-07-31 11:51 ` Mariusz Tkaczyk
2024-07-31 15:17 ` Marek Behún
2024-07-31 15:52 ` Lukas Wunner
2024-08-01 9:06 ` Marek Behún
2024-08-01 11:15 ` Lukas Wunner
2024-08-01 9:09 ` Marek Behún
2024-07-11 8:30 ` Mariusz Tkaczyk [this message]
2024-07-25 20:08 ` [PATCH v4 0/3] PCIe Enclosure LED Management Bjorn Helgaas
2024-07-26 7:29 ` Mariusz Tkaczyk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240711083009.5580-4-mariusz.tkaczyk@linux.intel.com \
--to=mariusz.tkaczyk@linux.intel.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=arnd@arndb.de \
--cc=bhelgaas@google.com \
--cc=dan.j.williams@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=hch@lst.de \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=kbusch@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lukas@wunner.de \
--cc=marek.behun@nic.cz \
--cc=pavel@ucw.cz \
--cc=rdunlap@infradead.org \
--cc=stuart.w.hayes@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).