chiark / gitweb /
[PATCH[ udev: ata_id: Fix length of INQUIRY command
[elogind.git] / extras / ata_id / ata_id.c
index 92387e50775632b38cd15732e62b416bb725a5c7..64df86c23ad429a53c951209ff4205aed7dc5ca7 100644 (file)
@@ -52,7 +52,7 @@ static int disk_scsi_inquiry_command(int      fd,
                                     size_t   buf_len)
 {
        struct sg_io_v4 io_v4;
-       uint8_t cdb[12];
+       uint8_t cdb[6];
        uint8_t sense[32];
        int ret;
 
@@ -448,6 +448,7 @@ int main(int argc, char *argv[])
        struct udev *udev;
        struct hd_driveid id;
        uint8_t identify[512];
+       uint16_t *identify_words;
        char model[41];
        char model_enc[256];
        char serial[21];
@@ -486,8 +487,6 @@ int main(int argc, char *argv[])
                        printf("Usage: ata_id [--export] [--help] <device>\n"
                               "  --export    print values as environment keys\n"
                               "  --help      print this help text\n\n");
-               default:
-                       rc = 1;
                        goto exit;
                }
        }
@@ -537,22 +536,23 @@ int main(int argc, char *argv[])
                                info(udev, "HDIO_GET_IDENTITY unsupported for '%s'\n", node);
                                rc = 2;
                        } else {
-                               err(udev, "HDIO_GET_IDENTITY failed for '%s'\n", node);
+                               err(udev, "HDIO_GET_IDENTITY failed for '%s': %m\n", node);
                                rc = 3;
                        }
                        goto close;
                }
        }
+       identify_words = (uint16_t *) identify;
 
        memcpy (model, id.model, 40);
        model[40] = '\0';
        udev_util_encode_string(model, model_enc, sizeof(model_enc));
-       udev_util_replace_whitespace((char *) id.model, model, 40);
-       udev_util_replace_chars(model, NULL);
-       udev_util_replace_whitespace((char *) id.serial_no, serial, 20);
-       udev_util_replace_chars(serial, NULL);
-       udev_util_replace_whitespace((char *) id.fw_rev, revision, 8);
-       udev_util_replace_chars(revision, NULL);
+       util_replace_whitespace((char *) id.model, model, 40);
+       util_replace_chars(model, NULL);
+       util_replace_whitespace((char *) id.serial_no, serial, 20);
+       util_replace_chars(serial, NULL);
+       util_replace_whitespace((char *) id.fw_rev, revision, 8);
+       util_replace_chars(revision, NULL);
 
        if (export) {
                /* Set this to convey the disk speaks the ATA protocol */
@@ -584,8 +584,12 @@ int main(int argc, char *argv[])
                printf("ID_MODEL=%s\n", model);
                printf("ID_MODEL_ENC=%s\n", model_enc);
                printf("ID_REVISION=%s\n", revision);
-               printf("ID_SERIAL=%s_%s\n", model, serial);
-               printf("ID_SERIAL_SHORT=%s\n", serial);
+               if (serial[0] != '\0') {
+                       printf("ID_SERIAL=%s_%s\n", model, serial);
+                       printf("ID_SERIAL_SHORT=%s\n", serial);
+               } else {
+                       printf("ID_SERIAL=%s\n", model);
+               }
 
                if (id.command_set_1 & (1<<5)) {
                        printf ("ID_ATA_WRITE_CACHE=1\n");
@@ -698,6 +702,15 @@ int main(int argc, char *argv[])
                        /* ATA devices have no vendor extension */
                        printf("ID_WWN_WITH_EXTENSION=0x%llx\n", (unsigned long long int) wwwn);
                }
+
+               /* from Linux's include/linux/ata.h */
+               if (identify_words[0] == 0x848a || identify_words[0] == 0x844a) {
+                       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);