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} |