1 /* vi: set sw=4 ts=4: */
3 * hdparm implementation for busybox
5 * Copyright (C) [2003] by [Matteo Croce] <3297627799@wind.it>
6 * Hacked by Tito <farmatito@tiscali.it> for size optimization.
8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
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
14 //config:config HDPARM
15 //config: bool "hdparm"
17 //config: select PLATFORM_LINUX
19 //config: Get/Set hard drive parameters. Primarily intended for ATA
20 //config: drives. Adds about 13k (or around 30k if you enable the
21 //config: FEATURE_HDPARM_GET_IDENTITY option)....
23 //config:config FEATURE_HDPARM_GET_IDENTITY
24 //config: bool "Support obtaining detailed information directly from drives"
26 //config: depends on HDPARM
28 //config: Enables the -I and -i options to obtain detailed information
29 //config: directly from drives about their capabilities and supported ATA
30 //config: feature set. If no device name is specified, hdparm will read
31 //config: identify data from stdin. Enabling this option will add about 16k...
33 //config:config FEATURE_HDPARM_HDIO_SCAN_HWIF
34 //config: bool "Register an IDE interface (DANGEROUS)"
36 //config: depends on HDPARM
38 //config: Enables the 'hdparm -R' option to register an IDE interface.
39 //config: This is dangerous stuff, so you should probably say N.
41 //config:config FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
42 //config: bool "Un-register an IDE interface (DANGEROUS)"
44 //config: depends on HDPARM
46 //config: Enables the 'hdparm -U' option to un-register an IDE interface.
47 //config: This is dangerous stuff, so you should probably say N.
49 //config:config FEATURE_HDPARM_HDIO_DRIVE_RESET
50 //config: bool "Perform device reset (DANGEROUS)"
52 //config: depends on HDPARM
54 //config: Enables the 'hdparm -w' option to perform a device reset.
55 //config: This is dangerous stuff, so you should probably say N.
57 //config:config FEATURE_HDPARM_HDIO_TRISTATE_HWIF
58 //config: bool "Tristate device for hotswap (DANGEROUS)"
60 //config: depends on HDPARM
62 //config: Enables the 'hdparm -x' option to tristate device for hotswap,
63 //config: and the '-b' option to get/set bus state. This is dangerous
64 //config: stuff, so you should probably say N.
66 //config:config FEATURE_HDPARM_HDIO_GETSET_DMA
67 //config: bool "Get/set using_dma flag"
69 //config: depends on HDPARM
71 //config: Enables the 'hdparm -d' option to get/set using_dma flag.
73 //usage:#define hdparm_trivial_usage
74 //usage: "[OPTIONS] [DEVICE]"
75 //usage:#define hdparm_full_usage "\n\n"
76 //usage: " -a Get/set fs readahead"
77 //usage: "\n -A Set drive read-lookahead flag (0/1)"
78 //usage: "\n -b Get/set bus state (0 == off, 1 == on, 2 == tristate)"
79 //usage: "\n -B Set Advanced Power Management setting (1-255)"
80 //usage: "\n -c Get/set IDE 32-bit IO setting"
81 //usage: "\n -C Check IDE power mode status"
82 //usage: IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
83 //usage: "\n -d Get/set using_dma flag")
84 //usage: "\n -D Enable/disable drive defect-mgmt"
85 //usage: "\n -f Flush buffer cache for device on exit"
86 //usage: "\n -g Display drive geometry"
87 //usage: "\n -h Display terse usage information"
88 //usage: IF_FEATURE_HDPARM_GET_IDENTITY(
89 //usage: "\n -i Display drive identification")
90 //usage: IF_FEATURE_HDPARM_GET_IDENTITY(
91 //usage: "\n -I Detailed/current information directly from drive")
92 //usage: "\n -k Get/set keep_settings_over_reset flag (0/1)"
93 //usage: "\n -K Set drive keep_features_over_reset flag (0/1)"
94 //usage: "\n -L Set drive doorlock (0/1) (removable harddisks only)"
95 //usage: "\n -m Get/set multiple sector count"
96 //usage: "\n -n Get/set ignore-write-errors flag (0/1)"
97 //usage: "\n -p Set PIO mode on IDE interface chipset (0,1,2,3,4,...)"
98 //usage: "\n -P Set drive prefetch count"
99 /* //usage: "\n -q Change next setting quietly" - not supported ib bbox */
100 //usage: "\n -Q Get/set DMA tagged-queuing depth (if supported)"
101 //usage: "\n -r Get/set readonly flag (DANGEROUS to set)"
102 //usage: IF_FEATURE_HDPARM_HDIO_SCAN_HWIF(
103 //usage: "\n -R Register an IDE interface (DANGEROUS)")
104 //usage: "\n -S Set standby (spindown) timeout"
105 //usage: "\n -t Perform device read timings"
106 //usage: "\n -T Perform cache read timings"
107 //usage: "\n -u Get/set unmaskirq flag (0/1)"
108 //usage: IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(
109 //usage: "\n -U Unregister an IDE interface (DANGEROUS)")
110 //usage: "\n -v Defaults; same as -mcudkrag for IDE drives"
111 //usage: "\n -V Display program version and exit immediately"
112 //usage: IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(
113 //usage: "\n -w Perform device reset (DANGEROUS)")
114 //usage: "\n -W Set drive write-caching flag (0/1) (DANGEROUS)"
115 //usage: IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(
116 //usage: "\n -x Tristate device for hotswap (0/1) (DANGEROUS)")
117 //usage: "\n -X Set IDE xfer mode (DANGEROUS)"
118 //usage: "\n -y Put IDE drive in standby mode"
119 //usage: "\n -Y Put IDE drive to sleep"
120 //usage: "\n -Z Disable Seagate auto-powersaving mode"
121 //usage: "\n -z Reread partition table"
124 #include "common_bufsiz.h"
125 /* must be _after_ libbb.h: */
126 #include <linux/hdreg.h>
127 #include <sys/mount.h>
128 #if !defined(BLKGETSIZE64)
129 # define BLKGETSIZE64 _IOR(0x12,114,size_t)
134 #define NO_DEV 0xffff
135 #define ATA_DEV 0x0000
136 #define ATAPI_DEV 0x0001
138 /* word definitions */
139 /* ---------------- */
140 #define GEN_CONFIG 0 /* general configuration */
141 #define LCYLS 1 /* number of logical cylinders */
142 #define CONFIG 2 /* specific configuration */
143 #define LHEADS 3 /* number of logical heads */
144 #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
145 #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
146 #define LSECTS 6 /* number of logical sectors/track */
147 #define START_SERIAL 10 /* ASCII serial number */
148 #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
149 #define BUF_TYPE 20 /* buffer type (ATA-1) */
150 #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
151 #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
152 #define START_FW_REV 23 /* ASCII firmware revision */
153 #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
154 #define START_MODEL 27 /* ASCII model number */
155 #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
156 #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
157 #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
158 #define CAPAB_0 49 /* capabilities */
160 #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
161 #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
162 #define WHATS_VALID 53 /* what fields are valid */
163 #define LCYLS_CUR 54 /* current logical cylinders */
164 #define LHEADS_CUR 55 /* current logical heads */
165 #define LSECTS_CUR 56 /* current logical sectors/track */
166 #define CAPACITY_LSB 57 /* current capacity in sectors */
167 #define CAPACITY_MSB 58
168 #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
169 #define LBA_SECTS_LSB 60 /* LBA: total number of user */
170 #define LBA_SECTS_MSB 61 /* addressable sectors */
171 #define SINGLE_DMA 62 /* singleword DMA modes */
172 #define MULTI_DMA 63 /* multiword DMA modes */
173 #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
174 /* multiword DMA xfer cycle time: */
175 #define DMA_TIME_MIN 65 /* - minimum */
176 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
177 /* minimum PIO xfer cycle time: */
178 #define PIO_NO_FLOW 67 /* - without flow control */
179 #define PIO_FLOW 68 /* - with IORDY flow control */
180 #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
181 #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
182 #define CDR_MAJOR 73 /* CD ROM: major version number */
183 #define CDR_MINOR 74 /* CD ROM: minor version number */
184 #define QUEUE_DEPTH 75 /* queue depth */
185 #define MAJOR 80 /* major version number */
186 #define MINOR 81 /* minor version number */
187 #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
188 #define CMDS_SUPP_1 83
189 #define CMDS_SUPP_2 84
190 #define CMDS_EN_0 85 /* command/feature set(s) enabled */
193 #define ULTRA_DMA 88 /* ultra DMA modes */
194 /* time to complete security erase */
195 #define ERASE_TIME 89 /* - ordinary */
196 #define ENH_ERASE_TIME 90 /* - enhanced */
197 #define ADV_PWR 91 /* current advanced power management level
198 in low byte, 0x40 in high byte. */
199 #define PSWD_CODE 92 /* master password revision code */
200 #define HWRST_RSLT 93 /* hardware reset result */
201 #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
202 #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
203 #define LBA_MID 101 /* bits are used, but addr 103 */
204 #define LBA_48_MSB 102 /* has been reserved for LBA in */
205 #define LBA_64_MSB 103 /* the future. */
206 #define RM_STAT 127 /* removable media status notification feature set support */
207 #define SECU_STATUS 128 /* security status */
208 #define CFA_PWR_MODE 160 /* CFA power mode 1 */
209 #define START_MEDIA 176 /* media serial number */
210 #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
211 #define START_MANUF 196 /* media manufacturer I.D. */
212 #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
213 #define INTEGRITY 255 /* integrity word */
215 /* bit definitions within the words */
216 /* -------------------------------- */
218 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
220 #define VALID_VAL 0x4000
221 /* many words are considered invalid if they are either all-0 or all-1 */
222 #define NOVAL_0 0x0000
223 #define NOVAL_1 0xffff
225 /* word 0: gen_config */
226 #define NOT_ATA 0x8000
227 #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
228 #define MEDIA_REMOVABLE 0x0080
229 #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
230 #define INCOMPLETE 0x0004
231 #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
232 #define DRQ_RESPONSE_TIME 0x0060
233 #define DRQ_3MS_VAL 0x0000
234 #define DRQ_INTR_VAL 0x0020
235 #define DRQ_50US_VAL 0x0040
236 #define PKT_SIZE_SUPPORTED 0x0003
237 #define PKT_SIZE_12_VAL 0x0000
238 #define PKT_SIZE_16_VAL 0x0001
239 #define EQPT_TYPE 0x1f00
244 /* word 1: number of logical cylinders */
245 #define LCYLS_MAX 0x3fff /* maximum allowable value */
247 /* word 2: specific configuration
248 * (a) require SET FEATURES to spin-up
249 * (b) require spin-up to fully reply to IDENTIFY DEVICE
251 #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
252 #define STBY_ID_VAL 0x738c /* (a) and not (b) */
253 #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
254 #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
256 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
257 #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
258 #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
260 /* word 49: capabilities 0 */
261 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
262 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
263 #define IORDY_OFF 0x0400 /* 1=may be disabled */
264 #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
265 #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
266 #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
267 #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
268 #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
269 #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
271 /* word 50: capabilities 1 */
272 #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
274 /* words 51 & 52: PIO & DMA cycle times */
275 #define MODE 0xff00 /* the mode is in the MSBs */
277 /* word 53: whats_valid */
278 #define OK_W88 0x0004 /* the ultra_dma info is valid */
279 #define OK_W64_70 0x0002 /* see above for word descriptions */
280 #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
282 /*word 63,88: dma_mode, ultra_dma_mode*/
283 #define MODE_MAX 7 /* bit definitions force udma <=7 (when
284 * udma >=8 comes out it'll have to be
285 * defined in a new dma_mode word!) */
287 /* word 64: PIO transfer modes */
288 #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
289 #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
291 /* word 75: queue_depth */
292 #define DEPTH_BITS 0x001f /* bits used for queue depth */
294 /* words 80-81: version numbers */
295 /* NOVAL_0 or NOVAL_1 means device does not report version */
297 /* word 81: minor version number */
298 #define MINOR_MAX 0x22
299 /* words 82-84: cmds/feats supported */
300 #define CMDS_W82 0x77ff /* word 82: defined command locations*/
301 #define CMDS_W83 0x3fff /* word 83: defined command locations*/
302 #define CMDS_W84 0x002f /* word 83: defined command locations*/
303 #define SUPPORT_48_BIT 0x0400
304 #define NUM_CMD_FEAT_STR 48
306 /* words 85-87: cmds/feats enabled */
307 /* use cmd_feat_str[] to display what commands and features have
308 * been enabled with words 85-87
311 /* words 89, 90, SECU ERASE TIME */
312 #define ERASE_BITS 0x00ff
314 /* word 92: master password revision */
315 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
317 /* word 93: hw reset result */
318 #define CBLID 0x2000 /* CBLID status */
319 #define RST0 0x0001 /* 1=reset to device #0 */
320 #define DEV_DET 0x0006 /* how device num determined */
321 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
322 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
324 /* word 127: removable media status notification feature set support */
325 #define RM_STAT_BITS 0x0003
326 #define RM_STAT_SUP 0x0001
328 /* word 128: security */
329 #define SECU_ENABLED 0x0002
330 #define SECU_LEVEL 0x0010
331 #define NUM_SECU_STR 6
333 /* word 160: CFA power mode */
334 #define VALID_W160 0x8000 /* 1=word valid */
335 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
336 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
337 #define MAX_AMPS 0x0fff /* value = max current in ma */
339 /* word 255: integrity */
340 #define SIG 0x00ff /* signature location */
341 #define SIG_VAL 0x00a5 /* signature value */
343 #define TIMING_BUF_MB 1
344 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
346 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
357 smallint get_identity, get_geom;
359 smallint do_ctimings, do_timings;
360 smallint reread_partn;
361 smallint set_piomode, noisy_piomode;
362 smallint getset_readahead;
363 smallint getset_readonly;
364 smallint getset_unmask;
365 smallint getset_mult;
367 smallint getset_dma_q;
369 smallint getset_nowerr;
370 smallint getset_keep;
371 smallint getset_io32bit;
373 unsigned long Xreadahead;
374 unsigned long readonly;
375 unsigned long unmask;
380 unsigned long nowerr;
382 unsigned long io32bit;
383 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
387 #ifdef HDIO_DRIVE_CMD
388 smallint set_xfermode, get_xfermode;
389 smallint getset_dkeep;
390 smallint getset_standby;
391 smallint getset_lookahead;
392 smallint getset_prefetch;
393 smallint getset_defects;
394 smallint getset_wcache;
395 smallint getset_doorlock;
396 smallint set_seagate;
397 smallint set_standbynow;
398 smallint set_sleepnow;
399 smallint get_powermode;
400 smallint getset_apmmode;
401 int xfermode_requested;
403 unsigned long standby_requested; /* 0..255 */
404 unsigned long lookahead;
405 unsigned long prefetch;
406 unsigned long defects;
407 unsigned long wcache;
408 unsigned long doorlock;
409 unsigned long apmmode;
411 IF_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
412 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint getset_busstate;)
413 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
414 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
415 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
416 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
417 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
418 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
419 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
420 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
421 unsigned long hwif_data;
422 unsigned long hwif_ctrl;
423 unsigned long hwif_irq;
426 unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
429 #define G (*(struct globals*)bb_common_bufsiz1)
430 #define get_identity (G.get_identity )
431 #define get_geom (G.get_geom )
432 #define do_flush (G.do_flush )
433 #define do_ctimings (G.do_ctimings )
434 #define do_timings (G.do_timings )
435 #define reread_partn (G.reread_partn )
436 #define set_piomode (G.set_piomode )
437 #define noisy_piomode (G.noisy_piomode )
438 #define getset_readahead (G.getset_readahead )
439 #define getset_readonly (G.getset_readonly )
440 #define getset_unmask (G.getset_unmask )
441 #define getset_mult (G.getset_mult )
442 #define getset_dma_q (G.getset_dma_q )
443 #define getset_nowerr (G.getset_nowerr )
444 #define getset_keep (G.getset_keep )
445 #define getset_io32bit (G.getset_io32bit )
446 #define piomode (G.piomode )
447 #define Xreadahead (G.Xreadahead )
448 #define readonly (G.readonly )
449 #define unmask (G.unmask )
450 #define mult (G.mult )
451 #define dma_q (G.dma_q )
452 #define nowerr (G.nowerr )
453 #define keep (G.keep )
454 #define io32bit (G.io32bit )
456 #define getset_dma (G.getset_dma )
457 #define set_xfermode (G.set_xfermode )
458 #define get_xfermode (G.get_xfermode )
459 #define getset_dkeep (G.getset_dkeep )
460 #define getset_standby (G.getset_standby )
461 #define getset_lookahead (G.getset_lookahead )
462 #define getset_prefetch (G.getset_prefetch )
463 #define getset_defects (G.getset_defects )
464 #define getset_wcache (G.getset_wcache )
465 #define getset_doorlock (G.getset_doorlock )
466 #define set_seagate (G.set_seagate )
467 #define set_standbynow (G.set_standbynow )
468 #define set_sleepnow (G.set_sleepnow )
469 #define get_powermode (G.get_powermode )
470 #define getset_apmmode (G.getset_apmmode )
471 #define xfermode_requested (G.xfermode_requested )
472 #define dkeep (G.dkeep )
473 #define standby_requested (G.standby_requested )
474 #define lookahead (G.lookahead )
475 #define prefetch (G.prefetch )
476 #define defects (G.defects )
477 #define wcache (G.wcache )
478 #define doorlock (G.doorlock )
479 #define apmmode (G.apmmode )
480 #define get_IDentity (G.get_IDentity )
481 #define getset_busstate (G.getset_busstate )
482 #define perform_reset (G.perform_reset )
483 #define perform_tristate (G.perform_tristate )
484 #define unregister_hwif (G.unregister_hwif )
485 #define scan_hwif (G.scan_hwif )
486 #define busstate (G.busstate )
487 #define tristate (G.tristate )
488 #define hwif (G.hwif )
489 #define hwif_data (G.hwif_data )
490 #define hwif_ctrl (G.hwif_ctrl )
491 #define hwif_irq (G.hwif_irq )
492 #define INIT_G() do { \
493 setup_common_bufsiz(); \
494 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
498 /* Busybox messages and functions */
499 #if ENABLE_IOCTL_HEX2STR_ERROR
500 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
502 if (!ioctl(fd, cmd, args))
505 return bb_ioctl_or_warn(fd, cmd, args, string);
507 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
509 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
511 if (!ioctl(fd, cmd, args))
514 return bb_ioctl_or_warn(fd, cmd, args);
516 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
519 static void on_off(int value)
521 puts(value ? " (on)" : " (off)");
524 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
527 printf(" setting %s to %lu", s, arg);
532 static void print_value_on_off(const char *str, unsigned long argp)
534 printf(" %s\t= %2lu", str, argp);
538 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
539 static void print_ascii(const char *p, int length)
546 /* every 16bit word is big-endian (i.e. inverted) */
547 /* accessing bytes in 1,0, 3,2, 5,4... sequence */
552 /* find first non-space & print it */
553 while (length && p[ofs] != ' ') {
558 while (length && p[ofs]) {
568 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
571 printf("\t%-20s", string);
572 print_ascii((void*)&val[i], n);
576 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
581 for (ii = 0; ii <= MODE_MAX; ii++) {
582 if (mode_sel & 0x0001) {
583 printf("*%cdma%u ", cc, ii);
587 } else if (mode_sup & 0x0001)
588 printf("%cdma%u ", cc, ii);
596 static const char pkt_str[] ALIGN1 =
597 "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
598 "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
599 "Printer" "\0" /* word 0, bits 12-8 = 02 */
600 "Processor" "\0" /* word 0, bits 12-8 = 03 */
601 "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
602 "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
603 "Scanner" "\0" /* word 0, bits 12-8 = 06 */
604 "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
605 "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
606 "Communications device" "\0" /* word 0, bits 12-8 = 09 */
607 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
608 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
609 "Array controller" "\0" /* word 0, bits 12-8 = 0c */
610 "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
611 "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
612 "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
615 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
616 "reserved" "\0" /* bit 0 */
617 "hard sectored" "\0" /* bit 1 */
618 "soft sectored" "\0" /* bit 2 */
619 "not MFM encoded " "\0" /* bit 3 */
620 "head switch time > 15us" "\0" /* bit 4 */
621 "spindle motor control option" "\0" /* bit 5 */
622 "fixed drive" "\0" /* bit 6 */
623 "removable drive" "\0" /* bit 7 */
624 "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
625 "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
626 "disk xfer rate > 5Mbs" "\0" /* bit 10 */
627 "rotational speed tol." "\0" /* bit 11 */
628 "data strobe offset option" "\0" /* bit 12 */
629 "track offset option" "\0" /* bit 13 */
630 "format speed tolerance gap reqd" "\0" /* bit 14 */
634 static const char minor_str[] ALIGN1 =
636 "Unspecified" "\0" /* 0x0000 */
637 "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
638 "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
639 "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
640 "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
641 "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
642 "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
643 "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
644 "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
645 "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
646 "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
647 "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
648 "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
649 "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
650 "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
651 "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
652 "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
653 "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
654 "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
655 "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
656 "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
657 "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
658 "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
659 "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
660 "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
661 "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
662 "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
663 "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
664 "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
665 "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
666 "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
667 "reserved" "\0" /* 0x001f */
668 "reserved" "\0" /* 0x0020 */
669 "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
670 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
671 "reserved" /* 0x0023-0xfffe */
673 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
675 0, /* 0x0000 WARNING: actual_ver[] array */
676 1, /* 0x0001 WARNING: corresponds */
677 1, /* 0x0002 WARNING: *exactly* */
678 1, /* 0x0003 WARNING: to the ATA/ */
679 2, /* 0x0004 WARNING: ATAPI version */
680 2, /* 0x0005 WARNING: listed in */
681 3, /* 0x0006 WARNING: the */
682 2, /* 0x0007 WARNING: minor_str */
683 3, /* 0x0008 WARNING: array */
684 2, /* 0x0009 WARNING: above. */
685 3, /* 0x000a WARNING: */
686 3, /* 0x000b WARNING: If you change */
687 3, /* 0x000c WARNING: that one, */
688 4, /* 0x000d WARNING: change this one */
689 4, /* 0x000e WARNING: too!!! */
710 0 /* 0x0023-0xfffe */
713 static const char cmd_feat_str[] ALIGN1 =
714 "" "\0" /* word 82 bit 15: obsolete */
715 "NOP cmd" "\0" /* word 82 bit 14 */
716 "READ BUFFER cmd" "\0" /* word 82 bit 13 */
717 "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
718 "" "\0" /* word 82 bit 11: obsolete */
719 "Host Protected Area feature set" "\0" /* word 82 bit 10 */
720 "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
721 "SERVICE interrupt" "\0" /* word 82 bit 8 */
722 "Release interrupt" "\0" /* word 82 bit 7 */
723 "Look-ahead" "\0" /* word 82 bit 6 */
724 "Write cache" "\0" /* word 82 bit 5 */
725 "PACKET command feature set" "\0" /* word 82 bit 4 */
726 "Power Management feature set" "\0" /* word 82 bit 3 */
727 "Removable Media feature set" "\0" /* word 82 bit 2 */
728 "Security Mode feature set" "\0" /* word 82 bit 1 */
729 "SMART feature set" "\0" /* word 82 bit 0 */
731 "" "\0" /* word 83 bit 15: !valid bit */
732 "" "\0" /* word 83 bit 14: valid bit */
733 "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
734 "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
735 "Device Configuration Overlay feature set " "\0"
736 "48-bit Address feature set " "\0" /* word 83 bit 10 */
738 "SET MAX security extension" "\0" /* word 83 bit 8 */
739 "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
740 "SET FEATURES subcommand required to spinup after power up" "\0"
741 "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
742 "Removable Media Status Notification feature set" "\0"
743 "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
744 "CFA feature set" "\0" /* word 83 bit 2 */
745 "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
746 "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
748 "" "\0" /* word 84 bit 15: !valid bit */
749 "" "\0" /* word 84 bit 14: valid bit */
750 "" "\0" /* word 84 bit 13: reserved */
751 "" "\0" /* word 84 bit 12: reserved */
752 "" "\0" /* word 84 bit 11: reserved */
753 "" "\0" /* word 84 bit 10: reserved */
754 "" "\0" /* word 84 bit 9: reserved */
755 "" "\0" /* word 84 bit 8: reserved */
756 "" "\0" /* word 84 bit 7: reserved */
757 "" "\0" /* word 84 bit 6: reserved */
758 "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
759 "" "\0" /* word 84 bit 4: reserved */
760 "Media Card Pass Through Command feature set " "\0"
761 "Media serial number " "\0" /* word 84 bit 2 */
762 "SMART self-test " "\0" /* word 84 bit 1 */
763 "SMART error logging " /* word 84 bit 0 */
766 static const char secu_str[] ALIGN1 =
767 "supported" "\0" /* word 128, bit 0 */
768 "enabled" "\0" /* word 128, bit 1 */
769 "locked" "\0" /* word 128, bit 2 */
770 "frozen" "\0" /* word 128, bit 3 */
771 "expired: security count" "\0" /* word 128, bit 4 */
772 "supported: enhanced erase" /* word 128, bit 5 */
775 // Parse 512 byte disk identification block and print much crap.
776 static void identify(uint16_t *val) NORETURN;
777 static void identify(uint16_t *val)
780 uint16_t like_std = 1, std = 0, min_std = 0xffff;
781 uint16_t dev = NO_DEV, eqpt = NO_DEV;
782 uint8_t have_mode = 0, err_dma = 0;
784 uint32_t ll, mm, nn, oo;
785 uint64_t bbbig; /* (:) */
790 // Adjust for endianness
791 swab(val, buf, sizeof(buf));
794 /* check if we recognize the device type */
796 if (!(val[GEN_CONFIG] & NOT_ATA)) {
798 printf("ATA device, with ");
799 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
802 printf("CompactFlash ATA device, with ");
803 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
805 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
806 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
809 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
810 bb_error_msg_and_die("unknown device type");
812 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
813 /* Info from the specific configuration word says whether or not the
814 * ID command completed correctly. It is only defined, however in
815 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
816 * standards. Since the values allowed for this word are extremely
817 * specific, it should be safe to check it now, even though we don't
818 * know yet what standard this device is using.
820 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
821 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
824 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
825 puts("powers-up in standby; SET FEATURES subcmd spins-up.");
826 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
827 puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n");
830 /* output the model and serial numbers and the fw revision */
831 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
832 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
833 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
834 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
835 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
837 /* major & minor standards version number (Note: these words were not
838 * defined until ATA-3 & the CDROM std uses different words.) */
839 printf("Standards:");
841 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
842 if (like_std < 3) like_std = 3;
843 std = actual_ver[val[MINOR]];
845 printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
847 /* looks like when they up-issue the std, they obsolete one;
848 * thus, only the newest 4 issues need be supported. (That's
849 * what "kk" and "min_std" are all about.) */
850 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
851 printf("\n\tSupported: ");
852 jj = val[MAJOR] << 1;
853 kk = like_std >4 ? like_std-4: 0;
854 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
859 kk = like_std >4 ? like_std-4: 0;
861 if (min_std > ii) min_std = ii;
865 if (like_std < 3) like_std = 3;
867 /* Figure out what standard the device is using if it hasn't told
868 * us. If we know the std, check if the device is using any of
869 * the words from the next level up. It happens.
871 if (like_std < std) like_std = std;
873 if (((std == 5) || (!std && (like_std < 6))) &&
874 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
875 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
876 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
877 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
880 } else if (((std == 4) || (!std && (like_std < 5))) &&
881 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
882 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
883 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
884 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
887 } else if (((std == 3) || (!std && (like_std < 4))) &&
888 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
889 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
890 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
891 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
892 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
893 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
896 } else if (((std == 2) || (!std && (like_std < 3)))
897 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
900 } else if (((std == 1) || (!std && (like_std < 2))) &&
901 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
902 (val[WHATS_VALID] & OK_W64_70)) )
908 printf("\n\tLikely used: %u\n", like_std);
909 else if (like_std > std)
910 printf("& some of %u\n", like_std);
914 /* TBD: do CDROM stuff more thoroughly. For now... */
916 if (val[CDR_MINOR] == 9) {
918 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
920 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
922 printf("\n\tSupported: CD-ROM ATAPI");
923 jj = val[CDR_MAJOR] >> 1;
924 for (ii = 1; ii < 15; ii++) {
925 if (jj & 0x0001) printf("-%u ", ii);
929 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
930 /* the cdrom stuff is more like ATA-2 than anything else, so: */
934 if (min_std == 0xffff)
935 min_std = like_std > 4 ? like_std - 3 : 1;
937 puts("Configuration:");
938 /* more info from the general configuration word */
939 if ((eqpt != CDROM) && (like_std == 1)) {
940 jj = val[GEN_CONFIG] >> 1;
941 for (ii = 1; ii < 15; ii++) {
943 printf("\t%s\n", nth_string(ata1_cfg_str, ii));
947 if (dev == ATAPI_DEV) {
948 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
950 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
951 strng = "<=10ms with INTRQ";
952 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
956 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
958 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
960 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
966 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
967 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
970 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
971 puts("\tCHS addressing not supported");
973 jj = val[WHATS_VALID] & OK_W54_58;
974 printf("\tLogical\t\tmax\tcurrent\n"
975 "\tcylinders\t%u\t%u\n"
976 "\theads\t\t%u\t%u\n"
977 "\tsectors/track\t%u\t%u\n"
980 jj ? val[LCYLS_CUR] : 0,
982 jj ? val[LHEADS_CUR] : 0,
984 jj ? val[LSECTS_CUR] : 0);
986 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
987 printf("\tbytes/track: %u\tbytes/sector: %u\n",
988 val[TRACK_BYTES], val[SECT_BYTES]);
991 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
993 /* check Endian of capacity bytes */
994 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
995 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
996 if (abs(mm - nn) > abs(oo - nn))
999 printf("\tCHS current addressable sectors:%11u\n", mm);
1002 /* LBA addressing */
1003 printf("\tLBA user addressable sectors:%11u\n", ll);
1004 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
1005 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
1007 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
1008 (uint64_t)val[LBA_48_MSB] << 32 |
1009 (uint64_t)val[LBA_MID] << 16 |
1011 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
1015 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
1016 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
1017 bbbig = (bbbig << 9) / 1000000;
1018 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
1021 printf("(%"PRIu64" GB)\n", bbbig/1000);
1026 /* hw support of commands (capabilities) */
1027 printf("Capabilities:\n\t");
1029 if (dev == ATAPI_DEV) {
1030 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP))
1031 printf("Cmd queuing, ");
1032 if (val[CAPAB_0] & OVLP_SUP)
1033 printf("Cmd overlap, ");
1035 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
1037 if (like_std != 1) {
1038 printf("IORDY%s(can%s be disabled)\n",
1039 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
1040 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
1044 if ((like_std == 1) && val[BUF_TYPE]) {
1045 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
1046 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
1047 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
1050 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
1051 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
1053 if ((min_std < 4) && (val[RW_LONG])) {
1054 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
1056 if ((eqpt != CDROM) && (like_std > 3)) {
1057 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
1060 if (dev == ATA_DEV) {
1062 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
1064 printf("\tStandby timer values: spec'd by %s",
1065 (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor");
1066 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
1067 printf(", %s device specific minimum\n",
1068 (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
1072 printf("\tR/W multiple sector transfer: ");
1073 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
1074 puts("not supported");
1076 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
1077 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
1078 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
1082 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
1083 /* We print out elsewhere whether the APM feature is enabled or
1084 * not. If it's not enabled, let's not repeat the info; just print
1086 printf("\tAdvancedPM level: ");
1087 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
1088 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
1089 printf("%u (0x%x)\n", apm_level, apm_level);
1092 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
1094 if (like_std > 5 && val[ACOUSTIC]) {
1095 printf("\tRecommended acoustic management value: %u, current value: %u\n",
1096 (val[ACOUSTIC] >> 8) & 0x00ff,
1097 val[ACOUSTIC] & 0x00ff);
1101 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
1102 puts("\tATA sw reset required");
1104 if (val[PKT_REL] || val[SVC_NBSY]) {
1105 printf("\tOverlap support:");
1107 printf(" %uus to release bus.", val[PKT_REL]);
1109 printf(" %uus to clear BSY after SERVICE cmd.",
1115 /* DMA stuff. Check that only one DMA mode is selected. */
1117 if (!(val[CAPAB_0] & DMA_SUP))
1118 puts("not supported");
1120 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1121 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1122 if (val[SINGLE_DMA]) {
1123 jj = val[SINGLE_DMA];
1124 kk = val[SINGLE_DMA] >> 8;
1125 err_dma += mode_loop(jj, kk, 's', &have_mode);
1127 if (val[MULTI_DMA]) {
1128 jj = val[MULTI_DMA];
1129 kk = val[MULTI_DMA] >> 8;
1130 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1132 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1133 jj = val[ULTRA_DMA];
1134 kk = val[ULTRA_DMA] >> 8;
1135 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1137 if (err_dma || !have_mode) printf("(?)");
1140 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1141 puts("\t\tInterleaved DMA support");
1143 if ((val[WHATS_VALID] & OK_W64_70)
1144 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1146 printf("\t\tCycle time:");
1147 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1148 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1153 /* Programmed IO stuff */
1155 /* If a drive supports mode n (e.g. 3), it also supports all modes less
1156 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1157 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1158 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1159 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1160 if (jj & 0x0001) printf("pio%d ", ii);
1164 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1165 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1166 printf("pio%d ", ii);
1171 if (val[WHATS_VALID] & OK_W64_70) {
1172 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1173 printf("\t\tCycle time:");
1174 if (val[PIO_NO_FLOW])
1175 printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1177 printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1182 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1183 puts("Commands/features:\n"
1184 "\tEnabled\tSupported:");
1185 jj = val[CMDS_SUPP_0];
1186 kk = val[CMDS_EN_0];
1187 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1188 const char *feat_str = nth_string(cmd_feat_str, ii);
1189 if ((jj & 0x8000) && (*feat_str != '\0')) {
1190 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
1194 if (ii % 16 == 15) {
1195 jj = val[CMDS_SUPP_0+1+(ii/16)];
1196 kk = val[CMDS_EN_0+1+(ii/16)];
1199 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1204 /* Removable Media Status Notification feature set */
1205 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1206 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1209 if ((eqpt != CDROM) && (like_std > 3)
1210 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1213 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1214 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1215 jj = val[SECU_STATUS];
1217 for (ii = 0; ii < NUM_SECU_STR; ii++) {
1218 printf("\t%s\t%s\n",
1219 (!(jj & 0x0001)) ? "not" : "",
1220 nth_string(secu_str, ii));
1223 if (val[SECU_STATUS] & SECU_ENABLED) {
1224 printf("\tSecurity level %s\n",
1225 (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1228 jj = val[ERASE_TIME] & ERASE_BITS;
1229 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1232 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1233 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1239 jj = val[HWRST_RSLT];
1240 if ((jj & VALID) == VALID_VAL) {
1244 if ((jj & DEV_DET) == JUMPER_VAL)
1245 strng = " determined by the jumper";
1246 else if ((jj & DEV_DET) == CSEL_VAL)
1247 strng = " determined by CSEL";
1250 printf("HW reset results:\n"
1252 "\tDevice num = %i%s\n",
1253 (val[HWRST_RSLT] & CBLID) ? "above" : "below",
1257 /* more stuff from std 5 */
1258 if ((like_std > 4) && (eqpt != CDROM)) {
1259 if (val[CFA_PWR_MODE] & VALID_W160) {
1260 printf("CFA power mode 1:\n"
1262 (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1263 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1264 if (val[CFA_PWR_MODE] & MAX_AMPS)
1265 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1267 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1268 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1276 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1277 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1278 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1279 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1280 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1281 // (which they should, but they should just return -EINVAL).
1283 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1284 // On a really old system, it will not, and we will be confused.
1287 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1288 static const char cfg_str[] ALIGN1 =
1289 """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
1290 "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
1291 "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1292 "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
1295 static const char BuffType[] ALIGN1 =
1296 "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
1299 static NOINLINE void dump_identity(const struct hd_driveid *id)
1302 const unsigned short *id_regs = (const void*) id;
1304 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1305 id->model, id->fw_rev, id->serial_no);
1306 for (i = 0; i <= 15; i++) {
1307 if (id->config & (1<<i))
1308 printf(" %s", nth_string(cfg_str, i));
1310 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1311 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1312 id->cyls, id->heads, id->sectors, id->track_bytes,
1313 id->sector_bytes, id->ecc_bytes,
1315 nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1316 id->buf_size/2, id->max_multsect);
1317 if (id->max_multsect) {
1318 printf(", MultSect=");
1319 if (!(id->multsect_valid & 1))
1320 printf("?%u?", id->multsect);
1321 else if (id->multsect)
1322 printf("%u", id->multsect);
1328 if (!(id->field_valid & 1))
1329 printf(" (maybe):");
1331 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1334 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1335 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1336 ((id->capability&2) == 0) ? "no" : "yes");
1338 if (id->capability & 2)
1339 printf(", LBAsects=%u", id->lba_capacity);
1341 printf("\n IORDY=%s",
1342 (id->capability & 8)
1343 ? ((id->capability & 4) ? "on/off" : "yes")
1346 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1347 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1349 if ((id->capability & 1) && (id->field_valid & 2))
1350 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1352 printf("\n PIO modes: ");
1353 if (id->tPIO <= 5) {
1355 if (id->tPIO >= 1) printf("pio1 ");
1356 if (id->tPIO >= 2) printf("pio2 ");
1358 if (id->field_valid & 2) {
1359 static const masks_labels_t pio_modes = {
1360 .masks = { 1, 2, ~3 },
1361 .labels = "pio3 \0""pio4 \0""pio? \0",
1363 print_flags(&pio_modes, id->eide_pio_modes);
1365 if (id->capability & 1) {
1366 if (id->dma_1word | id->dma_mword) {
1367 static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
1368 printf("\n DMA modes: ");
1369 print_flags_separated(dma_wmode_masks,
1370 "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
1371 id->dma_1word, NULL);
1372 print_flags_separated(dma_wmode_masks,
1373 "*\0""mdma0 \0""*\0""mdma1 \0""*\0""mdma2 \0""*\0""mdma? \0",
1374 id->dma_mword, NULL);
1377 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1378 static const masks_labels_t ultra_modes1 = {
1379 .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
1380 .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
1383 printf("\n UDMA modes: ");
1384 print_flags(&ultra_modes1, id->dma_ultra);
1385 #ifdef __NEW_HD_DRIVE_ID
1386 if (id->hw_config & 0x2000) {
1387 #else /* !__NEW_HD_DRIVE_ID */
1388 if (id->word93 & 0x2000) {
1389 #endif /* __NEW_HD_DRIVE_ID */
1390 static const masks_labels_t ultra_modes2 = {
1391 .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
1392 0x2000, 0x0020, 0x4000, 0x0040,
1394 .labels = "*\0""udma3 \0""*\0""udma4 \0"
1395 "*\0""udma5 \0""*\0""udma6 \0"
1398 print_flags(&ultra_modes2, id->dma_ultra);
1401 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1402 if (id_regs[83] & 8) {
1403 if (!(id_regs[86] & 8))
1404 printf(": disabled (255)");
1405 else if ((id_regs[91] & 0xFF00) != 0x4000)
1406 printf(": unknown setting");
1408 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1410 if (id_regs[82] & 0x20)
1411 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1412 #ifdef __NEW_HD_DRIVE_ID
1413 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1414 || (id->major_rev_num && id->minor_rev_num <= 31)
1416 printf("\n Drive conforms to: %s: ",
1417 (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1418 if (id->major_rev_num != 0x0000 /* NOVAL_0 */
1419 && id->major_rev_num != 0xFFFF /* NOVAL_1 */
1421 for (i = 0; i <= 15; i++) {
1422 if (id->major_rev_num & (1<<i))
1423 printf(" ATA/ATAPI-%u", i);
1427 #endif /* __NEW_HD_DRIVE_ID */
1428 puts("\n\n * current active mode\n");
1432 static void flush_buffer_cache(/*int fd*/ void)
1434 fsync(fd); /* flush buffers */
1435 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1436 #ifdef HDIO_DRIVE_CMD
1438 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1439 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1440 bb_perror_msg("HDIO_DRIVE_CMD");
1442 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1447 static void seek_to_zero(/*int fd*/ void)
1449 xlseek(fd, (off_t) 0, SEEK_SET);
1452 static void read_big_block(/*int fd,*/ char *buf)
1456 xread(fd, buf, TIMING_BUF_BYTES);
1457 /* access all sectors of buf to ensure the read fully completed */
1458 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1462 static unsigned dev_size_mb(/*int fd*/ void)
1465 unsigned long long blksize64;
1469 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1470 u.blksize64 /= (1024 * 1024);
1472 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1473 u.blksize64 = u.blksize32 / (2 * 1024);
1475 if (u.blksize64 > UINT_MAX)
1480 static void print_timing(unsigned m, unsigned elapsed_us)
1482 unsigned sec = elapsed_us / 1000000;
1483 unsigned hs = (elapsed_us % 1000000) / 10000;
1485 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1487 /* "| 1" prevents div-by-0 */
1488 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1489 // ~= (m * 1024) / (elapsed_us / 1000000)
1490 // = kb / elapsed_sec
1494 static void do_time(int cache /*,int fd*/)
1495 /* cache=1: time cache: repeatedly read N MB at offset 0
1496 * cache=0: time device: linear read, starting at offset 0
1499 unsigned max_iterations, iterations;
1500 unsigned start; /* doesn't need to be long long */
1501 unsigned elapsed, elapsed2;
1503 char *buf = xmalloc(TIMING_BUF_BYTES);
1505 if (mlock(buf, TIMING_BUF_BYTES))
1506 bb_perror_msg_and_die("mlock");
1508 /* Clear out the device request queues & give them time to complete.
1509 * NB: *small* delay. User is expected to have a clue and to not run
1510 * heavy io in parallel with measurements. */
1513 if (cache) { /* Time cache */
1515 read_big_block(buf);
1516 printf("Timing buffer-cache reads: ");
1517 } else { /* Time device */
1518 printf("Timing buffered disk reads:");
1522 /* Now do the timing */
1524 /* Max time to run (small for cache, avoids getting
1525 * huge total_MB which can overlow unsigned type) */
1526 elapsed2 = 510000; /* cache */
1527 max_iterations = UINT_MAX;
1529 elapsed2 = 3000000; /* not cache */
1530 /* Don't want to read past the end! */
1531 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1533 start = monotonic_us();
1537 read_big_block(buf);
1538 elapsed = (unsigned)monotonic_us() - start;
1540 } while (elapsed < elapsed2 && iterations < max_iterations);
1541 total_MB = iterations * TIMING_BUF_MB;
1542 //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1544 /* Cache: remove lseek() and monotonic_us() overheads
1546 start = monotonic_us();
1549 elapsed2 = (unsigned)monotonic_us() - start;
1550 } while (--iterations);
1551 //printf(" elapsed2:%u ", elapsed2);
1552 elapsed -= elapsed2;
1553 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1554 flush_buffer_cache();
1556 print_timing(total_MB, elapsed);
1557 munlock(buf, TIMING_BUF_BYTES);
1561 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1562 static void bus_state_value(unsigned value)
1564 if (value == BUSSTATE_ON)
1566 else if (value == BUSSTATE_OFF)
1568 else if (value == BUSSTATE_TRISTATE)
1569 puts(" (tristate)");
1571 printf(" (unknown: %u)\n", value);
1575 #ifdef HDIO_DRIVE_CMD
1576 static void interpret_standby(uint8_t standby)
1581 } else if (standby <= 240 || standby == 252 || standby == 255) {
1582 /* standby is in 5 sec units */
1583 unsigned t = standby * 5;
1584 printf("%u minutes %u seconds", t / 60, t % 60);
1585 } else if (standby <= 251) {
1586 unsigned t = (standby - 240); /* t is in 30 min units */;
1587 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0');
1590 printf("vendor-specific");
1596 static const uint8_t xfermode_val[] ALIGN1 = {
1597 8, 9, 10, 11, 12, 13, 14, 15,
1598 16, 17, 18, 19, 20, 21, 22, 23,
1599 32, 33, 34, 35, 36, 37, 38, 39,
1600 64, 65, 66, 67, 68, 69, 70, 71
1602 /* NB: we save size by _not_ storing terninating NUL! */
1603 static const char xfermode_name[][5] ALIGN1 = {
1604 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1605 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1606 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1607 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1610 static int translate_xfermode(const char *name)
1615 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1616 if (!strncmp(name, xfermode_name[i], 5))
1617 if (strlen(name) <= 5)
1618 return xfermode_val[i];
1620 /* Negative numbers are invalid and are caught later */
1621 val = bb_strtoi(name, NULL, 10);
1627 static void interpret_xfermode(unsigned xfermode)
1631 printf("default PIO mode");
1632 else if (xfermode == 1)
1633 printf("default PIO mode, disable IORDY");
1634 else if (xfermode >= 8 && xfermode <= 15)
1635 printf("PIO flow control mode%u", xfermode - 8);
1636 else if (xfermode >= 16 && xfermode <= 23)
1637 printf("singleword DMA mode%u", xfermode - 16);
1638 else if (xfermode >= 32 && xfermode <= 39)
1639 printf("multiword DMA mode%u", xfermode - 32);
1640 else if (xfermode >= 64 && xfermode <= 71)
1641 printf("UltraDMA mode%u", xfermode - 64);
1646 #endif /* HDIO_DRIVE_CMD */
1648 static void print_flag(int flag, const char *s, unsigned long value)
1651 printf(" setting %s to %lu\n", s, value);
1654 static void process_dev(char *devname)
1657 long parm, multcount;
1658 #ifndef HDIO_DRIVE_CMD
1659 int force_operation = 0;
1661 /* Please restore args[n] to these values after each ioctl
1662 except for args[2] */
1663 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1664 const char *fmt = " %s\t= %2ld";
1666 /*fd = xopen_nonblocking(devname);*/
1667 xmove_fd(xopen_nonblocking(devname), fd);
1668 printf("\n%s:\n", devname);
1670 if (getset_readahead == IS_SET) {
1671 print_flag(getset_readahead, "fs readahead", Xreadahead);
1672 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1674 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1675 if (unregister_hwif) {
1676 printf(" attempting to unregister hwif#%lu\n", hwif);
1677 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1680 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1681 if (scan_hwif == IS_SET) {
1682 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1683 args[0] = hwif_data;
1684 args[1] = hwif_ctrl;
1686 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1687 args[0] = WIN_SETFEATURES;
1692 if (noisy_piomode) {
1693 printf(" attempting to ");
1695 puts("auto-tune PIO mode");
1696 else if (piomode < 100)
1697 printf("set PIO mode to %d\n", piomode);
1698 else if (piomode < 200)
1699 printf("set MDMA mode to %d\n", (piomode-100));
1701 printf("set UDMA mode to %d\n", (piomode-200));
1703 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1705 if (getset_io32bit == IS_SET) {
1706 print_flag(getset_io32bit, "32-bit IO_support flag", io32bit);
1707 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1709 if (getset_mult == IS_SET) {
1710 print_flag(getset_mult, "multcount", mult);
1711 #ifdef HDIO_DRIVE_CMD
1712 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1714 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1717 if (getset_readonly == IS_SET) {
1718 print_flag_on_off(getset_readonly, "readonly", readonly);
1719 ioctl_or_warn(fd, BLKROSET, &readonly);
1721 if (getset_unmask == IS_SET) {
1722 print_flag_on_off(getset_unmask, "unmaskirq", unmask);
1723 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1725 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1726 if (getset_dma == IS_SET) {
1727 print_flag_on_off(getset_dma, "using_dma", dma);
1728 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1730 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1731 #ifdef HDIO_SET_QDMA
1732 if (getset_dma_q == IS_SET) {
1733 print_flag_on_off(getset_dma_q, "DMA queue_depth", dma_q);
1734 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1737 if (getset_nowerr == IS_SET) {
1738 print_flag_on_off(getset_nowerr, "nowerr", nowerr);
1739 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1741 if (getset_keep == IS_SET) {
1742 print_flag_on_off(getset_keep, "keep_settings", keep);
1743 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1745 #ifdef HDIO_DRIVE_CMD
1746 if (getset_doorlock == IS_SET) {
1747 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1749 print_flag_on_off(getset_doorlock, "drive doorlock", doorlock);
1750 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1751 args[0] = WIN_SETFEATURES;
1753 if (getset_dkeep == IS_SET) {
1754 /* lock/unlock the drive's "feature" settings */
1755 print_flag_on_off(getset_dkeep, "drive keep features", dkeep);
1756 args[2] = dkeep ? 0x66 : 0xcc;
1757 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1759 if (getset_defects == IS_SET) {
1760 args[2] = defects ? 0x04 : 0x84;
1761 print_flag(getset_defects, "drive defect-mgmt", defects);
1762 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1764 if (getset_prefetch == IS_SET) {
1767 print_flag(getset_prefetch, "drive prefetch", prefetch);
1768 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1772 args[1] = xfermode_requested;
1774 print_flag(1, "xfermode", xfermode_requested);
1775 interpret_xfermode(xfermode_requested);
1776 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1779 if (getset_lookahead == IS_SET) {
1780 args[2] = lookahead ? 0xaa : 0x55;
1781 print_flag_on_off(getset_lookahead, "drive read-lookahead", lookahead);
1782 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1784 if (getset_apmmode == IS_SET) {
1785 /* feature register */
1786 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */;
1787 args[1] = apmmode; /* sector count register 1-255 */
1788 printf(" setting APM level to %s 0x%02lX (%ld)\n",
1789 (apmmode == 255) ? "disabled" : "",
1791 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1794 if (getset_wcache == IS_SET) {
1795 #ifdef DO_FLUSHCACHE
1796 #ifndef WIN_FLUSHCACHE
1797 #define WIN_FLUSHCACHE 0xe7
1799 #endif /* DO_FLUSHCACHE */
1800 args[2] = wcache ? 0x02 : 0x82;
1801 print_flag_on_off(getset_wcache, "drive write-caching", wcache);
1802 #ifdef DO_FLUSHCACHE
1804 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1805 #endif /* DO_FLUSHCACHE */
1806 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1807 #ifdef DO_FLUSHCACHE
1809 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1810 #endif /* DO_FLUSHCACHE */
1813 /* In code below, we do not preserve args[0], but the rest
1814 is preserved, including args[2] */
1817 if (set_standbynow) {
1818 #ifndef WIN_STANDBYNOW1
1819 #define WIN_STANDBYNOW1 0xE0
1821 #ifndef WIN_STANDBYNOW2
1822 #define WIN_STANDBYNOW2 0x94
1824 puts(" issuing standby command");
1825 args[0] = WIN_STANDBYNOW1;
1826 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1829 #ifndef WIN_SLEEPNOW1
1830 #define WIN_SLEEPNOW1 0xE6
1832 #ifndef WIN_SLEEPNOW2
1833 #define WIN_SLEEPNOW2 0x99
1835 puts(" issuing sleep command");
1836 args[0] = WIN_SLEEPNOW1;
1837 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1841 puts(" disabling Seagate auto powersaving mode");
1842 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1844 if (getset_standby == IS_SET) {
1845 args[0] = WIN_SETIDLE1;
1846 args[1] = standby_requested;
1847 print_flag(1, "standby", standby_requested);
1848 interpret_standby(standby_requested);
1849 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1852 #else /* HDIO_DRIVE_CMD */
1853 if (force_operation) {
1855 flush_buffer_cache();
1856 if (-1 == read(fd, buf, sizeof(buf)))
1857 bb_perror_msg("read of 512 bytes failed");
1859 #endif /* HDIO_DRIVE_CMD */
1860 if (getset_mult || get_identity) {
1862 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1863 /* To be coherent with ioctl_or_warn. */
1864 if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1865 bb_perror_msg("HDIO_GET_MULTCOUNT");
1867 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1868 } else if (getset_mult) {
1869 printf(fmt, "multcount", multcount);
1870 on_off(multcount != 0);
1873 if (getset_io32bit) {
1874 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1875 printf(" IO_support\t=%3ld (", parm);
1877 puts("default 16-bit)");
1883 puts("32-bit w/sync)");
1885 puts("Request-Queue-Bypass)");
1890 if (getset_unmask) {
1891 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
1892 print_value_on_off("unmaskirq", parm);
1894 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1896 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1897 printf(fmt, "using_dma", parm);
1899 puts(" (DMA-Assisted-PIO)");
1905 #ifdef HDIO_GET_QDMA
1907 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
1908 print_value_on_off("queue_depth", parm);
1912 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
1913 print_value_on_off("keepsettings", parm);
1915 if (getset_nowerr) {
1916 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
1917 print_value_on_off("nowerr", parm);
1919 if (getset_readonly) {
1920 if (!ioctl_or_warn(fd, BLKROGET, &parm))
1921 print_value_on_off("readonly", parm);
1923 if (getset_readahead) {
1924 if (!ioctl_or_warn(fd, BLKRAGET, &parm))
1925 print_value_on_off("readahead", parm);
1928 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1929 struct hd_geometry g;
1931 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1932 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1933 g.cylinders, g.heads, g.sectors, parm, g.start);
1936 #ifdef HDIO_DRIVE_CMD
1937 if (get_powermode) {
1938 #ifndef WIN_CHECKPOWERMODE1
1939 #define WIN_CHECKPOWERMODE1 0xE5
1941 #ifndef WIN_CHECKPOWERMODE2
1942 #define WIN_CHECKPOWERMODE2 0x98
1946 args[0] = WIN_CHECKPOWERMODE1;
1947 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1948 if (errno != EIO || args[0] != 0 || args[1] != 0)
1953 state = (args[2] == 255) ? "active/idle" : "standby";
1954 args[1] = args[2] = 0;
1956 printf(" drive state is: %s\n", state);
1959 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1960 if (perform_reset) {
1961 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1963 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1964 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1965 if (perform_tristate) {
1968 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1970 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1971 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1973 struct hd_driveid id;
1975 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1976 if (multcount != -1) {
1977 id.multsect = multcount;
1978 id.multsect_valid |= 1;
1980 id.multsect_valid &= ~1;
1982 } else if (errno == -ENOMSG)
1983 puts(" no identification info available");
1984 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1985 bb_perror_msg("HDIO_GET_IDENTITY");
1987 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1991 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1993 memset(args1, 0, sizeof(args1));
1994 args1[0] = WIN_IDENTIFY;
1996 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1997 identify((void *)(args1 + 4));
2000 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
2001 if (getset_busstate == IS_SET) {
2002 print_flag(1, "bus state", busstate);
2003 bus_state_value(busstate);
2004 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
2006 if (getset_busstate) {
2007 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
2008 printf(fmt, "bus state", parm);
2009 bus_state_value(parm);
2014 ioctl_or_warn(fd, BLKRRPART, NULL);
2017 do_time(1 /*,fd*/); /* time cache */
2019 do_time(0 /*,fd*/); /* time device */
2021 flush_buffer_cache();
2025 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
2026 static int fromhex(unsigned char c)
2030 if (c >= 'a' && c <= 'f')
2031 return (c - ('a' - 10));
2032 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
2035 static void identify_from_stdin(void) NORETURN;
2036 static void identify_from_stdin(void)
2039 unsigned char buf[1280];
2040 unsigned char *b = (unsigned char *)buf;
2043 xread(STDIN_FILENO, buf, 1280);
2045 // Convert the newline-separated hex data into an identify block.
2047 for (i = 0; i < 256; i++) {
2049 for (j = 0; j < 4; j++)
2050 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
2058 void identify_from_stdin(void);
2061 /* busybox specific stuff */
2062 static int parse_opts(unsigned long *value, int min, int max)
2065 *value = xatol_range(optarg, min, max);
2070 static int parse_opts_0_max(unsigned long *value, int max)
2072 return parse_opts(value, 0, max);
2074 static int parse_opts_0_1(unsigned long *value)
2076 return parse_opts(value, 0, 1);
2078 static int parse_opts_0_INTMAX(unsigned long *value)
2080 return parse_opts(value, 0, INT_MAX);
2083 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
2088 *value = translate_xfermode(optarg);
2089 *set = (*value > -1);
2094 /*------- getopt short options --------*/
2095 static const char hdparm_options[] ALIGN1 =
2096 "gfu::n::p:r::m::c::k::a::B:tT"
2097 IF_FEATURE_HDPARM_GET_IDENTITY("iI")
2098 IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
2099 #ifdef HDIO_DRIVE_CMD
2100 "S:D:P:X:K:A:L:W:CyYzZ"
2102 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
2103 #ifdef HDIO_GET_QDMA
2104 #ifdef HDIO_SET_QDMA
2110 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
2111 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
2112 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
2113 /*-------------------------------------*/
2115 /* our main() routine: */
2116 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2117 int hdparm_main(int argc, char **argv)
2124 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2126 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2127 IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2128 get_geom |= (c == 'g');
2129 do_flush |= (c == 'f');
2130 if (c == 'u') getset_unmask = parse_opts_0_1(&unmask);
2131 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
2132 if (c == 'd') getset_dma = parse_opts_0_max(&dma, 9);
2134 if (c == 'n') getset_nowerr = parse_opts_0_1(&nowerr);
2135 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2136 if (c == 'r') getset_readonly = parse_opts_0_1(&readonly);
2137 if (c == 'm') getset_mult = parse_opts_0_INTMAX(&mult /*32*/);
2138 if (c == 'c') getset_io32bit = parse_opts_0_INTMAX(&io32bit /*8*/);
2139 if (c == 'k') getset_keep = parse_opts_0_1(&keep);
2140 if (c == 'a') getset_readahead = parse_opts_0_INTMAX(&Xreadahead);
2141 if (c == 'B') getset_apmmode = parse_opts(&apmmode, 1, 255);
2142 do_flush |= do_timings |= (c == 't');
2143 do_flush |= do_ctimings |= (c == 'T');
2144 #ifdef HDIO_DRIVE_CMD
2145 if (c == 'S') getset_standby = parse_opts_0_max(&standby_requested, 255);
2146 if (c == 'D') getset_defects = parse_opts_0_INTMAX(&defects);
2147 if (c == 'P') getset_prefetch = parse_opts_0_INTMAX(&prefetch);
2148 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2149 if (c == 'K') getset_dkeep = parse_opts_0_1(&prefetch);
2150 if (c == 'A') getset_lookahead = parse_opts_0_1(&lookahead);
2151 if (c == 'L') getset_doorlock = parse_opts_0_1(&doorlock);
2152 if (c == 'W') getset_wcache = parse_opts_0_1(&wcache);
2153 get_powermode |= (c == 'C');
2154 set_standbynow |= (c == 'y');
2155 set_sleepnow |= (c == 'Y');
2156 reread_partn |= (c == 'z');
2157 set_seagate |= (c == 'Z');
2159 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') unregister_hwif = parse_opts_0_INTMAX(&hwif));
2160 #ifdef HDIO_GET_QDMA
2162 getset_dma_q = parse_opts_0_INTMAX(&dma_q);
2165 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2166 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') perform_tristate = parse_opts_0_1(&tristate));
2167 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') getset_busstate = parse_opts_0_max(&busstate, 2));
2168 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2170 scan_hwif = parse_opts_0_INTMAX(&hwif_data);
2171 hwif_ctrl = xatoi_positive((argv[optind]) ? argv[optind] : "");
2172 hwif_irq = xatoi_positive((argv[optind+1]) ? argv[optind+1] : "");
2173 /* Move past the 2 additional arguments */
2179 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2181 getset_mult = getset_io32bit = getset_unmask = getset_keep = getset_readonly = getset_readahead = get_geom = IS_GET;
2182 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(getset_dma = IS_GET);
2187 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2188 identify_from_stdin(); /* EXIT */
2193 process_dev(*argv++);
2196 return EXIT_SUCCESS;