xref: /aosp_15_r20/external/iproute2/rdma/dev.c (revision de1e4e894b0c224df933550f0afdecc354b238c4)
1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker  * dev.c	RDMA tool
3*de1e4e89SAndroid Build Coastguard Worker  *
4*de1e4e89SAndroid Build Coastguard Worker  *              This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker  *              modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker  *              as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker  *              2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker  *
9*de1e4e89SAndroid Build Coastguard Worker  * Authors:     Leon Romanovsky <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker  */
11*de1e4e89SAndroid Build Coastguard Worker 
12*de1e4e89SAndroid Build Coastguard Worker #include "rdma.h"
13*de1e4e89SAndroid Build Coastguard Worker 
dev_help(struct rd * rd)14*de1e4e89SAndroid Build Coastguard Worker static int dev_help(struct rd *rd)
15*de1e4e89SAndroid Build Coastguard Worker {
16*de1e4e89SAndroid Build Coastguard Worker 	pr_out("Usage: %s dev show [DEV]\n", rd->filename);
17*de1e4e89SAndroid Build Coastguard Worker 	return 0;
18*de1e4e89SAndroid Build Coastguard Worker }
19*de1e4e89SAndroid Build Coastguard Worker 
dev_caps_to_str(uint32_t idx)20*de1e4e89SAndroid Build Coastguard Worker static const char *dev_caps_to_str(uint32_t idx)
21*de1e4e89SAndroid Build Coastguard Worker {
22*de1e4e89SAndroid Build Coastguard Worker #define RDMA_DEV_FLAGS(x) \
23*de1e4e89SAndroid Build Coastguard Worker 	x(RESIZE_MAX_WR, 0) \
24*de1e4e89SAndroid Build Coastguard Worker 	x(BAD_PKEY_CNTR, 1) \
25*de1e4e89SAndroid Build Coastguard Worker 	x(BAD_QKEY_CNTR, 2) \
26*de1e4e89SAndroid Build Coastguard Worker 	x(RAW_MULTI, 3) \
27*de1e4e89SAndroid Build Coastguard Worker 	x(AUTO_PATH_MIG, 4) \
28*de1e4e89SAndroid Build Coastguard Worker 	x(CHANGE_PHY_PORT, 5) \
29*de1e4e89SAndroid Build Coastguard Worker 	x(UD_AV_PORT_ENFORCE_PORT_ENFORCE, 6) \
30*de1e4e89SAndroid Build Coastguard Worker 	x(CURR_QP_STATE_MOD, 7) \
31*de1e4e89SAndroid Build Coastguard Worker 	x(SHUTDOWN_PORT, 8) \
32*de1e4e89SAndroid Build Coastguard Worker 	x(INIT_TYPE, 9) \
33*de1e4e89SAndroid Build Coastguard Worker 	x(PORT_ACTIVE_EVENT, 10) \
34*de1e4e89SAndroid Build Coastguard Worker 	x(SYS_IMAGE_GUID, 11) \
35*de1e4e89SAndroid Build Coastguard Worker 	x(RC_RNR_NAK_GEN, 12) \
36*de1e4e89SAndroid Build Coastguard Worker 	x(SRQ_RESIZE, 13) \
37*de1e4e89SAndroid Build Coastguard Worker 	x(N_NOTIFY_CQ, 14) \
38*de1e4e89SAndroid Build Coastguard Worker 	x(LOCAL_DMA_LKEY, 15) \
39*de1e4e89SAndroid Build Coastguard Worker 	x(MEM_WINDOW, 17) \
40*de1e4e89SAndroid Build Coastguard Worker 	x(UD_IP_CSUM, 18) \
41*de1e4e89SAndroid Build Coastguard Worker 	x(UD_TSO, 19) \
42*de1e4e89SAndroid Build Coastguard Worker 	x(XRC, 20) \
43*de1e4e89SAndroid Build Coastguard Worker 	x(MEM_MGT_EXTENSIONS, 21) \
44*de1e4e89SAndroid Build Coastguard Worker 	x(BLOCK_MULTICAST_LOOPBACK, 22) \
45*de1e4e89SAndroid Build Coastguard Worker 	x(MEM_WINDOW_TYPE_2A, 23) \
46*de1e4e89SAndroid Build Coastguard Worker 	x(MEM_WINDOW_TYPE_2B, 24) \
47*de1e4e89SAndroid Build Coastguard Worker 	x(RC_IP_CSUM, 25) \
48*de1e4e89SAndroid Build Coastguard Worker 	x(RAW_IP_CSUM, 26) \
49*de1e4e89SAndroid Build Coastguard Worker 	x(CROSS_CHANNEL, 27) \
50*de1e4e89SAndroid Build Coastguard Worker 	x(MANAGED_FLOW_STEERING, 29) \
51*de1e4e89SAndroid Build Coastguard Worker 	x(SIGNATURE_HANDOVER, 30) \
52*de1e4e89SAndroid Build Coastguard Worker 	x(ON_DEMAND_PAGING, 31) \
53*de1e4e89SAndroid Build Coastguard Worker 	x(SG_GAPS_REG, 32) \
54*de1e4e89SAndroid Build Coastguard Worker 	x(VIRTUAL_FUNCTION, 33) \
55*de1e4e89SAndroid Build Coastguard Worker 	x(RAW_SCATTER_FCS, 34) \
56*de1e4e89SAndroid Build Coastguard Worker 	x(RDMA_NETDEV_OPA_VNIC, 35)
57*de1e4e89SAndroid Build Coastguard Worker 
58*de1e4e89SAndroid Build Coastguard Worker 	enum { RDMA_DEV_FLAGS(RDMA_BITMAP_ENUM) };
59*de1e4e89SAndroid Build Coastguard Worker 
60*de1e4e89SAndroid Build Coastguard Worker 	static const char * const
61*de1e4e89SAndroid Build Coastguard Worker 		rdma_dev_names[] = { RDMA_DEV_FLAGS(RDMA_BITMAP_NAMES) };
62*de1e4e89SAndroid Build Coastguard Worker 	#undef RDMA_DEV_FLAGS
63*de1e4e89SAndroid Build Coastguard Worker 
64*de1e4e89SAndroid Build Coastguard Worker 	if (idx < ARRAY_SIZE(rdma_dev_names) && rdma_dev_names[idx])
65*de1e4e89SAndroid Build Coastguard Worker 		return rdma_dev_names[idx];
66*de1e4e89SAndroid Build Coastguard Worker 	return "UNKNOWN";
67*de1e4e89SAndroid Build Coastguard Worker }
68*de1e4e89SAndroid Build Coastguard Worker 
dev_print_caps(struct rd * rd,struct nlattr ** tb)69*de1e4e89SAndroid Build Coastguard Worker static void dev_print_caps(struct rd *rd, struct nlattr **tb)
70*de1e4e89SAndroid Build Coastguard Worker {
71*de1e4e89SAndroid Build Coastguard Worker 	uint64_t caps;
72*de1e4e89SAndroid Build Coastguard Worker 	uint32_t idx;
73*de1e4e89SAndroid Build Coastguard Worker 
74*de1e4e89SAndroid Build Coastguard Worker 	if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
75*de1e4e89SAndroid Build Coastguard Worker 		return;
76*de1e4e89SAndroid Build Coastguard Worker 
77*de1e4e89SAndroid Build Coastguard Worker 	caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
78*de1e4e89SAndroid Build Coastguard Worker 
79*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output) {
80*de1e4e89SAndroid Build Coastguard Worker 		jsonw_name(rd->jw, "caps");
81*de1e4e89SAndroid Build Coastguard Worker 		jsonw_start_array(rd->jw);
82*de1e4e89SAndroid Build Coastguard Worker 	} else {
83*de1e4e89SAndroid Build Coastguard Worker 		pr_out("\n    caps: <");
84*de1e4e89SAndroid Build Coastguard Worker 	}
85*de1e4e89SAndroid Build Coastguard Worker 	for (idx = 0; caps; idx++) {
86*de1e4e89SAndroid Build Coastguard Worker 		if (caps & 0x1) {
87*de1e4e89SAndroid Build Coastguard Worker 			if (rd->json_output) {
88*de1e4e89SAndroid Build Coastguard Worker 				jsonw_string(rd->jw, dev_caps_to_str(idx));
89*de1e4e89SAndroid Build Coastguard Worker 			} else {
90*de1e4e89SAndroid Build Coastguard Worker 				pr_out("%s", dev_caps_to_str(idx));
91*de1e4e89SAndroid Build Coastguard Worker 				if (caps >> 0x1)
92*de1e4e89SAndroid Build Coastguard Worker 					pr_out(", ");
93*de1e4e89SAndroid Build Coastguard Worker 			}
94*de1e4e89SAndroid Build Coastguard Worker 		}
95*de1e4e89SAndroid Build Coastguard Worker 		caps >>= 0x1;
96*de1e4e89SAndroid Build Coastguard Worker 	}
97*de1e4e89SAndroid Build Coastguard Worker 
98*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output)
99*de1e4e89SAndroid Build Coastguard Worker 		jsonw_end_array(rd->jw);
100*de1e4e89SAndroid Build Coastguard Worker 	else
101*de1e4e89SAndroid Build Coastguard Worker 		pr_out(">");
102*de1e4e89SAndroid Build Coastguard Worker }
103*de1e4e89SAndroid Build Coastguard Worker 
dev_print_fw(struct rd * rd,struct nlattr ** tb)104*de1e4e89SAndroid Build Coastguard Worker static void dev_print_fw(struct rd *rd, struct nlattr **tb)
105*de1e4e89SAndroid Build Coastguard Worker {
106*de1e4e89SAndroid Build Coastguard Worker 	const char *str;
107*de1e4e89SAndroid Build Coastguard Worker 	if (!tb[RDMA_NLDEV_ATTR_FW_VERSION])
108*de1e4e89SAndroid Build Coastguard Worker 		return;
109*de1e4e89SAndroid Build Coastguard Worker 
110*de1e4e89SAndroid Build Coastguard Worker 	str = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_FW_VERSION]);
111*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output)
112*de1e4e89SAndroid Build Coastguard Worker 		jsonw_string_field(rd->jw, "fw", str);
113*de1e4e89SAndroid Build Coastguard Worker 	else
114*de1e4e89SAndroid Build Coastguard Worker 		pr_out("fw %s ", str);
115*de1e4e89SAndroid Build Coastguard Worker }
116*de1e4e89SAndroid Build Coastguard Worker 
dev_print_node_guid(struct rd * rd,struct nlattr ** tb)117*de1e4e89SAndroid Build Coastguard Worker static void dev_print_node_guid(struct rd *rd, struct nlattr **tb)
118*de1e4e89SAndroid Build Coastguard Worker {
119*de1e4e89SAndroid Build Coastguard Worker 	uint64_t node_guid;
120*de1e4e89SAndroid Build Coastguard Worker 	uint16_t vp[4];
121*de1e4e89SAndroid Build Coastguard Worker 	char str[32];
122*de1e4e89SAndroid Build Coastguard Worker 
123*de1e4e89SAndroid Build Coastguard Worker 	if (!tb[RDMA_NLDEV_ATTR_NODE_GUID])
124*de1e4e89SAndroid Build Coastguard Worker 		return;
125*de1e4e89SAndroid Build Coastguard Worker 
126*de1e4e89SAndroid Build Coastguard Worker 	node_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_NODE_GUID]);
127*de1e4e89SAndroid Build Coastguard Worker 	memcpy(vp, &node_guid, sizeof(uint64_t));
128*de1e4e89SAndroid Build Coastguard Worker 	snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]);
129*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output)
130*de1e4e89SAndroid Build Coastguard Worker 		jsonw_string_field(rd->jw, "node_guid", str);
131*de1e4e89SAndroid Build Coastguard Worker 	else
132*de1e4e89SAndroid Build Coastguard Worker 		pr_out("node_guid %s ", str);
133*de1e4e89SAndroid Build Coastguard Worker }
134*de1e4e89SAndroid Build Coastguard Worker 
dev_print_sys_image_guid(struct rd * rd,struct nlattr ** tb)135*de1e4e89SAndroid Build Coastguard Worker static void dev_print_sys_image_guid(struct rd *rd, struct nlattr **tb)
136*de1e4e89SAndroid Build Coastguard Worker {
137*de1e4e89SAndroid Build Coastguard Worker 	uint64_t sys_image_guid;
138*de1e4e89SAndroid Build Coastguard Worker 	uint16_t vp[4];
139*de1e4e89SAndroid Build Coastguard Worker 	char str[32];
140*de1e4e89SAndroid Build Coastguard Worker 
141*de1e4e89SAndroid Build Coastguard Worker 	if (!tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID])
142*de1e4e89SAndroid Build Coastguard Worker 		return;
143*de1e4e89SAndroid Build Coastguard Worker 
144*de1e4e89SAndroid Build Coastguard Worker 	sys_image_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID]);
145*de1e4e89SAndroid Build Coastguard Worker 	memcpy(vp, &sys_image_guid, sizeof(uint64_t));
146*de1e4e89SAndroid Build Coastguard Worker 	snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]);
147*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output)
148*de1e4e89SAndroid Build Coastguard Worker 		jsonw_string_field(rd->jw, "sys_image_guid", str);
149*de1e4e89SAndroid Build Coastguard Worker 	else
150*de1e4e89SAndroid Build Coastguard Worker 		pr_out("sys_image_guid %s ", str);
151*de1e4e89SAndroid Build Coastguard Worker }
152*de1e4e89SAndroid Build Coastguard Worker 
node_type_to_str(uint8_t node_type)153*de1e4e89SAndroid Build Coastguard Worker static const char *node_type_to_str(uint8_t node_type)
154*de1e4e89SAndroid Build Coastguard Worker {
155*de1e4e89SAndroid Build Coastguard Worker 	static const char * const node_type_str[] = { "unknown", "ca",
156*de1e4e89SAndroid Build Coastguard Worker 						      "switch", "router",
157*de1e4e89SAndroid Build Coastguard Worker 						      "rnic", "usnic",
158*de1e4e89SAndroid Build Coastguard Worker 						      "usnic_dp" };
159*de1e4e89SAndroid Build Coastguard Worker 	if (node_type < ARRAY_SIZE(node_type_str))
160*de1e4e89SAndroid Build Coastguard Worker 		return node_type_str[node_type];
161*de1e4e89SAndroid Build Coastguard Worker 	return "unknown";
162*de1e4e89SAndroid Build Coastguard Worker }
163*de1e4e89SAndroid Build Coastguard Worker 
dev_print_node_type(struct rd * rd,struct nlattr ** tb)164*de1e4e89SAndroid Build Coastguard Worker static void dev_print_node_type(struct rd *rd, struct nlattr **tb)
165*de1e4e89SAndroid Build Coastguard Worker {
166*de1e4e89SAndroid Build Coastguard Worker 	const char *node_str;
167*de1e4e89SAndroid Build Coastguard Worker 	uint8_t node_type;
168*de1e4e89SAndroid Build Coastguard Worker 
169*de1e4e89SAndroid Build Coastguard Worker 	if (!tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE])
170*de1e4e89SAndroid Build Coastguard Worker 		return;
171*de1e4e89SAndroid Build Coastguard Worker 
172*de1e4e89SAndroid Build Coastguard Worker 	node_type = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE]);
173*de1e4e89SAndroid Build Coastguard Worker 	node_str = node_type_to_str(node_type);
174*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output)
175*de1e4e89SAndroid Build Coastguard Worker 		jsonw_string_field(rd->jw, "node_type", node_str);
176*de1e4e89SAndroid Build Coastguard Worker 	else
177*de1e4e89SAndroid Build Coastguard Worker 		pr_out("node_type %s ", node_str);
178*de1e4e89SAndroid Build Coastguard Worker }
179*de1e4e89SAndroid Build Coastguard Worker 
dev_parse_cb(const struct nlmsghdr * nlh,void * data)180*de1e4e89SAndroid Build Coastguard Worker static int dev_parse_cb(const struct nlmsghdr *nlh, void *data)
181*de1e4e89SAndroid Build Coastguard Worker {
182*de1e4e89SAndroid Build Coastguard Worker 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
183*de1e4e89SAndroid Build Coastguard Worker 	struct rd *rd = data;
184*de1e4e89SAndroid Build Coastguard Worker 	const char *name;
185*de1e4e89SAndroid Build Coastguard Worker 	uint32_t idx;
186*de1e4e89SAndroid Build Coastguard Worker 
187*de1e4e89SAndroid Build Coastguard Worker 	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
188*de1e4e89SAndroid Build Coastguard Worker 	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
189*de1e4e89SAndroid Build Coastguard Worker 		return MNL_CB_ERROR;
190*de1e4e89SAndroid Build Coastguard Worker 
191*de1e4e89SAndroid Build Coastguard Worker 	idx =  mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
192*de1e4e89SAndroid Build Coastguard Worker 	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
193*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output) {
194*de1e4e89SAndroid Build Coastguard Worker 		jsonw_uint_field(rd->jw, "ifindex", idx);
195*de1e4e89SAndroid Build Coastguard Worker 		jsonw_string_field(rd->jw, "ifname", name);
196*de1e4e89SAndroid Build Coastguard Worker 	} else {
197*de1e4e89SAndroid Build Coastguard Worker 		pr_out("%u: %s: ", idx, name);
198*de1e4e89SAndroid Build Coastguard Worker 	}
199*de1e4e89SAndroid Build Coastguard Worker 
200*de1e4e89SAndroid Build Coastguard Worker 	dev_print_node_type(rd, tb);
201*de1e4e89SAndroid Build Coastguard Worker 	dev_print_fw(rd, tb);
202*de1e4e89SAndroid Build Coastguard Worker 	dev_print_node_guid(rd, tb);
203*de1e4e89SAndroid Build Coastguard Worker 	dev_print_sys_image_guid(rd, tb);
204*de1e4e89SAndroid Build Coastguard Worker 	if (rd->show_details)
205*de1e4e89SAndroid Build Coastguard Worker 		dev_print_caps(rd, tb);
206*de1e4e89SAndroid Build Coastguard Worker 
207*de1e4e89SAndroid Build Coastguard Worker 	if (!rd->json_output)
208*de1e4e89SAndroid Build Coastguard Worker 		pr_out("\n");
209*de1e4e89SAndroid Build Coastguard Worker 	return MNL_CB_OK;
210*de1e4e89SAndroid Build Coastguard Worker }
211*de1e4e89SAndroid Build Coastguard Worker 
dev_no_args(struct rd * rd)212*de1e4e89SAndroid Build Coastguard Worker static int dev_no_args(struct rd *rd)
213*de1e4e89SAndroid Build Coastguard Worker {
214*de1e4e89SAndroid Build Coastguard Worker 	uint32_t seq;
215*de1e4e89SAndroid Build Coastguard Worker 	int ret;
216*de1e4e89SAndroid Build Coastguard Worker 
217*de1e4e89SAndroid Build Coastguard Worker 	rd_prepare_msg(rd, RDMA_NLDEV_CMD_GET,
218*de1e4e89SAndroid Build Coastguard Worker 		       &seq, (NLM_F_REQUEST | NLM_F_ACK));
219*de1e4e89SAndroid Build Coastguard Worker 	mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
220*de1e4e89SAndroid Build Coastguard Worker 	ret = rd_send_msg(rd);
221*de1e4e89SAndroid Build Coastguard Worker 	if (ret)
222*de1e4e89SAndroid Build Coastguard Worker 		return ret;
223*de1e4e89SAndroid Build Coastguard Worker 
224*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output)
225*de1e4e89SAndroid Build Coastguard Worker 		jsonw_start_object(rd->jw);
226*de1e4e89SAndroid Build Coastguard Worker 	ret = rd_recv_msg(rd, dev_parse_cb, rd, seq);
227*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output)
228*de1e4e89SAndroid Build Coastguard Worker 		jsonw_end_object(rd->jw);
229*de1e4e89SAndroid Build Coastguard Worker 	return ret;
230*de1e4e89SAndroid Build Coastguard Worker }
231*de1e4e89SAndroid Build Coastguard Worker 
dev_one_show(struct rd * rd)232*de1e4e89SAndroid Build Coastguard Worker static int dev_one_show(struct rd *rd)
233*de1e4e89SAndroid Build Coastguard Worker {
234*de1e4e89SAndroid Build Coastguard Worker 	const struct rd_cmd cmds[] = {
235*de1e4e89SAndroid Build Coastguard Worker 		{ NULL,		dev_no_args},
236*de1e4e89SAndroid Build Coastguard Worker 		{ 0 }
237*de1e4e89SAndroid Build Coastguard Worker 	};
238*de1e4e89SAndroid Build Coastguard Worker 
239*de1e4e89SAndroid Build Coastguard Worker 	return rd_exec_cmd(rd, cmds, "parameter");
240*de1e4e89SAndroid Build Coastguard Worker }
241*de1e4e89SAndroid Build Coastguard Worker 
dev_show(struct rd * rd)242*de1e4e89SAndroid Build Coastguard Worker static int dev_show(struct rd *rd)
243*de1e4e89SAndroid Build Coastguard Worker {
244*de1e4e89SAndroid Build Coastguard Worker 	struct dev_map *dev_map;
245*de1e4e89SAndroid Build Coastguard Worker 	int ret = 0;
246*de1e4e89SAndroid Build Coastguard Worker 
247*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output)
248*de1e4e89SAndroid Build Coastguard Worker 		jsonw_start_array(rd->jw);
249*de1e4e89SAndroid Build Coastguard Worker 	if (rd_no_arg(rd)) {
250*de1e4e89SAndroid Build Coastguard Worker 		list_for_each_entry(dev_map, &rd->dev_map_list, list) {
251*de1e4e89SAndroid Build Coastguard Worker 			rd->dev_idx = dev_map->idx;
252*de1e4e89SAndroid Build Coastguard Worker 			ret = dev_one_show(rd);
253*de1e4e89SAndroid Build Coastguard Worker 			if (ret)
254*de1e4e89SAndroid Build Coastguard Worker 				goto out;
255*de1e4e89SAndroid Build Coastguard Worker 		}
256*de1e4e89SAndroid Build Coastguard Worker 	} else {
257*de1e4e89SAndroid Build Coastguard Worker 		dev_map = dev_map_lookup(rd, false);
258*de1e4e89SAndroid Build Coastguard Worker 		if (!dev_map) {
259*de1e4e89SAndroid Build Coastguard Worker 			pr_err("Wrong device name\n");
260*de1e4e89SAndroid Build Coastguard Worker 			ret = -ENOENT;
261*de1e4e89SAndroid Build Coastguard Worker 			goto out;
262*de1e4e89SAndroid Build Coastguard Worker 		}
263*de1e4e89SAndroid Build Coastguard Worker 		rd_arg_inc(rd);
264*de1e4e89SAndroid Build Coastguard Worker 		rd->dev_idx = dev_map->idx;
265*de1e4e89SAndroid Build Coastguard Worker 		ret = dev_one_show(rd);
266*de1e4e89SAndroid Build Coastguard Worker 	}
267*de1e4e89SAndroid Build Coastguard Worker out:
268*de1e4e89SAndroid Build Coastguard Worker 	if (rd->json_output)
269*de1e4e89SAndroid Build Coastguard Worker 		jsonw_end_array(rd->jw);
270*de1e4e89SAndroid Build Coastguard Worker 	return ret;
271*de1e4e89SAndroid Build Coastguard Worker }
272*de1e4e89SAndroid Build Coastguard Worker 
cmd_dev(struct rd * rd)273*de1e4e89SAndroid Build Coastguard Worker int cmd_dev(struct rd *rd)
274*de1e4e89SAndroid Build Coastguard Worker {
275*de1e4e89SAndroid Build Coastguard Worker 	const struct rd_cmd cmds[] = {
276*de1e4e89SAndroid Build Coastguard Worker 		{ NULL,		dev_show },
277*de1e4e89SAndroid Build Coastguard Worker 		{ "show",	dev_show },
278*de1e4e89SAndroid Build Coastguard Worker 		{ "list",	dev_show },
279*de1e4e89SAndroid Build Coastguard Worker 		{ "help",	dev_help },
280*de1e4e89SAndroid Build Coastguard Worker 		{ 0 }
281*de1e4e89SAndroid Build Coastguard Worker 	};
282*de1e4e89SAndroid Build Coastguard Worker 
283*de1e4e89SAndroid Build Coastguard Worker 	return rd_exec_cmd(rd, cmds, "dev command");
284*de1e4e89SAndroid Build Coastguard Worker }
285