1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate * Implementation to get PORT nodes state and condition information
31*0Sstevel@tonic-gate */
32*0Sstevel@tonic-gate #include <stdio.h>
33*0Sstevel@tonic-gate #include <stdlib.h>
34*0Sstevel@tonic-gate #include <ctype.h>
35*0Sstevel@tonic-gate #include <strings.h>
36*0Sstevel@tonic-gate #include <fcntl.h>
37*0Sstevel@tonic-gate #include <unistd.h>
38*0Sstevel@tonic-gate #include <stropts.h>
39*0Sstevel@tonic-gate #include <locale.h>
40*0Sstevel@tonic-gate #include <syslog.h>
41*0Sstevel@tonic-gate #include <sys/types.h>
42*0Sstevel@tonic-gate #include <sys/termios.h>
43*0Sstevel@tonic-gate #include <sys/stat.h>
44*0Sstevel@tonic-gate #include <fcntl.h>
45*0Sstevel@tonic-gate #include <kstat.h>
46*0Sstevel@tonic-gate #include <signal.h>
47*0Sstevel@tonic-gate #include <assert.h>
48*0Sstevel@tonic-gate #include <config_admin.h>
49*0Sstevel@tonic-gate
50*0Sstevel@tonic-gate #include <picl.h>
51*0Sstevel@tonic-gate #include "piclfrutree.h"
52*0Sstevel@tonic-gate
53*0Sstevel@tonic-gate #define LINK_UP "link_up"
54*0Sstevel@tonic-gate #define DUPLEX "duplex"
55*0Sstevel@tonic-gate #define IF_SPEED "ifspeed"
56*0Sstevel@tonic-gate #define IERRORS "ierrors"
57*0Sstevel@tonic-gate #define IPACKETS "ipackets"
58*0Sstevel@tonic-gate #define OERRORS "oerrors"
59*0Sstevel@tonic-gate #define OPACKETS "opackets"
60*0Sstevel@tonic-gate #define NOCANPUT "nocanput"
61*0Sstevel@tonic-gate #define RUNT_ERRORS "runt_errors"
62*0Sstevel@tonic-gate #define COLLISIONS "collisions"
63*0Sstevel@tonic-gate
64*0Sstevel@tonic-gate typedef int (*funcp)(kstat_ctl_t *, char *, int);
65*0Sstevel@tonic-gate
66*0Sstevel@tonic-gate static kstat_named_t *kstat_name_lookup(kstat_ctl_t *, char *, int, char *);
67*0Sstevel@tonic-gate static int kstat_network_port_state(kstat_ctl_t *kc, char *, int);
68*0Sstevel@tonic-gate static int kstat_network_port_cond(kstat_ctl_t *kc, char *, int);
69*0Sstevel@tonic-gate static int serial_port_state(kstat_ctl_t *, char *, int);
70*0Sstevel@tonic-gate static int serial_port_cond(kstat_ctl_t *kc, char *, int);
71*0Sstevel@tonic-gate static int parallel_port_state(kstat_ctl_t *, char *, int);
72*0Sstevel@tonic-gate static int parallel_port_cond(kstat_ctl_t *kc, char *, int);
73*0Sstevel@tonic-gate
74*0Sstevel@tonic-gate static funcp port_state[] = {
75*0Sstevel@tonic-gate kstat_network_port_state,
76*0Sstevel@tonic-gate serial_port_state,
77*0Sstevel@tonic-gate parallel_port_state
78*0Sstevel@tonic-gate };
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gate static funcp port_cond[] = {
81*0Sstevel@tonic-gate kstat_network_port_cond,
82*0Sstevel@tonic-gate serial_port_cond,
83*0Sstevel@tonic-gate parallel_port_cond
84*0Sstevel@tonic-gate };
85*0Sstevel@tonic-gate
86*0Sstevel@tonic-gate /*
87*0Sstevel@tonic-gate * kstat_port_state: returns ethernet, or serial, or parallel port status
88*0Sstevel@tonic-gate * 1 = up, 0 = down, anything else = unknown
89*0Sstevel@tonic-gate */
90*0Sstevel@tonic-gate int
kstat_port_state(frutree_port_type_t port_type,char * driver_name,int driver_instance)91*0Sstevel@tonic-gate kstat_port_state(frutree_port_type_t port_type, char *driver_name,
92*0Sstevel@tonic-gate int driver_instance)
93*0Sstevel@tonic-gate {
94*0Sstevel@tonic-gate int rc = -1;
95*0Sstevel@tonic-gate kstat_ctl_t *kc = NULL;
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gate switch (port_type) {
98*0Sstevel@tonic-gate case NETWORK_PORT:
99*0Sstevel@tonic-gate case SERIAL_PORT:
100*0Sstevel@tonic-gate case PARALLEL_PORT:
101*0Sstevel@tonic-gate if ((kc = kstat_open()) == NULL) {
102*0Sstevel@tonic-gate return (-1);
103*0Sstevel@tonic-gate }
104*0Sstevel@tonic-gate rc = port_state[port_type](kc, driver_name, driver_instance);
105*0Sstevel@tonic-gate kstat_close(kc);
106*0Sstevel@tonic-gate return (rc);
107*0Sstevel@tonic-gate default:
108*0Sstevel@tonic-gate return (-1);
109*0Sstevel@tonic-gate }
110*0Sstevel@tonic-gate }
111*0Sstevel@tonic-gate
112*0Sstevel@tonic-gate /*
113*0Sstevel@tonic-gate * kstat_port_cond: returns ethernet, or serial, or parallel port condition
114*0Sstevel@tonic-gate */
115*0Sstevel@tonic-gate int
kstat_port_cond(frutree_port_type_t port_type,char * driver_name,int driver_instance)116*0Sstevel@tonic-gate kstat_port_cond(frutree_port_type_t port_type, char *driver_name,
117*0Sstevel@tonic-gate int driver_instance)
118*0Sstevel@tonic-gate {
119*0Sstevel@tonic-gate int rc = -1;
120*0Sstevel@tonic-gate kstat_ctl_t *kc = NULL;
121*0Sstevel@tonic-gate switch (port_type) {
122*0Sstevel@tonic-gate case NETWORK_PORT:
123*0Sstevel@tonic-gate case SERIAL_PORT:
124*0Sstevel@tonic-gate case PARALLEL_PORT:
125*0Sstevel@tonic-gate if ((kc = kstat_open()) == NULL) {
126*0Sstevel@tonic-gate return (-1);
127*0Sstevel@tonic-gate }
128*0Sstevel@tonic-gate rc = port_cond[port_type](kc, driver_name, driver_instance);
129*0Sstevel@tonic-gate kstat_close(kc);
130*0Sstevel@tonic-gate return (rc);
131*0Sstevel@tonic-gate default:
132*0Sstevel@tonic-gate return (-1);
133*0Sstevel@tonic-gate }
134*0Sstevel@tonic-gate }
135*0Sstevel@tonic-gate
136*0Sstevel@tonic-gate static kstat_named_t *
kstat_name_lookup(kstat_ctl_t * kc,char * ks_module,int ks_instance,char * name)137*0Sstevel@tonic-gate kstat_name_lookup(kstat_ctl_t *kc, char *ks_module, int ks_instance, char *name)
138*0Sstevel@tonic-gate {
139*0Sstevel@tonic-gate kstat_t *ksp;
140*0Sstevel@tonic-gate
141*0Sstevel@tonic-gate assert(kc);
142*0Sstevel@tonic-gate assert(ks_module);
143*0Sstevel@tonic-gate assert(name);
144*0Sstevel@tonic-gate
145*0Sstevel@tonic-gate for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
146*0Sstevel@tonic-gate if (strcmp(ksp->ks_module, ks_module) == 0 &&
147*0Sstevel@tonic-gate ksp->ks_instance == ks_instance &&
148*0Sstevel@tonic-gate ksp->ks_type == KSTAT_TYPE_NAMED &&
149*0Sstevel@tonic-gate kstat_read(kc, ksp, NULL) != -1 &&
150*0Sstevel@tonic-gate kstat_data_lookup(ksp, name)) {
151*0Sstevel@tonic-gate
152*0Sstevel@tonic-gate ksp = kstat_lookup(kc, ks_module, ks_instance,
153*0Sstevel@tonic-gate ksp->ks_name);
154*0Sstevel@tonic-gate if (!ksp)
155*0Sstevel@tonic-gate return (NULL);
156*0Sstevel@tonic-gate if (kstat_read(kc, ksp, NULL) == -1)
157*0Sstevel@tonic-gate return (NULL);
158*0Sstevel@tonic-gate return ((kstat_named_t *)kstat_data_lookup(ksp, name));
159*0Sstevel@tonic-gate }
160*0Sstevel@tonic-gate }
161*0Sstevel@tonic-gate return (NULL);
162*0Sstevel@tonic-gate }
163*0Sstevel@tonic-gate
164*0Sstevel@tonic-gate /*
165*0Sstevel@tonic-gate * kstat_network_port_state: returns kstat info of a network port
166*0Sstevel@tonic-gate * 1 = up, 0 = down, anything else = unknown
167*0Sstevel@tonic-gate */
168*0Sstevel@tonic-gate static int
kstat_network_port_state(kstat_ctl_t * kc,char * ks_module,int ks_instance)169*0Sstevel@tonic-gate kstat_network_port_state(kstat_ctl_t *kc, char *ks_module, int ks_instance)
170*0Sstevel@tonic-gate {
171*0Sstevel@tonic-gate kstat_named_t *port_datap = NULL;
172*0Sstevel@tonic-gate
173*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
174*0Sstevel@tonic-gate LINK_UP)) == NULL) {
175*0Sstevel@tonic-gate return (-1);
176*0Sstevel@tonic-gate }
177*0Sstevel@tonic-gate if (port_datap == NULL) {
178*0Sstevel@tonic-gate return (-1);
179*0Sstevel@tonic-gate }
180*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
181*0Sstevel@tonic-gate if (port_datap->value.ui32 == 1) {
182*0Sstevel@tonic-gate return (1);
183*0Sstevel@tonic-gate } else if (port_datap->value.ui32 == 0) {
184*0Sstevel@tonic-gate return (0);
185*0Sstevel@tonic-gate } else {
186*0Sstevel@tonic-gate return (-1);
187*0Sstevel@tonic-gate }
188*0Sstevel@tonic-gate } else {
189*0Sstevel@tonic-gate if (port_datap->value.ui64 == 1) {
190*0Sstevel@tonic-gate return (1);
191*0Sstevel@tonic-gate } else if (port_datap->value.ui64 == 0) {
192*0Sstevel@tonic-gate return (0);
193*0Sstevel@tonic-gate } else {
194*0Sstevel@tonic-gate return (-1);
195*0Sstevel@tonic-gate }
196*0Sstevel@tonic-gate }
197*0Sstevel@tonic-gate }
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate /*
200*0Sstevel@tonic-gate * kstat_network_port_cond: returns kstat info of a network port
201*0Sstevel@tonic-gate * 0 = OK, 1 = FAILING, 2 = FAILED, 3 = TESTING, -1 = unknown
202*0Sstevel@tonic-gate */
203*0Sstevel@tonic-gate static int
kstat_network_port_cond(kstat_ctl_t * kc,char * ks_module,int ks_instance)204*0Sstevel@tonic-gate kstat_network_port_cond(kstat_ctl_t *kc, char *ks_module, int ks_instance)
205*0Sstevel@tonic-gate {
206*0Sstevel@tonic-gate kstat_named_t *port_datap = NULL;
207*0Sstevel@tonic-gate uint64_t collisions, runt, link_up, link_duplex;
208*0Sstevel@tonic-gate uint64_t ifspeed, ierrors, ipackets, oerrors, opackets;
209*0Sstevel@tonic-gate
210*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
211*0Sstevel@tonic-gate LINK_UP)) == NULL) {
212*0Sstevel@tonic-gate return (-1);
213*0Sstevel@tonic-gate }
214*0Sstevel@tonic-gate
215*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
216*0Sstevel@tonic-gate link_up = port_datap->value.ui32;
217*0Sstevel@tonic-gate } else {
218*0Sstevel@tonic-gate link_up = port_datap->value.ui64;
219*0Sstevel@tonic-gate }
220*0Sstevel@tonic-gate if (link_up == 0) {
221*0Sstevel@tonic-gate return (2);
222*0Sstevel@tonic-gate }
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
225*0Sstevel@tonic-gate DUPLEX)) == NULL) {
226*0Sstevel@tonic-gate return (-1);
227*0Sstevel@tonic-gate }
228*0Sstevel@tonic-gate
229*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
230*0Sstevel@tonic-gate link_duplex = port_datap->value.ui32;
231*0Sstevel@tonic-gate } else {
232*0Sstevel@tonic-gate link_duplex = port_datap->value.ui64;
233*0Sstevel@tonic-gate }
234*0Sstevel@tonic-gate if (link_duplex == 0) {
235*0Sstevel@tonic-gate return (2);
236*0Sstevel@tonic-gate }
237*0Sstevel@tonic-gate
238*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
239*0Sstevel@tonic-gate IF_SPEED)) == NULL) {
240*0Sstevel@tonic-gate return (-1);
241*0Sstevel@tonic-gate }
242*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
243*0Sstevel@tonic-gate ifspeed = port_datap->value.ui32;
244*0Sstevel@tonic-gate } else {
245*0Sstevel@tonic-gate ifspeed = port_datap->value.ui64;
246*0Sstevel@tonic-gate }
247*0Sstevel@tonic-gate if (ifspeed == 0) {
248*0Sstevel@tonic-gate return (2);
249*0Sstevel@tonic-gate }
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate /* check for FAILING conditions */
252*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
253*0Sstevel@tonic-gate IERRORS)) == NULL) {
254*0Sstevel@tonic-gate return (-1);
255*0Sstevel@tonic-gate }
256*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
257*0Sstevel@tonic-gate ierrors = port_datap->value.ui32;
258*0Sstevel@tonic-gate } else {
259*0Sstevel@tonic-gate ierrors = port_datap->value.ui64;
260*0Sstevel@tonic-gate }
261*0Sstevel@tonic-gate
262*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
263*0Sstevel@tonic-gate IPACKETS)) == NULL) {
264*0Sstevel@tonic-gate return (-1);
265*0Sstevel@tonic-gate }
266*0Sstevel@tonic-gate
267*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
268*0Sstevel@tonic-gate ipackets = port_datap->value.ui32;
269*0Sstevel@tonic-gate } else {
270*0Sstevel@tonic-gate ipackets = port_datap->value.ui64;
271*0Sstevel@tonic-gate }
272*0Sstevel@tonic-gate if (ierrors > ipackets/10) {
273*0Sstevel@tonic-gate return (1);
274*0Sstevel@tonic-gate }
275*0Sstevel@tonic-gate
276*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
277*0Sstevel@tonic-gate OERRORS)) == NULL) {
278*0Sstevel@tonic-gate return (-1);
279*0Sstevel@tonic-gate }
280*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
281*0Sstevel@tonic-gate oerrors = port_datap->value.ui32;
282*0Sstevel@tonic-gate } else {
283*0Sstevel@tonic-gate oerrors = port_datap->value.ui64;
284*0Sstevel@tonic-gate }
285*0Sstevel@tonic-gate
286*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
287*0Sstevel@tonic-gate OPACKETS)) == NULL) {
288*0Sstevel@tonic-gate return (-1);
289*0Sstevel@tonic-gate }
290*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
291*0Sstevel@tonic-gate opackets = port_datap->value.ui32;
292*0Sstevel@tonic-gate } else {
293*0Sstevel@tonic-gate opackets = port_datap->value.ui64;
294*0Sstevel@tonic-gate }
295*0Sstevel@tonic-gate if (oerrors > opackets/10) {
296*0Sstevel@tonic-gate return (1);
297*0Sstevel@tonic-gate }
298*0Sstevel@tonic-gate
299*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
300*0Sstevel@tonic-gate RUNT_ERRORS)) == NULL) {
301*0Sstevel@tonic-gate return (-1);
302*0Sstevel@tonic-gate }
303*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
304*0Sstevel@tonic-gate runt = port_datap->value.ui32;
305*0Sstevel@tonic-gate } else {
306*0Sstevel@tonic-gate runt = port_datap->value.ui64;
307*0Sstevel@tonic-gate }
308*0Sstevel@tonic-gate if (runt > ipackets/10) {
309*0Sstevel@tonic-gate return (1);
310*0Sstevel@tonic-gate }
311*0Sstevel@tonic-gate
312*0Sstevel@tonic-gate if ((port_datap = kstat_name_lookup(kc, ks_module, ks_instance,
313*0Sstevel@tonic-gate COLLISIONS)) == NULL) {
314*0Sstevel@tonic-gate return (-1);
315*0Sstevel@tonic-gate }
316*0Sstevel@tonic-gate if (port_datap->data_type == KSTAT_DATA_UINT32) {
317*0Sstevel@tonic-gate collisions = port_datap->value.ui32;
318*0Sstevel@tonic-gate } else {
319*0Sstevel@tonic-gate collisions = port_datap->value.ui64;
320*0Sstevel@tonic-gate }
321*0Sstevel@tonic-gate if (collisions > (opackets+ipackets)/30) {
322*0Sstevel@tonic-gate return (1);
323*0Sstevel@tonic-gate }
324*0Sstevel@tonic-gate return (0);
325*0Sstevel@tonic-gate }
326*0Sstevel@tonic-gate
327*0Sstevel@tonic-gate /*
328*0Sstevel@tonic-gate * serial_port_state: returns status a serial port
329*0Sstevel@tonic-gate * 1 = up, 0 = down, anything else = unknown
330*0Sstevel@tonic-gate */
331*0Sstevel@tonic-gate
332*0Sstevel@tonic-gate /* ARGSUSED */
333*0Sstevel@tonic-gate static int
serial_port_state(kstat_ctl_t * kc,char * driver,int instance)334*0Sstevel@tonic-gate serial_port_state(kstat_ctl_t *kc, char *driver, int instance)
335*0Sstevel@tonic-gate {
336*0Sstevel@tonic-gate int fd;
337*0Sstevel@tonic-gate char device[20];
338*0Sstevel@tonic-gate struct termios flags;
339*0Sstevel@tonic-gate struct sigaction old_sa, new_sa;
340*0Sstevel@tonic-gate static void sig_alarm_handler(int);
341*0Sstevel@tonic-gate
342*0Sstevel@tonic-gate (void) memset(&old_sa, 0, sizeof (old_sa));
343*0Sstevel@tonic-gate (void) memset(&new_sa, 0, sizeof (new_sa));
344*0Sstevel@tonic-gate new_sa.sa_handler = sig_alarm_handler;
345*0Sstevel@tonic-gate (void) sigaction(SIGALRM, &new_sa, &old_sa);
346*0Sstevel@tonic-gate (void) alarm(1);
347*0Sstevel@tonic-gate
348*0Sstevel@tonic-gate (void) snprintf(device, sizeof (device), "/dev/tty%c", instance+'a');
349*0Sstevel@tonic-gate fd = open(device, O_RDONLY|O_NDELAY|O_NONBLOCK|O_NOCTTY);
350*0Sstevel@tonic-gate
351*0Sstevel@tonic-gate /* Restore sig action flags */
352*0Sstevel@tonic-gate (void) sigaction(SIGALRM, &old_sa, (struct sigaction *)0);
353*0Sstevel@tonic-gate /* Disable alarm */
354*0Sstevel@tonic-gate (void) alarm(0);
355*0Sstevel@tonic-gate
356*0Sstevel@tonic-gate if (fd == -1) {
357*0Sstevel@tonic-gate return (-1);
358*0Sstevel@tonic-gate }
359*0Sstevel@tonic-gate
360*0Sstevel@tonic-gate if (isatty(fd) == 0) {
361*0Sstevel@tonic-gate (void) close(fd);
362*0Sstevel@tonic-gate return (-1);
363*0Sstevel@tonic-gate }
364*0Sstevel@tonic-gate (void) memset(&flags, 0, sizeof (flags));
365*0Sstevel@tonic-gate if (ioctl(fd, TCGETS, &flags) != 0) {
366*0Sstevel@tonic-gate (void) close(fd);
367*0Sstevel@tonic-gate return (-1);
368*0Sstevel@tonic-gate }
369*0Sstevel@tonic-gate (void) close(fd);
370*0Sstevel@tonic-gate return ((flags.c_cflag & TIOCM_LE) ? 1 : 0);
371*0Sstevel@tonic-gate }
372*0Sstevel@tonic-gate
373*0Sstevel@tonic-gate /* ARGSUSED */
374*0Sstevel@tonic-gate static void
sig_alarm_handler(int signo)375*0Sstevel@tonic-gate sig_alarm_handler(int signo)
376*0Sstevel@tonic-gate {
377*0Sstevel@tonic-gate }
378*0Sstevel@tonic-gate
379*0Sstevel@tonic-gate /*
380*0Sstevel@tonic-gate * serial_port_cond: returns status of a serial port
381*0Sstevel@tonic-gate * 0 = OK, 1 = FAILING, 2 = FAILED, 3 = TESTING, anything else = UNKNOWN
382*0Sstevel@tonic-gate */
383*0Sstevel@tonic-gate static int
serial_port_cond(kstat_ctl_t * kc,char * driver,int instance)384*0Sstevel@tonic-gate serial_port_cond(kstat_ctl_t *kc, char *driver, int instance)
385*0Sstevel@tonic-gate {
386*0Sstevel@tonic-gate switch (serial_port_state(kc, driver, instance)) {
387*0Sstevel@tonic-gate case 1:
388*0Sstevel@tonic-gate return (0);
389*0Sstevel@tonic-gate default:
390*0Sstevel@tonic-gate return (-1);
391*0Sstevel@tonic-gate }
392*0Sstevel@tonic-gate }
393*0Sstevel@tonic-gate
394*0Sstevel@tonic-gate /*
395*0Sstevel@tonic-gate * parallel_port_state: returns kstat info of a serial port
396*0Sstevel@tonic-gate * 1 = up, 0 = down, anything else = unknown
397*0Sstevel@tonic-gate */
398*0Sstevel@tonic-gate static int
parallel_port_state(kstat_ctl_t * kc,char * ks_module,int ks_instance)399*0Sstevel@tonic-gate parallel_port_state(kstat_ctl_t *kc, char *ks_module, int ks_instance)
400*0Sstevel@tonic-gate {
401*0Sstevel@tonic-gate kstat_t *ksp = NULL;
402*0Sstevel@tonic-gate kstat_named_t *port_datap = NULL;
403*0Sstevel@tonic-gate char *data_lookup;
404*0Sstevel@tonic-gate char ks_name[20];
405*0Sstevel@tonic-gate
406*0Sstevel@tonic-gate (void) snprintf(ks_name, sizeof (ks_name), "%s%d", ks_module,
407*0Sstevel@tonic-gate ks_instance);
408*0Sstevel@tonic-gate if ((ksp = kstat_lookup(kc, ks_module, ks_instance, ks_name)) == NULL) {
409*0Sstevel@tonic-gate return (-1);
410*0Sstevel@tonic-gate }
411*0Sstevel@tonic-gate if (kstat_read(kc, ksp, NULL) == -1) {
412*0Sstevel@tonic-gate return (-1);
413*0Sstevel@tonic-gate }
414*0Sstevel@tonic-gate data_lookup = "";
415*0Sstevel@tonic-gate port_datap = (kstat_named_t *)kstat_data_lookup(ksp, data_lookup);
416*0Sstevel@tonic-gate if (port_datap == NULL) {
417*0Sstevel@tonic-gate return (-1);
418*0Sstevel@tonic-gate }
419*0Sstevel@tonic-gate return (-1);
420*0Sstevel@tonic-gate }
421*0Sstevel@tonic-gate
422*0Sstevel@tonic-gate /*
423*0Sstevel@tonic-gate * parallel_port_cond: returns kstat info of a serial port
424*0Sstevel@tonic-gate * 1 = up, 0 = down, anything else = unknown
425*0Sstevel@tonic-gate */
426*0Sstevel@tonic-gate static int
parallel_port_cond(kstat_ctl_t * kc,char * ks_module,int ks_instance)427*0Sstevel@tonic-gate parallel_port_cond(kstat_ctl_t *kc, char *ks_module, int ks_instance)
428*0Sstevel@tonic-gate {
429*0Sstevel@tonic-gate return (parallel_port_state(kc, ks_module, ks_instance));
430*0Sstevel@tonic-gate }
431