ata_id.c revision ad29a9f14fa8b1932c0e418bfcf1c10ce6a35a33
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * ata_id - reads product/serial number from ATA drives
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers * Copyright (C) 2005-2008 Kay Sievers <kay.sievers@vrfy.org>
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers * Copyright (C) 2009 Lennart Poettering <lennart@poettering.net>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Copyright (C) 2009-2010 David Zeuthen <zeuthen@gmail.com>
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * This program is free software: you can redistribute it and/or modify
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * it under the terms of the GNU General Public License as published by
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * the Free Software Foundation, either version 2 of the License, or
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * (at your option) any later version.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * This program is distributed in the hope that it will be useful,
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * GNU General Public License for more details.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * You should have received a copy of the GNU General Public License
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * along with this program. If not, see <http://www.gnu.org/licenses/>.
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger * INQUIRY, see SPC-4 section 6.4
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger cdb[0] = 0x12; /* OPERATION CODE: INQUIRY */
a59f16ce4a11c440cb2136ad3d5e3184714c545eRobert Schiele cdb[3] = (buf_len >> 8); /* ALLOCATION LENGTH */
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger memset(&io_v4, 0, sizeof(struct sg_io_v4));
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
f975e971accc4d50c73ae53167db3df7a7099cf2Lennart Poettering /* could be that the driver doesn't do version 4, try version 3 */
66b0e0e0e3652227fe107ab9d09fa14fd4bc4dfaCristian Rodríguez /* even if the ioctl succeeds, we need to check the return value */
92ec4495f76a7a2a6c31f5bb2a5240f78dcfe1d2Javier Jardón /* even if the ioctl succeeds, we need to check the return value */
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmek if (!(io_v4.device_status == 0 &&
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek * ATA Pass-Through 12 byte command, as described in
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek * T10 04-262r8 ATA Command Pass-Through
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek cdb[0] = 0xa1; /* OPERATION CODE: 12 byte pass through */
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek cdb[1] = 4 << 1; /* PROTOCOL: PIO Data-in */
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek cdb[2] = 0x2e; /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek cdb[9] = 0xEC; /* Command: ATA IDENTIFY DEVICE */;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek memset(sense, 0, sizeof(sense));
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek memset(&io_v4, 0, sizeof(struct sg_io_v4));
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek io_v4.protocol = BSG_PROTOCOL_SCSI;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek io_v4.request_len = sizeof (cdb);
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek io_v4.request = (uintptr_t) cdb;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering /* could be that the driver doesn't do version 4, try version 3 */
03930e48636e86ad84946253ca2bf4f91deeb645Lennart Poettering memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
213298fb822258bb69c6b85b7c8d7f019fd2306aLennart Poettering if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
aca33b078cd32c5416a7fa3d5020a5d461c130eeCristian Rodríguezstatic int disk_identify_packet_device_command(int fd,
b850b06e1efcc7e27cfd785759a3a913ac9ed196Kay Sievers * ATA Pass-Through 16 byte command, as described in
b850b06e1efcc7e27cfd785759a3a913ac9ed196Kay Sievers * T10 04-262r8 ATA Command Pass-Through
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
a6c0b31d509f76023d8efbcd5e912863c8fb254cZbigniew Jędrzejewski-Szmek cdb[0] = 0x85; /* OPERATION CODE: 16 byte pass through */
a6c0b31d509f76023d8efbcd5e912863c8fb254cZbigniew Jędrzejewski-Szmek cdb[1] = 4 << 1; /* PROTOCOL: PIO Data-in */
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek cdb[2] = 0x2e; /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
ccd06097c79218f7d5ea4c21721bbcbc7c467dcaZbigniew Jędrzejewski-Szmek cdb[14] = 0xA1; /* Command: ATA IDENTIFY PACKET DEVICE */;
de99c9dcbaf6e474551266d8f0b519bf2d8d0522Lennart Poettering memset(&io_v4, 0, sizeof(struct sg_io_v4));
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek io_v4.protocol = BSG_PROTOCOL_SCSI;
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek io_v4.request_len = sizeof (cdb);
ccd06097c79218f7d5ea4c21721bbcbc7c467dcaZbigniew Jędrzejewski-Szmek io_v4.request = (uintptr_t) cdb;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek io_v4.max_response_len = sizeof (sense);
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek io_v4.response = (uintptr_t) sense;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek io_v4.din_xferp = (uintptr_t) buf;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek io_v4.timeout = COMMAND_TIMEOUT_MSEC;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek /* could be that the driver doesn't do version 4, try version 3 */
be8737ae386166d2f279767ac87b226204c0de7eFilipe Brandenburger memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek io_hdr.mx_sb_len = sizeof (sense);
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek ret = ioctl(fd, SG_IO, &io_hdr);
1864b0e39505cd44a98eee61c97916b86491c0b4Zbigniew Jędrzejewski-Szmek if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
a6c0b31d509f76023d8efbcd5e912863c8fb254cZbigniew Jędrzejewski-Szmek * disk_identify_get_string:
a6c0b31d509f76023d8efbcd5e912863c8fb254cZbigniew Jędrzejewski-Szmek * @identify: A block of IDENTIFY data
f2ec0646aba7c6703a6c79603957e805b74c3befZbigniew Jędrzejewski-Szmek * @offset_words: Offset of the string to get, in words.
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek * @dest: Destination buffer for the string.
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek * @dest_len: Length of destination buffer, in bytes.
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek * Copies the ATA string from @identify located at @offset_words into @dest.
afea26ad7d406d8b6c95d2642cb5a1d807b87546Lennart Poetteringstatic void disk_identify_get_string (uint8_t identify[512],
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers unsigned int c1;
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers unsigned int c2;
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers while (dest_len > 0) {
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers c1 = ((uint16_t *) identify)[offset_words] >> 8;
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers c2 = ((uint16_t *) identify)[offset_words] & 0xff;
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmekstatic void disk_identify_fixup_string (uint8_t identify[512],
5f381b355a95b953654e46ba3ccdc81bdec165eaLennart Poettering disk_identify_get_string(identify, offset_words,
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek (char *) identify + offset_words * 2, len);
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmekstatic void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offset_words)
75616a1332aff00d27db713cda3bd93c508a5b59Zbigniew Jędrzejewski-Szmek p[offset_words] = le16toh (p[offset_words]);
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek * disk_identify:
8ecec322fe6b34b64868d8cc3808b5613f09e8d3Zbigniew Jędrzejewski-Szmek * @udev: The libudev context.
cf1755bac0426132c21fdca519a336ce7d920277Michael Olbrich * @fd: File descriptor for the block device.
34f7b9f98facbf3431c6849622104cee992f2b7dLennart Poettering * @out_identify: Return location for IDENTIFY data.
34f7b9f98facbf3431c6849622104cee992f2b7dLennart Poettering * @out_is_packet_device: Return location for whether returned data is from a IDENTIFY PACKET DEVICE.
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek * Sends the IDENTIFY DEVICE or IDENTIFY PACKET DEVICE command to the
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek * device represented by @fd. If successful, then the result will be
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek * copied into @out_identify and @out_is_packet_device.
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek * This routine is based on code from libatasmart, Copyright 2008
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek * Lennart Poettering, LGPL v2.1.
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek * Returns: 0 if the data was successfully obtained, otherwise
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek * non-zero with errno set.
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek /* init results */
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing /* If we were to use ATA PASS_THROUGH (12) on an ATAPI device
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing * we could accidentally blank media. This is because MMC's BLANK
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing * command has the same op-code (0x61).
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing * To prevent this from happening we bail out if the device
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing * isn't a Direct Access Block Device, e.g. SCSI type 0x00
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing * (CD/DVD devices are type 0x05). So we send a SCSI INQUIRY
37161c5148396448921841ae1026b281c7949652Emil Renner Berthing * command first... libata is handling this via its SCSI
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek * emulation layer.
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek * This also ensures that we're actually dealing with a device
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek * that understands SCSI commands.
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek * (Yes, it is a bit perverse that we're tunneling the ATA
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek * command through SCSI and relying on the ATA driver
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek * emulating SCSI well-enough...)
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek * (See commit 160b069c25690bfb0c785994c7c3710289179107 for
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek * the original bug-fix and see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=556635
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen * for the original bug-report.)
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen ret = disk_scsi_inquiry_command (fd, inquiry_buf, sizeof (inquiry_buf));
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen /* SPC-4, section 6.4.2: Standard INQUIRY data */
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen peripheral_device_type = inquiry_buf[0] & 0x1f;
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen ret = disk_identify_packet_device_command(fd, out_identify, 512);
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen /* OK, now issue the IDENTIFY DEVICE command */
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen ret = disk_identify_command(fd, out_identify, 512);
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen /* Check if IDENTIFY data is all NUL bytes - if so, bail */
e2ca86cf78f911a8be51f0224796e24883019139Dave Reisner for (n = 0; n < 512; n++) {
d4f5a1f47dbd04f26f2ddf951c97c4cb0ebbbe62David Herrmannstatic void log_fn(struct udev *udev, int priority,
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier option = getopt_long(argc, argv, "xh", options, NULL);
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu printf("Usage: ata_id [--export] [--help] <device>\n"
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu " --export print values as environment keys\n"
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu " --help print this help text\n\n");
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering err(udev, "unable to open '%s'\n", node);
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer if (disk_identify(udev, fd, identify, &is_packet_device) == 0) {
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer * fix up only the fields from the IDENTIFY data that we are going to
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer * use and copy it into the hd_driveid struct for convenience
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_string (identify, 10, 20); /* serial */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_string (identify, 23, 6); /* fwrev */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_string (identify, 27, 40); /* model */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_uint16 (identify, 0); /* configuration */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_uint16 (identify, 75); /* queue depth */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_uint16 (identify, 75); /* SATA capabilities */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_uint16 (identify, 82); /* command set supported */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_uint16 (identify, 83); /* command set supported */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_uint16 (identify, 84); /* command set supported */
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer disk_identify_fixup_uint16 (identify, 85); /* command set supported */
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez disk_identify_fixup_uint16 (identify, 86); /* command set supported */
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez disk_identify_fixup_uint16 (identify, 87); /* command set supported */
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez disk_identify_fixup_uint16 (identify, 89); /* time required for SECURITY ERASE UNIT */
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez disk_identify_fixup_uint16 (identify, 90); /* time required for enhanced SECURITY ERASE UNIT */
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez disk_identify_fixup_uint16 (identify, 91); /* current APM values */
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez disk_identify_fixup_uint16 (identify, 94); /* current AAM value */
5ec6b15b65304d94dc1c8cbad05c8b996b470d3aKay Sievers disk_identify_fixup_uint16 (identify, 128); /* device lock function */
56cf987fe74270bde4e16c7ec9e0414a9030723bDaniel J Walsh disk_identify_fixup_uint16 (identify, 217); /* nominal media rotation rate */
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez /* If this fails, then try HDIO_GET_IDENTITY */
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0) {
45df1f2c9a7fee67b37f64ddd00adad5982844faCristian Rodríguez info(udev, "HDIO_GET_IDENTITY unsupported for '%s'\n", node);
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmek err(udev, "HDIO_GET_IDENTITY failed for '%s': %m\n", node);
ad95fd1d2b9c6344864857c2ba7634fd87753f8eZbigniew Jędrzejewski-Szmek identify_words = (uint16_t *) identify;
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering udev_util_encode_string(model, model_enc, sizeof(model_enc));
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering util_replace_whitespace((char *) id.model, model, 40);
6bf12f55aff33a588a1945d9d06aa31c164984fdLennart Poettering util_replace_whitespace((char *) id.serial_no, serial, 20);
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek util_replace_whitespace((char *) id.fw_rev, revision, 8);
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering /* Set this to convey the disk speaks the ATA protocol */
edce2aed3aa93b84f7b4c70412bdb665da2977b0Lennart Poettering /* This is an ATAPI device */
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek printf("ID_MODEL_ENC=%s\n", model_enc);
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek printf("ID_SERIAL=%s_%s\n", model, serial);
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek printf("ID_SERIAL_SHORT=%s\n", serial);
d89c8fdf48c7bad5816b9f2e77e8361721f22517Zbigniew Jędrzejewski-Szmek printf("ID_SERIAL=%s\n", model);
3b1a55e110ab387a8d213581983e20c0a63d7894Zbigniew Jędrzejewski-Szmek if (id.command_set_1 & (1<<5)) {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf ("ID_ATA_WRITE_CACHE_ENABLED=%d\n", (id.cfs_enable_1 & (1<<5)) ? 1 : 0);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_HPA_ENABLED=%d\n", (id.cfs_enable_1 & (1<<10)) ? 1 : 0);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering * TODO: use the READ NATIVE MAX ADDRESS command to get the native max address
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering * so it is easy to check whether the protected area is in use.
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_PM_ENABLED=%d\n", (id.cfs_enable_1 & (1<<3)) ? 1 : 0);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_SECURITY=1\n");
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_SECURITY_ENABLED=%d\n", (id.cfs_enable_1 & (1<<1)) ? 1 : 0);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_SECURITY_ERASE_UNIT_MIN=%d\n", id.trseuc * 2);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering if ((id.cfs_enable_1 & (1<<1))) /* enabled */ {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=maximum\n");
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=high\n");
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_SECURITY_ENHANCED_ERASE_UNIT_MIN=%d\n", id.trsEuc * 2);
6a6751fe24bf456cf5c1efad785a4d11e78b42d0Lennart Poettering printf("ID_ATA_FEATURE_SET_SECURITY_EXPIRE=1\n");
812cce323db081634f37e4ec6d29f2b9328a3f52Lennart Poettering printf("ID_ATA_FEATURE_SET_SECURITY_FROZEN=1\n");
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_SECURITY_LOCKED=1\n");
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering printf("ID_ATA_FEATURE_SET_SMART_ENABLED=%d\n", (id.cfs_enable_1 & (1<<0)) ? 1 : 0);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering printf("ID_ATA_FEATURE_SET_AAM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<9)) ? 1 : 0);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering printf("ID_ATA_FEATURE_SET_AAM_VENDOR_RECOMMENDED_VALUE=%d\n", id.acoustic >> 8);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering printf("ID_ATA_FEATURE_SET_AAM_CURRENT_VALUE=%d\n", id.acoustic & 0xff);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering printf("ID_ATA_FEATURE_SET_PUIS_ENABLED=%d\n", (id.cfs_enable_2 & (1<<5)) ? 1 : 0);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering printf("ID_ATA_FEATURE_SET_APM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<3)) ? 1 : 0);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering printf("ID_ATA_FEATURE_SET_APM_CURRENT_VALUE=%d\n", id.CurAPMvalues & 0xff);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering * Word 76 indicates the capabilities of a SATA device. A PATA device shall set
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering * word 76 to 0000h or FFFFh. If word 76 is set to 0000h or FFFFh, then
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering * the device does not claim compliance with the Serial ATA specification and words
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering * 76 through 79 are not valid and shall be ignored.
a48a62a1af02aec4473c9deed98dd5b89d210f93Zbigniew Jędrzejewski-Szmek * If bit 2 of word 76 is set to one, then the device supports the Gen2
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering * signaling rate of 3.0 Gb/s (see SATA 2.6).
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering * If bit 1 of word 76 is set to one, then the device supports the Gen1
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering * signaling rate of 1.5 Gb/s (see SATA 2.6).
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering printf("ID_ATA_SATA_SIGNAL_RATE_GEN2=1\n");
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering printf("ID_ATA_SATA_SIGNAL_RATE_GEN1=1\n");
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski /* Word 217 indicates the nominal media rotation rate of the device */
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski printf ("ID_ATA_ROTATION_RATE_RPM=0\n"); /* non-rotating e.g. SSD */
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski } else if (word >= 0x0401 && word <= 0xfffe) {
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski printf ("ID_ATA_ROTATION_RATE_RPM=%d\n", word);
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski * Words 108-111 contain a mandatory World Wide Name (WWN) in the NAA IEEE Registered identifier
8b197c3a8a57c3f7c231b39e5660856fd9580c80Auke Kok * format. Word 108 bits (15:12) shall contain 5h, indicating that the naming authority is IEEE.
8b197c3a8a57c3f7c231b39e5660856fd9580c80Auke Kok * All other values are reserved.
dd5ae4c36c89da5dbe8d1628939b26c00db98753Przemyslaw Kedzierski wwwn |= *((uint16_t *) identify + 110);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering printf("ID_WWN=0x%llx\n", (unsigned long long int) wwwn);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering /* ATA devices have no vendor extension */
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering printf("ID_WWN_WITH_EXTENSION=0x%llx\n", (unsigned long long int) wwwn);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering /* from Linux's include/linux/ata.h */
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering if (identify_words[0] == 0x848a || identify_words[0] == 0x844a) {
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering if ((identify_words[83] & 0xc004) == 0x4004) {