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