nvme-core: choose PIF from QPIF if QPIFS supports and PIF is QTYPE
authorFrancis Pravin <francis.p@samsung.com>
Mon, 15 Jul 2024 01:01:57 +0000 (06:31 +0530)
committerKeith Busch <kbusch@kernel.org>
Tue, 16 Jul 2024 14:55:31 +0000 (07:55 -0700)
As per TP4141a:
"If the Qualified Protection Information Format Support(QPIFS) bit is
set to 1 and the Protection Information Format(PIF) field is set to 11b
(i.e., Qualified Type), then the pif is as defined in the Qualified
Protection Information Format (QPIF) field."
So, choose PIF from QPIF if QPIFS supports and PIF is QTYPE.

Signed-off-by: Francis Pravin <francis.p@samsung.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/host/core.c
include/linux/nvme.h

index 448b8239bc9944ee4c02b59f90bcadf40d83f0da..e78ef31eeef0c8523812b4c143d4d558db97b477 100644 (file)
@@ -1875,12 +1875,18 @@ static void nvme_configure_pi_elbas(struct nvme_ns_head *head,
                struct nvme_id_ns *id, struct nvme_id_ns_nvm *nvm)
 {
        u32 elbaf = le32_to_cpu(nvm->elbaf[nvme_lbaf_index(id->flbas)]);
+       u8 guard_type;
 
        /* no support for storage tag formats right now */
        if (nvme_elbaf_sts(elbaf))
                return;
 
-       head->guard_type = nvme_elbaf_guard_type(elbaf);
+       guard_type = nvme_elbaf_guard_type(elbaf);
+       if ((nvm->pic & NVME_ID_NS_NVM_QPIFS) &&
+            guard_type == NVME_NVM_NS_QTYPE_GUARD)
+               guard_type = nvme_elbaf_qualified_guard_type(elbaf);
+
+       head->guard_type = guard_type;
        switch (head->guard_type) {
        case NVME_NVM_NS_64B_GUARD:
                head->pi_size = sizeof(struct crc64_pi_tuple);
index 57e27e48c9131da94ccb506e9f2de0fb5bf24cca..5c2290f0d5afe1273098491a12c6fd4f46e6b8ca 100644 (file)
@@ -483,6 +483,9 @@ enum {
        NVME_ID_NS_NVM_STS_MASK         = 0x7f,
        NVME_ID_NS_NVM_GUARD_SHIFT      = 7,
        NVME_ID_NS_NVM_GUARD_MASK       = 0x3,
+       NVME_ID_NS_NVM_QPIF_SHIFT       = 9,
+       NVME_ID_NS_NVM_QPIF_MASK        = 0xf,
+       NVME_ID_NS_NVM_QPIFS            = 1 << 3,
 };
 
 static inline __u8 nvme_elbaf_sts(__u32 elbaf)
@@ -495,6 +498,11 @@ static inline __u8 nvme_elbaf_guard_type(__u32 elbaf)
        return (elbaf >> NVME_ID_NS_NVM_GUARD_SHIFT) & NVME_ID_NS_NVM_GUARD_MASK;
 }
 
+static inline __u8 nvme_elbaf_qualified_guard_type(__u32 elbaf)
+{
+       return (elbaf >> NVME_ID_NS_NVM_QPIF_SHIFT) & NVME_ID_NS_NVM_QPIF_MASK;
+}
+
 struct nvme_id_ctrl_nvm {
        __u8    vsl;
        __u8    wzsl;
@@ -574,6 +582,7 @@ enum {
        NVME_NVM_NS_16B_GUARD   = 0,
        NVME_NVM_NS_32B_GUARD   = 1,
        NVME_NVM_NS_64B_GUARD   = 2,
+       NVME_NVM_NS_QTYPE_GUARD = 3,
 };
 
 static inline __u8 nvme_lbaf_index(__u8 flbas)