Skip to content

Commit 5933343

Browse files
committed
examples/mi-mctp: Add identify subcommand
Now that we have admin command support in libnvme-mi, use the new partial identify to request basic serial/model/firmware information from the drive. Signed-off-by: Jeremy Kerr <[email protected]>
1 parent 178fdf6 commit 5933343

1 file changed

Lines changed: 66 additions & 1 deletion

File tree

examples/mi-mctp.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
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+
165223
enum action {
166224
ACTION_INFO,
167225
ACTION_CONTROLLERS,
226+
ACTION_IDENTIFY,
168227
};
169228

170229
int 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

Comments
 (0)