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