| fix from upstream |
| |
| https://www.smartmontools.org/changeset?new=4671@/&old=4670@/ |
| |
| Index: trunk/smartmontools-6.6/ChangeLog |
| =================================================================== |
| 2017-12-27 Douglas Gilbert <dgilbert@interlog.com> |
| |
| + nvmecmds.cpp: according to NVMe 1.3a spec, the SMART/ |
| + health information log page is global and should take |
| + the global nsid (all ff_s). It also says the Error |
| + info lpage is "global. Broke WD Black PCIe (NVMe) |
| + SSD but worked on Intel SSDs. Fix; could break others. |
| + |
| +2017-12-27 Douglas Gilbert <dgilbert@interlog.com> |
| + |
| os_freebsd.cpp: on error was setting set_nvme_err() to 1, |
| not the actual NVMe status value; fix. |
| |
| Index: trunk/smartmontools-6.6/nvmecmds.cpp |
| =================================================================== |
| diff --git smartmontools-6.6/nvmecmds.cpp smartmontools-6.6/nvmecmds.cpp |
| --- smartmontools-6.6/nvmecmds.cpp (revision 4670) |
| +++ smartmontools-6.6/nvmecmds.cpp (revision 4671) |
| @@ -196,7 +196,8 @@ |
| } |
| |
| // Read NVMe log page with identifier LID. |
| -bool nvme_read_log_page(nvme_device * device, unsigned char lid, void * data, unsigned size) |
| +bool nvme_read_log_page(nvme_device * device, unsigned char lid, void * data, |
| + unsigned size, bool broadcast_nsid) |
| { |
| if (!(4 <= size && size <= 0x4000 && (size % 4) == 0)) |
| throw std::logic_error("nvme_read_log_page(): invalid size"); |
| @@ -204,7 +205,7 @@ |
| memset(data, 0, size); |
| nvme_cmd_in in; |
| in.set_data_in(nvme_admin_get_log_page, data, size); |
| - in.nsid = device->get_nsid(); |
| + in.nsid = broadcast_nsid ? 0xffffffff : device->get_nsid(); |
| in.cdw10 = lid | (((size / 4) - 1) << 16); |
| |
| return nvme_pass_through(device, in); |
| @@ -213,7 +214,7 @@ |
| // Read NVMe Error Information Log. |
| bool nvme_read_error_log(nvme_device * device, nvme_error_log_page * error_log, unsigned num_entries) |
| { |
| - if (!nvme_read_log_page(device, 0x01, error_log, num_entries * sizeof(*error_log))) |
| + if (!nvme_read_log_page(device, 0x01, error_log, num_entries * sizeof(*error_log), true)) |
| return false; |
| |
| if (isbigendian()) { |
| @@ -234,7 +235,7 @@ |
| // Read NVMe SMART/Health Information log. |
| bool nvme_read_smart_log(nvme_device * device, nvme_smart_log & smart_log) |
| { |
| - if (!nvme_read_log_page(device, 0x02, &smart_log, sizeof(smart_log))) |
| + if (!nvme_read_log_page(device, 0x02, &smart_log, sizeof(smart_log), true)) |
| return false; |
| |
| if (isbigendian()) { |
| Index: trunk/smartmontools-6.6/nvmecmds.h |
| =================================================================== |
| diff --git smartmontools-6.6/nvmecmds.h smartmontools-6.6/nvmecmds.h |
| --- smartmontools-6.6/nvmecmds.h (revision 4670) |
| +++ smartmontools-6.6/nvmecmds.h (revision 4671) |
| @@ -248,7 +248,8 @@ |
| bool nvme_read_id_ns(nvme_device * device, unsigned nsid, smartmontools::nvme_id_ns & id_ns); |
| |
| // Read NVMe log page with identifier LID. |
| -bool nvme_read_log_page(nvme_device * device, unsigned char lid, void * data, unsigned size); |
| +bool nvme_read_log_page(nvme_device * device, unsigned char lid, void * data, |
| + unsigned size, bool broadcast_nsid); |
| |
| // Read NVMe Error Information Log. |
| bool nvme_read_error_log(nvme_device * device, smartmontools::nvme_error_log_page * error_log, |
| Index: trunk/smartmontools-6.6/nvmeprint.cpp |
| =================================================================== |
| diff --git smartmontools-6.6/nvmeprint.cpp smartmontools-6.6/nvmeprint.cpp |
| --- smartmontools-6.6/nvmeprint.cpp (revision 4670) |
| +++ smartmontools-6.6/nvmeprint.cpp (revision 4671) |
| @@ -473,9 +473,21 @@ |
| if (options.log_page_size) { |
| // Align size to dword boundary |
| unsigned size = ((options.log_page_size + 4-1) / 4) * 4; |
| + bool broadcast_nsid; |
| raw_buffer log_buf(size); |
| |
| - if (!nvme_read_log_page(device, options.log_page, log_buf.data(), size)) { |
| + switch (options.log_page) { |
| + case 1: |
| + case 2: |
| + case 3: |
| + broadcast_nsid = true; |
| + break; |
| + default: |
| + broadcast_nsid = false; |
| + break; |
| + } |
| + if (!nvme_read_log_page(device, options.log_page, log_buf.data(), |
| + size, broadcast_nsid)) { |
| pout("Read NVMe Log 0x%02x failed: %s\n\n", options.log_page, device->get_errmsg()); |
| return retval | FAILSMART; |
| } |