xref: /openbmc/ipmitool/lib/ipmi_vita.c (revision c04aa9bb)
1f1c6118cSZdenek Styblik /*
2f1c6118cSZdenek Styblik  * Copyright (c) 2014 Pigeon Point Systems. All right reserved
3f1c6118cSZdenek Styblik  *
4f1c6118cSZdenek Styblik  * Redistribution and use in source and binary forms, with or without
5f1c6118cSZdenek Styblik  * modification, are permitted provided that the following conditions
6f1c6118cSZdenek Styblik  * are met:
7f1c6118cSZdenek Styblik  *
8f1c6118cSZdenek Styblik  * Redistribution of source code must retain the above copyright
9f1c6118cSZdenek Styblik  * notice, this list of conditions and the following disclaimer.
10f1c6118cSZdenek Styblik  *
11f1c6118cSZdenek Styblik  * Redistribution in binary form must reproduce the above copyright
12f1c6118cSZdenek Styblik  * notice, this list of conditions and the following disclaimer in the
13f1c6118cSZdenek Styblik  * documentation and/or other materials provided with the distribution.
14f1c6118cSZdenek Styblik  *
15f1c6118cSZdenek Styblik  * Neither the name of Pigeon Point Systems, or the names of
16f1c6118cSZdenek Styblik  * contributors may be used to endorse or promote products derived
17f1c6118cSZdenek Styblik  * from this software without specific prior written permission.
18f1c6118cSZdenek Styblik  *
19f1c6118cSZdenek Styblik  * This software is provided "AS IS, " without a warranty of any kind.
20f1c6118cSZdenek Styblik  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21f1c6118cSZdenek Styblik  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22f1c6118cSZdenek Styblik  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23f1c6118cSZdenek Styblik  * PIGEON POINT SYSTEMS ("PPS") AND ITS LICENSORS SHALL NOT BE LIABLE
24f1c6118cSZdenek Styblik  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25f1c6118cSZdenek Styblik  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26f1c6118cSZdenek Styblik  * PPS OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27f1c6118cSZdenek Styblik  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28f1c6118cSZdenek Styblik  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29f1c6118cSZdenek Styblik  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30f1c6118cSZdenek Styblik  * EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31f1c6118cSZdenek Styblik  */
32f1c6118cSZdenek Styblik 
33f1c6118cSZdenek Styblik 
34f1c6118cSZdenek Styblik #include <ipmitool/ipmi_intf.h>
35f1c6118cSZdenek Styblik #include <ipmitool/ipmi_picmg.h>
36f1c6118cSZdenek Styblik #include <ipmitool/ipmi_vita.h>
37f1c6118cSZdenek Styblik #include <ipmitool/ipmi_fru.h>
38f1c6118cSZdenek Styblik #include <ipmitool/ipmi_strings.h>
39f1c6118cSZdenek Styblik #include <ipmitool/log.h>
40f1c6118cSZdenek Styblik 
41f1c6118cSZdenek Styblik /* Handled VITA 46.11 commands */
42f1c6118cSZdenek Styblik #define VITA_CMD_HELP		0
43f1c6118cSZdenek Styblik #define VITA_CMD_PROPERTIES	1
44f1c6118cSZdenek Styblik #define VITA_CMD_FRUCONTROL	2
45f1c6118cSZdenek Styblik #define VITA_CMD_ADDRINFO	3
46f1c6118cSZdenek Styblik #define VITA_CMD_ACTIVATE	4
47f1c6118cSZdenek Styblik #define VITA_CMD_DEACTIVATE	5
48f1c6118cSZdenek Styblik #define VITA_CMD_POLICY_GET	6
49f1c6118cSZdenek Styblik #define VITA_CMD_POLICY_SET	7
50f1c6118cSZdenek Styblik #define VITA_CMD_LED_PROP	8
51f1c6118cSZdenek Styblik #define VITA_CMD_LED_CAP	9
52f1c6118cSZdenek Styblik #define VITA_CMD_LED_GET	10
53f1c6118cSZdenek Styblik #define VITA_CMD_LED_SET	11
54f1c6118cSZdenek Styblik #define VITA_CMD_UNKNOWN	255
55f1c6118cSZdenek Styblik 
56f1c6118cSZdenek Styblik /* VITA 46.11 Site Type strings */
57f1c6118cSZdenek Styblik static struct valstr vita_site_types[] = {
58f1c6118cSZdenek Styblik 	{ VITA_FRONT_VPX_MODULE, "Front Loading VPX Plug-In Module" },
59f1c6118cSZdenek Styblik 	{ VITA_POWER_ENTRY, "Power Entry Module" },
60f1c6118cSZdenek Styblik 	{ VITA_CHASSIS_FRU, "Chassic FRU Information Module" },
61f1c6118cSZdenek Styblik 	{ VITA_DEDICATED_CHMC, "Dedicated Chassis Manager" },
62f1c6118cSZdenek Styblik 	{ VITA_FAN_TRAY, "Fan Tray" },
63f1c6118cSZdenek Styblik 	{ VITA_FAN_TRAY_FILTER, "Fan Tray Filter" },
64f1c6118cSZdenek Styblik 	{ VITA_ALARM_PANEL, "Alarm Panel" },
65f1c6118cSZdenek Styblik 	{ VITA_XMC, "XMC" },
66f1c6118cSZdenek Styblik 	{ VITA_VPX_RTM, "VPX Rear Transition Module" },
67f1c6118cSZdenek Styblik 	{ VITA_FRONT_VME_MODULE, "Front Loading VME Plug-In Module" },
68f1c6118cSZdenek Styblik 	{ VITA_FRONT_VXS_MODULE, "Front Loading VXS Plug-In Module" },
69f1c6118cSZdenek Styblik 	{ VITA_POWER_SUPPLY, "Power Supply" },
70f1c6118cSZdenek Styblik 	{ VITA_FRONT_VITA62_MODULE, "Front Loading VITA 62 Module\n" },
71f1c6118cSZdenek Styblik 	{ VITA_71_MODULE, "VITA 71 Module\n" },
72f1c6118cSZdenek Styblik 	{ VITA_FMC, "FMC\n" },
73f1c6118cSZdenek Styblik 	{ 0, NULL }
74f1c6118cSZdenek Styblik };
75f1c6118cSZdenek Styblik 
76f1c6118cSZdenek Styblik /* VITA 46.11 command help strings */
77f1c6118cSZdenek Styblik static struct valstr vita_help_strings[] = {
78f1c6118cSZdenek Styblik 	{
79f1c6118cSZdenek Styblik 		VITA_CMD_HELP,
80f1c6118cSZdenek Styblik 		"VITA commands:\n"
81f1c6118cSZdenek Styblik 		"    properties        - get VSO properties\n"
82f1c6118cSZdenek Styblik 		"    frucontrol        - FRU control\n"
83f1c6118cSZdenek Styblik 		"    addrinfo          - get address information\n"
84f1c6118cSZdenek Styblik 		"    activate          - activate a FRU\n"
85f1c6118cSZdenek Styblik 		"    deactivate        - deactivate a FRU\n"
86f1c6118cSZdenek Styblik 		"    policy get        - get the FRU activation policy\n"
87f1c6118cSZdenek Styblik 		"    policy set        - set the FRU activation policy\n"
88f1c6118cSZdenek Styblik 		"    led prop          - get led properties\n"
89f1c6118cSZdenek Styblik 		"    led cap           - get led color capabilities\n"
90f1c6118cSZdenek Styblik 		"    led get           - get led state\n"
91f1c6118cSZdenek Styblik 		"    led set           - set led state"
92f1c6118cSZdenek Styblik 	},
93f1c6118cSZdenek Styblik 	{
94f1c6118cSZdenek Styblik 		VITA_CMD_FRUCONTROL,
95f1c6118cSZdenek Styblik 		"usage: frucontrol <FRU-ID> <OPTION>\n"
96f1c6118cSZdenek Styblik 		"    OPTION: 0 - Cold Reset\n"
97f1c6118cSZdenek Styblik 		"            1 - Warm Reset\n"
98f1c6118cSZdenek Styblik 		"            2 - Graceful Reboot\n"
99f1c6118cSZdenek Styblik 		"            3 - Issue Diagnostic Interrupt"
100f1c6118cSZdenek Styblik 	},
101f1c6118cSZdenek Styblik 	{
102f1c6118cSZdenek Styblik 		VITA_CMD_ADDRINFO,
103f1c6118cSZdenek Styblik 		"usage: addrinfo [<FRU-ID>]"
104f1c6118cSZdenek Styblik 	},
105f1c6118cSZdenek Styblik 	{
106f1c6118cSZdenek Styblik 		VITA_CMD_ACTIVATE,
107f1c6118cSZdenek Styblik 		"usage: activate <FRU-ID>"
108f1c6118cSZdenek Styblik 	},
109f1c6118cSZdenek Styblik 	{
110f1c6118cSZdenek Styblik 		VITA_CMD_DEACTIVATE,
111f1c6118cSZdenek Styblik 		"usage: deactivate <FRU-ID>"
112f1c6118cSZdenek Styblik 	},
113f1c6118cSZdenek Styblik     	{
114f1c6118cSZdenek Styblik 		VITA_CMD_POLICY_GET,
115f1c6118cSZdenek Styblik 		"usage: policy get <FRU-ID>"
116f1c6118cSZdenek Styblik 	},
117f1c6118cSZdenek Styblik 	{
118f1c6118cSZdenek Styblik 		VITA_CMD_POLICY_SET,
119f1c6118cSZdenek Styblik 		"usage: policy set <FRU-ID> <MASK> <VALUE>\n"
120f1c6118cSZdenek Styblik 		"    MASK:  [3] affect the Default-Activation-Locked Policy Bit\n"
121f1c6118cSZdenek Styblik 		"           [2] affect the Commanded-Deactivation-Ignored Policy Bit\n"
122f1c6118cSZdenek Styblik 		"           [1] affect the Deactivation-Locked Policy Bit\n"
123f1c6118cSZdenek Styblik 		"           [0] affect the Activation-Locked Policy Bit\n"
124f1c6118cSZdenek Styblik 		"    VALUE: [3] value for the Default-Activation-Locked Policy Bit\n"
125f1c6118cSZdenek Styblik 		"           [2] value for the Commanded-Deactivation-Ignored Policy Bit\n"
126f1c6118cSZdenek Styblik 		"           [1] value for the Deactivation-Locked Policy Bit\n"
127f1c6118cSZdenek Styblik 		"           [0] value for the Activation-Locked Policy Bit"
128f1c6118cSZdenek Styblik 	},
129f1c6118cSZdenek Styblik 	{
130f1c6118cSZdenek Styblik 		VITA_CMD_LED_PROP,
131f1c6118cSZdenek Styblik 		"usage: led prop <FRU-ID>"
132f1c6118cSZdenek Styblik 	},
133f1c6118cSZdenek Styblik 	{
134f1c6118cSZdenek Styblik 		VITA_CMD_LED_CAP,
135f1c6118cSZdenek Styblik 		"usage: led cap <FRU-ID> <LED-ID"
136f1c6118cSZdenek Styblik 	},
137f1c6118cSZdenek Styblik 	{
138f1c6118cSZdenek Styblik 		VITA_CMD_LED_GET,
139f1c6118cSZdenek Styblik 		"usage: led get <FRU-ID> <LED-ID",
140f1c6118cSZdenek Styblik 	},
141f1c6118cSZdenek Styblik 	{
142f1c6118cSZdenek Styblik 		VITA_CMD_LED_SET,
143f1c6118cSZdenek Styblik 		"usage: led set <FRU-ID> <LED-ID> <FUNCTION> <DURATION> <COLOR>\n"
144f1c6118cSZdenek Styblik 		"    <FRU-ID>\n"
145f1c6118cSZdenek Styblik 		"    <LED-ID>   0-0xFE:    Specified LED\n"
146f1c6118cSZdenek Styblik 		"               0xFF:      All LEDs under management control\n"
147f1c6118cSZdenek Styblik 		"    <FUNCTION> 0:       LED OFF override\n"
148f1c6118cSZdenek Styblik 		"               1 - 250: LED blinking override (off duration)\n"
149f1c6118cSZdenek Styblik 		"               251:     LED Lamp Test\n"
150f1c6118cSZdenek Styblik 		"               252:     LED restore to local control\n"
151f1c6118cSZdenek Styblik 		"               255:     LED ON override\n"
152f1c6118cSZdenek Styblik 		"    <DURATION> 1 - 127: LED Lamp Test / on duration\n"
153f1c6118cSZdenek Styblik 		"    <COLOR>    1:   BLUE\n"
154f1c6118cSZdenek Styblik 		"               2:   RED\n"
155f1c6118cSZdenek Styblik 		"               3:   GREEN\n"
156f1c6118cSZdenek Styblik 		"               4:   AMBER\n"
157f1c6118cSZdenek Styblik 		"               5:   ORANGE\n"
158f1c6118cSZdenek Styblik 		"               6:   WHITE\n"
159f1c6118cSZdenek Styblik 		"               0xE: do not change\n"
160f1c6118cSZdenek Styblik 		"               0xF: use default color"
161f1c6118cSZdenek Styblik 	},
162f1c6118cSZdenek Styblik 	{
163f1c6118cSZdenek Styblik 		VITA_CMD_UNKNOWN,
164f1c6118cSZdenek Styblik 		"Unknown command"
165f1c6118cSZdenek Styblik 	},
166f1c6118cSZdenek Styblik 	{ 0, NULL }
167f1c6118cSZdenek Styblik };
168f1c6118cSZdenek Styblik 
169f1c6118cSZdenek Styblik /* check if VITA 46.11 is supported */
170f1c6118cSZdenek Styblik uint8_t
vita_discover(struct ipmi_intf * intf)171f1c6118cSZdenek Styblik vita_discover(struct ipmi_intf *intf)
172f1c6118cSZdenek Styblik {
173f1c6118cSZdenek Styblik 	struct ipmi_rq req;
174f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
175f1c6118cSZdenek Styblik 	unsigned char msg_data;
176f1c6118cSZdenek Styblik 	int vita_avail = 0;
177f1c6118cSZdenek Styblik 
178f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
179f1c6118cSZdenek Styblik 
180f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
181f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
182f1c6118cSZdenek Styblik 	req.msg.data = &msg_data;
183f1c6118cSZdenek Styblik 	req.msg.data_len = 1;
184f1c6118cSZdenek Styblik 
185f1c6118cSZdenek Styblik 	msg_data = GROUP_EXT_VITA;
186f1c6118cSZdenek Styblik 
187f1c6118cSZdenek Styblik 	lprintf(LOG_INFO, "Running Get VSO Capabilities my_addr %#x, "
188f1c6118cSZdenek Styblik 		"transit %#x, target %#x",
189f1c6118cSZdenek Styblik 		intf->my_addr, intf->transit_addr, intf->target_addr);
190f1c6118cSZdenek Styblik 
191f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
192f1c6118cSZdenek Styblik 
193f1c6118cSZdenek Styblik 	if (rsp == NULL) {
194f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received");
195372b458eSZdenek Styblik 	} else if (rsp->ccode == 0xC1) {
196*c04aa9bbSZdenek Styblik 		lprintf(LOG_INFO, "Invalid completion code received: %s",
197372b458eSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
198329281bbSZdenek Styblik 	} else if (rsp->ccode == 0xCC) {
199329281bbSZdenek Styblik 		lprintf(LOG_INFO, "Invalid data field received: %s",
200329281bbSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
201f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
202*c04aa9bbSZdenek Styblik 		lprintf(LOG_INFO, "Invalid completion code received: %s",
203f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
204f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 5) {
205*c04aa9bbSZdenek Styblik 		lprintf(LOG_INFO, "Invalid response length %d",
206f1c6118cSZdenek Styblik 			rsp->data_len);
207f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
208*c04aa9bbSZdenek Styblik 		lprintf(LOG_INFO, "Invalid group extension %#x",
209f1c6118cSZdenek Styblik 			rsp->data[0]);
210f1c6118cSZdenek Styblik 	} else if ((rsp->data[3] & 0x03) != 0) {
211*c04aa9bbSZdenek Styblik 		lprintf(LOG_INFO, "Unknown VSO Standard %d",
212f1c6118cSZdenek Styblik 			(rsp->data[3] & 0x03));
213f1c6118cSZdenek Styblik 	} else if ((rsp->data[4] & 0x0F) != 1) {
214*c04aa9bbSZdenek Styblik 		lprintf(LOG_INFO, "Unknown VSO Specification Revision %d.%d",
215f1c6118cSZdenek Styblik 			(rsp->data[4] & 0x0F), (rsp->data[4] >> 4));
216f1c6118cSZdenek Styblik 	} else {
217f1c6118cSZdenek Styblik 		vita_avail = 1;
218f1c6118cSZdenek Styblik 		lprintf(LOG_INFO, "Discovered VITA 46.11 Revision %d.%d",
219f1c6118cSZdenek Styblik 			(rsp->data[4] & 0x0F), (rsp->data[4] >> 4));
220f1c6118cSZdenek Styblik 	}
221f1c6118cSZdenek Styblik 
222f1c6118cSZdenek Styblik 	return vita_avail;
223f1c6118cSZdenek Styblik }
224f1c6118cSZdenek Styblik 
225f1c6118cSZdenek Styblik uint8_t
ipmi_vita_ipmb_address(struct ipmi_intf * intf)226f1c6118cSZdenek Styblik ipmi_vita_ipmb_address(struct ipmi_intf *intf)
227f1c6118cSZdenek Styblik {
228f1c6118cSZdenek Styblik 	struct ipmi_rq req;
229f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
230f1c6118cSZdenek Styblik 	unsigned char msg_data;
231f1c6118cSZdenek Styblik 
232f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
233f1c6118cSZdenek Styblik 
234f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
235f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
236f1c6118cSZdenek Styblik 	req.msg.data = &msg_data;
237f1c6118cSZdenek Styblik 	req.msg.data_len = 1;
238f1c6118cSZdenek Styblik 
239f1c6118cSZdenek Styblik 	msg_data = GROUP_EXT_VITA;
240f1c6118cSZdenek Styblik 
241f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
242f1c6118cSZdenek Styblik 
243f1c6118cSZdenek Styblik 	if (rsp == NULL) {
244f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received");
245f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
246f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
247f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
248f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 7) {
249f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d",
250f1c6118cSZdenek Styblik 			rsp->data_len);
251f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
252f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x",
253f1c6118cSZdenek Styblik 			rsp->data[0]);
254f1c6118cSZdenek Styblik 	} else {
255f1c6118cSZdenek Styblik 		return rsp->data[2];
256f1c6118cSZdenek Styblik 	}
257f1c6118cSZdenek Styblik 
258f1c6118cSZdenek Styblik 	return 0;
259f1c6118cSZdenek Styblik }
260f1c6118cSZdenek Styblik 
261f1c6118cSZdenek Styblik static int
ipmi_vita_getaddr(struct ipmi_intf * intf,int argc,char ** argv)262f1c6118cSZdenek Styblik ipmi_vita_getaddr(struct ipmi_intf *intf, int argc, char **argv)
263f1c6118cSZdenek Styblik {
264f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
265f1c6118cSZdenek Styblik 	struct ipmi_rq req;
266f1c6118cSZdenek Styblik 	unsigned char msg_data[2];
267f1c6118cSZdenek Styblik 
268f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
269f1c6118cSZdenek Styblik 
270f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
271f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
272f1c6118cSZdenek Styblik 	req.msg.data = msg_data;
273f1c6118cSZdenek Styblik 	req.msg.data_len = 2;
274f1c6118cSZdenek Styblik 
275f1c6118cSZdenek Styblik 	msg_data[0] = GROUP_EXT_VITA;		/* VITA identifier */
276f1c6118cSZdenek Styblik 	msg_data[1] = 0;			/* default FRU ID */
277f1c6118cSZdenek Styblik 
278f1c6118cSZdenek Styblik 	if (argc > 0) {
279f1c6118cSZdenek Styblik 		/* validate and get FRU Device ID */
280f1c6118cSZdenek Styblik 		if (is_fru_id(argv[0], &msg_data[1]) != 0) {
281f1c6118cSZdenek Styblik 			return -1;
282f1c6118cSZdenek Styblik 		}
283f1c6118cSZdenek Styblik 	}
284f1c6118cSZdenek Styblik 
285f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
286f1c6118cSZdenek Styblik 
287f1c6118cSZdenek Styblik 	if (rsp == NULL) {
288f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received");
289f1c6118cSZdenek Styblik 		return -1;
290f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
291f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
292f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
293f1c6118cSZdenek Styblik 		return -1;
294f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 7) {
295f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d",
296f1c6118cSZdenek Styblik 			rsp->data_len);
297f1c6118cSZdenek Styblik 		return -1;
298f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
299f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x",
300f1c6118cSZdenek Styblik 			rsp->data[0]);
301f1c6118cSZdenek Styblik 		return -1;
302f1c6118cSZdenek Styblik 	}
303f1c6118cSZdenek Styblik 
304f1c6118cSZdenek Styblik 	printf("Hardware Address : 0x%02x\n", rsp->data[1]);
305f1c6118cSZdenek Styblik 	printf("IPMB-0 Address   : 0x%02x\n", rsp->data[2]);
306f1c6118cSZdenek Styblik 	printf("FRU ID           : 0x%02x\n", rsp->data[4]);
307f1c6118cSZdenek Styblik 	printf("Site ID          : 0x%02x\n", rsp->data[5]);
308f1c6118cSZdenek Styblik 	printf("Site Type        : %s\n", val2str(rsp->data[6],
309f1c6118cSZdenek Styblik 		vita_site_types));
310f1c6118cSZdenek Styblik 	if (rsp->data_len > 8) {
311f1c6118cSZdenek Styblik 		printf("Channel 7 Address: 0x%02x\n", rsp->data[8]);
312f1c6118cSZdenek Styblik 	}
313f1c6118cSZdenek Styblik 
314f1c6118cSZdenek Styblik 	return 0;
315f1c6118cSZdenek Styblik }
316f1c6118cSZdenek Styblik 
317f1c6118cSZdenek Styblik static int
ipmi_vita_get_vso_capabilities(struct ipmi_intf * intf)318f1c6118cSZdenek Styblik ipmi_vita_get_vso_capabilities(struct ipmi_intf *intf)
319f1c6118cSZdenek Styblik {
320f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
321f1c6118cSZdenek Styblik 	struct ipmi_rq req;
322f1c6118cSZdenek Styblik 	unsigned char msg_data, tmp;
323f1c6118cSZdenek Styblik 
324f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
325f1c6118cSZdenek Styblik 
326f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
327f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
328f1c6118cSZdenek Styblik 	req.msg.data = &msg_data;
329f1c6118cSZdenek Styblik 	req.msg.data_len = 1;
330f1c6118cSZdenek Styblik 
331f1c6118cSZdenek Styblik 	msg_data = GROUP_EXT_VITA;		/* VITA identifier */
332f1c6118cSZdenek Styblik 
333f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
334f1c6118cSZdenek Styblik 
335f1c6118cSZdenek Styblik 	if (rsp == NULL) {
336f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received.");
337f1c6118cSZdenek Styblik 		return -1;
338f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
339f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
340f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
341f1c6118cSZdenek Styblik 		return -1;
342f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 5) {
343f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
344f1c6118cSZdenek Styblik 		return -1;
345f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
346f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
347f1c6118cSZdenek Styblik 		return -1;
348f1c6118cSZdenek Styblik 	}
349f1c6118cSZdenek Styblik 
350f1c6118cSZdenek Styblik 	printf("VSO Identifier    : 0x%02x\n", rsp->data[0]);
351f1c6118cSZdenek Styblik 	printf("IPMC Identifier   : 0x%02x\n", rsp->data[1]);
352f1c6118cSZdenek Styblik 	printf("    Tier  %d\n", (rsp->data[1] & 0x03) + 1);
353f1c6118cSZdenek Styblik 	printf("    Layer %d\n", ((rsp->data[1] & 0x30) >> 4) + 1);
354f1c6118cSZdenek Styblik 
355f1c6118cSZdenek Styblik 	printf("IPMB Capabilities : 0x%02x\n", rsp->data[2]);
356f1c6118cSZdenek Styblik 
357f1c6118cSZdenek Styblik 	tmp = (rsp->data[2] & 0x30) >> 4;
358f1c6118cSZdenek Styblik 
359f1c6118cSZdenek Styblik 	printf("    Frequency  %skHz\n",
360f1c6118cSZdenek Styblik 		tmp == 0 ? "100" : tmp == 1 ? "400" : "RESERVED");
361f1c6118cSZdenek Styblik 
362f1c6118cSZdenek Styblik 	tmp = rsp->data[2] & 3;
363f1c6118cSZdenek Styblik 
364f1c6118cSZdenek Styblik 	if (tmp == 1) {
365f1c6118cSZdenek Styblik 		printf("    2 IPMB interfaces supported\n");
366f1c6118cSZdenek Styblik 	} else if (tmp == 0) {
367f1c6118cSZdenek Styblik 		printf("    1 IPMB interface supported\n");
368f1c6118cSZdenek Styblik 	}
369f1c6118cSZdenek Styblik 
370f1c6118cSZdenek Styblik 	printf("VSO Standard      : %s\n",
371f1c6118cSZdenek Styblik 		(rsp->data[3] & 0x3) == 0 ? "VITA 46.11" : "RESERVED");
372f1c6118cSZdenek Styblik 
373f1c6118cSZdenek Styblik 	printf("VSO Spec Revision : %d.%d\n", rsp->data[4] & 0xf,
374f1c6118cSZdenek Styblik 		rsp->data[4] >> 4);
375f1c6118cSZdenek Styblik 
376f1c6118cSZdenek Styblik 	printf("Max FRU Device ID : 0x%02x\n", rsp->data[5]);
377f1c6118cSZdenek Styblik 	printf("FRU Device ID     : 0x%02x\n", rsp->data[6]);
378f1c6118cSZdenek Styblik 
379f1c6118cSZdenek Styblik 	return 0;
380f1c6118cSZdenek Styblik }
381f1c6118cSZdenek Styblik 
382f1c6118cSZdenek Styblik static int
ipmi_vita_set_fru_activation(struct ipmi_intf * intf,char ** argv,unsigned char command)383f1c6118cSZdenek Styblik ipmi_vita_set_fru_activation(struct ipmi_intf *intf,
384f1c6118cSZdenek Styblik 	char **argv, unsigned char command)
385f1c6118cSZdenek Styblik {
386f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
387f1c6118cSZdenek Styblik 	struct ipmi_rq req;
388f1c6118cSZdenek Styblik 	unsigned char msg_data[3];
389f1c6118cSZdenek Styblik 
390f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
391f1c6118cSZdenek Styblik 
392f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
393f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_SET_FRU_ACTIVATION_CMD;
394f1c6118cSZdenek Styblik 	req.msg.data = msg_data;
395f1c6118cSZdenek Styblik 	req.msg.data_len = 3;
396f1c6118cSZdenek Styblik 
397f1c6118cSZdenek Styblik 	msg_data[0]	= GROUP_EXT_VITA;		/* VITA identifier */
398f1c6118cSZdenek Styblik 	if (is_fru_id(argv[0], &msg_data[1]) != 0) {	/* FRU ID */
399f1c6118cSZdenek Styblik 		return -1;
400f1c6118cSZdenek Styblik 	}
401f1c6118cSZdenek Styblik 	msg_data[2]	= command;			/* command */
402f1c6118cSZdenek Styblik 
403f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
404f1c6118cSZdenek Styblik 
405f1c6118cSZdenek Styblik 	if (rsp == NULL) {
406f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received.");
407f1c6118cSZdenek Styblik 		return -1;
408f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
409f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
410f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
411f1c6118cSZdenek Styblik 		return -1;
412f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 1) {
413f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
414f1c6118cSZdenek Styblik 		return -1;
415f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
416f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
417f1c6118cSZdenek Styblik 		return -1;
418f1c6118cSZdenek Styblik 	}
419f1c6118cSZdenek Styblik 
420f1c6118cSZdenek Styblik 	printf("FRU has been successfully %s\n",
421f1c6118cSZdenek Styblik 		command ? "activated" : "deactivated");
422f1c6118cSZdenek Styblik 
423f1c6118cSZdenek Styblik 	return 0;
424f1c6118cSZdenek Styblik }
425f1c6118cSZdenek Styblik 
426f1c6118cSZdenek Styblik static int
ipmi_vita_get_fru_state_policy_bits(struct ipmi_intf * intf,char ** argv)427f1c6118cSZdenek Styblik ipmi_vita_get_fru_state_policy_bits(struct ipmi_intf *intf, char **argv)
428f1c6118cSZdenek Styblik {
429f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
430f1c6118cSZdenek Styblik 	struct ipmi_rq req;
431f1c6118cSZdenek Styblik 	unsigned char msg_data[2];
432f1c6118cSZdenek Styblik 
433f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
434f1c6118cSZdenek Styblik 
435f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
436f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_GET_FRU_STATE_POLICY_BITS_CMD;
437f1c6118cSZdenek Styblik 	req.msg.data = msg_data;
438f1c6118cSZdenek Styblik 	req.msg.data_len = 2;
439f1c6118cSZdenek Styblik 
440f1c6118cSZdenek Styblik 	msg_data[0] = GROUP_EXT_VITA;			/* VITA identifier */
441f1c6118cSZdenek Styblik 	if (is_fru_id(argv[0], &msg_data[1]) != 0) {	/* FRU ID */
442f1c6118cSZdenek Styblik 		return -1;
443f1c6118cSZdenek Styblik 	}
444f1c6118cSZdenek Styblik 
445f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
446f1c6118cSZdenek Styblik 
447f1c6118cSZdenek Styblik 	if (rsp == NULL) {
448f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received.");
449f1c6118cSZdenek Styblik 		return -1;
450f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
451f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
452f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
453f1c6118cSZdenek Styblik 		return -1;
454f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 2) {
455f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
456f1c6118cSZdenek Styblik 		return -1;
457f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
458f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
459f1c6118cSZdenek Styblik 		return -1;
460f1c6118cSZdenek Styblik 	}
461f1c6118cSZdenek Styblik 
462f1c6118cSZdenek Styblik 	printf("FRU State Policy Bits:	%xh\n", rsp->data[1]);
463f1c6118cSZdenek Styblik 	printf("    Default-Activation-Locked Policy Bit is %d\n",
464f1c6118cSZdenek Styblik 		rsp->data[1] & 0x08 ? 1 : 0);
465f1c6118cSZdenek Styblik 	printf("    Commanded-Deactivation-Ignored Policy Bit is %d\n",
466f1c6118cSZdenek Styblik 		rsp->data[1] & 0x04 ? 1 : 0);
467f1c6118cSZdenek Styblik 	printf("    Deactivation-Locked Policy Bit is %d\n",
468f1c6118cSZdenek Styblik 		rsp->data[1] & 0x02 ? 1 : 0);
469f1c6118cSZdenek Styblik 	printf("    Activation-Locked Policy Bit is %d\n",
470f1c6118cSZdenek Styblik 		rsp->data[1] & 0x01);
471f1c6118cSZdenek Styblik 
472f1c6118cSZdenek Styblik 	return 0;
473f1c6118cSZdenek Styblik }
474f1c6118cSZdenek Styblik 
475f1c6118cSZdenek Styblik static int
ipmi_vita_set_fru_state_policy_bits(struct ipmi_intf * intf,char ** argv)476f1c6118cSZdenek Styblik ipmi_vita_set_fru_state_policy_bits(struct ipmi_intf *intf, char **argv)
477f1c6118cSZdenek Styblik {
478f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
479f1c6118cSZdenek Styblik 	struct ipmi_rq req;
480f1c6118cSZdenek Styblik 	unsigned char msg_data[4];
481f1c6118cSZdenek Styblik 
482f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
483f1c6118cSZdenek Styblik 
484f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
485f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_SET_FRU_STATE_POLICY_BITS_CMD;
486f1c6118cSZdenek Styblik 	req.msg.data = msg_data;
487f1c6118cSZdenek Styblik 	req.msg.data_len = 4;
488f1c6118cSZdenek Styblik 
489f1c6118cSZdenek Styblik 	msg_data[0] = GROUP_EXT_VITA;			/* VITA identifier */
490f1c6118cSZdenek Styblik 	if (is_fru_id(argv[0], &msg_data[1]) != 0) {	/* FRU ID */
491f1c6118cSZdenek Styblik 		return -1;
492f1c6118cSZdenek Styblik 	}
493f1c6118cSZdenek Styblik 	if (str2uchar(argv[1], &msg_data[2]) != 0) {	/* bits mask */
494f1c6118cSZdenek Styblik 		return -1;
495f1c6118cSZdenek Styblik 	}
496f1c6118cSZdenek Styblik 	if (str2uchar(argv[2], &msg_data[3]) != 0) {	/* bits */
497f1c6118cSZdenek Styblik 		return -1;
498f1c6118cSZdenek Styblik 	}
499f1c6118cSZdenek Styblik 
500f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
501f1c6118cSZdenek Styblik 
502f1c6118cSZdenek Styblik 	if (rsp == NULL) {
503f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received.");
504f1c6118cSZdenek Styblik 		return -1;
505f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
506f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
507f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
508f1c6118cSZdenek Styblik 		return -1;
509f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 1) {
510f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
511f1c6118cSZdenek Styblik 		return -1;
512f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
513f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
514f1c6118cSZdenek Styblik 		return -1;
515f1c6118cSZdenek Styblik 	}
516f1c6118cSZdenek Styblik 
517f1c6118cSZdenek Styblik 	printf("FRU state policy bits have been updated\n");
518f1c6118cSZdenek Styblik 
519f1c6118cSZdenek Styblik 	return 0;
520f1c6118cSZdenek Styblik }
521f1c6118cSZdenek Styblik 
522f1c6118cSZdenek Styblik static int
ipmi_vita_get_led_properties(struct ipmi_intf * intf,char ** argv)523f1c6118cSZdenek Styblik ipmi_vita_get_led_properties(struct ipmi_intf *intf, char **argv)
524f1c6118cSZdenek Styblik {
525f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
526f1c6118cSZdenek Styblik 	struct ipmi_rq req;
527f1c6118cSZdenek Styblik 	unsigned char msg_data[2];
528f1c6118cSZdenek Styblik 
529f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
530f1c6118cSZdenek Styblik 
531f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
532f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_GET_FRU_LED_PROPERTIES_CMD;
533f1c6118cSZdenek Styblik 	req.msg.data = msg_data;
534f1c6118cSZdenek Styblik 	req.msg.data_len = 2;
535f1c6118cSZdenek Styblik 
536f1c6118cSZdenek Styblik 	msg_data[0] = GROUP_EXT_VITA;			/* VITA identifier */
537f1c6118cSZdenek Styblik 	if (is_fru_id(argv[0], &msg_data[1]) != 0) {	/* FRU ID */
538f1c6118cSZdenek Styblik 		return -1;
539f1c6118cSZdenek Styblik 	}
540f1c6118cSZdenek Styblik 
541f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
542f1c6118cSZdenek Styblik 
543f1c6118cSZdenek Styblik 	if (rsp == NULL) {
544f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received.");
545f1c6118cSZdenek Styblik 		return -1;
546f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
547f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
548f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
549f1c6118cSZdenek Styblik 		return -1;
550f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 3) {
551f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
552f1c6118cSZdenek Styblik 		return -1;
553f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
554f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
555f1c6118cSZdenek Styblik 		return -1;
556f1c6118cSZdenek Styblik 	}
557f1c6118cSZdenek Styblik 
558f1c6118cSZdenek Styblik 	printf("LED Count:	   %#x\n", rsp->data[2]);
559f1c6118cSZdenek Styblik 
560f1c6118cSZdenek Styblik 	return 0;
561f1c6118cSZdenek Styblik }
562f1c6118cSZdenek Styblik 
563f1c6118cSZdenek Styblik static int
ipmi_vita_get_led_color_capabilities(struct ipmi_intf * intf,char ** argv)564f1c6118cSZdenek Styblik ipmi_vita_get_led_color_capabilities(struct ipmi_intf *intf, char **argv)
565f1c6118cSZdenek Styblik {
566f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
567f1c6118cSZdenek Styblik 	struct ipmi_rq req;
568f1c6118cSZdenek Styblik 	unsigned char msg_data[3];
569f1c6118cSZdenek Styblik 	int i;
570f1c6118cSZdenek Styblik 
571f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
572f1c6118cSZdenek Styblik 
573f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
574f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_GET_LED_COLOR_CAPABILITIES_CMD;
575f1c6118cSZdenek Styblik 	req.msg.data = msg_data;
576f1c6118cSZdenek Styblik 	req.msg.data_len = 3;
577f1c6118cSZdenek Styblik 
578f1c6118cSZdenek Styblik 	msg_data[0] = GROUP_EXT_VITA;			/* VITA identifier */
579f1c6118cSZdenek Styblik 	if (is_fru_id(argv[0], &msg_data[1]) != 0) {	/* FRU ID */
580f1c6118cSZdenek Styblik 		return -1;
581f1c6118cSZdenek Styblik 	}
582f1c6118cSZdenek Styblik 	if (str2uchar(argv[1], &msg_data[2]) != 0) {	/* LED-ID */
583f1c6118cSZdenek Styblik 		return -1;
584f1c6118cSZdenek Styblik 	}
585f1c6118cSZdenek Styblik 
586f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
587f1c6118cSZdenek Styblik 
588f1c6118cSZdenek Styblik 	if (rsp == NULL) {
589f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received.");
590f1c6118cSZdenek Styblik 		return -1;
591f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
592f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
593f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
594f1c6118cSZdenek Styblik 		return -1;
595f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 5) {
596f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
597f1c6118cSZdenek Styblik 		return -1;
598f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
599f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
600f1c6118cSZdenek Styblik 		return -1;
601f1c6118cSZdenek Styblik 	}
602f1c6118cSZdenek Styblik 
603f1c6118cSZdenek Styblik 	printf("LED Color Capabilities: ");
604f1c6118cSZdenek Styblik 	for (i = 0; i < 8; i++) {
605f1c6118cSZdenek Styblik 		if (rsp->data[1] & (0x01 << i)) {
606f1c6118cSZdenek Styblik 			printf("%s, ", led_color_str[i]);
607f1c6118cSZdenek Styblik 		}
608f1c6118cSZdenek Styblik 	}
609f1c6118cSZdenek Styblik 	putchar('\n');
610f1c6118cSZdenek Styblik 
611f1c6118cSZdenek Styblik 	printf("Default LED Color in\n");
612f1c6118cSZdenek Styblik 	printf("      LOCAL control:  %s\n", led_color_str[rsp->data[2]]);
613f1c6118cSZdenek Styblik 	printf("      OVERRIDE state: %s\n", led_color_str[rsp->data[3]]);
614f1c6118cSZdenek Styblik 
615f1c6118cSZdenek Styblik 	if (rsp->data_len == 5) {
616f1c6118cSZdenek Styblik 		printf("LED flags:\n");
617f1c6118cSZdenek Styblik 		if (rsp->data[4] & 2) {
618f1c6118cSZdenek Styblik 			printf("      [HW RESTRICT]\n");
619f1c6118cSZdenek Styblik 		}
620f1c6118cSZdenek Styblik 		if (rsp->data[4] & 1) {
621f1c6118cSZdenek Styblik 			printf("      [PAYLOAD PWR]\n");
622f1c6118cSZdenek Styblik 		}
623f1c6118cSZdenek Styblik 	}
624f1c6118cSZdenek Styblik 
625f1c6118cSZdenek Styblik 	return 0;
626f1c6118cSZdenek Styblik }
627f1c6118cSZdenek Styblik 
628f1c6118cSZdenek Styblik static int
ipmi_vita_get_led_state(struct ipmi_intf * intf,char ** argv)629f1c6118cSZdenek Styblik ipmi_vita_get_led_state(struct ipmi_intf *intf, char **argv)
630f1c6118cSZdenek Styblik {
631f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
632f1c6118cSZdenek Styblik 	struct ipmi_rq req;
633f1c6118cSZdenek Styblik 	unsigned char msg_data[3];
634f1c6118cSZdenek Styblik 
635f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
636f1c6118cSZdenek Styblik 
637f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
638f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_GET_FRU_LED_STATE_CMD;
639f1c6118cSZdenek Styblik 	req.msg.data = msg_data;
640f1c6118cSZdenek Styblik 	req.msg.data_len = 3;
641f1c6118cSZdenek Styblik 
642f1c6118cSZdenek Styblik 	msg_data[0] = GROUP_EXT_VITA;			/* VITA identifier */
643f1c6118cSZdenek Styblik 	if (is_fru_id(argv[0], &msg_data[1]) != 0) {	/* FRU ID */
644f1c6118cSZdenek Styblik 		return -1;
645f1c6118cSZdenek Styblik 	}
646f1c6118cSZdenek Styblik 	if (str2uchar(argv[1], &msg_data[2]) != 0) {	/* LED-ID */
647f1c6118cSZdenek Styblik 		return -1;
648f1c6118cSZdenek Styblik 	}
649f1c6118cSZdenek Styblik 
650f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
651f1c6118cSZdenek Styblik 
652f1c6118cSZdenek Styblik 	if (rsp == NULL) {
653f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received.");
654f1c6118cSZdenek Styblik 		return -1;
655f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
656f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
657f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
658f1c6118cSZdenek Styblik 		return -1;
659f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 5
660f1c6118cSZdenek Styblik 		|| ((rsp->data[1] & 0x2) && rsp->data_len < 8)
661f1c6118cSZdenek Styblik 		|| ((rsp->data[1] & 0x4) && rsp->data_len < 9)) {
662f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
663f1c6118cSZdenek Styblik 		return -1;
664f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
665f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
666f1c6118cSZdenek Styblik 		return -1;
667f1c6118cSZdenek Styblik 	}
668f1c6118cSZdenek Styblik 
669f1c6118cSZdenek Styblik 	printf("LED states:                   %x\t", rsp->data[1]);
670f1c6118cSZdenek Styblik 	if (rsp->data[1] & 0x1) {
671f1c6118cSZdenek Styblik 		printf("[LOCAL CONTROL] ");
672f1c6118cSZdenek Styblik 	}
673f1c6118cSZdenek Styblik 	if (rsp->data[1] & 0x2) {
674f1c6118cSZdenek Styblik 		printf("[OVERRIDE] ");
675f1c6118cSZdenek Styblik 	}
676f1c6118cSZdenek Styblik 	if (rsp->data[1] & 0x4) {
677f1c6118cSZdenek Styblik 		printf("[LAMPTEST] ");
678f1c6118cSZdenek Styblik 	}
679f1c6118cSZdenek Styblik 	if (rsp->data[1] & 0x8) {
680f1c6118cSZdenek Styblik 		printf("[HW RESTRICT] ");
681f1c6118cSZdenek Styblik 	}
682f1c6118cSZdenek Styblik 	putchar('\n');
683f1c6118cSZdenek Styblik 
684f1c6118cSZdenek Styblik 	if (rsp->data[1] & 1) {
685f1c6118cSZdenek Styblik 		printf("  Local Control function:     %x\t", rsp->data[2]);
686f1c6118cSZdenek Styblik 		if (rsp->data[2] == 0x0) {
687f1c6118cSZdenek Styblik 			printf("[OFF]\n");
688f1c6118cSZdenek Styblik 		} else if (rsp->data[2] == 0xff) {
689f1c6118cSZdenek Styblik 			printf("[ON]\n");
690f1c6118cSZdenek Styblik 		} else {
691f1c6118cSZdenek Styblik 			printf("[BLINKING]\n");
692f1c6118cSZdenek Styblik 		}
693f1c6118cSZdenek Styblik 		printf("  Local Control On-Duration:  %x\n", rsp->data[3]);
694f1c6118cSZdenek Styblik 		printf("  Local Control Color:        %x\t[%s]\n",
695f1c6118cSZdenek Styblik 			rsp->data[4], led_color_str[rsp->data[4] & 7]);
696f1c6118cSZdenek Styblik 	}
697f1c6118cSZdenek Styblik 
698f1c6118cSZdenek Styblik 	/* override state or lamp test */
699f1c6118cSZdenek Styblik 	if (rsp->data[1] & 0x06) {
700f1c6118cSZdenek Styblik 		printf("  Override function:     %x\t", rsp->data[5]);
701f1c6118cSZdenek Styblik 		if (rsp->data[5] == 0x0) {
702f1c6118cSZdenek Styblik 			printf("[OFF]\n");
703f1c6118cSZdenek Styblik 		} else if (rsp->data[5] == 0xff) {
704f1c6118cSZdenek Styblik 			printf("[ON]\n");
705f1c6118cSZdenek Styblik 		} else {
706f1c6118cSZdenek Styblik 			printf("[BLINKING]\n");
707f1c6118cSZdenek Styblik 		}
708f1c6118cSZdenek Styblik 		printf("  Override On-Duration:  %x\n", rsp->data[6]);
709f1c6118cSZdenek Styblik 		printf("  Override Color:        %x\t[%s]\n",
710f1c6118cSZdenek Styblik 			rsp->data[7], led_color_str[rsp->data[7] & 7]);
711f1c6118cSZdenek Styblik 		if (rsp->data[1] == 0x04) {
712f1c6118cSZdenek Styblik 			printf("  Lamp test duration:    %x\n", rsp->data[8]);
713f1c6118cSZdenek Styblik 		}
714f1c6118cSZdenek Styblik 	}
715f1c6118cSZdenek Styblik 
716f1c6118cSZdenek Styblik 	return 0;
717f1c6118cSZdenek Styblik }
718f1c6118cSZdenek Styblik 
719f1c6118cSZdenek Styblik static int
ipmi_vita_set_led_state(struct ipmi_intf * intf,char ** argv)720f1c6118cSZdenek Styblik ipmi_vita_set_led_state(struct ipmi_intf *intf, char **argv)
721f1c6118cSZdenek Styblik {
722f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
723f1c6118cSZdenek Styblik 	struct ipmi_rq req;
724f1c6118cSZdenek Styblik 	unsigned char msg_data[6];
725f1c6118cSZdenek Styblik 
726f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
727f1c6118cSZdenek Styblik 
728f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
729f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_SET_FRU_LED_STATE_CMD;
730f1c6118cSZdenek Styblik 	req.msg.data = msg_data;
731f1c6118cSZdenek Styblik 	req.msg.data_len = 6;
732f1c6118cSZdenek Styblik 
733f1c6118cSZdenek Styblik 	msg_data[0] = GROUP_EXT_VITA;			/* VITA identifier */
734f1c6118cSZdenek Styblik 	if (is_fru_id(argv[0], &msg_data[1]) != 0) {	/* FRU ID */
735f1c6118cSZdenek Styblik 		return -1;
736f1c6118cSZdenek Styblik 	}
737f1c6118cSZdenek Styblik 	if (str2uchar(argv[1], &msg_data[2]) != 0) {	/* LED-ID */
738f1c6118cSZdenek Styblik 		return -1;
739f1c6118cSZdenek Styblik 	}
740f1c6118cSZdenek Styblik 	if (str2uchar(argv[2], &msg_data[3]) != 0) {	/* LED function */
741f1c6118cSZdenek Styblik 		return -1;
742f1c6118cSZdenek Styblik 	}
743f1c6118cSZdenek Styblik 	if (str2uchar(argv[3], &msg_data[4]) != 0) {	/* LED on duration */
744f1c6118cSZdenek Styblik 		return -1;
745f1c6118cSZdenek Styblik 	}
746f1c6118cSZdenek Styblik 	if (str2uchar(argv[4], &msg_data[5]) != 0) {	/* LED color */
747f1c6118cSZdenek Styblik 		return -1;
748f1c6118cSZdenek Styblik 	}
749f1c6118cSZdenek Styblik 
750f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
751f1c6118cSZdenek Styblik 
752f1c6118cSZdenek Styblik 	if (rsp == NULL) {
753f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received.");
754f1c6118cSZdenek Styblik 		return -1;
755f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
756f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
757f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
758f1c6118cSZdenek Styblik 		return -1;
759f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 1) {
760f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
761f1c6118cSZdenek Styblik 		return -1;
762f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
763f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
764f1c6118cSZdenek Styblik 		return -1;
765f1c6118cSZdenek Styblik 	}
766f1c6118cSZdenek Styblik 
767f1c6118cSZdenek Styblik 	printf("LED state has been updated\n");
768f1c6118cSZdenek Styblik 
769f1c6118cSZdenek Styblik 	return 0;
770f1c6118cSZdenek Styblik }
771f1c6118cSZdenek Styblik 
772f1c6118cSZdenek Styblik static int
ipmi_vita_fru_control(struct ipmi_intf * intf,char ** argv)773f1c6118cSZdenek Styblik ipmi_vita_fru_control(struct ipmi_intf *intf, char **argv)
774f1c6118cSZdenek Styblik {
775f1c6118cSZdenek Styblik 	struct ipmi_rs *rsp;
776f1c6118cSZdenek Styblik 	struct ipmi_rq req;
777f1c6118cSZdenek Styblik 	unsigned char msg_data[3];
778f1c6118cSZdenek Styblik 
779f1c6118cSZdenek Styblik 	memset(&req, 0, sizeof(req));
780f1c6118cSZdenek Styblik 
781f1c6118cSZdenek Styblik 	req.msg.netfn = IPMI_NETFN_PICMG;
782f1c6118cSZdenek Styblik 	req.msg.cmd = VITA_FRU_CONTROL_CMD;
783f1c6118cSZdenek Styblik 	req.msg.data = msg_data;
784f1c6118cSZdenek Styblik 	req.msg.data_len = 3;
785f1c6118cSZdenek Styblik 
786f1c6118cSZdenek Styblik 	msg_data[0] = GROUP_EXT_VITA;			/* VITA identifier */
787f1c6118cSZdenek Styblik 	if (is_fru_id(argv[0], &msg_data[1]) != 0) {	/* FRU ID */
788f1c6118cSZdenek Styblik 		return -1;
789f1c6118cSZdenek Styblik 	}
790f1c6118cSZdenek Styblik 	if (str2uchar(argv[1], &msg_data[2]) != 0) {	/* control option */
791f1c6118cSZdenek Styblik 		return -1;
792f1c6118cSZdenek Styblik 	}
793f1c6118cSZdenek Styblik 
794f1c6118cSZdenek Styblik 	printf("FRU Device Id: %d FRU Control Option: %s\n", msg_data[1],
795f1c6118cSZdenek Styblik 		val2str(msg_data[2], picmg_frucontrol_vals));
796f1c6118cSZdenek Styblik 
797f1c6118cSZdenek Styblik 	rsp = intf->sendrecv(intf, &req);
798f1c6118cSZdenek Styblik 
799f1c6118cSZdenek Styblik 	if (rsp == NULL) {
800f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "No valid response received.");
801f1c6118cSZdenek Styblik 		return -1;
802f1c6118cSZdenek Styblik 	} else if (rsp->ccode != 0) {
803f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid completion code received: %s",
804f1c6118cSZdenek Styblik 			val2str(rsp->ccode, completion_code_vals));
805f1c6118cSZdenek Styblik 		return -1;
806f1c6118cSZdenek Styblik 	} else if (rsp->data_len < 1) {
807f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
808f1c6118cSZdenek Styblik 		return -1;
809f1c6118cSZdenek Styblik 	} else if (rsp->data[0] != GROUP_EXT_VITA) {
810f1c6118cSZdenek Styblik 		lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
811f1c6118cSZdenek Styblik 		return -1;
812f1c6118cSZdenek Styblik 	}
813f1c6118cSZdenek Styblik 
814f1c6118cSZdenek Styblik 	printf("FRU Control: ok\n");
815f1c6118cSZdenek Styblik 
816f1c6118cSZdenek Styblik 	return 0;
817f1c6118cSZdenek Styblik }
818f1c6118cSZdenek Styblik 
819f1c6118cSZdenek Styblik static int
ipmi_vita_get_cmd(int argc,char ** argv)820f1c6118cSZdenek Styblik ipmi_vita_get_cmd(int argc, char **argv)
821f1c6118cSZdenek Styblik {
822f1c6118cSZdenek Styblik 	if (argc < 1 || !strncmp(argv[0], "help", 4)) {
823f1c6118cSZdenek Styblik 		return VITA_CMD_HELP;
824f1c6118cSZdenek Styblik 	}
825f1c6118cSZdenek Styblik 
826f1c6118cSZdenek Styblik 	/* Get VSO Properties */
827f1c6118cSZdenek Styblik 	if (!strncmp(argv[0], "properties", 10)) {
828f1c6118cSZdenek Styblik 		return VITA_CMD_PROPERTIES;
829f1c6118cSZdenek Styblik 	}
830f1c6118cSZdenek Styblik 
831f1c6118cSZdenek Styblik 	/* FRU Control command */
832f1c6118cSZdenek Styblik 	if (!strncmp(argv[0], "frucontrol", 10)) {
833f1c6118cSZdenek Styblik 		return VITA_CMD_FRUCONTROL;
834f1c6118cSZdenek Styblik 	}
835f1c6118cSZdenek Styblik 
836f1c6118cSZdenek Styblik 	/* Get FRU Address Info command */
837f1c6118cSZdenek Styblik 	if (!strncmp(argv[0], "addrinfo", 8)) {
838f1c6118cSZdenek Styblik 		return VITA_CMD_ADDRINFO;
839f1c6118cSZdenek Styblik 	}
840f1c6118cSZdenek Styblik 
841f1c6118cSZdenek Styblik 	/* Set FRU Activation (activate) command */
842f1c6118cSZdenek Styblik 	if (!strncmp(argv[0], "activate", 8)) {
843f1c6118cSZdenek Styblik 		return VITA_CMD_ACTIVATE;
844f1c6118cSZdenek Styblik 	}
845f1c6118cSZdenek Styblik 
846f1c6118cSZdenek Styblik 	/* Set FRU Activation (deactivate) command */
847f1c6118cSZdenek Styblik 	if (!strncmp(argv[0], "deactivate", 10)) {
848f1c6118cSZdenek Styblik 		return VITA_CMD_DEACTIVATE;
849f1c6118cSZdenek Styblik 	}
850f1c6118cSZdenek Styblik 
851f1c6118cSZdenek Styblik 	/* FRU State Policy Bits commands */
852f1c6118cSZdenek Styblik 	if (!strncmp(argv[0], "policy", 6)) {
853f1c6118cSZdenek Styblik 		if (argc < 2) {
854f1c6118cSZdenek Styblik 			return VITA_CMD_UNKNOWN;
855f1c6118cSZdenek Styblik 		}
856f1c6118cSZdenek Styblik 
857f1c6118cSZdenek Styblik 		/* Get FRU State Policy Bits command */
858f1c6118cSZdenek Styblik 		if (!strncmp(argv[1], "get", 3)) {
859f1c6118cSZdenek Styblik 			return VITA_CMD_POLICY_GET;
860f1c6118cSZdenek Styblik 		}
861f1c6118cSZdenek Styblik 
862f1c6118cSZdenek Styblik 		/* Set FRU State Policy Bits command */
863f1c6118cSZdenek Styblik 		if (!strncmp(argv[1], "set", 3)) {
864f1c6118cSZdenek Styblik 			return VITA_CMD_POLICY_SET;
865f1c6118cSZdenek Styblik 		}
866f1c6118cSZdenek Styblik 
867f1c6118cSZdenek Styblik 		/* unknown command */
868f1c6118cSZdenek Styblik 		return VITA_CMD_UNKNOWN;
869f1c6118cSZdenek Styblik 	}
870f1c6118cSZdenek Styblik 
871f1c6118cSZdenek Styblik 	/* FRU LED commands */
872f1c6118cSZdenek Styblik 	if (!strncmp(argv[0], "led", 3)) {
873f1c6118cSZdenek Styblik 		if (argc < 2) {
874f1c6118cSZdenek Styblik 			return VITA_CMD_UNKNOWN;
875f1c6118cSZdenek Styblik 		}
876f1c6118cSZdenek Styblik 
877f1c6118cSZdenek Styblik 		/* FRU LED Get Properties */
878f1c6118cSZdenek Styblik 		if (!strncmp(argv[1], "prop", 4)) {
879f1c6118cSZdenek Styblik 			return VITA_CMD_LED_PROP;
880f1c6118cSZdenek Styblik 		}
881f1c6118cSZdenek Styblik 
882f1c6118cSZdenek Styblik 		/* FRU LED Get Capabilities */
883f1c6118cSZdenek Styblik 		if (!strncmp(argv[1], "cap", 3)) {
884f1c6118cSZdenek Styblik 			return VITA_CMD_LED_CAP;
885f1c6118cSZdenek Styblik 		}
886f1c6118cSZdenek Styblik 
887f1c6118cSZdenek Styblik 		/* FRU LED Get State */
888f1c6118cSZdenek Styblik 		if (!strncmp(argv[1], "get", 3)) {
889f1c6118cSZdenek Styblik 			return VITA_CMD_LED_GET;
890f1c6118cSZdenek Styblik 		}
891f1c6118cSZdenek Styblik 
892f1c6118cSZdenek Styblik 		/* FRU LED Set State */
893f1c6118cSZdenek Styblik 		if (!strncmp(argv[1], "set", 3)) {
894f1c6118cSZdenek Styblik 			return VITA_CMD_LED_SET;
895f1c6118cSZdenek Styblik 		}
896f1c6118cSZdenek Styblik 
897f1c6118cSZdenek Styblik 		/* unknown command */
898f1c6118cSZdenek Styblik 		return VITA_CMD_UNKNOWN;
899f1c6118cSZdenek Styblik 	}
900f1c6118cSZdenek Styblik 
901f1c6118cSZdenek Styblik 	/* unknown command */
902f1c6118cSZdenek Styblik 	return VITA_CMD_UNKNOWN;
903f1c6118cSZdenek Styblik }
904f1c6118cSZdenek Styblik 
905f1c6118cSZdenek Styblik int
ipmi_vita_main(struct ipmi_intf * intf,int argc,char ** argv)906f1c6118cSZdenek Styblik ipmi_vita_main (struct ipmi_intf *intf, int argc, char **argv)
907f1c6118cSZdenek Styblik {
908f1c6118cSZdenek Styblik 	int rc = -1, show_help = 0;
909f1c6118cSZdenek Styblik 	int cmd = ipmi_vita_get_cmd(argc, argv);
910f1c6118cSZdenek Styblik 
911f1c6118cSZdenek Styblik 	switch (cmd) {
912f1c6118cSZdenek Styblik 	case VITA_CMD_HELP:
913f1c6118cSZdenek Styblik 		cmd = ipmi_vita_get_cmd(argc - 1, &argv[1]);
914f1c6118cSZdenek Styblik 		show_help = 1;
915f1c6118cSZdenek Styblik 		rc = 0;
916f1c6118cSZdenek Styblik 		break;
917f1c6118cSZdenek Styblik 
918f1c6118cSZdenek Styblik 	case VITA_CMD_PROPERTIES:
919f1c6118cSZdenek Styblik 		rc = ipmi_vita_get_vso_capabilities(intf);
920f1c6118cSZdenek Styblik 		break;
921f1c6118cSZdenek Styblik 
922f1c6118cSZdenek Styblik 	case VITA_CMD_FRUCONTROL:
923f1c6118cSZdenek Styblik 		if (argc > 2) {
924f1c6118cSZdenek Styblik 			rc = ipmi_vita_fru_control(intf, &argv[1]);
925f1c6118cSZdenek Styblik 		} else {
926f1c6118cSZdenek Styblik 			show_help = 1;
927f1c6118cSZdenek Styblik 		}
928f1c6118cSZdenek Styblik 		break;
929f1c6118cSZdenek Styblik 
930f1c6118cSZdenek Styblik 	case VITA_CMD_ADDRINFO:
931f1c6118cSZdenek Styblik 		rc = ipmi_vita_getaddr(intf, argc - 1, &argv[1]);
932f1c6118cSZdenek Styblik 		break;
933f1c6118cSZdenek Styblik 
934f1c6118cSZdenek Styblik 	case VITA_CMD_ACTIVATE:
935f1c6118cSZdenek Styblik 		if (argc > 1) {
936f1c6118cSZdenek Styblik 			rc = ipmi_vita_set_fru_activation(intf, &argv[1], 1);
937f1c6118cSZdenek Styblik 		} else {
938f1c6118cSZdenek Styblik 			show_help = 1;
939f1c6118cSZdenek Styblik 		}
940f1c6118cSZdenek Styblik 		break;
941f1c6118cSZdenek Styblik 
942f1c6118cSZdenek Styblik 	case VITA_CMD_DEACTIVATE:
943f1c6118cSZdenek Styblik 		if (argc > 1) {
944f1c6118cSZdenek Styblik 			rc = ipmi_vita_set_fru_activation(intf, &argv[1], 0);
945f1c6118cSZdenek Styblik 		} else {
946f1c6118cSZdenek Styblik 			show_help = 1;
947f1c6118cSZdenek Styblik 		}
948f1c6118cSZdenek Styblik 		break;
949f1c6118cSZdenek Styblik 
950f1c6118cSZdenek Styblik 	case VITA_CMD_POLICY_GET:
951f1c6118cSZdenek Styblik 		if (argc > 2) {
952f1c6118cSZdenek Styblik 			rc = ipmi_vita_get_fru_state_policy_bits(intf,
953f1c6118cSZdenek Styblik 				&argv[2]);
954f1c6118cSZdenek Styblik 		} else {
955f1c6118cSZdenek Styblik 			show_help = 1;
956f1c6118cSZdenek Styblik 		}
957f1c6118cSZdenek Styblik 		break;
958f1c6118cSZdenek Styblik 
959f1c6118cSZdenek Styblik 	case VITA_CMD_POLICY_SET:
960f1c6118cSZdenek Styblik 		if (argc > 4) {
961f1c6118cSZdenek Styblik 			rc = ipmi_vita_set_fru_state_policy_bits(intf,
962f1c6118cSZdenek Styblik 				&argv[2]);
963f1c6118cSZdenek Styblik 		} else {
964f1c6118cSZdenek Styblik 			show_help = 1;
965f1c6118cSZdenek Styblik 		}
966f1c6118cSZdenek Styblik 		break;
967f1c6118cSZdenek Styblik 
968f1c6118cSZdenek Styblik 	case VITA_CMD_LED_PROP:
969f1c6118cSZdenek Styblik 		if (argc > 2) {
970f1c6118cSZdenek Styblik 			rc = ipmi_vita_get_led_properties(intf, &argv[2]);
971f1c6118cSZdenek Styblik 		} else {
972f1c6118cSZdenek Styblik 			show_help = 1;
973f1c6118cSZdenek Styblik 		}
974f1c6118cSZdenek Styblik 		break;
975f1c6118cSZdenek Styblik 
976f1c6118cSZdenek Styblik 	case VITA_CMD_LED_CAP:
977f1c6118cSZdenek Styblik 		if (argc > 3) {
978f1c6118cSZdenek Styblik 			rc = ipmi_vita_get_led_color_capabilities(intf,
979f1c6118cSZdenek Styblik 				&argv[2]);
980f1c6118cSZdenek Styblik 		} else {
981f1c6118cSZdenek Styblik 			show_help = 1;
982f1c6118cSZdenek Styblik 		}
983f1c6118cSZdenek Styblik 		break;
984f1c6118cSZdenek Styblik 
985f1c6118cSZdenek Styblik 	case VITA_CMD_LED_GET:
986f1c6118cSZdenek Styblik 		if (argc > 3) {
987f1c6118cSZdenek Styblik 			rc = ipmi_vita_get_led_state(intf, &argv[2]);
988f1c6118cSZdenek Styblik 		} else {
989f1c6118cSZdenek Styblik 			show_help = 1;
990f1c6118cSZdenek Styblik 		}
991f1c6118cSZdenek Styblik 		break;
992f1c6118cSZdenek Styblik 
993f1c6118cSZdenek Styblik 	case VITA_CMD_LED_SET:
994f1c6118cSZdenek Styblik 		if (argc > 6) {
995f1c6118cSZdenek Styblik 			rc = ipmi_vita_set_led_state(intf, &argv[2]);
996f1c6118cSZdenek Styblik 		} else {
997f1c6118cSZdenek Styblik 			show_help = 1;
998f1c6118cSZdenek Styblik 		}
999f1c6118cSZdenek Styblik 		break;
1000f1c6118cSZdenek Styblik 	default:
1001f1c6118cSZdenek Styblik 		lprintf(LOG_NOTICE, "Unknown command");
1002f1c6118cSZdenek Styblik 		cmd = VITA_CMD_HELP;
1003f1c6118cSZdenek Styblik 		show_help = 1;
1004f1c6118cSZdenek Styblik 		break;
1005f1c6118cSZdenek Styblik 	}
1006f1c6118cSZdenek Styblik 
1007f1c6118cSZdenek Styblik 	if (show_help) {
1008f1c6118cSZdenek Styblik 		lprintf(LOG_NOTICE, "%s", val2str(cmd, vita_help_strings));
1009f1c6118cSZdenek Styblik 	}
1010f1c6118cSZdenek Styblik 
1011f1c6118cSZdenek Styblik 	return rc;
1012f1c6118cSZdenek Styblik }
1013