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
15 //usage:#define hdparm_trivial_usage
16 //usage: "[OPTIONS] [DEVICE]"
17 //usage:#define hdparm_full_usage "\n\n"
18 //usage: " -a Get/set fs readahead"
19 //usage: "\n -A Set drive read-lookahead flag (0/1)"
20 //usage: "\n -b Get/set bus state (0 == off, 1 == on, 2 == tristate)"
21 //usage: "\n -B Set Advanced Power Management setting (1-255)"
22 //usage: "\n -c Get/set IDE 32-bit IO setting"
23 //usage: "\n -C Check IDE power mode status"
24 //usage: IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
25 //usage: "\n -d Get/set using_dma flag")
26 //usage: "\n -D Enable/disable drive defect-mgmt"
27 //usage: "\n -f Flush buffer cache for device on exit"
28 //usage: "\n -g Display drive geometry"
29 //usage: "\n -h Display terse usage information"
30 //usage: IF_FEATURE_HDPARM_GET_IDENTITY(
31 //usage: "\n -i Display drive identification")
32 //usage: IF_FEATURE_HDPARM_GET_IDENTITY(
33 //usage: "\n -I Detailed/current information directly from drive")
34 //usage: "\n -k Get/set keep_settings_over_reset flag (0/1)"
35 //usage: "\n -K Set drive keep_features_over_reset flag (0/1)"
36 //usage: "\n -L Set drive doorlock (0/1) (removable harddisks only)"
37 //usage: "\n -m Get/set multiple sector count"
38 //usage: "\n -n Get/set ignore-write-errors flag (0/1)"
39 //usage: "\n -p Set PIO mode on IDE interface chipset (0,1,2,3,4,...)"
40 //usage: "\n -P Set drive prefetch count"
41 /* //usage: "\n -q Change next setting quietly" - not supported ib bbox */
42 //usage: "\n -Q Get/set DMA tagged-queuing depth (if supported)"
43 //usage: "\n -r Get/set readonly flag (DANGEROUS to set)"
44 //usage: IF_FEATURE_HDPARM_HDIO_SCAN_HWIF(
45 //usage: "\n -R Register an IDE interface (DANGEROUS)")
46 //usage: "\n -S Set standby (spindown) timeout"
47 //usage: "\n -t Perform device read timings"
48 //usage: "\n -T Perform cache read timings"
49 //usage: "\n -u Get/set unmaskirq flag (0/1)"
50 //usage: IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(
51 //usage: "\n -U Unregister an IDE interface (DANGEROUS)")
52 //usage: "\n -v Defaults; same as -mcudkrag for IDE drives"
53 //usage: "\n -V Display program version and exit immediately"
54 //usage: IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(
55 //usage: "\n -w Perform device reset (DANGEROUS)")
56 //usage: "\n -W Set drive write-caching flag (0/1) (DANGEROUS)"
57 //usage: IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(
58 //usage: "\n -x Tristate device for hotswap (0/1) (DANGEROUS)")
59 //usage: "\n -X Set IDE xfer mode (DANGEROUS)"
60 //usage: "\n -y Put IDE drive in standby mode"
61 //usage: "\n -Y Put IDE drive to sleep"
62 //usage: "\n -Z Disable Seagate auto-powersaving mode"
63 //usage: "\n -z Reread partition table"
66 /* must be _after_ libbb.h: */
67 #include <linux/hdreg.h>
68 #include <sys/mount.h>
69 #if !defined(BLKGETSIZE64)
70 # define BLKGETSIZE64 _IOR(0x12,114,size_t)
76 #define ATA_DEV 0x0000
77 #define ATAPI_DEV 0x0001
79 /* word definitions */
80 /* ---------------- */
81 #define GEN_CONFIG 0 /* general configuration */
82 #define LCYLS 1 /* number of logical cylinders */
83 #define CONFIG 2 /* specific configuration */
84 #define LHEADS 3 /* number of logical heads */
85 #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
86 #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
87 #define LSECTS 6 /* number of logical sectors/track */
88 #define START_SERIAL 10 /* ASCII serial number */
89 #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
90 #define BUF_TYPE 20 /* buffer type (ATA-1) */
91 #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
92 #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
93 #define START_FW_REV 23 /* ASCII firmware revision */
94 #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
95 #define START_MODEL 27 /* ASCII model number */
96 #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
97 #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
98 #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
99 #define CAPAB_0 49 /* capabilities */
101 #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
102 #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
103 #define WHATS_VALID 53 /* what fields are valid */
104 #define LCYLS_CUR 54 /* current logical cylinders */
105 #define LHEADS_CUR 55 /* current logical heads */
106 #define LSECTS_CUR 56 /* current logical sectors/track */
107 #define CAPACITY_LSB 57 /* current capacity in sectors */
108 #define CAPACITY_MSB 58
109 #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
110 #define LBA_SECTS_LSB 60 /* LBA: total number of user */
111 #define LBA_SECTS_MSB 61 /* addressable sectors */
112 #define SINGLE_DMA 62 /* singleword DMA modes */
113 #define MULTI_DMA 63 /* multiword DMA modes */
114 #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
115 /* multiword DMA xfer cycle time: */
116 #define DMA_TIME_MIN 65 /* - minimum */
117 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
118 /* minimum PIO xfer cycle time: */
119 #define PIO_NO_FLOW 67 /* - without flow control */
120 #define PIO_FLOW 68 /* - with IORDY flow control */
121 #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
122 #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
123 #define CDR_MAJOR 73 /* CD ROM: major version number */
124 #define CDR_MINOR 74 /* CD ROM: minor version number */
125 #define QUEUE_DEPTH 75 /* queue depth */
126 #define MAJOR 80 /* major version number */
127 #define MINOR 81 /* minor version number */
128 #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
129 #define CMDS_SUPP_1 83
130 #define CMDS_SUPP_2 84
131 #define CMDS_EN_0 85 /* command/feature set(s) enabled */
134 #define ULTRA_DMA 88 /* ultra DMA modes */
135 /* time to complete security erase */
136 #define ERASE_TIME 89 /* - ordinary */
137 #define ENH_ERASE_TIME 90 /* - enhanced */
138 #define ADV_PWR 91 /* current advanced power management level
139 in low byte, 0x40 in high byte. */
140 #define PSWD_CODE 92 /* master password revision code */
141 #define HWRST_RSLT 93 /* hardware reset result */
142 #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
143 #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
144 #define LBA_MID 101 /* bits are used, but addr 103 */
145 #define LBA_48_MSB 102 /* has been reserved for LBA in */
146 #define LBA_64_MSB 103 /* the future. */
147 #define RM_STAT 127 /* removable media status notification feature set support */
148 #define SECU_STATUS 128 /* security status */
149 #define CFA_PWR_MODE 160 /* CFA power mode 1 */
150 #define START_MEDIA 176 /* media serial number */
151 #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
152 #define START_MANUF 196 /* media manufacturer I.D. */
153 #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
154 #define INTEGRITY 255 /* integrity word */
156 /* bit definitions within the words */
157 /* -------------------------------- */
159 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
161 #define VALID_VAL 0x4000
162 /* many words are considered invalid if they are either all-0 or all-1 */
163 #define NOVAL_0 0x0000
164 #define NOVAL_1 0xffff
166 /* word 0: gen_config */
167 #define NOT_ATA 0x8000
168 #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
169 #define MEDIA_REMOVABLE 0x0080
170 #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
171 #define INCOMPLETE 0x0004
172 #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
173 #define DRQ_RESPONSE_TIME 0x0060
174 #define DRQ_3MS_VAL 0x0000
175 #define DRQ_INTR_VAL 0x0020
176 #define DRQ_50US_VAL 0x0040
177 #define PKT_SIZE_SUPPORTED 0x0003
178 #define PKT_SIZE_12_VAL 0x0000
179 #define PKT_SIZE_16_VAL 0x0001
180 #define EQPT_TYPE 0x1f00
185 /* word 1: number of logical cylinders */
186 #define LCYLS_MAX 0x3fff /* maximum allowable value */
188 /* word 2: specific configuration
189 * (a) require SET FEATURES to spin-up
190 * (b) require spin-up to fully reply to IDENTIFY DEVICE
192 #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
193 #define STBY_ID_VAL 0x738c /* (a) and not (b) */
194 #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
195 #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
197 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
198 #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
199 #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
201 /* word 49: capabilities 0 */
202 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
203 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
204 #define IORDY_OFF 0x0400 /* 1=may be disabled */
205 #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
206 #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
207 #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
208 #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
209 #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
210 #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
212 /* word 50: capabilities 1 */
213 #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
215 /* words 51 & 52: PIO & DMA cycle times */
216 #define MODE 0xff00 /* the mode is in the MSBs */
218 /* word 53: whats_valid */
219 #define OK_W88 0x0004 /* the ultra_dma info is valid */
220 #define OK_W64_70 0x0002 /* see above for word descriptions */
221 #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
223 /*word 63,88: dma_mode, ultra_dma_mode*/
224 #define MODE_MAX 7 /* bit definitions force udma <=7 (when
225 * udma >=8 comes out it'll have to be
226 * defined in a new dma_mode word!) */
228 /* word 64: PIO transfer modes */
229 #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
230 #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
232 /* word 75: queue_depth */
233 #define DEPTH_BITS 0x001f /* bits used for queue depth */
235 /* words 80-81: version numbers */
236 /* NOVAL_0 or NOVAL_1 means device does not report version */
238 /* word 81: minor version number */
239 #define MINOR_MAX 0x22
240 /* words 82-84: cmds/feats supported */
241 #define CMDS_W82 0x77ff /* word 82: defined command locations*/
242 #define CMDS_W83 0x3fff /* word 83: defined command locations*/
243 #define CMDS_W84 0x002f /* word 83: defined command locations*/
244 #define SUPPORT_48_BIT 0x0400
245 #define NUM_CMD_FEAT_STR 48
247 /* words 85-87: cmds/feats enabled */
248 /* use cmd_feat_str[] to display what commands and features have
249 * been enabled with words 85-87
252 /* words 89, 90, SECU ERASE TIME */
253 #define ERASE_BITS 0x00ff
255 /* word 92: master password revision */
256 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
258 /* word 93: hw reset result */
259 #define CBLID 0x2000 /* CBLID status */
260 #define RST0 0x0001 /* 1=reset to device #0 */
261 #define DEV_DET 0x0006 /* how device num determined */
262 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
263 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
265 /* word 127: removable media status notification feature set support */
266 #define RM_STAT_BITS 0x0003
267 #define RM_STAT_SUP 0x0001
269 /* word 128: security */
270 #define SECU_ENABLED 0x0002
271 #define SECU_LEVEL 0x0010
272 #define NUM_SECU_STR 6
274 /* word 160: CFA power mode */
275 #define VALID_W160 0x8000 /* 1=word valid */
276 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
277 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
278 #define MAX_AMPS 0x0fff /* value = max current in ma */
280 /* word 255: integrity */
281 #define SIG 0x00ff /* signature location */
282 #define SIG_VAL 0x00a5 /* signature value */
284 #define TIMING_BUF_MB 1
285 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
287 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
298 smallint get_identity, get_geom;
300 smallint do_ctimings, do_timings;
301 smallint reread_partn;
302 smallint set_piomode, noisy_piomode;
303 smallint getset_readahead;
304 smallint getset_readonly;
305 smallint getset_unmask;
306 smallint getset_mult;
308 smallint getset_dma_q;
310 smallint getset_nowerr;
311 smallint getset_keep;
312 smallint getset_io32bit;
314 unsigned long Xreadahead;
315 unsigned long readonly;
316 unsigned long unmask;
321 unsigned long nowerr;
323 unsigned long io32bit;
324 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
328 #ifdef HDIO_DRIVE_CMD
329 smallint set_xfermode, get_xfermode;
330 smallint getset_dkeep;
331 smallint getset_standby;
332 smallint getset_lookahead;
333 smallint getset_prefetch;
334 smallint getset_defects;
335 smallint getset_wcache;
336 smallint getset_doorlock;
337 smallint set_seagate;
338 smallint set_standbynow;
339 smallint set_sleepnow;
340 smallint get_powermode;
341 smallint getset_apmmode;
342 int xfermode_requested;
344 unsigned long standby_requested; /* 0..255 */
345 unsigned long lookahead;
346 unsigned long prefetch;
347 unsigned long defects;
348 unsigned long wcache;
349 unsigned long doorlock;
350 unsigned long apmmode;
352 IF_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
353 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint getset_busstate;)
354 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
355 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
356 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
357 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
358 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
359 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
360 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
361 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
362 unsigned long hwif_data;
363 unsigned long hwif_ctrl;
364 unsigned long hwif_irq;
367 unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
370 #define G (*(struct globals*)&bb_common_bufsiz1)
371 #define get_identity (G.get_identity )
372 #define get_geom (G.get_geom )
373 #define do_flush (G.do_flush )
374 #define do_ctimings (G.do_ctimings )
375 #define do_timings (G.do_timings )
376 #define reread_partn (G.reread_partn )
377 #define set_piomode (G.set_piomode )
378 #define noisy_piomode (G.noisy_piomode )
379 #define getset_readahead (G.getset_readahead )
380 #define getset_readonly (G.getset_readonly )
381 #define getset_unmask (G.getset_unmask )
382 #define getset_mult (G.getset_mult )
383 #define getset_dma_q (G.getset_dma_q )
384 #define getset_nowerr (G.getset_nowerr )
385 #define getset_keep (G.getset_keep )
386 #define getset_io32bit (G.getset_io32bit )
387 #define piomode (G.piomode )
388 #define Xreadahead (G.Xreadahead )
389 #define readonly (G.readonly )
390 #define unmask (G.unmask )
391 #define mult (G.mult )
392 #define dma_q (G.dma_q )
393 #define nowerr (G.nowerr )
394 #define keep (G.keep )
395 #define io32bit (G.io32bit )
397 #define getset_dma (G.getset_dma )
398 #define set_xfermode (G.set_xfermode )
399 #define get_xfermode (G.get_xfermode )
400 #define getset_dkeep (G.getset_dkeep )
401 #define getset_standby (G.getset_standby )
402 #define getset_lookahead (G.getset_lookahead )
403 #define getset_prefetch (G.getset_prefetch )
404 #define getset_defects (G.getset_defects )
405 #define getset_wcache (G.getset_wcache )
406 #define getset_doorlock (G.getset_doorlock )
407 #define set_seagate (G.set_seagate )
408 #define set_standbynow (G.set_standbynow )
409 #define set_sleepnow (G.set_sleepnow )
410 #define get_powermode (G.get_powermode )
411 #define getset_apmmode (G.getset_apmmode )
412 #define xfermode_requested (G.xfermode_requested )
413 #define dkeep (G.dkeep )
414 #define standby_requested (G.standby_requested )
415 #define lookahead (G.lookahead )
416 #define prefetch (G.prefetch )
417 #define defects (G.defects )
418 #define wcache (G.wcache )
419 #define doorlock (G.doorlock )
420 #define apmmode (G.apmmode )
421 #define get_IDentity (G.get_IDentity )
422 #define getset_busstate (G.getset_busstate )
423 #define perform_reset (G.perform_reset )
424 #define perform_tristate (G.perform_tristate )
425 #define unregister_hwif (G.unregister_hwif )
426 #define scan_hwif (G.scan_hwif )
427 #define busstate (G.busstate )
428 #define tristate (G.tristate )
429 #define hwif (G.hwif )
430 #define hwif_data (G.hwif_data )
431 #define hwif_ctrl (G.hwif_ctrl )
432 #define hwif_irq (G.hwif_irq )
433 #define INIT_G() do { \
434 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
438 /* Busybox messages and functions */
439 #if ENABLE_IOCTL_HEX2STR_ERROR
440 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
442 if (!ioctl(fd, cmd, args))
445 return bb_ioctl_or_warn(fd, cmd, args, string);
447 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
449 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
451 if (!ioctl(fd, cmd, args))
454 return bb_ioctl_or_warn(fd, cmd, args);
456 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
459 static void on_off(int value)
461 puts(value ? " (on)" : " (off)");
464 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
467 printf(" setting %s to %lu", s, arg);
472 static void print_value_on_off(const char *str, unsigned long argp)
474 printf(" %s\t= %2lu", str, argp);
478 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
479 static void print_ascii(const char *p, int length)
486 /* every 16bit word is big-endian (i.e. inverted) */
487 /* accessing bytes in 1,0, 3,2, 5,4... sequence */
492 /* find first non-space & print it */
493 while (length && p[ofs] != ' ') {
498 while (length && p[ofs]) {
508 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
511 printf("\t%-20s", string);
512 print_ascii((void*)&val[i], n);
516 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
521 for (ii = 0; ii <= MODE_MAX; ii++) {
522 if (mode_sel & 0x0001) {
523 printf("*%cdma%u ", cc, ii);
527 } else if (mode_sup & 0x0001)
528 printf("%cdma%u ", cc, ii);
536 static const char pkt_str[] ALIGN1 =
537 "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
538 "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
539 "Printer" "\0" /* word 0, bits 12-8 = 02 */
540 "Processor" "\0" /* word 0, bits 12-8 = 03 */
541 "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
542 "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
543 "Scanner" "\0" /* word 0, bits 12-8 = 06 */
544 "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
545 "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
546 "Communications device" "\0" /* word 0, bits 12-8 = 09 */
547 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
548 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
549 "Array controller" "\0" /* word 0, bits 12-8 = 0c */
550 "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
551 "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
552 "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
555 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
556 "reserved" "\0" /* bit 0 */
557 "hard sectored" "\0" /* bit 1 */
558 "soft sectored" "\0" /* bit 2 */
559 "not MFM encoded " "\0" /* bit 3 */
560 "head switch time > 15us" "\0" /* bit 4 */
561 "spindle motor control option" "\0" /* bit 5 */
562 "fixed drive" "\0" /* bit 6 */
563 "removable drive" "\0" /* bit 7 */
564 "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
565 "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
566 "disk xfer rate > 5Mbs" "\0" /* bit 10 */
567 "rotational speed tol." "\0" /* bit 11 */
568 "data strobe offset option" "\0" /* bit 12 */
569 "track offset option" "\0" /* bit 13 */
570 "format speed tolerance gap reqd" "\0" /* bit 14 */
574 static const char minor_str[] ALIGN1 =
576 "Unspecified" "\0" /* 0x0000 */
577 "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
578 "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
579 "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
580 "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
581 "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
582 "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
583 "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
584 "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
585 "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
586 "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
587 "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
588 "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
589 "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
590 "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
591 "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
592 "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
593 "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
594 "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
595 "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
596 "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
597 "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
598 "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
599 "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
600 "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
601 "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
602 "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
603 "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
604 "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
605 "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
606 "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
607 "reserved" "\0" /* 0x001f */
608 "reserved" "\0" /* 0x0020 */
609 "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
610 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
611 "reserved" /* 0x0023-0xfffe */
613 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
615 0, /* 0x0000 WARNING: actual_ver[] array */
616 1, /* 0x0001 WARNING: corresponds */
617 1, /* 0x0002 WARNING: *exactly* */
618 1, /* 0x0003 WARNING: to the ATA/ */
619 2, /* 0x0004 WARNING: ATAPI version */
620 2, /* 0x0005 WARNING: listed in */
621 3, /* 0x0006 WARNING: the */
622 2, /* 0x0007 WARNING: minor_str */
623 3, /* 0x0008 WARNING: array */
624 2, /* 0x0009 WARNING: above. */
625 3, /* 0x000a WARNING: */
626 3, /* 0x000b WARNING: If you change */
627 3, /* 0x000c WARNING: that one, */
628 4, /* 0x000d WARNING: change this one */
629 4, /* 0x000e WARNING: too!!! */
650 0 /* 0x0023-0xfffe */
653 static const char cmd_feat_str[] ALIGN1 =
654 "" "\0" /* word 82 bit 15: obsolete */
655 "NOP cmd" "\0" /* word 82 bit 14 */
656 "READ BUFFER cmd" "\0" /* word 82 bit 13 */
657 "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
658 "" "\0" /* word 82 bit 11: obsolete */
659 "Host Protected Area feature set" "\0" /* word 82 bit 10 */
660 "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
661 "SERVICE interrupt" "\0" /* word 82 bit 8 */
662 "Release interrupt" "\0" /* word 82 bit 7 */
663 "Look-ahead" "\0" /* word 82 bit 6 */
664 "Write cache" "\0" /* word 82 bit 5 */
665 "PACKET command feature set" "\0" /* word 82 bit 4 */
666 "Power Management feature set" "\0" /* word 82 bit 3 */
667 "Removable Media feature set" "\0" /* word 82 bit 2 */
668 "Security Mode feature set" "\0" /* word 82 bit 1 */
669 "SMART feature set" "\0" /* word 82 bit 0 */
671 "" "\0" /* word 83 bit 15: !valid bit */
672 "" "\0" /* word 83 bit 14: valid bit */
673 "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
674 "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
675 "Device Configuration Overlay feature set " "\0"
676 "48-bit Address feature set " "\0" /* word 83 bit 10 */
678 "SET MAX security extension" "\0" /* word 83 bit 8 */
679 "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
680 "SET FEATURES subcommand required to spinup after power up" "\0"
681 "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
682 "Removable Media Status Notification feature set" "\0"
683 "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
684 "CFA feature set" "\0" /* word 83 bit 2 */
685 "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
686 "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
688 "" "\0" /* word 84 bit 15: !valid bit */
689 "" "\0" /* word 84 bit 14: valid bit */
690 "" "\0" /* word 84 bit 13: reserved */
691 "" "\0" /* word 84 bit 12: reserved */
692 "" "\0" /* word 84 bit 11: reserved */
693 "" "\0" /* word 84 bit 10: reserved */
694 "" "\0" /* word 84 bit 9: reserved */
695 "" "\0" /* word 84 bit 8: reserved */
696 "" "\0" /* word 84 bit 7: reserved */
697 "" "\0" /* word 84 bit 6: reserved */
698 "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
699 "" "\0" /* word 84 bit 4: reserved */
700 "Media Card Pass Through Command feature set " "\0"
701 "Media serial number " "\0" /* word 84 bit 2 */
702 "SMART self-test " "\0" /* word 84 bit 1 */
703 "SMART error logging " /* word 84 bit 0 */
706 static const char secu_str[] ALIGN1 =
707 "supported" "\0" /* word 128, bit 0 */
708 "enabled" "\0" /* word 128, bit 1 */
709 "locked" "\0" /* word 128, bit 2 */
710 "frozen" "\0" /* word 128, bit 3 */
711 "expired: security count" "\0" /* word 128, bit 4 */
712 "supported: enhanced erase" /* word 128, bit 5 */
715 // Parse 512 byte disk identification block and print much crap.
716 static void identify(uint16_t *val) NORETURN;
717 static void identify(uint16_t *val)
720 uint16_t like_std = 1, std = 0, min_std = 0xffff;
721 uint16_t dev = NO_DEV, eqpt = NO_DEV;
722 uint8_t have_mode = 0, err_dma = 0;
724 uint32_t ll, mm, nn, oo;
725 uint64_t bbbig; /* (:) */
730 // Adjust for endianness
731 swab(val, buf, sizeof(buf));
734 /* check if we recognize the device type */
736 if (!(val[GEN_CONFIG] & NOT_ATA)) {
738 printf("ATA device, with ");
739 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
742 printf("CompactFlash ATA device, with ");
743 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
745 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
746 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
749 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
750 bb_error_msg_and_die("unknown device type");
752 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
753 /* Info from the specific configuration word says whether or not the
754 * ID command completed correctly. It is only defined, however in
755 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
756 * standards. Since the values allowed for this word are extremely
757 * specific, it should be safe to check it now, even though we don't
758 * know yet what standard this device is using.
760 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
761 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
764 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
765 puts("powers-up in standby; SET FEATURES subcmd spins-up.");
766 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
767 puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n");
770 /* output the model and serial numbers and the fw revision */
771 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
772 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
773 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
774 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
775 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
777 /* major & minor standards version number (Note: these words were not
778 * defined until ATA-3 & the CDROM std uses different words.) */
779 printf("Standards:");
781 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
782 if (like_std < 3) like_std = 3;
783 std = actual_ver[val[MINOR]];
785 printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
787 /* looks like when they up-issue the std, they obsolete one;
788 * thus, only the newest 4 issues need be supported. (That's
789 * what "kk" and "min_std" are all about.) */
790 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
791 printf("\n\tSupported: ");
792 jj = val[MAJOR] << 1;
793 kk = like_std >4 ? like_std-4: 0;
794 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
799 kk = like_std >4 ? like_std-4: 0;
801 if (min_std > ii) min_std = ii;
805 if (like_std < 3) like_std = 3;
807 /* Figure out what standard the device is using if it hasn't told
808 * us. If we know the std, check if the device is using any of
809 * the words from the next level up. It happens.
811 if (like_std < std) like_std = std;
813 if (((std == 5) || (!std && (like_std < 6))) &&
814 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
815 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
816 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
817 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
820 } else if (((std == 4) || (!std && (like_std < 5))) &&
821 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
822 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
823 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
824 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
827 } else if (((std == 3) || (!std && (like_std < 4))) &&
828 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
829 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
830 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
831 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
832 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
833 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
836 } else if (((std == 2) || (!std && (like_std < 3)))
837 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
840 } else if (((std == 1) || (!std && (like_std < 2))) &&
841 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
842 (val[WHATS_VALID] & OK_W64_70)) )
848 printf("\n\tLikely used: %u\n", like_std);
849 else if (like_std > std)
850 printf("& some of %u\n", like_std);
854 /* TBD: do CDROM stuff more thoroughly. For now... */
856 if (val[CDR_MINOR] == 9) {
858 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
860 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
862 printf("\n\tSupported: CD-ROM ATAPI");
863 jj = val[CDR_MAJOR] >> 1;
864 for (ii = 1; ii < 15; ii++) {
865 if (jj & 0x0001) printf("-%u ", ii);
869 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
870 /* the cdrom stuff is more like ATA-2 than anything else, so: */
874 if (min_std == 0xffff)
875 min_std = like_std > 4 ? like_std - 3 : 1;
877 puts("Configuration:");
878 /* more info from the general configuration word */
879 if ((eqpt != CDROM) && (like_std == 1)) {
880 jj = val[GEN_CONFIG] >> 1;
881 for (ii = 1; ii < 15; ii++) {
883 printf("\t%s\n", nth_string(ata1_cfg_str, ii));
887 if (dev == ATAPI_DEV) {
888 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
890 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
891 strng = "<=10ms with INTRQ";
892 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
896 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
898 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
900 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
906 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
907 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
910 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
911 puts("\tCHS addressing not supported");
913 jj = val[WHATS_VALID] & OK_W54_58;
914 printf("\tLogical\t\tmax\tcurrent\n"
915 "\tcylinders\t%u\t%u\n"
916 "\theads\t\t%u\t%u\n"
917 "\tsectors/track\t%u\t%u\n"
920 jj ? val[LCYLS_CUR] : 0,
922 jj ? val[LHEADS_CUR] : 0,
924 jj ? val[LSECTS_CUR] : 0);
926 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
927 printf("\tbytes/track: %u\tbytes/sector: %u\n",
928 val[TRACK_BYTES], val[SECT_BYTES]);
931 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
933 /* check Endian of capacity bytes */
934 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
935 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
936 if (abs(mm - nn) > abs(oo - nn))
939 printf("\tCHS current addressable sectors:%11u\n", mm);
943 printf("\tLBA user addressable sectors:%11u\n", ll);
944 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
945 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
947 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
948 (uint64_t)val[LBA_48_MSB] << 32 |
949 (uint64_t)val[LBA_MID] << 16 |
951 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
955 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
956 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
957 bbbig = (bbbig << 9) / 1000000;
958 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
961 printf("(%"PRIu64" GB)\n", bbbig/1000);
966 /* hw support of commands (capabilities) */
967 printf("Capabilities:\n\t");
969 if (dev == ATAPI_DEV) {
970 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP))
971 printf("Cmd queuing, ");
972 if (val[CAPAB_0] & OVLP_SUP)
973 printf("Cmd overlap, ");
975 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
978 printf("IORDY%s(can%s be disabled)\n",
979 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
980 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
984 if ((like_std == 1) && val[BUF_TYPE]) {
985 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
986 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
987 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
990 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
991 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
993 if ((min_std < 4) && (val[RW_LONG])) {
994 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
996 if ((eqpt != CDROM) && (like_std > 3)) {
997 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
1000 if (dev == ATA_DEV) {
1002 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
1004 printf("\tStandby timer values: spec'd by %s",
1005 (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor");
1006 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
1007 printf(", %s device specific minimum\n",
1008 (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
1012 printf("\tR/W multiple sector transfer: ");
1013 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
1014 puts("not supported");
1016 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
1017 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
1018 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
1022 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
1023 /* We print out elsewhere whether the APM feature is enabled or
1024 * not. If it's not enabled, let's not repeat the info; just print
1026 printf("\tAdvancedPM level: ");
1027 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
1028 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
1029 printf("%u (0x%x)\n", apm_level, apm_level);
1032 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
1034 if (like_std > 5 && val[ACOUSTIC]) {
1035 printf("\tRecommended acoustic management value: %u, current value: %u\n",
1036 (val[ACOUSTIC] >> 8) & 0x00ff,
1037 val[ACOUSTIC] & 0x00ff);
1041 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
1042 puts("\tATA sw reset required");
1044 if (val[PKT_REL] || val[SVC_NBSY]) {
1045 printf("\tOverlap support:");
1047 printf(" %uus to release bus.", val[PKT_REL]);
1049 printf(" %uus to clear BSY after SERVICE cmd.",
1055 /* DMA stuff. Check that only one DMA mode is selected. */
1057 if (!(val[CAPAB_0] & DMA_SUP))
1058 puts("not supported");
1060 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1061 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1062 if (val[SINGLE_DMA]) {
1063 jj = val[SINGLE_DMA];
1064 kk = val[SINGLE_DMA] >> 8;
1065 err_dma += mode_loop(jj, kk, 's', &have_mode);
1067 if (val[MULTI_DMA]) {
1068 jj = val[MULTI_DMA];
1069 kk = val[MULTI_DMA] >> 8;
1070 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1072 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1073 jj = val[ULTRA_DMA];
1074 kk = val[ULTRA_DMA] >> 8;
1075 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1077 if (err_dma || !have_mode) printf("(?)");
1080 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1081 puts("\t\tInterleaved DMA support");
1083 if ((val[WHATS_VALID] & OK_W64_70)
1084 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1086 printf("\t\tCycle time:");
1087 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1088 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1093 /* Programmed IO stuff */
1095 /* If a drive supports mode n (e.g. 3), it also supports all modes less
1096 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1097 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1098 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1099 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1100 if (jj & 0x0001) printf("pio%d ", ii);
1104 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1105 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1106 printf("pio%d ", ii);
1111 if (val[WHATS_VALID] & OK_W64_70) {
1112 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1113 printf("\t\tCycle time:");
1114 if (val[PIO_NO_FLOW])
1115 printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1117 printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1122 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1123 puts("Commands/features:\n"
1124 "\tEnabled\tSupported:");
1125 jj = val[CMDS_SUPP_0];
1126 kk = val[CMDS_EN_0];
1127 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1128 const char *feat_str = nth_string(cmd_feat_str, ii);
1129 if ((jj & 0x8000) && (*feat_str != '\0')) {
1130 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
1134 if (ii % 16 == 15) {
1135 jj = val[CMDS_SUPP_0+1+(ii/16)];
1136 kk = val[CMDS_EN_0+1+(ii/16)];
1139 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1144 /* Removable Media Status Notification feature set */
1145 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1146 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1149 if ((eqpt != CDROM) && (like_std > 3)
1150 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1153 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1154 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1155 jj = val[SECU_STATUS];
1157 for (ii = 0; ii < NUM_SECU_STR; ii++) {
1158 printf("\t%s\t%s\n",
1159 (!(jj & 0x0001)) ? "not" : "",
1160 nth_string(secu_str, ii));
1163 if (val[SECU_STATUS] & SECU_ENABLED) {
1164 printf("\tSecurity level %s\n",
1165 (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1168 jj = val[ERASE_TIME] & ERASE_BITS;
1169 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1172 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1173 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1179 jj = val[HWRST_RSLT];
1180 if ((jj & VALID) == VALID_VAL) {
1184 if ((jj & DEV_DET) == JUMPER_VAL)
1185 strng = " determined by the jumper";
1186 else if ((jj & DEV_DET) == CSEL_VAL)
1187 strng = " determined by CSEL";
1190 printf("HW reset results:\n"
1192 "\tDevice num = %i%s\n",
1193 (val[HWRST_RSLT] & CBLID) ? "above" : "below",
1197 /* more stuff from std 5 */
1198 if ((like_std > 4) && (eqpt != CDROM)) {
1199 if (val[CFA_PWR_MODE] & VALID_W160) {
1200 printf("CFA power mode 1:\n"
1202 (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1203 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1204 if (val[CFA_PWR_MODE] & MAX_AMPS)
1205 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1207 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1208 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1216 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1217 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1218 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1219 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1220 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1221 // (which they should, but they should just return -EINVAL).
1223 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1224 // On a really old system, it will not, and we will be confused.
1227 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1228 static const char cfg_str[] ALIGN1 =
1229 """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
1230 "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
1231 "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1232 "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
1235 static const char BuffType[] ALIGN1 =
1236 "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
1239 static NOINLINE void dump_identity(const struct hd_driveid *id)
1242 const unsigned short *id_regs = (const void*) id;
1244 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1245 id->model, id->fw_rev, id->serial_no);
1246 for (i = 0; i <= 15; i++) {
1247 if (id->config & (1<<i))
1248 printf(" %s", nth_string(cfg_str, i));
1250 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1251 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1252 id->cyls, id->heads, id->sectors, id->track_bytes,
1253 id->sector_bytes, id->ecc_bytes,
1255 nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1256 id->buf_size/2, id->max_multsect);
1257 if (id->max_multsect) {
1258 printf(", MultSect=");
1259 if (!(id->multsect_valid & 1))
1260 printf("?%u?", id->multsect);
1261 else if (id->multsect)
1262 printf("%u", id->multsect);
1268 if (!(id->field_valid & 1))
1269 printf(" (maybe):");
1271 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1274 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1275 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1276 ((id->capability&2) == 0) ? "no" : "yes");
1278 if (id->capability & 2)
1279 printf(", LBAsects=%u", id->lba_capacity);
1281 printf("\n IORDY=%s",
1282 (id->capability & 8)
1283 ? ((id->capability & 4) ? "on/off" : "yes")
1286 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1287 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1289 if ((id->capability & 1) && (id->field_valid & 2))
1290 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1292 printf("\n PIO modes: ");
1293 if (id->tPIO <= 5) {
1295 if (id->tPIO >= 1) printf("pio1 ");
1296 if (id->tPIO >= 2) printf("pio2 ");
1298 if (id->field_valid & 2) {
1299 static const masks_labels_t pio_modes = {
1300 .masks = { 1, 2, ~3 },
1301 .labels = "pio3 \0""pio4 \0""pio? \0",
1303 print_flags(&pio_modes, id->eide_pio_modes);
1305 if (id->capability & 1) {
1306 if (id->dma_1word | id->dma_mword) {
1307 static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
1308 printf("\n DMA modes: ");
1309 print_flags_separated(dma_wmode_masks,
1310 "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
1311 id->dma_1word, NULL);
1312 print_flags_separated(dma_wmode_masks,
1313 "*\0""mdma0 \0""*\0""mdma1 \0""*\0""mdma2 \0""*\0""mdma? \0",
1314 id->dma_mword, NULL);
1317 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1318 static const masks_labels_t ultra_modes1 = {
1319 .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
1320 .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
1323 printf("\n UDMA modes: ");
1324 print_flags(&ultra_modes1, id->dma_ultra);
1325 #ifdef __NEW_HD_DRIVE_ID
1326 if (id->hw_config & 0x2000) {
1327 #else /* !__NEW_HD_DRIVE_ID */
1328 if (id->word93 & 0x2000) {
1329 #endif /* __NEW_HD_DRIVE_ID */
1330 static const masks_labels_t ultra_modes2 = {
1331 .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
1332 0x2000, 0x0020, 0x4000, 0x0040,
1334 .labels = "*\0""udma3 \0""*\0""udma4 \0"
1335 "*\0""udma5 \0""*\0""udma6 \0"
1338 print_flags(&ultra_modes2, id->dma_ultra);
1341 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1342 if (id_regs[83] & 8) {
1343 if (!(id_regs[86] & 8))
1344 printf(": disabled (255)");
1345 else if ((id_regs[91] & 0xFF00) != 0x4000)
1346 printf(": unknown setting");
1348 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1350 if (id_regs[82] & 0x20)
1351 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1352 #ifdef __NEW_HD_DRIVE_ID
1353 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1354 || (id->major_rev_num && id->minor_rev_num <= 31)
1356 printf("\n Drive conforms to: %s: ",
1357 (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1358 if (id->major_rev_num != 0x0000 /* NOVAL_0 */
1359 && id->major_rev_num != 0xFFFF /* NOVAL_1 */
1361 for (i = 0; i <= 15; i++) {
1362 if (id->major_rev_num & (1<<i))
1363 printf(" ATA/ATAPI-%u", i);
1367 #endif /* __NEW_HD_DRIVE_ID */
1368 puts("\n\n * current active mode\n");
1372 static void flush_buffer_cache(/*int fd*/ void)
1374 fsync(fd); /* flush buffers */
1375 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1376 #ifdef HDIO_DRIVE_CMD
1378 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1379 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1380 bb_perror_msg("HDIO_DRIVE_CMD");
1382 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1387 static void seek_to_zero(/*int fd*/ void)
1389 xlseek(fd, (off_t) 0, SEEK_SET);
1392 static void read_big_block(/*int fd,*/ char *buf)
1396 xread(fd, buf, TIMING_BUF_BYTES);
1397 /* access all sectors of buf to ensure the read fully completed */
1398 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1402 static unsigned dev_size_mb(/*int fd*/ void)
1405 unsigned long long blksize64;
1409 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1410 u.blksize64 /= (1024 * 1024);
1412 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1413 u.blksize64 = u.blksize32 / (2 * 1024);
1415 if (u.blksize64 > UINT_MAX)
1420 static void print_timing(unsigned m, unsigned elapsed_us)
1422 unsigned sec = elapsed_us / 1000000;
1423 unsigned hs = (elapsed_us % 1000000) / 10000;
1425 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1427 /* "| 1" prevents div-by-0 */
1428 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1429 // ~= (m * 1024) / (elapsed_us / 1000000)
1430 // = kb / elapsed_sec
1434 static void do_time(int cache /*,int fd*/)
1435 /* cache=1: time cache: repeatedly read N MB at offset 0
1436 * cache=0: time device: linear read, starting at offset 0
1439 unsigned max_iterations, iterations;
1440 unsigned start; /* doesn't need to be long long */
1441 unsigned elapsed, elapsed2;
1443 char *buf = xmalloc(TIMING_BUF_BYTES);
1445 if (mlock(buf, TIMING_BUF_BYTES))
1446 bb_perror_msg_and_die("mlock");
1448 /* Clear out the device request queues & give them time to complete.
1449 * NB: *small* delay. User is expected to have a clue and to not run
1450 * heavy io in parallel with measurements. */
1453 if (cache) { /* Time cache */
1455 read_big_block(buf);
1456 printf("Timing buffer-cache reads: ");
1457 } else { /* Time device */
1458 printf("Timing buffered disk reads:");
1462 /* Now do the timing */
1464 /* Max time to run (small for cache, avoids getting
1465 * huge total_MB which can overlow unsigned type) */
1466 elapsed2 = 510000; /* cache */
1467 max_iterations = UINT_MAX;
1469 elapsed2 = 3000000; /* not cache */
1470 /* Don't want to read past the end! */
1471 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1473 start = monotonic_us();
1477 read_big_block(buf);
1478 elapsed = (unsigned)monotonic_us() - start;
1480 } while (elapsed < elapsed2 && iterations < max_iterations);
1481 total_MB = iterations * TIMING_BUF_MB;
1482 //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1484 /* Cache: remove lseek() and monotonic_us() overheads
1486 start = monotonic_us();
1489 elapsed2 = (unsigned)monotonic_us() - start;
1490 } while (--iterations);
1491 //printf(" elapsed2:%u ", elapsed2);
1492 elapsed -= elapsed2;
1493 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1494 flush_buffer_cache();
1496 print_timing(total_MB, elapsed);
1497 munlock(buf, TIMING_BUF_BYTES);
1501 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1502 static void bus_state_value(unsigned value)
1504 if (value == BUSSTATE_ON)
1506 else if (value == BUSSTATE_OFF)
1508 else if (value == BUSSTATE_TRISTATE)
1509 puts(" (tristate)");
1511 printf(" (unknown: %u)\n", value);
1515 #ifdef HDIO_DRIVE_CMD
1516 static void interpret_standby(uint8_t standby)
1521 } else if (standby <= 240 || standby == 252 || standby == 255) {
1522 /* standby is in 5 sec units */
1523 unsigned t = standby * 5;
1524 printf("%u minutes %u seconds", t / 60, t % 60);
1525 } else if (standby <= 251) {
1526 unsigned t = (standby - 240); /* t is in 30 min units */;
1527 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0');
1530 printf("vendor-specific");
1536 static const uint8_t xfermode_val[] ALIGN1 = {
1537 8, 9, 10, 11, 12, 13, 14, 15,
1538 16, 17, 18, 19, 20, 21, 22, 23,
1539 32, 33, 34, 35, 36, 37, 38, 39,
1540 64, 65, 66, 67, 68, 69, 70, 71
1542 /* NB: we save size by _not_ storing terninating NUL! */
1543 static const char xfermode_name[][5] ALIGN1 = {
1544 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1545 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1546 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1547 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1550 static int translate_xfermode(const char *name)
1555 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1556 if (!strncmp(name, xfermode_name[i], 5))
1557 if (strlen(name) <= 5)
1558 return xfermode_val[i];
1560 /* Negative numbers are invalid and are caught later */
1561 val = bb_strtoi(name, NULL, 10);
1567 static void interpret_xfermode(unsigned xfermode)
1571 printf("default PIO mode");
1572 else if (xfermode == 1)
1573 printf("default PIO mode, disable IORDY");
1574 else if (xfermode >= 8 && xfermode <= 15)
1575 printf("PIO flow control mode%u", xfermode - 8);
1576 else if (xfermode >= 16 && xfermode <= 23)
1577 printf("singleword DMA mode%u", xfermode - 16);
1578 else if (xfermode >= 32 && xfermode <= 39)
1579 printf("multiword DMA mode%u", xfermode - 32);
1580 else if (xfermode >= 64 && xfermode <= 71)
1581 printf("UltraDMA mode%u", xfermode - 64);
1586 #endif /* HDIO_DRIVE_CMD */
1588 static void print_flag(int flag, const char *s, unsigned long value)
1591 printf(" setting %s to %lu\n", s, value);
1594 static void process_dev(char *devname)
1597 long parm, multcount;
1598 #ifndef HDIO_DRIVE_CMD
1599 int force_operation = 0;
1601 /* Please restore args[n] to these values after each ioctl
1602 except for args[2] */
1603 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1604 const char *fmt = " %s\t= %2ld";
1606 /*fd = xopen_nonblocking(devname);*/
1607 xmove_fd(xopen_nonblocking(devname), fd);
1608 printf("\n%s:\n", devname);
1610 if (getset_readahead == IS_SET) {
1611 print_flag(getset_readahead, "fs readahead", Xreadahead);
1612 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1614 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1615 if (unregister_hwif) {
1616 printf(" attempting to unregister hwif#%lu\n", hwif);
1617 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1620 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1621 if (scan_hwif == IS_SET) {
1622 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1623 args[0] = hwif_data;
1624 args[1] = hwif_ctrl;
1626 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1627 args[0] = WIN_SETFEATURES;
1632 if (noisy_piomode) {
1633 printf(" attempting to ");
1635 puts("auto-tune PIO mode");
1636 else if (piomode < 100)
1637 printf("set PIO mode to %d\n", piomode);
1638 else if (piomode < 200)
1639 printf("set MDMA mode to %d\n", (piomode-100));
1641 printf("set UDMA mode to %d\n", (piomode-200));
1643 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1645 if (getset_io32bit == IS_SET) {
1646 print_flag(getset_io32bit, "32-bit IO_support flag", io32bit);
1647 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1649 if (getset_mult == IS_SET) {
1650 print_flag(getset_mult, "multcount", mult);
1651 #ifdef HDIO_DRIVE_CMD
1652 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1654 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1657 if (getset_readonly == IS_SET) {
1658 print_flag_on_off(getset_readonly, "readonly", readonly);
1659 ioctl_or_warn(fd, BLKROSET, &readonly);
1661 if (getset_unmask == IS_SET) {
1662 print_flag_on_off(getset_unmask, "unmaskirq", unmask);
1663 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1665 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1666 if (getset_dma == IS_SET) {
1667 print_flag_on_off(getset_dma, "using_dma", dma);
1668 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1670 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1671 #ifdef HDIO_SET_QDMA
1672 if (getset_dma_q == IS_SET) {
1673 print_flag_on_off(getset_dma_q, "DMA queue_depth", dma_q);
1674 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1677 if (getset_nowerr == IS_SET) {
1678 print_flag_on_off(getset_nowerr, "nowerr", nowerr);
1679 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1681 if (getset_keep == IS_SET) {
1682 print_flag_on_off(getset_keep, "keep_settings", keep);
1683 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1685 #ifdef HDIO_DRIVE_CMD
1686 if (getset_doorlock == IS_SET) {
1687 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1689 print_flag_on_off(getset_doorlock, "drive doorlock", doorlock);
1690 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1691 args[0] = WIN_SETFEATURES;
1693 if (getset_dkeep == IS_SET) {
1694 /* lock/unlock the drive's "feature" settings */
1695 print_flag_on_off(getset_dkeep, "drive keep features", dkeep);
1696 args[2] = dkeep ? 0x66 : 0xcc;
1697 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1699 if (getset_defects == IS_SET) {
1700 args[2] = defects ? 0x04 : 0x84;
1701 print_flag(getset_defects, "drive defect-mgmt", defects);
1702 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1704 if (getset_prefetch == IS_SET) {
1707 print_flag(getset_prefetch, "drive prefetch", prefetch);
1708 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1712 args[1] = xfermode_requested;
1714 print_flag(1, "xfermode", xfermode_requested);
1715 interpret_xfermode(xfermode_requested);
1716 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1719 if (getset_lookahead == IS_SET) {
1720 args[2] = lookahead ? 0xaa : 0x55;
1721 print_flag_on_off(getset_lookahead, "drive read-lookahead", lookahead);
1722 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1724 if (getset_apmmode == IS_SET) {
1725 /* feature register */
1726 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */;
1727 args[1] = apmmode; /* sector count register 1-255 */
1728 printf(" setting APM level to %s 0x%02lX (%ld)\n",
1729 (apmmode == 255) ? "disabled" : "",
1731 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1734 if (getset_wcache == IS_SET) {
1735 #ifdef DO_FLUSHCACHE
1736 #ifndef WIN_FLUSHCACHE
1737 #define WIN_FLUSHCACHE 0xe7
1739 #endif /* DO_FLUSHCACHE */
1740 args[2] = wcache ? 0x02 : 0x82;
1741 print_flag_on_off(getset_wcache, "drive write-caching", wcache);
1742 #ifdef DO_FLUSHCACHE
1744 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1745 #endif /* DO_FLUSHCACHE */
1746 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1747 #ifdef DO_FLUSHCACHE
1749 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1750 #endif /* DO_FLUSHCACHE */
1753 /* In code below, we do not preserve args[0], but the rest
1754 is preserved, including args[2] */
1757 if (set_standbynow) {
1758 #ifndef WIN_STANDBYNOW1
1759 #define WIN_STANDBYNOW1 0xE0
1761 #ifndef WIN_STANDBYNOW2
1762 #define WIN_STANDBYNOW2 0x94
1764 puts(" issuing standby command");
1765 args[0] = WIN_STANDBYNOW1;
1766 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1769 #ifndef WIN_SLEEPNOW1
1770 #define WIN_SLEEPNOW1 0xE6
1772 #ifndef WIN_SLEEPNOW2
1773 #define WIN_SLEEPNOW2 0x99
1775 puts(" issuing sleep command");
1776 args[0] = WIN_SLEEPNOW1;
1777 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1781 puts(" disabling Seagate auto powersaving mode");
1782 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1784 if (getset_standby == IS_SET) {
1785 args[0] = WIN_SETIDLE1;
1786 args[1] = standby_requested;
1787 print_flag(1, "standby", standby_requested);
1788 interpret_standby(standby_requested);
1789 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1792 #else /* HDIO_DRIVE_CMD */
1793 if (force_operation) {
1795 flush_buffer_cache();
1796 if (-1 == read(fd, buf, sizeof(buf)))
1797 bb_perror_msg("read of 512 bytes failed");
1799 #endif /* HDIO_DRIVE_CMD */
1800 if (getset_mult || get_identity) {
1802 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1803 /* To be coherent with ioctl_or_warn. */
1804 if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1805 bb_perror_msg("HDIO_GET_MULTCOUNT");
1807 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1808 } else if (getset_mult) {
1809 printf(fmt, "multcount", multcount);
1810 on_off(multcount != 0);
1813 if (getset_io32bit) {
1814 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1815 printf(" IO_support\t=%3ld (", parm);
1817 puts("default 16-bit)");
1823 puts("32-bit w/sync)");
1825 puts("Request-Queue-Bypass)");
1830 if (getset_unmask) {
1831 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
1832 print_value_on_off("unmaskirq", parm);
1834 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1836 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1837 printf(fmt, "using_dma", parm);
1839 puts(" (DMA-Assisted-PIO)");
1845 #ifdef HDIO_GET_QDMA
1847 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
1848 print_value_on_off("queue_depth", parm);
1852 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
1853 print_value_on_off("keepsettings", parm);
1855 if (getset_nowerr) {
1856 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
1857 print_value_on_off("nowerr", parm);
1859 if (getset_readonly) {
1860 if (!ioctl_or_warn(fd, BLKROGET, &parm))
1861 print_value_on_off("readonly", parm);
1863 if (getset_readahead) {
1864 if (!ioctl_or_warn(fd, BLKRAGET, &parm))
1865 print_value_on_off("readahead", parm);
1868 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1869 struct hd_geometry g;
1871 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1872 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1873 g.cylinders, g.heads, g.sectors, parm, g.start);
1876 #ifdef HDIO_DRIVE_CMD
1877 if (get_powermode) {
1878 #ifndef WIN_CHECKPOWERMODE1
1879 #define WIN_CHECKPOWERMODE1 0xE5
1881 #ifndef WIN_CHECKPOWERMODE2
1882 #define WIN_CHECKPOWERMODE2 0x98
1886 args[0] = WIN_CHECKPOWERMODE1;
1887 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1888 if (errno != EIO || args[0] != 0 || args[1] != 0)
1893 state = (args[2] == 255) ? "active/idle" : "standby";
1894 args[1] = args[2] = 0;
1896 printf(" drive state is: %s\n", state);
1899 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1900 if (perform_reset) {
1901 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1903 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1904 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1905 if (perform_tristate) {
1908 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1910 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1911 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1913 struct hd_driveid id;
1915 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1916 if (multcount != -1) {
1917 id.multsect = multcount;
1918 id.multsect_valid |= 1;
1920 id.multsect_valid &= ~1;
1922 } else if (errno == -ENOMSG)
1923 puts(" no identification info available");
1924 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1925 bb_perror_msg("HDIO_GET_IDENTITY");
1927 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1931 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1933 memset(args1, 0, sizeof(args1));
1934 args1[0] = WIN_IDENTIFY;
1936 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1937 identify((void *)(args1 + 4));
1940 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1941 if (getset_busstate == IS_SET) {
1942 print_flag(1, "bus state", busstate);
1943 bus_state_value(busstate);
1944 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1946 if (getset_busstate) {
1947 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1948 printf(fmt, "bus state", parm);
1949 bus_state_value(parm);
1954 ioctl_or_warn(fd, BLKRRPART, NULL);
1957 do_time(1 /*,fd*/); /* time cache */
1959 do_time(0 /*,fd*/); /* time device */
1961 flush_buffer_cache();
1965 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1966 static int fromhex(unsigned char c)
1970 if (c >= 'a' && c <= 'f')
1971 return (c - ('a' - 10));
1972 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1975 static void identify_from_stdin(void) NORETURN;
1976 static void identify_from_stdin(void)
1979 unsigned char buf[1280];
1980 unsigned char *b = (unsigned char *)buf;
1983 xread(STDIN_FILENO, buf, 1280);
1985 // Convert the newline-separated hex data into an identify block.
1987 for (i = 0; i < 256; i++) {
1989 for (j = 0; j < 4; j++)
1990 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1998 void identify_from_stdin(void);
2001 /* busybox specific stuff */
2002 static int parse_opts(unsigned long *value, int min, int max)
2005 *value = xatol_range(optarg, min, max);
2010 static int parse_opts_0_max(unsigned long *value, int max)
2012 return parse_opts(value, 0, max);
2014 static int parse_opts_0_1(unsigned long *value)
2016 return parse_opts(value, 0, 1);
2018 static int parse_opts_0_INTMAX(unsigned long *value)
2020 return parse_opts(value, 0, INT_MAX);
2023 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
2028 *value = translate_xfermode(optarg);
2029 *set = (*value > -1);
2034 /*------- getopt short options --------*/
2035 static const char hdparm_options[] ALIGN1 =
2036 "gfu::n::p:r::m::c::k::a::B:tT"
2037 IF_FEATURE_HDPARM_GET_IDENTITY("iI")
2038 IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
2039 #ifdef HDIO_DRIVE_CMD
2040 "S:D:P:X:K:A:L:W:CyYzZ"
2042 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
2043 #ifdef HDIO_GET_QDMA
2044 #ifdef HDIO_SET_QDMA
2050 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
2051 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
2052 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
2053 /*-------------------------------------*/
2055 /* our main() routine: */
2056 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2057 int hdparm_main(int argc, char **argv)
2064 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2066 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2067 IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2068 get_geom |= (c == 'g');
2069 do_flush |= (c == 'f');
2070 if (c == 'u') getset_unmask = parse_opts_0_1(&unmask);
2071 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
2072 if (c == 'd') getset_dma = parse_opts_0_max(&dma, 9);
2074 if (c == 'n') getset_nowerr = parse_opts_0_1(&nowerr);
2075 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2076 if (c == 'r') getset_readonly = parse_opts_0_1(&readonly);
2077 if (c == 'm') getset_mult = parse_opts_0_INTMAX(&mult /*32*/);
2078 if (c == 'c') getset_io32bit = parse_opts_0_INTMAX(&io32bit /*8*/);
2079 if (c == 'k') getset_keep = parse_opts_0_1(&keep);
2080 if (c == 'a') getset_readahead = parse_opts_0_INTMAX(&Xreadahead);
2081 if (c == 'B') getset_apmmode = parse_opts(&apmmode, 1, 255);
2082 do_flush |= do_timings |= (c == 't');
2083 do_flush |= do_ctimings |= (c == 'T');
2084 #ifdef HDIO_DRIVE_CMD
2085 if (c == 'S') getset_standby = parse_opts_0_max(&standby_requested, 255);
2086 if (c == 'D') getset_defects = parse_opts_0_INTMAX(&defects);
2087 if (c == 'P') getset_prefetch = parse_opts_0_INTMAX(&prefetch);
2088 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2089 if (c == 'K') getset_dkeep = parse_opts_0_1(&prefetch);
2090 if (c == 'A') getset_lookahead = parse_opts_0_1(&lookahead);
2091 if (c == 'L') getset_doorlock = parse_opts_0_1(&doorlock);
2092 if (c == 'W') getset_wcache = parse_opts_0_1(&wcache);
2093 get_powermode |= (c == 'C');
2094 set_standbynow |= (c == 'y');
2095 set_sleepnow |= (c == 'Y');
2096 reread_partn |= (c == 'z');
2097 set_seagate |= (c == 'Z');
2099 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') unregister_hwif = parse_opts_0_INTMAX(&hwif));
2100 #ifdef HDIO_GET_QDMA
2102 getset_dma_q = parse_opts_0_INTMAX(&dma_q);
2105 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2106 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') perform_tristate = parse_opts_0_1(&tristate));
2107 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') getset_busstate = parse_opts_0_max(&busstate, 2));
2108 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2110 scan_hwif = parse_opts_0_INTMAX(&hwif_data);
2111 hwif_ctrl = xatoi_positive((argv[optind]) ? argv[optind] : "");
2112 hwif_irq = xatoi_positive((argv[optind+1]) ? argv[optind+1] : "");
2113 /* Move past the 2 additional arguments */
2119 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2121 getset_mult = getset_io32bit = getset_unmask = getset_keep = getset_readonly = getset_readahead = get_geom = IS_GET;
2122 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(getset_dma = IS_GET);
2127 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2128 identify_from_stdin(); /* EXIT */
2133 process_dev(*argv++);
2136 return EXIT_SUCCESS;