9738620fd86cb80b5971bec9d4d686613a70de6a
[external/busybox.git] / util-linux / miscutils / hdparm.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * hdparm implementation for busybox
4  *
5  * Copyright (C) [2003] by [Matteo Croce] <3297627799@wind.it>
6  * Hacked by Tito <farmatito@tiscali.it> for size optimization.
7  *
8  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
9  *
10  * This program is based on the source code of hdparm: see below...
11  * hdparm.c - Command line interface to get/set hard disk parameters
12  *          - by Mark Lord (C) 1994-2002 -- freely distributable
13  */
14 #include "libbb.h"
15 /* must be _after_ libbb.h: */
16 #include <linux/hdreg.h>
17 #include <sys/mount.h>
18 #if !defined(BLKGETSIZE64)
19 # define BLKGETSIZE64 _IOR(0x12,114,size_t)
20 #endif
21
22 /* device types */
23 /* ------------ */
24 #define NO_DEV                  0xffff
25 #define ATA_DEV                 0x0000
26 #define ATAPI_DEV               0x0001
27
28 /* word definitions */
29 /* ---------------- */
30 #define GEN_CONFIG              0   /* general configuration */
31 #define LCYLS                   1   /* number of logical cylinders */
32 #define CONFIG                  2   /* specific configuration */
33 #define LHEADS                  3   /* number of logical heads */
34 #define TRACK_BYTES             4   /* number of bytes/track (ATA-1) */
35 #define SECT_BYTES              5   /* number of bytes/sector (ATA-1) */
36 #define LSECTS                  6   /* number of logical sectors/track */
37 #define START_SERIAL            10  /* ASCII serial number */
38 #define LENGTH_SERIAL           10  /* 10 words (20 bytes or characters) */
39 #define BUF_TYPE                20  /* buffer type (ATA-1) */
40 #define BUFFER__SIZE            21  /* buffer size (ATA-1) */
41 #define RW_LONG                 22  /* extra bytes in R/W LONG cmd ( < ATA-4)*/
42 #define START_FW_REV            23  /* ASCII firmware revision */
43 #define LENGTH_FW_REV            4  /*  4 words (8 bytes or characters) */
44 #define START_MODEL             27  /* ASCII model number */
45 #define LENGTH_MODEL            20  /* 20 words (40 bytes or characters) */
46 #define SECTOR_XFER_MAX         47  /* r/w multiple: max sectors xfered */
47 #define DWORD_IO                48  /* can do double-word IO (ATA-1 only) */
48 #define CAPAB_0                 49  /* capabilities */
49 #define CAPAB_1                 50
50 #define PIO_MODE                51  /* max PIO mode supported (obsolete)*/
51 #define DMA_MODE                52  /* max Singleword DMA mode supported (obs)*/
52 #define WHATS_VALID             53  /* what fields are valid */
53 #define LCYLS_CUR               54  /* current logical cylinders */
54 #define LHEADS_CUR              55  /* current logical heads */
55 #define LSECTS_CUR              56  /* current logical sectors/track */
56 #define CAPACITY_LSB            57  /* current capacity in sectors */
57 #define CAPACITY_MSB            58
58 #define SECTOR_XFER_CUR         59  /* r/w multiple: current sectors xfered */
59 #define LBA_SECTS_LSB           60  /* LBA: total number of user */
60 #define LBA_SECTS_MSB           61  /*      addressable sectors */
61 #define SINGLE_DMA              62  /* singleword DMA modes */
62 #define MULTI_DMA               63  /* multiword DMA modes */
63 #define ADV_PIO_MODES           64  /* advanced PIO modes supported */
64                                     /* multiword DMA xfer cycle time: */
65 #define DMA_TIME_MIN            65  /*   - minimum */
66 #define DMA_TIME_NORM           66  /*   - manufacturer's recommended */
67                                     /* minimum PIO xfer cycle time: */
68 #define PIO_NO_FLOW             67  /*   - without flow control */
69 #define PIO_FLOW                68  /*   - with IORDY flow control */
70 #define PKT_REL                 71  /* typical #ns from PKT cmd to bus rel */
71 #define SVC_NBSY                72  /* typical #ns from SERVICE cmd to !BSY */
72 #define CDR_MAJOR               73  /* CD ROM: major version number */
73 #define CDR_MINOR               74  /* CD ROM: minor version number */
74 #define QUEUE_DEPTH             75  /* queue depth */
75 #define MAJOR                   80  /* major version number */
76 #define MINOR                   81  /* minor version number */
77 #define CMDS_SUPP_0             82  /* command/feature set(s) supported */
78 #define CMDS_SUPP_1             83
79 #define CMDS_SUPP_2             84
80 #define CMDS_EN_0               85  /* command/feature set(s) enabled */
81 #define CMDS_EN_1               86
82 #define CMDS_EN_2               87
83 #define ULTRA_DMA               88  /* ultra DMA modes */
84                                     /* time to complete security erase */
85 #define ERASE_TIME              89  /*   - ordinary */
86 #define ENH_ERASE_TIME          90  /*   - enhanced */
87 #define ADV_PWR                 91  /* current advanced power management level
88                                        in low byte, 0x40 in high byte. */
89 #define PSWD_CODE               92  /* master password revision code */
90 #define HWRST_RSLT              93  /* hardware reset result */
91 #define ACOUSTIC                94  /* acoustic mgmt values ( >= ATA-6) */
92 #define LBA_LSB                 100 /* LBA: maximum.  Currently only 48 */
93 #define LBA_MID                 101 /*      bits are used, but addr 103 */
94 #define LBA_48_MSB              102 /*      has been reserved for LBA in */
95 #define LBA_64_MSB              103 /*      the future. */
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 INTEGRITY               255 /* integrity word */
104
105 /* bit definitions within the words */
106 /* -------------------------------- */
107
108 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
109 #define VALID                   0xc000
110 #define VALID_VAL               0x4000
111 /* many words are considered invalid if they are either all-0 or all-1 */
112 #define NOVAL_0                 0x0000
113 #define NOVAL_1                 0xffff
114
115 /* word 0: gen_config */
116 #define NOT_ATA                 0x8000
117 #define NOT_ATAPI               0x4000  /* (check only if bit 15 == 1) */
118 #define MEDIA_REMOVABLE         0x0080
119 #define DRIVE_NOT_REMOVABLE     0x0040  /* bit obsoleted in ATA 6 */
120 #define INCOMPLETE              0x0004
121 #define CFA_SUPPORT_VAL         0x848a  /* 848a=CFA feature set support */
122 #define DRQ_RESPONSE_TIME       0x0060
123 #define DRQ_3MS_VAL             0x0000
124 #define DRQ_INTR_VAL            0x0020
125 #define DRQ_50US_VAL            0x0040
126 #define PKT_SIZE_SUPPORTED      0x0003
127 #define PKT_SIZE_12_VAL         0x0000
128 #define PKT_SIZE_16_VAL         0x0001
129 #define EQPT_TYPE               0x1f00
130 #define SHIFT_EQPT              8
131
132 #define CDROM 0x0005
133
134 /* word 1: number of logical cylinders */
135 #define LCYLS_MAX               0x3fff /* maximum allowable value */
136
137 /* word 2: specific configuration
138  * (a) require SET FEATURES to spin-up
139  * (b) require spin-up to fully reply to IDENTIFY DEVICE
140  */
141 #define STBY_NID_VAL            0x37c8  /*     (a) and     (b) */
142 #define STBY_ID_VAL             0x738c  /*     (a) and not (b) */
143 #define PWRD_NID_VAL            0x8c73  /* not (a) and     (b) */
144 #define PWRD_ID_VAL             0xc837  /* not (a) and not (b) */
145
146 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
147 #define SECTOR_XFER             0x00ff  /* sectors xfered on r/w multiple cmds*/
148 #define MULTIPLE_SETTING_VALID  0x0100  /* 1=multiple sector setting is valid */
149
150 /* word 49: capabilities 0 */
151 #define STD_STBY                0x2000  /* 1=standard values supported (ATA); 0=vendor specific values */
152 #define IORDY_SUP               0x0800  /* 1=support; 0=may be supported */
153 #define IORDY_OFF               0x0400  /* 1=may be disabled */
154 #define LBA_SUP                 0x0200  /* 1=Logical Block Address support */
155 #define DMA_SUP                 0x0100  /* 1=Direct Memory Access support */
156 #define DMA_IL_SUP              0x8000  /* 1=interleaved DMA support (ATAPI) */
157 #define CMD_Q_SUP               0x4000  /* 1=command queuing support (ATAPI) */
158 #define OVLP_SUP                0x2000  /* 1=overlap operation support (ATAPI) */
159 #define SWRST_REQ               0x1000  /* 1=ATA SW reset required (ATAPI, obsolete */
160
161 /* word 50: capabilities 1 */
162 #define MIN_STANDBY_TIMER       0x0001  /* 1=device specific standby timer value minimum */
163
164 /* words 51 & 52: PIO & DMA cycle times */
165 #define MODE                    0xff00  /* the mode is in the MSBs */
166
167 /* word 53: whats_valid */
168 #define OK_W88                  0x0004  /* the ultra_dma info is valid */
169 #define OK_W64_70               0x0002  /* see above for word descriptions */
170 #define OK_W54_58               0x0001  /* current cyl, head, sector, cap. info valid */
171
172 /*word 63,88: dma_mode, ultra_dma_mode*/
173 #define MODE_MAX                7       /* bit definitions force udma <=7 (when
174                                          * udma >=8 comes out it'll have to be
175                                          * defined in a new dma_mode word!) */
176
177 /* word 64: PIO transfer modes */
178 #define PIO_SUP                 0x00ff  /* only bits 0 & 1 are used so far,  */
179 #define PIO_MODE_MAX            8       /* but all 8 bits are defined        */
180
181 /* word 75: queue_depth */
182 #define DEPTH_BITS              0x001f  /* bits used for queue depth */
183
184 /* words 80-81: version numbers */
185 /* NOVAL_0 or  NOVAL_1 means device does not report version */
186
187 /* word 81: minor version number */
188 #define MINOR_MAX               0x22
189 /* words 82-84: cmds/feats supported */
190 #define CMDS_W82                0x77ff  /* word 82: defined command locations*/
191 #define CMDS_W83                0x3fff  /* word 83: defined command locations*/
192 #define CMDS_W84                0x002f  /* word 83: defined command locations*/
193 #define SUPPORT_48_BIT          0x0400
194 #define NUM_CMD_FEAT_STR        48
195
196 /* words 85-87: cmds/feats enabled */
197 /* use cmd_feat_str[] to display what commands and features have
198  * been enabled with words 85-87
199  */
200
201 /* words 89, 90, SECU ERASE TIME */
202 #define ERASE_BITS      0x00ff
203
204 /* word 92: master password revision */
205 /* NOVAL_0 or  NOVAL_1 means no support for master password revision */
206
207 /* word 93: hw reset result */
208 #define CBLID           0x2000  /* CBLID status */
209 #define RST0            0x0001  /* 1=reset to device #0 */
210 #define DEV_DET         0x0006  /* how device num determined */
211 #define JUMPER_VAL      0x0002  /* device num determined by jumper */
212 #define CSEL_VAL        0x0004  /* device num determined by CSEL_VAL */
213
214 /* word 127: removable media status notification feature set support */
215 #define RM_STAT_BITS    0x0003
216 #define RM_STAT_SUP     0x0001
217
218 /* word 128: security */
219 #define SECU_ENABLED    0x0002
220 #define SECU_LEVEL      0x0010
221 #define NUM_SECU_STR    6
222
223 /* word 160: CFA power mode */
224 #define VALID_W160              0x8000  /* 1=word valid */
225 #define PWR_MODE_REQ            0x2000  /* 1=CFA power mode req'd by some cmds*/
226 #define PWR_MODE_OFF            0x1000  /* 1=CFA power moded disabled */
227 #define MAX_AMPS                0x0fff  /* value = max current in ma */
228
229 /* word 255: integrity */
230 #define SIG                     0x00ff  /* signature location */
231 #define SIG_VAL                 0x00a5  /* signature value */
232
233 #define TIMING_BUF_MB           1
234 #define TIMING_BUF_BYTES        (TIMING_BUF_MB * 1024 * 1024)
235
236 #undef DO_FLUSHCACHE            /* under construction: force cache flush on -W0 */
237
238
239 #define IS_GET 1
240 #define IS_SET 2
241
242
243 enum { fd = 3 };
244
245
246 struct globals {
247         smallint get_identity, get_geom;
248         smallint do_flush;
249         smallint do_ctimings, do_timings;
250         smallint reread_partn;
251         smallint set_piomode, noisy_piomode;
252         smallint getset_readahead;
253         smallint getset_readonly;
254         smallint getset_unmask;
255         smallint getset_mult;
256 #ifdef HDIO_GET_QDMA
257         smallint getset_dma_q;
258 #endif
259         smallint getset_nowerr;
260         smallint getset_keep;
261         smallint getset_io32bit;
262         int piomode;
263         unsigned long Xreadahead;
264         unsigned long readonly;
265         unsigned long unmask;
266         unsigned long mult;
267 #ifdef HDIO_SET_QDMA
268         unsigned long dma_q;
269 #endif
270         unsigned long nowerr;
271         unsigned long keep;
272         unsigned long io32bit;
273 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
274         unsigned long dma;
275         smallint getset_dma;
276 #endif
277 #ifdef HDIO_DRIVE_CMD
278         smallint set_xfermode, get_xfermode;
279         smallint getset_dkeep;
280         smallint getset_standby;
281         smallint getset_lookahead;
282         smallint getset_prefetch;
283         smallint getset_defects;
284         smallint getset_wcache;
285         smallint getset_doorlock;
286         smallint set_seagate;
287         smallint set_standbynow;
288         smallint set_sleepnow;
289         smallint get_powermode;
290         smallint getset_apmmode;
291         int xfermode_requested;
292         unsigned long dkeep;
293         unsigned long standby_requested; /* 0..255 */
294         unsigned long lookahead;
295         unsigned long prefetch;
296         unsigned long defects;
297         unsigned long wcache;
298         unsigned long doorlock;
299         unsigned long apmmode;
300 #endif
301         IF_FEATURE_HDPARM_GET_IDENTITY(        smallint get_IDentity;)
302         IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(  smallint getset_busstate;)
303         IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(    smallint perform_reset;)
304         IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(  smallint perform_tristate;)
305         IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
306         IF_FEATURE_HDPARM_HDIO_SCAN_HWIF(      smallint scan_hwif;)
307         IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(  unsigned long busstate;)
308         IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(  unsigned long tristate;)
309         IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
310 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
311         unsigned long hwif_data;
312         unsigned long hwif_ctrl;
313         unsigned long hwif_irq;
314 #endif
315 #ifdef DO_FLUSHCACHE
316         unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
317 #endif
318 } FIX_ALIASING;
319 #define G (*(struct globals*)&bb_common_bufsiz1)
320 struct BUG_G_too_big {
321         char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
322 };
323 #define get_identity       (G.get_identity           )
324 #define get_geom           (G.get_geom               )
325 #define do_flush           (G.do_flush               )
326 #define do_ctimings        (G.do_ctimings            )
327 #define do_timings         (G.do_timings             )
328 #define reread_partn       (G.reread_partn           )
329 #define set_piomode        (G.set_piomode            )
330 #define noisy_piomode      (G.noisy_piomode          )
331 #define getset_readahead   (G.getset_readahead       )
332 #define getset_readonly    (G.getset_readonly        )
333 #define getset_unmask      (G.getset_unmask          )
334 #define getset_mult        (G.getset_mult            )
335 #define getset_dma_q       (G.getset_dma_q           )
336 #define getset_nowerr      (G.getset_nowerr          )
337 #define getset_keep        (G.getset_keep            )
338 #define getset_io32bit     (G.getset_io32bit         )
339 #define piomode            (G.piomode                )
340 #define Xreadahead         (G.Xreadahead             )
341 #define readonly           (G.readonly               )
342 #define unmask             (G.unmask                 )
343 #define mult               (G.mult                   )
344 #define dma_q              (G.dma_q                  )
345 #define nowerr             (G.nowerr                 )
346 #define keep               (G.keep                   )
347 #define io32bit            (G.io32bit                )
348 #define dma                (G.dma                    )
349 #define getset_dma         (G.getset_dma             )
350 #define set_xfermode       (G.set_xfermode           )
351 #define get_xfermode       (G.get_xfermode           )
352 #define getset_dkeep       (G.getset_dkeep           )
353 #define getset_standby     (G.getset_standby         )
354 #define getset_lookahead   (G.getset_lookahead       )
355 #define getset_prefetch    (G.getset_prefetch        )
356 #define getset_defects     (G.getset_defects         )
357 #define getset_wcache      (G.getset_wcache          )
358 #define getset_doorlock    (G.getset_doorlock        )
359 #define set_seagate        (G.set_seagate            )
360 #define set_standbynow     (G.set_standbynow         )
361 #define set_sleepnow       (G.set_sleepnow           )
362 #define get_powermode      (G.get_powermode          )
363 #define getset_apmmode     (G.getset_apmmode         )
364 #define xfermode_requested (G.xfermode_requested     )
365 #define dkeep              (G.dkeep                  )
366 #define standby_requested  (G.standby_requested      )
367 #define lookahead          (G.lookahead              )
368 #define prefetch           (G.prefetch               )
369 #define defects            (G.defects                )
370 #define wcache             (G.wcache                 )
371 #define doorlock           (G.doorlock               )
372 #define apmmode            (G.apmmode                )
373 #define get_IDentity       (G.get_IDentity           )
374 #define getset_busstate    (G.getset_busstate        )
375 #define perform_reset      (G.perform_reset          )
376 #define perform_tristate   (G.perform_tristate       )
377 #define unregister_hwif    (G.unregister_hwif        )
378 #define scan_hwif          (G.scan_hwif              )
379 #define busstate           (G.busstate               )
380 #define tristate           (G.tristate               )
381 #define hwif               (G.hwif                   )
382 #define hwif_data          (G.hwif_data              )
383 #define hwif_ctrl          (G.hwif_ctrl              )
384 #define hwif_irq           (G.hwif_irq               )
385
386
387 /* Busybox messages and functions */
388 #if ENABLE_IOCTL_HEX2STR_ERROR
389 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
390 {
391         if (!ioctl(fd, cmd, args))
392                 return 0;
393         args[0] = alt;
394         return bb_ioctl_or_warn(fd, cmd, args, string);
395 }
396 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
397 #else
398 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
399 {
400         if (!ioctl(fd, cmd, args))
401                 return 0;
402         args[0] = alt;
403         return bb_ioctl_or_warn(fd, cmd, args);
404 }
405 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
406 #endif
407
408 static void on_off(int value)
409 {
410         puts(value ? " (on)" : " (off)");
411 }
412
413 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
414 {
415         if (get_arg) {
416                 printf(" setting %s to %ld", s, arg);
417                 on_off(arg);
418         }
419 }
420
421 static void print_value_on_off(const char *str, unsigned long argp)
422 {
423         printf(" %s\t= %2ld", str, argp);
424         on_off(argp != 0);
425 }
426
427 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
428 static void print_ascii(const char *p, int length)
429 {
430 #if BB_BIG_ENDIAN
431 #define LE_ONLY(x)
432         enum { ofs = 0 };
433 #else
434 #define LE_ONLY(x) x
435         /* every 16bit word is big-endian (i.e. inverted) */
436         /* accessing bytes in 1,0, 3,2, 5,4... sequence */
437         int ofs = 1;
438 #endif
439
440         length *= 2;
441         /* find first non-space & print it */
442         while (length && p[ofs] != ' ') {
443                 p++;
444                 LE_ONLY(ofs = -ofs;)
445                 length--;
446         }
447         while (length && p[ofs]) {
448                 bb_putchar(p[ofs]);
449                 p++;
450                 LE_ONLY(ofs = -ofs;)
451                 length--;
452         }
453         bb_putchar('\n');
454 #undef LE_ONLY
455 }
456
457 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
458 {
459         if (val[i]) {
460                 printf("\t%-20s", string);
461                 print_ascii((void*)&val[i], n);
462         }
463 }
464
465 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
466 {
467         uint16_t ii;
468         uint8_t err_dma = 0;
469
470         for (ii = 0; ii <= MODE_MAX; ii++) {
471                 if (mode_sel & 0x0001) {
472                         printf("*%cdma%u ", cc, ii);
473                         if (*have_mode)
474                                 err_dma = 1;
475                         *have_mode = 1;
476                 } else if (mode_sup & 0x0001)
477                         printf("%cdma%u ", cc, ii);
478
479                 mode_sup >>= 1;
480                 mode_sel >>= 1;
481         }
482         return err_dma;
483 }
484
485 static const char pkt_str[] ALIGN1 =
486         "Direct-access device" "\0"             /* word 0, bits 12-8 = 00 */
487         "Sequential-access device" "\0"         /* word 0, bits 12-8 = 01 */
488         "Printer" "\0"                          /* word 0, bits 12-8 = 02 */
489         "Processor" "\0"                        /* word 0, bits 12-8 = 03 */
490         "Write-once device" "\0"                /* word 0, bits 12-8 = 04 */
491         "CD-ROM" "\0"                           /* word 0, bits 12-8 = 05 */
492         "Scanner" "\0"                          /* word 0, bits 12-8 = 06 */
493         "Optical memory" "\0"                   /* word 0, bits 12-8 = 07 */
494         "Medium changer" "\0"                   /* word 0, bits 12-8 = 08 */
495         "Communications device" "\0"            /* word 0, bits 12-8 = 09 */
496         "ACS-IT8 device" "\0"                   /* word 0, bits 12-8 = 0a */
497         "ACS-IT8 device" "\0"                   /* word 0, bits 12-8 = 0b */
498         "Array controller" "\0"                 /* word 0, bits 12-8 = 0c */
499         "Enclosure services" "\0"               /* word 0, bits 12-8 = 0d */
500         "Reduced block command device" "\0"     /* word 0, bits 12-8 = 0e */
501         "Optical card reader/writer" "\0"       /* word 0, bits 12-8 = 0f */
502 ;
503
504 static const char ata1_cfg_str[] ALIGN1 =       /* word 0 in ATA-1 mode */
505         "reserved" "\0"                         /* bit 0 */
506         "hard sectored" "\0"                    /* bit 1 */
507         "soft sectored" "\0"                    /* bit 2 */
508         "not MFM encoded " "\0"                 /* bit 3 */
509         "head switch time > 15us" "\0"          /* bit 4 */
510         "spindle motor control option" "\0"     /* bit 5 */
511         "fixed drive" "\0"                      /* bit 6 */
512         "removable drive" "\0"                  /* bit 7 */
513         "disk xfer rate <= 5Mbs" "\0"           /* bit 8 */
514         "disk xfer rate > 5Mbs, <= 10Mbs" "\0"  /* bit 9 */
515         "disk xfer rate > 5Mbs" "\0"            /* bit 10 */
516         "rotational speed tol." "\0"            /* bit 11 */
517         "data strobe offset option" "\0"        /* bit 12 */
518         "track offset option" "\0"              /* bit 13 */
519         "format speed tolerance gap reqd" "\0"  /* bit 14 */
520         "ATAPI"                                 /* bit 14 */
521 ;
522
523 static const char minor_str[] ALIGN1 =
524         /* word 81 value: */
525         "Unspecified" "\0"                                  /* 0x0000 */
526         "ATA-1 X3T9.2 781D prior to rev.4" "\0"             /* 0x0001 */
527         "ATA-1 published, ANSI X3.221-1994" "\0"            /* 0x0002 */
528         "ATA-1 X3T9.2 781D rev.4" "\0"                      /* 0x0003 */
529         "ATA-2 published, ANSI X3.279-1996" "\0"            /* 0x0004 */
530         "ATA-2 X3T10 948D prior to rev.2k" "\0"             /* 0x0005 */
531         "ATA-3 X3T10 2008D rev.1" "\0"                      /* 0x0006 */
532         "ATA-2 X3T10 948D rev.2k" "\0"                      /* 0x0007 */
533         "ATA-3 X3T10 2008D rev.0" "\0"                      /* 0x0008 */
534         "ATA-2 X3T10 948D rev.3" "\0"                       /* 0x0009 */
535         "ATA-3 published, ANSI X3.298-199x" "\0"            /* 0x000a */
536         "ATA-3 X3T10 2008D rev.6" "\0"                      /* 0x000b */
537         "ATA-3 X3T13 2008D rev.7 and 7a" "\0"               /* 0x000c */
538         "ATA/ATAPI-4 X3T13 1153D rev.6" "\0"                /* 0x000d */
539         "ATA/ATAPI-4 T13 1153D rev.13" "\0"                 /* 0x000e */
540         "ATA/ATAPI-4 X3T13 1153D rev.7" "\0"                /* 0x000f */
541         "ATA/ATAPI-4 T13 1153D rev.18" "\0"                 /* 0x0010 */
542         "ATA/ATAPI-4 T13 1153D rev.15" "\0"                 /* 0x0011 */
543         "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0"  /* 0x0012 */
544         "ATA/ATAPI-5 T13 1321D rev.3" "\0"                  /* 0x0013 */
545         "ATA/ATAPI-4 T13 1153D rev.14" "\0"                 /* 0x0014 */
546         "ATA/ATAPI-5 T13 1321D rev.1" "\0"                  /* 0x0015 */
547         "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0"  /* 0x0016 */
548         "ATA/ATAPI-4 T13 1153D rev.17" "\0"                 /* 0x0017 */
549         "ATA/ATAPI-6 T13 1410D rev.0" "\0"                  /* 0x0018 */
550         "ATA/ATAPI-6 T13 1410D rev.3a" "\0"                 /* 0x0019 */
551         "ATA/ATAPI-7 T13 1532D rev.1" "\0"                  /* 0x001a */
552         "ATA/ATAPI-6 T13 1410D rev.2" "\0"                  /* 0x001b */
553         "ATA/ATAPI-6 T13 1410D rev.1" "\0"                  /* 0x001c */
554         "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0"  /* 0x001d */
555         "ATA/ATAPI-7 T13 1532D rev.0" "\0"                  /* 0x001e */
556         "reserved" "\0"                                     /* 0x001f */
557         "reserved" "\0"                                     /* 0x0020 */
558         "ATA/ATAPI-7 T13 1532D rev.4a" "\0"                 /* 0x0021 */
559         "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0"  /* 0x0022 */
560         "reserved"                                          /* 0x0023-0xfffe */
561 ;
562 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
563            /* word 81 value: */
564         0, /* 0x0000 WARNING: actual_ver[] array */
565         1, /* 0x0001 WARNING: corresponds        */
566         1, /* 0x0002 WARNING: *exactly*          */
567         1, /* 0x0003 WARNING: to the ATA/        */
568         2, /* 0x0004 WARNING: ATAPI version      */
569         2, /* 0x0005 WARNING: listed in          */
570         3, /* 0x0006 WARNING: the                */
571         2, /* 0x0007 WARNING: minor_str          */
572         3, /* 0x0008 WARNING: array              */
573         2, /* 0x0009 WARNING: above.             */
574         3, /* 0x000a WARNING:                    */
575         3, /* 0x000b WARNING: If you change      */
576         3, /* 0x000c WARNING: that one,          */
577         4, /* 0x000d WARNING: change this one    */
578         4, /* 0x000e WARNING: too!!!             */
579         4, /* 0x000f */
580         4, /* 0x0010 */
581         4, /* 0x0011 */
582         4, /* 0x0012 */
583         5, /* 0x0013 */
584         4, /* 0x0014 */
585         5, /* 0x0015 */
586         5, /* 0x0016 */
587         4, /* 0x0017 */
588         6, /* 0x0018 */
589         6, /* 0x0019 */
590         7, /* 0x001a */
591         6, /* 0x001b */
592         6, /* 0x001c */
593         7, /* 0x001d */
594         7, /* 0x001e */
595         0, /* 0x001f */
596         0, /* 0x0020 */
597         7, /* 0x0021 */
598         6, /* 0x0022 */
599         0  /* 0x0023-0xfffe */
600 };
601
602 static const char cmd_feat_str[] ALIGN1 =
603         "" "\0"                                     /* word 82 bit 15: obsolete  */
604         "NOP cmd" "\0"                              /* word 82 bit 14 */
605         "READ BUFFER cmd" "\0"                      /* word 82 bit 13 */
606         "WRITE BUFFER cmd" "\0"                     /* word 82 bit 12 */
607         "" "\0"                                     /* word 82 bit 11: obsolete  */
608         "Host Protected Area feature set" "\0"      /* word 82 bit 10 */
609         "DEVICE RESET cmd" "\0"                     /* word 82 bit  9 */
610         "SERVICE interrupt" "\0"                    /* word 82 bit  8 */
611         "Release interrupt" "\0"                    /* word 82 bit  7 */
612         "Look-ahead" "\0"                           /* word 82 bit  6 */
613         "Write cache" "\0"                          /* word 82 bit  5 */
614         "PACKET command feature set" "\0"           /* word 82 bit  4 */
615         "Power Management feature set" "\0"         /* word 82 bit  3 */
616         "Removable Media feature set" "\0"          /* word 82 bit  2 */
617         "Security Mode feature set" "\0"            /* word 82 bit  1 */
618         "SMART feature set" "\0"                    /* word 82 bit  0 */
619                                                     /* -------------- */
620         "" "\0"                                     /* word 83 bit 15: !valid bit */
621         "" "\0"                                     /* word 83 bit 14:  valid bit */
622         "FLUSH CACHE EXT cmd" "\0"                  /* word 83 bit 13 */
623         "Mandatory FLUSH CACHE cmd " "\0"           /* word 83 bit 12 */
624         "Device Configuration Overlay feature set " "\0"
625         "48-bit Address feature set " "\0"          /* word 83 bit 10 */
626         "" "\0"
627         "SET MAX security extension" "\0"           /* word 83 bit  8 */
628         "Address Offset Reserved Area Boot" "\0"    /* word 83 bit  7 */
629         "SET FEATURES subcommand required to spinup after power up" "\0"
630         "Power-Up In Standby feature set" "\0"      /* word 83 bit  5 */
631         "Removable Media Status Notification feature set" "\0"
632         "Adv. Power Management feature set" "\0"    /* word 83 bit  3 */
633         "CFA feature set" "\0"                      /* word 83 bit  2 */
634         "READ/WRITE DMA QUEUED" "\0"                /* word 83 bit  1 */
635         "DOWNLOAD MICROCODE cmd" "\0"               /* word 83 bit  0 */
636                                                     /* -------------- */
637         "" "\0"                                     /* word 84 bit 15: !valid bit */
638         "" "\0"                                     /* word 84 bit 14:  valid bit */
639         "" "\0"                                     /* word 84 bit 13:  reserved */
640         "" "\0"                                     /* word 84 bit 12:  reserved */
641         "" "\0"                                     /* word 84 bit 11:  reserved */
642         "" "\0"                                     /* word 84 bit 10:  reserved */
643         "" "\0"                                     /* word 84 bit  9:  reserved */
644         "" "\0"                                     /* word 84 bit  8:  reserved */
645         "" "\0"                                     /* word 84 bit  7:  reserved */
646         "" "\0"                                     /* word 84 bit  6:  reserved */
647         "General Purpose Logging feature set" "\0"  /* word 84 bit  5 */
648         "" "\0"                                     /* word 84 bit  4:  reserved */
649         "Media Card Pass Through Command feature set " "\0"
650         "Media serial number " "\0"                 /* word 84 bit  2 */
651         "SMART self-test " "\0"                     /* word 84 bit  1 */
652         "SMART error logging "                      /* word 84 bit  0 */
653 ;
654
655 static const char secu_str[] ALIGN1 =
656         "supported" "\0"                /* word 128, bit 0 */
657         "enabled" "\0"                  /* word 128, bit 1 */
658         "locked" "\0"                   /* word 128, bit 2 */
659         "frozen" "\0"                   /* word 128, bit 3 */
660         "expired: security count" "\0"  /* word 128, bit 4 */
661         "supported: enhanced erase"     /* word 128, bit 5 */
662 ;
663
664 // Parse 512 byte disk identification block and print much crap.
665 static void identify(uint16_t *val) NORETURN;
666 static void identify(uint16_t *val)
667 {
668         uint16_t ii, jj, kk;
669         uint16_t like_std = 1, std = 0, min_std = 0xffff;
670         uint16_t dev = NO_DEV, eqpt = NO_DEV;
671         uint8_t  have_mode = 0, err_dma = 0;
672         uint8_t  chksum = 0;
673         uint32_t ll, mm, nn, oo;
674         uint64_t bbbig; /* (:) */
675         const char *strng;
676 #if BB_BIG_ENDIAN
677         uint16_t buf[256];
678
679         // Adjust for endianness
680         swab(val, buf, sizeof(buf));
681         val = buf;
682 #endif
683         /* check if we recognize the device type */
684         bb_putchar('\n');
685         if (!(val[GEN_CONFIG] & NOT_ATA)) {
686                 dev = ATA_DEV;
687                 printf("ATA device, with ");
688         } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
689                 dev = ATA_DEV;
690                 like_std = 4;
691                 printf("CompactFlash ATA device, with ");
692         } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
693                 dev = ATAPI_DEV;
694                 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
695                 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
696                 like_std = 3;
697         } else
698                 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
699                 bb_error_msg_and_die("unknown device type");
700
701         printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
702         /* Info from the specific configuration word says whether or not the
703          * ID command completed correctly.  It is only defined, however in
704          * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
705          * standards.  Since the values allowed for this word are extremely
706          * specific, it should be safe to check it now, even though we don't
707          * know yet what standard this device is using.
708          */
709         if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
710          || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
711         ) {
712                 like_std = 5;
713                 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
714                         printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
715                 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
716                         printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
717         }
718
719         /* output the model and serial numbers and the fw revision */
720         xprint_ascii(val, START_MODEL,  "Model Number:",        LENGTH_MODEL);
721         xprint_ascii(val, START_SERIAL, "Serial Number:",       LENGTH_SERIAL);
722         xprint_ascii(val, START_FW_REV, "Firmware Revision:",   LENGTH_FW_REV);
723         xprint_ascii(val, START_MEDIA,  "Media Serial Num:",    LENGTH_MEDIA);
724         xprint_ascii(val, START_MANUF,  "Media Manufacturer:",  LENGTH_MANUF);
725
726         /* major & minor standards version number (Note: these words were not
727          * defined until ATA-3 & the CDROM std uses different words.) */
728         printf("Standards:");
729         if (eqpt != CDROM) {
730                 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
731                         if (like_std < 3) like_std = 3;
732                         std = actual_ver[val[MINOR]];
733                         if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
734
735                 }
736                 /* looks like when they up-issue the std, they obsolete one;
737                  * thus, only the newest 4 issues need be supported. (That's
738                  * what "kk" and "min_std" are all about.) */
739                 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
740                         printf("\n\tSupported: ");
741                         jj = val[MAJOR] << 1;
742                         kk = like_std >4 ? like_std-4: 0;
743                         for (ii = 14; (ii >0)&&(ii>kk); ii--) {
744                                 if (jj & 0x8000) {
745                                         printf("%u ", ii);
746                                         if (like_std < ii) {
747                                                 like_std = ii;
748                                                 kk = like_std >4 ? like_std-4: 0;
749                                         }
750                                         if (min_std > ii) min_std = ii;
751                                 }
752                                 jj <<= 1;
753                         }
754                         if (like_std < 3) like_std = 3;
755                 }
756                 /* Figure out what standard the device is using if it hasn't told
757                  * us.  If we know the std, check if the device is using any of
758                  * the words from the next level up.  It happens.
759                  */
760                 if (like_std < std) like_std = std;
761
762                 if (((std == 5) || (!std && (like_std < 6))) &&
763                         ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
764                         ((      val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
765                         (((     val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
766                         (       val[CMDS_SUPP_2] & CMDS_W84) ) )
767                 ) {
768                         like_std = 6;
769                 } else if (((std == 4) || (!std && (like_std < 5))) &&
770                         ((((val[INTEGRITY]      & SIG) == SIG_VAL) && !chksum) ||
771                         ((      val[HWRST_RSLT] & VALID) == VALID_VAL) ||
772                         (((     val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
773                         ((      val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
774                 {
775                         like_std = 5;
776                 } else if (((std == 3) || (!std && (like_std < 4))) &&
777                                 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
778                                 (((     val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
779                                 ((      val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
780                                 ((      val[CAPAB_1] & VALID) == VALID_VAL) ||
781                                 ((      val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
782                                 ((      val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
783                 ) {
784                         like_std = 4;
785                 } else if (((std == 2) || (!std && (like_std < 3)))
786                  && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
787                 ) {
788                         like_std = 3;
789                 } else if (((std == 1) || (!std && (like_std < 2))) &&
790                                 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
791                                 (val[WHATS_VALID] & OK_W64_70)) )
792                 {
793                         like_std = 2;
794                 }
795
796                 if (!std)
797                         printf("\n\tLikely used: %u\n", like_std);
798                 else if (like_std > std)
799                         printf("& some of %u\n", like_std);
800                 else
801                         bb_putchar('\n');
802         } else {
803                 /* TBD: do CDROM stuff more thoroughly.  For now... */
804                 kk = 0;
805                 if (val[CDR_MINOR] == 9) {
806                         kk = 1;
807                         printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
808                 }
809                 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
810                         kk = 1;
811                         printf("\n\tSupported: CD-ROM ATAPI");
812                         jj = val[CDR_MAJOR] >> 1;
813                         for (ii = 1; ii < 15; ii++) {
814                                 if (jj & 0x0001) printf("-%u ", ii);
815                                 jj >>= 1;
816                         }
817                 }
818                 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
819                 /* the cdrom stuff is more like ATA-2 than anything else, so: */
820                 like_std = 2;
821         }
822
823         if (min_std == 0xffff)
824                 min_std = like_std > 4 ? like_std - 3 : 1;
825
826         printf("Configuration:\n");
827         /* more info from the general configuration word */
828         if ((eqpt != CDROM) && (like_std == 1)) {
829                 jj = val[GEN_CONFIG] >> 1;
830                 for (ii = 1; ii < 15; ii++) {
831                         if (jj & 0x0001)
832                                 printf("\t%s\n", nth_string(ata1_cfg_str, ii));
833                         jj >>=1;
834                 }
835         }
836         if (dev == ATAPI_DEV) {
837                 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) ==  DRQ_3MS_VAL)
838                         strng = "3ms";
839                 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) ==  DRQ_INTR_VAL)
840                         strng = "<=10ms with INTRQ";
841                 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) ==  DRQ_50US_VAL)
842                         strng ="50us";
843                 else
844                         strng = "unknown";
845                 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
846
847                 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
848                         strng = "12 bytes";
849                 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
850                         strng = "16 bytes";
851                 else
852                         strng = "unknown";
853                 puts(strng);
854         } else {
855                 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
856                 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
857                 mm = 0;
858                 bbbig = 0;
859                 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
860                         printf("\tCHS addressing not supported\n");
861                 else {
862                         jj = val[WHATS_VALID] & OK_W54_58;
863                         printf("\tLogical\t\tmax\tcurrent\n"
864                                 "\tcylinders\t%u\t%u\n"
865                                 "\theads\t\t%u\t%u\n"
866                                 "\tsectors/track\t%u\t%u\n"
867                                 "\t--\n",
868                                 val[LCYLS],
869                                 jj ? val[LCYLS_CUR] : 0,
870                                 val[LHEADS],
871                                 jj ? val[LHEADS_CUR] : 0,
872                                 val[LSECTS],
873                                 jj ? val[LSECTS_CUR] : 0);
874
875                         if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
876                                 printf("\tbytes/track: %u\tbytes/sector: %u\n",
877                                         val[TRACK_BYTES], val[SECT_BYTES]);
878
879                         if (jj) {
880                                 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
881                                 if (like_std < 3) {
882                                         /* check Endian of capacity bytes */
883                                         nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
884                                         oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
885                                         if (abs(mm - nn) > abs(oo - nn))
886                                                 mm = oo;
887                                 }
888                                 printf("\tCHS current addressable sectors:%11u\n", mm);
889                         }
890                 }
891                 /* LBA addressing */
892                 printf("\tLBA    user addressable sectors:%11u\n", ll);
893                 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
894                  && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
895                 ) {
896                         bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
897                                 (uint64_t)val[LBA_48_MSB] << 32 |
898                                 (uint64_t)val[LBA_MID] << 16 |
899                                         val[LBA_LSB];
900                         printf("\tLBA48  user addressable sectors:%11"PRIu64"\n", bbbig);
901                 }
902
903                 if (!bbbig)
904                         bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
905                 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
906                 bbbig = (bbbig << 9) / 1000000;
907                 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
908
909                 if (bbbig > 1000)
910                         printf("(%"PRIu64" GB)\n", bbbig/1000);
911                 else
912                         bb_putchar('\n');
913         }
914
915         /* hw support of commands (capabilities) */
916         printf("Capabilities:\n\t");
917
918         if (dev == ATAPI_DEV) {
919                 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP))
920                         printf("Cmd queuing, ");
921                 if (val[CAPAB_0] & OVLP_SUP)
922                         printf("Cmd overlap, ");
923         }
924         if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
925
926         if (like_std != 1) {
927                 printf("IORDY%s(can%s be disabled)\n",
928                         !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
929                         (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
930         } else
931                 printf("no IORDY\n");
932
933         if ((like_std == 1) && val[BUF_TYPE]) {
934                 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
935                         (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
936                         (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
937         }
938
939         if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
940                 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
941         }
942         if ((min_std < 4) && (val[RW_LONG])) {
943                 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
944         }
945         if ((eqpt != CDROM) && (like_std > 3)) {
946                 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
947         }
948
949         if (dev == ATA_DEV) {
950                 if (like_std == 1)
951                         printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
952                 else {
953                         printf("\tStandby timer values: spec'd by %s",
954                                 (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor");
955                         if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
956                                 printf(", %s device specific minimum\n",
957                                         (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
958                         else
959                                 bb_putchar('\n');
960                 }
961                 printf("\tR/W multiple sector transfer: ");
962                 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
963                         printf("not supported\n");
964                 else {
965                         printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
966                         if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
967                                 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
968                         else
969                                 printf("?\n");
970                 }
971                 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
972                         /* We print out elsewhere whether the APM feature is enabled or
973                            not.  If it's not enabled, let's not repeat the info; just print
974                            nothing here. */
975                         printf("\tAdvancedPM level: ");
976                         if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
977                                 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
978                                 printf("%u (0x%x)\n", apm_level, apm_level);
979                         }
980                         else
981                                 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
982                 }
983                 if (like_std > 5 && val[ACOUSTIC]) {
984                         printf("\tRecommended acoustic management value: %u, current value: %u\n",
985                                 (val[ACOUSTIC] >> 8) & 0x00ff,
986                                 val[ACOUSTIC] & 0x00ff);
987                 }
988         } else {
989                  /* ATAPI */
990                 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
991                         printf("\tATA sw reset required\n");
992
993                 if (val[PKT_REL] || val[SVC_NBSY]) {
994                         printf("\tOverlap support:");
995                         if (val[PKT_REL])
996                                 printf(" %uus to release bus.", val[PKT_REL]);
997                         if (val[SVC_NBSY])
998                                 printf(" %uus to clear BSY after SERVICE cmd.",
999                                         val[SVC_NBSY]);
1000                         bb_putchar('\n');
1001                 }
1002         }
1003
1004         /* DMA stuff. Check that only one DMA mode is selected. */
1005         printf("\tDMA: ");
1006         if (!(val[CAPAB_0] & DMA_SUP))
1007                 printf("not supported\n");
1008         else {
1009                 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1010                         printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1011                 if (val[SINGLE_DMA]) {
1012                         jj = val[SINGLE_DMA];
1013                         kk = val[SINGLE_DMA] >> 8;
1014                         err_dma += mode_loop(jj, kk, 's', &have_mode);
1015                 }
1016                 if (val[MULTI_DMA]) {
1017                         jj = val[MULTI_DMA];
1018                         kk = val[MULTI_DMA] >> 8;
1019                         err_dma += mode_loop(jj, kk, 'm', &have_mode);
1020                 }
1021                 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1022                         jj = val[ULTRA_DMA];
1023                         kk = val[ULTRA_DMA] >> 8;
1024                         err_dma += mode_loop(jj, kk, 'u', &have_mode);
1025                 }
1026                 if (err_dma || !have_mode) printf("(?)");
1027                 bb_putchar('\n');
1028
1029                 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1030                         printf("\t\tInterleaved DMA support\n");
1031
1032                 if ((val[WHATS_VALID] & OK_W64_70)
1033                  && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1034                 ) {
1035                         printf("\t\tCycle time:");
1036                         if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1037                         if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1038                         bb_putchar('\n');
1039                 }
1040         }
1041
1042         /* Programmed IO stuff */
1043         printf("\tPIO: ");
1044         /* If a drive supports mode n (e.g. 3), it also supports all modes less
1045          * than n (e.g. 3, 2, 1 and 0).  Print all the modes. */
1046         if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1047                 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1048                 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1049                         if (jj & 0x0001) printf("pio%d ", ii);
1050                         jj >>=1;
1051                 }
1052                 bb_putchar('\n');
1053         } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1054                 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1055                         printf("pio%d ", ii);
1056                 bb_putchar('\n');
1057         } else
1058                 puts("unknown");
1059
1060         if (val[WHATS_VALID] & OK_W64_70) {
1061                 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1062                         printf("\t\tCycle time:");
1063                         if (val[PIO_NO_FLOW])
1064                                 printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1065                         if (val[PIO_FLOW])
1066                                 printf("  IORDY flow control=%uns", val[PIO_FLOW]);
1067                         bb_putchar('\n');
1068                 }
1069         }
1070
1071         if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1072                 printf("Commands/features:\n"
1073                         "\tEnabled\tSupported:\n");
1074                 jj = val[CMDS_SUPP_0];
1075                 kk = val[CMDS_EN_0];
1076                 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1077                         const char *feat_str = nth_string(cmd_feat_str, ii);
1078                         if ((jj & 0x8000) && (*feat_str != '\0')) {
1079                                 printf("\t%s\t%s\n", (kk & 0x8000) ? "   *" : "", feat_str);
1080                         }
1081                         jj <<= 1;
1082                         kk <<= 1;
1083                         if (ii % 16 == 15) {
1084                                 jj = val[CMDS_SUPP_0+1+(ii/16)];
1085                                 kk = val[CMDS_EN_0+1+(ii/16)];
1086                         }
1087                         if (ii == 31) {
1088                                 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1089                                         ii +=16;
1090                         }
1091                 }
1092         }
1093         /* Removable Media Status Notification feature set */
1094         if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1095                 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1096
1097         /* security */
1098         if ((eqpt != CDROM) && (like_std > 3)
1099          && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1100         ) {
1101                 printf("Security:\n");
1102                 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1103                         printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1104                 jj = val[SECU_STATUS];
1105                 if (jj) {
1106                         for (ii = 0; ii < NUM_SECU_STR; ii++) {
1107                                 printf("\t%s\t%s\n",
1108                                         (!(jj & 0x0001)) ? "not" : "",
1109                                         nth_string(secu_str, ii));
1110                                 jj >>=1;
1111                         }
1112                         if (val[SECU_STATUS] & SECU_ENABLED) {
1113                                 printf("\tSecurity level %s\n",
1114                                         (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1115                         }
1116                 }
1117                 jj =  val[ERASE_TIME]     & ERASE_BITS;
1118                 kk =  val[ENH_ERASE_TIME] & ERASE_BITS;
1119                 if (jj || kk) {
1120                         bb_putchar('\t');
1121                         if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1122                         if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1123                         bb_putchar('\n');
1124                 }
1125         }
1126
1127         /* reset result */
1128         jj = val[HWRST_RSLT];
1129         if ((jj & VALID) == VALID_VAL) {
1130                 oo = (jj & RST0);
1131                 if (!oo)
1132                         jj >>= 8;
1133                 if ((jj & DEV_DET) == JUMPER_VAL)
1134                         strng = " determined by the jumper";
1135                 else if ((jj & DEV_DET) == CSEL_VAL)
1136                         strng = " determined by CSEL";
1137                 else
1138                         strng = "";
1139                 printf("HW reset results:\n"
1140                         "\tCBLID- %s Vih\n"
1141                         "\tDevice num = %i%s\n",
1142                         (val[HWRST_RSLT] & CBLID) ? "above" : "below",
1143                         !(oo), strng);
1144         }
1145
1146         /* more stuff from std 5 */
1147         if ((like_std > 4) && (eqpt != CDROM)) {
1148                 if (val[CFA_PWR_MODE] & VALID_W160) {
1149                         printf("CFA power mode 1:\n"
1150                                 "\t%s%s\n",
1151                                 (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1152                                 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1153                         if (val[CFA_PWR_MODE] & MAX_AMPS)
1154                                 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1155                 }
1156                 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1157                         printf("Checksum: %scorrect\n", chksum ? "in" : "");
1158                 }
1159         }
1160
1161         exit(EXIT_SUCCESS);
1162 }
1163 #endif
1164
1165 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1166 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1167 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1168 // and HDIO_GET_IDENTITY returns 512 bytes.  But the latest
1169 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1170 // (which they should, but they should just return -EINVAL).
1171 //
1172 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1173 // On a really old system, it will not, and we will be confused.
1174 // Too bad, really.
1175
1176 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1177 static const char cfg_str[] ALIGN1 =
1178         """\0"            "HardSect""\0"   "SoftSect""\0"  "NotMFM""\0"
1179         "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0"     "Removeable""\0"
1180         "DTR<=5Mbs""\0"   "DTR>5Mbs""\0"   "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1181         "dStbOff""\0"     "TrkOff""\0"     "FmtGapReq""\0" "nonMagnetic"
1182 ;
1183
1184 static const char BuffType[] ALIGN1 =
1185         "unknown""\0"     "1Sect""\0"      "DualPort""\0"  "DualPortCache"
1186 ;
1187
1188 static NOINLINE void dump_identity(const struct hd_driveid *id)
1189 {
1190         int i;
1191         const unsigned short *id_regs = (const void*) id;
1192
1193         printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1194                                 id->model, id->fw_rev, id->serial_no);
1195         for (i = 0; i <= 15; i++) {
1196                 if (id->config & (1<<i))
1197                         printf(" %s", nth_string(cfg_str, i));
1198         }
1199         printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1200                 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1201                 id->cyls, id->heads, id->sectors, id->track_bytes,
1202                 id->sector_bytes, id->ecc_bytes,
1203                 id->buf_type,
1204                 nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1205                 id->buf_size/2, id->max_multsect);
1206         if (id->max_multsect) {
1207                 printf(", MultSect=");
1208                 if (!(id->multsect_valid & 1))
1209                         printf("?%u?", id->multsect);
1210                 else if (id->multsect)
1211                         printf("%u", id->multsect);
1212                 else
1213                         printf("off");
1214         }
1215         bb_putchar('\n');
1216
1217         if (!(id->field_valid & 1))
1218                 printf(" (maybe):");
1219
1220         printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1221                 id->cur_sectors,
1222                 (BB_BIG_ENDIAN) ?
1223                         (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1224                         (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1225                         ((id->capability&2) == 0) ? "no" : "yes");
1226
1227         if (id->capability & 2)
1228                 printf(", LBAsects=%u", id->lba_capacity);
1229
1230         printf("\n IORDY=%s",
1231                 (id->capability & 8)
1232                         ? ((id->capability & 4) ? "on/off" : "yes")
1233                         : "no");
1234
1235         if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1236                 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1237
1238         if ((id->capability & 1) && (id->field_valid & 2))
1239                 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1240
1241         printf("\n PIO modes:  ");
1242         if (id->tPIO <= 5) {
1243                 printf("pio0 ");
1244                 if (id->tPIO >= 1) printf("pio1 ");
1245                 if (id->tPIO >= 2) printf("pio2 ");
1246         }
1247         if (id->field_valid & 2) {
1248                 static const masks_labels_t pio_modes = {
1249                         .masks = { 1, 2, ~3 },
1250                         .labels = "pio3 \0""pio4 \0""pio? \0",
1251                 };
1252                 print_flags(&pio_modes, id->eide_pio_modes);
1253         }
1254         if (id->capability & 1) {
1255                 if (id->dma_1word | id->dma_mword) {
1256                         static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
1257                         printf("\n DMA modes:  ");
1258                         print_flags_separated(dma_wmode_masks,
1259                                 "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
1260                                 id->dma_1word, NULL);
1261                         print_flags_separated(dma_wmode_masks,
1262                                 "*\0""mdma0 \0""*\0""mdma1 \0""*\0""mdma2 \0""*\0""mdma? \0",
1263                                 id->dma_mword, NULL);
1264                 }
1265         }
1266         if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1267                 static const masks_labels_t ultra_modes1 = {
1268                         .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
1269                         .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
1270                 };
1271
1272                 printf("\n UDMA modes: ");
1273                 print_flags(&ultra_modes1, id->dma_ultra);
1274 #ifdef __NEW_HD_DRIVE_ID
1275                 if (id->hw_config & 0x2000) {
1276 #else /* !__NEW_HD_DRIVE_ID */
1277                 if (id->word93 & 0x2000) {
1278 #endif /* __NEW_HD_DRIVE_ID */
1279                         static const masks_labels_t ultra_modes2 = {
1280                                 .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
1281                                         0x2000, 0x0020, 0x4000, 0x0040,
1282                                         0x8000, 0x0080 },
1283                                 .labels = "*\0""udma3 \0""*\0""udma4 \0"
1284                                         "*\0""udma5 \0""*\0""udma6 \0"
1285                                         "*\0""udma7 \0"
1286                         };
1287                         print_flags(&ultra_modes2, id->dma_ultra);
1288                 }
1289         }
1290         printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1291         if (id_regs[83] & 8) {
1292                 if (!(id_regs[86] & 8))
1293                         printf(": disabled (255)");
1294                 else if ((id_regs[91] & 0xFF00) != 0x4000)
1295                         printf(": unknown setting");
1296                 else
1297                         printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1298         }
1299         if (id_regs[82] & 0x20)
1300                 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1301 #ifdef __NEW_HD_DRIVE_ID
1302         if ((id->minor_rev_num && id->minor_rev_num <= 31)
1303          || (id->major_rev_num && id->minor_rev_num <= 31)
1304         ) {
1305                 printf("\n Drive conforms to: %s: ",
1306                         (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1307                 if (id->major_rev_num != 0x0000 /* NOVAL_0 */
1308                  && id->major_rev_num != 0xFFFF /* NOVAL_1 */
1309                 ) {
1310                         for (i = 0; i <= 15; i++) {
1311                                 if (id->major_rev_num & (1<<i))
1312                                         printf(" ATA/ATAPI-%u", i);
1313                         }
1314                 }
1315         }
1316 #endif /* __NEW_HD_DRIVE_ID */
1317         printf("\n\n * current active mode\n\n");
1318 }
1319 #endif
1320
1321 static void flush_buffer_cache(/*int fd*/ void)
1322 {
1323         fsync(fd);                              /* flush buffers */
1324         ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1325 #ifdef HDIO_DRIVE_CMD
1326         sleep(1);
1327         if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) {       /* await completion */
1328                 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1329                         bb_perror_msg("HDIO_DRIVE_CMD");
1330                 else
1331                         bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1332         }
1333 #endif
1334 }
1335
1336 static void seek_to_zero(/*int fd*/ void)
1337 {
1338         xlseek(fd, (off_t) 0, SEEK_SET);
1339 }
1340
1341 static void read_big_block(/*int fd,*/ char *buf)
1342 {
1343         int i;
1344
1345         xread(fd, buf, TIMING_BUF_BYTES);
1346         /* access all sectors of buf to ensure the read fully completed */
1347         for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1348                 buf[i] &= 1;
1349 }
1350
1351 static unsigned dev_size_mb(/*int fd*/ void)
1352 {
1353         union {
1354                 unsigned long long blksize64;
1355                 unsigned blksize32;
1356         } u;
1357
1358         if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1359                 u.blksize64 /= (1024 * 1024);
1360         } else {
1361                 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1362                 u.blksize64 = u.blksize32 / (2 * 1024);
1363         }
1364         if (u.blksize64 > UINT_MAX)
1365                 return UINT_MAX;
1366         return u.blksize64;
1367 }
1368
1369 static void print_timing(unsigned m, unsigned elapsed_us)
1370 {
1371         unsigned sec = elapsed_us / 1000000;
1372         unsigned hs = (elapsed_us % 1000000) / 10000;
1373
1374         printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1375                 m, sec, hs,
1376                 /* "| 1" prevents div-by-0 */
1377                 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1378                 // ~= (m * 1024) / (elapsed_us / 1000000)
1379                 // = kb / elapsed_sec
1380         );
1381 }
1382
1383 static void do_time(int cache /*,int fd*/)
1384 /* cache=1: time cache: repeatedly read N MB at offset 0
1385  * cache=0: time device: linear read, starting at offset 0
1386  */
1387 {
1388         unsigned max_iterations, iterations;
1389         unsigned start; /* doesn't need to be long long */
1390         unsigned elapsed, elapsed2;
1391         unsigned total_MB;
1392         char *buf = xmalloc(TIMING_BUF_BYTES);
1393
1394         if (mlock(buf, TIMING_BUF_BYTES))
1395                 bb_perror_msg_and_die("mlock");
1396
1397         /* Clear out the device request queues & give them time to complete.
1398          * NB: *small* delay. User is expected to have a clue and to not run
1399          * heavy io in parallel with measurements. */
1400         sync();
1401         sleep(1);
1402         if (cache) { /* Time cache */
1403                 seek_to_zero();
1404                 read_big_block(buf);
1405                 printf("Timing buffer-cache reads: ");
1406         } else { /* Time device */
1407                 printf("Timing buffered disk reads:");
1408         }
1409         fflush_all();
1410
1411         /* Now do the timing */
1412         iterations = 0;
1413         /* Max time to run (small for cache, avoids getting
1414          * huge total_MB which can overlow unsigned type) */
1415         elapsed2 = 510000; /* cache */
1416         max_iterations = UINT_MAX;
1417         if (!cache) {
1418                 elapsed2 = 3000000; /* not cache */
1419                 /* Don't want to read past the end! */
1420                 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1421         }
1422         start = monotonic_us();
1423         do {
1424                 if (cache)
1425                         seek_to_zero();
1426                 read_big_block(buf);
1427                 elapsed = (unsigned)monotonic_us() - start;
1428                 ++iterations;
1429         } while (elapsed < elapsed2 && iterations < max_iterations);
1430         total_MB = iterations * TIMING_BUF_MB;
1431         //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1432         if (cache) {
1433                 /* Cache: remove lseek() and monotonic_us() overheads
1434                  * from elapsed */
1435                 start = monotonic_us();
1436                 do {
1437                         seek_to_zero();
1438                         elapsed2 = (unsigned)monotonic_us() - start;
1439                 } while (--iterations);
1440                 //printf(" elapsed2:%u ", elapsed2);
1441                 elapsed -= elapsed2;
1442                 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1443                 flush_buffer_cache();
1444         }
1445         print_timing(total_MB, elapsed);
1446         munlock(buf, TIMING_BUF_BYTES);
1447         free(buf);
1448 }
1449
1450 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1451 static void bus_state_value(unsigned value)
1452 {
1453         if (value == BUSSTATE_ON)
1454                 on_off(1);
1455         else if (value == BUSSTATE_OFF)
1456                 on_off(0);
1457         else if (value == BUSSTATE_TRISTATE)
1458                 printf(" (tristate)\n");
1459         else
1460                 printf(" (unknown: %d)\n", value);
1461 }
1462 #endif
1463
1464 #ifdef HDIO_DRIVE_CMD
1465 static void interpret_standby(uint8_t standby)
1466 {
1467         printf(" (");
1468         if (standby == 0) {
1469                 printf("off");
1470         } else if (standby <= 240 || standby == 252 || standby == 255) {
1471                 /* standby is in 5 sec units */
1472                 unsigned t = standby * 5;
1473                 printf("%u minutes %u seconds", t / 60, t % 60);
1474         } else if (standby <= 251) {
1475                 unsigned t = (standby - 240); /* t is in 30 min units */;
1476                 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0');
1477         }
1478         if (standby == 253)
1479                 printf("vendor-specific");
1480         if (standby == 254)
1481                 printf("reserved");
1482         printf(")\n");
1483 }
1484
1485 static const uint8_t xfermode_val[] ALIGN1 = {
1486          8,      9,     10,     11,     12,     13,     14,     15,
1487         16,     17,     18,     19,     20,     21,     22,     23,
1488         32,     33,     34,     35,     36,     37,     38,     39,
1489         64,     65,     66,     67,     68,     69,     70,     71
1490 };
1491 /* NB: we save size by _not_ storing terninating NUL! */
1492 static const char xfermode_name[][5] ALIGN1 = {
1493         "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1494         "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1495         "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1496         "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1497 };
1498
1499 static int translate_xfermode(const char *name)
1500 {
1501         int val;
1502         unsigned i;
1503
1504         for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1505                 if (!strncmp(name, xfermode_name[i], 5))
1506                         if (strlen(name) <= 5)
1507                                 return xfermode_val[i];
1508         }
1509         /* Negative numbers are invalid and are caught later */
1510         val = bb_strtoi(name, NULL, 10);
1511         if (!errno)
1512                 return val;
1513         return -1;
1514 }
1515
1516 static void interpret_xfermode(unsigned xfermode)
1517 {
1518         printf(" (");
1519         if (xfermode == 0)
1520                 printf("default PIO mode");
1521         else if (xfermode == 1)
1522                 printf("default PIO mode, disable IORDY");
1523         else if (xfermode >= 8 && xfermode <= 15)
1524                 printf("PIO flow control mode%u", xfermode - 8);
1525         else if (xfermode >= 16 && xfermode <= 23)
1526                 printf("singleword DMA mode%u", xfermode - 16);
1527         else if (xfermode >= 32 && xfermode <= 39)
1528                 printf("multiword DMA mode%u", xfermode - 32);
1529         else if (xfermode >= 64 && xfermode <= 71)
1530                 printf("UltraDMA mode%u", xfermode - 64);
1531         else
1532                 printf("unknown");
1533         printf(")\n");
1534 }
1535 #endif /* HDIO_DRIVE_CMD */
1536
1537 static void print_flag(int flag, const char *s, unsigned long value)
1538 {
1539         if (flag)
1540                 printf(" setting %s to %ld\n", s, value);
1541 }
1542
1543 static void process_dev(char *devname)
1544 {
1545         /*int fd;*/
1546         long parm, multcount;
1547 #ifndef HDIO_DRIVE_CMD
1548         int force_operation = 0;
1549 #endif
1550         /* Please restore args[n] to these values after each ioctl
1551            except for args[2] */
1552         unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1553         const char *fmt = " %s\t= %2ld";
1554
1555         /*fd = xopen_nonblocking(devname);*/
1556         xmove_fd(xopen_nonblocking(devname), fd);
1557         printf("\n%s:\n", devname);
1558
1559         if (getset_readahead == IS_SET) {
1560                 print_flag(getset_readahead, "fs readahead", Xreadahead);
1561                 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1562         }
1563 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1564         if (unregister_hwif) {
1565                 printf(" attempting to unregister hwif#%lu\n", hwif);
1566                 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1567         }
1568 #endif
1569 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1570         if (scan_hwif == IS_SET) {
1571                 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1572                 args[0] = hwif_data;
1573                 args[1] = hwif_ctrl;
1574                 args[2] = hwif_irq;
1575                 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1576                 args[0] = WIN_SETFEATURES;
1577                 args[1] = 0;
1578         }
1579 #endif
1580         if (set_piomode) {
1581                 if (noisy_piomode) {
1582                         printf(" attempting to ");
1583                         if (piomode == 255)
1584                                 printf("auto-tune PIO mode\n");
1585                         else if (piomode < 100)
1586                                 printf("set PIO mode to %d\n", piomode);
1587                         else if (piomode < 200)
1588                                 printf("set MDMA mode to %d\n", (piomode-100));
1589                         else
1590                                 printf("set UDMA mode to %d\n", (piomode-200));
1591                 }
1592                 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1593         }
1594         if (getset_io32bit == IS_SET) {
1595                 print_flag(getset_io32bit, "32-bit IO_support flag", io32bit);
1596                 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1597         }
1598         if (getset_mult == IS_SET) {
1599                 print_flag(getset_mult, "multcount", mult);
1600 #ifdef HDIO_DRIVE_CMD
1601                 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1602 #else
1603                 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1604 #endif
1605         }
1606         if (getset_readonly == IS_SET) {
1607                 print_flag_on_off(getset_readonly, "readonly", readonly);
1608                 ioctl_or_warn(fd, BLKROSET, &readonly);
1609         }
1610         if (getset_unmask == IS_SET) {
1611                 print_flag_on_off(getset_unmask, "unmaskirq", unmask);
1612                 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1613         }
1614 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1615         if (getset_dma == IS_SET) {
1616                 print_flag_on_off(getset_dma, "using_dma", dma);
1617                 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1618         }
1619 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1620 #ifdef HDIO_SET_QDMA
1621         if (getset_dma_q == IS_SET) {
1622                 print_flag_on_off(getset_dma_q, "DMA queue_depth", dma_q);
1623                 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1624         }
1625 #endif
1626         if (getset_nowerr == IS_SET) {
1627                 print_flag_on_off(getset_nowerr, "nowerr", nowerr);
1628                 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1629         }
1630         if (getset_keep == IS_SET) {
1631                 print_flag_on_off(getset_keep, "keep_settings", keep);
1632                 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1633         }
1634 #ifdef HDIO_DRIVE_CMD
1635         if (getset_doorlock == IS_SET) {
1636                 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1637                 args[2] = 0;
1638                 print_flag_on_off(getset_doorlock, "drive doorlock", doorlock);
1639                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1640                 args[0] = WIN_SETFEATURES;
1641         }
1642         if (getset_dkeep == IS_SET) {
1643                 /* lock/unlock the drive's "feature" settings */
1644                 print_flag_on_off(getset_dkeep, "drive keep features", dkeep);
1645                 args[2] = dkeep ? 0x66 : 0xcc;
1646                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1647         }
1648         if (getset_defects == IS_SET) {
1649                 args[2] = defects ? 0x04 : 0x84;
1650                 print_flag(getset_defects, "drive defect-mgmt", defects);
1651                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1652         }
1653         if (getset_prefetch == IS_SET) {
1654                 args[1] = prefetch;
1655                 args[2] = 0xab;
1656                 print_flag(getset_prefetch, "drive prefetch", prefetch);
1657                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1658                 args[1] = 0;
1659         }
1660         if (set_xfermode) {
1661                 args[1] = xfermode_requested;
1662                 args[2] = 3;
1663                 print_flag(1, "xfermode", xfermode_requested);
1664                 interpret_xfermode(xfermode_requested);
1665                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1666                 args[1] = 0;
1667         }
1668         if (getset_lookahead == IS_SET) {
1669                 args[2] = lookahead ? 0xaa : 0x55;
1670                 print_flag_on_off(getset_lookahead, "drive read-lookahead", lookahead);
1671                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1672         }
1673         if (getset_apmmode == IS_SET) {
1674                 /* feature register */
1675                 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */;
1676                 args[1] = apmmode; /* sector count register 1-255 */
1677                 printf(" setting APM level to %s 0x%02lX (%ld)\n",
1678                         (apmmode == 255) ? "disabled" : "",
1679                         apmmode, apmmode);
1680                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1681                 args[1] = 0;
1682         }
1683         if (getset_wcache == IS_SET) {
1684 #ifdef DO_FLUSHCACHE
1685 #ifndef WIN_FLUSHCACHE
1686 #define WIN_FLUSHCACHE 0xe7
1687 #endif
1688 #endif /* DO_FLUSHCACHE */
1689                 args[2] = wcache ? 0x02 : 0x82;
1690                 print_flag_on_off(getset_wcache, "drive write-caching", wcache);
1691 #ifdef DO_FLUSHCACHE
1692                 if (!wcache)
1693                         ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1694 #endif /* DO_FLUSHCACHE */
1695                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1696 #ifdef DO_FLUSHCACHE
1697                 if (!wcache)
1698                         ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1699 #endif /* DO_FLUSHCACHE */
1700         }
1701
1702         /* In code below, we do not preserve args[0], but the rest
1703            is preserved, including args[2] */
1704         args[2] = 0;
1705
1706         if (set_standbynow) {
1707 #ifndef WIN_STANDBYNOW1
1708 #define WIN_STANDBYNOW1 0xE0
1709 #endif
1710 #ifndef WIN_STANDBYNOW2
1711 #define WIN_STANDBYNOW2 0x94
1712 #endif
1713                 printf(" issuing standby command\n");
1714                 args[0] = WIN_STANDBYNOW1;
1715                 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1716         }
1717         if (set_sleepnow) {
1718 #ifndef WIN_SLEEPNOW1
1719 #define WIN_SLEEPNOW1 0xE6
1720 #endif
1721 #ifndef WIN_SLEEPNOW2
1722 #define WIN_SLEEPNOW2 0x99
1723 #endif
1724                 printf(" issuing sleep command\n");
1725                 args[0] = WIN_SLEEPNOW1;
1726                 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1727         }
1728         if (set_seagate) {
1729                 args[0] = 0xfb;
1730                 printf(" disabling Seagate auto powersaving mode\n");
1731                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1732         }
1733         if (getset_standby == IS_SET) {
1734                 args[0] = WIN_SETIDLE1;
1735                 args[1] = standby_requested;
1736                 print_flag(1, "standby", standby_requested);
1737                 interpret_standby(standby_requested);
1738                 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1739                 args[1] = 0;
1740         }
1741 #else   /* HDIO_DRIVE_CMD */
1742         if (force_operation) {
1743                 char buf[512];
1744                 flush_buffer_cache();
1745                 if (-1 == read(fd, buf, sizeof(buf)))
1746                         bb_perror_msg("read of 512 bytes failed");
1747         }
1748 #endif  /* HDIO_DRIVE_CMD */
1749         if (getset_mult || get_identity) {
1750                 multcount = -1;
1751                 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1752                         /* To be coherent with ioctl_or_warn. */
1753                         if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1754                                 bb_perror_msg("HDIO_GET_MULTCOUNT");
1755                         else
1756                                 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1757                 } else if (getset_mult) {
1758                         printf(fmt, "multcount", multcount);
1759                         on_off(multcount != 0);
1760                 }
1761         }
1762         if (getset_io32bit) {
1763                 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1764                         printf(" IO_support\t=%3ld (", parm);
1765                         if (parm == 0)
1766                                 printf("default 16-bit)\n");
1767                         else if (parm == 2)
1768                                 printf("16-bit)\n");
1769                         else if (parm == 1)
1770                                 printf("32-bit)\n");
1771                         else if (parm == 3)
1772                                 printf("32-bit w/sync)\n");
1773                         else if (parm == 8)
1774                                 printf("Request-Queue-Bypass)\n");
1775                         else
1776                                 printf("\?\?\?)\n");
1777                 }
1778         }
1779         if (getset_unmask) {
1780                 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
1781                         print_value_on_off("unmaskirq", parm);
1782         }
1783 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1784         if (getset_dma) {
1785                 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1786                         printf(fmt, "using_dma", parm);
1787                         if (parm == 8)
1788                                 printf(" (DMA-Assisted-PIO)\n");
1789                         else
1790                                 on_off(parm != 0);
1791                 }
1792         }
1793 #endif
1794 #ifdef HDIO_GET_QDMA
1795         if (getset_dma_q) {
1796                 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
1797                         print_value_on_off("queue_depth", parm);
1798         }
1799 #endif
1800         if (getset_keep) {
1801                 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
1802                         print_value_on_off("keepsettings", parm);
1803         }
1804         if (getset_nowerr) {
1805                 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
1806                         print_value_on_off("nowerr", parm);
1807         }
1808         if (getset_readonly) {
1809                 if (!ioctl_or_warn(fd, BLKROGET, &parm))
1810                         print_value_on_off("readonly", parm);
1811         }
1812         if (getset_readahead) {
1813                 if (!ioctl_or_warn(fd, BLKRAGET, &parm))
1814                         print_value_on_off("readahead", parm);
1815         }
1816         if (get_geom) {
1817                 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1818                         struct hd_geometry g;
1819
1820                         if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1821                                 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1822                                         g.cylinders, g.heads, g.sectors, parm, g.start);
1823                 }
1824         }
1825 #ifdef HDIO_DRIVE_CMD
1826         if (get_powermode) {
1827 #ifndef WIN_CHECKPOWERMODE1
1828 #define WIN_CHECKPOWERMODE1 0xE5
1829 #endif
1830 #ifndef WIN_CHECKPOWERMODE2
1831 #define WIN_CHECKPOWERMODE2 0x98
1832 #endif
1833                 const char *state;
1834
1835                 args[0] = WIN_CHECKPOWERMODE1;
1836                 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1837                         if (errno != EIO || args[0] != 0 || args[1] != 0)
1838                                 state = "unknown";
1839                         else
1840                                 state = "sleeping";
1841                 } else
1842                         state = (args[2] == 255) ? "active/idle" : "standby";
1843                 args[1] = args[2] = 0;
1844
1845                 printf(" drive state is:  %s\n", state);
1846         }
1847 #endif
1848 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1849         if (perform_reset) {
1850                 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1851         }
1852 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1853 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1854         if (perform_tristate) {
1855                 args[0] = 0;
1856                 args[1] = tristate;
1857                 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1858         }
1859 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1860 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1861         if (get_identity) {
1862                 struct hd_driveid id;
1863
1864                 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1865                         if (multcount != -1) {
1866                                 id.multsect = multcount;
1867                                 id.multsect_valid |= 1;
1868                         } else
1869                                 id.multsect_valid &= ~1;
1870                         dump_identity(&id);
1871                 } else if (errno == -ENOMSG)
1872                         printf(" no identification info available\n");
1873                 else if (ENABLE_IOCTL_HEX2STR_ERROR)  /* To be coherent with ioctl_or_warn */
1874                         bb_perror_msg("HDIO_GET_IDENTITY");
1875                 else
1876                         bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1877         }
1878
1879         if (get_IDentity) {
1880                 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1881
1882                 memset(args1, 0, sizeof(args1));
1883                 args1[0] = WIN_IDENTIFY;
1884                 args1[3] = 1;
1885                 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1886                         identify((void *)(args1 + 4));
1887         }
1888 #endif
1889 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1890         if (getset_busstate == IS_SET) {
1891                 print_flag(1, "bus state", busstate);
1892                 bus_state_value(busstate);
1893                 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1894         }
1895         if (getset_busstate) {
1896                 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1897                         printf(fmt, "bus state", parm);
1898                         bus_state_value(parm);
1899                 }
1900         }
1901 #endif
1902         if (reread_partn)
1903                 ioctl_or_warn(fd, BLKRRPART, NULL);
1904
1905         if (do_ctimings)
1906                 do_time(1 /*,fd*/); /* time cache */
1907         if (do_timings)
1908                 do_time(0 /*,fd*/); /* time device */
1909         if (do_flush)
1910                 flush_buffer_cache();
1911         close(fd);
1912 }
1913
1914 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1915 static int fromhex(unsigned char c)
1916 {
1917         if (isdigit(c))
1918                 return (c - '0');
1919         if (c >= 'a' && c <= 'f')
1920                 return (c - ('a' - 10));
1921         bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1922 }
1923
1924 static void identify_from_stdin(void) NORETURN;
1925 static void identify_from_stdin(void)
1926 {
1927         uint16_t sbuf[256];
1928         unsigned char buf[1280];
1929         unsigned char *b = (unsigned char *)buf;
1930         int i;
1931
1932         xread(STDIN_FILENO, buf, 1280);
1933
1934         // Convert the newline-separated hex data into an identify block.
1935
1936         for (i = 0; i < 256; i++) {
1937                 int j;
1938                 for (j = 0; j < 4; j++)
1939                         sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1940         }
1941
1942         // Parse the data.
1943
1944         identify(sbuf);
1945 }
1946 #else
1947 void identify_from_stdin(void);
1948 #endif
1949
1950 /* busybox specific stuff */
1951 static int parse_opts(unsigned long *value, int min, int max)
1952 {
1953         if (optarg) {
1954                 *value = xatol_range(optarg, min, max);
1955                 return IS_SET;
1956         }
1957         return IS_GET;
1958 }
1959 static int parse_opts_0_max(unsigned long *value, int max)
1960 {
1961         return parse_opts(value, 0, max);
1962 }
1963 static int parse_opts_0_1(unsigned long *value)
1964 {
1965         return parse_opts(value, 0, 1);
1966 }
1967 static int parse_opts_0_INTMAX(unsigned long *value)
1968 {
1969         return parse_opts(value, 0, INT_MAX);
1970 }
1971
1972 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
1973 {
1974         if (flag) {
1975                 *get = IS_GET;
1976                 if (optarg) {
1977                         *value = translate_xfermode(optarg);
1978                         *set = (*value > -1);
1979                 }
1980         }
1981 }
1982
1983 /*------- getopt short options --------*/
1984 static const char hdparm_options[] ALIGN1 =
1985         "gfu::n::p:r::m::c::k::a::B:tT"
1986         IF_FEATURE_HDPARM_GET_IDENTITY("iI")
1987         IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
1988 #ifdef HDIO_DRIVE_CMD
1989         "S:D:P:X:K:A:L:W:CyYzZ"
1990 #endif
1991         IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
1992 #ifdef HDIO_GET_QDMA
1993 #ifdef HDIO_SET_QDMA
1994         "Q:"
1995 #else
1996         "Q"
1997 #endif
1998 #endif
1999         IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
2000         IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
2001         IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
2002 /*-------------------------------------*/
2003
2004 /* our main() routine: */
2005 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2006 int hdparm_main(int argc, char **argv)
2007 {
2008         int c;
2009         int flagcount = 0;
2010
2011         while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2012                 flagcount++;
2013                 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2014                 IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2015                 get_geom |= (c == 'g');
2016                 do_flush |= (c == 'f');
2017                 if (c == 'u') getset_unmask    = parse_opts_0_1(&unmask);
2018         IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
2019                 if (c == 'd') getset_dma       = parse_opts_0_max(&dma, 9);
2020         )
2021                 if (c == 'n') getset_nowerr    = parse_opts_0_1(&nowerr);
2022                 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2023                 if (c == 'r') getset_readonly  = parse_opts_0_1(&readonly);
2024                 if (c == 'm') getset_mult      = parse_opts_0_INTMAX(&mult /*32*/);
2025                 if (c == 'c') getset_io32bit   = parse_opts_0_INTMAX(&io32bit /*8*/);
2026                 if (c == 'k') getset_keep      = parse_opts_0_1(&keep);
2027                 if (c == 'a') getset_readahead = parse_opts_0_INTMAX(&Xreadahead);
2028                 if (c == 'B') getset_apmmode   = parse_opts(&apmmode, 1, 255);
2029                 do_flush |= do_timings |= (c == 't');
2030                 do_flush |= do_ctimings |= (c == 'T');
2031 #ifdef HDIO_DRIVE_CMD
2032                 if (c == 'S') getset_standby  = parse_opts_0_max(&standby_requested, 255);
2033                 if (c == 'D') getset_defects  = parse_opts_0_INTMAX(&defects);
2034                 if (c == 'P') getset_prefetch = parse_opts_0_INTMAX(&prefetch);
2035                 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2036                 if (c == 'K') getset_dkeep     = parse_opts_0_1(&prefetch);
2037                 if (c == 'A') getset_lookahead = parse_opts_0_1(&lookahead);
2038                 if (c == 'L') getset_doorlock  = parse_opts_0_1(&doorlock);
2039                 if (c == 'W') getset_wcache    = parse_opts_0_1(&wcache);
2040                 get_powermode |= (c == 'C');
2041                 set_standbynow |= (c == 'y');
2042                 set_sleepnow |= (c == 'Y');
2043                 reread_partn |= (c == 'z');
2044                 set_seagate |= (c == 'Z');
2045 #endif
2046                 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') unregister_hwif = parse_opts_0_INTMAX(&hwif));
2047 #ifdef HDIO_GET_QDMA
2048                 if (c == 'Q') {
2049                         getset_dma_q = parse_opts_0_INTMAX(&dma_q);
2050                 }
2051 #endif
2052                 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2053                 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') perform_tristate = parse_opts_0_1(&tristate));
2054                 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') getset_busstate = parse_opts_0_max(&busstate, 2));
2055 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2056                 if (c == 'R') {
2057                         scan_hwif = parse_opts_0_INTMAX(&hwif_data);
2058                         hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
2059                         hwif_irq  = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
2060                         /* Move past the 2 additional arguments */
2061                         argv += 2;
2062                         argc -= 2;
2063                 }
2064 #endif
2065         }
2066         /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2067         if (!flagcount) {
2068                 getset_mult = getset_io32bit = getset_unmask = getset_keep = getset_readonly = getset_readahead = get_geom = IS_GET;
2069                 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(getset_dma = IS_GET);
2070         }
2071         argv += optind;
2072
2073         if (!*argv) {
2074                 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2075                         identify_from_stdin(); /* EXIT */
2076                 bb_show_usage();
2077         }
2078
2079         do {
2080                 process_dev(*argv++);
2081         } while (*argv);
2082
2083         return EXIT_SUCCESS;
2084 }