Add camcontrol subcommands to control APM and AAM levels.

MFC after:	1 week
Sponsored by:	iXsystems, Inc.
This commit is contained in:
Alexander Motin 2015-03-19 12:22:57 +00:00
parent 2fb34dae14
commit e7affda584
2 changed files with 99 additions and 3 deletions

View File

@ -27,7 +27,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd August 31, 2014 .Dd March 19, 2015
.Dt CAMCONTROL 8 .Dt CAMCONTROL 8
.Os .Os
.Sh NAME .Sh NAME
@ -239,6 +239,16 @@
.Op device id .Op device id
.Op generic args .Op generic args
.Nm .Nm
.Ic apm
.Op device id
.Op generic args
.Op Fl l Ar level
.Nm
.Ic aam
.Op device id
.Op generic args
.Op Fl l Ar level
.Nm
.Ic fwdownload .Ic fwdownload
.Op device id .Op device id
.Op generic args .Op generic args
@ -1291,6 +1301,19 @@ Value 0 disables timer.
Put ATA device into SLEEP state. Put ATA device into SLEEP state.
Note that the only way get device out of Note that the only way get device out of
this state may be reset. this state may be reset.
.It Ic apm
It optional parameter
.Pq Fl l
specified, enables and sets advanced power management level, where
1 -- minimum power, 127 -- maximum performance with standby,
128 -- minimum power without standby, 254 -- maximum performance.
If not specified -- APM is disabled.
.It Ic aam
It optional parameter
.Pq Fl l
specified, enables and sets automatic acoustic management level, where
1 -- minimum noise, 254 -- maximum performance.
If not specified -- AAM is disabled.
.It Ic security .It Ic security
Update or report security settings, using an ATA identify command (0xec). Update or report security settings, using an ATA identify command (0xec).
By default, By default,

View File

@ -96,7 +96,9 @@ typedef enum {
CAM_CMD_SECURITY = 0x0000001d, CAM_CMD_SECURITY = 0x0000001d,
CAM_CMD_HPA = 0x0000001e, CAM_CMD_HPA = 0x0000001e,
CAM_CMD_SANITIZE = 0x0000001f, CAM_CMD_SANITIZE = 0x0000001f,
CAM_CMD_PERSIST = 0x00000020 CAM_CMD_PERSIST = 0x00000020,
CAM_CMD_APM = 0x00000021,
CAM_CMD_AAM = 0x00000022
} cam_cmdmask; } cam_cmdmask;
typedef enum { typedef enum {
@ -216,6 +218,8 @@ static struct camcontrol_opts option_table[] = {
{"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"}, {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
{"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"}, {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
{"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""}, {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
{"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
{"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
{"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"}, {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"},
{"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"}, {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
{"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"}, {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
@ -1406,7 +1410,7 @@ atacapprint(struct ata_params *parm)
parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no"); parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
if (parm->support.command2 & ATA_SUPPORT_APM) { if (parm->support.command2 & ATA_SUPPORT_APM) {
printf(" %d/0x%02X\n", printf(" %d/0x%02X\n",
parm->apm_value, parm->apm_value); parm->apm_value & 0xff, parm->apm_value & 0xff);
} else } else
printf("\n"); printf("\n");
printf("automatic acoustic management %s %s", printf("automatic acoustic management %s %s",
@ -7983,6 +7987,68 @@ atapm(struct cam_device *device, int argc, char **argv,
return (retval); return (retval);
} }
static int
ataaxm(struct cam_device *device, int argc, char **argv,
char *combinedopt, int retry_count, int timeout)
{
union ccb *ccb;
int retval = 0;
int l = -1;
int c;
u_char cmd, sc;
ccb = cam_getccb(device);
if (ccb == NULL) {
warnx("%s: error allocating ccb", __func__);
return (1);
}
while ((c = getopt(argc, argv, combinedopt)) != -1) {
switch (c) {
case 'l':
l = atoi(optarg);
break;
default:
break;
}
}
sc = 0;
if (strcmp(argv[1], "apm") == 0) {
if (l == -1)
cmd = 0x85;
else {
cmd = 0x05;
sc = l;
}
} else /* aam */ {
if (l == -1)
cmd = 0xC2;
else {
cmd = 0x42;
sc = l;
}
}
retval = ata_do_28bit_cmd(device,
ccb,
/*retries*/retry_count,
/*flags*/CAM_DIR_NONE,
/*protocol*/AP_PROTO_NON_DATA,
/*tag_action*/MSG_SIMPLE_Q_TAG,
/*command*/ATA_SETFEATURES,
/*features*/cmd,
/*lba*/0,
/*sector_count*/sc,
/*data_ptr*/NULL,
/*dxfer_len*/0,
/*timeout*/timeout ? timeout : 30 * 1000,
/*quiet*/1);
cam_freeccb(ccb);
return (retval);
}
#endif /* MINIMALISTIC */ #endif /* MINIMALISTIC */
void void
@ -8040,6 +8106,8 @@ usage(int printlong)
" camcontrol idle [dev_id][generic args][-t time]\n" " camcontrol idle [dev_id][generic args][-t time]\n"
" camcontrol standby [dev_id][generic args][-t time]\n" " camcontrol standby [dev_id][generic args][-t time]\n"
" camcontrol sleep [dev_id][generic args]\n" " camcontrol sleep [dev_id][generic args]\n"
" camcontrol apm [dev_id][generic args][-l level]\n"
" camcontrol aam [dev_id][generic args][-l level]\n"
" camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n" " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
" camcontrol security [dev_id][generic args]\n" " camcontrol security [dev_id][generic args]\n"
" <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n" " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
@ -8560,6 +8628,11 @@ main(int argc, char **argv)
error = atapm(cam_dev, argc, argv, error = atapm(cam_dev, argc, argv,
combinedopt, retry_count, timeout); combinedopt, retry_count, timeout);
break; break;
case CAM_CMD_APM:
case CAM_CMD_AAM:
error = ataaxm(cam_dev, argc, argv,
combinedopt, retry_count, timeout);
break;
case CAM_CMD_SECURITY: case CAM_CMD_SECURITY:
error = atasecurity(cam_dev, retry_count, timeout, error = atasecurity(cam_dev, retry_count, timeout,
argc, argv, combinedopt); argc, argv, combinedopt);