@@ -152,6 +152,47 @@ static void test_endpoint_lifetime(nvme_mi_ep_t ep)
152152 assert (count == 1 );
153153}
154154
155+ unsigned int count_ep_controllers (nvme_mi_ep_t ep )
156+ {
157+ unsigned int i = 0 ;
158+ nvme_mi_ctrl_t ctrl ;
159+
160+ nvme_mi_for_each_ctrl (ep , ctrl )
161+ i ++ ;
162+
163+ return i ;
164+ }
165+
166+ /* test that the ep->controllers list is updated on controller
167+ * creation/destruction */
168+ static void test_ctrl_lifetime (nvme_mi_ep_t ep )
169+ {
170+ nvme_mi_ctrl_t c1 , c2 ;
171+ int count ;
172+
173+ ep -> controllers_scanned = true;
174+
175+ count = count_ep_controllers (ep );
176+ assert (count == 0 );
177+
178+ c1 = nvme_mi_init_ctrl (ep , 1 );
179+ count = count_ep_controllers (ep );
180+ assert (count == 1 );
181+
182+ c2 = nvme_mi_init_ctrl (ep , 2 );
183+ count = count_ep_controllers (ep );
184+ assert (count == 2 );
185+
186+ nvme_mi_close_ctrl (c1 );
187+ count = count_ep_controllers (ep );
188+ assert (count == 1 );
189+
190+ nvme_mi_close_ctrl (c2 );
191+ count = count_ep_controllers (ep );
192+ assert (count == 0 );
193+ }
194+
195+
155196/* test: basic read MI datastructure command */
156197static int test_read_mi_data_cb (struct nvme_mi_ep * ep ,
157198 struct nvme_mi_req * req ,
@@ -262,6 +303,75 @@ static void test_invalid_crc(nvme_mi_ep_t ep)
262303 assert (rc != 0 );
263304}
264305
306+ /* test: test that the controller list populates the endpoint's list of
307+ * controllers */
308+ static int test_scan_ctrl_list_cb (struct nvme_mi_ep * ep ,
309+ struct nvme_mi_req * req ,
310+ struct nvme_mi_resp * resp ,
311+ void * data )
312+ {
313+ __u8 ror , mt , * hdr , * buf ;
314+
315+ assert (req -> hdr -> type == NVME_MI_MSGTYPE_NVME );
316+
317+ ror = req -> hdr -> nmp >> 7 ;
318+ mt = req -> hdr -> nmp >> 3 & 0x7 ;
319+ assert (ror == NVME_MI_ROR_REQ );
320+ assert (mt == NVME_MI_MT_MI );
321+
322+ /* do we have enough for a mi header? */
323+ assert (req -> hdr_len == sizeof (struct nvme_mi_mi_req_hdr ));
324+
325+ /* inspect response as raw bytes */
326+ hdr = (__u8 * )req -> hdr ;
327+ assert (hdr [4 ] == nvme_mi_mi_opcode_mi_data_read );
328+ assert (hdr [11 ] == nvme_mi_dtyp_ctrl_list );
329+
330+ /* create basic response */
331+ assert (resp -> hdr_len >= sizeof (struct nvme_mi_mi_resp_hdr ));
332+ assert (resp -> data_len >= 4 );
333+
334+ hdr = (__u8 * )resp -> hdr ;
335+ hdr [4 ] = 0 ; /* status */
336+
337+ buf = (__u8 * )resp -> data ;
338+ memset (buf , 0 , resp -> data_len );
339+ buf [0 ] = 3 ; buf [1 ] = 0 ; /* num controllers */
340+ buf [2 ] = 1 ; buf [3 ] = 0 ; /* id 1 */
341+ buf [4 ] = 4 ; buf [5 ] = 0 ; /* id 4 */
342+ buf [6 ] = 5 ; buf [7 ] = 0 ; /* id 5 */
343+
344+ test_transport_resp_calc_mic (resp );
345+
346+ return 0 ;
347+ }
348+
349+ static void test_scan_ctrl_list (nvme_mi_ep_t ep )
350+ {
351+ struct nvme_mi_ctrl * ctrl ;
352+
353+ ep -> controllers_scanned = false;
354+
355+ test_set_transport_callback (ep , test_scan_ctrl_list_cb , NULL );
356+
357+ nvme_mi_scan_ep (ep , false);
358+
359+ ctrl = nvme_mi_first_ctrl (ep );
360+ assert (ctrl );
361+ assert (ctrl -> id == 1 );
362+
363+ ctrl = nvme_mi_next_ctrl (ep , ctrl );
364+ assert (ctrl );
365+ assert (ctrl -> id == 4 );
366+
367+ ctrl = nvme_mi_next_ctrl (ep , ctrl );
368+ assert (ctrl );
369+ assert (ctrl -> id == 5 );
370+
371+ ctrl = nvme_mi_next_ctrl (ep , ctrl );
372+ assert (ctrl == NULL );
373+ }
374+
265375/* test: simple NVMe admin request/response */
266376static int test_admin_id_cb (struct nvme_mi_ep * ep ,
267377 struct nvme_mi_req * req ,
@@ -389,9 +499,11 @@ struct test {
389499 void (* fn )(nvme_mi_ep_t );
390500} tests [] = {
391501 DEFINE_TEST (endpoint_lifetime ),
502+ DEFINE_TEST (ctrl_lifetime ),
392503 DEFINE_TEST (read_mi_data ),
393504 DEFINE_TEST (transport_fail ),
394505 DEFINE_TEST (transport_describe ),
506+ DEFINE_TEST (scan_ctrl_list ),
395507 DEFINE_TEST (invalid_crc ),
396508 DEFINE_TEST (admin_id ),
397509 DEFINE_TEST (admin_err_resp ),
0 commit comments