1111 */
1212
1313#include <assert.h>
14+ #include <ctype.h>
1415#include <err.h>
1516#include <stdio.h>
1617#include <stdlib.h>
@@ -240,10 +241,93 @@ int do_identify(nvme_mi_ep_t ep, int argc, char **argv)
240241 return 0 ;
241242}
242243
244+ void fhexdump (FILE * fp , const unsigned char * buf , int len )
245+ {
246+ const int row_len = 16 ;
247+ int i , j ;
248+
249+ for (i = 0 ; i < len ; i += row_len ) {
250+ char hbuf [row_len * strlen ("00 " ) + 1 ];
251+ char cbuf [row_len + strlen ("|" ) + 1 ];
252+
253+ for (j = 0 ; (j < row_len ) && ((i + j ) < len ); j ++ ) {
254+ unsigned char c = buf [i + j ];
255+
256+ sprintf (hbuf + j * 3 , "%02x " , c );
257+
258+ if (!isprint (c ))
259+ c = '.' ;
260+
261+ sprintf (cbuf + j , "%c" , c );
262+ }
263+
264+ strcat (cbuf , "|" );
265+
266+ fprintf (fp , "%08x %*s |%s\n" , i ,
267+ 0 - (int )sizeof (hbuf ) + 1 , hbuf , cbuf );
268+ }
269+ }
270+
271+ void hexdump (const unsigned char * buf , int len )
272+ {
273+ fhexdump (stdout , buf , len );
274+ }
275+
276+ int do_get_log_page (nvme_mi_ep_t ep , int argc , char * * argv )
277+ {
278+ struct nvme_get_log_args args = { 0 };
279+ struct nvme_mi_ctrl * ctrl ;
280+ uint8_t buf [512 ];
281+ uint16_t ctrl_id ;
282+ int rc , tmp ;
283+
284+ if (argc < 2 ) {
285+ fprintf (stderr , "no controller ID specified\n" );
286+ return -1 ;
287+ }
288+
289+ tmp = atoi (argv [1 ]);
290+ if (tmp < 0 || tmp > 0xffff ) {
291+ fprintf (stderr , "invalid controller ID\n" );
292+ return -1 ;
293+ }
294+
295+ ctrl_id = tmp & 0xffff ;
296+
297+ args .args_size = sizeof (args );
298+ args .log = buf ;
299+ args .len = sizeof (buf );
300+
301+ if (argc > 2 ) {
302+ tmp = atoi (argv [2 ]);
303+ args .lid = tmp & 0xff ;
304+ } else {
305+ args .lid = 0x1 ;
306+ }
307+
308+ ctrl = nvme_mi_init_ctrl (ep , ctrl_id );
309+ if (!ctrl ) {
310+ warn ("can't create controller" );
311+ return -1 ;
312+ }
313+
314+ rc = nvme_mi_admin_get_log_page (ctrl , & args );
315+ if (rc ) {
316+ warn ("can't perform Get Log page command" );
317+ return -1 ;
318+ }
319+
320+ printf ("Get log page (log id = 0x%02x) data:\n" , args .lid );
321+ hexdump (buf , args .len );
322+
323+ return 0 ;
324+ }
325+
243326enum action {
244327 ACTION_INFO ,
245328 ACTION_CONTROLLERS ,
246329 ACTION_IDENTIFY ,
330+ ACTION_GET_LOG_PAGE ,
247331};
248332
249333int main (int argc , char * * argv )
@@ -261,7 +345,9 @@ int main(int argc, char **argv)
261345 fprintf (stderr , "where action is:\n"
262346 " info\n"
263347 " controllers\n"
264- " identify <controller-id> [--partial]\n" );
348+ " identify <controller-id> [--partial]\n"
349+ " get-log-page <controller-id> [<log-id>]\n"
350+ );
265351 return EXIT_FAILURE ;
266352 }
267353
@@ -283,6 +369,8 @@ int main(int argc, char **argv)
283369 action = ACTION_CONTROLLERS ;
284370 } else if (!strcmp (action_str , "identify" )) {
285371 action = ACTION_IDENTIFY ;
372+ } else if (!strcmp (action_str , "get-log-page" )) {
373+ action = ACTION_GET_LOG_PAGE ;
286374 } else {
287375 fprintf (stderr , "invalid action '%s'\n" , action_str );
288376 return EXIT_FAILURE ;
@@ -307,6 +395,9 @@ int main(int argc, char **argv)
307395 case ACTION_IDENTIFY :
308396 rc = do_identify (ep , argc , argv );
309397 break ;
398+ case ACTION_GET_LOG_PAGE :
399+ rc = do_get_log_page (ep , argc , argv );
400+ break ;
310401 }
311402
312403 nvme_mi_close (ep );
0 commit comments