From f96f09a5c9c7ba81132aa6bc25df7abf3e9031f4 Mon Sep 17 00:00:00 2001 From: Niklas Schnelle Date: Thu, 30 Apr 2026 15:33:43 +0200 Subject: [PATCH] nvmemon: libzpci: Skip SCLP on NVMes with non-IBM subsystem vendor ID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SCLP Write Event Data Action Qualifier 4 is only available for NVMes with subsystem vendor ID matching IBM. Add both IDs to struct zpci_dev in libzpci. Also add them to the libzpci_example output and adjust its output to multiline to handle more data. Reviewed-by: Jan Höppner Signed-off-by: Niklas Schnelle Signed-off-by: Jan Höppner --- include/lib/pci_list.h | 4 ++++ libzpci/libzpci_example.c | 12 ++++++++---- libzpci/pci_list.c | 10 ++++++++++ zpcimon/nvmemon.c | 2 +- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/include/lib/pci_list.h b/include/lib/pci_list.h index 226a82d9..204b710d 100644 --- a/include/lib/pci_list.h +++ b/include/lib/pci_list.h @@ -18,6 +18,7 @@ #include "util_list.h" #define PCI_BDF_LEN 13 /* DDDD:BB:dd.f\0 */ +#define PCI_VENDOR_ID_IBM 0x1014 enum zpci_pft { ZPCI_PFT_UNCLASSIFIED = 0x00, @@ -67,6 +68,9 @@ struct zpci_dev { bool uid_is_unique; /* Configuration state 0 - Standby, 1 Configured */ bool conf; + /* Common PCI attributes */ + uint16_t subsystem_vendor; + uint16_t subsystem_device; /* Associated netdevs if any */ int num_netdevs; diff --git a/libzpci/libzpci_example.c b/libzpci/libzpci_example.c index 583846b4..a9b8509e 100644 --- a/libzpci/libzpci_example.c +++ b/libzpci/libzpci_example.c @@ -12,13 +12,17 @@ static void zpci_print(struct zpci_dev *zdev) int i; if (!zdev->conf) { - printf("fid: %8x address: %s\n", zdev->fid, pci_addr); + printf("fid:\t%4x address: %s\n", zdev->fid, pci_addr); } else { - printf("fid: %8x address: %s uid: %4x%s pchid: %4x vfn: %4d port: %1d pft: %s ", + printf("fid:\t%4x address: %s uid: %4x%s pchid: %4x vfn: %4d\n", zdev->fid, pci_addr, zdev->uid, (zdev->uid_is_unique) ? " (unique)" : "", - zdev->pchid, zdev->vfn, zdev->port, zpci_pft_str(zdev)); + zdev->pchid, zdev->vfn); + printf("\n"); + printf("\tport: %1d pft: %s subsystem_device: %4x subsystem_vendor: %4x\n", + zdev->port, zpci_pft_str(zdev), zdev->subsystem_device, + zdev->subsystem_vendor); if (zdev->num_netdevs) { - printf("netdevs: "); + printf("\tnetdevs: "); for (i = 0; i < zdev->num_netdevs; i++) { printf("%s (%s)", zdev->netdevs[i].name, zpci_operstate_str(zdev->netdevs[i].operstate)); diff --git a/libzpci/pci_list.c b/libzpci/pci_list.c index e81bb4b8..a125bf71 100644 --- a/libzpci/pci_list.c +++ b/libzpci/pci_list.c @@ -262,6 +262,16 @@ static int zpci_populate_from_dev_dir(struct zpci_dev *zdev) goto out_path; zdev->pft = val; + rc = util_file_read_i(&val, 16, "%s/subsystem_device", path); + if (rc) + goto out_path; + zdev->subsystem_device = val; + + rc = util_file_read_i(&val, 16, "%s/subsystem_vendor", path); + if (rc) + goto out_path; + zdev->subsystem_vendor = val; + if (util_path_is_readable("%s/net", path)) { rc = zpci_populate_netdevices(zdev, path); if (rc) diff --git a/zpcimon/nvmemon.c b/zpcimon/nvmemon.c index 14f088c0..bd5ef1a7 100644 --- a/zpcimon/nvmemon.c +++ b/zpcimon/nvmemon.c @@ -144,7 +144,7 @@ static int sclp_issue_nvme_smart_report(struct zpci_dev *zdev, const uint8_t *sm char *pci_addr; int rc; - if (zdev->pft != ZPCI_PFT_NVME) + if (zdev->pft != ZPCI_PFT_NVME || zdev->subsystem_vendor != PCI_VENDOR_ID_IBM) return -ENOTSUP; pci_addr = zpci_pci_addr(zdev); rc = zpci_sclp_issue_action(pci_addr, SCLP_ERRNOTIFY_AQ_NVME_SMART_DATA,