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