dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libtsalarm / common / tsalarm.c
blobdfc4142e64f2480033b01075c9c5eec995f7e9c4
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
26 * Telco-alarm library, which communicates through libpcp to set/get
27 * alarms.
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34 #include <libpcp.h>
36 #include "tsalarm.h"
38 /* Message Types */
39 #define TSALARM_CONTROL 15
40 #define TSALARM_CONTROL_R 16
42 #define TSALARM_CHANNEL_TIMEOUT 20
43 #define TSALARM_MAX_RETRIES 3
44 #define TSALARM_SERVICE_NAME "SUNW,sun4v-telco-alarm"
46 int
47 tsalarm_get(uint32_t alarm_type, uint32_t *alarm_state)
49 int chnl_fd;
50 tsalarm_req_t *req_ptr = NULL;
51 tsalarm_resp_t *resp_ptr = NULL;
52 pcp_msg_t send_msg;
53 pcp_msg_t recv_msg;
54 int rc = TSALARM_SUCCESS;
55 int retries;
57 /* initialize virtual channel */
58 for (retries = 1; retries <= TSALARM_MAX_RETRIES; retries++) {
59 if ((chnl_fd = pcp_init(TSALARM_SERVICE_NAME)) < 0) {
60 if (retries == TSALARM_MAX_RETRIES) {
61 rc = TSALARM_CHANNEL_INIT_FAILURE;
62 goto cleanup;
64 (void) sleep(TSALARM_CHANNEL_TIMEOUT);
65 } else
66 break;
69 /* create request message data */
70 req_ptr = malloc(sizeof (tsalarm_req_t));
71 if (req_ptr == NULL) {
72 rc = TSALARM_NULL_REQ_DATA;
73 goto cleanup;
75 req_ptr->alarm_action = TSALARM_STATUS;
76 req_ptr->alarm_id = alarm_type;
78 send_msg.msg_type = TSALARM_CONTROL;
79 send_msg.sub_type = NULL;
80 send_msg.msg_len = sizeof (tsalarm_req_t);
81 send_msg.msg_data = (uint8_t *)req_ptr;
84 * Send the request and receive the response.
86 if (pcp_send_recv(chnl_fd, &send_msg, &recv_msg,
87 TSALARM_CHANNEL_TIMEOUT) < 0) {
88 /* we either timed out or erred; either way try again */
89 (void) sleep(TSALARM_CHANNEL_TIMEOUT);
91 if (pcp_send_recv(chnl_fd, &send_msg, &recv_msg,
92 TSALARM_CHANNEL_TIMEOUT) < 0) {
93 rc = TSALARM_COMM_FAILURE;
94 goto cleanup;
99 * verify that the Alarm action has taken place
101 if ((resp_ptr = (tsalarm_resp_t *)recv_msg.msg_data) == NULL)
102 goto cleanup;
105 * validate that this data was meant for us
107 if (recv_msg.msg_type != TSALARM_CONTROL_R) {
108 rc = TSALARM_UNBOUND_PACKET_RECVD;
109 goto cleanup;
112 if (resp_ptr->status == TSALARM_ERROR) {
113 rc = TSALARM_GET_ERROR;
114 goto cleanup;
117 if (resp_ptr->alarm_state == TSALARM_STATE_UNKNOWN) {
118 rc = TSALARM_GET_ERROR;
119 goto cleanup;
122 *alarm_state = resp_ptr->alarm_state;
124 cleanup:
125 free(req_ptr);
127 /* free recv_msg.msg_data through pointer to make sure it is valid */
128 free(resp_ptr);
130 /* close virtual channel fd */
131 (void) pcp_close(chnl_fd);
133 return (rc);
137 tsalarm_set(uint32_t alarm_type, uint32_t alarm_state)
139 int chnl_fd;
140 tsalarm_req_t *req_ptr = NULL;
141 tsalarm_resp_t *resp_ptr = NULL;
142 pcp_msg_t send_msg;
143 pcp_msg_t recv_msg;
144 int rc = TSALARM_SUCCESS;
145 int retries;
147 /* initialize virtual channel */
148 for (retries = 1; retries <= TSALARM_MAX_RETRIES; retries++) {
149 if ((chnl_fd = pcp_init(TSALARM_SERVICE_NAME)) < 0) {
150 if (retries == TSALARM_MAX_RETRIES) {
151 rc = TSALARM_CHANNEL_INIT_FAILURE;
152 goto cleanup;
154 (void) sleep(TSALARM_CHANNEL_TIMEOUT);
155 } else
156 break;
159 /* create request message data */
160 req_ptr = malloc(sizeof (tsalarm_req_t));
161 if (req_ptr == NULL) {
162 rc = TSALARM_NULL_REQ_DATA;
163 goto cleanup;
165 req_ptr->alarm_id = alarm_type;
166 if (alarm_state == TSALARM_STATE_ON)
167 req_ptr->alarm_action = TSALARM_ENABLE;
168 else if (alarm_state == TSALARM_STATE_OFF)
169 req_ptr->alarm_action = TSALARM_DISABLE;
171 send_msg.msg_type = TSALARM_CONTROL;
172 send_msg.sub_type = NULL;
173 send_msg.msg_len = sizeof (tsalarm_req_t);
174 send_msg.msg_data = (uint8_t *)req_ptr;
177 * Send the request and receive the response.
179 if (pcp_send_recv(chnl_fd, &send_msg, &recv_msg,
180 TSALARM_CHANNEL_TIMEOUT) < 0) {
181 /* we either timed out or erred; either way try again */
182 (void) sleep(TSALARM_CHANNEL_TIMEOUT);
184 if (pcp_send_recv(chnl_fd, &send_msg, &recv_msg,
185 TSALARM_CHANNEL_TIMEOUT) < 0) {
186 rc = TSALARM_COMM_FAILURE;
187 goto cleanup;
192 * verify that the Alarm action has taken place
194 if ((resp_ptr = (tsalarm_resp_t *)recv_msg.msg_data) == NULL)
195 goto cleanup;
198 * validate that this data was meant for us
200 if (recv_msg.msg_type != TSALARM_CONTROL_R) {
201 rc = TSALARM_UNBOUND_PACKET_RECVD;
202 goto cleanup;
205 if (resp_ptr->status == TSALARM_ERROR) {
206 rc = TSALARM_SET_ERROR;
207 goto cleanup;
211 * ensure the Alarm action taken is the one requested
213 if ((req_ptr->alarm_action == TSALARM_DISABLE) &&
214 (resp_ptr->alarm_state != TSALARM_STATE_OFF)) {
215 rc = TSALARM_SET_ERROR;
216 goto cleanup;
217 } else if ((req_ptr->alarm_action == TSALARM_ENABLE) &&
218 (resp_ptr->alarm_state != TSALARM_STATE_ON)) {
219 rc = TSALARM_SET_ERROR;
220 goto cleanup;
221 } else if (resp_ptr->alarm_state == TSALARM_STATE_UNKNOWN) {
222 rc = TSALARM_SET_ERROR;
223 goto cleanup;
226 cleanup:
227 free(req_ptr);
229 /* free recv_msg.msg_data through pointer to make sure it is valid */
230 free(resp_ptr);
232 /* close virtual channel fd */
233 (void) pcp_close(chnl_fd);
235 return (rc);