"Fossies" - the Fresh Open Source Software Archive

Member "hdparm-9.60/identify.c" (21 Nov 2020, 56191 Bytes) of package /linux/misc/hdparm-9.60.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "identify.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 9.58_vs_9.60.

    1 /* identify.c - by Mark Lord (C) 2000-2007 -- freely distributable */
    2 
    3 #include <stdio.h>
    4 #include <stdlib.h>
    5 #include <errno.h>
    6 #include <string.h>
    7 #include <linux/types.h>
    8 #include <endian.h>
    9 
   10 #if __BYTE_ORDER == __BIG_ENDIAN
   11 #define __USE_XOPEN
   12 #endif
   13 
   14 #include "hdparm.h"
   15 
   16 /* device types */
   17 /* ------------ */
   18 #define NO_DEV                  0xffff
   19 #define ATA_DEV                 0x0000
   20 #define ATAPI_DEV               0x0001
   21 
   22 /* word definitions */
   23 /* ---------------- */
   24 #define GEN_CONFIG      0   /* general configuration */
   25 #define LCYLS           1   /* number of logical cylinders */
   26 #define CONFIG          2   /* specific configuration */
   27 #define LHEADS          3   /* number of logical heads */
   28 #define TRACK_BYTES     4   /* number of bytes/track (ATA-1) */
   29 #define SECT_BYTES      5   /* number of bytes/sector (ATA-1) */
   30 #define LSECTS          6   /* number of logical sectors/track */
   31 #define START_SERIAL            10  /* ASCII serial number */
   32 #define LENGTH_SERIAL           10  /* 10 words (20 bytes or characters) */
   33 #define BUF_TYPE        20  /* buffer type (ATA-1) */
   34 #define BUF_SIZE        21  /* buffer size (ATA-1) */
   35 #define RW_LONG         22  /* extra bytes in R/W LONG cmd ( < ATA-4)*/
   36 #define START_FW_REV            23  /* ASCII firmware revision */
   37 #define LENGTH_FW_REV        4  /*  4 words (8 bytes or characters) */
   38 #define START_MODEL         27  /* ASCII model number */
   39 #define LENGTH_MODEL        20  /* 20 words (40 bytes or characters) */
   40 #define SECTOR_XFER_MAX     47  /* r/w multiple: max sectors xfered */
   41 #define DWORD_IO        48  /* can do double-word IO (ATA-1 only) */
   42 #define CAPAB_0         49  /* capabilities */
   43 #define CAPAB_1         50
   44 #define PIO_MODE        51  /* max PIO mode supported (obsolete)*/
   45 #define DMA_MODE        52  /* max Singleword DMA mode supported (obs)*/
   46 #define WHATS_VALID     53  /* what fields are valid */
   47 #define LCYLS_CUR       54  /* current logical cylinders */
   48 #define LHEADS_CUR      55  /* current logical heads */
   49 #define LSECTS_CUR      56  /* current logical sectors/track */
   50 #define CAPACITY_LSB        57  /* current capacity in sectors */
   51 #define CAPACITY_MSB        58
   52 #define SECTOR_XFER_CUR     59  /* r/w multiple: current sectors xfered */
   53 #define LBA_SECTS_LSB       60  /* LBA: total number of user */
   54 #define LBA_SECTS_MSB       61  /*      addressable sectors */
   55 #define SINGLE_DMA      62  /* singleword DMA modes */
   56 #define MULTI_DMA       63  /* multiword DMA modes */
   57 #define ADV_PIO_MODES       64  /* advanced PIO modes supported */
   58                     /* multiword DMA xfer cycle time: */
   59 #define DMA_TIME_MIN        65  /*   - minimum */
   60 #define DMA_TIME_NORM       66  /*   - manufacturer's recommended   */
   61                     /* minimum PIO xfer cycle time: */
   62 #define PIO_NO_FLOW     67  /*   - without flow control */
   63 #define PIO_FLOW        68  /*   - with IORDY flow control */
   64 #define PKT_REL         71  /* typical #ns from PKT cmd to bus rel */
   65 #define SVC_NBSY        72  /* typical #ns from SERVICE cmd to !BSY */
   66 #define CDR_MAJOR       73  /* CD ROM: major version number */
   67 #define CDR_MINOR       74  /* CD ROM: minor version number */
   68 #define QUEUE_DEPTH     75  /* queue depth */
   69 #define SATA_CAP_0      76  /* Serial ATA Capabilities */
   70 #define SATA_RESERVED_77    77  /* reserved for future Serial ATA definition */
   71 #define SATA_SUPP_0     78  /* Serial ATA features supported */
   72 #define SATA_EN_0       79  /* Serial ATA features enabled */
   73 #define MAJOR           80  /* major version number */
   74 #define MINOR           81  /* minor version number */
   75 #define CMDS_SUPP_0     82  /* command/feature set(s) supported */
   76 #define CMDS_SUPP_1     83
   77 #define CMDS_SUPP_2     84
   78 #define CMDS_EN_0       85  /* command/feature set(s) enabled */
   79 #define CMDS_EN_1       86
   80 #define CMDS_EN_2       87
   81 #define ULTRA_DMA       88  /* ultra DMA modes */
   82                     /* time to complete security erase */
   83 #define ERASE_TIME      89  /*   - ordinary */
   84 #define ENH_ERASE_TIME      90  /*   - enhanced */
   85 #define ADV_PWR         91  /* current advanced power management level
   86                        in low byte, 0x40 in high byte. */  
   87 #define PSWD_CODE       92  /* master password revision code    */
   88 #define HWRST_RSLT      93  /* hardware reset result */
   89 #define ACOUSTIC        94  /* acoustic mgmt values ( >= ATA-6) */
   90 #define LBA_LSB         100 /* LBA: maximum.  Currently only 48 */
   91 #define LBA_MID         101 /*      bits are used, but addr 103 */
   92 #define LBA_48_MSB      102 /*      has been reserved for LBA in */
   93 #define LBA_64_MSB      103 /*      the future. */
   94 #define CMDS_SUPP_3     119
   95 #define CMDS_EN_3       120
   96 #define RM_STAT         127 /* removable media status notification feature set support */
   97 #define SECU_STATUS     128 /* security status */
   98 #define CFA_PWR_MODE        160 /* CFA power mode 1 */
   99 #define START_MEDIA             176 /* media serial number */
  100 #define LENGTH_MEDIA            20  /* 20 words (40 bytes or characters)*/
  101 #define START_MANUF             196 /* media manufacturer I.D. */
  102 #define LENGTH_MANUF            10  /* 10 words (20 bytes or characters) */
  103 #define SCT_SUPP        206 /* SMART command transport (SCT) support */
  104 #define TRANSPORT_MAJOR     222 /* PATA vs. SATA etc.. */
  105 #define TRANSPORT_MINOR     223 /* minor revision number */
  106 #define NMRR            217 /* nominal media rotation rate */
  107 #define INTEGRITY       255 /* integrity word */
  108 
  109 /* bit definitions within the words */
  110 /* -------------------------------- */
  111 
  112 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
  113 #define VALID           0xc000
  114 #define VALID_VAL       0x4000
  115 /* many words are considered invalid if they are either all-0 or all-1 */
  116 
  117 /* word 0: gen_config */
  118 #define NOT_ATA         0x8000  
  119 #define NOT_ATAPI       0x4000  /* (check only if bit 15 == 1) */
  120 #define MEDIA_REMOVABLE     0x0080
  121 #define DRIVE_NOT_REMOVABLE 0x0040  /* bit obsoleted in ATA 6 */
  122 #define INCOMPLETE      0x0004
  123 #define DRQ_RESPONSE_TIME   0x0060
  124 #define DRQ_3MS_VAL     0x0000
  125 #define DRQ_INTR_VAL        0x0020
  126 #define DRQ_50US_VAL        0x0040
  127 #define PKT_SIZE_SUPPORTED  0x0003
  128 #define PKT_SIZE_12_VAL     0x0000
  129 #define PKT_SIZE_16_VAL     0x0001
  130 #define EQPT_TYPE       0x1f00
  131 #define SHIFT_EQPT      8
  132 
  133 #define CDROM 0x0005
  134 const char *pkt_str[] = {
  135     "Direct-access device",         /* word 0, bits 12-8 = 00 */
  136     "Sequential-access device",     /* word 0, bits 12-8 = 01 */
  137     "Printer",              /* word 0, bits 12-8 = 02 */
  138     "Processor",                /* word 0, bits 12-8 = 03 */
  139     "Write-once device",            /* word 0, bits 12-8 = 04 */
  140     "CD-ROM",               /* word 0, bits 12-8 = 05 */
  141     "Scanner",              /* word 0, bits 12-8 = 06 */
  142     "Optical memory",           /* word 0, bits 12-8 = 07 */
  143     "Medium changer",           /* word 0, bits 12-8 = 08 */
  144     "Communications device",        /* word 0, bits 12-8 = 09 */
  145     "ACS-IT8 device",           /* word 0, bits 12-8 = 0a */
  146     "ACS-IT8 device",           /* word 0, bits 12-8 = 0b */
  147     "Array controller",         /* word 0, bits 12-8 = 0c */
  148     "Enclosure services",           /* word 0, bits 12-8 = 0d */
  149     "Reduced block command device",     /* word 0, bits 12-8 = 0e */
  150     "Optical card reader/writer",       /* word 0, bits 12-8 = 0f */
  151     "",                 /* word 0, bits 12-8 = 10 */
  152     "",                 /* word 0, bits 12-8 = 11 */
  153     "",                 /* word 0, bits 12-8 = 12 */
  154     "",                 /* word 0, bits 12-8 = 13 */
  155     "",                 /* word 0, bits 12-8 = 14 */
  156     "",                 /* word 0, bits 12-8 = 15 */
  157     "",                 /* word 0, bits 12-8 = 16 */
  158     "",                 /* word 0, bits 12-8 = 17 */
  159     "",                 /* word 0, bits 12-8 = 18 */
  160     "",                 /* word 0, bits 12-8 = 19 */
  161     "",                 /* word 0, bits 12-8 = 1a */
  162     "",                 /* word 0, bits 12-8 = 1b */
  163     "",                 /* word 0, bits 12-8 = 1c */
  164     "",                 /* word 0, bits 12-8 = 1d */
  165     "",                 /* word 0, bits 12-8 = 1e */
  166     "Unknown",              /* word 0, bits 12-8 = 1f */
  167 };
  168 const char *ata1_cfg_str[] = {          /* word 0 in ATA-1 mode */
  169     "reserved",             /* bit 0 */
  170     "hard sectored",            /* bit 1 */
  171     "soft sectored",            /* bit 2 */
  172     "not MFM encoded ",         /* bit 3 */
  173     "head switch time > 15us",      /* bit 4 */
  174     "spindle motor control option",     /* bit 5 */
  175     "fixed drive",              /* bit 6 */
  176     "removable drive",          /* bit 7 */
  177     "disk xfer rate <= 5Mbs",       /* bit 8 */
  178     "disk xfer rate > 5Mbs, <= 10Mbs",  /* bit 9 */
  179     "disk xfer rate > 5Mbs",        /* bit 10 */
  180     "rotational speed tol.",        /* bit 11 */
  181     "data strobe offset option",        /* bit 12 */
  182     "track offset option",          /* bit 13 */
  183     "format speed tolerance gap reqd",  /* bit 14 */
  184     "ATAPI"                 /* bit 14 */
  185 };
  186 
  187 /* word 1: number of logical cylinders */
  188 #define LCYLS_MAX       0x3fff /* maximum allowable value */
  189 
  190 /* word 2: specific configureation 
  191  * (a) require SET FEATURES to spin-up
  192  * (b) require spin-up to fully reply to IDENTIFY DEVICE
  193  */
  194 #define STBY_NID_VAL        0x37c8  /*     (a) and     (b) */
  195 #define STBY_ID_VAL     0x738c  /*     (a) and not (b) */
  196 #define PWRD_NID_VAL        0x8c73  /* not (a) and     (b) */
  197 #define PWRD_ID_VAL     0xc837  /* not (a) and not (b) */
  198 
  199 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
  200 #define SECTOR_XFER     0x00ff  /* sectors xfered on r/w multiple cmds*/
  201 #define MULTIPLE_SETTING_VALID  0x0100  /* 1=multiple sector setting is valid */
  202 #define SANITIZE_FEAT_SUP       0x1000 /* SANITIZE FETURES set is supported */
  203 
  204 /* word 49: capabilities 0 */
  205 #define STD_STBY        0x2000  /* 1=standard values supported (ATA);
  206                        0=vendor specific values */
  207 #define IORDY_SUP       0x0800  /* 1=support; 0=may be supported */
  208 #define IORDY_OFF       0x0400  /* 1=may be disabled */
  209 #define LBA_SUP         0x0200  /* 1=Logical Block Address support */
  210 #define DMA_SUP         0x0100  /* 1=Direct Memory Access support */
  211 #define DMA_IL_SUP      0x8000  /* 1=interleaved DMA support (ATAPI) */
  212 #define CMD_Q_SUP       0x4000  /* 1=command queuing support (ATAPI) */
  213 #define OVLP_SUP        0x2000  /* 1=overlap operation support (ATAPI) */
  214 #define SWRST_REQ       0x1000  /* 1=ATA SW reset required (ATAPI, obsolete */
  215 
  216 /* word 50: capabilities 1 */
  217 #define MIN_STANDBY_TIMER   0x0001  /* 1=device specific standby timer value minimum */
  218 
  219 /* words 51 & 52: PIO & DMA cycle times */
  220 #define MODE            0xff00  /* the mode is in the MSBs */
  221 
  222 /* word 53: whats_valid */
  223 #define OK_W88          0x0004  /* the ultra_dma info is valid */
  224 #define OK_W64_70       0x0002  /* see above for word descriptions */
  225 #define OK_W54_58       0x0001  /* current cyl, head, sector, cap. info valid */
  226 
  227 /* word 59: sanitize feature set */
  228 static const char *feat_word59_str[16] = {
  229     "BLOCK_ERASE_EXT command",                      /* word 84 bit 15 */
  230     "OVERWRITE_EXT command",                        /* word 84 bit 14 */
  231     "CRYPTO_SCRAMBLE_EXT command",                  /* word 59 bit 13 */
  232     "SANITIZE feature set",                         /* word 59 bit 12 */
  233     NULL,                                           /* word 59 bit 11 */
  234     "SANITIZE_ANTIFREEZE_LOCK_EXT command",         /* word 59 bit 10 */
  235     NULL,               /* word 59 bit  9 */
  236     NULL,               /* word 59 bit  8 */
  237     NULL,               /* word 59 bit  7 */
  238     NULL,               /* word 59 bit  6 */
  239     NULL,               /* word 59 bit  5 */
  240     NULL,               /* word 59 bit  4 */
  241     NULL,               /* word 59 bit  3 */
  242     NULL,               /* word 59 bit  2 */
  243     NULL,               /* word 59 bit  1 */
  244     NULL                /* word 59 bit  0 */
  245 };
  246 
  247 /*word 63,88: dma_mode, ultra_dma_mode*/
  248 #define MODE_MAX        7   /* bit definitions force udma <=7 (when
  249                      * udma >=8 comes out it'll have to be
  250                      * defined in a new dma_mode word!) */
  251 
  252 /* word 64: PIO transfer modes */
  253 #define PIO_SUP         0x00ff  /* only bits 0 & 1 are used so far,  */
  254 #define PIO_MODE_MAX        8       /* but all 8 bits are defined        */
  255 
  256 /* word 75: queue_depth */
  257 #define DEPTH_BITS      0x001f  /* bits used for queue depth */
  258 
  259 /* words 80-81: version numbers */
  260 /* 0x0000 or  0xffff means device does not report version */
  261 
  262 /* word 81: minor version number */
  263 #define MINOR_MAX       0x22
  264 const char *minor_str[MINOR_MAX+2] = {          /* word 81 value: */
  265     "Unspecified",                  /* 0x0000   */
  266     "ATA-1 X3T9.2 781D prior to revision 4",    /* 0x0001   */
  267     "ATA-1 published, ANSI X3.221-1994",        /* 0x0002   */
  268     "ATA-1 X3T9.2 781D revision 4",         /* 0x0003   */
  269     "ATA-2 published, ANSI X3.279-1996",        /* 0x0004   */
  270     "ATA-2 X3T10 948D prior to revision 2k",    /* 0x0005   */
  271     "ATA-3 X3T10 2008D revision 1",         /* 0x0006   */
  272     "ATA-2 X3T10 948D revision 2k",         /* 0x0007   */
  273     "ATA-3 X3T10 2008D revision 0",         /* 0x0008   */
  274     "ATA-2 X3T10 948D revision 3",          /* 0x0009   */
  275     "ATA-3 published, ANSI X3.298-199x",        /* 0x000a   */
  276     "ATA-3 X3T10 2008D revision 6",         /* 0x000b   */
  277     "ATA-3 X3T13 2008D revision 7 and 7a",      /* 0x000c   */
  278     "ATA/ATAPI-4 X3T13 1153D revision 6",       /* 0x000d   */
  279     "ATA/ATAPI-4 T13 1153D revision 13",        /* 0x000e   */
  280     "ATA/ATAPI-4 X3T13 1153D revision 7",       /* 0x000f   */
  281     "ATA/ATAPI-4 T13 1153D revision 18",        /* 0x0010   */
  282     "ATA/ATAPI-4 T13 1153D revision 15",        /* 0x0011   */
  283     "ATA/ATAPI-4 published, ANSI INCITS 317-1998",  /* 0x0012   */
  284     "ATA/ATAPI-5 T13 1321D revision 3",
  285     "ATA/ATAPI-4 T13 1153D revision 14",        /* 0x0014   */
  286     "ATA/ATAPI-5 T13 1321D revision 1",     /* 0x0015   */
  287     "ATA/ATAPI-5 published, ANSI INCITS 340-2000",  /* 0x0016   */
  288     "ATA/ATAPI-4 T13 1153D revision 17",        /* 0x0017   */
  289     "ATA/ATAPI-6 T13 1410D revision 0",     /* 0x0018   */
  290     "ATA/ATAPI-6 T13 1410D revision 3a",        /* 0x0019   */
  291     "ATA/ATAPI-7 T13 1532D revision 1",     /* 0x001a   */
  292     "ATA/ATAPI-6 T13 1410D revision 2",     /* 0x001b   */
  293     "ATA/ATAPI-6 T13 1410D revision 1",     /* 0x001c   */
  294     "ATA/ATAPI-7 published, ANSI INCITS 397-2005",  /* 0x001d   */
  295     "ATA/ATAPI-7 T13 1532D revision 0",     /* 0x001e   */
  296     "Reserved",                 /* 0x001f   */
  297     "Reserved",                 /* 0x0020   */
  298     "ATA/ATAPI-7 T13 1532D revision 4a",        /* 0x0021   */
  299     "ATA/ATAPI-6 published, ANSI INCITS 361-2002",  /* 0x0022   */
  300     "Reserved",                 /* 0x0023-0xfffe*/
  301 };
  302 const char actual_ver[MINOR_MAX+2] = { 
  303             /* word 81 value: */
  304     0,      /* 0x0000   WARNING:    */
  305     1,      /* 0x0001   WARNING:    */
  306     1,      /* 0x0002   WARNING:    */
  307     1,      /* 0x0003   WARNING:    */
  308     2,      /* 0x0004   WARNING:   This array       */
  309     2,      /* 0x0005   WARNING:   corresponds      */
  310     3,      /* 0x0006   WARNING:   *exactly*        */
  311     2,      /* 0x0007   WARNING:   to the ATA/      */
  312     3,      /* 0x0008   WARNING:   ATAPI version    */
  313     2,      /* 0x0009   WARNING:   listed in        */
  314     3,      /* 0x000a   WARNING:   the          */
  315     3,      /* 0x000b   WARNING:   minor_str        */
  316     3,      /* 0x000c   WARNING:   array        */
  317     4,      /* 0x000d   WARNING:   above.       */
  318     4,      /* 0x000e   WARNING:            */
  319     4,      /* 0x000f   WARNING:   if you change    */
  320     4,      /* 0x0010   WARNING:   that one,        */
  321     4,      /* 0x0011   WARNING:   change this one  */
  322     4,      /* 0x0012   WARNING:   too!!!           */
  323     5,      /* 0x0013   WARNING:    */
  324     4,      /* 0x0014   WARNING:    */
  325     5,      /* 0x0015   WARNING:    */
  326     5,      /* 0x0016   WARNING:    */
  327     4,      /* 0x0017   WARNING:    */
  328     6,      /* 0x0018   WARNING:    */
  329     6,      /* 0x0019   WARNING:    */
  330     7,      /* 0x001a   WARNING:    */
  331     6,      /* 0x001b   WARNING:    */
  332     6,      /* 0x001c   WARNING:    */
  333     7,      /* 0x001d   WARNING:    */
  334     7,      /* 0x001e   WARNING:    */
  335     0,      /* 0x001f   WARNING:    */
  336     0,      /* 0x0020   WARNING:    */
  337     7,      /* 0x0021   WARNING:    */
  338     6,      /* 0x0022   WARNING:    */
  339     0       /* 0x0023-0xfffe            */
  340 };
  341 
  342 /* words 82-84: cmds/feats supported */
  343 #define CMDS_W82        0x77ff  /* word 82: defined command locations*/
  344 #define CMDS_W83        0x3fff  /* word 83: defined command locations*/
  345 #define CMDS_W84        0x27ff  /* word 84: defined command locations*/
  346 #define SUPPORT_48_BIT      0x0400  
  347 #define NUM_CMD_FEAT_STR    48
  348 
  349 static const char *feat_word69_str[16] = { 
  350     "CFast specification support",          /* word 69 bit 15 */
  351     "Deterministic read data after TRIM",       /* word 69 bit 14 */
  352     "Long physical sector diagnostics",     /* word 69 bit 13 */
  353     "DEVICE CONFIGURATION SET/IDENTIFY DMA commands", /* word 69 bit 12 */
  354     "READ BUFFER DMA command",          /* word 69 bit 11 */
  355     "WRITE BUFFER DMA command",         /* word 69 bit 10 */
  356     "SET MAX SETPASSWORD/UNLOCK DMA commands",  /* word 69 bit  9 */
  357     "DOWNLOAD MICROCODE DMA command",       /* word 69 bit  8 */
  358     "IEEE 1667 authentication of transient storage devices",    /* word 69 bit  7 */
  359     "Optional ATA device 28-bit commands",          /* word 69 bit  6 */
  360     "Deterministic read ZEROs after TRIM",          /* word 69 bit  5 */
  361     "Device encrypts all user data",                /* word 69 bit  4 */
  362     "Extended number of user addressable sectors ", /* word 69 bit  3 */
  363     "All write cache is non-volatile",              /* word 69 bit  2 */
  364     "reserved 69[1]",               /* word 69 bit  1 */
  365     "reserved 69[0]",               /* word 69 bit  0 */
  366 };
  367 
  368 static const char *feat_word82_str[16] = { 
  369     "obsolete 82[15]",              /* word 82 bit 15: obsolete  */
  370     "NOP cmd",                  /* word 82 bit 14 */
  371     "READ_BUFFER command",              /* word 82 bit 13 */
  372     "WRITE_BUFFER command",             /* word 82 bit 12 */
  373     "WRITE_VERIFY command",             /* word 82 bit 11: obsolete  */
  374     "Host Protected Area feature set",      /* word 82 bit 10 */
  375     "DEVICE_RESET command",             /* word 82 bit  9 */
  376     "SERVICE interrupt",                /* word 82 bit  8 */
  377     "Release interrupt",                /* word 82 bit  7 */
  378     "Look-ahead",                   /* word 82 bit  6 */
  379     "Write cache",                  /* word 82 bit  5 */
  380     "PACKET command feature set",           /* word 82 bit  4 */
  381     "Power Management feature set",         /* word 82 bit  3 */
  382     "Removable Media feature set",          /* word 82 bit  2 */
  383     "Security Mode feature set",            /* word 82 bit  1 */
  384     "SMART feature set"             /* word 82 bit  0 */
  385 };
  386 static const char *feat_word83_str[16] = { 
  387     NULL,                       /* word 83 bit 15: !valid bit */
  388     NULL,                       /* word 83 bit 14:  valid bit */
  389     "FLUSH_CACHE_EXT",              /* word 83 bit 13 */
  390     "Mandatory FLUSH_CACHE",            /* word 83 bit 12 */
  391     "Device Configuration Overlay feature set", /* word 83 bit 11 */
  392     "48-bit Address feature set",           /* word 83 bit 10 */
  393     "Automatic Acoustic Management feature set",    /* word 83 bit  9 */
  394     "SET_MAX security extension",           /* word 83 bit  8 */
  395     "Address Offset Reserved Area Boot",        /* word 83 bit  7 */
  396     "SET_FEATURES required to spinup after power up",/* word 83 bit 6 */
  397     "Power-Up In Standby feature set",      /* word 83 bit  5 */
  398     "Removable Media Status Notification feature set",/* word 83 bit 4 */
  399     "Advanced Power Management feature set",    /* word 83 bit  3 */
  400     "CFA feature set",              /* word 83 bit  2 */
  401     "READ/WRITE_DMA_QUEUED",            /* word 83 bit  1 */
  402     "DOWNLOAD_MICROCODE"                /* word 83 bit  0 */
  403 };
  404 static const char *feat_word84_str[16] = { 
  405     NULL,                       /* word 84 bit 15: !valid bit */
  406     NULL,                       /* word 84 bit 14:  valid bit */
  407     "IDLE_IMMEDIATE with UNLOAD",           /* word 84 bit 13 */
  408     "Command Completion Time Limit (CCTL)",     /* word 84 bit 12 (ref: dt1696) */
  409     "Time Limited Commands (TLC) feature set",  /* word 84 bit 11 (ref: dt1696) */
  410     "URG for WRITE_STREAM[_DMA]_EXT",       /* word 84 bit 10 */
  411     "URG for READ_STREAM[_DMA]_EXT",        /* word 84 bit  9 */
  412     "64-bit World wide name",           /* word 84 bit  8 */
  413     "WRITE_DMA_QUEUED_FUA_EXT",         /* word 84 bit  7 */
  414     "WRITE_{DMA|MULTIPLE}_FUA_EXT",         /* word 84 bit  6 */
  415     "General Purpose Logging feature set",      /* word 84 bit  5 */
  416     "Media Card Pass-Through",          /* word 84 bit  4 */
  417     "Media Card Pass Through Command feature set",  /* word 84 bit  3 */
  418     "Media serial number",              /* word 84 bit  2 */
  419     "SMART self-test",              /* word 84 bit  1 */
  420     "SMART error logging"               /* word 84 bit  0 */
  421 };
  422 static const char *feat_3_str[16] = { 
  423     NULL,                       /* word 119 bit 15: !valid bit */
  424     NULL,                       /* word 119 bit 14:  valid bit */
  425     "unknown 119[13]",              /* word 119 bit 13 */
  426     "unknown 119[12]",              /* word 119 bit 12 */
  427     "unknown 119[11]",              /* word 119 bit 11 */
  428     "unknown 119[10]",              /* word 119 bit 10 */
  429     "unknown 119[9]",               /* word 119 bit  9 */
  430     "unknown 119[8]",               /* word 119 bit  8 */
  431     "unknown 119[7]",               /* word 119 bit  7 */
  432     "unknown 119[6]",               /* word 119 bit  6 */
  433     "Free-fall Control feature set",        /* word 119 bit  5 */
  434     "Segmented DOWNLOAD_MICROCODE",         /* word 119 bit  4 */
  435     "{READ,WRITE}_DMA_EXT_GPL commands",        /* word 119 bit  3 */
  436     "WRITE_UNCORRECTABLE_EXT command",      /* word 119 bit  2 */
  437     "Write-Read-Verify feature set",        /* word 119 bit  1 */
  438     "Disable Data Transfer After Error Detection"   /* word 119 bit  0 (ref: 2014DT)*/
  439 };
  440 static const char *cap_sata0_str[16] = { 
  441     "READ_LOG_DMA_EXT equivalent to READ_LOG_EXT",  /* word 76 bit 15 */
  442     "Device automatic Partial to Slumber transitions",/* word 76 bit 14 */
  443     "Host automatic Partial to Slumber transitions",/* word 76 bit 13 */
  444     "NCQ priority information",         /* word 76 bit 12 */
  445     "Idle-Unload when NCQ is active",       /* word 76 bit 11 */
  446     "Phy event counters",               /* word 76 bit 10 */
  447     "Host-initiated interface power management",    /* word 76 bit  9 */
  448     "Native Command Queueing (NCQ)",        /* word 76 bit  8 */
  449     "unknown 76[7]",                /* word 76 bit  7 */
  450     "unknown 76[6]",                /* word 76 bit  6 */
  451     "unknown 76[5]",                /* word 76 bit  5 */
  452     "unknown 76[4]",                /* word 76 bit  4 */
  453     "Gen3 signaling speed (6.0Gb/s)",       /* word 76 bit  3 */
  454     "Gen2 signaling speed (3.0Gb/s)",       /* word 76 bit  2 */
  455     "Gen1 signaling speed (1.5Gb/s)",       /* word 76 bit  1 */
  456     "unknown 76[0]"                 /* word 76 bit  0 */
  457 };
  458 static const char *feat_sata0_str[16] = {
  459     "unknown 78[15]",               /* word 78 bit 15 */
  460     "unknown 78[14]",               /* word 78 bit 14 */
  461     "unknown 78[13]",               /* word 78 bit 13 */
  462     "unknown 78[12]",               /* word 78 bit 12 */
  463     "unknown 78[11]",               /* word 78 bit 11 */
  464     "unknown 78[10]",               /* word 78 bit 10 */
  465     "unknown 78[9]",                /* word 78 bit  9 */
  466     "Device Sleep (DEVSLP)",            /* word 78 bit  8 */
  467     "unknown 78[7]",                /* word 78 bit  7 */
  468     "Software settings preservation",       /* word 78 bit  6 */
  469     "Asynchronous notification (eg. media change)", /* word 78 bit  5 */
  470     "In-order data delivery",           /* word 78 bit  4 */
  471     "Device-initiated interface power management",  /* word 78 bit  3 */
  472     "DMA Setup Auto-Activate optimization",     /* word 78 bit  2 */
  473     "Non-Zero buffer offsets in DMA Setup FIS", /* word 78 bit  1 */
  474     "unknown 78[0]"                 /* word 78 bit  0 */
  475 };
  476 
  477 /* words 85-87: cmds/feats enabled */
  478 /* use cmd_feat_str[] to display what commands and features have
  479  * been enabled with words 85-87 
  480  */
  481 #define WWN_SUP         0x100 /* 1=support; 0=not supported */
  482 
  483 /* words 89, 90, SECU ERASE TIME */
  484 #define ERASE_BITS      0x00ff
  485 
  486 /* word 92: master password revision */
  487 /* 0x0000 or  0xffff means no support for master password revision */
  488 
  489 /* word 93: hw reset result */
  490 #define CBLID           0x2000  /* CBLID status */
  491 #define RST0            0x0001  /* 1=reset to device #0 */
  492 #define DEV_DET         0x0006  /* how device num determined */
  493 #define JUMPER_VAL      0x0002  /* device num determined by jumper */
  494 #define CSEL_VAL        0x0004  /* device num determined by CSEL_VAL */
  495 
  496 /* word 127: removable media status notification feature set support */
  497 #define RM_STAT_BITS        0x0003
  498 #define RM_STAT_SUP     0x0001
  499     
  500 /* word 128: security */
  501 #define SECU_ENABLED        0x0002
  502 #define SECU_LEVEL      0x0100  /* was 0x0010 */
  503 #define NUM_SECU_STR        6
  504 const char *secu_str[] = {
  505     "supported",            /* word 128, bit 0 */
  506     "enabled",          /* word 128, bit 1 */
  507     "locked",           /* word 128, bit 2 */
  508     "frozen",           /* word 128, bit 3 */
  509     "expired: security count",  /* word 128, bit 4 */
  510     "supported: enhanced erase" /* word 128, bit 5 */
  511 };
  512 
  513 /* word 160: CFA power mode */
  514 #define VALID_W160      0x8000  /* 1=word valid */
  515 #define PWR_MODE_REQ        0x2000  /* 1=CFA power level 1 is NOT supported */
  516 #define PWR_MODE_OFF        0x1000  /* 1=CFA power level 1 commands are DISABLED */
  517 #define MAX_AMPS        0x0fff  /* value = max current in milli-amperes (mA) */
  518 
  519 /* word 206: SMART command transport (SCT) */
  520 static const char *feat_sct_str[16] = {
  521     "unknown 206[15] (vendor specific)",        /* word 206 bit 15 */
  522     "unknown 206[14] (vendor specific)",        /* word 206 bit 14 */
  523     "unknown 206[13] (vendor specific)",        /* word 206 bit 13 */
  524     "unknown 206[12] (vendor specific)",        /* word 206 bit 12 */
  525     "unknown 206[11]",              /* word 206 bit 11 */
  526     "unknown 206[10]",              /* word 206 bit 10 */
  527     "unknown 206[9]",               /* word 206 bit  9 */
  528     "unknown 206[8]",               /* word 206 bit  8 */
  529     "unknown 206[7]",               /* word 206 bit  7 */
  530     "unknown 206[6]",               /* word 206 bit  6 */
  531     "SCT Data Tables (AC5)",            /* word 206 bit  5 */
  532     "SCT Features Control (AC4)",           /* word 206 bit  4 */
  533     "SCT Error Recovery Control (AC3)",     /* word 206 bit  3 */
  534     "SCT Write Same (AC2)",             /* word 206 bit  2 */
  535     "SCT Read/Write Long (AC1), obsolete",      /* word 206 bit  1: obsolete per T13/e08153r1 */
  536     "SMART Command Transport (SCT) feature set" /* word 206 bit  0 */
  537 };
  538 
  539 /* word 255: integrity */
  540 #define SIG         0x00ff  /* signature location */
  541 #define SIG_VAL         0x00A5  /* signature value */
  542 
  543 __u8 mode_loop(__u16 mode_sup, __u16 mode_sel, int cc, __u8 *have_mode);
  544 
  545 static void print_ascii(__u16 *p, unsigned int length) {
  546     __u8 ii;
  547     char cl;
  548 
  549     /* find first non-space & print it */
  550     for (ii = 0; ii< length; ii++) {
  551         if(((char) 0x00ff&((*p)>>8)) != ' ') break;
  552         if((cl = (char) 0x00ff&(*p)) != ' ') {
  553             if(cl != '\0') printf("%c",cl);
  554             p++; ii++;
  555             break;
  556         }
  557         p++;
  558     }
  559     /* print the rest */
  560     for (; ii < length; ii++) {
  561         __u8 c;
  562         /* some older devices have NULLs */
  563         c = (*p) >> 8;
  564         if (c) putchar(c);
  565         c = (*p);
  566         if (c) putchar(c);
  567         p++;
  568     }
  569     printf("\n");
  570 }
  571 
  572 // Given a known-supported ATA major revision,
  573 // return the lowest possible supported ATA revision.
  574 // Each new revision seems to (sometimes) obsolete one
  575 // of the bits corresponding to an older revision.
  576 static __u16 min_ata_std (__u16 major)
  577 {
  578     if (major <= 4)     // up to ata4, no obsolete bits
  579         return 1;
  580     if (major == 5)     // ata5 obsoleted the ata1 bit
  581         return 2;
  582     if (major <= 7)     // ata6,7 obsoleted the ata2 bit
  583         return 3;
  584     return 4;       // ata8 obsoleted the ata3 bit
  585 }
  586 
  587 static void print_features (__u16 supported, __u16 enabled, const char *names[])
  588 {
  589     int i;
  590     for (i = 0; i < 16; ++i) {
  591         __u16 mask = 1 << i;
  592         if ((supported & mask) && names[15 - i])
  593             printf("\t   %c\t%s\n", (enabled & mask) ? '*' : ' ', names[15 - i]);
  594     }
  595 }
  596 
  597 static int print_transport_type(__u16 val[])
  598 {
  599     __u16 major = val[TRANSPORT_MAJOR], minor = val[TRANSPORT_MINOR];
  600     unsigned int ttype, subtype, transport = 0;
  601 
  602     if (major == 0x0000 || major == 0xffff) {
  603 #if 0
  604         printf("\t%-20snot reported","Transport:");
  605         if ((val[SATA_CAP_0]  && val[SATA_CAP_0]  != 0xffff)
  606          || (val[SATA_SUPP_0] && val[SATA_SUPP_0] != 0xffff)) {
  607             printf(" (serial)");
  608         }
  609         putchar('\n');
  610 #endif
  611         return transport;
  612     }
  613     printf("\t%-20s","Transport:");
  614     ttype = major >> 12;
  615     subtype = major & 0xfff;
  616     transport = ttype;
  617     switch (ttype) {
  618         case 0:
  619             printf("Parallel");
  620             if (subtype & 1)
  621                 printf(", ATA8-APT");
  622             break;
  623         case 1:
  624             printf("Serial");
  625             if (subtype & 0x2f) {
  626                 if (subtype & (1<<0))
  627                     printf(", ATA8-AST");
  628                 if (subtype & (1<<1))
  629                     printf(", SATA 1.0a");
  630                 if (subtype & (1<<2))
  631                     printf(", SATA II Extensions");
  632                 if (subtype & (1<<3))
  633                     printf(", SATA Rev 2.5");
  634                 if (subtype & (1<<4))
  635                     printf(", SATA Rev 2.6");
  636                 if (subtype & (1<<5))
  637                     printf(", SATA Rev 3.0");
  638             }
  639             break;
  640         default:
  641             printf("0x%04x", major);
  642             break;
  643     }
  644     if (minor != 0x0000 && minor != 0xffff) {
  645         printf("; Revision: ");
  646         switch (minor) {
  647             case 0x21:
  648                 printf("ATA8-AST T13 Project D1697 Revision 0b");
  649                 break;
  650             default:
  651                 printf("0x%04x", minor);
  652         }
  653     }
  654     putchar('\n');
  655     return transport;
  656 }
  657 
  658 static int is_cfa_dev (__u16 *id)
  659 {
  660     /*
  661      * id[0] == 0x848a means "CFA compliant, not ATA-4 compliant".
  662      * id[0] == 0x044a is also allowed, but ISTR that some HDs use it too.
  663      * Also, bit 0x0004 of id[83] means "supports CFA feature set".
  664      */
  665     return id[0] == 0x848a || id[0] == 0x844a || (id[83] & 0xc004) == 0x4004;
  666 }
  667 
  668 static void print_devslp_info (int fd, __u16 *id)
  669 {
  670     /* Print DEVSLP information */
  671     if (id[78] & 0x0100) {
  672         __u8 buf[512];
  673         int deto = 0;
  674         int mdat = 0;
  675 
  676         memset(buf, 0, 512);
  677         if (fd != -1 && !get_log_page_data(fd, 0x30, 8, buf) && (buf[0x37] & 0x80)) {
  678             mdat = buf[0x30] & 0x1f;
  679             deto = buf[0x31];
  680             printf("Device Sleep:\n");
  681             printf("\tDEVSLP Exit Timeout (DETO): %d ms (%s)\n", deto?deto:20, deto?"drive":"default");
  682             printf("\tMinimum DEVSLP Assertion Time (MDAT): %d ms (%s)\n", mdat?mdat:10, deto?"drive":"default");
  683         }
  684     }
  685 }
  686 
  687 static void
  688 print_logical_sector_sizes (int fd)
  689 {
  690     __u8 d[512] = {0,};
  691     int i, found = 0, rc;
  692 
  693     rc = get_log_page_data(fd, 0x2f, 0, d);
  694     if (rc)
  695         return;
  696     for (i = 0; i < 128; i += 16) {
  697         unsigned int lss;
  698         if ((d[i] & 0x80) == 0)  /* Is this descriptor valid? */
  699             continue;  /* not valid */
  700         if (!found++)
  701             printf(" [ Supported:");
  702         lss = d[i + 4] | (d[i + 5] << 8) | (d[i + 6] << 16) | (d[i + 7] << 24);  /* logical sector size */
  703         printf(" %u", lss);
  704     }
  705     if (found)
  706         printf(" ]");
  707 }
  708 
  709 /* our main() routine: */
  710 void identify (int fd, __u16 *id_supplied)
  711 {
  712     unsigned int sector_bytes = 512;
  713     __u16 val[256], ii, jj, kk;
  714     __u16 like_std = 1, std = 0, min_std = 0xffff;
  715     __u16 dev = NO_DEV, eqpt = NO_DEV;
  716     __u8  have_mode = 0, err_dma = 0;
  717     __u8  chksum = 0;
  718     __u32 ll, mm, nn;
  719     __u64 bb, bbbig; /* (:) */
  720     int transport, is_cfa = 0, atapi_has_dmadir = 0, sdma_ok;
  721 
  722     memcpy(val, id_supplied, sizeof(val));
  723 
  724     /* calculate checksum over all bytes */
  725     for (ii = GEN_CONFIG; ii<=INTEGRITY; ii++) {
  726         chksum += val[ii] + (val[ii] >> 8);
  727     }
  728 
  729     /* check if we recognise the device type */
  730     printf("\n");
  731 
  732     //if(val[GEN_CONFIG] == 0x848a || val[GEN_CONFIG] == 0x844a) {
  733     if (is_cfa_dev(val)) {
  734         is_cfa = 1;
  735         dev = ATA_DEV;
  736         like_std = 4;
  737         printf("CompactFlash ATA device\n");
  738     } else if(!(val[GEN_CONFIG] & NOT_ATA)) {
  739         dev = ATA_DEV;
  740         printf("ATA device, with ");
  741     } else if(!(val[GEN_CONFIG] & NOT_ATAPI)) {
  742         dev = ATAPI_DEV;
  743         eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
  744         printf("ATAPI %s, with ", pkt_str[eqpt]);
  745         like_std = 3;
  746     } else {
  747         printf("Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n");
  748         exit(EINVAL);
  749     }
  750     if (!is_cfa) {
  751         if(!(val[GEN_CONFIG] & MEDIA_REMOVABLE))
  752             printf("non-");
  753         printf("removable media\n");
  754     }
  755 
  756     /* Info from the specific configuration word says whether or not the
  757      * ID command completed correctly.  It is only defined, however in
  758      * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior 
  759      * standards.  Since the values allowed for this word are extremely
  760      * specific, it should be safe to check it now, even though we don't
  761      * know yet what standard this device is using.
  762      */
  763     if((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL) ||
  764        (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL) ) {
  765         like_std = 5;
  766         if((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
  767             printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
  768         if(((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) &&
  769            (val[GEN_CONFIG] & INCOMPLETE)) 
  770             printf("\n\tWARNING: ID response incomplete.\n\tWARNING: Following data may be incorrect.\n\n");
  771     }
  772 
  773     /* output the model and serial numbers and the fw revision */
  774     if(val[START_MODEL]) {
  775         printf("\t%-20s","Model Number:");
  776         print_ascii(&val[START_MODEL], LENGTH_MODEL);
  777     }
  778     if(val[START_SERIAL]) {
  779         printf("\t%-20s","Serial Number:");
  780         print_ascii( &val[START_SERIAL], LENGTH_SERIAL);
  781     }
  782     if(val[START_FW_REV]) {
  783         printf("\t%-20s","Firmware Revision:");
  784         print_ascii(&val[START_FW_REV], LENGTH_FW_REV);
  785     }
  786     if(val[START_MEDIA]) {
  787         printf("\t%-20s","Media Serial Num:");
  788         print_ascii(&val[START_MEDIA], LENGTH_MEDIA);
  789     }
  790     if(val[START_MANUF]) {
  791         printf("\t%-20s","Media Manufacturer:");
  792         print_ascii(&val[START_MANUF], LENGTH_MANUF);
  793     }
  794 
  795     transport = print_transport_type(val);
  796 
  797     /* major & minor standards version number (Note: these words were not
  798      * defined until ATA-3 & the CDROM std uses different words.) */
  799     printf("Standards:");
  800     if(eqpt != CDROM) {
  801         //printf("major=%04x minor=%04x\n", val[MAJOR], val[MINOR]);
  802         const char * used = 0;
  803         if(val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
  804             if(like_std < 3)
  805                 like_std = 3;
  806             std = actual_ver[val[MINOR]];
  807             if (std)
  808                 used = minor_str[val[MINOR]];
  809         } else {
  810             /* check for recent ATA-8 revision codes (not added to
  811              * actual_ver/minor_str to avoid large sparse tables) */
  812             switch (val[MINOR]) {
  813               case 0x0027: used = "ATA-8-ACS revision 3c"; break;
  814               case 0x0033: used = "ATA-8-ACS revision 3e"; break;
  815               case 0x0042: used = "ATA-8-ACS revision 3f"; break;
  816               case 0x0052: used = "ATA-8-ACS revision 3b"; break;
  817               case 0x0107: used = "ATA-8-ACS revision 2d"; break;
  818             }
  819             if (used)
  820                 std = 8;
  821         }
  822         if (used)
  823             printf("\n\tUsed: %s ", used);
  824         else if (val[MINOR] >= 0x001f) /* first "reserved" value possibly later used by ATA-8 */
  825             printf("\n\tUsed: unknown (minor revision code 0x%04x) ", val[MINOR]);
  826 
  827         /* looks like when they up-issue the std, they obsolete one;
  828          * thus, only the newest 4 issues need be supported.
  829          * (That's what "kk" and "min_std" are all about) */
  830         if(val[MAJOR] && (val[MAJOR] != 0xffff)) {
  831             printf("\n\tSupported: ");
  832             jj = val[MAJOR] << 1;
  833             kk = min_ata_std(like_std);
  834             for (ii = 14; ii > kk; ii--) {
  835                 if(jj & 0x8000) {
  836                     printf("%u ", ii);
  837                     if (ii > like_std) {
  838                         like_std = ii;
  839                         kk = min_ata_std(like_std);
  840                     }
  841                     if (min_std > ii)
  842                         min_std = ii;
  843                 }
  844                 jj <<= 1;
  845             }
  846             if(like_std < 3)
  847                 like_std = 3;
  848         }
  849         /* Figure out what standard the device is using if it hasn't told
  850          * us.  If we know the std, check if the device is using any of
  851          * the words from the next level up.  It happens.
  852          */
  853         if(like_std < std) like_std = std;
  854         if(((std == 7) || (!std && (like_std < 8))) &&
  855            (val[SCT_SUPP] & 0x1)) {
  856             like_std = 8;
  857         } else if(((std == 5) || (!std && (like_std < 6))) &&
  858            ( (((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
  859              ((val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
  860             (((val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
  861              (val[CMDS_SUPP_2] & CMDS_W84) ) ) ) {
  862             like_std = 6;
  863         }  else if(((std == 4) || (!std && (like_std < 5))) &&
  864            ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
  865             ((val[HWRST_RSLT] & VALID) == VALID_VAL) ||
  866             (((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
  867              ((val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) ) {
  868             like_std = 5;
  869         }  else if(((std == 3) || (!std && (like_std < 4))) &&
  870                ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
  871                  (((val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||  
  872                   ((val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
  873                 ((val[CAPAB_1] & VALID) == VALID_VAL) ||
  874                 ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
  875                 ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) ) ) {
  876             like_std = 4;
  877         }  else if(((std == 2) || (!std && (like_std < 3))) &&
  878                ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) ) {
  879             like_std = 3;
  880         }  else if(((std == 1) || (!std && (like_std < 2))) &&
  881                ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
  882                 (val[WHATS_VALID] & OK_W64_70)) ) {
  883             like_std = 2;
  884         }
  885         if(!std) {
  886             printf("\n\tLikely used: %u\n",like_std);
  887         } else if(like_std > std) {
  888             printf("& some of %u\n",like_std);
  889         } else  printf("\n");
  890     } else {
  891         /* TBD: do CDROM stuff more thoroughly.  For now... */
  892         kk = 0;
  893         if(val[CDR_MINOR] == 9) {
  894             kk = 1;
  895             printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
  896         }
  897         if(val[CDR_MAJOR] && (val[CDR_MAJOR] != 0xffff)) {
  898             kk = 1;
  899             printf("\n\tSupported: CD-ROM ATAPI");
  900             jj = val[CDR_MAJOR] >> 1;
  901             for (ii = 1; ii <15; ii++) {
  902                 if(jj & 0x0001) {
  903                     printf("-%u ", ii);
  904                 }
  905                 jj >>= 1;
  906             }
  907         }
  908         if(!kk) printf("\n\tLikely used CD-ROM ATAPI-1\n");
  909         else    printf("\n");
  910         /* the cdrom stuff is more like ATA-2 than anything else, so: */
  911         like_std = 2;
  912     }
  913 
  914     if(min_std == 0xffff)
  915         min_std = like_std > 4 ? like_std - 3 : 1;
  916 
  917     printf("Configuration:\n");
  918     /* more info from the general configuration word */
  919     if((eqpt != CDROM) && (like_std == 1)) {
  920         jj = val[GEN_CONFIG] >> 1;
  921         for (ii = 1; ii < 15; ii++) {
  922             if(jj & 0x0001) printf("\t%s\n",ata1_cfg_str[ii]);
  923             jj >>=1;
  924         }
  925     }
  926     if(dev == ATAPI_DEV) {
  927         printf("\tDRQ response: "); /* Data Request (DRQ) */
  928         switch(val[GEN_CONFIG] & DRQ_RESPONSE_TIME) {
  929         case DRQ_3MS_VAL : printf("3ms.\n"); break;
  930         case DRQ_INTR_VAL : printf("<=10ms with INTRQ\n"); break;
  931         case DRQ_50US_VAL : printf("50us.\n"); break;
  932         default : printf("unknown.\n"); break;
  933         }
  934         printf("\tPacket size: ");
  935         switch(val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) {
  936         case PKT_SIZE_12_VAL : printf("12 bytes\n"); break;
  937         case PKT_SIZE_16_VAL : printf("16 bytes\n"); break;
  938         default : printf("Unknown\n"); break;
  939         }
  940     } else {
  941         /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
  942         ll = 0; mm = 0; bb = 0; bbbig = 0;
  943         if (val[CAPAB_0] & LBA_SUP)
  944             ll = (__u32)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
  945         if ( (ll > 0x00FBFC10) && (!val[LCYLS])) {
  946             printf("\tCHS addressing not supported\n");
  947         } else {
  948             jj = val[WHATS_VALID] & OK_W54_58;
  949             printf("\tLogical\t\tmax\tcurrent\n");
  950             printf("\tcylinders\t%u\t%u\n",val[LCYLS],jj?val[LCYLS_CUR]:0);
  951             printf("\theads\t\t%u\t%u\n",val[LHEADS],jj?val[LHEADS_CUR]:0);
  952             printf("\tsectors/track\t%u\t%u\n",val[LSECTS],jj?val[LSECTS_CUR]:0);
  953             if(jj)
  954                 bb = (__u64)val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
  955             else
  956                 bb = (__u64)val[LCYLS] * val[LHEADS] * val[LSECTS];
  957             printf("\t--\n");
  958             if((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES])) {
  959                 printf("\tbytes/track: %u",val[TRACK_BYTES]);
  960                 printf("\tbytes/sector: %u\n",val[SECT_BYTES]);
  961             }
  962             if(jj) {
  963                 mm = (__u32)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
  964                 /* ATA-1 is ambiguous on ordering of words 57 & 58 */
  965                 if(like_std < 3) {
  966                     nn = (__u32)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
  967                     /* check Endian of capacity bytes */
  968                     if(llabs((long long)(mm - bb)) > llabs((long long)(nn - bb)))
  969                         mm = nn;
  970                 }
  971                 printf("\tCHS current addressable sectors:%12u\n",mm);
  972             } 
  973         }
  974         if (val[CAPAB_0] & LBA_SUP) {
  975         /* LBA addressing */
  976             printf("\tLBA    user addressable sectors:%12u\n",ll);
  977             if( ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
  978                  (val[CMDS_SUPP_1] & SUPPORT_48_BIT) ) {
  979                 bbbig = (__u64)val[LBA_64_MSB] << 48 | 
  980                         (__u64)val[LBA_48_MSB] << 32 |
  981                         (__u64)val[LBA_MID] << 16 | 
  982                     val[LBA_LSB] ;
  983                 printf("\tLBA48  user addressable sectors:%12llu\n", (unsigned long long)bbbig);
  984             }
  985         }
  986         if((val[106] & 0xc000) != 0x4000) {
  987             printf("\t%-31s %11u bytes\n","Logical/Physical Sector size:", sector_bytes);
  988         } else {
  989             unsigned int lsize = 256, pfactor = 1;
  990             if (val[106] & (1<<13))
  991                 pfactor = (1 << (val[106] & 0xf));
  992             if (val[106] & (1<<12))
  993                 lsize = (val[118] << 16) | val[117];
  994             sector_bytes = 2 * lsize;
  995             printf("\t%-31s %11u bytes","Logical  Sector size:", sector_bytes);
  996             print_logical_sector_sizes(fd);
  997             printf("\n");
  998             printf("\t%-31s %11u bytes\n","Physical Sector size:", sector_bytes * pfactor);
  999             if ((val[209] & 0xc000) == 0x4000) {
 1000                 unsigned int offset = val[209] & 0x1fff;
 1001                 printf("\t%-31s %11u bytes\n", "Logical Sector-0 offset:", offset * sector_bytes);
 1002             }
 1003         }
 1004         if (!bbbig) bbbig = (__u64)((ll > mm) ? ll : mm); /* # 512 byte blocks */
 1005         if (!bbbig) bbbig = bb;
 1006         bbbig *= sector_bytes;
 1007 
 1008         printf("\tdevice size with M = 1024*1024: %11llu MBytes\n", bbbig / (1024ull * 1024ull));
 1009         bbbig /= 1000ull;
 1010         printf("\tdevice size with M = 1000*1000: %11llu MBytes ",  bbbig / 1000ull);
 1011         if (bbbig > 1000ull) printf("(%llu GB)\n", bbbig/1000000ull);
 1012         else printf("\n");
 1013     }
 1014 
 1015     /* device cache/buffer size, if reported (obsolete field, but usually valid regardless) */
 1016     printf("\tcache/buffer size  = ");
 1017     if (val[20] <= 3 && val[BUF_SIZE] && val[BUF_SIZE] != 0xffff) {
 1018         printf("%u KBytes", val[BUF_SIZE] / 2);
 1019         if (val[20])
 1020             printf(" (type=%s)", BuffType[val[20]]);
 1021     } else {
 1022         printf("unknown");
 1023     }
 1024     putchar('\n');
 1025 
 1026     /* Form factor */
 1027     if(val[168] && (val[168] & 0xfff8) == 0) {
 1028         printf("\tForm Factor: ");
 1029         switch(val[168]) {
 1030         case 1:
 1031             printf("5.25 inch");
 1032             break;
 1033         case 2:
 1034             printf("3.5 inch");
 1035             break;
 1036         case 3:
 1037             printf("2.5 inch");
 1038             break;
 1039         case 4:
 1040             printf("1.8 inch");
 1041             break;
 1042         case 5:
 1043             printf("less than 1.8 inch");
 1044             break;
 1045         default:
 1046             printf("unknown (0x%04x]", val[168]);
 1047             break;
 1048         }
 1049         printf("\n");
 1050     }
 1051 
 1052     /* Spinning disk or solid state? */
 1053     if(val[NMRR] == 1)
 1054         printf("\tNominal Media Rotation Rate: Solid State Device\n");
 1055     else if(val[NMRR] > 0x401)
 1056         printf("\tNominal Media Rotation Rate: %u\n", val[NMRR]);
 1057 
 1058     /* hw support of commands (capabilities) */
 1059     printf("Capabilities:\n");
 1060     printf("\t");
 1061     if(dev == ATAPI_DEV) {
 1062         if(eqpt != CDROM) {
 1063             if(val[CAPAB_0] & CMD_Q_SUP) printf("Cmd queuing, ");
 1064         }
 1065         if(val[CAPAB_0] & OVLP_SUP) printf("Cmd overlap, ");
 1066     }
 1067     if(val[CAPAB_0] & LBA_SUP) printf("LBA, ");
 1068     if(like_std != 1) {
 1069         printf("IORDY");
 1070         if(!(val[CAPAB_0] & IORDY_SUP)) printf("(may be)");
 1071         if(val[CAPAB_0] & IORDY_OFF) printf("(can");
 1072         else                 printf("(cannot");
 1073         printf(" be disabled)");
 1074     } else {
 1075         printf("IORDY not likely"); 
 1076     }
 1077     printf("\n");
 1078     if((like_std == 1) && val[BUF_TYPE]) {
 1079         kk = val[BUF_TYPE];
 1080         printf("\tBuffer type: %04x: ",kk);
 1081         if (kk < 2)     printf("single port, single-sector");
 1082         else        printf("dual port, multi-sector");
 1083         if (kk > 2) printf(" with read caching ability");
 1084         printf("\n");
 1085     }
 1086     jj = 0;
 1087     if((min_std == 1) && (val[BUF_SIZE] && (val[BUF_SIZE] != 0xffff))) {
 1088         printf("\tBuffer size: %.1fkB",(float)val[BUF_SIZE]/2);
 1089         jj = 1;
 1090     }
 1091     if((min_std < 4) && (val[RW_LONG])) {
 1092         printf("\tbytes avail on r/w long: %u",val[RW_LONG]);
 1093         jj = 1;
 1094     }
 1095     if((eqpt != CDROM) && (like_std > 3)) {
 1096         int has_queuing = 0;
 1097         if (transport == 1 || (val[SATA_CAP_0] && val[SATA_CAP_0] != 0xffff)) {
 1098             if (val[SATA_CAP_0] & 0x0100)
 1099                 has_queuing = 1;    // SATA NCQ
 1100         }
 1101         if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL && val[CMDS_SUPP_1] & 2) {
 1102             has_queuing = 1;        // TCQ
 1103         }
 1104         if (has_queuing) {
 1105             printf("\tQueue depth: %u",(val[QUEUE_DEPTH] & DEPTH_BITS)+1);
 1106             jj = 1;
 1107         }
 1108     }
 1109     if(jj) printf("\n");
 1110     if(dev == ATA_DEV) {
 1111         if(like_std == 1) {
 1112             printf("\tCan");
 1113             if(!val[DWORD_IO]) printf("not");
 1114             printf(" perform double-word IO\n");
 1115         } else {
 1116             printf("\tStandby timer values: spec'd by ");
 1117             if(val[CAPAB_0] & STD_STBY) printf("Standard");
 1118             else                printf("Vendor");
 1119             if((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL)) {
 1120                 if(val[CAPAB_1] & MIN_STANDBY_TIMER) printf(", with ");
 1121                 else                     printf(", no ");
 1122                 printf("device specific minimum\n");
 1123             } else  printf("\n");
 1124         }
 1125         printf("\tR/W multiple sector transfer: ");
 1126         if((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER)) {
 1127             printf("not supported\n");
 1128         } else {
 1129             printf("Max = %u\t",val[SECTOR_XFER_MAX] & SECTOR_XFER);
 1130             printf("Current = ");
 1131             if(val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
 1132                 printf("%u\n",val[SECTOR_XFER_CUR] & SECTOR_XFER);
 1133             else    printf("?\n");
 1134         }
 1135         if((like_std > 3) && (val[CMDS_SUPP_1] & 0xc008) == 0x4008) {
 1136             printf("\tAdvanced power management level: ");
 1137             if (val[CMDS_EN_1] & 0x0008)
 1138                 printf("%u\n", val[ADV_PWR] & 0xff);
 1139             else
 1140                 printf("disabled\n");
 1141         }
 1142         if(like_std > 5) {
 1143             if(val[ACOUSTIC]) {
 1144                 printf("\tRecommended acoustic management value: %u, current value: %u\n", (val[ACOUSTIC] >> 8) & 0x00ff, val[ACOUSTIC] & 0x00ff);
 1145             }
 1146         }
 1147     } else { /* ATAPI */
 1148         if(eqpt != CDROM) {
 1149             if(val[CAPAB_0] & SWRST_REQ) printf("\tATA sw reset required\n");
 1150         }
 1151         if(val[PKT_REL] || val[SVC_NBSY]) {
 1152             printf("\tOverlap support:");
 1153             if(val[PKT_REL]) printf(" %uus to release bus.",val[PKT_REL]);
 1154             if(val[SVC_NBSY]) printf(" %uus to clear BSY after SERVICE cmd.",val[SVC_NBSY]);
 1155             printf("\n");
 1156         }
 1157     }
 1158 
 1159     /* Some SATA-ATAPI devices use a different interpretation of IDENTIFY words for DMA modes */
 1160     if (dev == ATAPI_DEV && val[62] & 0x8000) {
 1161         atapi_has_dmadir = 1;
 1162         sdma_ok = 0;  /* word 62 has been re-purposed for non-sdma mode reporting */
 1163         printf("\tDMADIR bit required in PACKET commands\n");
 1164     } else {
 1165         __u16 w62 = val[62];
 1166         __u8 hi = w62 >> 8, lo = w62;
 1167         if (!w62 || (lo & 0xf8))
 1168             sdma_ok = 0;
 1169         else if (hi && hi != 1 && hi != 2 && hi != 4)
 1170             sdma_ok = 0;
 1171         else
 1172             sdma_ok = 1;
 1173     }
 1174 
 1175     printf("\tDMA: ");
 1176     /* DMA stuff. Check that only one DMA mode is selected. */
 1177     if(!atapi_has_dmadir && !(val[CAPAB_0] & DMA_SUP)) {
 1178         printf("not supported\n");
 1179     } else {
 1180         if(val[DMA_MODE] && !val[62] && !val[MULTI_DMA]) {
 1181             printf("sdma%u",(val[DMA_MODE] & MODE) >> 8);
 1182         } else {
 1183             if(sdma_ok) {
 1184                 kk = val[62] >> 8;
 1185                 jj = val[62];
 1186                 err_dma += mode_loop(jj,kk,'s',&have_mode);
 1187             }
 1188             if(val[MULTI_DMA]) {
 1189                 kk = val[MULTI_DMA] >> 8;
 1190                 jj = atapi_has_dmadir ? (val[62] >> 7) & 7 : val[MULTI_DMA];
 1191                 err_dma += mode_loop(jj,kk,'m',&have_mode);
 1192             }
 1193             if((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
 1194                 kk = val[ULTRA_DMA] >> 8;
 1195                 jj = atapi_has_dmadir ? val[62] & 0x7f : val[ULTRA_DMA];
 1196                 err_dma += mode_loop(jj,kk,'u',&have_mode);
 1197             }
 1198             if(err_dma || !have_mode)
 1199                 printf("(?)");
 1200         }
 1201         printf("\n");
 1202 
 1203         if((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP)) 
 1204             printf("\t     Interleaved DMA support\n");
 1205 
 1206         if((val[WHATS_VALID] & OK_W64_70) && 
 1207            (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])) {
 1208             printf("\t     Cycle time:");
 1209             if(val[DMA_TIME_MIN])
 1210                 printf(" min=%uns",val[DMA_TIME_MIN]);
 1211             if(val[DMA_TIME_NORM])
 1212                 printf(" recommended=%uns",val[DMA_TIME_NORM]);
 1213             printf("\n");
 1214         }
 1215     }
 1216 
 1217     /* Programmed IO stuff */
 1218     printf("\tPIO: ");
 1219         /* If a drive supports mode n (e.g. 3), it also supports all modes less
 1220      * than n (e.g. 3, 2, 1 and 0).  Print all the modes. */
 1221     if((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
 1222         jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
 1223         for (ii = 0; ii <= PIO_MODE_MAX ; ii++) {
 1224             if(jj & 0x0001)
 1225                 printf("pio%d ",ii);
 1226             jj >>=1;
 1227         }
 1228         printf("\n");
 1229     } else if(((min_std < 5) || (eqpt == CDROM)) && ((val[PIO_MODE]>>8) <= 2)) {
 1230         for (ii = 0; ii <= val[PIO_MODE]>>8; ii++) {
 1231             printf("pio%d ",ii);
 1232         }
 1233         printf("\n");
 1234     } else  printf("unknown\n");
 1235     if(val[WHATS_VALID] & OK_W64_70) {
 1236         if(val[PIO_NO_FLOW] || val[PIO_FLOW]) {
 1237             printf("\t     Cycle time:");
 1238             if(val[PIO_NO_FLOW])
 1239                 printf(" no flow control=%uns", val[PIO_NO_FLOW]);
 1240             if(val[PIO_FLOW])
 1241                 printf("  IORDY flow control=%uns", val[PIO_FLOW]);
 1242             printf("\n");
 1243         }
 1244     }
 1245 
 1246     if((val[CMDS_SUPP_1] & VALID) == VALID_VAL){
 1247         printf("Commands/features:\n\tEnabled\tSupported:\n");
 1248         print_features(val[CMDS_SUPP_0] & 0x7fff, val[CMDS_EN_0], feat_word82_str);
 1249         if( (val[CMDS_SUPP_1] &  VALID) == VALID_VAL)
 1250             print_features(val[CMDS_SUPP_1] & 0x3fff, val[CMDS_EN_1], feat_word83_str);
 1251         if( (val[CMDS_SUPP_2] &  VALID) == VALID_VAL
 1252          && (val[CMDS_EN_2]  &   VALID) == VALID_VAL) {
 1253             print_features(val[CMDS_SUPP_2] & 0x3fff, val[CMDS_EN_2], feat_word84_str);
 1254             if ((val[CMDS_SUPP_2] & 0x1800) == 0x1800 && val[116] && val[116] != 0xffff)
 1255                 printf("                (%u msec for TLC completion timer)\n", 10 * (unsigned int)(val[116]));
 1256         }
 1257         if( (val[CMDS_SUPP_1] &  VALID) == VALID_VAL
 1258          && (val[CMDS_EN_1]   & 0x8000) == 0x8000
 1259          && (val[CMDS_SUPP_3] &  VALID) == VALID_VAL
 1260          && (val[CMDS_EN_3]   &  VALID) == VALID_VAL)
 1261             print_features(val[CMDS_SUPP_3] & 0x3fff, val[CMDS_EN_3], feat_3_str);
 1262         if (transport == 1 || (val[SATA_CAP_0] && val[SATA_CAP_0] != 0xffff))
 1263             print_features(val[SATA_CAP_0],  val[SATA_CAP_0], cap_sata0_str);
 1264         if (transport == 1 || (val[SATA_SUPP_0] && val[SATA_SUPP_0] != 0xffff))
 1265             print_features(val[SATA_SUPP_0], val[SATA_EN_0], feat_sata0_str);
 1266         if (val[SCT_SUPP] & 0x1)
 1267             print_features(val[SCT_SUPP], val[SCT_SUPP] & 0x3f, feat_sct_str);
 1268         if (val[SECTOR_XFER_CUR] & SANITIZE_FEAT_SUP)
 1269             print_features(val[SECTOR_XFER_CUR], val[SECTOR_XFER_CUR], feat_word59_str);
 1270     }
 1271     if (like_std > 6) {
 1272         const __u16 trimd = 1<<14;  /* deterministic read data after TRIM */
 1273         const __u16 trimz = 1<<5;   /* deterministic read ZEROs after TRIM */
 1274         __u16 word69 = val[69] & ~(trimz | trimd); /* TRIM bits require special interpretation */
 1275         print_features(word69, word69, feat_word69_str);
 1276         if (val[169] & 1 && val[169] != 0xffff) { /* supports TRIM ? */
 1277             printf("\t   *\tData Set Management TRIM supported");
 1278             if (val[105] && val[105] != 0xffff)
 1279                 printf(" (limit %u block%s)\n", val[105], val[105] > 1 ? "s" : "");
 1280             else
 1281                 printf(" (limit unknown)\n");
 1282             if (val[69] & trimd) { /* Deterministic TRIM support */
 1283                 if (val[69] & trimz)
 1284                     print_features(trimz, trimz, feat_word69_str);
 1285                 else
 1286                     print_features(trimd, trimd, feat_word69_str);
 1287             }
 1288         }
 1289         
 1290     }
 1291 
 1292     if (is_cfa) {
 1293         unsigned int mode, max, selected;
 1294         char modes[256];
 1295         modes[0] = '\0';
 1296 
 1297         // CFA pio5-6:
 1298         max = val[163] & 7;
 1299         if (max == 1 || max == 2) {
 1300             selected = (val[163] >> 6) & 7;
 1301             for (mode = 1; mode <= max; ++mode) {
 1302                 if (mode == selected)
 1303                     strcat(modes, "*");
 1304                 sprintf(modes + strlen(modes), "pio%u ", mode + 4);
 1305             }
 1306         }
 1307         // CFA mdma3-4:
 1308         max = (val[163] >> 3) & 7;
 1309         if (max == 1 || max == 2) {
 1310             selected = (val[163] >> 9) & 7;
 1311             for (mode = 1; mode <= max; ++mode) {
 1312                 if (mode == selected)
 1313                     strcat(modes, "*");
 1314                 sprintf(modes + strlen(modes), "mdma%u ", mode + 2);
 1315             }
 1316         }
 1317         if (val[164] & 0x8000)
 1318         {
 1319             static const unsigned char io_times [4] = {255,120,100,80};
 1320             static const unsigned char mem_times[4] = {250,120,100,80};
 1321             max = val[164] & 7;
 1322             if (max <= 3)
 1323                 printf("\t\tCFA max advanced io_udma cycle time: %uns\n", io_times[max]);
 1324             max = (val[164] >> 3) & 7;
 1325             if (max <= 3)
 1326                 printf("\t\tCFA max advanced mem_udma cycle time: %uns\n", mem_times[max]);
 1327             // CFA ioport dma0-6:
 1328             max = (val[164] >> 6) & 7;
 1329             if (max <= 6) {
 1330                 selected = (val[164] >> 12) & 7;
 1331                 for (mode = 0; mode <= max; ++mode) {
 1332                     if (mode == selected)
 1333                         strcat(modes, "*");
 1334                     sprintf(modes + strlen(modes), "io_udma%u ", mode + 4);
 1335                 }
 1336             }
 1337             // CFA memory udma0-6:
 1338             max = (val[164] >> 9) & 7;
 1339             if (max <= 6) {
 1340                 selected = (val[164] >> 12) & 7;
 1341                 for (mode = 0; mode <= max; ++mode) {
 1342                     if (mode == selected)
 1343                         strcat(modes, "*");
 1344                     sprintf(modes + strlen(modes), "mem_udma%u ", mode + 4);
 1345                 }
 1346             }
 1347         }
 1348         if (modes[0])
 1349             printf("\t   *\tCFA advanced modes: %s\n", modes);
 1350 
 1351         if(val[CFA_PWR_MODE] & VALID_W160) {
 1352             putchar('\t');
 1353             if((val[CFA_PWR_MODE] & PWR_MODE_REQ) == 0)
 1354                 printf("   *");
 1355             printf("\tCFA Power Level 1 ");
 1356             if(val[CFA_PWR_MODE] & PWR_MODE_REQ)
 1357                 printf(" not supported");
 1358             if(val[CFA_PWR_MODE] & MAX_AMPS)
 1359                 printf(" (max %umA)", val[CFA_PWR_MODE] & MAX_AMPS);
 1360             printf("\n");
 1361         }
 1362         //else printf("\t\tCFA Power modes not reported\n");
 1363         if (val[162] && val[162] != 0xffff) {
 1364             if (val[162] & 1)
 1365                 printf("\t\tKey Management (CPRM) feature set\n");
 1366         }
 1367     }
 1368 
 1369     if((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
 1370         printf("\t\tRemovable Media Status Notification feature set supported\n");
 1371 
 1372 
 1373     /* security */
 1374     if ((val[CMDS_SUPP_0] & (1 << 1)) && (eqpt != CDROM) && (like_std > 3) && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME]))
 1375     {
 1376         printf("Security: \n");
 1377         if (val[PSWD_CODE] && (val[PSWD_CODE] != 0xffff))
 1378             printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
 1379         jj = val[SECU_STATUS];
 1380         if (jj) {
 1381             for (ii = 0; ii < NUM_SECU_STR; ii++) {
 1382                 if (!(jj & 0x0001)) printf("%s", ii ? "\tnot\t" : "\t(?)\t");
 1383                 else                printf("\t\t");
 1384                 printf("%s\n", secu_str[ii]);
 1385                 jj >>= 1;
 1386             }
 1387             if (val[SECU_STATUS] & SECU_ENABLED) {
 1388                 printf("\tSecurity level ");
 1389                 if (val[SECU_STATUS] & SECU_LEVEL) printf("maximum\n");
 1390                 else                               printf("high\n");
 1391             }
 1392         }
 1393         jj = val[ERASE_TIME];                                 // Grab normal erase time
 1394         unsigned int const ext_time_n = (jj & (1 << 15)) != 0;// Check if erase time is extended format or not (ACS-3)
 1395         jj = ext_time_n ? jj & 0x7FFF: jj & 0x00FF;           // Mask off reserved bits accordingly
 1396         kk = val[ENH_ERASE_TIME];                             // Grab enhanced erase time
 1397         unsigned int const ext_time_e = (kk & (1 << 15)) != 0;// Check if erase time is extended format or not (ACS-3)
 1398         kk = ext_time_e ? kk & 0x7FFF: kk & 0x00FF;           // Mask off reserved bits accordingly
 1399         if ((jj != 0) || (kk != 0)) printf("\t");
 1400         if (jj != 0) {
 1401             if (ext_time_n && (jj == 0x7FFF)) {
 1402                 printf("more than 65532");
 1403             } else if (!ext_time_n && (jj == 0x00FF)) {
 1404                 printf("more than 508");
 1405             } else {
 1406                 printf("%u", jj * 2);
 1407             }
 1408             printf("min for SECURITY ERASE UNIT.");
 1409         }
 1410         if ((jj != 0) && (kk != 0)) printf(" ");
 1411         if (kk != 0) {
 1412             if (ext_time_e && (kk == 0x7FFF)) {
 1413                 printf("more than 65532");
 1414             } else if (!ext_time_e && (kk == 0x00FF)) {
 1415                 printf("more than 508");
 1416             } else {
 1417                 printf("%u", kk * 2);
 1418             }
 1419             printf("min for ENHANCED SECURITY ERASE UNIT.");
 1420         }
 1421         printf("\n");
 1422     }
 1423 
 1424 
 1425     //printf("w84=0x%04x w87=0x%04x like_std=%d\n", val[84], val[87], like_std);
 1426     if((eqpt != CDROM) && (like_std > 3) && (val[CMDS_SUPP_2] & WWN_SUP)) {
 1427         printf("Logical Unit WWN Device Identifier: %04x%04x%04x%04x\n", val[108], val[109], val[110], val[111]);
 1428         printf("\tNAA\t\t: %x\n", (val[108] & 0xf000) >> 12);
 1429         printf("\tIEEE OUI\t: %06x\n", (((val[108] & 0x0fff) << 12) | ((val[109] & 0xfff0) >> 4)));
 1430         printf("\tUnique ID\t: %x%08x\n", (val[109] & 0x000f), ((val[110] << 16) | val[111]));
 1431     }
 1432 
 1433     /* reset result */
 1434     if((val[HWRST_RSLT] & VALID) == VALID_VAL) {
 1435         printf("HW reset results:\n");
 1436         if(val[HWRST_RSLT] & CBLID) printf("\tCBLID- above Vih\n");
 1437         else                printf("\tCBLID- below Vih\n");
 1438         if(val[HWRST_RSLT] & RST0)  {
 1439             printf("\tDevice num = 0");
 1440             jj = val[HWRST_RSLT];
 1441         } else {
 1442             printf("\tDevice num = 1");
 1443             jj = val[HWRST_RSLT] >> 8;
 1444         }
 1445         if((jj & DEV_DET) == JUMPER_VAL) 
 1446             printf(" determined by the jumper");
 1447         else if((jj & DEV_DET) == CSEL_VAL)
 1448             printf(" determined by CSEL");
 1449         printf("\n");
 1450     }
 1451     print_devslp_info(fd, val);
 1452 
 1453     /* more stuff from std 5 */
 1454     if ((like_std > 4) && (eqpt != CDROM)) {
 1455         if ((val[INTEGRITY] & SIG) == SIG_VAL) {
 1456             printf("Checksum: %scorrect", chksum ? "in" : "");
 1457             if (chksum)
 1458                 printf(" (0x%02x), expected 0x%02x\n", chksum, 0x100 - chksum);
 1459             putchar('\n');
 1460         } else {
 1461             printf("Integrity word not set (found 0x%04x, expected 0x%02x%02x)\n",
 1462                 val[INTEGRITY], 0x100 - chksum, SIG_VAL);
 1463         }
 1464     }
 1465 }
 1466 
 1467 __u8 mode_loop(__u16 mode_sup, __u16 mode_sel, int cc, __u8 *have_mode) {
 1468     __u16 ii;
 1469     __u8 err_dma = 0;
 1470     for (ii = 0; ii <= MODE_MAX; ii++) {
 1471         if(mode_sel & 0x0001) {
 1472             printf("*%cdma%u ",cc,ii);
 1473             if(*have_mode) err_dma = 1;
 1474             *have_mode = 1;
 1475         } else if(mode_sup & 0x0001) {
 1476             printf("%cdma%u ",cc,ii);
 1477         }
 1478         mode_sup >>=1;   mode_sel >>=1;
 1479     }
 1480     return err_dma;
 1481 }
 1482 
 1483 void dco_identify_print (__u16 *dco)
 1484 {
 1485     __u64 lba;
 1486 
 1487     printf("DCO Revision: 0x%04x", dco[0]);
 1488     if (dco[0] == 0 || dco[0] > 2)
 1489         printf(" -- unknown, treating as 0002");
 1490     printf("\nThe following features can be selectively disabled via DCO:\n");
 1491 
 1492     printf("\tTransfer modes:\n\t\t");
 1493     if (dco[1] & 0x0007) {
 1494              if (dco[1] & (1<<2)) printf(" mdma0 mdma1 mdma2");
 1495         else if (dco[1] & (1<<1)) printf(" mdma0 mdma1");
 1496         else if (dco[1] & (1<<0)) printf(" mdma0");
 1497         printf("\n\t\t");
 1498     }
 1499     if (dco[2] & (1<<6)) {
 1500         printf(" udma0 udma1 udma2 udma3 udma4 udma5 udma6");
 1501         if (dco[0] < 2)
 1502             printf("(?)");
 1503     }
 1504     else if (dco[2] & (1<<5)) printf(" udma0 udma1 udma2 udma3 udma4 udma5");
 1505     else if (dco[2] & (1<<4)) printf(" udma0 udma1 udma2 udma3 udma4");
 1506     else if (dco[2] & (1<<3)) printf(" udma0 udma1 udma2 udma3");
 1507     else if (dco[2] & (1<<2)) printf(" udma0 udma1 udma2");
 1508     else if (dco[2] & (1<<1)) printf(" udma0 udma1");
 1509     else if (dco[2] & (1<<0)) printf(" udma0");
 1510     putchar('\n');
 1511 
 1512     lba = ((((__u64)dco[5]) << 32) | (dco[4] << 16) | dco[3]) + 1;
 1513     printf("\tReal max sectors: %llu\n", lba);
 1514 
 1515     printf("\tATA command/feature sets:");
 1516     if (dco[7] & 0x01ff) {
 1517         printf("\n\t\t");
 1518         if (dco[7] & (1<< 0)) printf(" SMART");
 1519         if (dco[7] & (1<< 1)) printf(" self_test");
 1520         if (dco[7] & (1<< 2)) printf(" error_log");
 1521         if (dco[7] & (1<< 3)) printf(" security");
 1522         if (dco[7] & (1<< 4)) printf(" PUIS");
 1523         if (dco[7] & (1<< 5)) printf(" TCQ");
 1524         if (dco[7] & (1<< 6)) printf(" AAM");
 1525         if (dco[7] & (1<< 7)) printf(" HPA");
 1526         if (dco[7] & (1<< 8)) printf(" 48_bit");
 1527     }
 1528     if (dco[7] & 0xfe00) {
 1529         printf("\n\t\t");
 1530         if (dco[0] < 2)
 1531             printf(" (?):");
 1532         if (dco[7] & (1<< 9)) printf(" streaming");
 1533         if (dco[7] & (1<<10)) printf(" TLC_Reserved_7[10]");
 1534         if (dco[7] & (1<<11)) printf(" FUA");
 1535         if (dco[7] & (1<<12)) printf(" selective_test");
 1536         if (dco[7] & (1<<13)) printf(" conveyance_test");
 1537         if (dco[7] & (1<<14)) printf(" write_read_verify");
 1538         if (dco[7] & (1<<15)) printf(" reserved_7[15]");
 1539     }
 1540     if (dco[21] & 0xf800) {
 1541         printf("\n\t\t");
 1542         if (dco[0] < 2)
 1543             printf(" (?):");
 1544         if (dco[21] & (1<<11)) printf(" free_fall");
 1545         if (dco[21] & (1<<12)) printf(" trusted_computing");
 1546         if (dco[21] & (1<<13)) printf(" WRITE_UNC_EXT");
 1547         if (dco[21] & (1<<14)) printf(" NV_cache_power_management");
 1548         if (dco[21] & (1<<15)) printf(" NV_cache");
 1549     }
 1550     putchar('\n');
 1551 
 1552     if (dco[8] & 0x1f) {
 1553         printf("\tSATA command/feature sets:\n\t\t");
 1554         if (dco[0] < 2)
 1555             printf(" (?):");
 1556         if (dco[8] & (1<<0)) printf(" NCQ");
 1557         if (dco[8] & (1<<1)) printf(" NZ_buffer_offsets");
 1558         if (dco[8] & (1<<2)) printf(" interface_power_management");
 1559         if (dco[8] & (1<<3)) printf(" async_notification");
 1560         if (dco[8] & (1<<4)) printf(" SSP");
 1561         putchar('\n');
 1562     }
 1563 }