chiark / gitweb /
Remove src/tty-ask-password-agent
[elogind.git] / src / udev / ata_id / ata_id.c
index 488fed4ac413bc7b2df279df45a11cc33265a229..9e4f674a9e3c3fd3d107b96135f2bdf89b1b7516 100644 (file)
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <linux/types.h>
 #include <linux/hdreg.h>
-#include <linux/fs.h>
-#include <linux/cdrom.h>
 #include <linux/bsg.h>
-#include <arpa/inet.h>
 
 #include "libudev.h"
 #include "libudev-private.h"
+#include "udev-util.h"
 #include "log.h"
 
 #define COMMAND_TIMEOUT_MSEC (30 * 1000)
@@ -51,65 +48,58 @@ static int disk_scsi_inquiry_command(int      fd,
                                      void    *buf,
                                      size_t   buf_len)
 {
-        struct sg_io_v4 io_v4;
-        uint8_t cdb[6];
-        uint8_t sense[32];
+        uint8_t cdb[6] = {
+                /*
+                 * INQUIRY, see SPC-4 section 6.4
+                 */
+                [0] = 0x12,                /* OPERATION CODE: INQUIRY */
+                [3] = (buf_len >> 8),      /* ALLOCATION LENGTH */
+                [4] = (buf_len & 0xff),
+        };
+        uint8_t sense[32] = {};
+        struct sg_io_v4 io_v4 = {
+                .guard = 'Q',
+                .protocol = BSG_PROTOCOL_SCSI,
+                .subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD,
+                .request_len = sizeof(cdb),
+                .request = (uintptr_t) cdb,
+                .max_response_len = sizeof(sense),
+                .response = (uintptr_t) sense,
+                .din_xfer_len = buf_len,
+                .din_xferp = (uintptr_t) buf,
+                .timeout = COMMAND_TIMEOUT_MSEC,
+        };
         int ret;
 
-        /*
-         * INQUIRY, see SPC-4 section 6.4
-         */
-        memset(cdb, 0, sizeof(cdb));
-        cdb[0] = 0x12;                         /* OPERATION CODE: INQUIRY */
-        cdb[3] = (buf_len >> 8);         /* ALLOCATION LENGTH */
-        cdb[4] = (buf_len & 0xff);
-
-        memset(sense, 0, sizeof(sense));
-
-        memset(&io_v4, 0, sizeof(struct sg_io_v4));
-        io_v4.guard = 'Q';
-        io_v4.protocol = BSG_PROTOCOL_SCSI;
-        io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
-        io_v4.request_len = sizeof (cdb);
-        io_v4.request = (uintptr_t) cdb;
-        io_v4.max_response_len = sizeof (sense);
-        io_v4.response = (uintptr_t) sense;
-        io_v4.din_xfer_len = buf_len;
-        io_v4.din_xferp = (uintptr_t) buf;
-        io_v4.timeout = COMMAND_TIMEOUT_MSEC;
-
         ret = ioctl(fd, SG_IO, &io_v4);
         if (ret != 0) {
                 /* could be that the driver doesn't do version 4, try version 3 */
                 if (errno == EINVAL) {
-                        struct sg_io_hdr io_hdr;
-
-                        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
-                        io_hdr.interface_id = 'S';
-                        io_hdr.cmdp = (unsigned char*) cdb;
-                        io_hdr.cmd_len = sizeof (cdb);
-                        io_hdr.dxferp = buf;
-                        io_hdr.dxfer_len = buf_len;
-                        io_hdr.sbp = sense;
-                        io_hdr.mx_sb_len = sizeof (sense);
-                        io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-                        io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
+                        struct sg_io_hdr io_hdr = {
+                                .interface_id = 'S',
+                                .cmdp = (unsigned char*) cdb,
+                                .cmd_len = sizeof (cdb),
+                                .dxferp = buf,
+                                .dxfer_len = buf_len,
+                                .sbp = sense,
+                                .mx_sb_len = sizeof(sense),
+                                .dxfer_direction = SG_DXFER_FROM_DEV,
+                                .timeout = COMMAND_TIMEOUT_MSEC,
+                        };
 
                         ret = ioctl(fd, SG_IO, &io_hdr);
                         if (ret != 0)
-                                goto out;
+                                return ret;
 
                         /* even if the ioctl succeeds, we need to check the return value */
                         if (!(io_hdr.status == 0 &&
                               io_hdr.host_status == 0 &&
                               io_hdr.driver_status == 0)) {
                                 errno = EIO;
-                                ret = -1;
-                                goto out;
+                                return -1;
                         }
-                } else {
-                        goto out;
-                }
+                } else
+                        return ret;
         }
 
         /* even if the ioctl succeeds, we need to check the return value */
@@ -117,172 +107,156 @@ static int disk_scsi_inquiry_command(int      fd,
               io_v4.transport_status == 0 &&
               io_v4.driver_status == 0)) {
                 errno = EIO;
-                ret = -1;
-                goto out;
+                return -1;
         }
 
- out:
-        return ret;
+        return 0;
 }
 
 static int disk_identify_command(int          fd,
                                  void         *buf,
                                  size_t          buf_len)
 {
-        struct sg_io_v4 io_v4;
-        uint8_t cdb[12];
-        uint8_t sense[32];
-        uint8_t *desc = sense+8;
+        uint8_t cdb[12] = {
+                /*
+                 * ATA Pass-Through 12 byte command, as described in
+                 *
+                 *  T10 04-262r8 ATA Command Pass-Through
+                 *
+                 * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
+                 */
+                [0] = 0xa1,     /* OPERATION CODE: 12 byte pass through */
+                [1] = 4 << 1,   /* PROTOCOL: PIO Data-in */
+                [2] = 0x2e,     /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
+                [3] = 0,        /* FEATURES */
+                [4] = 1,        /* SECTORS */
+                [5] = 0,        /* LBA LOW */
+                [6] = 0,        /* LBA MID */
+                [7] = 0,        /* LBA HIGH */
+                [8] = 0 & 0x4F, /* SELECT */
+                [9] = 0xEC,     /* Command: ATA IDENTIFY DEVICE */
+        };
+        uint8_t sense[32] = {};
+        uint8_t *desc = sense + 8;
+        struct sg_io_v4 io_v4 = {
+                .guard = 'Q',
+                .protocol = BSG_PROTOCOL_SCSI,
+                .subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD,
+                .request_len = sizeof(cdb),
+                .request = (uintptr_t) cdb,
+                .max_response_len = sizeof(sense),
+                .response = (uintptr_t) sense,
+                .din_xfer_len = buf_len,
+                .din_xferp = (uintptr_t) buf,
+                .timeout = COMMAND_TIMEOUT_MSEC,
+        };
         int ret;
 
-        /*
-         * ATA Pass-Through 12 byte command, as described in
-         *
-         *  T10 04-262r8 ATA Command Pass-Through
-         *
-         * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
-         */
-        memset(cdb, 0, sizeof(cdb));
-        cdb[0] = 0xa1;                        /* OPERATION CODE: 12 byte pass through */
-        cdb[1] = 4 << 1;                /* PROTOCOL: PIO Data-in */
-        cdb[2] = 0x2e;                        /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
-        cdb[3] = 0;                        /* FEATURES */
-        cdb[4] = 1;                        /* SECTORS */
-        cdb[5] = 0;                        /* LBA LOW */
-        cdb[6] = 0;                        /* LBA MID */
-        cdb[7] = 0;                        /* LBA HIGH */
-        cdb[8] = 0 & 0x4F;                /* SELECT */
-        cdb[9] = 0xEC;                        /* Command: ATA IDENTIFY DEVICE */;
-        memset(sense, 0, sizeof(sense));
-
-        memset(&io_v4, 0, sizeof(struct sg_io_v4));
-        io_v4.guard = 'Q';
-        io_v4.protocol = BSG_PROTOCOL_SCSI;
-        io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
-        io_v4.request_len = sizeof (cdb);
-        io_v4.request = (uintptr_t) cdb;
-        io_v4.max_response_len = sizeof (sense);
-        io_v4.response = (uintptr_t) sense;
-        io_v4.din_xfer_len = buf_len;
-        io_v4.din_xferp = (uintptr_t) buf;
-        io_v4.timeout = COMMAND_TIMEOUT_MSEC;
-
         ret = ioctl(fd, SG_IO, &io_v4);
         if (ret != 0) {
                 /* could be that the driver doesn't do version 4, try version 3 */
                 if (errno == EINVAL) {
-                        struct sg_io_hdr io_hdr;
-
-                        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
-                        io_hdr.interface_id = 'S';
-                        io_hdr.cmdp = (unsigned char*) cdb;
-                        io_hdr.cmd_len = sizeof (cdb);
-                        io_hdr.dxferp = buf;
-                        io_hdr.dxfer_len = buf_len;
-                        io_hdr.sbp = sense;
-                        io_hdr.mx_sb_len = sizeof (sense);
-                        io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-                        io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
+                        struct sg_io_hdr io_hdr = {
+                                .interface_id = 'S',
+                                .cmdp = (unsigned char*) cdb,
+                                .cmd_len = sizeof (cdb),
+                                .dxferp = buf,
+                                .dxfer_len = buf_len,
+                                .sbp = sense,
+                                .mx_sb_len = sizeof (sense),
+                                .dxfer_direction = SG_DXFER_FROM_DEV,
+                                .timeout = COMMAND_TIMEOUT_MSEC,
+                        };
 
                         ret = ioctl(fd, SG_IO, &io_hdr);
                         if (ret != 0)
-                                goto out;
-                } else {
-                        goto out;
-                }
+                                return ret;
+                } else
+                        return ret;
         }
 
         if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
                 errno = EIO;
-                ret = -1;
-                goto out;
+                return -1;
         }
 
- out:
-        return ret;
+        return 0;
 }
 
 static int disk_identify_packet_device_command(int          fd,
                                                void         *buf,
                                                size_t          buf_len)
 {
-        struct sg_io_v4 io_v4;
-        uint8_t cdb[16];
-        uint8_t sense[32];
-        uint8_t *desc = sense+8;
+        uint8_t cdb[16] = {
+                /*
+                 * ATA Pass-Through 16 byte command, as described in
+                 *
+                 *  T10 04-262r8 ATA Command Pass-Through
+                 *
+                 * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
+                 */
+                [0] = 0x85,   /* OPERATION CODE: 16 byte pass through */
+                [1] = 4 << 1, /* PROTOCOL: PIO Data-in */
+                [2] = 0x2e,   /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
+                [3] = 0,      /* FEATURES */
+                [4] = 0,      /* FEATURES */
+                [5] = 0,      /* SECTORS */
+                [6] = 1,      /* SECTORS */
+                [7] = 0,      /* LBA LOW */
+                [8] = 0,      /* LBA LOW */
+                [9] = 0,      /* LBA MID */
+                [10] = 0,     /* LBA MID */
+                [11] = 0,     /* LBA HIGH */
+                [12] = 0,     /* LBA HIGH */
+                [13] = 0,     /* DEVICE */
+                [14] = 0xA1,  /* Command: ATA IDENTIFY PACKET DEVICE */
+                [15] = 0,     /* CONTROL */
+        };
+        uint8_t sense[32] = {};
+        uint8_t *desc = sense + 8;
+        struct sg_io_v4 io_v4 = {
+                .guard = 'Q',
+                .protocol = BSG_PROTOCOL_SCSI,
+                .subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD,
+                .request_len = sizeof (cdb),
+                .request = (uintptr_t) cdb,
+                .max_response_len = sizeof (sense),
+                .response = (uintptr_t) sense,
+                .din_xfer_len = buf_len,
+                .din_xferp = (uintptr_t) buf,
+                .timeout = COMMAND_TIMEOUT_MSEC,
+        };
         int ret;
 
-        /*
-         * ATA Pass-Through 16 byte command, as described in
-         *
-         *  T10 04-262r8 ATA Command Pass-Through
-         *
-         * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
-         */
-        memset(cdb, 0, sizeof(cdb));
-        cdb[0] = 0x85;                        /* OPERATION CODE: 16 byte pass through */
-        cdb[1] = 4 << 1;                /* PROTOCOL: PIO Data-in */
-        cdb[2] = 0x2e;                        /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
-        cdb[3] = 0;                        /* FEATURES */
-        cdb[4] = 0;                        /* FEATURES */
-        cdb[5] = 0;                        /* SECTORS */
-        cdb[6] = 1;                        /* SECTORS */
-        cdb[7] = 0;                        /* LBA LOW */
-        cdb[8] = 0;                        /* LBA LOW */
-        cdb[9] = 0;                        /* LBA MID */
-        cdb[10] = 0;                        /* LBA MID */
-        cdb[11] = 0;                        /* LBA HIGH */
-        cdb[12] = 0;                        /* LBA HIGH */
-        cdb[13] = 0;                        /* DEVICE */
-        cdb[14] = 0xA1;                        /* Command: ATA IDENTIFY PACKET DEVICE */;
-        cdb[15] = 0;                        /* CONTROL */
-        memset(sense, 0, sizeof(sense));
-
-        memset(&io_v4, 0, sizeof(struct sg_io_v4));
-        io_v4.guard = 'Q';
-        io_v4.protocol = BSG_PROTOCOL_SCSI;
-        io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
-        io_v4.request_len = sizeof (cdb);
-        io_v4.request = (uintptr_t) cdb;
-        io_v4.max_response_len = sizeof (sense);
-        io_v4.response = (uintptr_t) sense;
-        io_v4.din_xfer_len = buf_len;
-        io_v4.din_xferp = (uintptr_t) buf;
-        io_v4.timeout = COMMAND_TIMEOUT_MSEC;
-
         ret = ioctl(fd, SG_IO, &io_v4);
         if (ret != 0) {
                 /* could be that the driver doesn't do version 4, try version 3 */
                 if (errno == EINVAL) {
-                        struct sg_io_hdr io_hdr;
-
-                        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
-                        io_hdr.interface_id = 'S';
-                        io_hdr.cmdp = (unsigned char*) cdb;
-                        io_hdr.cmd_len = sizeof (cdb);
-                        io_hdr.dxferp = buf;
-                        io_hdr.dxfer_len = buf_len;
-                        io_hdr.sbp = sense;
-                        io_hdr.mx_sb_len = sizeof (sense);
-                        io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-                        io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
+                        struct sg_io_hdr io_hdr = {
+                                .interface_id = 'S',
+                                .cmdp = (unsigned char*) cdb,
+                                .cmd_len = sizeof (cdb),
+                                .dxferp = buf,
+                                .dxfer_len = buf_len,
+                                .sbp = sense,
+                                .mx_sb_len = sizeof (sense),
+                                .dxfer_direction = SG_DXFER_FROM_DEV,
+                                .timeout = COMMAND_TIMEOUT_MSEC,
+                        };
 
                         ret = ioctl(fd, SG_IO, &io_hdr);
                         if (ret != 0)
-                                goto out;
-                } else {
-                        goto out;
-                }
+                                return ret;
+                } else
+                        return ret;
         }
 
         if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
                 errno = EIO;
-                ret = -1;
-                goto out;
+                return -1;
         }
 
- out:
-        return ret;
+        return 0;
 }
 
 /**
@@ -348,20 +322,19 @@ static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offs
  * non-zero with errno set.
  */
 static int disk_identify(struct udev *udev,
-                         int               fd,
-                         uint8_t      out_identify[512],
-                         int              *out_is_packet_device)
+                         int fd,
+                         uint8_t out_identify[512],
+                         int *out_is_packet_device)
 {
         int ret;
         uint8_t inquiry_buf[36];
         int peripheral_device_type;
         int all_nul_bytes;
         int n;
-        int is_packet_device;
+        int is_packet_device = 0;
 
         /* init results */
-        memset(out_identify, '\0', 512);
-        is_packet_device = 0;
+        memzero(out_identify, 512);
 
         /* If we were to use ATA PASS_THROUGH (12) on an ATAPI device
          * we could accidentally blank media. This is because MMC's BLANK
@@ -425,32 +398,27 @@ static int disk_identify(struct udev *udev,
 
 out:
         if (out_is_packet_device != NULL)
-          *out_is_packet_device = is_packet_device;
+                *out_is_packet_device = is_packet_device;
         return ret;
 }
 
-static void log_fn(struct udev *udev, int priority,
-                   const char *file, int line, const char *fn,
-                   const char *format, va_list args)
-{
-        vsyslog(priority, format, args);
-}
-
 int main(int argc, char *argv[])
 {
-        struct udev *udev;
+        _cleanup_udev_unref_ struct udev *udev = NULL;
         struct hd_driveid id;
-        uint8_t identify[512];
-        uint16_t *identify_words;
+        union {
+                uint8_t  byte[512];
+                uint16_t wyde[256];
+                uint64_t octa[64];
+        } identify;
         char model[41];
         char model_enc[256];
         char serial[21];
         char revision[9];
         const char *node = NULL;
         int export = 0;
-        int fd;
+        _cleanup_close_ int fd = -1;
         uint16_t word;
-        int rc = 0;
         int is_packet_device = 0;
         static const struct option options[] = {
                 { "export", no_argument, NULL, 'x' },
@@ -458,12 +426,12 @@ int main(int argc, char *argv[])
                 {}
         };
 
+        log_parse_environment();
+        log_open();
+
         udev = udev_new();
         if (udev == NULL)
-                goto exit;
-
-        log_open();
-        udev_set_log_fn(udev, log_fn);
+                return 0;
 
         while (1) {
                 int option;
@@ -478,59 +446,55 @@ int main(int argc, char *argv[])
                         break;
                 case 'h':
                         printf("Usage: ata_id [--export] [--help] <device>\n"
-                               "  --export    print values as environment keys\n"
-                               "  --help      print this help text\n\n");
-                        goto exit;
+                               "  -x,--export    print values as environment keys\n"
+                               "  -h,--help      print this help text\n\n");
+                        return 0;
                 }
         }
 
         node = argv[optind];
         if (node == NULL) {
-                log_error("no node specified\n");
-                rc = 1;
-                goto exit;
+                log_error("no node specified");
+                return 1;
         }
 
-        fd = open(node, O_RDONLY|O_NONBLOCK);
+        fd = open(node, O_RDONLY|O_NONBLOCK|O_CLOEXEC);
         if (fd < 0) {
-                log_error("unable to open '%s'\n", node);
-                rc = 1;
-                goto exit;
+                log_error("unable to open '%s'", node);
+                return 1;
         }
 
-        if (disk_identify(udev, fd, identify, &is_packet_device) == 0) {
+        if (disk_identify(udev, fd, identify.byte, &is_packet_device) == 0) {
                 /*
                  * fix up only the fields from the IDENTIFY data that we are going to
                  * use and copy it into the hd_driveid struct for convenience
                  */
-                disk_identify_fixup_string(identify,  10, 20); /* serial */
-                disk_identify_fixup_string(identify,  23,  8); /* fwrev */
-                disk_identify_fixup_string(identify,  27, 40); /* model */
-                disk_identify_fixup_uint16(identify,  0);      /* configuration */
-                disk_identify_fixup_uint16(identify,  75);     /* queue depth */
-                disk_identify_fixup_uint16(identify,  75);     /* SATA capabilities */
-                disk_identify_fixup_uint16(identify,  82);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  83);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  84);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  85);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  86);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  87);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  89);     /* time required for SECURITY ERASE UNIT */
-                disk_identify_fixup_uint16(identify,  90);     /* time required for enhanced SECURITY ERASE UNIT */
-                disk_identify_fixup_uint16(identify,  91);     /* current APM values */
-                disk_identify_fixup_uint16(identify,  94);     /* current AAM value */
-                disk_identify_fixup_uint16(identify, 128);     /* device lock function */
-                disk_identify_fixup_uint16(identify, 217);     /* nominal media rotation rate */
-                memcpy(&id, identify, sizeof id);
+                disk_identify_fixup_string(identify.byte,  10, 20); /* serial */
+                disk_identify_fixup_string(identify.byte,  23,  8); /* fwrev */
+                disk_identify_fixup_string(identify.byte,  27, 40); /* model */
+                disk_identify_fixup_uint16(identify.byte,  0);      /* configuration */
+                disk_identify_fixup_uint16(identify.byte,  75);     /* queue depth */
+                disk_identify_fixup_uint16(identify.byte,  75);     /* SATA capabilities */
+                disk_identify_fixup_uint16(identify.byte,  82);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  83);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  84);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  85);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  86);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  87);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  89);     /* time required for SECURITY ERASE UNIT */
+                disk_identify_fixup_uint16(identify.byte,  90);     /* time required for enhanced SECURITY ERASE UNIT */
+                disk_identify_fixup_uint16(identify.byte,  91);     /* current APM values */
+                disk_identify_fixup_uint16(identify.byte,  94);     /* current AAM value */
+                disk_identify_fixup_uint16(identify.byte, 128);     /* device lock function */
+                disk_identify_fixup_uint16(identify.byte, 217);     /* nominal media rotation rate */
+                memcpy(&id, identify.byte, sizeof id);
         } else {
                 /* If this fails, then try HDIO_GET_IDENTITY */
                 if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0) {
-                        log_info("HDIO_GET_IDENTITY failed for '%s': %m\n", node);
-                        rc = 2;
-                        goto close;
+                        log_debug_errno(errno, "HDIO_GET_IDENTITY failed for '%s': %m", node);
+                        return 2;
                 }
         }
-        identify_words = (uint16_t *) identify;
 
         memcpy (model, id.model, 40);
         model[40] = '\0';
@@ -580,8 +544,8 @@ int main(int argc, char *argv[])
                 }
 
                 if (id.command_set_1 & (1<<5)) {
-                        printf ("ID_ATA_WRITE_CACHE=1\n");
-                        printf ("ID_ATA_WRITE_CACHE_ENABLED=%d\n", (id.cfs_enable_1 & (1<<5)) ? 1 : 0);
+                        printf("ID_ATA_WRITE_CACHE=1\n");
+                        printf("ID_ATA_WRITE_CACHE_ENABLED=%d\n", (id.cfs_enable_1 & (1<<5)) ? 1 : 0);
                 }
                 if (id.command_set_1 & (1<<10)) {
                         printf("ID_ATA_FEATURE_SET_HPA=1\n");
@@ -644,7 +608,8 @@ int main(int argc, char *argv[])
                  * the device does not claim compliance with the Serial ATA specification and words
                  * 76 through 79 are not valid and shall be ignored.
                  */
-                word = *((uint16_t *) identify + 76);
+
+                word = identify.wyde[76];
                 if (word != 0x0000 && word != 0xffff) {
                         printf("ID_ATA_SATA=1\n");
                         /*
@@ -661,54 +626,34 @@ int main(int argc, char *argv[])
                 }
 
                 /* Word 217 indicates the nominal media rotation rate of the device */
-                word = *((uint16_t *) identify + 217);
-                if (word != 0x0000) {
-                        if (word == 0x0001) {
-                                printf ("ID_ATA_ROTATION_RATE_RPM=0\n"); /* non-rotating e.g. SSD */
-                        } else if (word >= 0x0401 && word <= 0xfffe) {
-                                printf ("ID_ATA_ROTATION_RATE_RPM=%d\n", word);
-                        }
-                }
+                word = identify.wyde[217];
+                if (word == 0x0001)
+                        printf ("ID_ATA_ROTATION_RATE_RPM=0\n"); /* non-rotating e.g. SSD */
+                else if (word >= 0x0401 && word <= 0xfffe)
+                        printf ("ID_ATA_ROTATION_RATE_RPM=%d\n", word);
 
                 /*
                  * Words 108-111 contain a mandatory World Wide Name (WWN) in the NAA IEEE Registered identifier
                  * format. Word 108 bits (15:12) shall contain 5h, indicating that the naming authority is IEEE.
                  * All other values are reserved.
                  */
-                word = *((uint16_t *) identify + 108);
-                if ((word & 0xf000) == 0x5000) {
-                        uint64_t wwwn;
-
-                        wwwn   = *((uint16_t *) identify + 108);
-                        wwwn <<= 16;
-                        wwwn  |= *((uint16_t *) identify + 109);
-                        wwwn <<= 16;
-                        wwwn  |= *((uint16_t *) identify + 110);
-                        wwwn <<= 16;
-                        wwwn  |= *((uint16_t *) identify + 111);
-                        printf("ID_WWN=0x%llx\n", (unsigned long long int) wwwn);
-                        /* ATA devices have no vendor extension */
-                        printf("ID_WWN_WITH_EXTENSION=0x%llx\n", (unsigned long long int) wwwn);
-                }
+                word = identify.wyde[108];
+                if ((word & 0xf000) == 0x5000)
+                        printf("ID_WWN=0x%1$"PRIu64"x\n"
+                               "ID_WWN_WITH_EXTENSION=0x%1$"PRIu64"x\n",
+                               identify.octa[108/4]);
 
                 /* from Linux's include/linux/ata.h */
-                if (identify_words[0] == 0x848a || identify_words[0] == 0x844a) {
+                if (identify.wyde[0] == 0x848a ||
+                    identify.wyde[0] == 0x844a ||
+                    (identify.wyde[83] & 0xc004) == 0x4004)
                         printf("ID_ATA_CFA=1\n");
-                } else {
-                        if ((identify_words[83] & 0xc004) == 0x4004) {
-                                printf("ID_ATA_CFA=1\n");
-                        }
-                }
         } else {
                 if (serial[0] != '\0')
                         printf("%s_%s\n", model, serial);
                 else
                         printf("%s\n", model);
         }
-close:
-        close(fd);
-exit:
-        udev_unref(udev);
-        log_close();
-        return rc;
+
+        return 0;
 }