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