nvmemon: libzpci: Skip SCLP on NVMes with non-IBM subsystem vendor ID

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 <hoeppner@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Niklas Schnelle
2026-04-30 15:33:43 +02:00
committed by Jan Höppner
parent 4fd607ae5c
commit f96f09a5c9
4 changed files with 23 additions and 5 deletions

View File

@@ -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;

View File

@@ -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));

View File

@@ -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)

View File

@@ -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,