Skip to content

Commit 31ddc5a

Browse files
committed
mi: Add NVMe-MI Read MI Data Structure commands for controller and controller list
Add MI functions perform Read MI Data Structure commands (section 5.6 of the NVMe-MI v1.1), to retrieve the controller list, and the controller data. Use these new functions to extend the mi-mctp example to show controller info, as a 'controllers' subcommand. Signed-off-by: Jeremy Kerr <[email protected]>
1 parent ef90bc1 commit 31ddc5a

4 files changed

Lines changed: 98 additions & 1 deletion

File tree

examples/mi-mctp.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,56 @@ int do_info(nvme_mi_ep_t ep)
115115
return 0;
116116
}
117117

118+
static int show_ctrl(nvme_mi_ep_t ep, uint16_t ctrl_id)
119+
{
120+
struct nvme_mi_read_ctrl_info ctrl;
121+
int rc;
122+
123+
rc = nvme_mi_mi_read_mi_data_ctrl(ep, ctrl_id, &ctrl);
124+
if (rc)
125+
return rc;
126+
127+
printf(" Controller id: %d\n", ctrl_id);
128+
printf(" port id: %d\n", ctrl.portid);
129+
if (ctrl.prii & 0x1) {
130+
uint16_t bdfn = le16_to_cpu(ctrl.pri);
131+
printf(" PCIe routing valid\n");
132+
printf(" PCIe bus: 0x%02x\n", bdfn >> 8);
133+
printf(" PCIe dev: 0x%02x\n", bdfn >> 3 & 0x1f);
134+
printf(" PCIe fn : 0x%02x\n", bdfn & 0x7);
135+
} else {
136+
printf(" PCIe routing invalid\n");
137+
}
138+
printf(" PCI vendor: %04x\n", le16_to_cpu(ctrl.vid));
139+
printf(" PCI device: %04x\n", le16_to_cpu(ctrl.did));
140+
printf(" PCI subsys vendor: %04x\n", le16_to_cpu(ctrl.ssvid));
141+
printf(" PCI subsys device: %04x\n", le16_to_cpu(ctrl.ssvid));
142+
143+
return 0;
144+
}
145+
146+
static int do_controllers(nvme_mi_ep_t ep)
147+
{
148+
struct nvme_ctrl_list ctrl_list;
149+
int rc, i;
150+
151+
rc = nvme_mi_mi_read_mi_data_ctrl_list(ep, 0, &ctrl_list);
152+
if (rc) {
153+
warnx("Can't perform Controller List operation");
154+
return rc;
155+
}
156+
157+
printf("NVMe controller list:\n");
158+
for (i = 0; i < le16_to_cpu(ctrl_list.num); i++) {
159+
uint16_t id = le16_to_cpu(ctrl_list.identifier[i]);
160+
show_ctrl(ep, id);
161+
}
162+
return 0;
163+
}
164+
118165
enum action {
119166
ACTION_INFO,
167+
ACTION_CONTROLLERS,
120168
};
121169

122170
int main(int argc, char **argv)
@@ -132,7 +180,8 @@ int main(int argc, char **argv)
132180
"usage: %s <net> <eid> [action] [action args]\n",
133181
argv[0]);
134182
fprintf(stderr, "where action is:\n"
135-
" info\n");
183+
" info\n"
184+
" controllers\n");
136185
return EXIT_FAILURE;
137186
}
138187

@@ -150,6 +199,8 @@ int main(int argc, char **argv)
150199

151200
if (!strcmp(action_str, "info")) {
152201
action = ACTION_INFO;
202+
} else if (!strcmp(action_str, "controllers")) {
203+
action = ACTION_CONTROLLERS;
153204
} else {
154205
fprintf(stderr, "invalid action '%s'\n", action_str);
155206
return EXIT_FAILURE;
@@ -168,6 +219,9 @@ int main(int argc, char **argv)
168219
case ACTION_INFO:
169220
rc = do_info(ep);
170221
break;
222+
case ACTION_CONTROLLERS:
223+
rc = do_controllers(ep);
224+
break;
171225
}
172226

173227
nvme_mi_close(ep);

src/libnvme-mi.map

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ LIBNVME_MI_1_1 {
77
nvme_mi_close;
88
nvme_mi_mi_read_mi_data_subsys;
99
nvme_mi_mi_read_mi_data_port;
10+
nvme_mi_mi_read_mi_data_ctrl_list;
11+
nvme_mi_mi_read_mi_data_ctrl;
1012
nvme_mi_mi_subsystem_health_status_poll;
1113
nvme_mi_open_mctp;
1214
local:

src/nvme/mi.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,43 @@ int nvme_mi_mi_read_mi_data_port(nvme_mi_ep_t ep, __u8 portid,
204204
return 0;
205205
}
206206

207+
int nvme_mi_mi_read_mi_data_ctrl_list(nvme_mi_ep_t ep, __u8 start_portid,
208+
struct nvme_ctrl_list *list)
209+
{
210+
size_t len;
211+
__u32 cdw0;
212+
int rc;
213+
214+
cdw0 = ((__u8)nvme_mi_dtyp_ctrl_list << 24) | (start_portid << 16);
215+
len = sizeof(*list);
216+
217+
rc = nvme_mi_read_data(ep, cdw0, list, &len);
218+
if (rc)
219+
return rc;
220+
221+
return 0;
222+
}
223+
224+
int nvme_mi_mi_read_mi_data_ctrl(nvme_mi_ep_t ep, __u16 ctrl_id,
225+
struct nvme_mi_read_ctrl_info *ctrl)
226+
{
227+
size_t len;
228+
__u32 cdw0;
229+
int rc;
230+
231+
cdw0 = ((__u8)nvme_mi_dtyp_ctrl_info << 24) | cpu_to_le16(ctrl_id);
232+
len = sizeof(*ctrl);
233+
234+
rc = nvme_mi_read_data(ep, cdw0, ctrl, &len);
235+
if (rc)
236+
return rc;
237+
238+
if (len != sizeof(*ctrl))
239+
return -EPROTO;
240+
241+
return 0;
242+
}
243+
207244
int nvme_mi_mi_subsystem_health_status_poll(nvme_mi_ep_t ep, bool clear,
208245
struct nvme_mi_nvm_ss_health_status *sshs)
209246
{

src/nvme/mi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ int nvme_mi_mi_read_mi_data_subsys(nvme_mi_ep_t ep,
9595
struct nvme_mi_read_nvm_ss_info *s);
9696
int nvme_mi_mi_read_mi_data_port(nvme_mi_ep_t ep, __u8 portid,
9797
struct nvme_mi_read_port_info *p);
98+
int nvme_mi_mi_read_mi_data_ctrl_list(nvme_mi_ep_t ep, __u8 start_portid,
99+
struct nvme_ctrl_list *list);
100+
int nvme_mi_mi_read_mi_data_ctrl(nvme_mi_ep_t ep, __u16 ctrl_id,
101+
struct nvme_mi_read_ctrl_info *ctrl);
98102
int nvme_mi_mi_subsystem_health_status_poll(nvme_mi_ep_t ep, bool clear,
99103
struct nvme_mi_nvm_ss_health_status *nshds);
100104

0 commit comments

Comments
 (0)