--- sys/dev/ata/ata-all.c.orig Tue Jun 7 17:33:23 2005 +++ sys/dev/ata/ata-all.c Sat Jun 18 17:12:48 2005 @@ -493,6 +493,38 @@ case IOCATAGMODE: *mode = atadev->mode; return 0; + + case IOCATASTANDBY: + if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) + ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0); + + ata_controlcmd(dev, ATA_STANDBY_IMMEDIATE, 0, 0, 0); + return 0; + + case IOCATAIDLE: + if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) + ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0); + + ata_controlcmd(dev, ATA_IDLE_IMMEDIATE, 0, 0, 0); + return 0; + + case IOCATACHECKPWRMODE: + if (!(request = ata_alloc_request())) + return ENOMEM; + + request->dev = dev; + request->u.ata.command = ATA_CHECK_PWR_MODE; + request->u.ata.lba = 0; + request->u.ata.count = 0; + request->u.ata.feature = 0; + request->flags = ATA_R_CONTROL; + request->timeout = 1; + request->retries = 0; + ata_queue_request(request); + *mode = request->u.ata.count; + ata_free_request(request); + return 0; + default: return ENOTTY; } --- sbin/atacontrol/atacontrol.c.orig Tue Jun 7 17:27:41 2005 +++ sbin/atacontrol/atacontrol.c Sat Jun 18 17:10:47 2005 @@ -109,6 +109,9 @@ " atacontrol status array\n" " atacontrol mode device [mode]\n" " atacontrol cap device\n" + " atacontrol pwrstatus device\n" + " atacontrol standby device\n" + " atacontrol idle device\n" ); exit(EX_USAGE); } @@ -337,6 +340,77 @@ if ((fd = open(device, O_RDONLY)) < 0) err(1, "device not found"); ata_cap_print(fd); + exit(EX_OK); + } + if (!strcmp(argv[1], "idle") && argc == 3) { + int disk; + char device[64]; + + if (!(sscanf(argv[2], "ad%d", &disk) == 1 || + sscanf(argv[2], "acd%d", &disk) == 1 || + sscanf(argv[2], "afd%d", &disk) == 1 || + sscanf(argv[2], "ast%d", &disk) == 1)) { + fprintf(stderr, "atacontrol: Invalid device %s\n", + argv[2]); + exit(EX_USAGE); + } + sprintf(device, "/dev/%s", argv[2]); + if ((fd = open(device, O_RDONLY)) < 0) + err(1, "device not found"); + if (ioctl(fd, IOCATAIDLE, &disk) < 0) + err(1, "ioctl(ATAIDLE)"); + exit(EX_OK); + } + if (!strcmp(argv[1], "standby") && argc == 3) { + int disk; + char device[64]; + + if (!(sscanf(argv[2], "ad%d", &disk) == 1 || + sscanf(argv[2], "acd%d", &disk) == 1 || + sscanf(argv[2], "afd%d", &disk) == 1 || + sscanf(argv[2], "ast%d", &disk) == 1)) { + fprintf(stderr, "atacontrol: Invalid device %s\n", + argv[2]); + exit(EX_USAGE); + } + sprintf(device, "/dev/%s", argv[2]); + if ((fd = open(device, O_RDONLY)) < 0) + err(1, "device not found"); + if (ioctl(fd, IOCATASTANDBY, &disk) < 0) + err(1, "ioctl(ATASTANDBY)"); + exit(EX_OK); + } + if (!strcmp(argv[1], "pwrstatus") && argc == 3) { + int disk; + char device[64]; + + if (!(sscanf(argv[2], "ad%d", &disk) == 1 || + sscanf(argv[2], "acd%d", &disk) == 1 || + sscanf(argv[2], "afd%d", &disk) == 1 || + sscanf(argv[2], "ast%d", &disk) == 1)) { + fprintf(stderr, "atacontrol: Invalid device %s\n", + argv[2]); + exit(EX_USAGE); + } + sprintf(device, "/dev/%s", argv[2]); + if ((fd = open(device, O_RDONLY)) < 0) + err(1, "device not found"); + if (ioctl(fd, IOCATACHECKPWRMODE, &disk) < 0) + err(1, "ioctl(ATACHECKPWRMODE)"); + switch (disk) { + case 0x00: + printf("device is in standby mode\n"); + break; + case 0x80: + printf("device is in idle mode\n"); + break; + case 0xff: + printf("device is in active or idle mode\n"); + break; + default: + printf("unknown mode\n"); + break; + } exit(EX_OK); } --- sys/sys/ata.h.orig Tue Jun 7 17:42:52 2005 +++ sys/sys/ata.h Sat Jun 18 18:01:30 2005 @@ -252,6 +252,7 @@ #define ATA_STANDBY_CMD 0xe2 /* standby */ #define ATA_IDLE_CMD 0xe3 /* idle */ #define ATA_READ_BUFFER 0xe4 /* read buffer */ +#define ATA_CHECK_PWR_MODE 0xe5 /* check power mode */ #define ATA_SLEEP 0xe6 /* sleep */ #define ATA_FLUSHCACHE 0xe7 /* flush cache to disk */ #define ATA_FLUSHCACHE48 0xea /* flush cache to disk */ @@ -372,6 +373,9 @@ #define IOCATAGPARM _IOR('a', 101, struct ata_params) #define IOCATAGMODE _IOR('a', 102, int) #define IOCATASMODE _IOW('a', 103, int) +#define IOCATAIDLE _IOW('a', 131, int) +#define IOCATASTANDBY _IOW('a', 132, int) +#define IOCATACHECKPWRMODE _IOR('a', 133, int) struct ata_ioc_raid_config {