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 (23 kb)"
17 //config: select PLATFORM_LINUX
19 //config: Get/Set hard drive parameters. Primarily intended for ATA
22 //config:config FEATURE_HDPARM_GET_IDENTITY
23 //config: bool "Support obtaining detailed information directly from drives"
25 //config: depends on HDPARM
27 //config: Enable the -I and -i options to obtain detailed information
28 //config: directly from drives about their capabilities and supported ATA
29 //config: feature set. If no device name is specified, hdparm will read
30 //config: identify data from stdin. Enabling this option will add about 16k...
32 //config:config FEATURE_HDPARM_HDIO_SCAN_HWIF
33 //config: bool "Register an IDE interface (DANGEROUS)"
35 //config: depends on HDPARM
37 //config: Enable the 'hdparm -R' option to register an IDE interface.
38 //config: This is dangerous stuff, so you should probably say N.
40 //config:config FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
41 //config: bool "Un-register an IDE interface (DANGEROUS)"
43 //config: depends on HDPARM
45 //config: Enable the 'hdparm -U' option to un-register an IDE interface.
46 //config: This is dangerous stuff, so you should probably say N.
48 //config:config FEATURE_HDPARM_HDIO_DRIVE_RESET
49 //config: bool "Perform device reset (DANGEROUS)"
51 //config: depends on HDPARM
53 //config: Enable the 'hdparm -w' option to perform a device reset.
54 //config: This is dangerous stuff, so you should probably say N.
56 //config:config FEATURE_HDPARM_HDIO_TRISTATE_HWIF
57 //config: bool "Tristate device for hotswap (DANGEROUS)"
59 //config: depends on HDPARM
61 //config: Enable the 'hdparm -x' option to tristate device for hotswap,
62 //config: and the '-b' option to get/set bus state. This is dangerous
63 //config: stuff, so you should probably say N.
65 //config:config FEATURE_HDPARM_HDIO_GETSET_DMA
66 //config: bool "Get/set using_dma flag"
68 //config: depends on HDPARM
70 //config: Enable the 'hdparm -d' option to get/set using_dma flag.
72 //applet:IF_HDPARM(APPLET(hdparm, BB_DIR_SBIN, BB_SUID_DROP))
74 //kbuild:lib-$(CONFIG_HDPARM) += hdparm.o
76 //usage:#define hdparm_trivial_usage
77 //usage: "[OPTIONS] [DEVICE]"
78 //usage:#define hdparm_full_usage "\n\n"
79 //usage: " -a Get/set fs readahead"
80 //usage: "\n -A Set drive read-lookahead flag (0/1)"
81 //usage: "\n -b Get/set bus state (0 == off, 1 == on, 2 == tristate)"
82 //usage: "\n -B Set Advanced Power Management setting (1-255)"
83 //usage: "\n -c Get/set IDE 32-bit IO setting"
84 //usage: "\n -C Check IDE power mode status"
85 //usage: IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
86 //usage: "\n -d Get/set using_dma flag")
87 //usage: "\n -D Enable/disable drive defect-mgmt"
88 //usage: "\n -f Flush buffer cache for device on exit"
89 //usage: "\n -g Display drive geometry"
90 //usage: "\n -h Display terse usage information"
91 //usage: IF_FEATURE_HDPARM_GET_IDENTITY(
92 //usage: "\n -i Display drive identification")
93 //usage: IF_FEATURE_HDPARM_GET_IDENTITY(
94 //usage: "\n -I Detailed/current information directly from drive")
95 //usage: "\n -k Get/set keep_settings_over_reset flag (0/1)"
96 //usage: "\n -K Set drive keep_features_over_reset flag (0/1)"
97 //usage: "\n -L Set drive doorlock (0/1) (removable harddisks only)"
98 //usage: "\n -m Get/set multiple sector count"
99 //usage: "\n -n Get/set ignore-write-errors flag (0/1)"
100 //usage: "\n -p Set PIO mode on IDE interface chipset (0,1,2,3,4,...)"
101 //usage: "\n -P Set drive prefetch count"
102 /* //usage: "\n -q Change next setting quietly" - not supported ib bbox */
103 //usage: "\n -Q Get/set DMA tagged-queuing depth (if supported)"
104 //usage: "\n -r Get/set readonly flag (DANGEROUS to set)"
105 //usage: IF_FEATURE_HDPARM_HDIO_SCAN_HWIF(
106 //usage: "\n -R Register an IDE interface (DANGEROUS)")
107 //usage: "\n -S Set standby (spindown) timeout"
108 //usage: "\n -t Perform device read timings"
109 //usage: "\n -T Perform cache read timings"
110 //usage: "\n -u Get/set unmaskirq flag (0/1)"
111 //usage: IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(
112 //usage: "\n -U Unregister an IDE interface (DANGEROUS)")
113 //usage: "\n -v Defaults; same as -mcudkrag for IDE drives"
114 //usage: "\n -V Display program version and exit immediately"
115 //usage: IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(
116 //usage: "\n -w Perform device reset (DANGEROUS)")
117 //usage: "\n -W Set drive write-caching flag (0/1) (DANGEROUS)"
118 //usage: IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(
119 //usage: "\n -x Tristate device for hotswap (0/1) (DANGEROUS)")
120 //usage: "\n -X Set IDE xfer mode (DANGEROUS)"
121 //usage: "\n -y Put IDE drive in standby mode"
122 //usage: "\n -Y Put IDE drive to sleep"
123 //usage: "\n -Z Disable Seagate auto-powersaving mode"
124 //usage: "\n -z Reread partition table"
127 #include "common_bufsiz.h"
128 /* must be _after_ libbb.h: */
129 #include <linux/hdreg.h>
130 #include <sys/mount.h>
131 #if !defined(BLKGETSIZE64)
132 # define BLKGETSIZE64 _IOR(0x12,114,size_t)
137 #define NO_DEV 0xffff
138 #define ATA_DEV 0x0000
139 #define ATAPI_DEV 0x0001
141 /* word definitions */
142 /* ---------------- */
143 #define GEN_CONFIG 0 /* general configuration */
144 #define LCYLS 1 /* number of logical cylinders */
145 #define CONFIG 2 /* specific configuration */
146 #define LHEADS 3 /* number of logical heads */
147 #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
148 #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
149 #define LSECTS 6 /* number of logical sectors/track */
150 #define START_SERIAL 10 /* ASCII serial number */
151 #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
152 #define BUF_TYPE 20 /* buffer type (ATA-1) */
153 #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
154 #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
155 #define START_FW_REV 23 /* ASCII firmware revision */
156 #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
157 #define START_MODEL 27 /* ASCII model number */
158 #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
159 #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
160 #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
161 #define CAPAB_0 49 /* capabilities */
163 #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
164 #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
165 #define WHATS_VALID 53 /* what fields are valid */
166 #define LCYLS_CUR 54 /* current logical cylinders */
167 #define LHEADS_CUR 55 /* current logical heads */
168 #define LSECTS_CUR 56 /* current logical sectors/track */
169 #define CAPACITY_LSB 57 /* current capacity in sectors */
170 #define CAPACITY_MSB 58
171 #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
172 #define LBA_SECTS_LSB 60 /* LBA: total number of user */
173 #define LBA_SECTS_MSB 61 /* addressable sectors */
174 #define SINGLE_DMA 62 /* singleword DMA modes */
175 #define MULTI_DMA 63 /* multiword DMA modes */
176 #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
177 /* multiword DMA xfer cycle time: */
178 #define DMA_TIME_MIN 65 /* - minimum */
179 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
180 /* minimum PIO xfer cycle time: */
181 #define PIO_NO_FLOW 67 /* - without flow control */
182 #define PIO_FLOW 68 /* - with IORDY flow control */
183 #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
184 #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
185 #define CDR_MAJOR 73 /* CD ROM: major version number */
186 #define CDR_MINOR 74 /* CD ROM: minor version number */
187 #define QUEUE_DEPTH 75 /* queue depth */
188 #define MAJOR 80 /* major version number */
189 #define MINOR 81 /* minor version number */
190 #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
191 #define CMDS_SUPP_1 83
192 #define CMDS_SUPP_2 84
193 #define CMDS_EN_0 85 /* command/feature set(s) enabled */
196 #define ULTRA_DMA 88 /* ultra DMA modes */
197 /* time to complete security erase */
198 #define ERASE_TIME 89 /* - ordinary */
199 #define ENH_ERASE_TIME 90 /* - enhanced */
200 #define ADV_PWR 91 /* current advanced power management level
201 in low byte, 0x40 in high byte. */
202 #define PSWD_CODE 92 /* master password revision code */
203 #define HWRST_RSLT 93 /* hardware reset result */
204 #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
205 #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
206 #define LBA_MID 101 /* bits are used, but addr 103 */
207 #define LBA_48_MSB 102 /* has been reserved for LBA in */
208 #define LBA_64_MSB 103 /* the future. */
209 #define RM_STAT 127 /* removable media status notification feature set support */
210 #define SECU_STATUS 128 /* security status */
211 #define CFA_PWR_MODE 160 /* CFA power mode 1 */
212 #define START_MEDIA 176 /* media serial number */
213 #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
214 #define START_MANUF 196 /* media manufacturer I.D. */
215 #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
216 #define INTEGRITY 255 /* integrity word */
218 /* bit definitions within the words */
219 /* -------------------------------- */
221 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
223 #define VALID_VAL 0x4000
224 /* many words are considered invalid if they are either all-0 or all-1 */
225 #define NOVAL_0 0x0000
226 #define NOVAL_1 0xffff
228 /* word 0: gen_config */
229 #define NOT_ATA 0x8000
230 #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
231 #define MEDIA_REMOVABLE 0x0080
232 #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
233 #define INCOMPLETE 0x0004
234 #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
235 #define DRQ_RESPONSE_TIME 0x0060
236 #define DRQ_3MS_VAL 0x0000
237 #define DRQ_INTR_VAL 0x0020
238 #define DRQ_50US_VAL 0x0040
239 #define PKT_SIZE_SUPPORTED 0x0003
240 #define PKT_SIZE_12_VAL 0x0000
241 #define PKT_SIZE_16_VAL 0x0001
242 #define EQPT_TYPE 0x1f00
247 /* word 1: number of logical cylinders */
248 #define LCYLS_MAX 0x3fff /* maximum allowable value */
250 /* word 2: specific configuration
251 * (a) require SET FEATURES to spin-up
252 * (b) require spin-up to fully reply to IDENTIFY DEVICE
254 #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
255 #define STBY_ID_VAL 0x738c /* (a) and not (b) */
256 #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
257 #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
259 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
260 #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
261 #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
263 /* word 49: capabilities 0 */
264 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
265 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
266 #define IORDY_OFF 0x0400 /* 1=may be disabled */
267 #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
268 #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
269 #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
270 #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
271 #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
272 #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
274 /* word 50: capabilities 1 */
275 #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
277 /* words 51 & 52: PIO & DMA cycle times */
278 #define MODE 0xff00 /* the mode is in the MSBs */
280 /* word 53: whats_valid */
281 #define OK_W88 0x0004 /* the ultra_dma info is valid */
282 #define OK_W64_70 0x0002 /* see above for word descriptions */
283 #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
285 /*word 63,88: dma_mode, ultra_dma_mode*/
286 #define MODE_MAX 7 /* bit definitions force udma <=7 (when
287 * udma >=8 comes out it'll have to be
288 * defined in a new dma_mode word!) */
290 /* word 64: PIO transfer modes */
291 #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
292 #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
294 /* word 75: queue_depth */
295 #define DEPTH_BITS 0x001f /* bits used for queue depth */
297 /* words 80-81: version numbers */
298 /* NOVAL_0 or NOVAL_1 means device does not report version */
300 /* word 81: minor version number */
301 #define MINOR_MAX 0x22
302 /* words 82-84: cmds/feats supported */
303 #define CMDS_W82 0x77ff /* word 82: defined command locations*/
304 #define CMDS_W83 0x3fff /* word 83: defined command locations*/
305 #define CMDS_W84 0x002f /* word 83: defined command locations*/
306 #define SUPPORT_48_BIT 0x0400
307 #define NUM_CMD_FEAT_STR 48
309 /* words 85-87: cmds/feats enabled */
310 /* use cmd_feat_str[] to display what commands and features have
311 * been enabled with words 85-87
314 /* words 89, 90, SECU ERASE TIME */
315 #define ERASE_BITS 0x00ff
317 /* word 92: master password revision */
318 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
320 /* word 93: hw reset result */
321 #define CBLID 0x2000 /* CBLID status */
322 #define RST0 0x0001 /* 1=reset to device #0 */
323 #define DEV_DET 0x0006 /* how device num determined */
324 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
325 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
327 /* word 127: removable media status notification feature set support */
328 #define RM_STAT_BITS 0x0003
329 #define RM_STAT_SUP 0x0001
331 /* word 128: security */
332 #define SECU_ENABLED 0x0002
333 #define SECU_LEVEL 0x0010
334 #define NUM_SECU_STR 6
336 /* word 160: CFA power mode */
337 #define VALID_W160 0x8000 /* 1=word valid */
338 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
339 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
340 #define MAX_AMPS 0x0fff /* value = max current in ma */
342 /* word 255: integrity */
343 #define SIG 0x00ff /* signature location */
344 #define SIG_VAL 0x00a5 /* signature value */
346 #define TIMING_BUF_MB 1
347 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
349 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
360 smallint get_identity, get_geom;
362 smallint do_ctimings, do_timings;
363 smallint reread_partn;
364 smallint set_piomode, noisy_piomode;
365 smallint getset_readahead;
366 smallint getset_readonly;
367 smallint getset_unmask;
368 smallint getset_mult;
370 smallint getset_dma_q;
372 smallint getset_nowerr;
373 smallint getset_keep;
374 smallint getset_io32bit;
376 unsigned long Xreadahead;
377 unsigned long readonly;
378 unsigned long unmask;
383 unsigned long nowerr;
385 unsigned long io32bit;
386 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
390 #ifdef HDIO_DRIVE_CMD
391 smallint set_xfermode, get_xfermode;
392 smallint getset_dkeep;
393 smallint getset_standby;
394 smallint getset_lookahead;
395 smallint getset_prefetch;
396 smallint getset_defects;
397 smallint getset_wcache;
398 smallint getset_doorlock;
399 smallint set_seagate;
400 smallint set_standbynow;
401 smallint set_sleepnow;
402 smallint get_powermode;
403 smallint getset_apmmode;
404 int xfermode_requested;
406 unsigned long standby_requested; /* 0..255 */
407 unsigned long lookahead;
408 unsigned long prefetch;
409 unsigned long defects;
410 unsigned long wcache;
411 unsigned long doorlock;
412 unsigned long apmmode;
414 IF_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
415 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint getset_busstate;)
416 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
417 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
418 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
419 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
420 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
421 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
422 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
423 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
424 unsigned long hwif_data;
425 unsigned long hwif_ctrl;
426 unsigned long hwif_irq;
429 unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
432 #define G (*(struct globals*)bb_common_bufsiz1)
433 #define get_identity (G.get_identity )
434 #define get_geom (G.get_geom )
435 #define do_flush (G.do_flush )
436 #define do_ctimings (G.do_ctimings )
437 #define do_timings (G.do_timings )
438 #define reread_partn (G.reread_partn )
439 #define set_piomode (G.set_piomode )
440 #define noisy_piomode (G.noisy_piomode )
441 #define getset_readahead (G.getset_readahead )
442 #define getset_readonly (G.getset_readonly )
443 #define getset_unmask (G.getset_unmask )
444 #define getset_mult (G.getset_mult )
445 #define getset_dma_q (G.getset_dma_q )
446 #define getset_nowerr (G.getset_nowerr )
447 #define getset_keep (G.getset_keep )
448 #define getset_io32bit (G.getset_io32bit )
449 #define piomode (G.piomode )
450 #define Xreadahead (G.Xreadahead )
451 #define readonly (G.readonly )
452 #define unmask (G.unmask )
453 #define mult (G.mult )
454 #define dma_q (G.dma_q )
455 #define nowerr (G.nowerr )
456 #define keep (G.keep )
457 #define io32bit (G.io32bit )
459 #define getset_dma (G.getset_dma )
460 #define set_xfermode (G.set_xfermode )
461 #define get_xfermode (G.get_xfermode )
462 #define getset_dkeep (G.getset_dkeep )
463 #define getset_standby (G.getset_standby )
464 #define getset_lookahead (G.getset_lookahead )
465 #define getset_prefetch (G.getset_prefetch )
466 #define getset_defects (G.getset_defects )
467 #define getset_wcache (G.getset_wcache )
468 #define getset_doorlock (G.getset_doorlock )
469 #define set_seagate (G.set_seagate )
470 #define set_standbynow (G.set_standbynow )
471 #define set_sleepnow (G.set_sleepnow )
472 #define get_powermode (G.get_powermode )
473 #define getset_apmmode (G.getset_apmmode )
474 #define xfermode_requested (G.xfermode_requested )
475 #define dkeep (G.dkeep )
476 #define standby_requested (G.standby_requested )
477 #define lookahead (G.lookahead )
478 #define prefetch (G.prefetch )
479 #define defects (G.defects )
480 #define wcache (G.wcache )
481 #define doorlock (G.doorlock )
482 #define apmmode (G.apmmode )
483 #define get_IDentity (G.get_IDentity )
484 #define getset_busstate (G.getset_busstate )
485 #define perform_reset (G.perform_reset )
486 #define perform_tristate (G.perform_tristate )
487 #define unregister_hwif (G.unregister_hwif )
488 #define scan_hwif (G.scan_hwif )
489 #define busstate (G.busstate )
490 #define tristate (G.tristate )
491 #define hwif (G.hwif )
492 #define hwif_data (G.hwif_data )
493 #define hwif_ctrl (G.hwif_ctrl )
494 #define hwif_irq (G.hwif_irq )
495 #define INIT_G() do { \
496 setup_common_bufsiz(); \
497 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
501 /* Busybox messages and functions */
502 #if ENABLE_IOCTL_HEX2STR_ERROR
503 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
505 if (!ioctl(fd, cmd, args))
508 return bb_ioctl_or_warn(fd, cmd, args, string);
510 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
512 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
514 if (!ioctl(fd, cmd, args))
517 return bb_ioctl_or_warn(fd, cmd, args);
519 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
522 static void on_off(int value)
524 puts(value ? " (on)" : " (off)");
527 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
530 printf(" setting %s to %lu", s, arg);
535 static void print_value_on_off(const char *str, unsigned long argp)
537 printf(" %s\t= %2lu", str, argp);
541 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
542 static void print_ascii(const char *p, int length)
549 /* every 16bit word is big-endian (i.e. inverted) */
550 /* accessing bytes in 1,0, 3,2, 5,4... sequence */
555 /* find first non-space & print it */
556 while (length && p[ofs] != ' ') {
561 while (length && p[ofs]) {
571 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
574 printf("\t%-20s", string);
575 print_ascii((void*)&val[i], n);
579 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
584 for (ii = 0; ii <= MODE_MAX; ii++) {
585 if (mode_sel & 0x0001) {
586 printf("*%cdma%u ", cc, ii);
590 } else if (mode_sup & 0x0001)
591 printf("%cdma%u ", cc, ii);
599 static const char pkt_str[] ALIGN1 =
600 "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
601 "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
602 "Printer" "\0" /* word 0, bits 12-8 = 02 */
603 "Processor" "\0" /* word 0, bits 12-8 = 03 */
604 "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
605 "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
606 "Scanner" "\0" /* word 0, bits 12-8 = 06 */
607 "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
608 "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
609 "Communications device" "\0" /* word 0, bits 12-8 = 09 */
610 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
611 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
612 "Array controller" "\0" /* word 0, bits 12-8 = 0c */
613 "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
614 "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
615 "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
618 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
619 "reserved" "\0" /* bit 0 */
620 "hard sectored" "\0" /* bit 1 */
621 "soft sectored" "\0" /* bit 2 */
622 "not MFM encoded " "\0" /* bit 3 */
623 "head switch time > 15us" "\0" /* bit 4 */
624 "spindle motor control option" "\0" /* bit 5 */
625 "fixed drive" "\0" /* bit 6 */
626 "removable drive" "\0" /* bit 7 */
627 "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
628 "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
629 "disk xfer rate > 5Mbs" "\0" /* bit 10 */
630 "rotational speed tol." "\0" /* bit 11 */
631 "data strobe offset option" "\0" /* bit 12 */
632 "track offset option" "\0" /* bit 13 */
633 "format speed tolerance gap reqd" "\0" /* bit 14 */
637 static const char minor_str[] ALIGN1 =
639 "Unspecified" "\0" /* 0x0000 */
640 "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
641 "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
642 "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
643 "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
644 "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
645 "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
646 "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
647 "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
648 "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
649 "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
650 "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
651 "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
652 "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
653 "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
654 "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
655 "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
656 "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
657 "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
658 "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
659 "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
660 "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
661 "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
662 "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
663 "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
664 "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
665 "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
666 "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
667 "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
668 "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
669 "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
670 "reserved" "\0" /* 0x001f */
671 "reserved" "\0" /* 0x0020 */
672 "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
673 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
674 "reserved" /* 0x0023-0xfffe */
676 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
678 0, /* 0x0000 WARNING: actual_ver[] array */
679 1, /* 0x0001 WARNING: corresponds */
680 1, /* 0x0002 WARNING: *exactly* */
681 1, /* 0x0003 WARNING: to the ATA/ */
682 2, /* 0x0004 WARNING: ATAPI version */
683 2, /* 0x0005 WARNING: listed in */
684 3, /* 0x0006 WARNING: the */
685 2, /* 0x0007 WARNING: minor_str */
686 3, /* 0x0008 WARNING: array */
687 2, /* 0x0009 WARNING: above. */
688 3, /* 0x000a WARNING: */
689 3, /* 0x000b WARNING: If you change */
690 3, /* 0x000c WARNING: that one, */
691 4, /* 0x000d WARNING: change this one */
692 4, /* 0x000e WARNING: too!!! */
713 0 /* 0x0023-0xfffe */
716 static const char cmd_feat_str[] ALIGN1 =
717 "" "\0" /* word 82 bit 15: obsolete */
718 "NOP cmd" "\0" /* word 82 bit 14 */
719 "READ BUFFER cmd" "\0" /* word 82 bit 13 */
720 "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
721 "" "\0" /* word 82 bit 11: obsolete */
722 "Host Protected Area feature set" "\0" /* word 82 bit 10 */
723 "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
724 "SERVICE interrupt" "\0" /* word 82 bit 8 */
725 "Release interrupt" "\0" /* word 82 bit 7 */
726 "Look-ahead" "\0" /* word 82 bit 6 */
727 "Write cache" "\0" /* word 82 bit 5 */
728 "PACKET command feature set" "\0" /* word 82 bit 4 */
729 "Power Management feature set" "\0" /* word 82 bit 3 */
730 "Removable Media feature set" "\0" /* word 82 bit 2 */
731 "Security Mode feature set" "\0" /* word 82 bit 1 */
732 "SMART feature set" "\0" /* word 82 bit 0 */
734 "" "\0" /* word 83 bit 15: !valid bit */
735 "" "\0" /* word 83 bit 14: valid bit */
736 "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
737 "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
738 "Device Configuration Overlay feature set " "\0"
739 "48-bit Address feature set " "\0" /* word 83 bit 10 */
741 "SET MAX security extension" "\0" /* word 83 bit 8 */
742 "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
743 "SET FEATURES subcommand required to spinup after power up" "\0"
744 "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
745 "Removable Media Status Notification feature set" "\0"
746 "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
747 "CFA feature set" "\0" /* word 83 bit 2 */
748 "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
749 "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
751 "" "\0" /* word 84 bit 15: !valid bit */
752 "" "\0" /* word 84 bit 14: valid bit */
753 "" "\0" /* word 84 bit 13: reserved */
754 "" "\0" /* word 84 bit 12: reserved */
755 "" "\0" /* word 84 bit 11: reserved */
756 "" "\0" /* word 84 bit 10: reserved */
757 "" "\0" /* word 84 bit 9: reserved */
758 "" "\0" /* word 84 bit 8: reserved */
759 "" "\0" /* word 84 bit 7: reserved */
760 "" "\0" /* word 84 bit 6: reserved */
761 "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
762 "" "\0" /* word 84 bit 4: reserved */
763 "Media Card Pass Through Command feature set " "\0"
764 "Media serial number " "\0" /* word 84 bit 2 */
765 "SMART self-test " "\0" /* word 84 bit 1 */
766 "SMART error logging " /* word 84 bit 0 */
769 static const char secu_str[] ALIGN1 =
770 "supported" "\0" /* word 128, bit 0 */
771 "enabled" "\0" /* word 128, bit 1 */
772 "locked" "\0" /* word 128, bit 2 */
773 "frozen" "\0" /* word 128, bit 3 */
774 "expired: security count" "\0" /* word 128, bit 4 */
775 "supported: enhanced erase" /* word 128, bit 5 */
778 // Parse 512 byte disk identification block and print much crap.
779 static void identify(uint16_t *val) NORETURN;
780 static void identify(uint16_t *val)
783 uint16_t like_std = 1, std = 0, min_std = 0xffff;
784 uint16_t dev = NO_DEV, eqpt = NO_DEV;
785 uint8_t have_mode = 0, err_dma = 0;
787 uint32_t ll, mm, nn, oo;
788 uint64_t bbbig; /* (:) */
793 // Adjust for endianness
794 swab(val, buf, sizeof(buf));
797 /* check if we recognize the device type */
799 if (!(val[GEN_CONFIG] & NOT_ATA)) {
801 printf("ATA device, with ");
802 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
805 printf("CompactFlash ATA device, with ");
806 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
808 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
809 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
812 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
813 bb_error_msg_and_die("unknown device type");
815 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
816 /* Info from the specific configuration word says whether or not the
817 * ID command completed correctly. It is only defined, however in
818 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
819 * standards. Since the values allowed for this word are extremely
820 * specific, it should be safe to check it now, even though we don't
821 * know yet what standard this device is using.
823 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
824 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
827 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
828 puts("powers-up in standby; SET FEATURES subcmd spins-up.");
829 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
830 puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n");
833 /* output the model and serial numbers and the fw revision */
834 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
835 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
836 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
837 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
838 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
840 /* major & minor standards version number (Note: these words were not
841 * defined until ATA-3 & the CDROM std uses different words.) */
842 printf("Standards:");
844 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
845 if (like_std < 3) like_std = 3;
846 std = actual_ver[val[MINOR]];
848 printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
850 /* looks like when they up-issue the std, they obsolete one;
851 * thus, only the newest 4 issues need be supported. (That's
852 * what "kk" and "min_std" are all about.) */
853 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
854 printf("\n\tSupported: ");
855 jj = val[MAJOR] << 1;
856 kk = like_std >4 ? like_std-4: 0;
857 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
862 kk = like_std >4 ? like_std-4: 0;
864 if (min_std > ii) min_std = ii;
868 if (like_std < 3) like_std = 3;
870 /* Figure out what standard the device is using if it hasn't told
871 * us. If we know the std, check if the device is using any of
872 * the words from the next level up. It happens.
874 if (like_std < std) like_std = std;
876 if (((std == 5) || (!std && (like_std < 6))) &&
877 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
878 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
879 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
880 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
883 } else if (((std == 4) || (!std && (like_std < 5))) &&
884 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
885 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
886 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
887 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
890 } else if (((std == 3) || (!std && (like_std < 4))) &&
891 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
892 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
893 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
894 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
895 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
896 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
899 } else if (((std == 2) || (!std && (like_std < 3)))
900 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
903 } else if (((std == 1) || (!std && (like_std < 2))) &&
904 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
905 (val[WHATS_VALID] & OK_W64_70)) )
911 printf("\n\tLikely used: %u\n", like_std);
912 else if (like_std > std)
913 printf("& some of %u\n", like_std);
917 /* TBD: do CDROM stuff more thoroughly. For now... */
919 if (val[CDR_MINOR] == 9) {
921 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
923 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
925 printf("\n\tSupported: CD-ROM ATAPI");
926 jj = val[CDR_MAJOR] >> 1;
927 for (ii = 1; ii < 15; ii++) {
928 if (jj & 0x0001) printf("-%u ", ii);
932 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
933 /* the cdrom stuff is more like ATA-2 than anything else, so: */
937 if (min_std == 0xffff)
938 min_std = like_std > 4 ? like_std - 3 : 1;
940 puts("Configuration:");
941 /* more info from the general configuration word */
942 if ((eqpt != CDROM) && (like_std == 1)) {
943 jj = val[GEN_CONFIG] >> 1;
944 for (ii = 1; ii < 15; ii++) {
946 printf("\t%s\n", nth_string(ata1_cfg_str, ii));
950 if (dev == ATAPI_DEV) {
951 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
953 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
954 strng = "<=10ms with INTRQ";
955 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
959 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
961 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
963 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
969 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
970 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
973 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
974 puts("\tCHS addressing not supported");
976 jj = val[WHATS_VALID] & OK_W54_58;
977 printf("\tLogical\t\tmax\tcurrent\n"
978 "\tcylinders\t%u\t%u\n"
979 "\theads\t\t%u\t%u\n"
980 "\tsectors/track\t%u\t%u\n"
983 jj ? val[LCYLS_CUR] : 0,
985 jj ? val[LHEADS_CUR] : 0,
987 jj ? val[LSECTS_CUR] : 0);
989 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
990 printf("\tbytes/track: %u\tbytes/sector: %u\n",
991 val[TRACK_BYTES], val[SECT_BYTES]);
994 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
996 /* check Endian of capacity bytes */
997 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
998 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
999 if (abs(mm - nn) > abs(oo - nn))
1002 printf("\tCHS current addressable sectors:%11u\n", mm);
1005 /* LBA addressing */
1006 printf("\tLBA user addressable sectors:%11u\n", ll);
1007 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
1008 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
1010 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
1011 (uint64_t)val[LBA_48_MSB] << 32 |
1012 (uint64_t)val[LBA_MID] << 16 |
1014 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
1018 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
1019 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
1020 bbbig = (bbbig << 9) / 1000000;
1021 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
1024 printf("(%"PRIu64" GB)\n", bbbig/1000);
1029 /* hw support of commands (capabilities) */
1030 printf("Capabilities:\n\t");
1032 if (dev == ATAPI_DEV) {
1033 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP))
1034 printf("Cmd queuing, ");
1035 if (val[CAPAB_0] & OVLP_SUP)
1036 printf("Cmd overlap, ");
1038 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
1040 if (like_std != 1) {
1041 printf("IORDY%s(can%s be disabled)\n",
1042 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
1043 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
1047 if ((like_std == 1) && val[BUF_TYPE]) {
1048 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
1049 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
1050 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
1053 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
1054 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
1056 if ((min_std < 4) && (val[RW_LONG])) {
1057 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
1059 if ((eqpt != CDROM) && (like_std > 3)) {
1060 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
1063 if (dev == ATA_DEV) {
1065 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
1067 printf("\tStandby timer values: spec'd by %s",
1068 (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor");
1069 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
1070 printf(", %s device specific minimum\n",
1071 (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
1075 printf("\tR/W multiple sector transfer: ");
1076 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
1077 puts("not supported");
1079 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
1080 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
1081 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
1085 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
1086 /* We print out elsewhere whether the APM feature is enabled or
1087 * not. If it's not enabled, let's not repeat the info; just print
1089 printf("\tAdvancedPM level: ");
1090 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
1091 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
1092 printf("%u (0x%x)\n", apm_level, apm_level);
1095 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
1097 if (like_std > 5 && val[ACOUSTIC]) {
1098 printf("\tRecommended acoustic management value: %u, current value: %u\n",
1099 (val[ACOUSTIC] >> 8) & 0x00ff,
1100 val[ACOUSTIC] & 0x00ff);
1104 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
1105 puts("\tATA sw reset required");
1107 if (val[PKT_REL] || val[SVC_NBSY]) {
1108 printf("\tOverlap support:");
1110 printf(" %uus to release bus.", val[PKT_REL]);
1112 printf(" %uus to clear BSY after SERVICE cmd.",
1118 /* DMA stuff. Check that only one DMA mode is selected. */
1120 if (!(val[CAPAB_0] & DMA_SUP))
1121 puts("not supported");
1123 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1124 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1125 if (val[SINGLE_DMA]) {
1126 jj = val[SINGLE_DMA];
1127 kk = val[SINGLE_DMA] >> 8;
1128 err_dma += mode_loop(jj, kk, 's', &have_mode);
1130 if (val[MULTI_DMA]) {
1131 jj = val[MULTI_DMA];
1132 kk = val[MULTI_DMA] >> 8;
1133 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1135 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1136 jj = val[ULTRA_DMA];
1137 kk = val[ULTRA_DMA] >> 8;
1138 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1140 if (err_dma || !have_mode) printf("(?)");
1143 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1144 puts("\t\tInterleaved DMA support");
1146 if ((val[WHATS_VALID] & OK_W64_70)
1147 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1149 printf("\t\tCycle time:");
1150 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1151 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1156 /* Programmed IO stuff */
1158 /* If a drive supports mode n (e.g. 3), it also supports all modes less
1159 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1160 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1161 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1162 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1163 if (jj & 0x0001) printf("pio%d ", ii);
1167 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1168 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1169 printf("pio%d ", ii);
1174 if (val[WHATS_VALID] & OK_W64_70) {
1175 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1176 printf("\t\tCycle time:");
1177 if (val[PIO_NO_FLOW])
1178 printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1180 printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1185 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1186 puts("Commands/features:\n"
1187 "\tEnabled\tSupported:");
1188 jj = val[CMDS_SUPP_0];
1189 kk = val[CMDS_EN_0];
1190 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1191 const char *feat_str = nth_string(cmd_feat_str, ii);
1192 if ((jj & 0x8000) && (*feat_str != '\0')) {
1193 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
1197 if (ii % 16 == 15) {
1198 jj = val[CMDS_SUPP_0+1+(ii/16)];
1199 kk = val[CMDS_EN_0+1+(ii/16)];
1202 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1207 /* Removable Media Status Notification feature set */
1208 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1209 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1212 if ((eqpt != CDROM) && (like_std > 3)
1213 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1216 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1217 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1218 jj = val[SECU_STATUS];
1220 for (ii = 0; ii < NUM_SECU_STR; ii++) {
1221 printf("\t%s\t%s\n",
1222 (!(jj & 0x0001)) ? "not" : "",
1223 nth_string(secu_str, ii));
1226 if (val[SECU_STATUS] & SECU_ENABLED) {
1227 printf("\tSecurity level %s\n",
1228 (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1231 jj = val[ERASE_TIME] & ERASE_BITS;
1232 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1235 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1236 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1242 jj = val[HWRST_RSLT];
1243 if ((jj & VALID) == VALID_VAL) {
1247 if ((jj & DEV_DET) == JUMPER_VAL)
1248 strng = " determined by the jumper";
1249 else if ((jj & DEV_DET) == CSEL_VAL)
1250 strng = " determined by CSEL";
1253 printf("HW reset results:\n"
1255 "\tDevice num = %i%s\n",
1256 (val[HWRST_RSLT] & CBLID) ? "above" : "below",
1260 /* more stuff from std 5 */
1261 if ((like_std > 4) && (eqpt != CDROM)) {
1262 if (val[CFA_PWR_MODE] & VALID_W160) {
1263 printf("CFA power mode 1:\n"
1265 (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1266 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1267 if (val[CFA_PWR_MODE] & MAX_AMPS)
1268 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1270 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1271 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1279 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1280 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1281 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1282 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1283 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1284 // (which they should, but they should just return -EINVAL).
1286 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1287 // On a really old system, it will not, and we will be confused.
1290 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1291 static const char cfg_str[] ALIGN1 =
1292 """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
1293 "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
1294 "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1295 "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
1298 static const char BuffType[] ALIGN1 =
1299 "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
1302 static NOINLINE void dump_identity(const struct hd_driveid *id)
1305 const unsigned short *id_regs = (const void*) id;
1307 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1308 id->model, id->fw_rev, id->serial_no);
1309 for (i = 0; i <= 15; i++) {
1310 if (id->config & (1<<i))
1311 printf(" %s", nth_string(cfg_str, i));
1313 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1314 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1315 id->cyls, id->heads, id->sectors, id->track_bytes,
1316 id->sector_bytes, id->ecc_bytes,
1318 nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1319 id->buf_size/2, id->max_multsect);
1320 if (id->max_multsect) {
1321 printf(", MultSect=");
1322 if (!(id->multsect_valid & 1))
1323 printf("?%u?", id->multsect);
1324 else if (id->multsect)
1325 printf("%u", id->multsect);
1331 if (!(id->field_valid & 1))
1332 printf(" (maybe):");
1334 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1337 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1338 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1339 ((id->capability&2) == 0) ? "no" : "yes");
1341 if (id->capability & 2)
1342 printf(", LBAsects=%u", id->lba_capacity);
1344 printf("\n IORDY=%s",
1345 (id->capability & 8)
1346 ? ((id->capability & 4) ? "on/off" : "yes")
1349 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1350 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1352 if ((id->capability & 1) && (id->field_valid & 2))
1353 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1355 printf("\n PIO modes: ");
1356 if (id->tPIO <= 5) {
1358 if (id->tPIO >= 1) printf("pio1 ");
1359 if (id->tPIO >= 2) printf("pio2 ");
1361 if (id->field_valid & 2) {
1362 static const masks_labels_t pio_modes = {
1363 .masks = { 1, 2, ~3 },
1364 .labels = "pio3 \0""pio4 \0""pio? \0",
1366 print_flags(&pio_modes, id->eide_pio_modes);
1368 if (id->capability & 1) {
1369 if (id->dma_1word | id->dma_mword) {
1370 static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
1371 printf("\n DMA modes: ");
1372 print_flags_separated(dma_wmode_masks,
1373 "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
1374 id->dma_1word, NULL);
1375 print_flags_separated(dma_wmode_masks,
1376 "*\0""mdma0 \0""*\0""mdma1 \0""*\0""mdma2 \0""*\0""mdma? \0",
1377 id->dma_mword, NULL);
1380 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1381 static const masks_labels_t ultra_modes1 = {
1382 .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
1383 .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
1386 printf("\n UDMA modes: ");
1387 print_flags(&ultra_modes1, id->dma_ultra);
1388 #ifdef __NEW_HD_DRIVE_ID
1389 if (id->hw_config & 0x2000) {
1390 #else /* !__NEW_HD_DRIVE_ID */
1391 if (id->word93 & 0x2000) {
1392 #endif /* __NEW_HD_DRIVE_ID */
1393 static const masks_labels_t ultra_modes2 = {
1394 .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
1395 0x2000, 0x0020, 0x4000, 0x0040,
1397 .labels = "*\0""udma3 \0""*\0""udma4 \0"
1398 "*\0""udma5 \0""*\0""udma6 \0"
1401 print_flags(&ultra_modes2, id->dma_ultra);
1404 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1405 if (id_regs[83] & 8) {
1406 if (!(id_regs[86] & 8))
1407 printf(": disabled (255)");
1408 else if ((id_regs[91] & 0xFF00) != 0x4000)
1409 printf(": unknown setting");
1411 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1413 if (id_regs[82] & 0x20)
1414 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1415 #ifdef __NEW_HD_DRIVE_ID
1416 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1417 || (id->major_rev_num && id->minor_rev_num <= 31)
1419 printf("\n Drive conforms to: %s: ",
1420 (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1421 if (id->major_rev_num != 0x0000 /* NOVAL_0 */
1422 && id->major_rev_num != 0xFFFF /* NOVAL_1 */
1424 for (i = 0; i <= 15; i++) {
1425 if (id->major_rev_num & (1<<i))
1426 printf(" ATA/ATAPI-%u", i);
1430 #endif /* __NEW_HD_DRIVE_ID */
1431 puts("\n\n * current active mode\n");
1435 static void flush_buffer_cache(/*int fd*/ void)
1437 fsync(fd); /* flush buffers */
1438 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1439 #ifdef HDIO_DRIVE_CMD
1441 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1442 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1443 bb_perror_msg("HDIO_DRIVE_CMD");
1445 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1450 static void seek_to_zero(/*int fd*/ void)
1452 xlseek(fd, (off_t) 0, SEEK_SET);
1455 static void read_big_block(/*int fd,*/ char *buf)
1459 xread(fd, buf, TIMING_BUF_BYTES);
1460 /* access all sectors of buf to ensure the read fully completed */
1461 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1465 static unsigned dev_size_mb(/*int fd*/ void)
1468 unsigned long long blksize64;
1472 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1473 u.blksize64 /= (1024 * 1024);
1475 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1476 u.blksize64 = u.blksize32 / (2 * 1024);
1478 if (u.blksize64 > UINT_MAX)
1483 static void print_timing(unsigned m, unsigned elapsed_us)
1485 unsigned sec = elapsed_us / 1000000;
1486 unsigned hs = (elapsed_us % 1000000) / 10000;
1488 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1490 /* "| 1" prevents div-by-0 */
1491 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1492 // ~= (m * 1024) / (elapsed_us / 1000000)
1493 // = kb / elapsed_sec
1497 static void do_time(int cache /*,int fd*/)
1498 /* cache=1: time cache: repeatedly read N MB at offset 0
1499 * cache=0: time device: linear read, starting at offset 0
1502 unsigned max_iterations, iterations;
1503 unsigned start; /* doesn't need to be long long */
1504 unsigned elapsed, elapsed2;
1506 char *buf = xmalloc(TIMING_BUF_BYTES);
1508 if (mlock(buf, TIMING_BUF_BYTES))
1509 bb_perror_msg_and_die("mlock");
1511 /* Clear out the device request queues & give them time to complete.
1512 * NB: *small* delay. User is expected to have a clue and to not run
1513 * heavy io in parallel with measurements. */
1516 if (cache) { /* Time cache */
1518 read_big_block(buf);
1519 printf("Timing buffer-cache reads: ");
1520 } else { /* Time device */
1521 printf("Timing buffered disk reads:");
1525 /* Now do the timing */
1527 /* Max time to run (small for cache, avoids getting
1528 * huge total_MB which can overlow unsigned type) */
1529 elapsed2 = 510000; /* cache */
1530 max_iterations = UINT_MAX;
1532 elapsed2 = 3000000; /* not cache */
1533 /* Don't want to read past the end! */
1534 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1536 start = monotonic_us();
1540 read_big_block(buf);
1541 elapsed = (unsigned)monotonic_us() - start;
1543 } while (elapsed < elapsed2 && iterations < max_iterations);
1544 total_MB = iterations * TIMING_BUF_MB;
1545 //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1547 /* Cache: remove lseek() and monotonic_us() overheads
1549 start = monotonic_us();
1552 elapsed2 = (unsigned)monotonic_us() - start;
1553 } while (--iterations);
1554 //printf(" elapsed2:%u ", elapsed2);
1555 elapsed -= elapsed2;
1556 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1557 flush_buffer_cache();
1559 print_timing(total_MB, elapsed);
1560 munlock(buf, TIMING_BUF_BYTES);
1564 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1565 static void bus_state_value(unsigned value)
1567 if (value == BUSSTATE_ON)
1569 else if (value == BUSSTATE_OFF)
1571 else if (value == BUSSTATE_TRISTATE)
1572 puts(" (tristate)");
1574 printf(" (unknown: %u)\n", value);
1578 #ifdef HDIO_DRIVE_CMD
1579 static void interpret_standby(uint8_t standby)
1584 } else if (standby <= 240 || standby == 252 || standby == 255) {
1585 /* standby is in 5 sec units */
1586 unsigned t = standby * 5;
1587 printf("%u minutes %u seconds", t / 60, t % 60);
1588 } else if (standby <= 251) {
1589 unsigned t = (standby - 240); /* t is in 30 min units */;
1590 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0');
1593 printf("vendor-specific");
1599 static const uint8_t xfermode_val[] ALIGN1 = {
1600 8, 9, 10, 11, 12, 13, 14, 15,
1601 16, 17, 18, 19, 20, 21, 22, 23,
1602 32, 33, 34, 35, 36, 37, 38, 39,
1603 64, 65, 66, 67, 68, 69, 70, 71
1605 /* NB: we save size by _not_ storing terninating NUL! */
1606 static const char xfermode_name[][5] ALIGN1 = {
1607 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1608 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1609 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1610 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1613 static int translate_xfermode(const char *name)
1618 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1619 if (!strncmp(name, xfermode_name[i], 5))
1620 if (strlen(name) <= 5)
1621 return xfermode_val[i];
1623 /* Negative numbers are invalid and are caught later */
1624 val = bb_strtoi(name, NULL, 10);
1630 static void interpret_xfermode(unsigned xfermode)
1634 printf("default PIO mode");
1635 else if (xfermode == 1)
1636 printf("default PIO mode, disable IORDY");
1637 else if (xfermode >= 8 && xfermode <= 15)
1638 printf("PIO flow control mode%u", xfermode - 8);
1639 else if (xfermode >= 16 && xfermode <= 23)
1640 printf("singleword DMA mode%u", xfermode - 16);
1641 else if (xfermode >= 32 && xfermode <= 39)
1642 printf("multiword DMA mode%u", xfermode - 32);
1643 else if (xfermode >= 64 && xfermode <= 71)
1644 printf("UltraDMA mode%u", xfermode - 64);
1649 #endif /* HDIO_DRIVE_CMD */
1651 static void print_flag(int flag, const char *s, unsigned long value)
1654 printf(" setting %s to %lu\n", s, value);
1657 static void process_dev(char *devname)
1660 long parm, multcount;
1661 #ifndef HDIO_DRIVE_CMD
1662 int force_operation = 0;
1664 /* Please restore args[n] to these values after each ioctl
1665 except for args[2] */
1666 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1667 const char *fmt = " %s\t= %2ld";
1669 /*fd = xopen_nonblocking(devname);*/
1670 xmove_fd(xopen_nonblocking(devname), fd);
1671 printf("\n%s:\n", devname);
1673 if (getset_readahead == IS_SET) {
1674 print_flag(getset_readahead, "fs readahead", Xreadahead);
1675 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1677 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1678 if (unregister_hwif) {
1679 printf(" attempting to unregister hwif#%lu\n", hwif);
1680 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1683 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1684 if (scan_hwif == IS_SET) {
1685 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1686 args[0] = hwif_data;
1687 args[1] = hwif_ctrl;
1689 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1690 args[0] = WIN_SETFEATURES;
1695 if (noisy_piomode) {
1696 printf(" attempting to ");
1698 puts("auto-tune PIO mode");
1699 else if (piomode < 100)
1700 printf("set PIO mode to %d\n", piomode);
1701 else if (piomode < 200)
1702 printf("set MDMA mode to %d\n", (piomode-100));
1704 printf("set UDMA mode to %d\n", (piomode-200));
1706 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1708 if (getset_io32bit == IS_SET) {
1709 print_flag(getset_io32bit, "32-bit IO_support flag", io32bit);
1710 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1712 if (getset_mult == IS_SET) {
1713 print_flag(getset_mult, "multcount", mult);
1714 #ifdef HDIO_DRIVE_CMD
1715 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1717 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1720 if (getset_readonly == IS_SET) {
1721 print_flag_on_off(getset_readonly, "readonly", readonly);
1722 ioctl_or_warn(fd, BLKROSET, &readonly);
1724 if (getset_unmask == IS_SET) {
1725 print_flag_on_off(getset_unmask, "unmaskirq", unmask);
1726 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1728 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1729 if (getset_dma == IS_SET) {
1730 print_flag_on_off(getset_dma, "using_dma", dma);
1731 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1733 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1734 #ifdef HDIO_SET_QDMA
1735 if (getset_dma_q == IS_SET) {
1736 print_flag_on_off(getset_dma_q, "DMA queue_depth", dma_q);
1737 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1740 if (getset_nowerr == IS_SET) {
1741 print_flag_on_off(getset_nowerr, "nowerr", nowerr);
1742 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1744 if (getset_keep == IS_SET) {
1745 print_flag_on_off(getset_keep, "keep_settings", keep);
1746 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1748 #ifdef HDIO_DRIVE_CMD
1749 if (getset_doorlock == IS_SET) {
1750 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1752 print_flag_on_off(getset_doorlock, "drive doorlock", doorlock);
1753 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1754 args[0] = WIN_SETFEATURES;
1756 if (getset_dkeep == IS_SET) {
1757 /* lock/unlock the drive's "feature" settings */
1758 print_flag_on_off(getset_dkeep, "drive keep features", dkeep);
1759 args[2] = dkeep ? 0x66 : 0xcc;
1760 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1762 if (getset_defects == IS_SET) {
1763 args[2] = defects ? 0x04 : 0x84;
1764 print_flag(getset_defects, "drive defect-mgmt", defects);
1765 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1767 if (getset_prefetch == IS_SET) {
1770 print_flag(getset_prefetch, "drive prefetch", prefetch);
1771 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1775 args[1] = xfermode_requested;
1777 print_flag(1, "xfermode", xfermode_requested);
1778 interpret_xfermode(xfermode_requested);
1779 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1782 if (getset_lookahead == IS_SET) {
1783 args[2] = lookahead ? 0xaa : 0x55;
1784 print_flag_on_off(getset_lookahead, "drive read-lookahead", lookahead);
1785 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1787 if (getset_apmmode == IS_SET) {
1788 /* feature register */
1789 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */;
1790 args[1] = apmmode; /* sector count register 1-255 */
1791 printf(" setting APM level to %s 0x%02lX (%ld)\n",
1792 (apmmode == 255) ? "disabled" : "",
1794 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1797 if (getset_wcache == IS_SET) {
1798 #ifdef DO_FLUSHCACHE
1799 #ifndef WIN_FLUSHCACHE
1800 #define WIN_FLUSHCACHE 0xe7
1802 #endif /* DO_FLUSHCACHE */
1803 args[2] = wcache ? 0x02 : 0x82;
1804 print_flag_on_off(getset_wcache, "drive write-caching", wcache);
1805 #ifdef DO_FLUSHCACHE
1807 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1808 #endif /* DO_FLUSHCACHE */
1809 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1810 #ifdef DO_FLUSHCACHE
1812 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1813 #endif /* DO_FLUSHCACHE */
1816 /* In code below, we do not preserve args[0], but the rest
1817 is preserved, including args[2] */
1820 if (set_standbynow) {
1821 #ifndef WIN_STANDBYNOW1
1822 #define WIN_STANDBYNOW1 0xE0
1824 #ifndef WIN_STANDBYNOW2
1825 #define WIN_STANDBYNOW2 0x94
1827 puts(" issuing standby command");
1828 args[0] = WIN_STANDBYNOW1;
1829 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1832 #ifndef WIN_SLEEPNOW1
1833 #define WIN_SLEEPNOW1 0xE6
1835 #ifndef WIN_SLEEPNOW2
1836 #define WIN_SLEEPNOW2 0x99
1838 puts(" issuing sleep command");
1839 args[0] = WIN_SLEEPNOW1;
1840 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1844 puts(" disabling Seagate auto powersaving mode");
1845 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1847 if (getset_standby == IS_SET) {
1848 args[0] = WIN_SETIDLE1;
1849 args[1] = standby_requested;
1850 print_flag(1, "standby", standby_requested);
1851 interpret_standby(standby_requested);
1852 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1855 #else /* HDIO_DRIVE_CMD */
1856 if (force_operation) {
1858 flush_buffer_cache();
1859 if (-1 == read(fd, buf, sizeof(buf)))
1860 bb_perror_msg("read of 512 bytes failed");
1862 #endif /* HDIO_DRIVE_CMD */
1863 if (getset_mult || get_identity) {
1865 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1866 /* To be coherent with ioctl_or_warn. */
1867 if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1868 bb_perror_msg("HDIO_GET_MULTCOUNT");
1870 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1871 } else if (getset_mult) {
1872 printf(fmt, "multcount", multcount);
1873 on_off(multcount != 0);
1876 if (getset_io32bit) {
1877 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1878 printf(" IO_support\t=%3ld (", parm);
1880 puts("default 16-bit)");
1886 puts("32-bit w/sync)");
1888 puts("Request-Queue-Bypass)");
1893 if (getset_unmask) {
1894 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
1895 print_value_on_off("unmaskirq", parm);
1897 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1899 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1900 printf(fmt, "using_dma", parm);
1902 puts(" (DMA-Assisted-PIO)");
1908 #ifdef HDIO_GET_QDMA
1910 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
1911 print_value_on_off("queue_depth", parm);
1915 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
1916 print_value_on_off("keepsettings", parm);
1918 if (getset_nowerr) {
1919 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
1920 print_value_on_off("nowerr", parm);
1922 if (getset_readonly) {
1923 if (!ioctl_or_warn(fd, BLKROGET, &parm))
1924 print_value_on_off("readonly", parm);
1926 if (getset_readahead) {
1927 if (!ioctl_or_warn(fd, BLKRAGET, &parm))
1928 print_value_on_off("readahead", parm);
1931 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1932 struct hd_geometry g;
1934 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1935 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1936 g.cylinders, g.heads, g.sectors, parm, g.start);
1939 #ifdef HDIO_DRIVE_CMD
1940 if (get_powermode) {
1941 #ifndef WIN_CHECKPOWERMODE1
1942 #define WIN_CHECKPOWERMODE1 0xE5
1944 #ifndef WIN_CHECKPOWERMODE2
1945 #define WIN_CHECKPOWERMODE2 0x98
1949 args[0] = WIN_CHECKPOWERMODE1;
1950 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1951 if (errno != EIO || args[0] != 0 || args[1] != 0)
1956 state = (args[2] == 255) ? "active/idle" : "standby";
1957 args[1] = args[2] = 0;
1959 printf(" drive state is: %s\n", state);
1962 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1963 if (perform_reset) {
1964 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1966 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1967 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1968 if (perform_tristate) {
1971 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1973 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1974 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1976 struct hd_driveid id;
1978 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1979 if (multcount != -1) {
1980 id.multsect = multcount;
1981 id.multsect_valid |= 1;
1983 id.multsect_valid &= ~1;
1985 } else if (errno == -ENOMSG)
1986 puts(" no identification info available");
1987 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1988 bb_perror_msg("HDIO_GET_IDENTITY");
1990 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1994 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1996 memset(args1, 0, sizeof(args1));
1997 args1[0] = WIN_IDENTIFY;
1999 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
2000 identify((void *)(args1 + 4));
2003 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
2004 if (getset_busstate == IS_SET) {
2005 print_flag(1, "bus state", busstate);
2006 bus_state_value(busstate);
2007 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
2009 if (getset_busstate) {
2010 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
2011 printf(fmt, "bus state", parm);
2012 bus_state_value(parm);
2017 ioctl_or_warn(fd, BLKRRPART, NULL);
2020 do_time(1 /*,fd*/); /* time cache */
2022 do_time(0 /*,fd*/); /* time device */
2024 flush_buffer_cache();
2028 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
2029 static int fromhex(unsigned char c)
2033 if (c >= 'a' && c <= 'f')
2034 return (c - ('a' - 10));
2035 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
2038 static void identify_from_stdin(void) NORETURN;
2039 static void identify_from_stdin(void)
2042 unsigned char buf[1280];
2043 unsigned char *b = (unsigned char *)buf;
2046 xread(STDIN_FILENO, buf, 1280);
2048 // Convert the newline-separated hex data into an identify block.
2050 for (i = 0; i < 256; i++) {
2052 for (j = 0; j < 4; j++)
2053 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
2061 void identify_from_stdin(void);
2064 /* busybox specific stuff */
2065 static int parse_opts(unsigned long *value, int min, int max)
2068 *value = xatol_range(optarg, min, max);
2073 static int parse_opts_0_max(unsigned long *value, int max)
2075 return parse_opts(value, 0, max);
2077 static int parse_opts_0_1(unsigned long *value)
2079 return parse_opts(value, 0, 1);
2081 static int parse_opts_0_INTMAX(unsigned long *value)
2083 return parse_opts(value, 0, INT_MAX);
2086 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
2091 *value = translate_xfermode(optarg);
2092 *set = (*value > -1);
2097 /*------- getopt short options --------*/
2098 static const char hdparm_options[] ALIGN1 =
2099 "gfu::n::p:r::m::c::k::a::B:tT"
2100 IF_FEATURE_HDPARM_GET_IDENTITY("iI")
2101 IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
2102 #ifdef HDIO_DRIVE_CMD
2103 "S:D:P:X:K:A:L:W:CyYzZ"
2105 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
2106 #ifdef HDIO_GET_QDMA
2107 #ifdef HDIO_SET_QDMA
2113 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
2114 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
2115 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
2116 /*-------------------------------------*/
2118 /* our main() routine: */
2119 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2120 int hdparm_main(int argc, char **argv)
2127 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2129 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2130 IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2131 get_geom |= (c == 'g');
2132 do_flush |= (c == 'f');
2133 if (c == 'u') getset_unmask = parse_opts_0_1(&unmask);
2134 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
2135 if (c == 'd') getset_dma = parse_opts_0_max(&dma, 9);
2137 if (c == 'n') getset_nowerr = parse_opts_0_1(&nowerr);
2138 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2139 if (c == 'r') getset_readonly = parse_opts_0_1(&readonly);
2140 if (c == 'm') getset_mult = parse_opts_0_INTMAX(&mult /*32*/);
2141 if (c == 'c') getset_io32bit = parse_opts_0_INTMAX(&io32bit /*8*/);
2142 if (c == 'k') getset_keep = parse_opts_0_1(&keep);
2143 if (c == 'a') getset_readahead = parse_opts_0_INTMAX(&Xreadahead);
2144 if (c == 'B') getset_apmmode = parse_opts(&apmmode, 1, 255);
2145 do_flush |= do_timings |= (c == 't');
2146 do_flush |= do_ctimings |= (c == 'T');
2147 #ifdef HDIO_DRIVE_CMD
2148 if (c == 'S') getset_standby = parse_opts_0_max(&standby_requested, 255);
2149 if (c == 'D') getset_defects = parse_opts_0_INTMAX(&defects);
2150 if (c == 'P') getset_prefetch = parse_opts_0_INTMAX(&prefetch);
2151 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2152 if (c == 'K') getset_dkeep = parse_opts_0_1(&prefetch);
2153 if (c == 'A') getset_lookahead = parse_opts_0_1(&lookahead);
2154 if (c == 'L') getset_doorlock = parse_opts_0_1(&doorlock);
2155 if (c == 'W') getset_wcache = parse_opts_0_1(&wcache);
2156 get_powermode |= (c == 'C');
2157 set_standbynow |= (c == 'y');
2158 set_sleepnow |= (c == 'Y');
2159 reread_partn |= (c == 'z');
2160 set_seagate |= (c == 'Z');
2162 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') unregister_hwif = parse_opts_0_INTMAX(&hwif));
2163 #ifdef HDIO_GET_QDMA
2165 getset_dma_q = parse_opts_0_INTMAX(&dma_q);
2168 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2169 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') perform_tristate = parse_opts_0_1(&tristate));
2170 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') getset_busstate = parse_opts_0_max(&busstate, 2));
2171 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2173 scan_hwif = parse_opts_0_INTMAX(&hwif_data);
2174 hwif_ctrl = xatoi_positive((argv[optind]) ? argv[optind] : "");
2175 hwif_irq = xatoi_positive((argv[optind+1]) ? argv[optind+1] : "");
2176 /* Move past the 2 additional arguments */
2182 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2184 getset_mult = getset_io32bit = getset_unmask = getset_keep = getset_readonly = getset_readahead = get_geom = IS_GET;
2185 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(getset_dma = IS_GET);
2190 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2191 identify_from_stdin(); /* EXIT */
2196 process_dev(*argv++);
2199 return EXIT_SUCCESS;