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 /* 28 * This program provides a command line interface to the 29 * three new ioctls for the emul64 driver - EMUL64_WRITE_OFF, 30 * EMUL64_WRITE_ON and EMUL64_ZERO_RANGE. All three of these 31 * ioctls require the range of blocks to be specified. The 32 * range is specified by starting block number and block count 33 * both of which are 64 bit. 34 * 35 * Returns 0 on success, >0 on failure. 36 * 37 */ 38 #include <stdio.h> 39 #include <fcntl.h> 40 #include <unistd.h> 41 #include <stropts.h> 42 #include <string.h> 43 #include <stdlib.h> 44 #include <errno.h> 45 #include <sys/types.h> 46 #include <sys/emul64.h> 47 48 #define DEBUG 1 49 #define ADMIN_DIR "/dev/cfg/" 50 51 char *Pname; 52 53 static int get_disk_addr(char *path, emul64_tgt_range_t *tr, char **admin); 54 55 static void 56 usage(void) 57 { 58 (void) fprintf(stderr, "Usage: emul64ioctl -s start_block " 59 "-b block_count -c write_off | write_on | zero emul64_dev\n"); 60 exit(1); 61 } 62 63 int 64 main(int argc, char **argv) 65 { 66 extern char *optarg; 67 extern int optind; 68 char *admin; 69 int count_seen = 0; 70 int fd, retval; 71 int cmd = -1; 72 int do_usage = 0; 73 char *slice; 74 int sb_seen = 0; 75 emul64_tgt_range_t tr; 76 77 Pname = strrchr(argv[0], '/'); 78 if (Pname == NULL) 79 Pname = argv[0]; 80 else 81 Pname++; 82 83 while ((retval = getopt(argc, argv, "s:b:c:")) != -1) { 84 switch (retval) { 85 case 's': 86 sb_seen = 1; 87 tr.emul64_blkrange.emul64_sb = atoll(optarg); 88 break; 89 case 'b': 90 count_seen = 1; 91 tr.emul64_blkrange.emul64_blkcnt = atoll(optarg); 92 break; 93 case 'c': 94 if (strncmp(optarg, "write_off", 95 strlen("write_off")) == 0) { 96 cmd = EMUL64_WRITE_OFF; 97 } else if (strncmp(optarg, "write_on", 98 strlen("write_on")) == 0) { 99 cmd = EMUL64_WRITE_ON; 100 } else if (strncmp(optarg, "zero", 101 strlen("zero")) == 0) { 102 cmd = EMUL64_ZERO_RANGE; 103 } else { 104 do_usage = 1; 105 } 106 break; 107 default: 108 break; 109 } 110 } 111 112 if (do_usage || (optind != argc - 1)) { 113 usage(); 114 } 115 if ((sb_seen == 0) || (count_seen == 0) || (cmd == -1)) 116 usage(); 117 118 slice = argv[optind]; 119 120 /* 121 * Get admin device, target and lun 122 */ 123 if (get_disk_addr(slice, &tr, &admin) != 0) 124 exit(1); 125 126 /* 127 * open the specified emul64_dev. 128 */ 129 if ((fd = open(admin, O_RDONLY, 0444)) != -1) { 130 131 retval = ioctl(fd, cmd, &tr); 132 (void) close(fd); 133 134 if (retval != -1) { 135 free(admin); 136 return (0); 137 } 138 (void) printf("emul64ioctl: %s: ioctl %s\n", 139 admin, strerror(errno)); 140 } else { 141 (void) printf("emul64ioctl: %s: open %s\n", 142 admin, strerror(errno)); 143 } 144 free(admin); 145 return (1); 146 } 147 148 #define TOK_CHECK(s) if (token == NULL) {\ 149 bogus = (s);\ 150 goto err_out;\ 151 } 152 153 static int 154 get_disk_addr(char *path, emul64_tgt_range_t *tr, char **admin) 155 { 156 size_t admin_size; 157 int ctlr_num; 158 int conversions; 159 char *ctds; 160 161 *admin = NULL; 162 ctds = strrchr(path, '/'); 163 if (ctds == NULL) 164 ctds = path; 165 else 166 ctds++; 167 conversions = sscanf(ctds, "c%dt%hud%hu", &ctlr_num, 168 &tr->emul64_target, &tr->emul64_lun); 169 if (conversions != 3) { 170 (void) fprintf(stderr, "%s: \"%s\" is invalid disk name. " 171 "%d conversions\n", Pname, ctds, conversions); 172 return (-1); 173 } 174 175 /* Build controller name */ 176 admin_size = strlen(ADMIN_DIR) + 177 10 + /* enough digits for an int */ 178 1 + /* c */ 179 1; /* Null terminator */ 180 *admin = malloc(admin_size); 181 if (*admin == NULL) { 182 (void) fprintf(stderr, "%s: out of memory\n", Pname); 183 return (-1); 184 } 185 (void) snprintf(*admin, admin_size, "%sc%d", ADMIN_DIR, ctlr_num); 186 return (0); 187 } 188