1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 2001 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #include <stdio.h>
28*7c478bd9Sstevel@tonic-gate #include <unistd.h>
29*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
30*7c478bd9Sstevel@tonic-gate #include <string.h>
31*7c478bd9Sstevel@tonic-gate #include <ctype.h>
32*7c478bd9Sstevel@tonic-gate #include <errno.h>
33*7c478bd9Sstevel@tonic-gate #include <libintl.h>
34*7c478bd9Sstevel@tonic-gate #include <syslog.h>
35*7c478bd9Sstevel@tonic-gate #include "fcal_leds.h"
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate /*
38*7c478bd9Sstevel@tonic-gate  * function templates for static functions
39*7c478bd9Sstevel@tonic-gate  */
40*7c478bd9Sstevel@tonic-gate static token_t get_token(char **pptr, int lineNo, actfun_t *fun);
41*7c478bd9Sstevel@tonic-gate static int get_cstr(str *p_str, cstr *p_cstr_res);
42*7c478bd9Sstevel@tonic-gate static int get_assert(str *p_str, int *assert);
43*7c478bd9Sstevel@tonic-gate static int get_pnz(str *p_str, int *pnz);
44*7c478bd9Sstevel@tonic-gate static int get_mask(str *p_str, int n_disks, int *p_intarray);
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate /*
47*7c478bd9Sstevel@tonic-gate  * Templates for functions which may be returned by get_token().
48*7c478bd9Sstevel@tonic-gate  * These functions are all called with a pointer to the position just
49*7c478bd9Sstevel@tonic-gate  * beyond the token being actioned.
50*7c478bd9Sstevel@tonic-gate  */
51*7c478bd9Sstevel@tonic-gate static int act_version(str *p_str, led_dtls_t *dtls);
52*7c478bd9Sstevel@tonic-gate static int act_leds_board(str *p_str, led_dtls_t *dtls);
53*7c478bd9Sstevel@tonic-gate static int act_status_board(str *p_str, led_dtls_t *dtls);
54*7c478bd9Sstevel@tonic-gate static int act_disk_driver(str *p_str, led_dtls_t *dtls);
55*7c478bd9Sstevel@tonic-gate static int act_n_disks(str *p_str, led_dtls_t *dtls);
56*7c478bd9Sstevel@tonic-gate static int act_asrt_pres(str *p_str, led_dtls_t *dtls);
57*7c478bd9Sstevel@tonic-gate static int act_asrt_fault(str *p_str, led_dtls_t *dtls);
58*7c478bd9Sstevel@tonic-gate static int act_led_on(str *p_str, led_dtls_t *dtls);
59*7c478bd9Sstevel@tonic-gate static int act_disk_present(str *p_str, led_dtls_t *dtls);
60*7c478bd9Sstevel@tonic-gate static int act_disk_fault(str *p_str, led_dtls_t *dtls);
61*7c478bd9Sstevel@tonic-gate static int act_led_id(str *p_str, led_dtls_t *dtls);
62*7c478bd9Sstevel@tonic-gate static int act_slow_poll(str *p_str, led_dtls_t *dtls);
63*7c478bd9Sstevel@tonic-gate static int act_fast_poll(str *p_str, led_dtls_t *dtls);
64*7c478bd9Sstevel@tonic-gate static int act_relax_interval(str *p_str, led_dtls_t *dtls);
65*7c478bd9Sstevel@tonic-gate static int act_test_interval(str *p_str, led_dtls_t *dtls);
66*7c478bd9Sstevel@tonic-gate static int act_disk_parent(str *p_str, led_dtls_t *dtls);
67*7c478bd9Sstevel@tonic-gate static int act_unit_parent(str *p_str, led_dtls_t *dtls);
68*7c478bd9Sstevel@tonic-gate static int act_led_nodes(str *p_str, led_dtls_t *dtls);
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate /*
71*7c478bd9Sstevel@tonic-gate  * The table below is used to lookup .conf file keywords to yield either
72*7c478bd9Sstevel@tonic-gate  * a corresponding enum or a function to process the keyword.
73*7c478bd9Sstevel@tonic-gate  */
74*7c478bd9Sstevel@tonic-gate static lookup_t table[] = {
75*7c478bd9Sstevel@tonic-gate 	{ FCAL_VERSION,		"VERSION", 		act_version	},
76*7c478bd9Sstevel@tonic-gate 	{ FCAL_REMOK_LED,	"REMOK",		NULL		},
77*7c478bd9Sstevel@tonic-gate 	{ FCAL_FAULT_LED,	"FAULT",		NULL		},
78*7c478bd9Sstevel@tonic-gate 	{ FCAL_READY_LED,	"READY",		NULL		},
79*7c478bd9Sstevel@tonic-gate 	{ FCAL_LEDS_BOARD,	"FCAL-LEDS",		act_leds_board	},
80*7c478bd9Sstevel@tonic-gate 	{ FCAL_STATUS_BOARD,	"FCAL-STATUS",		act_status_board },
81*7c478bd9Sstevel@tonic-gate 	{ FCAL_DISK_DRIVER,	"FCAL-DISK-DRIVER",	act_disk_driver },
82*7c478bd9Sstevel@tonic-gate 	{ FCAL_N_DISKS,		"N-DISKS",		act_n_disks	},
83*7c478bd9Sstevel@tonic-gate 	{ FCAL_ASSERT_PRESENT,	"ASSERT-PRESENT",	act_asrt_pres	},
84*7c478bd9Sstevel@tonic-gate 	{ FCAL_ASSERT_FAULT,	"ASSERT-FAULT",		act_asrt_fault	},
85*7c478bd9Sstevel@tonic-gate 	{ FCAL_LED_ON,		"LED-ON",		act_led_on	},
86*7c478bd9Sstevel@tonic-gate 	{ FCAL_DISK_PRESENT,	"DISK-PRESENT",		act_disk_present },
87*7c478bd9Sstevel@tonic-gate 	{ FCAL_DISK_FAULT,	"DISK-FAULT",		act_disk_fault	},
88*7c478bd9Sstevel@tonic-gate 	{ FCAL_LED_ID,		"LED",			act_led_id	},
89*7c478bd9Sstevel@tonic-gate 	{ FCAL_SLOW_POLL,	"SLOW-POLL",		act_slow_poll	},
90*7c478bd9Sstevel@tonic-gate 	{ FCAL_FAST_POLL,	"FAST-POLL",		act_fast_poll	},
91*7c478bd9Sstevel@tonic-gate 	{ FCAL_RELAX_INTERVAL,	"RELAX-INTERVAL",	act_relax_interval },
92*7c478bd9Sstevel@tonic-gate 	{ FCAL_TEST_INTERVAL,	"LED-TEST-INTERVAL",	act_test_interval },
93*7c478bd9Sstevel@tonic-gate 	{ FCAL_DISK_PARENT,	"FCAL-DISK-PARENT",	act_disk_parent	},
94*7c478bd9Sstevel@tonic-gate 	{ FCAL_UNIT_PARENT,	"DISK-UNIT-PARENT",	act_unit_parent	},
95*7c478bd9Sstevel@tonic-gate 	{ FCAL_LED_NODES,	"DISK-LED-NODES",	act_led_nodes	}
96*7c478bd9Sstevel@tonic-gate };
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate /*
99*7c478bd9Sstevel@tonic-gate  * length of longest string in table (with space for null terminator)
100*7c478bd9Sstevel@tonic-gate  */
101*7c478bd9Sstevel@tonic-gate #define	MAX_FCAL_TOKEN_LEN	18
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate static const int tab_len = (sizeof (table))/sizeof (table[0]);
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate /*
106*7c478bd9Sstevel@tonic-gate  * get_token
107*7c478bd9Sstevel@tonic-gate  * Parses the current line of data and returns the next token.
108*7c478bd9Sstevel@tonic-gate  * If there are no significant characters in the line, NO_TOKEN is returned.
109*7c478bd9Sstevel@tonic-gate  * If a syntax error is encountered, TOKEN_ERROR is returned.
110*7c478bd9Sstevel@tonic-gate  * Pointer to position in current line is updated to point to the terminator
111*7c478bd9Sstevel@tonic-gate  * of the token, unless TOKEN_ERROR is returned.
112*7c478bd9Sstevel@tonic-gate  */
113*7c478bd9Sstevel@tonic-gate static token_t
get_token(char ** pptr,int lineNo,actfun_t * fun)114*7c478bd9Sstevel@tonic-gate get_token(
115*7c478bd9Sstevel@tonic-gate 	char **pptr,	/* pointer to pointer to position in current line */
116*7c478bd9Sstevel@tonic-gate 			/* *ptr is updated by the function */
117*7c478bd9Sstevel@tonic-gate 	int lineNo,	/* current line number, used for syslog. If set to */
118*7c478bd9Sstevel@tonic-gate 			/* zero, syslogging is supressed */
119*7c478bd9Sstevel@tonic-gate 	actfun_t *fun)	/* pointer to function variable to receive action */
120*7c478bd9Sstevel@tonic-gate 			/* pointer for the token found. NULL may be returned */
121*7c478bd9Sstevel@tonic-gate {
122*7c478bd9Sstevel@tonic-gate 	char		*ptr;
123*7c478bd9Sstevel@tonic-gate 	char		*token_start;
124*7c478bd9Sstevel@tonic-gate 	int		toklen;
125*7c478bd9Sstevel@tonic-gate 	int		i;
126*7c478bd9Sstevel@tonic-gate 	int		ch;
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 	*fun = NULL;
129*7c478bd9Sstevel@tonic-gate 	ptr = *pptr;
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate 	/* strip leading white space */
132*7c478bd9Sstevel@tonic-gate 	do {
133*7c478bd9Sstevel@tonic-gate 		ch = (unsigned)(*ptr++);
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 	} while (isspace(ch));
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	if ((ch == '\0') || (ch == '#')) {
138*7c478bd9Sstevel@tonic-gate 		*pptr = ptr;
139*7c478bd9Sstevel@tonic-gate 		return (NO_TOKEN);	/* empty line or comment */
140*7c478bd9Sstevel@tonic-gate 	}
141*7c478bd9Sstevel@tonic-gate 
142*7c478bd9Sstevel@tonic-gate 	if (!isalpha(ch)) {
143*7c478bd9Sstevel@tonic-gate 		if (lineNo != 0)
144*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_NONALF_TOK, lineNo);
145*7c478bd9Sstevel@tonic-gate 		return (TOKEN_ERROR);
146*7c478bd9Sstevel@tonic-gate 	}
147*7c478bd9Sstevel@tonic-gate 	token_start = ptr - 1;
148*7c478bd9Sstevel@tonic-gate 	toklen = strcspn(token_start, ",: \t");
149*7c478bd9Sstevel@tonic-gate 	*pptr = token_start + toklen;
150*7c478bd9Sstevel@tonic-gate 	/*
151*7c478bd9Sstevel@tonic-gate 	 * got token, now look it up
152*7c478bd9Sstevel@tonic-gate 	 */
153*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < tab_len; i++) {
154*7c478bd9Sstevel@tonic-gate 		if ((strncasecmp(token_start, table[i].tok_str,
155*7c478bd9Sstevel@tonic-gate 		    toklen) == 0) && (table[i].tok_str[toklen] == '\0')) {
156*7c478bd9Sstevel@tonic-gate 			*fun = table[i].action;
157*7c478bd9Sstevel@tonic-gate 			return (table[i].tok);
158*7c478bd9Sstevel@tonic-gate 		}
159*7c478bd9Sstevel@tonic-gate 	}
160*7c478bd9Sstevel@tonic-gate 	if (lineNo != 0)
161*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_UNKN_TOK, lineNo);
162*7c478bd9Sstevel@tonic-gate 	return (TOKEN_ERROR);
163*7c478bd9Sstevel@tonic-gate }
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate static int
act_version(str * p_str,led_dtls_t * dtls)166*7c478bd9Sstevel@tonic-gate act_version(str *p_str, led_dtls_t *dtls)
167*7c478bd9Sstevel@tonic-gate {
168*7c478bd9Sstevel@tonic-gate 	dtls->ver_maj = strtoul(*p_str, p_str, 0);
169*7c478bd9Sstevel@tonic-gate 	if (*(*p_str)++ != '.') {
170*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_VER_FRMT);
171*7c478bd9Sstevel@tonic-gate 		return (-1);
172*7c478bd9Sstevel@tonic-gate 	}
173*7c478bd9Sstevel@tonic-gate 	dtls->ver_min = strtoul(*p_str, p_str, 0);
174*7c478bd9Sstevel@tonic-gate 	if ((**p_str != '\0') && !isspace(**p_str)) {
175*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_VER_FRMT);
176*7c478bd9Sstevel@tonic-gate 		return (-1);
177*7c478bd9Sstevel@tonic-gate 	}
178*7c478bd9Sstevel@tonic-gate 	if ((dtls->ver_maj != 1) || (dtls->ver_min != 0)) {
179*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_WRNGVER, dtls->ver_maj, dtls->ver_min);
180*7c478bd9Sstevel@tonic-gate 		return (-1);
181*7c478bd9Sstevel@tonic-gate 	}
182*7c478bd9Sstevel@tonic-gate 	return (0);
183*7c478bd9Sstevel@tonic-gate }
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate /*
186*7c478bd9Sstevel@tonic-gate  * get space to hold white-space terminated string at *p_str
187*7c478bd9Sstevel@tonic-gate  * advance *p_str to point to terminator
188*7c478bd9Sstevel@tonic-gate  * return copy of string, null terminated
189*7c478bd9Sstevel@tonic-gate  */
190*7c478bd9Sstevel@tonic-gate static int
get_cstr(str * p_str,cstr * p_cstr_res)191*7c478bd9Sstevel@tonic-gate get_cstr(str *p_str, cstr *p_cstr_res)
192*7c478bd9Sstevel@tonic-gate {
193*7c478bd9Sstevel@tonic-gate 	int ch;
194*7c478bd9Sstevel@tonic-gate 	int len;
195*7c478bd9Sstevel@tonic-gate 	char *ptr;
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 	while (isspace(**p_str))
198*7c478bd9Sstevel@tonic-gate 		(*p_str)++;
199*7c478bd9Sstevel@tonic-gate 	ptr = *p_str;
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 	do {
202*7c478bd9Sstevel@tonic-gate 		ch = *++ptr;
203*7c478bd9Sstevel@tonic-gate 	} while ((ch != '\0') && (!isspace(ch)));
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate 	len = ptr - *p_str;
206*7c478bd9Sstevel@tonic-gate 	if (*p_cstr_res != NULL)
207*7c478bd9Sstevel@tonic-gate 		free((void *)(*p_cstr_res));
208*7c478bd9Sstevel@tonic-gate 	ptr = malloc(len + 1);
209*7c478bd9Sstevel@tonic-gate 	*p_cstr_res = ptr;
210*7c478bd9Sstevel@tonic-gate 	if (ptr == NULL) {
211*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
212*7c478bd9Sstevel@tonic-gate 	}
213*7c478bd9Sstevel@tonic-gate 	(void) memcpy(ptr, *p_str, len);
214*7c478bd9Sstevel@tonic-gate 	ptr[len] = '\0';
215*7c478bd9Sstevel@tonic-gate 	(*p_str) += len;
216*7c478bd9Sstevel@tonic-gate 	return (0);
217*7c478bd9Sstevel@tonic-gate }
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate static int
act_leds_board(str * p_str,led_dtls_t * dtls)220*7c478bd9Sstevel@tonic-gate act_leds_board(str *p_str, led_dtls_t *dtls)
221*7c478bd9Sstevel@tonic-gate {
222*7c478bd9Sstevel@tonic-gate 	int res = get_cstr(p_str, &dtls->fcal_leds);
223*7c478bd9Sstevel@tonic-gate 	if (res == 0) {
224*7c478bd9Sstevel@tonic-gate 		if (dtls->fcal_leds[0] != '/') {
225*7c478bd9Sstevel@tonic-gate 			free((void *)dtls->fcal_leds);
226*7c478bd9Sstevel@tonic-gate 			dtls->fcal_leds = NULL;
227*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_REL_PATH);
228*7c478bd9Sstevel@tonic-gate 			return (-1);
229*7c478bd9Sstevel@tonic-gate 		}
230*7c478bd9Sstevel@tonic-gate 	}
231*7c478bd9Sstevel@tonic-gate 	return (res);
232*7c478bd9Sstevel@tonic-gate }
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate static int
act_status_board(str * p_str,led_dtls_t * dtls)235*7c478bd9Sstevel@tonic-gate act_status_board(str *p_str, led_dtls_t *dtls)
236*7c478bd9Sstevel@tonic-gate {
237*7c478bd9Sstevel@tonic-gate 	int res = get_cstr(p_str, &dtls->fcal_status);
238*7c478bd9Sstevel@tonic-gate 	if (res == 0) {
239*7c478bd9Sstevel@tonic-gate 		if (dtls->fcal_status[0] != '/') {
240*7c478bd9Sstevel@tonic-gate 			free((void *)dtls->fcal_status);
241*7c478bd9Sstevel@tonic-gate 			dtls->fcal_status = NULL;
242*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_REL_PATH);
243*7c478bd9Sstevel@tonic-gate 			return (-1);
244*7c478bd9Sstevel@tonic-gate 		}
245*7c478bd9Sstevel@tonic-gate 	}
246*7c478bd9Sstevel@tonic-gate 	return (res);
247*7c478bd9Sstevel@tonic-gate }
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate static int
act_disk_driver(str * p_str,led_dtls_t * dtls)250*7c478bd9Sstevel@tonic-gate act_disk_driver(str *p_str, led_dtls_t *dtls)
251*7c478bd9Sstevel@tonic-gate {
252*7c478bd9Sstevel@tonic-gate 	return (get_cstr(p_str, &dtls->fcal_driver));
253*7c478bd9Sstevel@tonic-gate }
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate static int
act_disk_parent(str * p_str,led_dtls_t * dtls)256*7c478bd9Sstevel@tonic-gate act_disk_parent(str *p_str, led_dtls_t *dtls)
257*7c478bd9Sstevel@tonic-gate {
258*7c478bd9Sstevel@tonic-gate 	return (get_cstr(p_str, &dtls->fcal_disk_parent));
259*7c478bd9Sstevel@tonic-gate }
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate static int
act_unit_parent(str * p_str,led_dtls_t * dtls)262*7c478bd9Sstevel@tonic-gate act_unit_parent(str *p_str, led_dtls_t *dtls)
263*7c478bd9Sstevel@tonic-gate {
264*7c478bd9Sstevel@tonic-gate 	return (get_cstr(p_str, &dtls->disk_unit_parent));
265*7c478bd9Sstevel@tonic-gate }
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate static int
act_led_nodes(str * p_str,led_dtls_t * dtls)268*7c478bd9Sstevel@tonic-gate act_led_nodes(str *p_str, led_dtls_t *dtls)
269*7c478bd9Sstevel@tonic-gate {
270*7c478bd9Sstevel@tonic-gate 	return (get_cstr(p_str, &dtls->disk_led_nodes));
271*7c478bd9Sstevel@tonic-gate }
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate /*
274*7c478bd9Sstevel@tonic-gate  * A number of fields in the led_dtls_t structure have per-disk copies.
275*7c478bd9Sstevel@tonic-gate  * This action routine creates the space for all such fields.
276*7c478bd9Sstevel@tonic-gate  * Following any failure, an error is returned and the calling routine
277*7c478bd9Sstevel@tonic-gate  * must handle the fact that only a subset of these fields are populated.
278*7c478bd9Sstevel@tonic-gate  * In practice, this function is only called by get_token() on behalf of
279*7c478bd9Sstevel@tonic-gate  * fc_led_parse(). fc_led_parse calls free_led_dtls() after any error.
280*7c478bd9Sstevel@tonic-gate  */
281*7c478bd9Sstevel@tonic-gate static int
act_n_disks(str * p_str,led_dtls_t * dtls)282*7c478bd9Sstevel@tonic-gate act_n_disks(str *p_str, led_dtls_t *dtls)
283*7c478bd9Sstevel@tonic-gate {
284*7c478bd9Sstevel@tonic-gate 	int i;
285*7c478bd9Sstevel@tonic-gate 
286*7c478bd9Sstevel@tonic-gate 	if (dtls->n_disks != 0) {
287*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NDISKS_DBL);
288*7c478bd9Sstevel@tonic-gate 		return (-1);
289*7c478bd9Sstevel@tonic-gate 	}
290*7c478bd9Sstevel@tonic-gate 	dtls->n_disks = strtoul(*p_str, p_str, 0);
291*7c478bd9Sstevel@tonic-gate 	if ((**p_str != '\0') && !isspace(**p_str)) {
292*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NUM_TERM);
293*7c478bd9Sstevel@tonic-gate 		return (-1);
294*7c478bd9Sstevel@tonic-gate 	}
295*7c478bd9Sstevel@tonic-gate 	if (dtls->n_disks < 1) {
296*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NO_DISKS);
297*7c478bd9Sstevel@tonic-gate 		return (-1);
298*7c478bd9Sstevel@tonic-gate 	}
299*7c478bd9Sstevel@tonic-gate 	dtls->presence = calloc(dtls->n_disks, sizeof (int));
300*7c478bd9Sstevel@tonic-gate 	if (dtls->presence == NULL)
301*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
302*7c478bd9Sstevel@tonic-gate 	dtls->faults = calloc(dtls->n_disks, sizeof (int));
303*7c478bd9Sstevel@tonic-gate 	if (dtls->faults == NULL)
304*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
305*7c478bd9Sstevel@tonic-gate 	dtls->disk_detected = calloc(dtls->n_disks, sizeof (int));
306*7c478bd9Sstevel@tonic-gate 	if (dtls->disk_detected == NULL)
307*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
308*7c478bd9Sstevel@tonic-gate 	dtls->disk_ready = calloc(dtls->n_disks, sizeof (int));
309*7c478bd9Sstevel@tonic-gate 	if (dtls->disk_ready == NULL)
310*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
311*7c478bd9Sstevel@tonic-gate 	dtls->disk_prev = calloc(dtls->n_disks, sizeof (int));
312*7c478bd9Sstevel@tonic-gate 	if (dtls->disk_prev == NULL)
313*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
314*7c478bd9Sstevel@tonic-gate 	dtls->led_test_end = calloc(dtls->n_disks, sizeof (int));
315*7c478bd9Sstevel@tonic-gate 	if (dtls->led_test_end == NULL)
316*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
317*7c478bd9Sstevel@tonic-gate 	dtls->picl_retry = calloc(dtls->n_disks, sizeof (boolean_t));
318*7c478bd9Sstevel@tonic-gate 	if (dtls->picl_retry == NULL)
319*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
320*7c478bd9Sstevel@tonic-gate 	dtls->disk_port = calloc(dtls->n_disks, sizeof (char *));
321*7c478bd9Sstevel@tonic-gate 	if (dtls->disk_port == NULL) {
322*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
323*7c478bd9Sstevel@tonic-gate 	}
324*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < FCAL_LED_CNT; i++) {
325*7c478bd9Sstevel@tonic-gate 		dtls->led_addr[i] = calloc(dtls->n_disks, sizeof (int));
326*7c478bd9Sstevel@tonic-gate 		if (dtls->led_addr[i] == NULL)
327*7c478bd9Sstevel@tonic-gate 			return (ENOMEM);
328*7c478bd9Sstevel@tonic-gate 		dtls->led_state[i] = calloc(dtls->n_disks,
329*7c478bd9Sstevel@tonic-gate 		    sizeof (led_state_t));
330*7c478bd9Sstevel@tonic-gate 		if (dtls->led_state[i] == NULL)
331*7c478bd9Sstevel@tonic-gate 			return (ENOMEM);
332*7c478bd9Sstevel@tonic-gate 	}
333*7c478bd9Sstevel@tonic-gate 	return (0);
334*7c478bd9Sstevel@tonic-gate }
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate static int
get_assert(str * p_str,int * assert)337*7c478bd9Sstevel@tonic-gate get_assert(str *p_str, int *assert)
338*7c478bd9Sstevel@tonic-gate {
339*7c478bd9Sstevel@tonic-gate 	int i = strtoul(*p_str, p_str, 0);
340*7c478bd9Sstevel@tonic-gate 	if ((**p_str != '\0') && !isspace(**p_str)) {
341*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NUM_TERM);
342*7c478bd9Sstevel@tonic-gate 		return (-1);
343*7c478bd9Sstevel@tonic-gate 	}
344*7c478bd9Sstevel@tonic-gate 	if ((i != 0) && (i != 1)) {
345*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_LOGIC_LVL);
346*7c478bd9Sstevel@tonic-gate 		return (-1);
347*7c478bd9Sstevel@tonic-gate 	}
348*7c478bd9Sstevel@tonic-gate 	*assert = i;
349*7c478bd9Sstevel@tonic-gate 	return (0);
350*7c478bd9Sstevel@tonic-gate }
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate static int
get_pnz(str * p_str,int * pnz)353*7c478bd9Sstevel@tonic-gate get_pnz(str *p_str, int *pnz)
354*7c478bd9Sstevel@tonic-gate {
355*7c478bd9Sstevel@tonic-gate 	int i = strtoul(*p_str, p_str, 0);
356*7c478bd9Sstevel@tonic-gate 	if ((**p_str != '\0') && !isspace(**p_str)) {
357*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NUM_TERM);
358*7c478bd9Sstevel@tonic-gate 		return (-1);
359*7c478bd9Sstevel@tonic-gate 	}
360*7c478bd9Sstevel@tonic-gate 	if (i < 1) {
361*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NOTPOS);
362*7c478bd9Sstevel@tonic-gate 		return (-1);
363*7c478bd9Sstevel@tonic-gate 	}
364*7c478bd9Sstevel@tonic-gate 	*pnz = i;
365*7c478bd9Sstevel@tonic-gate 	return (0);
366*7c478bd9Sstevel@tonic-gate }
367*7c478bd9Sstevel@tonic-gate 
368*7c478bd9Sstevel@tonic-gate static int
act_asrt_pres(str * p_str,led_dtls_t * dtls)369*7c478bd9Sstevel@tonic-gate act_asrt_pres(str *p_str, led_dtls_t *dtls)
370*7c478bd9Sstevel@tonic-gate {
371*7c478bd9Sstevel@tonic-gate 	return (get_assert(p_str, &dtls->assert_presence));
372*7c478bd9Sstevel@tonic-gate }
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate static int
act_asrt_fault(str * p_str,led_dtls_t * dtls)375*7c478bd9Sstevel@tonic-gate act_asrt_fault(str *p_str, led_dtls_t *dtls)
376*7c478bd9Sstevel@tonic-gate {
377*7c478bd9Sstevel@tonic-gate 	return (get_assert(p_str, &dtls->assert_fault));
378*7c478bd9Sstevel@tonic-gate }
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate static int
act_led_on(str * p_str,led_dtls_t * dtls)381*7c478bd9Sstevel@tonic-gate act_led_on(str *p_str, led_dtls_t *dtls)
382*7c478bd9Sstevel@tonic-gate {
383*7c478bd9Sstevel@tonic-gate 	return (get_assert(p_str, &dtls->assert_led_on));
384*7c478bd9Sstevel@tonic-gate }
385*7c478bd9Sstevel@tonic-gate 
386*7c478bd9Sstevel@tonic-gate static int
get_mask(str * p_str,int n_disks,int * p_intarray)387*7c478bd9Sstevel@tonic-gate get_mask(str *p_str, int n_disks, int *p_intarray)
388*7c478bd9Sstevel@tonic-gate {
389*7c478bd9Sstevel@tonic-gate 	int i;
390*7c478bd9Sstevel@tonic-gate 	int j = strtoul(*p_str, p_str, 0);
391*7c478bd9Sstevel@tonic-gate 	if (*(*p_str)++ != ',') {
392*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NUM_TERM);
393*7c478bd9Sstevel@tonic-gate 		return (-1);
394*7c478bd9Sstevel@tonic-gate 	}
395*7c478bd9Sstevel@tonic-gate 	if ((j < 0) || (j > n_disks)) {
396*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_DISK_RANGE);
397*7c478bd9Sstevel@tonic-gate 		return (-1);
398*7c478bd9Sstevel@tonic-gate 	}
399*7c478bd9Sstevel@tonic-gate 	i = strtoul(*p_str, p_str, 0);
400*7c478bd9Sstevel@tonic-gate 	if ((**p_str != '\0') && !isspace(**p_str)) {
401*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NUM_TERM);
402*7c478bd9Sstevel@tonic-gate 		return (-1);
403*7c478bd9Sstevel@tonic-gate 	}
404*7c478bd9Sstevel@tonic-gate 	p_intarray[j] = i;
405*7c478bd9Sstevel@tonic-gate 	return (0);
406*7c478bd9Sstevel@tonic-gate }
407*7c478bd9Sstevel@tonic-gate 
408*7c478bd9Sstevel@tonic-gate static int
act_disk_present(str * p_str,led_dtls_t * dtls)409*7c478bd9Sstevel@tonic-gate act_disk_present(str *p_str, led_dtls_t *dtls)
410*7c478bd9Sstevel@tonic-gate {
411*7c478bd9Sstevel@tonic-gate 	return (get_mask(p_str, dtls->n_disks, dtls->presence));
412*7c478bd9Sstevel@tonic-gate }
413*7c478bd9Sstevel@tonic-gate 
414*7c478bd9Sstevel@tonic-gate static int
act_disk_fault(str * p_str,led_dtls_t * dtls)415*7c478bd9Sstevel@tonic-gate act_disk_fault(str *p_str, led_dtls_t *dtls)
416*7c478bd9Sstevel@tonic-gate {
417*7c478bd9Sstevel@tonic-gate 	return (get_mask(p_str, dtls->n_disks, dtls->faults));
418*7c478bd9Sstevel@tonic-gate }
419*7c478bd9Sstevel@tonic-gate 
420*7c478bd9Sstevel@tonic-gate static int
act_led_id(str * p_str,led_dtls_t * dtls)421*7c478bd9Sstevel@tonic-gate act_led_id(str *p_str, led_dtls_t *dtls)
422*7c478bd9Sstevel@tonic-gate {
423*7c478bd9Sstevel@tonic-gate 	token_t		tok;
424*7c478bd9Sstevel@tonic-gate 	actfun_t	action;
425*7c478bd9Sstevel@tonic-gate 	int		i;
426*7c478bd9Sstevel@tonic-gate 	int		j = strtoul(*p_str, p_str, 0);
427*7c478bd9Sstevel@tonic-gate 
428*7c478bd9Sstevel@tonic-gate 	if (*(*p_str)++ != ',') {
429*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NUM_TERM);
430*7c478bd9Sstevel@tonic-gate 		return (-1);
431*7c478bd9Sstevel@tonic-gate 	}
432*7c478bd9Sstevel@tonic-gate 	if ((j < 0) || (j >= dtls->n_disks)) {
433*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_DISK_RANGE);
434*7c478bd9Sstevel@tonic-gate 		return (-1);
435*7c478bd9Sstevel@tonic-gate 	}
436*7c478bd9Sstevel@tonic-gate 	tok = get_token(p_str, 0, &action);
437*7c478bd9Sstevel@tonic-gate 	if ((tok <= LED_PROPS_START) || (tok >= LED_PROPS_END)) {
438*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NO_LED_PROP);
439*7c478bd9Sstevel@tonic-gate 		return (-1);
440*7c478bd9Sstevel@tonic-gate 	}
441*7c478bd9Sstevel@tonic-gate 	if (*(*p_str)++ != ',') {
442*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_PROP_TERM);
443*7c478bd9Sstevel@tonic-gate 		return (-1);
444*7c478bd9Sstevel@tonic-gate 	}
445*7c478bd9Sstevel@tonic-gate 	i = strtoul(*p_str, p_str, 0);
446*7c478bd9Sstevel@tonic-gate 	if ((**p_str != '\0') && !isspace(**p_str)) {
447*7c478bd9Sstevel@tonic-gate 		SYSLOG(LOG_ERR, EM_NUM_TERM);
448*7c478bd9Sstevel@tonic-gate 		return (-1);
449*7c478bd9Sstevel@tonic-gate 	}
450*7c478bd9Sstevel@tonic-gate 	dtls->led_addr[tok - FCAL_REMOK_LED][j] = i;
451*7c478bd9Sstevel@tonic-gate 	return (0);
452*7c478bd9Sstevel@tonic-gate }
453*7c478bd9Sstevel@tonic-gate 
454*7c478bd9Sstevel@tonic-gate static int
act_slow_poll(str * p_str,led_dtls_t * dtls)455*7c478bd9Sstevel@tonic-gate act_slow_poll(str *p_str, led_dtls_t *dtls)
456*7c478bd9Sstevel@tonic-gate {
457*7c478bd9Sstevel@tonic-gate 	return (get_pnz(p_str, &dtls->slow_poll_ticks));
458*7c478bd9Sstevel@tonic-gate }
459*7c478bd9Sstevel@tonic-gate 
460*7c478bd9Sstevel@tonic-gate static int
act_fast_poll(str * p_str,led_dtls_t * dtls)461*7c478bd9Sstevel@tonic-gate act_fast_poll(str *p_str, led_dtls_t *dtls)
462*7c478bd9Sstevel@tonic-gate {
463*7c478bd9Sstevel@tonic-gate 	return (get_pnz(p_str, &dtls->fast_poll));
464*7c478bd9Sstevel@tonic-gate }
465*7c478bd9Sstevel@tonic-gate 
466*7c478bd9Sstevel@tonic-gate static int
act_relax_interval(str * p_str,led_dtls_t * dtls)467*7c478bd9Sstevel@tonic-gate act_relax_interval(str *p_str, led_dtls_t *dtls)
468*7c478bd9Sstevel@tonic-gate {
469*7c478bd9Sstevel@tonic-gate 	return (get_pnz(p_str, &dtls->relax_time_ticks));
470*7c478bd9Sstevel@tonic-gate }
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate static int
act_test_interval(str * p_str,led_dtls_t * dtls)473*7c478bd9Sstevel@tonic-gate act_test_interval(str *p_str, led_dtls_t *dtls)
474*7c478bd9Sstevel@tonic-gate {
475*7c478bd9Sstevel@tonic-gate 	return (get_pnz(p_str, &dtls->led_test_time));
476*7c478bd9Sstevel@tonic-gate }
477*7c478bd9Sstevel@tonic-gate 
478*7c478bd9Sstevel@tonic-gate /*
479*7c478bd9Sstevel@tonic-gate  * Create a led_dtls_t structure
480*7c478bd9Sstevel@tonic-gate  * Parse configuration file and populate the led_dtls_t
481*7c478bd9Sstevel@tonic-gate  * In the event of an error, free the structure and return an error
482*7c478bd9Sstevel@tonic-gate  */
483*7c478bd9Sstevel@tonic-gate int
fc_led_parse(FILE * fp,led_dtls_t ** p_dtls)484*7c478bd9Sstevel@tonic-gate fc_led_parse(FILE *fp, led_dtls_t **p_dtls)
485*7c478bd9Sstevel@tonic-gate {
486*7c478bd9Sstevel@tonic-gate 	int		lineNo = 0;
487*7c478bd9Sstevel@tonic-gate 	int		err = 0;
488*7c478bd9Sstevel@tonic-gate 	char		linebuf[160];
489*7c478bd9Sstevel@tonic-gate 	char		*ptr;
490*7c478bd9Sstevel@tonic-gate 	led_dtls_t	*dtls = calloc(1, sizeof (led_dtls_t));
491*7c478bd9Sstevel@tonic-gate 	actfun_t	action;
492*7c478bd9Sstevel@tonic-gate 	token_t		tok;
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate 	*p_dtls = dtls;
495*7c478bd9Sstevel@tonic-gate 	if (dtls == NULL) {
496*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
497*7c478bd9Sstevel@tonic-gate 	}
498*7c478bd9Sstevel@tonic-gate 	dtls->ver_min = -1;	/* mark as version unknown */
499*7c478bd9Sstevel@tonic-gate 
500*7c478bd9Sstevel@tonic-gate 	while ((ptr = fgets(linebuf, sizeof (linebuf), fp)) != NULL) {
501*7c478bd9Sstevel@tonic-gate 		lineNo++;
502*7c478bd9Sstevel@tonic-gate 		tok = get_token(&ptr, lineNo, &action);
503*7c478bd9Sstevel@tonic-gate 		if (tok == NO_TOKEN)
504*7c478bd9Sstevel@tonic-gate 			continue;
505*7c478bd9Sstevel@tonic-gate 		if (tok == TOKEN_ERROR) {
506*7c478bd9Sstevel@tonic-gate 			err = -1;
507*7c478bd9Sstevel@tonic-gate 			break;
508*7c478bd9Sstevel@tonic-gate 		}
509*7c478bd9Sstevel@tonic-gate 		if (tok == FCAL_VERSION) {
510*7c478bd9Sstevel@tonic-gate 			if ((err = (*action)(&ptr, dtls)) != 0)
511*7c478bd9Sstevel@tonic-gate 				break;
512*7c478bd9Sstevel@tonic-gate 			else
513*7c478bd9Sstevel@tonic-gate 				continue;
514*7c478bd9Sstevel@tonic-gate 		}
515*7c478bd9Sstevel@tonic-gate 		if (dtls->ver_min < 0) {
516*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_NOVERS);
517*7c478bd9Sstevel@tonic-gate 			err = -1;
518*7c478bd9Sstevel@tonic-gate 			break;
519*7c478bd9Sstevel@tonic-gate 		}
520*7c478bd9Sstevel@tonic-gate 		if (tok <= LINE_DEFS) {
521*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_INVAL_TOK, lineNo);
522*7c478bd9Sstevel@tonic-gate 			err = -1;
523*7c478bd9Sstevel@tonic-gate 			break;
524*7c478bd9Sstevel@tonic-gate 		}
525*7c478bd9Sstevel@tonic-gate 		if (*ptr++ != ':') {
526*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_NOCOLON, lineNo);
527*7c478bd9Sstevel@tonic-gate 			err = -1;
528*7c478bd9Sstevel@tonic-gate 			break;
529*7c478bd9Sstevel@tonic-gate 		}
530*7c478bd9Sstevel@tonic-gate 		if ((err = (*action)(&ptr, dtls)) != 0) {
531*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_ERRLINE, lineNo);
532*7c478bd9Sstevel@tonic-gate 			break;
533*7c478bd9Sstevel@tonic-gate 		}
534*7c478bd9Sstevel@tonic-gate 		else
535*7c478bd9Sstevel@tonic-gate 			continue;
536*7c478bd9Sstevel@tonic-gate 	}
537*7c478bd9Sstevel@tonic-gate 
538*7c478bd9Sstevel@tonic-gate 	if (err == 0) {
539*7c478bd9Sstevel@tonic-gate 		err = -1;	/* just in case */
540*7c478bd9Sstevel@tonic-gate 		if (dtls->ver_min < 0) {
541*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_NOVERS);
542*7c478bd9Sstevel@tonic-gate 		} else if (dtls->n_disks == 0) {
543*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_NO_DISKS);
544*7c478bd9Sstevel@tonic-gate 		} else if (dtls->fcal_leds == NULL) {
545*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_STR_NOT_SET, "fcal-leds");
546*7c478bd9Sstevel@tonic-gate 		} else if (dtls->fcal_status == NULL) {
547*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_STR_NOT_SET, "fcal-status");
548*7c478bd9Sstevel@tonic-gate 		} else if (dtls->fcal_driver == NULL) {
549*7c478bd9Sstevel@tonic-gate 			SYSLOG(LOG_ERR, EM_STR_NOT_SET, "fcal-driver");
550*7c478bd9Sstevel@tonic-gate 		} else
551*7c478bd9Sstevel@tonic-gate 			err = 0;
552*7c478bd9Sstevel@tonic-gate 	}
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate 	if (err != 0) {
555*7c478bd9Sstevel@tonic-gate 		/*
556*7c478bd9Sstevel@tonic-gate 		 * clean up after error detected
557*7c478bd9Sstevel@tonic-gate 		 */
558*7c478bd9Sstevel@tonic-gate 		free_led_dtls(dtls);
559*7c478bd9Sstevel@tonic-gate 		*p_dtls = NULL;
560*7c478bd9Sstevel@tonic-gate 		return (err);
561*7c478bd9Sstevel@tonic-gate 	}
562*7c478bd9Sstevel@tonic-gate 
563*7c478bd9Sstevel@tonic-gate 	/*
564*7c478bd9Sstevel@tonic-gate 	 * set any unset timers to default time
565*7c478bd9Sstevel@tonic-gate 	 */
566*7c478bd9Sstevel@tonic-gate 	if (dtls->slow_poll_ticks == 0)
567*7c478bd9Sstevel@tonic-gate 		dtls->slow_poll_ticks = DFLT_SLOW_POLL;
568*7c478bd9Sstevel@tonic-gate 	if (dtls->fast_poll == 0)
569*7c478bd9Sstevel@tonic-gate 		dtls->fast_poll = DFLT_FAST_POLL;
570*7c478bd9Sstevel@tonic-gate 	if (dtls->relax_time_ticks == 0)
571*7c478bd9Sstevel@tonic-gate 		dtls->relax_time_ticks = DFLT_RELAX_TIME;
572*7c478bd9Sstevel@tonic-gate 	if (dtls->led_test_time == 0)
573*7c478bd9Sstevel@tonic-gate 		dtls->led_test_time = DFLT_TEST_TIME;
574*7c478bd9Sstevel@tonic-gate 
575*7c478bd9Sstevel@tonic-gate 	/*
576*7c478bd9Sstevel@tonic-gate 	 * set polling flag to avoid a start-up glitch
577*7c478bd9Sstevel@tonic-gate 	 * it will be cleared again if the poll thread fails
578*7c478bd9Sstevel@tonic-gate 	 */
579*7c478bd9Sstevel@tonic-gate 	dtls->polling = B_TRUE;
580*7c478bd9Sstevel@tonic-gate 
581*7c478bd9Sstevel@tonic-gate 	/*
582*7c478bd9Sstevel@tonic-gate 	 * convert derived timers to multiples of fast poll time
583*7c478bd9Sstevel@tonic-gate 	 */
584*7c478bd9Sstevel@tonic-gate 	dtls->slow_poll_ticks += dtls->fast_poll - 1;	/* for round up */
585*7c478bd9Sstevel@tonic-gate 	dtls->slow_poll_ticks /= dtls->fast_poll;
586*7c478bd9Sstevel@tonic-gate 	dtls->relax_time_ticks += dtls->fast_poll - 1;
587*7c478bd9Sstevel@tonic-gate 	dtls->relax_time_ticks /= dtls->fast_poll;
588*7c478bd9Sstevel@tonic-gate 	dtls->led_test_time += dtls->fast_poll - 1;
589*7c478bd9Sstevel@tonic-gate 	dtls->led_test_time /= dtls->fast_poll;
590*7c478bd9Sstevel@tonic-gate 	return (0);
591*7c478bd9Sstevel@tonic-gate }
592*7c478bd9Sstevel@tonic-gate 
593*7c478bd9Sstevel@tonic-gate void
free_led_dtls(led_dtls_t * dtls)594*7c478bd9Sstevel@tonic-gate free_led_dtls(led_dtls_t *dtls)
595*7c478bd9Sstevel@tonic-gate {
596*7c478bd9Sstevel@tonic-gate 	int	i;
597*7c478bd9Sstevel@tonic-gate 
598*7c478bd9Sstevel@tonic-gate 	if (dtls == NULL)
599*7c478bd9Sstevel@tonic-gate 		return;
600*7c478bd9Sstevel@tonic-gate 	if (dtls->fcal_leds != NULL)
601*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->fcal_leds);
602*7c478bd9Sstevel@tonic-gate 	if (dtls->fcal_status != NULL)
603*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->fcal_status);
604*7c478bd9Sstevel@tonic-gate 	if (dtls->fcal_driver != NULL)
605*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->fcal_driver);
606*7c478bd9Sstevel@tonic-gate 	if (dtls->presence != NULL)
607*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->presence);
608*7c478bd9Sstevel@tonic-gate 	if (dtls->faults != NULL)
609*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->faults);
610*7c478bd9Sstevel@tonic-gate 	if (dtls->disk_detected != NULL)
611*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->disk_detected);
612*7c478bd9Sstevel@tonic-gate 	if (dtls->disk_ready != NULL)
613*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->disk_ready);
614*7c478bd9Sstevel@tonic-gate 	if (dtls->disk_prev != NULL)
615*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->disk_prev);
616*7c478bd9Sstevel@tonic-gate 	if (dtls->led_test_end != NULL)
617*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->led_test_end);
618*7c478bd9Sstevel@tonic-gate 	if (dtls->picl_retry != NULL)
619*7c478bd9Sstevel@tonic-gate 		free((void *)dtls->picl_retry);
620*7c478bd9Sstevel@tonic-gate 	if (dtls->disk_port != NULL) {
621*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < dtls->n_disks; i++) {
622*7c478bd9Sstevel@tonic-gate 			if (dtls->disk_port[i] != NULL)
623*7c478bd9Sstevel@tonic-gate 				free(dtls->disk_port[i]);
624*7c478bd9Sstevel@tonic-gate 		}
625*7c478bd9Sstevel@tonic-gate 		free(dtls->disk_port);
626*7c478bd9Sstevel@tonic-gate 	}
627*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < FCAL_LED_CNT; i++) {
628*7c478bd9Sstevel@tonic-gate 		if (dtls->led_addr[i] != NULL)
629*7c478bd9Sstevel@tonic-gate 			free((void *)dtls->led_addr[i]);
630*7c478bd9Sstevel@tonic-gate 		if (dtls->led_state[i] != NULL)
631*7c478bd9Sstevel@tonic-gate 			free((void *)dtls->led_state[i]);
632*7c478bd9Sstevel@tonic-gate 	}
633*7c478bd9Sstevel@tonic-gate 
634*7c478bd9Sstevel@tonic-gate 	free(dtls);
635*7c478bd9Sstevel@tonic-gate }
636