Deleted Added
full compact
chio.c (64692) chio.c (66019)
1/* $NetBSD: chio.c,v 1.6 1998/01/04 23:53:58 thorpej Exp $ */
2/*
3 * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 18 unchanged lines hidden (view full) ---

27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33/*
34 * Additional Copyright (c) 1997, by Matthew Jacob, for NASA/Ames Research Ctr.
1/* $NetBSD: chio.c,v 1.6 1998/01/04 23:53:58 thorpej Exp $ */
2/*
3 * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 18 unchanged lines hidden (view full) ---

27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33/*
34 * Additional Copyright (c) 1997, by Matthew Jacob, for NASA/Ames Research Ctr.
35 * Addidional Copyright (c) 2000, by C. Stephen Gunn, Waterspout Communications
35 */
36
37#ifndef lint
38static const char copyright[] =
39 "@(#) Copyright (c) 1996 Jason R. Thorpe. All rights reserved.";
40static const char rcsid[] =
36 */
37
38#ifndef lint
39static const char copyright[] =
40 "@(#) Copyright (c) 1996 Jason R. Thorpe. All rights reserved.";
41static const char rcsid[] =
41 "$FreeBSD: head/bin/chio/chio.c 64692 2000-08-16 05:14:49Z imp $";
42 "$FreeBSD: head/bin/chio/chio.c 66019 2000-09-18 06:09:11Z ken $";
42#endif /* not lint */
43
44#include <sys/param.h>
45#include <sys/chio.h>
46#include <err.h>
47#include <fcntl.h>
48#include <stdio.h>
49#include <stdlib.h>

--- 9 unchanged lines hidden (view full) ---

59static void cleanup __P((void));
60static int parse_element_type __P((char *));
61static int parse_element_unit __P((char *));
62static const char * element_type_name __P((int et));
63static int parse_special __P((char *));
64static int is_special __P((char *));
65static const char *bits_to_string __P((int, const char *));
66
43#endif /* not lint */
44
45#include <sys/param.h>
46#include <sys/chio.h>
47#include <err.h>
48#include <fcntl.h>
49#include <stdio.h>
50#include <stdlib.h>

--- 9 unchanged lines hidden (view full) ---

60static void cleanup __P((void));
61static int parse_element_type __P((char *));
62static int parse_element_unit __P((char *));
63static const char * element_type_name __P((int et));
64static int parse_special __P((char *));
65static int is_special __P((char *));
66static const char *bits_to_string __P((int, const char *));
67
68static void find_element __P((char *, u_int16_t *, u_int16_t *));
69static struct changer_element_status *get_element_status __P((u_int16_t, u_int16_t));
70
67static int do_move __P((char *, int, char **));
68static int do_exchange __P((char *, int, char **));
69static int do_position __P((char *, int, char **));
70static int do_params __P((char *, int, char **));
71static int do_getpicker __P((char *, int, char **));
72static int do_setpicker __P((char *, int, char **));
73static int do_status __P((char *, int, char **));
74static int do_ielem __P((char *, int, char **));
71static int do_move __P((char *, int, char **));
72static int do_exchange __P((char *, int, char **));
73static int do_position __P((char *, int, char **));
74static int do_params __P((char *, int, char **));
75static int do_getpicker __P((char *, int, char **));
76static int do_setpicker __P((char *, int, char **));
77static int do_status __P((char *, int, char **));
78static int do_ielem __P((char *, int, char **));
79static int do_return __P((char *, int, char **));
75static int do_voltag __P((char *, int, char **));
76
80static int do_voltag __P((char *, int, char **));
81
82#ifndef CHET_VT
83#define CHET_VT 10 /* Completely Arbitrary */
84#endif
85
77/* Valid changer element types. */
78const struct element_type elements[] = {
79 { "drive", CHET_DT },
80 { "picker", CHET_MT },
81 { "portal", CHET_IE },
82 { "slot", CHET_ST },
86/* Valid changer element types. */
87const struct element_type elements[] = {
88 { "drive", CHET_DT },
89 { "picker", CHET_MT },
90 { "portal", CHET_IE },
91 { "slot", CHET_ST },
92 { "voltag", CHET_VT }, /* Select tapes by barcode */
83 { NULL, 0 },
84};
85
86/* Valid commands. */
87const struct changer_command commands[] = {
88 { "exchange", do_exchange },
89 { "getpicker", do_getpicker },
90 { "ielem", do_ielem },
91 { "move", do_move },
92 { "params", do_params },
93 { "position", do_position },
94 { "setpicker", do_setpicker },
95 { "status", do_status },
93 { NULL, 0 },
94};
95
96/* Valid commands. */
97const struct changer_command commands[] = {
98 { "exchange", do_exchange },
99 { "getpicker", do_getpicker },
100 { "ielem", do_ielem },
101 { "move", do_move },
102 { "params", do_params },
103 { "position", do_position },
104 { "setpicker", do_setpicker },
105 { "status", do_status },
106 { "return", do_return },
96 { "voltag", do_voltag },
97 { NULL, 0 },
98};
99
100/* Valid special words. */
101const struct special_word specials[] = {
102 { "inv", SW_INVERT },
103 { "inv1", SW_INVERT1 },

--- 86 unchanged lines hidden (view full) ---

190 goto usage;
191 }
192 (void) memset(&cmd, 0, sizeof(cmd));
193
194 /* <from ET> */
195 cmd.cm_fromtype = parse_element_type(*argv);
196 ++argv; --argc;
197
107 { "voltag", do_voltag },
108 { NULL, 0 },
109};
110
111/* Valid special words. */
112const struct special_word specials[] = {
113 { "inv", SW_INVERT },
114 { "inv1", SW_INVERT1 },

--- 86 unchanged lines hidden (view full) ---

201 goto usage;
202 }
203 (void) memset(&cmd, 0, sizeof(cmd));
204
205 /* <from ET> */
206 cmd.cm_fromtype = parse_element_type(*argv);
207 ++argv; --argc;
208
198 /* <from EU> */
199 cmd.cm_fromunit = parse_element_unit(*argv);
209 /* Check for voltag virtual type */
210 if (CHET_VT == cmd.cm_fromtype) {
211 find_element(*argv, &cmd.cm_fromtype, &cmd.cm_fromunit);
212 } else {
213 /* <from EU> */
214 cmd.cm_fromunit = parse_element_unit(*argv);
215 }
200 ++argv; --argc;
201
202 /* <to ET> */
203 cmd.cm_totype = parse_element_type(*argv);
204 ++argv; --argc;
205
216 ++argv; --argc;
217
218 /* <to ET> */
219 cmd.cm_totype = parse_element_type(*argv);
220 ++argv; --argc;
221
222 /* Check for voltag virtual type, and report error */
223 if (CHET_VT == cmd.cm_totype)
224 errx(1,"%s: voltag only makes sense as an element source",
225 cname);
226
206 /* <to EU> */
207 cmd.cm_tounit = parse_element_unit(*argv);
208 ++argv; --argc;
209
210 /* Deal with optional command modifier. */
211 if (argc) {
212 val = parse_special(*argv);
213 switch (val) {

--- 47 unchanged lines hidden (view full) ---

261 goto usage;
262 }
263 (void) memset(&cmd, 0, sizeof(cmd));
264
265 /* <src ET> */
266 cmd.ce_srctype = parse_element_type(*argv);
267 ++argv; --argc;
268
227 /* <to EU> */
228 cmd.cm_tounit = parse_element_unit(*argv);
229 ++argv; --argc;
230
231 /* Deal with optional command modifier. */
232 if (argc) {
233 val = parse_special(*argv);
234 switch (val) {

--- 47 unchanged lines hidden (view full) ---

282 goto usage;
283 }
284 (void) memset(&cmd, 0, sizeof(cmd));
285
286 /* <src ET> */
287 cmd.ce_srctype = parse_element_type(*argv);
288 ++argv; --argc;
289
269 /* <src EU> */
270 cmd.ce_srcunit = parse_element_unit(*argv);
290 /* Check for voltag virtual type */
291 if (CHET_VT == cmd.ce_srctype) {
292 find_element(*argv, &cmd.ce_srctype, &cmd.ce_srcunit);
293 } else {
294 /* <from EU> */
295 cmd.ce_srcunit = parse_element_unit(*argv);
296 }
271 ++argv; --argc;
272
273 /* <dst1 ET> */
274 cmd.ce_fdsttype = parse_element_type(*argv);
275 ++argv; --argc;
276
297 ++argv; --argc;
298
299 /* <dst1 ET> */
300 cmd.ce_fdsttype = parse_element_type(*argv);
301 ++argv; --argc;
302
277 /* <dst1 EU> */
278 cmd.ce_fdstunit = parse_element_unit(*argv);
303 /* Check for voltag virtual type */
304 if (CHET_VT == cmd.ce_fdsttype) {
305 find_element(*argv, &cmd.ce_fdsttype, &cmd.ce_fdstunit);
306 } else {
307 /* <from EU> */
308 cmd.ce_fdstunit = parse_element_unit(*argv);
309 }
279 ++argv; --argc;
280
281 /*
282 * If the next token is a special word or there are no more
283 * arguments, then this is a case of simple exchange.
284 * dst2 == src.
285 */
286 if ((argc == 0) || is_special(*argv)) {
287 cmd.ce_sdsttype = cmd.ce_srctype;
288 cmd.ce_sdstunit = cmd.ce_srcunit;
289 goto do_special;
290 }
291
292 /* <dst2 ET> */
293 cmd.ce_sdsttype = parse_element_type(*argv);
294 ++argv; --argc;
295
310 ++argv; --argc;
311
312 /*
313 * If the next token is a special word or there are no more
314 * arguments, then this is a case of simple exchange.
315 * dst2 == src.
316 */
317 if ((argc == 0) || is_special(*argv)) {
318 cmd.ce_sdsttype = cmd.ce_srctype;
319 cmd.ce_sdstunit = cmd.ce_srcunit;
320 goto do_special;
321 }
322
323 /* <dst2 ET> */
324 cmd.ce_sdsttype = parse_element_type(*argv);
325 ++argv; --argc;
326
327 if (CHET_VT == cmd.ce_sdsttype)
328 errx(1,"%s %s: voltag only makes sense as an element source",
329 cname, *argv);
330
296 /* <dst2 EU> */
297 cmd.ce_sdstunit = parse_element_unit(*argv);
298 ++argv; --argc;
299
300 do_special:
301 /* Deal with optional command modifiers. */
302 while (argc) {
303 val = parse_special(*argv);

--- 343 unchanged lines hidden (view full) ---

647 }
648 }
649
650 bzero(&cesr, sizeof(cesr));
651 cesr.cesr_element_type = chet;
652 cesr.cesr_element_base = base;
653 cesr.cesr_element_count = count;
654 /* Allocate storage for the status structures. */
331 /* <dst2 EU> */
332 cmd.ce_sdstunit = parse_element_unit(*argv);
333 ++argv; --argc;
334
335 do_special:
336 /* Deal with optional command modifiers. */
337 while (argc) {
338 val = parse_special(*argv);

--- 343 unchanged lines hidden (view full) ---

682 }
683 }
684
685 bzero(&cesr, sizeof(cesr));
686 cesr.cesr_element_type = chet;
687 cesr.cesr_element_base = base;
688 cesr.cesr_element_count = count;
689 /* Allocate storage for the status structures. */
655 cesr.cesr_element_status
656 = (struct changer_element_status *)
657 malloc(count * sizeof(struct changer_element_status));
690 cesr.cesr_element_status =
691 (struct changer_element_status *)
692 calloc(count, sizeof(struct changer_element_status));
658
659 if (!cesr.cesr_element_status)
660 errx(1, "can't allocate status storage");
661
662 if (avoltag || pvoltag)
663 cesr.cesr_flags |= CESR_VOLTAGS;
664
665 if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cesr)) {

--- 263 unchanged lines hidden (view full) ---

929 bp += strlen(bp);
930 sep = ',';
931 }
932 if (sep != '<')
933 *bp = '>';
934
935 return (buf);
936}
693
694 if (!cesr.cesr_element_status)
695 errx(1, "can't allocate status storage");
696
697 if (avoltag || pvoltag)
698 cesr.cesr_flags |= CESR_VOLTAGS;
699
700 if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cesr)) {

--- 263 unchanged lines hidden (view full) ---

964 bp += strlen(bp);
965 sep = ',';
966 }
967 if (sep != '<')
968 *bp = '>';
969
970 return (buf);
971}
972/*
973 * do_return()
974 *
975 * Given an element reference, ask the changer/picker to move that
976 * element back to its source slot.
977 */
978static int
979do_return(cname, argc, argv)
980 char *cname;
981 int argc;
982 char **argv;
983{
984 struct changer_element_status *ces;
985 struct changer_move cmd;
986 u_int16_t type, element;
937
987
988 ++argv; --argc;
989
990 if (argc < 2) {
991 warnx("%s: too few arguments", cname);
992 goto usage;
993 } else if (argc > 3) {
994 warnx("%s: too many arguments", cname);
995 goto usage;
996 }
997
998 type = parse_element_type(*argv);
999 ++argv; --argc;
1000
1001 /* Handle voltag virtual Changer Element Type */
1002 if (CHET_VT == type) {
1003 find_element(*argv, &type, &element);
1004 } else {
1005 element = parse_element_unit(*argv);
1006 }
1007 ++argv; --argc;
1008
1009 ces = get_element_status(type, element); /* Get the status */
1010
1011 if (NULL == ces)
1012 errx(1, "%s: null element status pointer", cname);
1013
1014 if (!(ces->ces_flags & CES_SOURCE_VALID))
1015 errx(1, "%s: no source information", cname);
1016
1017 (void) memset(&cmd, 0, sizeof(cmd));
1018
1019 cmd.cm_fromtype = type;
1020 cmd.cm_fromunit = element;
1021 cmd.cm_totype = ces->ces_source_type;
1022 cmd.cm_tounit = ces->ces_source_addr;
1023
1024 if (ioctl(changer_fd, CHIOMOVE, &cmd) == -1)
1025 err(1, "%s: CHIOMOVE", changer_name);
1026 free(ces);
1027
1028 return(0);
1029
1030usage:
1031 (void) fprintf(stderr, "usage: %s %s "
1032 "<from ET> <from EU>\n", __progname, cname);
1033 return(1);
1034}
1035
1036/*
1037 * get_element_status()
1038 *
1039 * return a *cesr for the specified changer element. This
1040 * routing will malloc()/calloc() the memory. The caller
1041 * should free() it when done.
1042 */
1043static struct changer_element_status *
1044get_element_status(type, element)
1045 u_int16_t type;
1046 u_int16_t element;
1047{
1048 struct changer_element_status_request cesr;
1049 struct changer_element_status *ces;
1050
1051 ces = (struct changer_element_status *)
1052 calloc(1, sizeof(struct changer_element_status));
1053
1054 if (NULL == ces)
1055 errx(1, "can't allocate status storage");
1056
1057 (void)memset(&cesr, 0, sizeof(cesr));
1058
1059 cesr.cesr_element_type = type;
1060 cesr.cesr_element_base = element;
1061 cesr.cesr_element_count = 1; /* Only this one element */
1062 cesr.cesr_flags |= CESR_VOLTAGS; /* Grab voltags as well */
1063 cesr.cesr_element_status = ces;
1064
1065 if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cesr) == -1) {
1066 free(ces);
1067 err(1, "%s: CHIOGSTATUS", changer_name);
1068 /* NOTREACHED */
1069 }
1070
1071 return ces;
1072}
1073
1074
1075/*
1076 * find_element()
1077 *
1078 * Given a <voltag> find the chager element and unit, or exit
1079 * with an error if it isn't found. We grab the changer status
1080 * and iterate until we find a match, or crap out.
1081 */
938static void
1082static void
1083find_element(voltag, et, eu)
1084 char *voltag;
1085 u_int16_t *et;
1086 u_int16_t *eu;
1087{
1088 struct changer_params cp;
1089 struct changer_element_status_request cesr;
1090 struct changer_element_status *ch_ces, *ces;
1091 int elem, total_elem, found = 0;
1092
1093 /*
1094 * Get the changer parameters, we're interested in the counts
1095 * for all types of elements to perform our search.
1096 */
1097 if (ioctl(changer_fd, CHIOGPARAMS, (char *)&cp))
1098 err(1, "%s: CHIOGPARAMS", changer_name);
1099
1100 /* Allocate some memory for the results */
1101 total_elem = (cp.cp_nslots + cp.cp_ndrives
1102 + cp.cp_npickers + cp.cp_nportals);
1103
1104 ch_ces = (struct changer_element_status *)
1105 calloc(total_elem, sizeof(struct changer_element_status));
1106
1107 if (NULL == ch_ces)
1108 errx(1, "can't allocate status storage");
1109
1110 ces = ch_ces;
1111
1112 /* Read in the changer slots */
1113 if (cp.cp_nslots > 0) {
1114 cesr.cesr_element_type = CHET_ST;
1115 cesr.cesr_element_base = 0;
1116 cesr.cesr_element_count = cp.cp_nslots;
1117 cesr.cesr_flags |= CESR_VOLTAGS;
1118 cesr.cesr_element_status = ces;
1119
1120 if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cesr) == -1) {
1121 free(ch_ces);
1122 err(1, "%s: CHIOGSTATUS", changer_name);
1123 }
1124 ces += cp.cp_nslots;
1125 }
1126
1127 /* Read in the drive information */
1128 if (cp.cp_ndrives > 0 ) {
1129
1130 (void) memset(&cesr, 0, sizeof(cesr));
1131 cesr.cesr_element_type = CHET_DT;
1132 cesr.cesr_element_base = 0;
1133 cesr.cesr_element_count = cp.cp_ndrives;
1134 cesr.cesr_flags |= CESR_VOLTAGS;
1135 cesr.cesr_element_status = ces;
1136
1137 if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cesr) == -1) {
1138 free(ch_ces);
1139 err(1, "%s: CHIOGSTATUS", changer_name);
1140 }
1141 ces += cp.cp_ndrives;
1142 }
1143
1144 /* Read in the portal information */
1145 if (cp.cp_nportals > 0 ) {
1146 (void) memset(&cesr, 0, sizeof(cesr));
1147 cesr.cesr_element_type = CHET_IE;
1148 cesr.cesr_element_base = 0;
1149 cesr.cesr_element_count = cp.cp_nportals;
1150 cesr.cesr_flags |= CESR_VOLTAGS;
1151 cesr.cesr_element_status = ces;
1152
1153 if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cesr) == -1) {
1154 free(ch_ces);
1155 err(1, "%s: CHIOGSTATUS", changer_name);
1156 }
1157 ces += cp.cp_nportals;
1158 }
1159
1160 /* Read in the picker information */
1161 if (cp.cp_npickers > 0) {
1162 (void) memset(&cesr, 0, sizeof(cesr));
1163 cesr.cesr_element_type = CHET_MT;
1164 cesr.cesr_element_base = 0;
1165 cesr.cesr_element_count = cp.cp_npickers;
1166 cesr.cesr_flags |= CESR_VOLTAGS;
1167 cesr.cesr_element_status = ces;
1168
1169 if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cesr) == -1) {
1170 free(ch_ces);
1171 err(1, "%s: CHIOGSTATUS", changer_name);
1172 }
1173 }
1174
1175 /*
1176 * Now search the list the specified <voltag>
1177 */
1178 for (elem = 0; elem <= total_elem; ++elem) {
1179
1180 ces = &ch_ces[elem];
1181
1182 /* Make sure we have a tape in this element */
1183 if ((ces->ces_flags & (CES_STATUS_ACCESS|CES_STATUS_FULL))
1184 != (CES_STATUS_ACCESS|CES_STATUS_FULL))
1185 continue;
1186
1187 /* Check to see if it is our target */
1188 if (strcasecmp(voltag, ces->ces_pvoltag.cv_volid) == 0) {
1189 *et = ces->ces_type;
1190 *eu = ces->ces_addr;
1191 ++found;
1192 break;
1193 }
1194 }
1195 if (!found) {
1196 errx(1, "%s: unable to locate voltag: %s", changer_name,
1197 voltag);
1198 }
1199 free(ch_ces);
1200 return;
1201}
1202
1203static void
939cleanup()
940{
941 /* Simple enough... */
942 (void)close(changer_fd);
943}
944
945static void
946usage()
947{
948 (void) fprintf(stderr, "usage: %s [-f changer] command [-<flags>] "
949 "arg1 arg2 [arg3 [...]]\n", __progname);
950 exit(1);
951}
1204cleanup()
1205{
1206 /* Simple enough... */
1207 (void)close(changer_fd);
1208}
1209
1210static void
1211usage()
1212{
1213 (void) fprintf(stderr, "usage: %s [-f changer] command [-<flags>] "
1214 "arg1 arg2 [arg3 [...]]\n", __progname);
1215 exit(1);
1216}