1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /*
30 * This program provides a command line interface to the
31 * three new ioctls for the emul64 driver - EMUL64_WRITE_OFF,
32 * EMUL64_WRITE_ON and EMUL64_ZERO_RANGE. All three of these
33 * ioctls require the range of blocks to be specified. The
34 * range is specified by starting block number and block count
35 * both of which are 64 bit.
36 *
37 * Returns 0 on success, >0 on failure.
38 *
39 */
40 #include <stdio.h>
41 #include <fcntl.h>
42 #include <unistd.h>
43 #include <stropts.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <errno.h>
47 #include <sys/types.h>
48 #include <sys/emul64.h>
49
50 #define DEBUG 1
51 #define ADMIN_DIR "/dev/cfg/"
52
53 char *Pname;
54
55 static int get_disk_addr(char *path, emul64_tgt_range_t *tr, char **admin);
56
57 static void
usage(void)58 usage(void)
59 {
60 (void) fprintf(stderr, "Usage: emul64ioctl -s start_block "
61 "-b block_count -c write_off | write_on | zero emul64_dev\n");
62 exit(1);
63 }
64
65 int
main(int argc,char ** argv)66 main(int argc, char **argv)
67 {
68 extern char *optarg;
69 extern int optind;
70 char *admin;
71 int count_seen = 0;
72 int fd, retval;
73 int cmd = -1;
74 int do_usage = 0;
75 char *slice;
76 int sb_seen = 0;
77 emul64_tgt_range_t tr;
78
79 Pname = strrchr(argv[0], '/');
80 if (Pname == NULL)
81 Pname = argv[0];
82 else
83 Pname++;
84
85 while ((retval = getopt(argc, argv, "s:b:c:")) != -1) {
86 switch (retval) {
87 case 's':
88 sb_seen = 1;
89 tr.emul64_blkrange.emul64_sb = atoll(optarg);
90 break;
91 case 'b':
92 count_seen = 1;
93 tr.emul64_blkrange.emul64_blkcnt = atoll(optarg);
94 break;
95 case 'c':
96 if (strncmp(optarg, "write_off",
97 strlen("write_off")) == 0) {
98 cmd = EMUL64_WRITE_OFF;
99 } else if (strncmp(optarg, "write_on",
100 strlen("write_on")) == 0) {
101 cmd = EMUL64_WRITE_ON;
102 } else if (strncmp(optarg, "zero",
103 strlen("zero")) == 0) {
104 cmd = EMUL64_ZERO_RANGE;
105 } else {
106 do_usage = 1;
107 }
108 break;
109 default:
110 break;
111 }
112 }
113
114 if (do_usage || (optind != argc - 1)) {
115 usage();
116 }
117 if ((sb_seen == 0) || (count_seen == 0) || (cmd == -1))
118 usage();
119
120 slice = argv[optind];
121
122 /*
123 * Get admin device, target and lun
124 */
125 if (get_disk_addr(slice, &tr, &admin) != 0)
126 exit(1);
127
128 /*
129 * open the specified emul64_dev.
130 */
131 if ((fd = open(admin, O_RDONLY, 0444)) != -1) {
132
133 retval = ioctl(fd, cmd, &tr);
134 (void) close(fd);
135
136 if (retval != -1) {
137 free(admin);
138 return (0);
139 }
140 (void) printf("emul64ioctl: %s: ioctl %s\n",
141 admin, strerror(errno));
142 } else {
143 (void) printf("emul64ioctl: %s: open %s\n",
144 admin, strerror(errno));
145 }
146 free(admin);
147 return (1);
148 }
149
150 #define TOK_CHECK(s) if (token == NULL) {\
151 bogus = (s);\
152 goto err_out;\
153 }
154
155 static int
get_disk_addr(char * path,emul64_tgt_range_t * tr,char ** admin)156 get_disk_addr(char *path, emul64_tgt_range_t *tr, char **admin)
157 {
158 size_t admin_size;
159 int ctlr_num;
160 int conversions;
161 char *ctds;
162
163 *admin = NULL;
164 ctds = strrchr(path, '/');
165 if (ctds == NULL)
166 ctds = path;
167 else
168 ctds++;
169 conversions = sscanf(ctds, "c%dt%hud%hu", &ctlr_num,
170 &tr->emul64_target, &tr->emul64_lun);
171 if (conversions != 3) {
172 (void) fprintf(stderr, "%s: \"%s\" is invalid disk name. "
173 "%d conversions\n", Pname, ctds, conversions);
174 return (-1);
175 }
176
177 /* Build controller name */
178 admin_size = strlen(ADMIN_DIR) +
179 10 + /* enough digits for an int */
180 1 + /* c */
181 1; /* Null terminator */
182 *admin = malloc(admin_size);
183 if (*admin == NULL) {
184 (void) fprintf(stderr, "%s: out of memory\n", Pname);
185 return (-1);
186 }
187 (void) snprintf(*admin, admin_size, "%sc%d", ADMIN_DIR, ctlr_num);
188 return (0);
189 }
190