1010 * mi-mctp: open a MI connection over MCTP, and query controller info
1111 */
1212
13+ #include <assert.h>
1314#include <err.h>
1415#include <stdio.h>
1516#include <stdlib.h>
17+ #include <stddef.h>
1618#include <string.h>
1719
1820#include <libnvme-mi.h>
@@ -162,9 +164,66 @@ static int do_controllers(nvme_mi_ep_t ep)
162164 return 0 ;
163165}
164166
167+ static const char * __copy_id_str (const void * field , size_t size ,
168+ char * buf , size_t buf_size )
169+ {
170+ assert (size < buf_size );
171+ strncpy (buf , field , size );
172+ buf [size ] = '\0' ;
173+ return buf ;
174+ }
175+
176+ #define copy_id_str (f ,b ) __copy_id_str(f, sizeof(f), b, sizeof(b))
177+
178+ int do_identify (nvme_mi_ep_t ep , int argc , char * * argv )
179+ {
180+ struct nvme_mi_ctrl * ctrl ;
181+ struct nvme_id_ctrl id ;
182+ uint16_t ctrl_id ;
183+ char buf [41 ];
184+ int rc , tmp ;
185+
186+ if (argc != 2 ) {
187+ fprintf (stderr , "no controller ID specified\n" );
188+ return -1 ;
189+ }
190+
191+ tmp = atoi (argv [1 ]);
192+ if (tmp < 0 || tmp > 0xffff ) {
193+ fprintf (stderr , "invalid controller ID\n" );
194+ return -1 ;
195+ }
196+
197+ ctrl_id = tmp & 0xffff ;
198+
199+ ctrl = nvme_mi_init_ctrl (ep , tmp );
200+ if (!ctrl ) {
201+ warn ("can't create controller" );
202+ return -1 ;
203+ }
204+
205+ /* we only use the fields before rab; just request partial ID data */
206+ rc = nvme_mi_admin_identify_ctrl_partial (ctrl , & id , 0 ,
207+ offsetof(struct nvme_id_ctrl , rab ));
208+ if (rc ) {
209+ warn ("can't perform Admin Identify command" );
210+ return -1 ;
211+ }
212+
213+ printf ("NVMe Controller %d identify\n" , ctrl_id );
214+ printf (" PCI vendor: %04x\n" , le16_to_cpu (id .vid ));
215+ printf (" PCI subsys vendor: %04x\n" , le16_to_cpu (id .ssvid ));
216+ printf (" Serial number: %s\n" , copy_id_str (id .sn , buf ));
217+ printf (" Model number: %s\n" , copy_id_str (id .mn , buf ));
218+ printf (" Firmware rev: %s\n" , copy_id_str (id .fr , buf ));
219+
220+ return 0 ;
221+ }
222+
165223enum action {
166224 ACTION_INFO ,
167225 ACTION_CONTROLLERS ,
226+ ACTION_IDENTIFY ,
168227};
169228
170229int main (int argc , char * * argv )
@@ -181,7 +240,8 @@ int main(int argc, char **argv)
181240 argv [0 ]);
182241 fprintf (stderr , "where action is:\n"
183242 " info\n"
184- " controllers\n" );
243+ " controllers\n"
244+ " identify <controller-id>\n" );
185245 return EXIT_FAILURE ;
186246 }
187247
@@ -201,6 +261,8 @@ int main(int argc, char **argv)
201261 action = ACTION_INFO ;
202262 } else if (!strcmp (action_str , "controllers" )) {
203263 action = ACTION_CONTROLLERS ;
264+ } else if (!strcmp (action_str , "identify" )) {
265+ action = ACTION_IDENTIFY ;
204266 } else {
205267 fprintf (stderr , "invalid action '%s'\n" , action_str );
206268 return EXIT_FAILURE ;
@@ -222,6 +284,9 @@ int main(int argc, char **argv)
222284 case ACTION_CONTROLLERS :
223285 rc = do_controllers (ep );
224286 break ;
287+ case ACTION_IDENTIFY :
288+ rc = do_identify (ep , argc , argv );
289+ break ;
225290 }
226291
227292 nvme_mi_close (ep );
0 commit comments