/* Device Config */
#define WDC_NVME_VID 0x1c58
-#define WDC_NVME_SN100_CNTL_ID 0x0003
-#define WDC_NVME_SN200_CNTL_ID 0x0023
+#define WDC_NVME_SN100_DEV_ID 0x0003
+#define WDC_NVME_SN200_DEV_ID 0x0023
+#define WDC_NVME_VID_2 0x1b96
+#define WDC_NVME_SN310_DEV_ID 0x2200
+#define WDC_NVME_SN510_DEV_ID 0x2300
+
#define WDC_NVME_SNDK_VID 0x15b7
-#define WDC_NVME_SXSLCL_CNTRL_ID 0x0000
+#define WDC_NVME_SXSLCL_DEV_ID 0x2001
+#define WDC_NVME_SN520_DEV_ID_1 0x5003
+#define WDC_NVME_SN520_DEV_ID_2 0x5005
+#define WDC_NVME_SN720_DEV_ID 0x5002
/* Capture Diagnostics */
#define WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE WDC_NVME_LOG_SIZE_DATA_LEN
(uint64_t)(((double)numerator / (double)denominator) * 100) : 0;
}
-static int wdc_check_device(int fd)
+static int wdc_get_pci_dev_id(int *device_id)
+{
+ int fd, ret = -1;
+ char *base, path[512], *id;
+
+ base = nvme_char_from_block((char *)devicename);
+ sprintf(path, "/sys/class/nvme/%s/device/device", base);
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ sprintf(path, "/sys/class/misc/%s/device/device", base);
+ fd = open(path, O_RDONLY);
+ }
+ if (fd < 0) {
+ fprintf(stderr, "%s: did not find a pci device\n", __func__);
+ return -1;
+ }
+
+ id = calloc(1, 32);
+ if (!id)
+ goto close_fd;
+
+ ret = read(fd, id, 32);
+ if (ret < 0) {
+ fprintf(stderr, "%s: Read of pci device id failed\n", __func__);
+ } else {
+ if (id[strlen(id) - 1] == '\n')
+ id[strlen(id) - 1] = '\0';
+
+ /* convert the device id string to an int */
+ *device_id = (int)strtol(&id[2], NULL, 16);
+ ret = 0;
+ }
+
+ free(id);
+
+close_fd:
+ close(fd);
+ return ret;
+}
+
+static bool wdc_check_device(int fd)
{
int ret;
+ bool supported;
struct nvme_id_ctrl ctrl;
+ int device_id;
memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
ret = nvme_identify_ctrl(fd, &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
"0x%x\n", ret);
- return -1;
+ return false;
}
- ret = -1;
- /* WDC : ctrl->cntlid == PCI Device ID, use that with VID to identify WDC Devices */
+
+ ret = wdc_get_pci_dev_id((int *)&device_id);
+ if (ret < 0)
+ return false;
+
+ supported = false;
+
+ /* WDC : Use PCI Vendor and Device ID's to identify WDC Devices */
if ((le32_to_cpu(ctrl.vid) == WDC_NVME_VID) &&
- ((le32_to_cpu(ctrl.cntlid) == WDC_NVME_SN100_CNTL_ID) ||
- (le32_to_cpu(ctrl.cntlid) == WDC_NVME_SN200_CNTL_ID)))
- ret = 0;
+ ((device_id == WDC_NVME_SN100_DEV_ID) ||
+ (device_id == WDC_NVME_SN200_DEV_ID)))
+ supported = true;
else if ((le32_to_cpu(ctrl.vid) == WDC_NVME_SNDK_VID) &&
- (le32_to_cpu(ctrl.cntlid) == WDC_NVME_SXSLCL_CNTRL_ID))
- ret = 0;
+ (device_id == WDC_NVME_SXSLCL_DEV_ID))
+ supported = true;
+ else if ((le32_to_cpu(ctrl.vid) == WDC_NVME_VID_2) &&
+ ((device_id == WDC_NVME_SN310_DEV_ID) ||
+ (device_id == WDC_NVME_SN510_DEV_ID)))
+ supported = true;
else
- fprintf(stderr, "WARNING : WDC : Device not supported\n");
+ fprintf(stderr, "WARNING : WDC not supported, Vendor ID = 0x%x, Device ID = 0x%x\n", le32_to_cpu(ctrl.vid), device_id);
- return ret;
+ return supported;
}
-static int wdc_check_device_sxslcl(int fd)
+static bool wdc_check_device_sxslcl(int fd)
{
int ret;
struct nvme_id_ctrl ctrl;
+ int device_id;
memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
ret = nvme_identify_ctrl(fd, &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
"0x%x\n", ret);
- return -1;
+ return false;
}
- ret = -1;
- /* WDC : ctrl->cntlid == PCI Device ID, use that with VID to identify WDC Devices */
- if ((le32_to_cpu(ctrl.vid) == WDC_NVME_SNDK_VID) &&
- (le32_to_cpu(ctrl.cntlid) == WDC_NVME_SXSLCL_CNTRL_ID))
- ret = 0;
+ ret = wdc_get_pci_dev_id((int *)&device_id);
+ if (ret < 0)
+ return false;
- return ret;
+ /* WDC : Use PCI Vendor and Device ID's to identify WDC Devices */
+ if ((le32_to_cpu(ctrl.vid) == WDC_NVME_SNDK_VID) &&
+ (device_id == WDC_NVME_SXSLCL_DEV_ID))
+ return true;
+ else
+ return false;
}
static bool wdc_check_device_sn100(int fd)
{
- bool ret;
+ int ret;
struct nvme_id_ctrl ctrl;
+ int device_id;
memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
ret = nvme_identify_ctrl(fd, &ctrl);
return false;
}
- /* WDC : ctrl->cntlid == PCI Device ID, use that with VID to identify WDC Devices */
+ ret = wdc_get_pci_dev_id((int *)&device_id);
+ if (ret < 0)
+ return false;
+
+ /* WDC : Use PCI Vendor and Device ID's to identify WDC Devices */
if ((le32_to_cpu(ctrl.vid) == WDC_NVME_VID) &&
- (le32_to_cpu(ctrl.cntlid) == WDC_NVME_SN100_CNTL_ID))
- ret = true;
+ (device_id == WDC_NVME_SN100_DEV_ID))
+ return true;
else
- ret = false;
-
- return ret;
+ return false;
}
static bool wdc_check_device_sn200(int fd)
{
- bool ret;
+ int ret;
struct nvme_id_ctrl ctrl;
+ int device_id;
memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
ret = nvme_identify_ctrl(fd, &ctrl);
return false;
}
- /* WDC : ctrl->cntlid == PCI Device ID, use that with VID to identify WDC Devices */
+ ret = wdc_get_pci_dev_id((int *)&device_id);
+ if (ret < 0)
+ return false;
+
+ /* WDC : Use PCI Vendor and Device ID's to identify WDC Devices */
if ((le32_to_cpu(ctrl.vid) == WDC_NVME_VID) &&
- (le32_to_cpu(ctrl.cntlid) == WDC_NVME_SN200_CNTL_ID))
- ret = true;
+ (device_id == WDC_NVME_SN200_DEV_ID))
+ return true;
else
- ret = false;
-
- return ret;
+ return false;
}
-
static int wdc_get_serial_name(int fd, char *file, size_t len, char *suffix)
{
int i;
if (fd < 0)
return fd;
- if ( wdc_check_device_sxslcl(fd) < 0) {
+ if (!wdc_check_device_sxslcl(fd)) {
fprintf(stderr, "WARNING : WDC : Device not supported\n");
return -1;
}