Last active
January 12, 2018 22:01
-
-
Save sjorge/c3e438b00cc73543e25aa049423cbfe8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* HD Set Parm | |
* ---------------------------- | |
* Based on setapm and setaam from: | |
* http://solaris.kuehnke.de/archives/23-Set-APM-and-AAM-feature-configuration \ | |
* -attributes-for-disks-on-Solaris.html | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <fcntl.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <limits.h> | |
#include <sys/ioctl.h> | |
#include <sys/scsi/impl/uscsi.h> | |
uchar_t sf_enable_apm_cdb[12] = { 0xa1, 0x06, 0x0c, 0x05, 0x24, 0x00, | |
0x00, 0x00, 0x00, 0xef, 0x00, 0x00 }; | |
uchar_t sf_enable_aam_cdb[12] = { 0xa1, 0x06, 0x0c, 0x42, 0xd0, 0x00, | |
0x00, 0x00, 0x00, 0xef, 0x00, 0x00 }; | |
static void | |
usage(int argc, char *argv[]) | |
{ | |
fprintf(stderr, "Usage: %s <device> <APM|AAM> <Level>\n", argv[0]); | |
fprintf(stderr, " where Level = [0..254] (0=Disable APM/AAM)\n"); | |
exit(EXIT_FAILURE); | |
} | |
int | |
main(int argc, char *argv[]) | |
{ | |
int i; | |
int disk_fd; | |
int plevel; | |
char pname[4]; | |
char disk_path[PATH_MAX]; | |
uchar_t sf_enable_axm_cdb[12]; | |
struct uscsi_cmd scsi_cmd; | |
/* | |
* validate input | |
*/ | |
if (argc != 4) { | |
/* incorrect argument count */ | |
usage(argc, argv); | |
} | |
if (argv[1][0] != '/') { | |
/* we have a bare disk name */ | |
snprintf(disk_path, sizeof (disk_path), | |
"/dev/rdsk/%s", argv[1]); | |
} else { | |
/* we have an absolute disk name */ | |
if (strlcpy(disk_path, argv[1], sizeof (disk_path)) >= | |
sizeof (disk_path)) { | |
perror("device path is to long!"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
if ((disk_fd = open(disk_path, O_RDWR | O_NDELAY)) < 0) { | |
/* unable to open device, does it exists? */ | |
perror("Failed to open device"); | |
exit(EXIT_FAILURE); | |
} | |
if (strlen(argv[2]) != 3) { | |
/* pname is not 3 long */ | |
usage(argc, argv); | |
} | |
strlcpy(pname, argv[2], sizeof (pname)); | |
if ((strncasecmp(pname, "APM", 3) != 0) && | |
(strncasecmp(pname, "AAM", 3) != 0)) { | |
usage(argc, argv); | |
} | |
for (i = 0; i < strlen(pname); i++) { | |
/* make the str pname to be upper case */ | |
/* FIXME: can this be cleaned up ? */ | |
pname[i] = toupper(pname[i]); | |
} | |
if (sscanf(argv[3], "%d", &plevel) != 1) { /* failed to read plevel */ | |
usage(argc, argv); | |
} | |
if (plevel < 0 || plevel > 254) { | |
/* plevel not in acceptable range */ | |
usage(argc, argv); | |
} | |
/* print notice */ | |
fprintf(stdout, "Setting %s to %d for disk %s ...\n", | |
pname, plevel, disk_path); | |
/* copy correct template */ | |
if (strncasecmp(pname, "APM", 3) == 0) { | |
memcpy(sf_enable_axm_cdb, sf_enable_apm_cdb, \ | |
sizeof (sf_enable_axm_cdb)); | |
} else { | |
memcpy(sf_enable_axm_cdb, sf_enable_aam_cdb, \ | |
sizeof (sf_enable_axm_cdb)); | |
} | |
/* insert plevel */ | |
sf_enable_axm_cdb[4] = (unsigned char)plevel; | |
if (plevel == 0) { | |
sf_enable_axm_cdb[3] = 0x85; | |
} | |
/* prepare scsi command */ | |
memset(&scsi_cmd, 0, sizeof (scsi_cmd)); | |
scsi_cmd.uscsi_cdblen = 12; | |
scsi_cmd.uscsi_timeout = 30; | |
scsi_cmd.uscsi_flags = USCSI_READ | USCSI_SILENT | USCSI_ISOLATE; | |
scsi_cmd.uscsi_cdb = (caddr_t)sf_enable_axm_cdb; | |
scsi_cmd.uscsi_rqbuf = NULL; | |
scsi_cmd.uscsi_rqlen = 0; | |
/* send scsi command */ | |
if (ioctl(disk_fd, USCSICMD, &scsi_cmd) < 0) { | |
close(disk_fd); | |
perror("USCSICMD ioctl failed"); | |
exit(EXIT_FAILURE); | |
} | |
/* cleanup */ | |
close(disk_fd); | |
fprintf(stdout, "Success.\n"); | |
return (EXIT_SUCCESS); | |
} | |
/* vim: set tabstop=8 noexpandtab shiftwidth=8 softtabstop=8 : */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@mgerdts is sys/ioctl.h and unistd.h needed? Compiles and seems to run fine without those, but IIRC close () is provided by unistd.h? And I thought the ioctl command came from ioctl.h?