@@ -69,6 +69,36 @@ def _check_ns_copy_limits(self):
6969 if missing :
7070 self .skipTest (f"{ ', ' .join (missing )} are 0, copy not supported on this namespace" )
7171
72+ def _check_ns_uses_64b_pi_guard (self ):
73+ """ Skip test if the namespace's current LBA format does not use 64-bit PI guard.
74+ Copy Descriptor Formats 1h and 3h require the source namespace to be formatted
75+ with 64-bit guard protection information (pif == 2 in the extended LBA format
76+ entry). If the namespace uses a standard 16-bit guard LBA format the controller
77+ will return 'Invalid Format'.
78+ """
79+ # decode the 6-bit LBA format index from the flbas field:
80+ # bits [3:0] are the low 4 bits; bits [6:5] are the high 2 bits
81+ flbas = to_decimal (self .get_id_ns_field_value ("flbas" ))
82+ lbaf_index = (flbas & 0xF ) | (((flbas >> 5 ) & 0x3 ) << 4 )
83+
84+ nvm_id_ns_cmd = f"{ self .nvme_bin } nvm-id-ns { self .ns1 } --output-format=json"
85+ result = self .run_cmd (nvm_id_ns_cmd )
86+ if result .returncode != 0 :
87+ self .skipTest ("nvm-id-ns not supported; cannot verify 64-bit PI guard compatibility" )
88+
89+ data = json .loads (result .stdout )
90+ elbafs = data .get ("elbafs" , [])
91+ if lbaf_index >= len (elbafs ):
92+ self .skipTest (f"lbaf index { lbaf_index } out of range in nvm-id-ns elbafs" )
93+
94+ pif = elbafs [lbaf_index ].get ("pif" , 0 )
95+ # NVME_NVM_PIF_64B_GUARD = 2; formats 1h and 3h require 64-bit guard PI
96+ if pif != 2 :
97+ self .skipTest (
98+ f"current LBA format { lbaf_index } has pif={ pif } (not 64-bit guard); "
99+ "copy descriptor formats 1h and 3h require 64-bit guard PI"
100+ )
101+
72102 def _enable_cdfe_for_format (self , desc_format ):
73103 """ Enable the host-behavior-support cdfe bit for the given cross-namespace format.
74104 Only the bit corresponding to desc_format is enabled; other bits are left unchanged.
@@ -135,6 +165,7 @@ def test_copy_format_1(self):
135165 """ Test copy with descriptor format 1 """
136166 self ._check_format_supported (1 )
137167 self ._check_ns_copy_limits ()
168+ self ._check_ns_uses_64b_pi_guard ()
138169 self .copy (0 , 1 , 2 , descriptor_format = 1 )
139170
140171 def test_copy_format_2 (self ):
@@ -155,12 +186,14 @@ def test_copy_format_3(self):
155186 """ Test copy with descriptor format 3 """
156187 self ._check_format_supported (3 )
157188 self ._check_ns_copy_limits ()
189+ self ._check_ns_uses_64b_pi_guard ()
158190 self ._enable_cdfe_for_format (3 )
159191 self .copy (0 , 1 , 2 , descriptor_format = 3 , snsids = self .ns1_nsid )
160192
161193 def test_copy_format_3_sopts (self ):
162194 """ Test copy with descriptor format 3 and source options """
163195 self ._check_format_supported (3 )
164196 self ._check_ns_copy_limits ()
197+ self ._check_ns_uses_64b_pi_guard ()
165198 self ._enable_cdfe_for_format (3 )
166199 self .copy (0 , 1 , 2 , descriptor_format = 3 , snsids = self .ns1_nsid , sopts = 0 )
0 commit comments