diff -ruN ../HEAD/sbin/atacontrol/atacontrol.8 ./sbin/atacontrol/atacontrol.8 --- ../HEAD/sbin/atacontrol/atacontrol.8 2008-06-25 20:11:22.000000000 +0200 +++ ./sbin/atacontrol/atacontrol.8 2008-09-20 23:21:14.000000000 +0200 @@ -70,6 +70,9 @@ .Ic cap .Ar device .Nm +.Ic security +.Ar device +.Nm .Ic spindown .Ar device .Op Ar seconds @@ -194,6 +197,9 @@ .It Ic cap Show detailed info about the device on .Ar device . +.It Ic security +Show details on the ATA Security status of the +.Ar device . .It Ic spindown Set or report timeout after which the .Ar device diff -ruN ../HEAD/sbin/atacontrol/atacontrol.c ./sbin/atacontrol/atacontrol.c --- ../HEAD/sbin/atacontrol/atacontrol.c 2008-08-06 20:08:02.000000000 +0200 +++ ./sbin/atacontrol/atacontrol.c 2008-09-20 22:57:33.000000000 +0200 @@ -103,6 +103,7 @@ " atacontrol status array\n" " atacontrol mode device [mode]\n" " atacontrol cap device\n" + " atacontrol security device\n" " atacontrol spindown device [seconds]\n" ); exit(EX_USAGE); @@ -309,6 +310,59 @@ } } +static void +security_print_time(u_int16_t tw) +{ + if (tw == 0) + printf("unspecified"); + else if (tw >= 255) + printf("> 508 min"); + else + printf("%i min", 2 * tw); +} + +static void +security_print(struct ata_params *parm) +{ + printf("\n"); +#if 0 + printf("Security status %04x\n", parm->security_status); +#endif + printf("Security supported %s\n", + parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no"); + printf("Security enabled %s\n", + parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no"); + printf("Drive locked %s\n", + parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no"); + printf("Configuration frozen %s\n", + parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no"); + printf("Count expired %s\n", + parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no"); + printf("Security level %s\n", + parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high"); + printf("Erase time "); + security_print_time(parm->erase_time); + printf("\n"); + printf("Enhanced erase time "); + security_print_time(parm->enhanced_erase_time); + printf("\n"); + printf("Master password rev %04x%s\n", + parm->master_passwd_revision, + parm->master_passwd_revision == 0x0000 || + parm->master_passwd_revision == 0xFFFF ? + " (unsupported)" : ""); +} + +static void +ata_security_print(int fd) +{ + struct ata_params params; + + if (ioctl(fd, IOCATAGPARM, ¶ms) < 0) + err(1, "ioctl(IOCATAGPARM)"); + security_print(¶ms); +} + static int open_dev(const char *arg, int mode) { @@ -386,6 +440,12 @@ exit(EX_OK); } + if (!strcmp(argv[1], "security") && argc == 3) { + fd = open_dev(argv[2], O_RDONLY); + ata_security_print(fd); + exit(EX_OK); + } + if ((fd = open("/dev/ata", O_RDWR)) < 0) err(1, "control device not found"); diff -ruN ../HEAD/sys/sys/ata.h ./sys/sys/ata.h --- ../HEAD/sys/sys/ata.h 2008-04-10 15:01:17.000000000 +0200 +++ ./sys/sys/ata.h 2008-09-20 22:44:11.000000000 +0200 @@ -170,10 +170,10 @@ } __packed support, enabled; /*088*/ u_int16_t udmamodes; /* UltraDMA modes */ -/*089*/ u_int16_t erase_time; -/*090*/ u_int16_t enhanced_erase_time; +/*089*/ u_int16_t erase_time; /* time req'd in 2min units */ +/*090*/ u_int16_t enhanced_erase_time; /* time req'd in 2min units */ /*091*/ u_int16_t apm_value; -/*092*/ u_int16_t master_passwd_revision; +/*092*/ u_int16_t master_passwd_revision; /* password revision code */ /*093*/ u_int16_t hwres; #define ATA_CABLE_ID 0x2000 @@ -191,7 +191,16 @@ u_int16_t lba_size48_4; u_int16_t reserved104[23]; /*127*/ u_int16_t removable_status; + /*128*/ u_int16_t security_status; +#define ATA_SECURITY_LEVEL 0x0100 /* 0: high, 1: maximum */ +#define ATA_SECURITY_ENH_SUPP 0x0020 /* enhanced erase supported */ +#define ATA_SECURITY_COUNT_EXP 0x0010 /* count expired */ +#define ATA_SECURITY_FROZEN 0x0008 /* security config is frozen */ +#define ATA_SECURITY_LOCKED 0x0004 /* drive is locked */ +#define ATA_SECURITY_ENABLED 0x0002 /* ATA Security is enabled */ +#define ATA_SECURITY_SUPPORTED 0x0001 /* ATA Security is supported */ + u_int16_t reserved129[31]; /*160*/ u_int16_t cfa_powermode1; u_int16_t reserved161[15]; @@ -283,7 +292,12 @@ #define ATA_SF_DIS_RELIRQ 0xdd /* disable release interrupt */ #define ATA_SF_ENAB_SRVIRQ 0x5e /* enable service interrupt */ #define ATA_SF_DIS_SRVIRQ 0xde /* disable service interrupt */ -#define ATA_SECURITY_FREEE_LOCK 0xf5 /* freeze security config */ +#define ATA_SECURITY_SET_PASSWORD 0xf1 /* set drive password */ +#define ATA_SECURITY_UNLOCK 0xf2 /* unlock drive using passwd */ +#define ATA_SECURITY_ERASE_PREPARE 0xf3 /* prepare to erase drive */ +#define ATA_SECURITY_ERASE_UNIT 0xf4 /* erase all blocks on drive */ +#define ATA_SECURITY_FREEZE_LOCK 0xf5 /* freeze security config */ +#define ATA_SECURITY_DISABLE_PASSWORD 0xf6 /* disable drive password */ #define ATA_READ_NATIVE_MAX_ADDRESS 0xf8 /* read native max address */ #define ATA_SET_MAX_ADDRESS 0xf9 /* set max address */ @@ -429,7 +443,7 @@ int error; }; -/* pr device ATA ioctl calls */ +/* per device ATA ioctl calls */ #define IOCATAREQUEST _IOWR('a', 100, struct ata_ioc_request) #define IOCATAGPARM _IOR('a', 101, struct ata_params) #define IOCATAGMODE _IOR('a', 102, int)