@@ -1908,6 +1908,103 @@ static void test_endpoint_quirk_probe(struct nvme_mi_ep *ep)
19081908 assert (rc == 0 );
19091909}
19101910
1911+ struct req_dlen_doff_data {
1912+ enum {
1913+ DATA_DIR_IN ,
1914+ DATA_DIR_OUT ,
1915+ } direction ;
1916+ unsigned int req_len ;
1917+ unsigned int resp_len ;
1918+ unsigned int exp_doff ;
1919+ };
1920+
1921+ static int test_admin_dlen_doff_cb (struct nvme_mi_ep * ep ,
1922+ struct nvme_mi_req * req ,
1923+ struct nvme_mi_resp * resp ,
1924+ void * data )
1925+ {
1926+ struct req_dlen_doff_data * args = data ;
1927+ __u8 * hdr = (__u8 * )req -> hdr ;
1928+ __u32 dlen , doff ;
1929+
1930+ dlen = hdr [35 ] << 24 | hdr [34 ] << 16 | hdr [33 ] << 8 | hdr [32 ];
1931+ doff = hdr [39 ] << 24 | hdr [38 ] << 16 | hdr [37 ] << 8 | hdr [36 ];
1932+
1933+ if (args -> direction == DATA_DIR_OUT ) {
1934+ assert (dlen == args -> req_len );
1935+ assert (dlen == req -> data_len );
1936+ assert (doff == 0 );
1937+ } else {
1938+ assert (dlen == args -> resp_len );
1939+ assert (dlen == resp -> data_len );
1940+ assert (doff == args -> exp_doff );
1941+ }
1942+
1943+ /* minimal valid response */
1944+ hdr = (__u8 * )resp -> hdr ;
1945+ hdr [4 ] = 0x00 ; /* status: success */
1946+
1947+ test_transport_resp_calc_mic (resp );
1948+
1949+ return 0 ;
1950+ }
1951+
1952+ /* Check dlen value on admin_xfer requests that include data. */
1953+ static void test_admin_dlen_doff_req (struct nvme_mi_ep * ep )
1954+ {
1955+ struct {
1956+ struct nvme_mi_admin_req_hdr hdr ;
1957+ unsigned char data [4096 ];
1958+ } admin_req = { 0 };
1959+ struct nvme_mi_admin_resp_hdr admin_resp = { 0 };
1960+ struct req_dlen_doff_data data = { 0 };
1961+ size_t resp_sz = 0 ;
1962+ nvme_mi_ctrl_t ctrl ;
1963+ int rc ;
1964+
1965+ data .direction = DATA_DIR_OUT ;
1966+ data .req_len = sizeof (admin_req .data );
1967+
1968+ test_set_transport_callback (ep , test_admin_dlen_doff_cb , & data );
1969+
1970+ ctrl = nvme_mi_init_ctrl (ep , 0 );
1971+ assert (ctrl );
1972+
1973+ rc = nvme_mi_admin_xfer (ctrl , & admin_req .hdr , sizeof (admin_req .data ),
1974+ & admin_resp , 0 , & resp_sz );
1975+
1976+ assert (!rc );
1977+ };
1978+
1979+ /* Check dlen value on admin_xfer requests that return data in their response.
1980+ */
1981+ static void test_admin_dlen_doff_resp (struct nvme_mi_ep * ep )
1982+ {
1983+ struct {
1984+ struct nvme_mi_admin_resp_hdr hdr ;
1985+ unsigned char data [4096 ];
1986+ } admin_resp = { 0 };
1987+ struct nvme_mi_admin_req_hdr admin_req = { 0 };
1988+ struct req_dlen_doff_data data = { 0 };
1989+ nvme_mi_ctrl_t ctrl ;
1990+ size_t resp_sz ;
1991+ int rc ;
1992+
1993+ data .direction = DATA_DIR_IN ;
1994+ data .resp_len = sizeof (admin_resp .data );
1995+ resp_sz = sizeof (admin_resp .data );
1996+
1997+ test_set_transport_callback (ep , test_admin_dlen_doff_cb , & data );
1998+
1999+ ctrl = nvme_mi_init_ctrl (ep , 0 );
2000+ assert (ctrl );
2001+
2002+ rc = nvme_mi_admin_xfer (ctrl , & admin_req , 0 , & admin_resp .hdr , 0 ,
2003+ & resp_sz );
2004+
2005+ assert (!rc );
2006+ };
2007+
19112008#define DEFINE_TEST (name ) { #name, test_ ## name }
19122009struct test {
19132010 const char * name ;
@@ -1950,6 +2047,8 @@ struct test {
19502047 DEFINE_TEST (admin_sanitize_nvm ),
19512048 DEFINE_TEST (admin_get_log_split ),
19522049 DEFINE_TEST (endpoint_quirk_probe ),
2050+ DEFINE_TEST (admin_dlen_doff_req ),
2051+ DEFINE_TEST (admin_dlen_doff_resp ),
19532052};
19542053
19552054static void run_test (struct test * test , FILE * logfd , nvme_mi_ep_t ep )
0 commit comments