157580Smjacob/* $FreeBSD: releng/10.3/share/examples/ses/srcs/getencstat.c 291429 2015-11-28 17:26:46Z mav $ */
257580Smjacob/*
357580Smjacob * Copyright (c) 2000 by Matthew Jacob
457580Smjacob * All rights reserved.
557580Smjacob *
657580Smjacob * Redistribution and use in source and binary forms, with or without
757580Smjacob * modification, are permitted provided that the following conditions
857580Smjacob * are met:
957580Smjacob * 1. Redistributions of source code must retain the above copyright
1057580Smjacob *    notice, this list of conditions, and the following disclaimer,
1157580Smjacob *    without modification, immediately at the beginning of the file.
1257580Smjacob * 2. The name of the author may not be used to endorse or promote products
1357580Smjacob *    derived from this software without specific prior written permission.
1457580Smjacob *
1557580Smjacob * Alternatively, this software may be distributed under the terms of the
1657580Smjacob * the GNU Public License ("GPL").
1757580Smjacob *
1857580Smjacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1957580Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2057580Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2157580Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2257580Smjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2357580Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2457580Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2557580Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2657580Smjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2757580Smjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2857580Smjacob * SUCH DAMAGE.
2957580Smjacob *
3057580Smjacob * Matthew Jacob
3157580Smjacob * Feral Software
3257580Smjacob * mjacob@feral.com
3357580Smjacob */
3457580Smjacob
3557580Smjacob#include <unistd.h>
36235911Smav#include <stddef.h>
37235911Smav#include <stdint.h>
3857580Smjacob#include <stdlib.h>
3957580Smjacob#include <stdio.h>
40198929Sdelphij#include <string.h>
4157580Smjacob#include <sys/ioctl.h>
4257580Smjacob#include <fcntl.h>
43235911Smav#include <cam/scsi/scsi_all.h>
44235911Smav#include <cam/scsi/scsi_enc.h>
4557580Smjacob
46198934Sdelphij#include "eltsub.h"
4757580Smjacob
4857580Smjacobint
49198934Sdelphijmain(int a, char **v)
5057580Smjacob{
51291429Smav	encioc_string_t stri;
52235911Smav	encioc_element_t *objp;
53235911Smav	encioc_elm_status_t ob;
54235911Smav	encioc_elm_desc_t objd;
55235911Smav	encioc_elm_devnames_t objdn;
5657580Smjacob	int fd, nobj, f, i, verbose, quiet, errors;
5757580Smjacob	u_char estat;
58291429Smav	char str[32];
5957580Smjacob
6057580Smjacob	if (a < 2) {
6157580Smjacob		fprintf(stderr, "usage: %s [ -v ] device [ device ... ]\n", *v);
6257580Smjacob		return (1);
6357580Smjacob	}
6457580Smjacob	errors = quiet = verbose = 0;
6557580Smjacob	if (strcmp(v[1], "-V") == 0) {
6657580Smjacob		verbose = 2;
6757580Smjacob		v++;
6857580Smjacob	} else if (strcmp(v[1], "-v") == 0) {
6957580Smjacob		verbose = 1;
7057580Smjacob		v++;
7157580Smjacob	} else if (strcmp(v[1], "-q") == 0) {
7257580Smjacob		quiet = 1;
7357580Smjacob		verbose = 0;
7457580Smjacob		v++;
7557580Smjacob	}
7657580Smjacob	while (*++v) {
7757580Smjacob
7857580Smjacob		fd = open(*v, O_RDONLY);
7957580Smjacob		if (fd < 0) {
8057580Smjacob			perror(*v);
8157580Smjacob			continue;
8257580Smjacob		}
83291429Smav		if (verbose > 1) {
84291429Smav			stri.bufsiz = sizeof(str);
85291429Smav			stri.buf = &str[0];
86291429Smav			if (ioctl(fd, ENCIOC_GETENCNAME, (caddr_t) &stri) == 0)
87291429Smav				printf("%s: Enclosure Name: %s\n", *v, stri.buf);
88291429Smav			stri.bufsiz = sizeof(str);
89291429Smav			stri.buf = &str[0];
90291429Smav			if (ioctl(fd, ENCIOC_GETENCID, (caddr_t) &stri) == 0)
91291429Smav				printf("%s: Enclosure ID: %s\n", *v, stri.buf);
92291429Smav		}
93235911Smav		if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) {
94235911Smav			perror("ENCIOC_GETNELM");
9557580Smjacob			(void) close(fd);
9657580Smjacob			continue;
9757580Smjacob		}
98235911Smav		if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &estat) < 0) {
99235911Smav			perror("ENCIOC_GETENCSTAT");
10057580Smjacob			(void) close(fd);
10157580Smjacob			continue;
10257580Smjacob		}
10357580Smjacob		if ((verbose == 0 || quiet == 1) && estat == 0) {
10457580Smjacob			if (quiet == 0)
10557580Smjacob				fprintf(stdout, "%s: Enclosure OK\n", *v);
10657580Smjacob			(void) close(fd);
10757580Smjacob			continue;
10857580Smjacob		}
10957580Smjacob		fprintf(stdout, "%s: Enclosure Status ", *v);
11057580Smjacob		if (estat == 0) {
11157580Smjacob			fprintf(stdout, "<OK");
11257580Smjacob		} else {
11357580Smjacob			errors++;
11457580Smjacob			f = '<';
11557580Smjacob			if (estat & SES_ENCSTAT_INFO) {
11657580Smjacob				fprintf(stdout, "%cINFO", f);
11757580Smjacob				f = ',';
11857580Smjacob			}
11957580Smjacob			if (estat & SES_ENCSTAT_NONCRITICAL) {
12057580Smjacob				fprintf(stdout, "%cNONCRITICAL", f);
12157580Smjacob				f = ',';
12257580Smjacob			}
12357580Smjacob			if (estat & SES_ENCSTAT_CRITICAL) {
12457580Smjacob				fprintf(stdout, "%cCRITICAL", f);
12557580Smjacob				f = ',';
12657580Smjacob			}
12757580Smjacob			if (estat & SES_ENCSTAT_UNRECOV) {
12857580Smjacob				fprintf(stdout, "%cUNRECOV", f);
12957580Smjacob				f = ',';
13057580Smjacob			}
13157580Smjacob		}
13257580Smjacob		fprintf(stdout, ">\n");
133235911Smav		objp = calloc(nobj, sizeof (encioc_element_t));
13457580Smjacob		if (objp == NULL) {
13557580Smjacob			perror("calloc");
13657580Smjacob			(void) close(fd);
13757580Smjacob			continue;
13857580Smjacob		}
139235911Smav                if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) {
140235911Smav                        perror("ENCIOC_GETELMMAP");
14157580Smjacob                        (void) close(fd);
14257580Smjacob                        continue;
14357580Smjacob                }
14457580Smjacob		for (i = 0; i < nobj; i++) {
145235911Smav			ob.elm_idx = objp[i].elm_idx;
146235911Smav			if (ioctl(fd, ENCIOC_GETELMSTAT, (caddr_t) &ob) < 0) {
147235911Smav				perror("ENCIOC_GETELMSTAT");
14857580Smjacob				(void) close(fd);
14957580Smjacob				break;
15057580Smjacob			}
151235911Smav			bzero(&objd, sizeof(objd));
152235911Smav			objd.elm_idx = objp[i].elm_idx;
153235911Smav			objd.elm_desc_len = UINT16_MAX;
154235911Smav			objd.elm_desc_str = calloc(UINT16_MAX, sizeof(char));
155235911Smav			if (objd.elm_desc_str == NULL) {
156235911Smav				perror("calloc");
157235911Smav				(void) close(fd);
15857580Smjacob				continue;
15957580Smjacob			}
160235911Smav			if (ioctl(fd, ENCIOC_GETELMDESC, (caddr_t)&objd) < 0) {
161235911Smav				perror("ENCIOC_GETELMDESC");
162235911Smav				(void) close(fd);
163235911Smav				break;
164235911Smav			}
165235911Smav			bzero(&objdn, sizeof(objdn));
166235911Smav			objdn.elm_idx = objp[i].elm_idx;
167235911Smav			objdn.elm_names_size = 128;
168235911Smav			objdn.elm_devnames = calloc(128, sizeof(char));
169235911Smav			if (objdn.elm_devnames == NULL) {
170235911Smav				perror("calloc");
171235911Smav				(void) close(fd);
172235911Smav				break;
173235911Smav			}
174235911Smav			/*
175235911Smav			 * This ioctl isn't critical and has a good chance
176235911Smav			 * of returning -1.
177235911Smav			 */
178235911Smav			(void)ioctl(fd, ENCIOC_GETELMDEVNAMES, (caddr_t)&objdn);
179235911Smav			fprintf(stdout, "Element 0x%x: %s", ob.elm_idx,
180235911Smav			    geteltnm(objp[i].elm_type));
181235911Smav			fprintf(stdout, ", %s",
182235911Smav			    stat2ascii(objp[i].elm_type, ob.cstat));
183235911Smav			if (objd.elm_desc_len > 0)
184235911Smav				fprintf(stdout, ", descriptor: '%s'",
185235911Smav				    objd.elm_desc_str);
186235911Smav			if (objdn.elm_names_len > 0)
187235911Smav				fprintf(stdout, ", dev: '%s'",
188235911Smav				    objdn.elm_devnames);
189235911Smav			fprintf(stdout, "\n");
190235911Smav			free(objdn.elm_devnames);
19157580Smjacob		}
19257580Smjacob		free(objp);
19357580Smjacob		(void) close(fd);
19457580Smjacob	}
19557580Smjacob	return (errors);
19657580Smjacob}
197