| 1 | /* $Id: ataid.c 76 2015-12-28 01:37:00Z bird $ */
 | 
|---|
| 2 | /** @file
 | 
|---|
| 3 |  * Verbose display of the device identify reply.
 | 
|---|
| 4 |  */
 | 
|---|
| 5 | 
 | 
|---|
| 6 | /*
 | 
|---|
| 7 |  * Copyright (c) 2015 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
 | 
|---|
| 8 |  *
 | 
|---|
| 9 |  * This program is free software; you can redistribute it and/or modify
 | 
|---|
| 10 |  * it under the terms of the GNU General Public License as published by
 | 
|---|
| 11 |  * the Free Software Foundation; either version 3 of the License, or
 | 
|---|
| 12 |  * (at your option) any later version.
 | 
|---|
| 13 |  *
 | 
|---|
| 14 |  * This program is distributed in the hope that it will be useful,
 | 
|---|
| 15 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 16 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 17 |  * GNU General Public License for more details.
 | 
|---|
| 18 |  *
 | 
|---|
| 19 |  * You should have received a copy of the GNU General Public License
 | 
|---|
| 20 |  * along with This program.  If not, see <http://www.gnu.org/licenses/>
 | 
|---|
| 21 |  *
 | 
|---|
| 22 |  */
 | 
|---|
| 23 | 
 | 
|---|
| 24 | 
 | 
|---|
| 25 | #include <stdio.h>
 | 
|---|
| 26 | #include <stdlib.h>
 | 
|---|
| 27 | #include <string.h>
 | 
|---|
| 28 | #include <stdint.h>
 | 
|---|
| 29 | #include <io.h>
 | 
|---|
| 30 | #include <conio.h>
 | 
|---|
| 31 | #include <time.h>
 | 
|---|
| 32 | 
 | 
|---|
| 33 | #include "atalib.h"
 | 
|---|
| 34 | 
 | 
|---|
| 35 | 
 | 
|---|
| 36 | uint8_t AtaCalcIdChecksum(void const *pv512Bytes)
 | 
|---|
| 37 | {
 | 
|---|
| 38 |     uint8_t        uCksum = 0;
 | 
|---|
| 39 |     uint8_t const *pb     = (uint8_t const *)pv512Bytes;
 | 
|---|
| 40 |     size_t         cbLeft = 511;
 | 
|---|
| 41 |     while (cbLeft-- > 0)
 | 
|---|
| 42 |         uCksum += *pb++;
 | 
|---|
| 43 |     return 0U - uCksum;
 | 
|---|
| 44 | }
 | 
|---|
| 45 | 
 | 
|---|
| 46 | 
 | 
|---|
| 47 | static void AtaPrintIdString(const char *pszPrefix, uint16_t const *pawStr, unsigned cWords, const char *pszSuffix)
 | 
|---|
| 48 | {
 | 
|---|
| 49 |     unsigned i;
 | 
|---|
| 50 | 
 | 
|---|
| 51 |     fputs(pszPrefix, stdout);
 | 
|---|
| 52 | 
 | 
|---|
| 53 |     putchar('\'');
 | 
|---|
| 54 |     for (i = 0; i < cWords; i++)
 | 
|---|
| 55 |     {
 | 
|---|
| 56 |         int j;
 | 
|---|
| 57 |         for (j = 8; j >= 0; j -= 8)
 | 
|---|
| 58 |         {
 | 
|---|
| 59 |             uint8_t b = (uint8_t)(pawStr[i] >> j);
 | 
|---|
| 60 |             if (b < UINT8_C(0x7f) || b >= UINT8_C(0x20))
 | 
|---|
| 61 |                 putchar(b);
 | 
|---|
| 62 |             else
 | 
|---|
| 63 |                 printf("\\x%02x", b);
 | 
|---|
| 64 |         }
 | 
|---|
| 65 |     }
 | 
|---|
| 66 |     putchar('\'');
 | 
|---|
| 67 | 
 | 
|---|
| 68 |     fputs(pszSuffix, stdout);
 | 
|---|
| 69 | }
 | 
|---|
| 70 | 
 | 
|---|
| 71 | 
 | 
|---|
| 72 | int main(int argc, char **argv)
 | 
|---|
| 73 | {
 | 
|---|
| 74 |     int             rc;
 | 
|---|
| 75 |     unsigned        i;
 | 
|---|
| 76 |     uint8_t         bCksum;
 | 
|---|
| 77 | 
 | 
|---|
| 78 |     rc = AtaInitFromArgv(1, argc, argv);
 | 
|---|
| 79 |     if (rc != 0)
 | 
|---|
| 80 |         return 2;
 | 
|---|
| 81 | 
 | 
|---|
| 82 |     /*
 | 
|---|
| 83 |      * Format the identify device response already stored in g_awIdentify.
 | 
|---|
| 84 |      */
 | 
|---|
| 85 |     /* Word[0]: */
 | 
|---|
| 86 |     i = 0;
 | 
|---|
| 87 |     printf("[%3u]=%#06x", i, g_awIdentify[i]);
 | 
|---|
| 88 |     if ((g_awIdentify[i] >> 7) & 1)     fputs(" removable-media", stdout);
 | 
|---|
| 89 |     if ((g_awIdentify[i] >> 6) & 1)     fputs(" not-removable", stdout);
 | 
|---|
| 90 |     if ((g_awIdentify[i] >> 2) & 1)     fputs(" bit2-maybe-incomplete!", stdout);
 | 
|---|
| 91 |     if ((g_awIdentify[i] >> 15) & 1)    fputs(" not-ATA-device!", stdout);
 | 
|---|
| 92 |     putchar('\n');
 | 
|---|
| 93 | 
 | 
|---|
| 94 |     i = 1; printf("[%3u]=%#06x - obsolete logical cylinders:         %d\n", i, g_awIdentify[i], g_awIdentify[i]);
 | 
|---|
| 95 |     i = 2; printf("[%3u]=%#06x (reserved / vendor specific)\n",             i, g_awIdentify[i]);
 | 
|---|
| 96 |     i = 3; printf("[%3u]=%#06x - obsolete logical heads:             %d\n", i, g_awIdentify[i], g_awIdentify[i]);
 | 
|---|
| 97 |     i = 4; printf("[%3u]=%#06x (vendor specific / retired)\n",              i, g_awIdentify[i]);
 | 
|---|
| 98 |     i = 5; printf("[%3u]=%#06x (vendor specific / retired)\n",              i, g_awIdentify[i]);
 | 
|---|
| 99 |     i = 6; printf("[%3u]=%#06x - obsolete logical sectors per track: %d\n", i, g_awIdentify[i], g_awIdentify[i]);
 | 
|---|
| 100 |     i = 7; printf("[%3u]=%#06x (vendor specific / reserved for CompactFlash)\n", i, g_awIdentify[i]);
 | 
|---|
| 101 |     i = 8; printf("[%3u]=%#06x (vendor specific / reserved for CompactFlash)\n", i, g_awIdentify[i]);
 | 
|---|
| 102 |     i = 9; printf("[%3u]=%#06x (vendor specific / retired)\n",              i, g_awIdentify[i]);
 | 
|---|
| 103 |     i = 10; AtaPrintIdString("[ 10:19]     - serial number:        ", &g_awIdentify[i], 10, "\n");
 | 
|---|
| 104 |     i = 20; printf("[%3u]=%#06x (vendor specific / obsolete)\n",            i, g_awIdentify[i]);
 | 
|---|
| 105 |     i = 21; printf("[%3u=%#06x (vendor specific / obsolete)\n",             i, g_awIdentify[i]);
 | 
|---|
| 106 |     i = 22; printf("[=%#06x - obsolete ECC/vendor bytes for READ/WRITE LONG %d\n", i, g_awIdentify[i], g_awIdentify[i]);
 | 
|---|
| 107 |     i = 23; AtaPrintIdString("[ 23:26]     - firmware revision:    ", &g_awIdentify[i], 4, "\n");
 | 
|---|
| 108 |     i = 27; AtaPrintIdString("[ 27:46]     - model number:         ", &g_awIdentify[i], 20, "\n");
 | 
|---|
| 109 | 
 | 
|---|
| 110 |     i = 47; printf("[%3u]=%#06x - READ/WRITE MULTIPLE ",                    i, g_awIdentify[i]);
 | 
|---|
| 111 |     if ((g_awIdentify[i] & 0xff) == 0)
 | 
|---|
| 112 |         fputs("not implemented", stdout);
 | 
|---|
| 113 |     else
 | 
|---|
| 114 |         printf("max %d sectors", g_awIdentify[47] & 0xff);
 | 
|---|
| 115 |     if ((g_awIdentify[i] >> 8) == 0x80)
 | 
|---|
| 116 |         fputs(", ATA-4 top value", stdout);
 | 
|---|
| 117 |     else
 | 
|---|
| 118 |         fputs(", vendor specific top value", stdout);
 | 
|---|
| 119 |     putchar('\n');
 | 
|---|
| 120 | 
 | 
|---|
| 121 |     i = 48; printf("[%3u]=%#06x - trusted computing group bits ",           i, g_awIdentify[i]);
 | 
|---|
| 122 |     if ((g_awIdentify[i] & UINT16_C(0xc001)) == UINT16_C(0x4001))
 | 
|---|
| 123 |         printf("%#x\n", g_awIdentify[i] & UINT16_C(0x3ffe));
 | 
|---|
| 124 |     else
 | 
|---|
| 125 |         fputs("not present\n", stdout);
 | 
|---|
| 126 | 
 | 
|---|
| 127 |     i = 49; printf("[%3u]=%#06x - capabilities:",                           i, g_awIdentify[i]);
 | 
|---|
| 128 |     if (g_awIdentify[i] & UINT16_C(0x0100))     fputs(" DMA", stdout);
 | 
|---|
| 129 |     if (g_awIdentify[i] & UINT16_C(0x0200))     fputs(" LBA", stdout);
 | 
|---|
| 130 |     if (g_awIdentify[i] & UINT16_C(0x0400))     fputs(" IORDY-disable", stdout);
 | 
|---|
| 131 |     if (g_awIdentify[i] & UINT16_C(0x0800))     fputs(" IORDY-supported", stdout);
 | 
|---|
| 132 |     if (g_awIdentify[i] & UINT16_C(0x1000))     fputs(" rsvd12", stdout);
 | 
|---|
| 133 |     if (g_awIdentify[i] & UINT16_C(0x2000))     fputs(" ata2-standby-timer", stdout);
 | 
|---|
| 134 |     if (g_awIdentify[i] & UINT16_C(0x4000))     fputs(" rsvd14", stdout);
 | 
|---|
| 135 |     if (g_awIdentify[i] & UINT16_C(0x8000))     fputs(" rsvd15", stdout);
 | 
|---|
| 136 |     if (g_awIdentify[i] & UINT16_C(0x00ff))     printf(" vendor07=%#x", g_awIdentify[i] & UINT16_C(0x00ff));
 | 
|---|
| 137 |     putchar('\n');
 | 
|---|
| 138 | 
 | 
|---|
| 139 |     i = 50; printf("[%3u]=%#06x - capabilities:",                           i, g_awIdentify[i]);
 | 
|---|
| 140 |     if ((g_awIdentify[i] & UINT16_C(0xc000)) == UINT16_C(0x4000))
 | 
|---|
| 141 |     {
 | 
|---|
| 142 |         if (g_awIdentify[i] & 1)                fputs(" vendor-standby-timer-min", stdout);
 | 
|---|
| 143 |         if (g_awIdentify[i] & 2)                fputs(" obsolete1", stdout);
 | 
|---|
| 144 |         if (g_awIdentify[i] & UINT16_C(0x3ffc)) printf(" reserved=%#x", g_awIdentify[i] & UINT16_C(0x3ffc));
 | 
|---|
| 145 |         putchar('\n');
 | 
|---|
| 146 |     }
 | 
|---|
| 147 |     else
 | 
|---|
| 148 |         fputs("not present\n", stdout);
 | 
|---|
| 149 | 
 | 
|---|
| 150 |     printf("[ 51]=%#06x - obsolete PIO data transfer cycle timing mode %d", g_awIdentify[51], g_awIdentify[51] >> 8);
 | 
|---|
| 151 |     if (g_awIdentify[51] & UINT16_C(0x00ff))
 | 
|---|
| 152 |         printf(", vendor specific %#x\n", g_awIdentify[51] & UINT16_C(0x00ff));
 | 
|---|
| 153 |     else
 | 
|---|
| 154 |         putchar('\n');
 | 
|---|
| 155 | 
 | 
|---|
| 156 |     printf("[ 52]=%#06x - obsolete DMA data transfer cycle timing mode %d", g_awIdentify[52], g_awIdentify[52] >> 8);
 | 
|---|
| 157 |     if (g_awIdentify[52] & UINT16_C(0x00ff))
 | 
|---|
| 158 |         printf(", vendor specific %#x\n", g_awIdentify[52] & UINT16_C(0x00ff));
 | 
|---|
| 159 |     else
 | 
|---|
| 160 |         putchar('\n');
 | 
|---|
| 161 | 
 | 
|---|
| 162 |     printf("[ 53]=%#06x - ", g_awIdentify[53]);
 | 
|---|
| 163 |     if (g_awIdentify[53] & 1)
 | 
|---|
| 164 |         fputs(" words54-58-obsolete", stdout);
 | 
|---|
| 165 |     if (g_awIdentify[53] & 2)
 | 
|---|
| 166 |         fputs(" words64-70", stdout);
 | 
|---|
| 167 |     if (g_awIdentify[53] & 4)
 | 
|---|
| 168 |         fputs(" word88", stdout);
 | 
|---|
| 169 |     if (g_awIdentify[53] & UINT16_C(0x00f8))
 | 
|---|
| 170 |         printf(" rsvd=%#x", g_awIdentify[53] & UINT16_C(0x00f8));
 | 
|---|
| 171 |     printf(" free-fall-sensitivity=%#x\n", g_awIdentify[53] >> 8);
 | 
|---|
| 172 | 
 | 
|---|
| 173 |     i = 54; printf("[%3u]=%#06x - obsolete current logical cylinders         %d", i, g_awIdentify[i], g_awIdentify[i]);
 | 
|---|
| 174 |     if (g_awIdentify[54] > 16383)
 | 
|---|
| 175 |         fputs(" (high!)", stdout);
 | 
|---|
| 176 |     putchar('\n');
 | 
|---|
| 177 | 
 | 
|---|
| 178 |     i = 55; printf("[%3u]=%#06x - obsolete current logical heads             %d", i, g_awIdentify[i], g_awIdentify[i]);
 | 
|---|
| 179 |     if (g_awIdentify[55] > 16)
 | 
|---|
| 180 |         fputs(" (high!)", stdout);
 | 
|---|
| 181 |     putchar('\n');
 | 
|---|
| 182 | 
 | 
|---|
| 183 |     i = 56; printf("[%3u]=%#06x - obsolete current logical sectors per track %d", i, g_awIdentify[i], g_awIdentify[i]);
 | 
|---|
| 184 |     if (g_awIdentify[56] > 63)
 | 
|---|
| 185 |         fputs(" (high!)", stdout);
 | 
|---|
| 186 |     putchar('\n');
 | 
|---|
| 187 | 
 | 
|---|
| 188 |     printf("[ 57:58]     - obsolete current capacity in sectors %lu (%#lx)\n",
 | 
|---|
| 189 |            *(uint32_t *)&g_awIdentify[57], *(uint32_t *)&g_awIdentify[57]);
 | 
|---|
| 190 | 
 | 
|---|
| 191 |     printf("[ 59]=%#06x - sectors per DRQ READ/WRITE MULTIPLE ", g_awIdentify[59]);
 | 
|---|
| 192 |     if (g_awIdentify[59] & UINT16_C(0x0100))
 | 
|---|
| 193 |         printf("%d", g_awIdentify[59] & UINT16_C(0xff));
 | 
|---|
| 194 |     else
 | 
|---|
| 195 |         fputs(" not specified", stdout);
 | 
|---|
| 196 |     if (g_awIdentify[59] & UINT16_C(0xfe00))
 | 
|---|
| 197 |         printf(" rsvd=%#x", g_awIdentify[59] & UINT16_C(0xfe00));
 | 
|---|
| 198 |     putchar('\n');
 | 
|---|
| 199 | 
 | 
|---|
| 200 |     printf("[ 60:61]     - LBA28 user addressable sectors       %lu (%#lx)\n",
 | 
|---|
| 201 |            *(uint32_t *)&g_awIdentify[60], *(uint32_t *)&g_awIdentify[60]);
 | 
|---|
| 202 | 
 | 
|---|
| 203 |     printf("[ 62]=%#06x - obsolete single word DMA:", g_awIdentify[62]);
 | 
|---|
| 204 |     for (i = 0; i < 7; i++)
 | 
|---|
| 205 |         if (g_awIdentify[62] & (UINT16_C(0x0001) << i))
 | 
|---|
| 206 |         {
 | 
|---|
| 207 |             if (g_awIdentify[62] & (UINT16_C(0x0100) << i))
 | 
|---|
| 208 |                 printf(" swdma%d[active]", i);
 | 
|---|
| 209 |             else
 | 
|---|
| 210 |                 printf(" swdma%d", i);
 | 
|---|
| 211 |         }
 | 
|---|
| 212 |         else if (g_awIdentify[62] & (UINT16_C(0x0100) << i))
 | 
|---|
| 213 |             printf(" swdma%d-unsupported-but-active!", i);
 | 
|---|
| 214 |     putchar('\n');
 | 
|---|
| 215 | 
 | 
|---|
| 216 |     printf("[ 63]=%#06x - multiword DMA:           ", g_awIdentify[63]);
 | 
|---|
| 217 |     for (i = 0; i < 7; i++)
 | 
|---|
| 218 |         if (g_awIdentify[63] & (UINT16_C(0x0001) << i))
 | 
|---|
| 219 |         {
 | 
|---|
| 220 |             if (g_awIdentify[63] & (UINT16_C(0x0100) << i))
 | 
|---|
| 221 |                 printf(" mwdma%d[active]", i);
 | 
|---|
| 222 |             else
 | 
|---|
| 223 |                 printf(" mwdma%d", i);
 | 
|---|
| 224 |         }
 | 
|---|
| 225 |         else if (g_awIdentify[63] & (UINT16_C(0x0100) << i))
 | 
|---|
| 226 |             printf(" mwdma%d-unsupported-but-active!", i);
 | 
|---|
| 227 |     putchar('\n');
 | 
|---|
| 228 | 
 | 
|---|
| 229 |     printf("[ 64]=%#06x - Advanced PIO modes:      ", g_awIdentify[64]);
 | 
|---|
| 230 |     for (i = 0; i < 7; i++)
 | 
|---|
| 231 |         if (g_awIdentify[64] & (UINT16_C(0x0001) << i))
 | 
|---|
| 232 |             printf(" pio%d", i+3);
 | 
|---|
| 233 |     if (g_awIdentify[64] & UINT16_C(0xff00))
 | 
|---|
| 234 |         printf("  rsvd8-15=%#x", g_awIdentify[64] & UINT16_C(0xff00));
 | 
|---|
| 235 |     putchar('\n');
 | 
|---|
| 236 | 
 | 
|---|
| 237 |     printf("[ 65]=%#06x - minimum multiword DMA xfer cycle time per word     %d ns\n", g_awIdentify[65], g_awIdentify[65]);
 | 
|---|
| 238 |     printf("[ 66]=%#06x - recommended multiword DMA xfer cycle time per word %d ns\n", g_awIdentify[66], g_awIdentify[66]);
 | 
|---|
| 239 |     printf("[ 67]=%#06x - minimum PIO cycle time without IORDY               %d ns\n", g_awIdentify[67], g_awIdentify[67]);
 | 
|---|
| 240 |     printf("[ 68]=%#06x - minimum PIO cycle time with IORDY                  %d ns\n", g_awIdentify[68], g_awIdentify[68]);
 | 
|---|
| 241 |     printf("[ 69]=%#06x (reserved)\n", g_awIdentify[69]);
 | 
|---|
| 242 |     printf("[ 70]=%#06x (reserved)\n", g_awIdentify[70]);
 | 
|---|
| 243 |     printf("[ 71]=%#06x (reserved for identify packet device)\n", g_awIdentify[71]);
 | 
|---|
| 244 |     printf("[ 72]=%#06x (reserved for identify packet device)\n", g_awIdentify[72]);
 | 
|---|
| 245 |     printf("[ 73]=%#06x (reserved for identify packet device)\n", g_awIdentify[73]);
 | 
|---|
| 246 |     printf("[ 74]=%#06x (reserved for identify packet device)\n", g_awIdentify[74]);
 | 
|---|
| 247 | 
 | 
|---|
| 248 |     printf("[ 75]=%#06x - queue depth %d", g_awIdentify[75], (g_awIdentify[75] & 0x1f) + 1);
 | 
|---|
| 249 |     if (g_awIdentify[75] & UINT16_C(0xffe0))
 | 
|---|
| 250 |         printf(", rsvd5-15=%#x", g_awIdentify[75] & UINT16_C(0xffe0));
 | 
|---|
| 251 |     putchar('\n');
 | 
|---|
| 252 | 
 | 
|---|
| 253 |     printf("[ 76]=%#06x - SATA capabilities: ", g_awIdentify[76]);
 | 
|---|
| 254 |     if (!(g_awIdentify[76] & 1))
 | 
|---|
| 255 |     {
 | 
|---|
| 256 |         if (g_awIdentify[76] & UINT16_C(0x0002))
 | 
|---|
| 257 |             fputs(" gen1-1.5Gbps", stdout);
 | 
|---|
| 258 |         if (g_awIdentify[76] & UINT16_C(0x0004))
 | 
|---|
| 259 |             fputs(" gen2-3.0Gbps", stdout);
 | 
|---|
| 260 |         if (g_awIdentify[76] & UINT16_C(0x00f8))
 | 
|---|
| 261 |             printf(" rsvd3-7=%#x", g_awIdentify[76] & UINT16_C(0x00f8));
 | 
|---|
| 262 |         if (g_awIdentify[76] & UINT16_C(0x0100))
 | 
|---|
| 263 |             fputs(" ncq", stdout);
 | 
|---|
| 264 |         if (g_awIdentify[76] & UINT16_C(0x0200))
 | 
|---|
| 265 |             fputs(" host-power-management", stdout);
 | 
|---|
| 266 |         if (g_awIdentify[76] & UINT16_C(0x0400))
 | 
|---|
| 267 |             fputs(" phy-event-counters", stdout);
 | 
|---|
| 268 |         if (g_awIdentify[76] & UINT16_C(0xf800))
 | 
|---|
| 269 |             printf(" rsvd11-16=%#x", g_awIdentify[76] & UINT16_C(0xf800));
 | 
|---|
| 270 |         putchar('\n');
 | 
|---|
| 271 |     }
 | 
|---|
| 272 |     else
 | 
|---|
| 273 |         fputs(" probably not SATA\n", stdout);
 | 
|---|
| 274 | 
 | 
|---|
| 275 |     printf("[ 77]=%#06x (reserved for SATA)\n", g_awIdentify[77]);
 | 
|---|
| 276 | 
 | 
|---|
| 277 |     printf("[ 78]=%#06x - SATA features supported: ", g_awIdentify[78]);
 | 
|---|
| 278 |     if (!(g_awIdentify[78] & 1))
 | 
|---|
| 279 |     {
 | 
|---|
| 280 |         if (g_awIdentify[78] & UINT16_C(0x0002))
 | 
|---|
| 281 |             fputs(" non-zero-buffer-offsets", stdout);
 | 
|---|
| 282 |         if (g_awIdentify[78] & UINT16_C(0x0004))
 | 
|---|
| 283 |             fputs(" DMA-setup-auto-activation", stdout);
 | 
|---|
| 284 |         if (g_awIdentify[78] & UINT16_C(0x0008))
 | 
|---|
| 285 |             fputs(" device-power-management", stdout);
 | 
|---|
| 286 |         if (g_awIdentify[78] & UINT16_C(0x0010))
 | 
|---|
| 287 |             fputs(" in-order-data-delivery", stdout);
 | 
|---|
| 288 |         if (g_awIdentify[78] & UINT16_C(0x0020))
 | 
|---|
| 289 |             fputs(" rsvd5", stdout);
 | 
|---|
| 290 |         if (g_awIdentify[78] & UINT16_C(0x0040))
 | 
|---|
| 291 |             fputs(" software-settings-preservation", stdout);
 | 
|---|
| 292 |         if (g_awIdentify[78] & UINT16_C(0xff80))
 | 
|---|
| 293 |             printf(" rsvd7-15=%#x", g_awIdentify[78] & UINT16_C(0xff80));
 | 
|---|
| 294 |         putchar('\n');
 | 
|---|
| 295 |     }
 | 
|---|
| 296 |     else
 | 
|---|
| 297 |         fputs(" probably not SATA\n", stdout);
 | 
|---|
| 298 | 
 | 
|---|
| 299 |     printf("[ 79]=%#06x - SATA features enabled: ", g_awIdentify[79]);
 | 
|---|
| 300 |     if (!(g_awIdentify[79] & 1))
 | 
|---|
| 301 |     {
 | 
|---|
| 302 |         if (g_awIdentify[79] & UINT16_C(0x0002))
 | 
|---|
| 303 |             fputs(" non-zero-buffer-offsets", stdout);
 | 
|---|
| 304 |         if (g_awIdentify[79] & UINT16_C(0x0004))
 | 
|---|
| 305 |             fputs(" DMA-setup-auto-activation", stdout);
 | 
|---|
| 306 |         if (g_awIdentify[79] & UINT16_C(0x0008))
 | 
|---|
| 307 |             fputs(" device-power-management", stdout);
 | 
|---|
| 308 |         if (g_awIdentify[79] & UINT16_C(0x0010))
 | 
|---|
| 309 |             fputs(" in-order-data-delivery", stdout);
 | 
|---|
| 310 |         if (g_awIdentify[79] & UINT16_C(0x0020))
 | 
|---|
| 311 |             fputs(" rsvd5", stdout);
 | 
|---|
| 312 |         if (g_awIdentify[79] & UINT16_C(0x0040))
 | 
|---|
| 313 |             fputs(" software-settings-preservation", stdout);
 | 
|---|
| 314 |         if (g_awIdentify[79] & UINT16_C(0xff80))
 | 
|---|
| 315 |             printf(" rsvd7-15=%#x", g_awIdentify[79] & UINT16_C(0xff80));
 | 
|---|
| 316 |         putchar('\n');
 | 
|---|
| 317 |     }
 | 
|---|
| 318 |     else
 | 
|---|
| 319 |         fputs(" probably not SATA\n", stdout);
 | 
|---|
| 320 | 
 | 
|---|
| 321 |     printf("[ 80]=%#06x - Major version number:", g_awIdentify[80]);
 | 
|---|
| 322 |     if (g_awIdentify[80] != 0 && g_awIdentify[80] != UINT16_MAX)
 | 
|---|
| 323 |     {
 | 
|---|
| 324 |         for (i = 0; i < 15; i++)
 | 
|---|
| 325 |             if (g_awIdentify[80] & (UINT16_C(0x0001) << i))
 | 
|---|
| 326 |                 printf(" ata%u", i);
 | 
|---|
| 327 |         putchar('\n');
 | 
|---|
| 328 |     }
 | 
|---|
| 329 |     else
 | 
|---|
| 330 |         fputs(" not specified\n", stdout);
 | 
|---|
| 331 | 
 | 
|---|
| 332 |     printf("[ 81]=%#06x - Minor version number: %d\n", g_awIdentify[81], g_awIdentify[81]);
 | 
|---|
| 333 | 
 | 
|---|
| 334 |     printf("[ 82]=%#06x - Supports: ", g_awIdentify[82]);
 | 
|---|
| 335 |     if ((g_awIdentify[83] & UINT16_C(0xc000)) == UINT16_C(0x4000)) /* yes, 83; see 7.16.7.38 in ata8. */
 | 
|---|
| 336 |     {
 | 
|---|
| 337 |         if (g_awIdentify[82] & UINT16_C(0x0001))    fputs(" smart", stdout);
 | 
|---|
| 338 |         if (g_awIdentify[82] & UINT16_C(0x0002))    fputs(" security", stdout);
 | 
|---|
| 339 |         if (g_awIdentify[82] & UINT16_C(0x0004))    fputs(" obsolete2", stdout);
 | 
|---|
| 340 |         if (g_awIdentify[82] & UINT16_C(0x0008))    fputs(" mand-power-management", stdout);
 | 
|---|
| 341 |         if (!(g_awIdentify[82] & UINT16_C(0x0010))) fputs(" no-packet", stdout);
 | 
|---|
| 342 |         if (g_awIdentify[82] & UINT16_C(0x0020))    fputs(" volatile-write-cache", stdout);
 | 
|---|
| 343 |         if (g_awIdentify[82] & UINT16_C(0x0040))    fputs(" look-ahead", stdout);
 | 
|---|
| 344 |         if (g_awIdentify[82] & UINT16_C(0x0080))    fputs(" release-intr", stdout);
 | 
|---|
| 345 |         if (g_awIdentify[82] & UINT16_C(0x0100))    fputs(" service-intr", stdout);
 | 
|---|
| 346 |         if (!(g_awIdentify[82] & UINT16_C(0x0200))) fputs(" no-device-reset", stdout);
 | 
|---|
| 347 |         if (g_awIdentify[82] & UINT16_C(0x0400))    fputs(" hpa", stdout);
 | 
|---|
| 348 |         if (g_awIdentify[82] & UINT16_C(0x0800))    fputs(" obsolete11", stdout);
 | 
|---|
| 349 |         if (g_awIdentify[82] & UINT16_C(0x1000))    fputs(" write-buffer", stdout);
 | 
|---|
| 350 |         if (g_awIdentify[82] & UINT16_C(0x2000))    fputs(" read-buffer", stdout);
 | 
|---|
| 351 |         if (g_awIdentify[82] & UINT16_C(0x4000))    fputs(" nop", stdout);
 | 
|---|
| 352 |         if (g_awIdentify[82] & UINT16_C(0x8000))    fputs(" obsolete15", stdout);
 | 
|---|
| 353 |         putchar('\n');
 | 
|---|
| 354 |     }
 | 
|---|
| 355 |     else
 | 
|---|
| 356 |         fputs(" not specified\n", stdout);
 | 
|---|
| 357 | 
 | 
|---|
| 358 |     printf("[ 83]=%#06x - Supports: ", g_awIdentify[83]);
 | 
|---|
| 359 |     if ((g_awIdentify[83] & UINT16_C(0xc000)) == UINT16_C(0x4000))
 | 
|---|
| 360 |     {
 | 
|---|
| 361 | 
 | 
|---|
| 362 |         if (g_awIdentify[83] & UINT16_C(0x0001))    fputs(" download-microcode", stdout);
 | 
|---|
| 363 |         if (g_awIdentify[83] & UINT16_C(0x0002))    fputs(" tcq", stdout);
 | 
|---|
| 364 |         if (g_awIdentify[83] & UINT16_C(0x0004))    fputs(" cfa", stdout);
 | 
|---|
| 365 |         if (g_awIdentify[83] & UINT16_C(0x0008))    fputs(" apm", stdout);
 | 
|---|
| 366 |         if (g_awIdentify[83] & UINT16_C(0x0010))    fputs(" obsolete4", stdout);
 | 
|---|
| 367 |         if (g_awIdentify[83] & UINT16_C(0x0020))    fputs(" puis", stdout);
 | 
|---|
| 368 |         if (g_awIdentify[83] & UINT16_C(0x0040))    fputs(" set-features-spin-up", stdout);
 | 
|---|
| 369 |         if (g_awIdentify[83] & UINT16_C(0x0080))    fputs(" reserved7", stdout);
 | 
|---|
| 370 |         if (g_awIdentify[83] & UINT16_C(0x0100))    fputs(" set-max-security", stdout);
 | 
|---|
| 371 |         if (g_awIdentify[83] & UINT16_C(0x0200))    fputs(" aam", stdout);
 | 
|---|
| 372 |         if (g_awIdentify[83] & UINT16_C(0x0400))    fputs(" lba48", stdout);
 | 
|---|
| 373 |         if (g_awIdentify[83] & UINT16_C(0x0800))    fputs(" dco", stdout);
 | 
|---|
| 374 |         if (g_awIdentify[83] & UINT16_C(0x1000))    fputs(" flush-cache", stdout);
 | 
|---|
| 375 |         if (g_awIdentify[83] & UINT16_C(0x2000))    fputs(" flush-cache-ext", stdout);
 | 
|---|
| 376 |         putchar('\n');
 | 
|---|
| 377 |     }
 | 
|---|
| 378 |     else
 | 
|---|
| 379 |         fputs(" not specified\n", stdout);
 | 
|---|
| 380 | 
 | 
|---|
| 381 |     printf("[ 84]=%#06x - Supports: ", g_awIdentify[84]);
 | 
|---|
| 382 |     if ((g_awIdentify[84] & UINT16_C(0xc000)) == UINT16_C(0x4000))
 | 
|---|
| 383 |     {
 | 
|---|
| 384 |         if (g_awIdentify[84] & UINT16_C(0x0001))    fputs(" smart-err-log", stdout);
 | 
|---|
| 385 |         if (g_awIdentify[84] & UINT16_C(0x0002))    fputs(" smart-self-test", stdout);
 | 
|---|
| 386 |         if (g_awIdentify[84] & UINT16_C(0x0004))    fputs(" media-serial-no", stdout);
 | 
|---|
| 387 |         if (g_awIdentify[84] & UINT16_C(0x0008))    fputs(" media-card-passthru", stdout);
 | 
|---|
| 388 |         if (g_awIdentify[84] & UINT16_C(0x0010))    fputs(" streaming", stdout);
 | 
|---|
| 389 |         if (g_awIdentify[84] & UINT16_C(0x0020))    fputs(" gpl", stdout);
 | 
|---|
| 390 |         if (g_awIdentify[84] & UINT16_C(0x0040))    fputs(" write-dma-mult-fua-ext", stdout);
 | 
|---|
| 391 |         if (g_awIdentify[84] & UINT16_C(0x0080))    fputs(" write-dma-queued-fua-ext", stdout);
 | 
|---|
| 392 |         if (g_awIdentify[84] & UINT16_C(0x0100))    fputs(" 64-bit-world-wide-name", stdout);
 | 
|---|
| 393 |         if (g_awIdentify[84] & UINT16_C(0x0200))    fputs(" obsolete9", stdout);
 | 
|---|
| 394 |         if (g_awIdentify[84] & UINT16_C(0x0400))    fputs(" obsolete10", stdout);
 | 
|---|
| 395 |         if (g_awIdentify[84] & UINT16_C(0x0800))    fputs(" reserved11", stdout);
 | 
|---|
| 396 |         if (g_awIdentify[84] & UINT16_C(0x1000))    fputs(" reserved12", stdout);
 | 
|---|
| 397 |         if (g_awIdentify[84] & UINT16_C(0x2000))    fputs(" idle-immediate-unload", stdout);
 | 
|---|
| 398 |         putchar('\n');
 | 
|---|
| 399 |     }
 | 
|---|
| 400 |     else
 | 
|---|
| 401 |         fputs(" not specified\n", stdout);
 | 
|---|
| 402 | 
 | 
|---|
| 403 |     printf("[ 85]=%#06x - Enabled:", g_awIdentify[85]);
 | 
|---|
| 404 |     if (g_awIdentify[85] & UINT16_C(0x0001))    fputs(" smart", stdout);
 | 
|---|
| 405 |     if (g_awIdentify[85] & UINT16_C(0x0002))    fputs(" security", stdout);
 | 
|---|
| 406 |     if (g_awIdentify[85] & UINT16_C(0x0020))    fputs(" volatile-write-cache", stdout);
 | 
|---|
| 407 |     if (g_awIdentify[85] & UINT16_C(0x0040))    fputs(" look-ahead", stdout);
 | 
|---|
| 408 |     if (g_awIdentify[85] & UINT16_C(0x0080))    fputs(" release-intr", stdout);
 | 
|---|
| 409 |     if (g_awIdentify[85] & UINT16_C(0x0100))    fputs(" service-intr", stdout);
 | 
|---|
| 410 |     fputs(" Supported:", stdout);
 | 
|---|
| 411 |     if (g_awIdentify[85] & UINT16_C(0x0004))    fputs(" obsolete2", stdout);
 | 
|---|
| 412 |     if (g_awIdentify[85] & UINT16_C(0x0008))    fputs(" mand-power-management", stdout);
 | 
|---|
| 413 |     if (!(g_awIdentify[85] & UINT16_C(0x0010))) fputs(" no-packet", stdout);
 | 
|---|
| 414 |     if (!(g_awIdentify[85] & UINT16_C(0x0200))) fputs(" no-device-reset", stdout);
 | 
|---|
| 415 |     if (g_awIdentify[85] & UINT16_C(0x0400))    fputs(" hpa", stdout);
 | 
|---|
| 416 |     if (g_awIdentify[85] & UINT16_C(0x0800))    fputs(" obsolete11", stdout);
 | 
|---|
| 417 |     if (g_awIdentify[85] & UINT16_C(0x1000))    fputs(" write-buffer", stdout);
 | 
|---|
| 418 |     if (g_awIdentify[85] & UINT16_C(0x2000))    fputs(" read-buffer", stdout);
 | 
|---|
| 419 |     if (g_awIdentify[85] & UINT16_C(0x4000))    fputs(" nop", stdout);
 | 
|---|
| 420 |     if (g_awIdentify[85] & UINT16_C(0x8000))    fputs(" obsolete15", stdout);
 | 
|---|
| 421 |     putchar('\n');
 | 
|---|
| 422 | 
 | 
|---|
| 423 |     if ((g_awIdentify[83] & UINT16_C(0xc000)) == UINT16_C(0x4000)) /* yeah, 83. */
 | 
|---|
| 424 |     {
 | 
|---|
| 425 |         printf("[ 86]=%#06x - Enabled: ", g_awIdentify[86]);
 | 
|---|
| 426 |         if (g_awIdentify[86] & UINT16_C(0x0008))    fputs(" apm", stdout);
 | 
|---|
| 427 |         if (g_awIdentify[86] & UINT16_C(0x0020))    fputs(" puis", stdout);
 | 
|---|
| 428 |         if (g_awIdentify[86] & UINT16_C(0x0100))    fputs(" set-max-security", stdout);
 | 
|---|
| 429 |         if (g_awIdentify[86] & UINT16_C(0x0200))    fputs(" aam", stdout);
 | 
|---|
| 430 |         fputs(" Supported:", stdout);
 | 
|---|
| 431 |         if (g_awIdentify[86] & UINT16_C(0x0001))    fputs(" download-microcode", stdout);
 | 
|---|
| 432 |         if (g_awIdentify[86] & UINT16_C(0x0002))    fputs(" tcq", stdout);
 | 
|---|
| 433 |         if (g_awIdentify[86] & UINT16_C(0x0004))    fputs(" cfa", stdout);
 | 
|---|
| 434 |         if (g_awIdentify[86] & UINT16_C(0x0010))    fputs(" obsolete4", stdout);
 | 
|---|
| 435 |         if (g_awIdentify[86] & UINT16_C(0x0040))    fputs(" set-features-spin-up", stdout);
 | 
|---|
| 436 |         if (g_awIdentify[86] & UINT16_C(0x0080))    fputs(" reserved7", stdout);
 | 
|---|
| 437 |         if (g_awIdentify[86] & UINT16_C(0x0400))    fputs(" lba48", stdout);
 | 
|---|
| 438 |         if (g_awIdentify[86] & UINT16_C(0x0800))    fputs(" dco", stdout);
 | 
|---|
| 439 |         if (g_awIdentify[86] & UINT16_C(0x1000))    fputs(" flush-cache", stdout);
 | 
|---|
| 440 |         if (g_awIdentify[86] & UINT16_C(0x2000))    fputs(" flush-cache-ext", stdout);
 | 
|---|
| 441 |         if (g_awIdentify[86] & UINT16_C(0x4000))    fputs(" reserved14", stdout);
 | 
|---|
| 442 |         if (g_awIdentify[86] & UINT16_C(0x8000))    fputs(" words119-120", stdout);
 | 
|---|
| 443 |         putchar('\n');
 | 
|---|
| 444 |     }
 | 
|---|
| 445 |     else
 | 
|---|
| 446 |         printf("[ 86]=%#06x - Enabled & Supports: not specified\n", g_awIdentify[86]);
 | 
|---|
| 447 | 
 | 
|---|
| 448 |     printf("[ 87]=%#06x - Enabled: ", g_awIdentify[87]);
 | 
|---|
| 449 |     if ((g_awIdentify[87] & UINT16_C(0xc000)) == UINT16_C(0x4000))
 | 
|---|
| 450 |     {
 | 
|---|
| 451 |         if (g_awIdentify[87] & UINT16_C(0x0004))    fputs(" media-serial-no-valid", stdout);
 | 
|---|
| 452 |         fputs(" Supported:", stdout);
 | 
|---|
| 453 |         if (g_awIdentify[87] & UINT16_C(0x0001))    fputs(" smart-err-log", stdout);
 | 
|---|
| 454 |         if (g_awIdentify[87] & UINT16_C(0x0002))    fputs(" smart-self-test", stdout);
 | 
|---|
| 455 |         if (g_awIdentify[87] & UINT16_C(0x0008))    fputs(" media-card-passthru", stdout);
 | 
|---|
| 456 |         if (g_awIdentify[87] & UINT16_C(0x0010))    fputs(" obsolete4", stdout);
 | 
|---|
| 457 |         if (g_awIdentify[87] & UINT16_C(0x0020))    fputs(" gpl", stdout);
 | 
|---|
| 458 |         if (g_awIdentify[87] & UINT16_C(0x0040))    fputs(" write-dma-mult-fua-ext", stdout);
 | 
|---|
| 459 |         if (g_awIdentify[87] & UINT16_C(0x0080))    fputs(" write-dma-queued-fua-ext", stdout);
 | 
|---|
| 460 |         if (g_awIdentify[87] & UINT16_C(0x0100))    fputs(" 64-bit-world-wide-name", stdout);
 | 
|---|
| 461 |         if (g_awIdentify[87] & UINT16_C(0x0200))    fputs(" obsolete9", stdout);
 | 
|---|
| 462 |         if (g_awIdentify[87] & UINT16_C(0x0400))    fputs(" obsolete10", stdout);
 | 
|---|
| 463 |         if (g_awIdentify[87] & UINT16_C(0x0800))    fputs(" reserved11", stdout);
 | 
|---|
| 464 |         if (g_awIdentify[87] & UINT16_C(0x1000))    fputs(" reserved12", stdout);
 | 
|---|
| 465 |         if (g_awIdentify[87] & UINT16_C(0x2000))    fputs(" idle-immediate-unload", stdout);
 | 
|---|
| 466 |         putchar('\n');
 | 
|---|
| 467 |     }
 | 
|---|
| 468 |     else
 | 
|---|
| 469 |         fputs(" not specified\n", stdout);
 | 
|---|
| 470 | 
 | 
|---|
| 471 |     printf("[ 88]=%#06x - Ultra DMA support: ", g_awIdentify[88]);
 | 
|---|
| 472 |     for (i = 0; i < 8; i++)
 | 
|---|
| 473 |         if (g_awIdentify[88] & (UINT16_C(0x0001) << i))
 | 
|---|
| 474 |             printf(" <=udma%d", i);
 | 
|---|
| 475 |     fputs(" Selected: ", stdout);
 | 
|---|
| 476 |     for (i = 0; i < 8; i++)
 | 
|---|
| 477 |         if (g_awIdentify[88] & (UINT16_C(0x0100) << i))
 | 
|---|
| 478 |             printf(" udma%d", i);
 | 
|---|
| 479 |     putchar('\n');
 | 
|---|
| 480 | 
 | 
|---|
| 481 |     printf("[ 89]=%#06x - time for normal erase mode security erase unit: %d\n",
 | 
|---|
| 482 |            g_awIdentify[88], g_awIdentify[89] & UINT16_C(0x00ff));
 | 
|---|
| 483 |     printf("[ 90]=%#06x - time for enh.   erase mode security erase unit: %d\n",
 | 
|---|
| 484 |            g_awIdentify[90], g_awIdentify[90] & UINT16_C(0x00ff));
 | 
|---|
| 485 |     printf("[ 91]=%#06x - current APM level value: %d\n", g_awIdentify[91], g_awIdentify[91]);
 | 
|---|
| 486 |     printf("[ 92]=%#06x - master password ID:      %d\n", g_awIdentify[92], g_awIdentify[92]);
 | 
|---|
| 487 | 
 | 
|---|
| 488 |     printf("[ 93]=%#06x - hardware reset result:", g_awIdentify[93], g_awIdentify[93]);
 | 
|---|
| 489 |     if ((g_awIdentify[93] & UINT16_C(0xc000)) == UINT16_C(0x4000))
 | 
|---|
| 490 |     {
 | 
|---|
| 491 |         static const char * const s_apszDevNum[4] = { " rsvd0", " jumper", " csel", " other" };
 | 
|---|
| 492 |         if (g_awIdentify[93] & UINT16_C(0x00ff))
 | 
|---|
| 493 |         {
 | 
|---|
| 494 |             fputs(" dev0: ", stdout);
 | 
|---|
| 495 |             fputs(s_apszDevNum[(g_awIdentify[93] >> 1) & 3], stdout);
 | 
|---|
| 496 |             if (!(g_awIdentify[93] & UINT16_C(0x0001))) fputs(" bit0-clear!", stdout);
 | 
|---|
| 497 |             fputs(g_awIdentify[93] & UINT16_C(0x0008) ? "diag-passed" : "diag-failed!", stdout);
 | 
|---|
| 498 |             fputs(g_awIdentify[93] & UINT16_C(0x0010) ? "PDIGA-" : "no-PDIAG-", stdout);
 | 
|---|
| 499 |             fputs(g_awIdentify[93] & UINT16_C(0x0020) ? "DASP-" : "no-DASP-", stdout);
 | 
|---|
| 500 |             fputs(g_awIdentify[93] & UINT16_C(0x0040) ? "responds-when-dev1-selected" : "dev1-can-be-selected", stdout);
 | 
|---|
| 501 |             if (g_awIdentify[93] & UINT16_C(0x0080))    fputs(" rsvd7!", stdout);
 | 
|---|
| 502 |         }
 | 
|---|
| 503 |         if (g_awIdentify[93] & UINT16_C(0x0f00))
 | 
|---|
| 504 |         {
 | 
|---|
| 505 |             fputs(" dev1: ", stdout);
 | 
|---|
| 506 |             fputs(s_apszDevNum[(g_awIdentify[93] >> 9) & 3], stdout);
 | 
|---|
| 507 |             fputs(g_awIdentify[93] & UINT16_C(0x0800) ? "PDIGA-" : "no-PDIAG-", stdout);
 | 
|---|
| 508 |             if (!(g_awIdentify[93] & UINT16_C(0x0100))) fputs(" bit8-clear!", stdout);
 | 
|---|
| 509 |             if (g_awIdentify[93] & UINT16_C(0x1000))    fputs(" rsvd12!", stdout);
 | 
|---|
| 510 |         }
 | 
|---|
| 511 |         fputs(g_awIdentify[93] & UINT16_C(0x2000) ? "CBLID-below-ViL" : "CBLID-above-ViHB", stdout);
 | 
|---|
| 512 |         putchar('\n');
 | 
|---|
| 513 |     }
 | 
|---|
| 514 |     else
 | 
|---|
| 515 |         fputs(" not specified\n", stdout);
 | 
|---|
| 516 | 
 | 
|---|
| 517 |     printf("[ 94]=%#06x - recommended AAM value: %#x  current: %#x\n",
 | 
|---|
| 518 |            g_awIdentify[94], g_awIdentify[94] >> 8, g_awIdentify[94] & UINT16_C(0x00ff));
 | 
|---|
| 519 |     printf("[ 95]=%#06x - stream minimum request size:       %d\n", g_awIdentify[95], g_awIdentify[95]);
 | 
|---|
| 520 |     printf("[ 96]=%#06x - streaming transfer time, DMA:      %d\n", g_awIdentify[96], g_awIdentify[96]);
 | 
|---|
| 521 |     printf("[ 97]=%#06x - streaming access latency, DMA+PIO: %d\n", g_awIdentify[97], g_awIdentify[97]);
 | 
|---|
| 522 |     printf("[ 98:99]     - streaming performance granularity: %ld (%#lx)\n",
 | 
|---|
| 523 |            *(uint32_t *)&g_awIdentify[98], *(uint32_t *)&g_awIdentify[98]);
 | 
|---|
| 524 |     printf("[100:103]    - LBA48 user addressable sectors:  %lld (%#llx)\n",
 | 
|---|
| 525 |            *(uint64_t *)&g_awIdentify[100], *(uint64_t *)&g_awIdentify[100]);
 | 
|---|
| 526 |     printf("[104]=%#06x - streaming transfer time, PIO:      %d\n", g_awIdentify[104], g_awIdentify[104]);
 | 
|---|
| 527 |     printf("[105]=%#06x (reserved)\n", g_awIdentify[105]);
 | 
|---|
| 528 |     if ((g_awIdentify[106] & UINT16_C(0xc000)) == UINT16_C(0x4000))
 | 
|---|
| 529 |     {
 | 
|---|
| 530 |         printf("[106]=%#06x - Physical/logical sector size: %u logical per physical",
 | 
|---|
| 531 |                g_awIdentify[106], 1U << (g_awIdentify[106] & 0xfU));
 | 
|---|
| 532 |         if (g_awIdentify[106] & UINT16_C(0x1000))    fputs(", more-than-512-byte-logical", stdout);
 | 
|---|
| 533 |         if (g_awIdentify[106] & UINT16_C(0x2000))    fputs(", multiple-logical-per-physical", stdout);
 | 
|---|
| 534 |         if (g_awIdentify[106] & UINT16_C(0x0ff0))    printf("rsvd4-11=%#x", g_awIdentify[106] & UINT16_C(0x0ff0));
 | 
|---|
| 535 |         putchar('\n');
 | 
|---|
| 536 |     }
 | 
|---|
| 537 |     else
 | 
|---|
| 538 |         printf("[106]=%#06x - Physical/logical sector size: not specified", g_awIdentify[106]);
 | 
|---|
| 539 | 
 | 
|---|
| 540 |     printf("[107]=%#06x - Inter-seek delay for acoustic testing\n", g_awIdentify[107]);
 | 
|---|
| 541 |     printf("[108:111]    - World wide name:     %#llx\n", *(uint64_t *)&g_awIdentify[108]);
 | 
|---|
| 542 |     for (i = 112; i <= 116; i++)
 | 
|---|
| 543 |         printf("[%u]=%#06x (reserved)\n", i, g_awIdentify[i]);
 | 
|---|
| 544 |     printf("[117:118]    - Logical sector size: %lu bytes (%#lx)\n",
 | 
|---|
| 545 |            *(uint32_t *)&g_awIdentify[117], *(uint32_t *)&g_awIdentify[117]);
 | 
|---|
| 546 |     for (i = 119; i <= 120; i++)
 | 
|---|
| 547 |         printf("[%u]=%#06x - todo\n", i, g_awIdentify[i]);
 | 
|---|
| 548 |     for (i = 121; i <= 126; i++)
 | 
|---|
| 549 |         printf("[%u]=%#06x (reserved)\n", i, g_awIdentify[i]);
 | 
|---|
| 550 |     printf("[127]=%#06x - obsolete\n", g_awIdentify[127]);
 | 
|---|
| 551 |     printf("[128]=%#06x - security status - todo\n", g_awIdentify[128]);
 | 
|---|
| 552 |     for (i = 129; i <= 159; i++)
 | 
|---|
| 553 |         printf("[%u]=%#06x - vendor specific\n", i, g_awIdentify[i]);
 | 
|---|
| 554 |     printf("[160]=%#06x - CFA power mode - todo\n", g_awIdentify[160]);
 | 
|---|
| 555 |     for (i = 161; i <= 167; i++)
 | 
|---|
| 556 |         printf("[%u]=%#06x (reserved for the CompactFlash guys)\n", i, g_awIdentify[i]);
 | 
|---|
| 557 |     printf("[168]=%#06x - Device nominal form factor - todo\n", g_awIdentify[168]);
 | 
|---|
| 558 |     for (i = 169; i <= 175; i++)
 | 
|---|
| 559 |         printf("[%u]=%#06x (reserved)\n", i, g_awIdentify[i]);
 | 
|---|
| 560 |     AtaPrintIdString("[176:205]    - current media string: ", &g_awIdentify[176], 30, "\n");
 | 
|---|
| 561 |     printf("[206]=%#06x - SCT command transport - todo\n", g_awIdentify[206]);
 | 
|---|
| 562 |     printf("[207]=%#06x (reserved for CE-ATA)\n", g_awIdentify[207]);
 | 
|---|
| 563 |     printf("[208]=%#06x (reserved for CE-ATA)\n", g_awIdentify[208]);
 | 
|---|
| 564 |     printf("[209]=%#06x - logical block alignment - todo\n", g_awIdentify[209]);
 | 
|---|
| 565 |     printf("[210:211]    - Write-Read-Verify sector count mode 3: %lu (%#lx)\n",
 | 
|---|
| 566 |            *(uint32_t *)&g_awIdentify[210], *(uint32_t *)&g_awIdentify[210]);
 | 
|---|
| 567 |     printf("[212:213]    - Write-Read-Verify sector count mode 2: %lu (%#lx)\n",
 | 
|---|
| 568 |            *(uint32_t *)&g_awIdentify[212], *(uint32_t *)&g_awIdentify[212]);
 | 
|---|
| 569 |     printf("[214]=%#06x - NV cache capabilities - todo\n", g_awIdentify[214]);
 | 
|---|
| 570 |     printf("[215:216]    - NV cache size: %lu logical blocks (%#lx)\n",
 | 
|---|
| 571 |            *(uint32_t *)&g_awIdentify[215], *(uint32_t *)&g_awIdentify[215]);
 | 
|---|
| 572 |     printf("[217]=%#06x - Nominal media rotation rate: %u\n", g_awIdentify[217], g_awIdentify[217]);
 | 
|---|
| 573 |     printf("[218]=%#06x (reserved)\n", g_awIdentify[218]);
 | 
|---|
| 574 |     printf("[219]=%#06x - NV cache options - todo\n", g_awIdentify[219]);
 | 
|---|
| 575 |     printf("[220]=%#06x - Current write-read-verify mode - todo\n", g_awIdentify[220]);
 | 
|---|
| 576 |     printf("[221]=%#06x (reserved)\n", g_awIdentify[221]);
 | 
|---|
| 577 |     printf("[222]=%#06x - Transport major version number - todo\n", g_awIdentify[222]);
 | 
|---|
| 578 |     printf("[223]=%#06x - Transport minor version number: %u\n", g_awIdentify[223], g_awIdentify[223]);
 | 
|---|
| 579 |     for (i = 224; i <= 233; i++)
 | 
|---|
| 580 |         printf("[%u]=%#06x (reserved for CE-ATA)\n", i, g_awIdentify[i]);
 | 
|---|
| 581 |     printf("[234]=%#06x - Min 512 bytes blocks per download microcode mode 3: %u\n", g_awIdentify[234], g_awIdentify[234]);
 | 
|---|
| 582 |     printf("[235]=%#06x - Max 512 bytes blocks per download microcode mode 3: %u\n", g_awIdentify[235], g_awIdentify[235]);
 | 
|---|
| 583 |     for (i = 236; i <= 254; i++)
 | 
|---|
| 584 |         printf("[%u]=%#06x (reserved)\n", i, g_awIdentify[i]);
 | 
|---|
| 585 | 
 | 
|---|
| 586 |     printf("[255]=%#06x - Integrity word: ", g_awIdentify[255]);
 | 
|---|
| 587 |     bCksum = AtaCalcIdChecksum(g_awIdentify);
 | 
|---|
| 588 |     if ((g_awIdentify[255] & UINT16_C(0xff)) == UINT16_C(0x00A5) /* ATA-8 7.16.7.88 */)
 | 
|---|
| 589 |     {
 | 
|---|
| 590 |         if ((g_awIdentify[255] >> 8) == bCksum)
 | 
|---|
| 591 |             printf("cksum=%#x (correct)\n", g_awIdentify[255] >> 8);
 | 
|---|
| 592 |         else
 | 
|---|
| 593 |             printf("cksum=%#x bad!, correct=%#x\n", g_awIdentify[255] >> 8, bCksum);
 | 
|---|
| 594 |     }
 | 
|---|
| 595 |     else
 | 
|---|
| 596 |         printf(" no checksum (should be %#x)\n", bCksum);
 | 
|---|
| 597 | 
 | 
|---|
| 598 |     return 0;
 | 
|---|
| 599 | }
 | 
|---|
| 600 | 
 | 
|---|