Mercurial > illumos > onarm
diff usr/src/cmd/emul64ioctl/emul64ioctl.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/emul64ioctl/emul64ioctl.c Tue Jun 02 18:56:50 2009 +0900 @@ -0,0 +1,189 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "@(#)emul64ioctl.c 1.1 05/06/27 SMI" + +/* + * This program provides a command line interface to the + * three new ioctls for the emul64 driver - EMUL64_WRITE_OFF, + * EMUL64_WRITE_ON and EMUL64_ZERO_RANGE. All three of these + * ioctls require the range of blocks to be specified. The + * range is specified by starting block number and block count + * both of which are 64 bit. + * + * Returns 0 on success, >0 on failure. + * + */ +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <stropts.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/emul64.h> + +#define DEBUG 1 +#define ADMIN_DIR "/dev/cfg/" + +char *Pname; + +static int get_disk_addr(char *path, emul64_tgt_range_t *tr, char **admin); + +static void +usage(void) +{ + (void) fprintf(stderr, "Usage: emul64ioctl -s start_block " + "-b block_count -c write_off | write_on | zero emul64_dev\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + extern char *optarg; + extern int optind; + char *admin; + int count_seen = 0; + int fd, retval; + int cmd = -1; + int do_usage = 0; + char *slice; + int sb_seen = 0; + emul64_tgt_range_t tr; + + Pname = strrchr(argv[0], '/'); + if (Pname == NULL) + Pname = argv[0]; + else + Pname++; + + while ((retval = getopt(argc, argv, "s:b:c:")) != -1) { + switch (retval) { + case 's': + sb_seen = 1; + tr.emul64_blkrange.emul64_sb = atoll(optarg); + break; + case 'b': + count_seen = 1; + tr.emul64_blkrange.emul64_blkcnt = atoll(optarg); + break; + case 'c': + if (strncmp(optarg, "write_off", + strlen("write_off")) == 0) { + cmd = EMUL64_WRITE_OFF; + } else if (strncmp(optarg, "write_on", + strlen("write_on")) == 0) { + cmd = EMUL64_WRITE_ON; + } else if (strncmp(optarg, "zero", + strlen("zero")) == 0) { + cmd = EMUL64_ZERO_RANGE; + } else { + do_usage = 1; + } + break; + default: + break; + } + } + + if (do_usage || (optind != argc - 1)) { + usage(); + } + if ((sb_seen == 0) || (count_seen == 0) || (cmd == -1)) + usage(); + + slice = argv[optind]; + + /* + * Get admin device, target and lun + */ + if (get_disk_addr(slice, &tr, &admin) != 0) + exit(1); + + /* + * open the specified emul64_dev. + */ + if ((fd = open(admin, O_RDONLY, 0444)) != -1) { + + retval = ioctl(fd, cmd, &tr); + (void) close(fd); + + if (retval != -1) { + free(admin); + return (0); + } + (void) printf("emul64ioctl: %s: ioctl %s\n", + admin, strerror(errno)); + } else { + (void) printf("emul64ioctl: %s: open %s\n", + admin, strerror(errno)); + } + free(admin); + return (1); +} + +#define TOK_CHECK(s) if (token == NULL) {\ + bogus = (s);\ + goto err_out;\ + } + +static int +get_disk_addr(char *path, emul64_tgt_range_t *tr, char **admin) +{ + size_t admin_size; + int ctlr_num; + int conversions; + char *ctds; + + *admin = NULL; + ctds = strrchr(path, '/'); + if (ctds == NULL) + ctds = path; + else + ctds++; + conversions = sscanf(ctds, "c%dt%hud%hu", &ctlr_num, + &tr->emul64_target, &tr->emul64_lun); + if (conversions != 3) { + (void) fprintf(stderr, "%s: \"%s\" is invalid disk name. " + "%d conversions\n", Pname, ctds, conversions); + return (-1); + } + + /* Build controller name */ + admin_size = strlen(ADMIN_DIR) + + 10 + /* enough digits for an int */ + 1 + /* c */ + 1; /* Null terminator */ + *admin = malloc(admin_size); + if (*admin == NULL) { + (void) fprintf(stderr, "%s: out of memory\n", Pname); + return (-1); + } + (void) snprintf(*admin, admin_size, "%sc%d", ADMIN_DIR, ctlr_num); + return (0); +}