OSDN Git Service

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