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