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 the GPL v2 or later, see the file LICENSE in this tarball.
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 /* must be _after_ libbb.h: */
16 #include <linux/hdreg.h>
17 #include <sys/mount.h>
18 #if !defined(BLKGETSIZE64)
19 # define BLKGETSIZE64 _IOR(0x12,114,size_t)
25 #define ATA_DEV 0x0000
26 #define ATAPI_DEV 0x0001
28 /* word definitions */
29 /* ---------------- */
30 #define GEN_CONFIG 0 /* general configuration */
31 #define LCYLS 1 /* number of logical cylinders */
32 #define CONFIG 2 /* specific configuration */
33 #define LHEADS 3 /* number of logical heads */
34 #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
35 #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
36 #define LSECTS 6 /* number of logical sectors/track */
37 #define START_SERIAL 10 /* ASCII serial number */
38 #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
39 #define BUF_TYPE 20 /* buffer type (ATA-1) */
40 #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
41 #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
42 #define START_FW_REV 23 /* ASCII firmware revision */
43 #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
44 #define START_MODEL 27 /* ASCII model number */
45 #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
46 #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
47 #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
48 #define CAPAB_0 49 /* capabilities */
50 #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
51 #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
52 #define WHATS_VALID 53 /* what fields are valid */
53 #define LCYLS_CUR 54 /* current logical cylinders */
54 #define LHEADS_CUR 55 /* current logical heads */
55 #define LSECTS_CUR 56 /* current logical sectors/track */
56 #define CAPACITY_LSB 57 /* current capacity in sectors */
57 #define CAPACITY_MSB 58
58 #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
59 #define LBA_SECTS_LSB 60 /* LBA: total number of user */
60 #define LBA_SECTS_MSB 61 /* addressable sectors */
61 #define SINGLE_DMA 62 /* singleword DMA modes */
62 #define MULTI_DMA 63 /* multiword DMA modes */
63 #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
64 /* multiword DMA xfer cycle time: */
65 #define DMA_TIME_MIN 65 /* - minimum */
66 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
67 /* minimum PIO xfer cycle time: */
68 #define PIO_NO_FLOW 67 /* - without flow control */
69 #define PIO_FLOW 68 /* - with IORDY flow control */
70 #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
71 #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
72 #define CDR_MAJOR 73 /* CD ROM: major version number */
73 #define CDR_MINOR 74 /* CD ROM: minor version number */
74 #define QUEUE_DEPTH 75 /* queue depth */
75 #define MAJOR 80 /* major version number */
76 #define MINOR 81 /* minor version number */
77 #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
78 #define CMDS_SUPP_1 83
79 #define CMDS_SUPP_2 84
80 #define CMDS_EN_0 85 /* command/feature set(s) enabled */
83 #define ULTRA_DMA 88 /* ultra DMA modes */
84 /* time to complete security erase */
85 #define ERASE_TIME 89 /* - ordinary */
86 #define ENH_ERASE_TIME 90 /* - enhanced */
87 #define ADV_PWR 91 /* current advanced power management level
88 in low byte, 0x40 in high byte. */
89 #define PSWD_CODE 92 /* master password revision code */
90 #define HWRST_RSLT 93 /* hardware reset result */
91 #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
92 #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
93 #define LBA_MID 101 /* bits are used, but addr 103 */
94 #define LBA_48_MSB 102 /* has been reserved for LBA in */
95 #define LBA_64_MSB 103 /* the future. */
96 #define RM_STAT 127 /* removable media status notification feature set support */
97 #define SECU_STATUS 128 /* security status */
98 #define CFA_PWR_MODE 160 /* CFA power mode 1 */
99 #define START_MEDIA 176 /* media serial number */
100 #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
101 #define START_MANUF 196 /* media manufacturer I.D. */
102 #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
103 #define INTEGRITY 255 /* integrity word */
105 /* bit definitions within the words */
106 /* -------------------------------- */
108 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
110 #define VALID_VAL 0x4000
111 /* many words are considered invalid if they are either all-0 or all-1 */
112 #define NOVAL_0 0x0000
113 #define NOVAL_1 0xffff
115 /* word 0: gen_config */
116 #define NOT_ATA 0x8000
117 #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
118 #define MEDIA_REMOVABLE 0x0080
119 #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
120 #define INCOMPLETE 0x0004
121 #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
122 #define DRQ_RESPONSE_TIME 0x0060
123 #define DRQ_3MS_VAL 0x0000
124 #define DRQ_INTR_VAL 0x0020
125 #define DRQ_50US_VAL 0x0040
126 #define PKT_SIZE_SUPPORTED 0x0003
127 #define PKT_SIZE_12_VAL 0x0000
128 #define PKT_SIZE_16_VAL 0x0001
129 #define EQPT_TYPE 0x1f00
134 /* word 1: number of logical cylinders */
135 #define LCYLS_MAX 0x3fff /* maximum allowable value */
137 /* word 2: specific configuration
138 * (a) require SET FEATURES to spin-up
139 * (b) require spin-up to fully reply to IDENTIFY DEVICE
141 #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
142 #define STBY_ID_VAL 0x738c /* (a) and not (b) */
143 #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
144 #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
146 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
147 #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
148 #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
150 /* word 49: capabilities 0 */
151 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
152 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
153 #define IORDY_OFF 0x0400 /* 1=may be disabled */
154 #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
155 #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
156 #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
157 #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
158 #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
159 #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
161 /* word 50: capabilities 1 */
162 #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
164 /* words 51 & 52: PIO & DMA cycle times */
165 #define MODE 0xff00 /* the mode is in the MSBs */
167 /* word 53: whats_valid */
168 #define OK_W88 0x0004 /* the ultra_dma info is valid */
169 #define OK_W64_70 0x0002 /* see above for word descriptions */
170 #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
172 /*word 63,88: dma_mode, ultra_dma_mode*/
173 #define MODE_MAX 7 /* bit definitions force udma <=7 (when
174 * udma >=8 comes out it'll have to be
175 * defined in a new dma_mode word!) */
177 /* word 64: PIO transfer modes */
178 #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
179 #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
181 /* word 75: queue_depth */
182 #define DEPTH_BITS 0x001f /* bits used for queue depth */
184 /* words 80-81: version numbers */
185 /* NOVAL_0 or NOVAL_1 means device does not report version */
187 /* word 81: minor version number */
188 #define MINOR_MAX 0x22
189 /* words 82-84: cmds/feats supported */
190 #define CMDS_W82 0x77ff /* word 82: defined command locations*/
191 #define CMDS_W83 0x3fff /* word 83: defined command locations*/
192 #define CMDS_W84 0x002f /* word 83: defined command locations*/
193 #define SUPPORT_48_BIT 0x0400
194 #define NUM_CMD_FEAT_STR 48
196 /* words 85-87: cmds/feats enabled */
197 /* use cmd_feat_str[] to display what commands and features have
198 * been enabled with words 85-87
201 /* words 89, 90, SECU ERASE TIME */
202 #define ERASE_BITS 0x00ff
204 /* word 92: master password revision */
205 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
207 /* word 93: hw reset result */
208 #define CBLID 0x2000 /* CBLID status */
209 #define RST0 0x0001 /* 1=reset to device #0 */
210 #define DEV_DET 0x0006 /* how device num determined */
211 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
212 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
214 /* word 127: removable media status notification feature set support */
215 #define RM_STAT_BITS 0x0003
216 #define RM_STAT_SUP 0x0001
218 /* word 128: security */
219 #define SECU_ENABLED 0x0002
220 #define SECU_LEVEL 0x0010
221 #define NUM_SECU_STR 6
223 /* word 160: CFA power mode */
224 #define VALID_W160 0x8000 /* 1=word valid */
225 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
226 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
227 #define MAX_AMPS 0x0fff /* value = max current in ma */
229 /* word 255: integrity */
230 #define SIG 0x00ff /* signature location */
231 #define SIG_VAL 0x00a5 /* signature value */
233 #define TIMING_BUF_MB 1
234 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
236 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
247 smallint get_identity, get_geom;
249 smallint do_ctimings, do_timings;
250 smallint reread_partn;
251 smallint set_piomode, noisy_piomode;
252 smallint getset_readahead;
253 smallint getset_readonly;
254 smallint getset_unmask;
255 smallint getset_mult;
257 smallint getset_dma_q;
259 smallint getset_nowerr;
260 smallint getset_keep;
261 smallint getset_io32bit;
263 unsigned long Xreadahead;
264 unsigned long readonly;
265 unsigned long unmask;
270 unsigned long nowerr;
272 unsigned long io32bit;
273 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
277 #ifdef HDIO_DRIVE_CMD
278 smallint set_xfermode, get_xfermode;
279 smallint getset_dkeep;
280 smallint getset_standby;
281 smallint getset_lookahead;
282 smallint getset_prefetch;
283 smallint getset_defects;
284 smallint getset_wcache;
285 smallint getset_doorlock;
286 smallint set_seagate;
287 smallint set_standbynow;
288 smallint set_sleepnow;
289 smallint get_powermode;
290 smallint getset_apmmode;
291 int xfermode_requested;
293 unsigned long standby_requested; /* 0..255 */
294 unsigned long lookahead;
295 unsigned long prefetch;
296 unsigned long defects;
297 unsigned long wcache;
298 unsigned long doorlock;
299 unsigned long apmmode;
301 IF_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
302 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint getset_busstate;)
303 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
304 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
305 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
306 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
307 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
308 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
309 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
310 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
311 unsigned long hwif_data;
312 unsigned long hwif_ctrl;
313 unsigned long hwif_irq;
316 unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
319 #define G (*(struct globals*)&bb_common_bufsiz1)
320 struct BUG_G_too_big {
321 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
323 #define get_identity (G.get_identity )
324 #define get_geom (G.get_geom )
325 #define do_flush (G.do_flush )
326 #define do_ctimings (G.do_ctimings )
327 #define do_timings (G.do_timings )
328 #define reread_partn (G.reread_partn )
329 #define set_piomode (G.set_piomode )
330 #define noisy_piomode (G.noisy_piomode )
331 #define getset_readahead (G.getset_readahead )
332 #define getset_readonly (G.getset_readonly )
333 #define getset_unmask (G.getset_unmask )
334 #define getset_mult (G.getset_mult )
335 #define getset_dma_q (G.getset_dma_q )
336 #define getset_nowerr (G.getset_nowerr )
337 #define getset_keep (G.getset_keep )
338 #define getset_io32bit (G.getset_io32bit )
339 #define piomode (G.piomode )
340 #define Xreadahead (G.Xreadahead )
341 #define readonly (G.readonly )
342 #define unmask (G.unmask )
343 #define mult (G.mult )
344 #define dma_q (G.dma_q )
345 #define nowerr (G.nowerr )
346 #define keep (G.keep )
347 #define io32bit (G.io32bit )
349 #define getset_dma (G.getset_dma )
350 #define set_xfermode (G.set_xfermode )
351 #define get_xfermode (G.get_xfermode )
352 #define getset_dkeep (G.getset_dkeep )
353 #define getset_standby (G.getset_standby )
354 #define getset_lookahead (G.getset_lookahead )
355 #define getset_prefetch (G.getset_prefetch )
356 #define getset_defects (G.getset_defects )
357 #define getset_wcache (G.getset_wcache )
358 #define getset_doorlock (G.getset_doorlock )
359 #define set_seagate (G.set_seagate )
360 #define set_standbynow (G.set_standbynow )
361 #define set_sleepnow (G.set_sleepnow )
362 #define get_powermode (G.get_powermode )
363 #define getset_apmmode (G.getset_apmmode )
364 #define xfermode_requested (G.xfermode_requested )
365 #define dkeep (G.dkeep )
366 #define standby_requested (G.standby_requested )
367 #define lookahead (G.lookahead )
368 #define prefetch (G.prefetch )
369 #define defects (G.defects )
370 #define wcache (G.wcache )
371 #define doorlock (G.doorlock )
372 #define apmmode (G.apmmode )
373 #define get_IDentity (G.get_IDentity )
374 #define getset_busstate (G.getset_busstate )
375 #define perform_reset (G.perform_reset )
376 #define perform_tristate (G.perform_tristate )
377 #define unregister_hwif (G.unregister_hwif )
378 #define scan_hwif (G.scan_hwif )
379 #define busstate (G.busstate )
380 #define tristate (G.tristate )
381 #define hwif (G.hwif )
382 #define hwif_data (G.hwif_data )
383 #define hwif_ctrl (G.hwif_ctrl )
384 #define hwif_irq (G.hwif_irq )
387 /* Busybox messages and functions */
388 #if ENABLE_IOCTL_HEX2STR_ERROR
389 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
391 if (!ioctl(fd, cmd, args))
394 return bb_ioctl_or_warn(fd, cmd, args, string);
396 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
398 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
400 if (!ioctl(fd, cmd, args))
403 return bb_ioctl_or_warn(fd, cmd, args);
405 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
408 static void on_off(int value)
410 puts(value ? " (on)" : " (off)");
413 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
416 printf(" setting %s to %ld", s, arg);
421 static void print_value_on_off(const char *str, unsigned long argp)
423 printf(" %s\t= %2ld", str, argp);
427 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
428 static void print_ascii(const char *p, int length)
435 /* every 16bit word is big-endian (i.e. inverted) */
436 /* accessing bytes in 1,0, 3,2, 5,4... sequence */
441 /* find first non-space & print it */
442 while (length && p[ofs] != ' ') {
447 while (length && p[ofs]) {
457 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
460 printf("\t%-20s", string);
461 print_ascii((void*)&val[i], n);
465 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
470 for (ii = 0; ii <= MODE_MAX; ii++) {
471 if (mode_sel & 0x0001) {
472 printf("*%cdma%u ", cc, ii);
476 } else if (mode_sup & 0x0001)
477 printf("%cdma%u ", cc, ii);
485 static const char pkt_str[] ALIGN1 =
486 "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
487 "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
488 "Printer" "\0" /* word 0, bits 12-8 = 02 */
489 "Processor" "\0" /* word 0, bits 12-8 = 03 */
490 "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
491 "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
492 "Scanner" "\0" /* word 0, bits 12-8 = 06 */
493 "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
494 "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
495 "Communications device" "\0" /* word 0, bits 12-8 = 09 */
496 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
497 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
498 "Array controller" "\0" /* word 0, bits 12-8 = 0c */
499 "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
500 "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
501 "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
504 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
505 "reserved" "\0" /* bit 0 */
506 "hard sectored" "\0" /* bit 1 */
507 "soft sectored" "\0" /* bit 2 */
508 "not MFM encoded " "\0" /* bit 3 */
509 "head switch time > 15us" "\0" /* bit 4 */
510 "spindle motor control option" "\0" /* bit 5 */
511 "fixed drive" "\0" /* bit 6 */
512 "removable drive" "\0" /* bit 7 */
513 "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
514 "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
515 "disk xfer rate > 5Mbs" "\0" /* bit 10 */
516 "rotational speed tol." "\0" /* bit 11 */
517 "data strobe offset option" "\0" /* bit 12 */
518 "track offset option" "\0" /* bit 13 */
519 "format speed tolerance gap reqd" "\0" /* bit 14 */
523 static const char minor_str[] ALIGN1 =
525 "Unspecified" "\0" /* 0x0000 */
526 "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
527 "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
528 "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
529 "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
530 "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
531 "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
532 "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
533 "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
534 "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
535 "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
536 "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
537 "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
538 "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
539 "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
540 "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
541 "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
542 "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
543 "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
544 "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
545 "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
546 "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
547 "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
548 "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
549 "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
550 "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
551 "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
552 "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
553 "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
554 "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
555 "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
556 "reserved" "\0" /* 0x001f */
557 "reserved" "\0" /* 0x0020 */
558 "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
559 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
560 "reserved" /* 0x0023-0xfffe */
562 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
564 0, /* 0x0000 WARNING: actual_ver[] array */
565 1, /* 0x0001 WARNING: corresponds */
566 1, /* 0x0002 WARNING: *exactly* */
567 1, /* 0x0003 WARNING: to the ATA/ */
568 2, /* 0x0004 WARNING: ATAPI version */
569 2, /* 0x0005 WARNING: listed in */
570 3, /* 0x0006 WARNING: the */
571 2, /* 0x0007 WARNING: minor_str */
572 3, /* 0x0008 WARNING: array */
573 2, /* 0x0009 WARNING: above. */
574 3, /* 0x000a WARNING: */
575 3, /* 0x000b WARNING: If you change */
576 3, /* 0x000c WARNING: that one, */
577 4, /* 0x000d WARNING: change this one */
578 4, /* 0x000e WARNING: too!!! */
599 0 /* 0x0023-0xfffe */
602 static const char cmd_feat_str[] ALIGN1 =
603 "" "\0" /* word 82 bit 15: obsolete */
604 "NOP cmd" "\0" /* word 82 bit 14 */
605 "READ BUFFER cmd" "\0" /* word 82 bit 13 */
606 "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
607 "" "\0" /* word 82 bit 11: obsolete */
608 "Host Protected Area feature set" "\0" /* word 82 bit 10 */
609 "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
610 "SERVICE interrupt" "\0" /* word 82 bit 8 */
611 "Release interrupt" "\0" /* word 82 bit 7 */
612 "Look-ahead" "\0" /* word 82 bit 6 */
613 "Write cache" "\0" /* word 82 bit 5 */
614 "PACKET command feature set" "\0" /* word 82 bit 4 */
615 "Power Management feature set" "\0" /* word 82 bit 3 */
616 "Removable Media feature set" "\0" /* word 82 bit 2 */
617 "Security Mode feature set" "\0" /* word 82 bit 1 */
618 "SMART feature set" "\0" /* word 82 bit 0 */
620 "" "\0" /* word 83 bit 15: !valid bit */
621 "" "\0" /* word 83 bit 14: valid bit */
622 "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
623 "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
624 "Device Configuration Overlay feature set " "\0"
625 "48-bit Address feature set " "\0" /* word 83 bit 10 */
627 "SET MAX security extension" "\0" /* word 83 bit 8 */
628 "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
629 "SET FEATURES subcommand required to spinup after power up" "\0"
630 "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
631 "Removable Media Status Notification feature set" "\0"
632 "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
633 "CFA feature set" "\0" /* word 83 bit 2 */
634 "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
635 "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
637 "" "\0" /* word 84 bit 15: !valid bit */
638 "" "\0" /* word 84 bit 14: valid bit */
639 "" "\0" /* word 84 bit 13: reserved */
640 "" "\0" /* word 84 bit 12: reserved */
641 "" "\0" /* word 84 bit 11: reserved */
642 "" "\0" /* word 84 bit 10: reserved */
643 "" "\0" /* word 84 bit 9: reserved */
644 "" "\0" /* word 84 bit 8: reserved */
645 "" "\0" /* word 84 bit 7: reserved */
646 "" "\0" /* word 84 bit 6: reserved */
647 "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
648 "" "\0" /* word 84 bit 4: reserved */
649 "Media Card Pass Through Command feature set " "\0"
650 "Media serial number " "\0" /* word 84 bit 2 */
651 "SMART self-test " "\0" /* word 84 bit 1 */
652 "SMART error logging " /* word 84 bit 0 */
655 static const char secu_str[] ALIGN1 =
656 "supported" "\0" /* word 128, bit 0 */
657 "enabled" "\0" /* word 128, bit 1 */
658 "locked" "\0" /* word 128, bit 2 */
659 "frozen" "\0" /* word 128, bit 3 */
660 "expired: security count" "\0" /* word 128, bit 4 */
661 "supported: enhanced erase" /* word 128, bit 5 */
664 // Parse 512 byte disk identification block and print much crap.
665 static void identify(uint16_t *val) NORETURN;
666 static void identify(uint16_t *val)
669 uint16_t like_std = 1, std = 0, min_std = 0xffff;
670 uint16_t dev = NO_DEV, eqpt = NO_DEV;
671 uint8_t have_mode = 0, err_dma = 0;
673 uint32_t ll, mm, nn, oo;
674 uint64_t bbbig; /* (:) */
679 // Adjust for endianness
680 swab(val, buf, sizeof(buf));
683 /* check if we recognize the device type */
685 if (!(val[GEN_CONFIG] & NOT_ATA)) {
687 printf("ATA device, with ");
688 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
691 printf("CompactFlash ATA device, with ");
692 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
694 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
695 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
698 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
699 bb_error_msg_and_die("unknown device type");
701 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
702 /* Info from the specific configuration word says whether or not the
703 * ID command completed correctly. It is only defined, however in
704 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
705 * standards. Since the values allowed for this word are extremely
706 * specific, it should be safe to check it now, even though we don't
707 * know yet what standard this device is using.
709 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
710 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
713 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
714 printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
715 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
716 printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
719 /* output the model and serial numbers and the fw revision */
720 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
721 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
722 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
723 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
724 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
726 /* major & minor standards version number (Note: these words were not
727 * defined until ATA-3 & the CDROM std uses different words.) */
728 printf("Standards:");
730 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
731 if (like_std < 3) like_std = 3;
732 std = actual_ver[val[MINOR]];
733 if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
736 /* looks like when they up-issue the std, they obsolete one;
737 * thus, only the newest 4 issues need be supported. (That's
738 * what "kk" and "min_std" are all about.) */
739 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
740 printf("\n\tSupported: ");
741 jj = val[MAJOR] << 1;
742 kk = like_std >4 ? like_std-4: 0;
743 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
748 kk = like_std >4 ? like_std-4: 0;
750 if (min_std > ii) min_std = ii;
754 if (like_std < 3) like_std = 3;
756 /* Figure out what standard the device is using if it hasn't told
757 * us. If we know the std, check if the device is using any of
758 * the words from the next level up. It happens.
760 if (like_std < std) like_std = std;
762 if (((std == 5) || (!std && (like_std < 6))) &&
763 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
764 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
765 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
766 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
769 } else if (((std == 4) || (!std && (like_std < 5))) &&
770 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
771 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
772 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
773 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
776 } else if (((std == 3) || (!std && (like_std < 4))) &&
777 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
778 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
779 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
780 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
781 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
782 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
785 } else if (((std == 2) || (!std && (like_std < 3)))
786 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
789 } else if (((std == 1) || (!std && (like_std < 2))) &&
790 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
791 (val[WHATS_VALID] & OK_W64_70)) )
797 printf("\n\tLikely used: %u\n", like_std);
798 else if (like_std > std)
799 printf("& some of %u\n", like_std);
803 /* TBD: do CDROM stuff more thoroughly. For now... */
805 if (val[CDR_MINOR] == 9) {
807 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
809 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
811 printf("\n\tSupported: CD-ROM ATAPI");
812 jj = val[CDR_MAJOR] >> 1;
813 for (ii = 1; ii < 15; ii++) {
814 if (jj & 0x0001) printf("-%u ", ii);
818 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
819 /* the cdrom stuff is more like ATA-2 than anything else, so: */
823 if (min_std == 0xffff)
824 min_std = like_std > 4 ? like_std - 3 : 1;
826 printf("Configuration:\n");
827 /* more info from the general configuration word */
828 if ((eqpt != CDROM) && (like_std == 1)) {
829 jj = val[GEN_CONFIG] >> 1;
830 for (ii = 1; ii < 15; ii++) {
832 printf("\t%s\n", nth_string(ata1_cfg_str, ii));
836 if (dev == ATAPI_DEV) {
837 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
839 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
840 strng = "<=10ms with INTRQ";
841 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
845 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
847 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
849 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
855 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
856 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
859 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
860 printf("\tCHS addressing not supported\n");
862 jj = val[WHATS_VALID] & OK_W54_58;
863 printf("\tLogical\t\tmax\tcurrent\n"
864 "\tcylinders\t%u\t%u\n"
865 "\theads\t\t%u\t%u\n"
866 "\tsectors/track\t%u\t%u\n"
869 jj ? val[LCYLS_CUR] : 0,
871 jj ? val[LHEADS_CUR] : 0,
873 jj ? val[LSECTS_CUR] : 0);
875 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
876 printf("\tbytes/track: %u\tbytes/sector: %u\n",
877 val[TRACK_BYTES], val[SECT_BYTES]);
880 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
882 /* check Endian of capacity bytes */
883 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
884 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
885 if (abs(mm - nn) > abs(oo - nn))
888 printf("\tCHS current addressable sectors:%11u\n", mm);
892 printf("\tLBA user addressable sectors:%11u\n", ll);
893 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
894 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
896 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
897 (uint64_t)val[LBA_48_MSB] << 32 |
898 (uint64_t)val[LBA_MID] << 16 |
900 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
904 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
905 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
906 bbbig = (bbbig << 9) / 1000000;
907 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
910 printf("(%"PRIu64" GB)\n", bbbig/1000);
915 /* hw support of commands (capabilities) */
916 printf("Capabilities:\n\t");
918 if (dev == ATAPI_DEV) {
919 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP))
920 printf("Cmd queuing, ");
921 if (val[CAPAB_0] & OVLP_SUP)
922 printf("Cmd overlap, ");
924 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
927 printf("IORDY%s(can%s be disabled)\n",
928 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
929 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
931 printf("no IORDY\n");
933 if ((like_std == 1) && val[BUF_TYPE]) {
934 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
935 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
936 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
939 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
940 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
942 if ((min_std < 4) && (val[RW_LONG])) {
943 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
945 if ((eqpt != CDROM) && (like_std > 3)) {
946 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
949 if (dev == ATA_DEV) {
951 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
953 printf("\tStandby timer values: spec'd by %s",
954 (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor");
955 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
956 printf(", %s device specific minimum\n",
957 (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
961 printf("\tR/W multiple sector transfer: ");
962 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
963 printf("not supported\n");
965 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
966 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
967 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
971 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
972 /* We print out elsewhere whether the APM feature is enabled or
973 not. If it's not enabled, let's not repeat the info; just print
975 printf("\tAdvancedPM level: ");
976 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
977 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
978 printf("%u (0x%x)\n", apm_level, apm_level);
981 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
983 if (like_std > 5 && val[ACOUSTIC]) {
984 printf("\tRecommended acoustic management value: %u, current value: %u\n",
985 (val[ACOUSTIC] >> 8) & 0x00ff,
986 val[ACOUSTIC] & 0x00ff);
990 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
991 printf("\tATA sw reset required\n");
993 if (val[PKT_REL] || val[SVC_NBSY]) {
994 printf("\tOverlap support:");
996 printf(" %uus to release bus.", val[PKT_REL]);
998 printf(" %uus to clear BSY after SERVICE cmd.",
1004 /* DMA stuff. Check that only one DMA mode is selected. */
1006 if (!(val[CAPAB_0] & DMA_SUP))
1007 printf("not supported\n");
1009 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1010 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1011 if (val[SINGLE_DMA]) {
1012 jj = val[SINGLE_DMA];
1013 kk = val[SINGLE_DMA] >> 8;
1014 err_dma += mode_loop(jj, kk, 's', &have_mode);
1016 if (val[MULTI_DMA]) {
1017 jj = val[MULTI_DMA];
1018 kk = val[MULTI_DMA] >> 8;
1019 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1021 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1022 jj = val[ULTRA_DMA];
1023 kk = val[ULTRA_DMA] >> 8;
1024 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1026 if (err_dma || !have_mode) printf("(?)");
1029 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1030 printf("\t\tInterleaved DMA support\n");
1032 if ((val[WHATS_VALID] & OK_W64_70)
1033 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1035 printf("\t\tCycle time:");
1036 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1037 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1042 /* Programmed IO stuff */
1044 /* If a drive supports mode n (e.g. 3), it also supports all modes less
1045 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1046 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1047 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1048 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1049 if (jj & 0x0001) printf("pio%d ", ii);
1053 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1054 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1055 printf("pio%d ", ii);
1060 if (val[WHATS_VALID] & OK_W64_70) {
1061 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1062 printf("\t\tCycle time:");
1063 if (val[PIO_NO_FLOW])
1064 printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1066 printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1071 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1072 printf("Commands/features:\n"
1073 "\tEnabled\tSupported:\n");
1074 jj = val[CMDS_SUPP_0];
1075 kk = val[CMDS_EN_0];
1076 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1077 const char *feat_str = nth_string(cmd_feat_str, ii);
1078 if ((jj & 0x8000) && (*feat_str != '\0')) {
1079 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
1083 if (ii % 16 == 15) {
1084 jj = val[CMDS_SUPP_0+1+(ii/16)];
1085 kk = val[CMDS_EN_0+1+(ii/16)];
1088 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1093 /* Removable Media Status Notification feature set */
1094 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1095 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1098 if ((eqpt != CDROM) && (like_std > 3)
1099 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1101 printf("Security:\n");
1102 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1103 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1104 jj = val[SECU_STATUS];
1106 for (ii = 0; ii < NUM_SECU_STR; ii++) {
1107 printf("\t%s\t%s\n",
1108 (!(jj & 0x0001)) ? "not" : "",
1109 nth_string(secu_str, ii));
1112 if (val[SECU_STATUS] & SECU_ENABLED) {
1113 printf("\tSecurity level %s\n",
1114 (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1117 jj = val[ERASE_TIME] & ERASE_BITS;
1118 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1121 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1122 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1128 jj = val[HWRST_RSLT];
1129 if ((jj & VALID) == VALID_VAL) {
1133 if ((jj & DEV_DET) == JUMPER_VAL)
1134 strng = " determined by the jumper";
1135 else if ((jj & DEV_DET) == CSEL_VAL)
1136 strng = " determined by CSEL";
1139 printf("HW reset results:\n"
1141 "\tDevice num = %i%s\n",
1142 (val[HWRST_RSLT] & CBLID) ? "above" : "below",
1146 /* more stuff from std 5 */
1147 if ((like_std > 4) && (eqpt != CDROM)) {
1148 if (val[CFA_PWR_MODE] & VALID_W160) {
1149 printf("CFA power mode 1:\n"
1151 (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1152 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1153 if (val[CFA_PWR_MODE] & MAX_AMPS)
1154 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1156 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1157 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1165 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1166 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1167 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1168 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1169 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1170 // (which they should, but they should just return -EINVAL).
1172 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1173 // On a really old system, it will not, and we will be confused.
1176 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1177 static const char cfg_str[] ALIGN1 =
1178 """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
1179 "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
1180 "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1181 "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
1184 static const char BuffType[] ALIGN1 =
1185 "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
1188 static NOINLINE void dump_identity(const struct hd_driveid *id)
1191 const unsigned short *id_regs = (const void*) id;
1193 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1194 id->model, id->fw_rev, id->serial_no);
1195 for (i = 0; i <= 15; i++) {
1196 if (id->config & (1<<i))
1197 printf(" %s", nth_string(cfg_str, i));
1199 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1200 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1201 id->cyls, id->heads, id->sectors, id->track_bytes,
1202 id->sector_bytes, id->ecc_bytes,
1204 nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1205 id->buf_size/2, id->max_multsect);
1206 if (id->max_multsect) {
1207 printf(", MultSect=");
1208 if (!(id->multsect_valid & 1))
1209 printf("?%u?", id->multsect);
1210 else if (id->multsect)
1211 printf("%u", id->multsect);
1217 if (!(id->field_valid & 1))
1218 printf(" (maybe):");
1220 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1223 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1224 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1225 ((id->capability&2) == 0) ? "no" : "yes");
1227 if (id->capability & 2)
1228 printf(", LBAsects=%u", id->lba_capacity);
1230 printf("\n IORDY=%s",
1231 (id->capability & 8)
1232 ? ((id->capability & 4) ? "on/off" : "yes")
1235 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1236 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1238 if ((id->capability & 1) && (id->field_valid & 2))
1239 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1241 printf("\n PIO modes: ");
1242 if (id->tPIO <= 5) {
1244 if (id->tPIO >= 1) printf("pio1 ");
1245 if (id->tPIO >= 2) printf("pio2 ");
1247 if (id->field_valid & 2) {
1248 static const masks_labels_t pio_modes = {
1249 .masks = { 1, 2, ~3 },
1250 .labels = "pio3 \0""pio4 \0""pio? \0",
1252 print_flags(&pio_modes, id->eide_pio_modes);
1254 if (id->capability & 1) {
1255 if (id->dma_1word | id->dma_mword) {
1256 static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
1257 printf("\n DMA modes: ");
1258 print_flags_separated(dma_wmode_masks,
1259 "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
1260 id->dma_1word, NULL);
1261 print_flags_separated(dma_wmode_masks,
1262 "*\0""mdma0 \0""*\0""mdma1 \0""*\0""mdma2 \0""*\0""mdma? \0",
1263 id->dma_mword, NULL);
1266 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1267 static const masks_labels_t ultra_modes1 = {
1268 .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
1269 .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
1272 printf("\n UDMA modes: ");
1273 print_flags(&ultra_modes1, id->dma_ultra);
1274 #ifdef __NEW_HD_DRIVE_ID
1275 if (id->hw_config & 0x2000) {
1276 #else /* !__NEW_HD_DRIVE_ID */
1277 if (id->word93 & 0x2000) {
1278 #endif /* __NEW_HD_DRIVE_ID */
1279 static const masks_labels_t ultra_modes2 = {
1280 .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
1281 0x2000, 0x0020, 0x4000, 0x0040,
1283 .labels = "*\0""udma3 \0""*\0""udma4 \0"
1284 "*\0""udma5 \0""*\0""udma6 \0"
1287 print_flags(&ultra_modes2, id->dma_ultra);
1290 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1291 if (id_regs[83] & 8) {
1292 if (!(id_regs[86] & 8))
1293 printf(": disabled (255)");
1294 else if ((id_regs[91] & 0xFF00) != 0x4000)
1295 printf(": unknown setting");
1297 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1299 if (id_regs[82] & 0x20)
1300 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1301 #ifdef __NEW_HD_DRIVE_ID
1302 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1303 || (id->major_rev_num && id->minor_rev_num <= 31)
1305 printf("\n Drive conforms to: %s: ",
1306 (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1307 if (id->major_rev_num != 0x0000 /* NOVAL_0 */
1308 && id->major_rev_num != 0xFFFF /* NOVAL_1 */
1310 for (i = 0; i <= 15; i++) {
1311 if (id->major_rev_num & (1<<i))
1312 printf(" ATA/ATAPI-%u", i);
1316 #endif /* __NEW_HD_DRIVE_ID */
1317 printf("\n\n * current active mode\n\n");
1321 static void flush_buffer_cache(/*int fd*/ void)
1323 fsync(fd); /* flush buffers */
1324 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1325 #ifdef HDIO_DRIVE_CMD
1327 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1328 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1329 bb_perror_msg("HDIO_DRIVE_CMD");
1331 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1336 static void seek_to_zero(/*int fd*/ void)
1338 xlseek(fd, (off_t) 0, SEEK_SET);
1341 static void read_big_block(/*int fd,*/ char *buf)
1345 xread(fd, buf, TIMING_BUF_BYTES);
1346 /* access all sectors of buf to ensure the read fully completed */
1347 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1351 static unsigned dev_size_mb(/*int fd*/ void)
1354 unsigned long long blksize64;
1358 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1359 u.blksize64 /= (1024 * 1024);
1361 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1362 u.blksize64 = u.blksize32 / (2 * 1024);
1364 if (u.blksize64 > UINT_MAX)
1369 static void print_timing(unsigned m, unsigned elapsed_us)
1371 unsigned sec = elapsed_us / 1000000;
1372 unsigned hs = (elapsed_us % 1000000) / 10000;
1374 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1376 /* "| 1" prevents div-by-0 */
1377 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1378 // ~= (m * 1024) / (elapsed_us / 1000000)
1379 // = kb / elapsed_sec
1383 static void do_time(int cache /*,int fd*/)
1384 /* cache=1: time cache: repeatedly read N MB at offset 0
1385 * cache=0: time device: linear read, starting at offset 0
1388 unsigned max_iterations, iterations;
1389 unsigned start; /* doesn't need to be long long */
1390 unsigned elapsed, elapsed2;
1392 char *buf = xmalloc(TIMING_BUF_BYTES);
1394 if (mlock(buf, TIMING_BUF_BYTES))
1395 bb_perror_msg_and_die("mlock");
1397 /* Clear out the device request queues & give them time to complete.
1398 * NB: *small* delay. User is expected to have a clue and to not run
1399 * heavy io in parallel with measurements. */
1402 if (cache) { /* Time cache */
1404 read_big_block(buf);
1405 printf("Timing buffer-cache reads: ");
1406 } else { /* Time device */
1407 printf("Timing buffered disk reads:");
1411 /* Now do the timing */
1413 /* Max time to run (small for cache, avoids getting
1414 * huge total_MB which can overlow unsigned type) */
1415 elapsed2 = 510000; /* cache */
1416 max_iterations = UINT_MAX;
1418 elapsed2 = 3000000; /* not cache */
1419 /* Don't want to read past the end! */
1420 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1422 start = monotonic_us();
1426 read_big_block(buf);
1427 elapsed = (unsigned)monotonic_us() - start;
1429 } while (elapsed < elapsed2 && iterations < max_iterations);
1430 total_MB = iterations * TIMING_BUF_MB;
1431 //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1433 /* Cache: remove lseek() and monotonic_us() overheads
1435 start = monotonic_us();
1438 elapsed2 = (unsigned)monotonic_us() - start;
1439 } while (--iterations);
1440 //printf(" elapsed2:%u ", elapsed2);
1441 elapsed -= elapsed2;
1442 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1443 flush_buffer_cache();
1445 print_timing(total_MB, elapsed);
1446 munlock(buf, TIMING_BUF_BYTES);
1450 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1451 static void bus_state_value(unsigned value)
1453 if (value == BUSSTATE_ON)
1455 else if (value == BUSSTATE_OFF)
1457 else if (value == BUSSTATE_TRISTATE)
1458 printf(" (tristate)\n");
1460 printf(" (unknown: %d)\n", value);
1464 #ifdef HDIO_DRIVE_CMD
1465 static void interpret_standby(uint8_t standby)
1470 } else if (standby <= 240 || standby == 252 || standby == 255) {
1471 /* standby is in 5 sec units */
1472 unsigned t = standby * 5;
1473 printf("%u minutes %u seconds", t / 60, t % 60);
1474 } else if (standby <= 251) {
1475 unsigned t = (standby - 240); /* t is in 30 min units */;
1476 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0');
1479 printf("vendor-specific");
1485 static const uint8_t xfermode_val[] ALIGN1 = {
1486 8, 9, 10, 11, 12, 13, 14, 15,
1487 16, 17, 18, 19, 20, 21, 22, 23,
1488 32, 33, 34, 35, 36, 37, 38, 39,
1489 64, 65, 66, 67, 68, 69, 70, 71
1491 /* NB: we save size by _not_ storing terninating NUL! */
1492 static const char xfermode_name[][5] ALIGN1 = {
1493 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1494 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1495 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1496 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1499 static int translate_xfermode(const char *name)
1504 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1505 if (!strncmp(name, xfermode_name[i], 5))
1506 if (strlen(name) <= 5)
1507 return xfermode_val[i];
1509 /* Negative numbers are invalid and are caught later */
1510 val = bb_strtoi(name, NULL, 10);
1516 static void interpret_xfermode(unsigned xfermode)
1520 printf("default PIO mode");
1521 else if (xfermode == 1)
1522 printf("default PIO mode, disable IORDY");
1523 else if (xfermode >= 8 && xfermode <= 15)
1524 printf("PIO flow control mode%u", xfermode - 8);
1525 else if (xfermode >= 16 && xfermode <= 23)
1526 printf("singleword DMA mode%u", xfermode - 16);
1527 else if (xfermode >= 32 && xfermode <= 39)
1528 printf("multiword DMA mode%u", xfermode - 32);
1529 else if (xfermode >= 64 && xfermode <= 71)
1530 printf("UltraDMA mode%u", xfermode - 64);
1535 #endif /* HDIO_DRIVE_CMD */
1537 static void print_flag(int flag, const char *s, unsigned long value)
1540 printf(" setting %s to %ld\n", s, value);
1543 static void process_dev(char *devname)
1546 long parm, multcount;
1547 #ifndef HDIO_DRIVE_CMD
1548 int force_operation = 0;
1550 /* Please restore args[n] to these values after each ioctl
1551 except for args[2] */
1552 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1553 const char *fmt = " %s\t= %2ld";
1555 /*fd = xopen_nonblocking(devname);*/
1556 xmove_fd(xopen_nonblocking(devname), fd);
1557 printf("\n%s:\n", devname);
1559 if (getset_readahead == IS_SET) {
1560 print_flag(getset_readahead, "fs readahead", Xreadahead);
1561 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1563 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1564 if (unregister_hwif) {
1565 printf(" attempting to unregister hwif#%lu\n", hwif);
1566 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1569 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1570 if (scan_hwif == IS_SET) {
1571 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1572 args[0] = hwif_data;
1573 args[1] = hwif_ctrl;
1575 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1576 args[0] = WIN_SETFEATURES;
1581 if (noisy_piomode) {
1582 printf(" attempting to ");
1584 printf("auto-tune PIO mode\n");
1585 else if (piomode < 100)
1586 printf("set PIO mode to %d\n", piomode);
1587 else if (piomode < 200)
1588 printf("set MDMA mode to %d\n", (piomode-100));
1590 printf("set UDMA mode to %d\n", (piomode-200));
1592 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1594 if (getset_io32bit == IS_SET) {
1595 print_flag(getset_io32bit, "32-bit IO_support flag", io32bit);
1596 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1598 if (getset_mult == IS_SET) {
1599 print_flag(getset_mult, "multcount", mult);
1600 #ifdef HDIO_DRIVE_CMD
1601 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1603 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1606 if (getset_readonly == IS_SET) {
1607 print_flag_on_off(getset_readonly, "readonly", readonly);
1608 ioctl_or_warn(fd, BLKROSET, &readonly);
1610 if (getset_unmask == IS_SET) {
1611 print_flag_on_off(getset_unmask, "unmaskirq", unmask);
1612 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1614 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1615 if (getset_dma == IS_SET) {
1616 print_flag_on_off(getset_dma, "using_dma", dma);
1617 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1619 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1620 #ifdef HDIO_SET_QDMA
1621 if (getset_dma_q == IS_SET) {
1622 print_flag_on_off(getset_dma_q, "DMA queue_depth", dma_q);
1623 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1626 if (getset_nowerr == IS_SET) {
1627 print_flag_on_off(getset_nowerr, "nowerr", nowerr);
1628 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1630 if (getset_keep == IS_SET) {
1631 print_flag_on_off(getset_keep, "keep_settings", keep);
1632 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1634 #ifdef HDIO_DRIVE_CMD
1635 if (getset_doorlock == IS_SET) {
1636 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1638 print_flag_on_off(getset_doorlock, "drive doorlock", doorlock);
1639 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1640 args[0] = WIN_SETFEATURES;
1642 if (getset_dkeep == IS_SET) {
1643 /* lock/unlock the drive's "feature" settings */
1644 print_flag_on_off(getset_dkeep, "drive keep features", dkeep);
1645 args[2] = dkeep ? 0x66 : 0xcc;
1646 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1648 if (getset_defects == IS_SET) {
1649 args[2] = defects ? 0x04 : 0x84;
1650 print_flag(getset_defects, "drive defect-mgmt", defects);
1651 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1653 if (getset_prefetch == IS_SET) {
1656 print_flag(getset_prefetch, "drive prefetch", prefetch);
1657 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1661 args[1] = xfermode_requested;
1663 print_flag(1, "xfermode", xfermode_requested);
1664 interpret_xfermode(xfermode_requested);
1665 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1668 if (getset_lookahead == IS_SET) {
1669 args[2] = lookahead ? 0xaa : 0x55;
1670 print_flag_on_off(getset_lookahead, "drive read-lookahead", lookahead);
1671 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1673 if (getset_apmmode == IS_SET) {
1674 /* feature register */
1675 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */;
1676 args[1] = apmmode; /* sector count register 1-255 */
1677 printf(" setting APM level to %s 0x%02lX (%ld)\n",
1678 (apmmode == 255) ? "disabled" : "",
1680 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1683 if (getset_wcache == IS_SET) {
1684 #ifdef DO_FLUSHCACHE
1685 #ifndef WIN_FLUSHCACHE
1686 #define WIN_FLUSHCACHE 0xe7
1688 #endif /* DO_FLUSHCACHE */
1689 args[2] = wcache ? 0x02 : 0x82;
1690 print_flag_on_off(getset_wcache, "drive write-caching", wcache);
1691 #ifdef DO_FLUSHCACHE
1693 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1694 #endif /* DO_FLUSHCACHE */
1695 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1696 #ifdef DO_FLUSHCACHE
1698 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1699 #endif /* DO_FLUSHCACHE */
1702 /* In code below, we do not preserve args[0], but the rest
1703 is preserved, including args[2] */
1706 if (set_standbynow) {
1707 #ifndef WIN_STANDBYNOW1
1708 #define WIN_STANDBYNOW1 0xE0
1710 #ifndef WIN_STANDBYNOW2
1711 #define WIN_STANDBYNOW2 0x94
1713 printf(" issuing standby command\n");
1714 args[0] = WIN_STANDBYNOW1;
1715 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1718 #ifndef WIN_SLEEPNOW1
1719 #define WIN_SLEEPNOW1 0xE6
1721 #ifndef WIN_SLEEPNOW2
1722 #define WIN_SLEEPNOW2 0x99
1724 printf(" issuing sleep command\n");
1725 args[0] = WIN_SLEEPNOW1;
1726 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1730 printf(" disabling Seagate auto powersaving mode\n");
1731 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1733 if (getset_standby == IS_SET) {
1734 args[0] = WIN_SETIDLE1;
1735 args[1] = standby_requested;
1736 print_flag(1, "standby", standby_requested);
1737 interpret_standby(standby_requested);
1738 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1741 #else /* HDIO_DRIVE_CMD */
1742 if (force_operation) {
1744 flush_buffer_cache();
1745 if (-1 == read(fd, buf, sizeof(buf)))
1746 bb_perror_msg("read of 512 bytes failed");
1748 #endif /* HDIO_DRIVE_CMD */
1749 if (getset_mult || get_identity) {
1751 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1752 /* To be coherent with ioctl_or_warn. */
1753 if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1754 bb_perror_msg("HDIO_GET_MULTCOUNT");
1756 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1757 } else if (getset_mult) {
1758 printf(fmt, "multcount", multcount);
1759 on_off(multcount != 0);
1762 if (getset_io32bit) {
1763 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1764 printf(" IO_support\t=%3ld (", parm);
1766 printf("default 16-bit)\n");
1768 printf("16-bit)\n");
1770 printf("32-bit)\n");
1772 printf("32-bit w/sync)\n");
1774 printf("Request-Queue-Bypass)\n");
1776 printf("\?\?\?)\n");
1779 if (getset_unmask) {
1780 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
1781 print_value_on_off("unmaskirq", parm);
1783 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1785 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1786 printf(fmt, "using_dma", parm);
1788 printf(" (DMA-Assisted-PIO)\n");
1794 #ifdef HDIO_GET_QDMA
1796 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
1797 print_value_on_off("queue_depth", parm);
1801 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
1802 print_value_on_off("keepsettings", parm);
1804 if (getset_nowerr) {
1805 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
1806 print_value_on_off("nowerr", parm);
1808 if (getset_readonly) {
1809 if (!ioctl_or_warn(fd, BLKROGET, &parm))
1810 print_value_on_off("readonly", parm);
1812 if (getset_readahead) {
1813 if (!ioctl_or_warn(fd, BLKRAGET, &parm))
1814 print_value_on_off("readahead", parm);
1817 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1818 struct hd_geometry g;
1820 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1821 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1822 g.cylinders, g.heads, g.sectors, parm, g.start);
1825 #ifdef HDIO_DRIVE_CMD
1826 if (get_powermode) {
1827 #ifndef WIN_CHECKPOWERMODE1
1828 #define WIN_CHECKPOWERMODE1 0xE5
1830 #ifndef WIN_CHECKPOWERMODE2
1831 #define WIN_CHECKPOWERMODE2 0x98
1835 args[0] = WIN_CHECKPOWERMODE1;
1836 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1837 if (errno != EIO || args[0] != 0 || args[1] != 0)
1842 state = (args[2] == 255) ? "active/idle" : "standby";
1843 args[1] = args[2] = 0;
1845 printf(" drive state is: %s\n", state);
1848 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1849 if (perform_reset) {
1850 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1852 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1853 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1854 if (perform_tristate) {
1857 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1859 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1860 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1862 struct hd_driveid id;
1864 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1865 if (multcount != -1) {
1866 id.multsect = multcount;
1867 id.multsect_valid |= 1;
1869 id.multsect_valid &= ~1;
1871 } else if (errno == -ENOMSG)
1872 printf(" no identification info available\n");
1873 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1874 bb_perror_msg("HDIO_GET_IDENTITY");
1876 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1880 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1882 memset(args1, 0, sizeof(args1));
1883 args1[0] = WIN_IDENTIFY;
1885 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1886 identify((void *)(args1 + 4));
1889 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1890 if (getset_busstate == IS_SET) {
1891 print_flag(1, "bus state", busstate);
1892 bus_state_value(busstate);
1893 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1895 if (getset_busstate) {
1896 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1897 printf(fmt, "bus state", parm);
1898 bus_state_value(parm);
1903 ioctl_or_warn(fd, BLKRRPART, NULL);
1906 do_time(1 /*,fd*/); /* time cache */
1908 do_time(0 /*,fd*/); /* time device */
1910 flush_buffer_cache();
1914 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1915 static int fromhex(unsigned char c)
1919 if (c >= 'a' && c <= 'f')
1920 return (c - ('a' - 10));
1921 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1924 static void identify_from_stdin(void) NORETURN;
1925 static void identify_from_stdin(void)
1928 unsigned char buf[1280];
1929 unsigned char *b = (unsigned char *)buf;
1932 xread(STDIN_FILENO, buf, 1280);
1934 // Convert the newline-separated hex data into an identify block.
1936 for (i = 0; i < 256; i++) {
1938 for (j = 0; j < 4; j++)
1939 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1947 void identify_from_stdin(void);
1950 /* busybox specific stuff */
1951 static int parse_opts(unsigned long *value, int min, int max)
1954 *value = xatol_range(optarg, min, max);
1959 static int parse_opts_0_max(unsigned long *value, int max)
1961 return parse_opts(value, 0, max);
1963 static int parse_opts_0_1(unsigned long *value)
1965 return parse_opts(value, 0, 1);
1967 static int parse_opts_0_INTMAX(unsigned long *value)
1969 return parse_opts(value, 0, INT_MAX);
1972 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
1977 *value = translate_xfermode(optarg);
1978 *set = (*value > -1);
1983 /*------- getopt short options --------*/
1984 static const char hdparm_options[] ALIGN1 =
1985 "gfu::n::p:r::m::c::k::a::B:tT"
1986 IF_FEATURE_HDPARM_GET_IDENTITY("iI")
1987 IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
1988 #ifdef HDIO_DRIVE_CMD
1989 "S:D:P:X:K:A:L:W:CyYzZ"
1991 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
1992 #ifdef HDIO_GET_QDMA
1993 #ifdef HDIO_SET_QDMA
1999 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
2000 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
2001 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
2002 /*-------------------------------------*/
2004 /* our main() routine: */
2005 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2006 int hdparm_main(int argc, char **argv)
2011 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2013 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2014 IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2015 get_geom |= (c == 'g');
2016 do_flush |= (c == 'f');
2017 if (c == 'u') getset_unmask = parse_opts_0_1(&unmask);
2018 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
2019 if (c == 'd') getset_dma = parse_opts_0_max(&dma, 9);
2021 if (c == 'n') getset_nowerr = parse_opts_0_1(&nowerr);
2022 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2023 if (c == 'r') getset_readonly = parse_opts_0_1(&readonly);
2024 if (c == 'm') getset_mult = parse_opts_0_INTMAX(&mult /*32*/);
2025 if (c == 'c') getset_io32bit = parse_opts_0_INTMAX(&io32bit /*8*/);
2026 if (c == 'k') getset_keep = parse_opts_0_1(&keep);
2027 if (c == 'a') getset_readahead = parse_opts_0_INTMAX(&Xreadahead);
2028 if (c == 'B') getset_apmmode = parse_opts(&apmmode, 1, 255);
2029 do_flush |= do_timings |= (c == 't');
2030 do_flush |= do_ctimings |= (c == 'T');
2031 #ifdef HDIO_DRIVE_CMD
2032 if (c == 'S') getset_standby = parse_opts_0_max(&standby_requested, 255);
2033 if (c == 'D') getset_defects = parse_opts_0_INTMAX(&defects);
2034 if (c == 'P') getset_prefetch = parse_opts_0_INTMAX(&prefetch);
2035 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2036 if (c == 'K') getset_dkeep = parse_opts_0_1(&prefetch);
2037 if (c == 'A') getset_lookahead = parse_opts_0_1(&lookahead);
2038 if (c == 'L') getset_doorlock = parse_opts_0_1(&doorlock);
2039 if (c == 'W') getset_wcache = parse_opts_0_1(&wcache);
2040 get_powermode |= (c == 'C');
2041 set_standbynow |= (c == 'y');
2042 set_sleepnow |= (c == 'Y');
2043 reread_partn |= (c == 'z');
2044 set_seagate |= (c == 'Z');
2046 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') unregister_hwif = parse_opts_0_INTMAX(&hwif));
2047 #ifdef HDIO_GET_QDMA
2049 getset_dma_q = parse_opts_0_INTMAX(&dma_q);
2052 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2053 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') perform_tristate = parse_opts_0_1(&tristate));
2054 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') getset_busstate = parse_opts_0_max(&busstate, 2));
2055 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2057 scan_hwif = parse_opts_0_INTMAX(&hwif_data);
2058 hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
2059 hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
2060 /* Move past the 2 additional arguments */
2066 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2068 getset_mult = getset_io32bit = getset_unmask = getset_keep = getset_readonly = getset_readahead = get_geom = IS_GET;
2069 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(getset_dma = IS_GET);
2074 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2075 identify_from_stdin(); /* EXIT */
2080 process_dev(*argv++);
2083 return EXIT_SUCCESS;