diff options
author | Chuck Tuffli <chuck@FreeBSD.org> | 2021-01-08 17:19:37 +0000 |
---|---|---|
committer | Chuck Tuffli <chuck@FreeBSD.org> | 2021-01-08 17:27:56 +0000 |
commit | 6733401935f83754b4b2744bc3d33ef84b1271e0 (patch) | |
tree | 297a3ca51527c2ac0fc101aef0cc2ad9a3426c44 /sys/dev | |
parent | 7edc1bd9dc174526c69246ba45bf2c8c230d38f4 (diff) | |
download | src-6733401935f83754b4b2744bc3d33ef84b1271e0.tar.gz src-6733401935f83754b4b2744bc3d33ef84b1271e0.zip |
nvmecontrol: add device self-test op and log page
Add decoding of the Device Self-test log page and the ability to start
or abort a test.
Reviewed by: imp, mav
Tested by: Muhammad Ahmad <muhammad.ahmad@seagate.com>
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D27517
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/nvme/nvme.h | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h index 3c159b1fd0fc..67d02ba73fd8 100644 --- a/sys/dev/nvme/nvme.h +++ b/sys/dev/nvme/nvme.h @@ -1396,6 +1396,28 @@ struct nvme_command_effects_page { _Static_assert(sizeof(struct nvme_command_effects_page) == 4096, "bad size for nvme_command_effects_page"); +struct nvme_device_self_test_page { + uint8_t curr_operation; + uint8_t curr_compl; + uint8_t rsvd2[2]; + struct { + uint8_t status; + uint8_t segment_num; + uint8_t valid_diag_info; + uint8_t rsvd3; + uint64_t poh; + uint32_t nsid; + /* Define as an array to simplify alignment issues */ + uint8_t failing_lba[8]; + uint8_t status_code_type; + uint8_t status_code; + uint8_t vendor_specific[2]; + } __packed result[20]; +} __packed __aligned(4); + +_Static_assert(sizeof(struct nvme_device_self_test_page) == 564, + "bad size for nvme_device_self_test_page"); + struct nvme_res_notification_page { uint64_t log_page_count; uint8_t log_page_type; @@ -2016,4 +2038,21 @@ void nvme_resv_status_ext_swapbytes(struct nvme_resv_status_ext *s __unused, #endif } +static inline void +nvme_device_self_test_swapbytes(struct nvme_device_self_test_page *s __unused) +{ +#if _BYTE_ORDER != _LITTLE_ENDIAN + uint64_t failing_lba; + uint32_t r; + + for (r = 0; r < 20; r++) { + s->result[r].poh = le64toh(s->result[r].poh); + s->result[r].nsid = le32toh(s->result[r].nsid); + /* Unaligned 64-bit loads fail on some architectures */ + memcpy(&failing_lba, s->result[r].failing_lba, sizeof(failing_lba)); + failing_lba = le64toh(failing_lba); + memcpy(s->result[r].failing_lba, &failing_lba, sizeof(failing_lba)); + } +#endif +} #endif /* __NVME_H__ */ |