"Fossies" - the Fresh Open Source Software Archive

Member "hdparm-9.60/identify.c.orig" (20 Nov 2018, 56075 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.

    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     "reserved 69[7]",               /* word 69 bit  7 */
  359     "reserved 69[6]",               /* word 69 bit  6 */
  360     "Deterministic read ZEROs after TRIM",      /* word 69 bit  5 */
  361     "reserved 69[4]",               /* word 69 bit  4 */
  362     "reserved 69[3]",               /* word 69 bit  3 */
  363     "reserved 69[2]",               /* 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 }