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>
22 #define ATA_DEV 0x0000
23 #define ATAPI_DEV 0x0001
25 /* word definitions */
26 /* ---------------- */
27 #define GEN_CONFIG 0 /* general configuration */
28 #define LCYLS 1 /* number of logical cylinders */
29 #define CONFIG 2 /* specific configuration */
30 #define LHEADS 3 /* number of logical heads */
31 #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
32 #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
33 #define LSECTS 6 /* number of logical sectors/track */
34 #define START_SERIAL 10 /* ASCII serial number */
35 #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
36 #define BUF_TYPE 20 /* buffer type (ATA-1) */
37 #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
38 #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
39 #define START_FW_REV 23 /* ASCII firmware revision */
40 #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
41 #define START_MODEL 27 /* ASCII model number */
42 #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
43 #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
44 #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
45 #define CAPAB_0 49 /* capabilities */
47 #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
48 #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
49 #define WHATS_VALID 53 /* what fields are valid */
50 #define LCYLS_CUR 54 /* current logical cylinders */
51 #define LHEADS_CUR 55 /* current logical heads */
52 #define LSECTS_CUR 56 /* current logical sectors/track */
53 #define CAPACITY_LSB 57 /* current capacity in sectors */
54 #define CAPACITY_MSB 58
55 #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
56 #define LBA_SECTS_LSB 60 /* LBA: total number of user */
57 #define LBA_SECTS_MSB 61 /* addressable sectors */
58 #define SINGLE_DMA 62 /* singleword DMA modes */
59 #define MULTI_DMA 63 /* multiword DMA modes */
60 #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
61 /* multiword DMA xfer cycle time: */
62 #define DMA_TIME_MIN 65 /* - minimum */
63 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
64 /* minimum PIO xfer cycle time: */
65 #define PIO_NO_FLOW 67 /* - without flow control */
66 #define PIO_FLOW 68 /* - with IORDY flow control */
67 #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
68 #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
69 #define CDR_MAJOR 73 /* CD ROM: major version number */
70 #define CDR_MINOR 74 /* CD ROM: minor version number */
71 #define QUEUE_DEPTH 75 /* queue depth */
72 #define MAJOR 80 /* major version number */
73 #define MINOR 81 /* minor version number */
74 #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
75 #define CMDS_SUPP_1 83
76 #define CMDS_SUPP_2 84
77 #define CMDS_EN_0 85 /* command/feature set(s) enabled */
80 #define ULTRA_DMA 88 /* ultra DMA modes */
81 /* time to complete security erase */
82 #define ERASE_TIME 89 /* - ordinary */
83 #define ENH_ERASE_TIME 90 /* - enhanced */
84 #define ADV_PWR 91 /* current advanced power management level
85 in low byte, 0x40 in high byte. */
86 #define PSWD_CODE 92 /* master password revision code */
87 #define HWRST_RSLT 93 /* hardware reset result */
88 #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
89 #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
90 #define LBA_MID 101 /* bits are used, but addr 103 */
91 #define LBA_48_MSB 102 /* has been reserved for LBA in */
92 #define LBA_64_MSB 103 /* the future. */
93 #define RM_STAT 127 /* removable media status notification feature set support */
94 #define SECU_STATUS 128 /* security status */
95 #define CFA_PWR_MODE 160 /* CFA power mode 1 */
96 #define START_MEDIA 176 /* media serial number */
97 #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
98 #define START_MANUF 196 /* media manufacturer I.D. */
99 #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
100 #define INTEGRITY 255 /* integrity word */
102 /* bit definitions within the words */
103 /* -------------------------------- */
105 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
107 #define VALID_VAL 0x4000
108 /* many words are considered invalid if they are either all-0 or all-1 */
109 #define NOVAL_0 0x0000
110 #define NOVAL_1 0xffff
112 /* word 0: gen_config */
113 #define NOT_ATA 0x8000
114 #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
115 #define MEDIA_REMOVABLE 0x0080
116 #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
117 #define INCOMPLETE 0x0004
118 #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
119 #define DRQ_RESPONSE_TIME 0x0060
120 #define DRQ_3MS_VAL 0x0000
121 #define DRQ_INTR_VAL 0x0020
122 #define DRQ_50US_VAL 0x0040
123 #define PKT_SIZE_SUPPORTED 0x0003
124 #define PKT_SIZE_12_VAL 0x0000
125 #define PKT_SIZE_16_VAL 0x0001
126 #define EQPT_TYPE 0x1f00
131 /* word 1: number of logical cylinders */
132 #define LCYLS_MAX 0x3fff /* maximum allowable value */
134 /* word 2: specific configuration
135 * (a) require SET FEATURES to spin-up
136 * (b) require spin-up to fully reply to IDENTIFY DEVICE
138 #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
139 #define STBY_ID_VAL 0x738c /* (a) and not (b) */
140 #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
141 #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
143 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
144 #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
145 #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
147 /* word 49: capabilities 0 */
148 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
149 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
150 #define IORDY_OFF 0x0400 /* 1=may be disabled */
151 #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
152 #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
153 #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
154 #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
155 #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
156 #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
158 /* word 50: capabilities 1 */
159 #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
161 /* words 51 & 52: PIO & DMA cycle times */
162 #define MODE 0xff00 /* the mode is in the MSBs */
164 /* word 53: whats_valid */
165 #define OK_W88 0x0004 /* the ultra_dma info is valid */
166 #define OK_W64_70 0x0002 /* see above for word descriptions */
167 #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
169 /*word 63,88: dma_mode, ultra_dma_mode*/
170 #define MODE_MAX 7 /* bit definitions force udma <=7 (when
171 * udma >=8 comes out it'll have to be
172 * defined in a new dma_mode word!) */
174 /* word 64: PIO transfer modes */
175 #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
176 #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
178 /* word 75: queue_depth */
179 #define DEPTH_BITS 0x001f /* bits used for queue depth */
181 /* words 80-81: version numbers */
182 /* NOVAL_0 or NOVAL_1 means device does not report version */
184 /* word 81: minor version number */
185 #define MINOR_MAX 0x22
186 /* words 82-84: cmds/feats supported */
187 #define CMDS_W82 0x77ff /* word 82: defined command locations*/
188 #define CMDS_W83 0x3fff /* word 83: defined command locations*/
189 #define CMDS_W84 0x002f /* word 83: defined command locations*/
190 #define SUPPORT_48_BIT 0x0400
191 #define NUM_CMD_FEAT_STR 48
193 /* words 85-87: cmds/feats enabled */
194 /* use cmd_feat_str[] to display what commands and features have
195 * been enabled with words 85-87
198 /* words 89, 90, SECU ERASE TIME */
199 #define ERASE_BITS 0x00ff
201 /* word 92: master password revision */
202 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
204 /* word 93: hw reset result */
205 #define CBLID 0x2000 /* CBLID status */
206 #define RST0 0x0001 /* 1=reset to device #0 */
207 #define DEV_DET 0x0006 /* how device num determined */
208 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
209 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
211 /* word 127: removable media status notification feature set support */
212 #define RM_STAT_BITS 0x0003
213 #define RM_STAT_SUP 0x0001
215 /* word 128: security */
216 #define SECU_ENABLED 0x0002
217 #define SECU_LEVEL 0x0010
218 #define NUM_SECU_STR 6
220 /* word 160: CFA power mode */
221 #define VALID_W160 0x8000 /* 1=word valid */
222 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
223 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
224 #define MAX_AMPS 0x0fff /* value = max current in ma */
226 /* word 255: integrity */
227 #define SIG 0x00ff /* signature location */
228 #define SIG_VAL 0x00a5 /* signature value */
230 #define TIMING_BUF_MB 1
231 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
233 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
244 smallint get_identity, get_geom;
246 smallint do_ctimings, do_timings;
247 smallint reread_partn;
248 smallint set_piomode, noisy_piomode;
249 smallint getset_readahead;
250 smallint getset_readonly;
251 smallint getset_unmask;
252 smallint getset_mult;
254 smallint getset_dma_q;
256 smallint getset_nowerr;
257 smallint getset_keep;
258 smallint getset_io32bit;
260 unsigned long Xreadahead;
261 unsigned long readonly;
262 unsigned long unmask;
267 unsigned long nowerr;
269 unsigned long io32bit;
270 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
274 #ifdef HDIO_DRIVE_CMD
275 smallint set_xfermode, get_xfermode;
276 smallint getset_dkeep;
277 smallint getset_standby;
278 smallint getset_lookahead;
279 smallint getset_prefetch;
280 smallint getset_defects;
281 smallint getset_wcache;
282 smallint getset_doorlock;
283 smallint set_seagate;
284 smallint set_standbynow;
285 smallint set_sleepnow;
286 smallint get_powermode;
287 smallint getset_apmmode;
288 int xfermode_requested;
290 unsigned long standby_requested; /* 0..255 */
291 unsigned long lookahead;
292 unsigned long prefetch;
293 unsigned long defects;
294 unsigned long wcache;
295 unsigned long doorlock;
296 unsigned long apmmode;
298 IF_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
299 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint getset_busstate;)
300 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
301 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
302 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
303 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
304 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
305 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
306 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
307 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
308 unsigned long hwif_data;
309 unsigned long hwif_ctrl;
310 unsigned long hwif_irq;
313 unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
316 #define G (*(struct globals*)&bb_common_bufsiz1)
317 struct BUG_G_too_big {
318 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
320 #define get_identity (G.get_identity )
321 #define get_geom (G.get_geom )
322 #define do_flush (G.do_flush )
323 #define do_ctimings (G.do_ctimings )
324 #define do_timings (G.do_timings )
325 #define reread_partn (G.reread_partn )
326 #define set_piomode (G.set_piomode )
327 #define noisy_piomode (G.noisy_piomode )
328 #define getset_readahead (G.getset_readahead )
329 #define getset_readonly (G.getset_readonly )
330 #define getset_unmask (G.getset_unmask )
331 #define getset_mult (G.getset_mult )
332 #define getset_dma_q (G.getset_dma_q )
333 #define getset_nowerr (G.getset_nowerr )
334 #define getset_keep (G.getset_keep )
335 #define getset_io32bit (G.getset_io32bit )
336 #define piomode (G.piomode )
337 #define Xreadahead (G.Xreadahead )
338 #define readonly (G.readonly )
339 #define unmask (G.unmask )
340 #define mult (G.mult )
341 #define dma_q (G.dma_q )
342 #define nowerr (G.nowerr )
343 #define keep (G.keep )
344 #define io32bit (G.io32bit )
346 #define getset_dma (G.getset_dma )
347 #define set_xfermode (G.set_xfermode )
348 #define get_xfermode (G.get_xfermode )
349 #define getset_dkeep (G.getset_dkeep )
350 #define getset_standby (G.getset_standby )
351 #define getset_lookahead (G.getset_lookahead )
352 #define getset_prefetch (G.getset_prefetch )
353 #define getset_defects (G.getset_defects )
354 #define getset_wcache (G.getset_wcache )
355 #define getset_doorlock (G.getset_doorlock )
356 #define set_seagate (G.set_seagate )
357 #define set_standbynow (G.set_standbynow )
358 #define set_sleepnow (G.set_sleepnow )
359 #define get_powermode (G.get_powermode )
360 #define getset_apmmode (G.getset_apmmode )
361 #define xfermode_requested (G.xfermode_requested )
362 #define dkeep (G.dkeep )
363 #define standby_requested (G.standby_requested )
364 #define lookahead (G.lookahead )
365 #define prefetch (G.prefetch )
366 #define defects (G.defects )
367 #define wcache (G.wcache )
368 #define doorlock (G.doorlock )
369 #define apmmode (G.apmmode )
370 #define get_IDentity (G.get_IDentity )
371 #define getset_busstate (G.getset_busstate )
372 #define perform_reset (G.perform_reset )
373 #define perform_tristate (G.perform_tristate )
374 #define unregister_hwif (G.unregister_hwif )
375 #define scan_hwif (G.scan_hwif )
376 #define busstate (G.busstate )
377 #define tristate (G.tristate )
378 #define hwif (G.hwif )
379 #define hwif_data (G.hwif_data )
380 #define hwif_ctrl (G.hwif_ctrl )
381 #define hwif_irq (G.hwif_irq )
384 /* Busybox messages and functions */
385 #if ENABLE_IOCTL_HEX2STR_ERROR
386 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
388 if (!ioctl(fd, cmd, args))
391 return bb_ioctl_or_warn(fd, cmd, args, string);
393 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
395 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
397 if (!ioctl(fd, cmd, args))
400 return bb_ioctl_or_warn(fd, cmd, args);
402 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
405 static void on_off(int value)
407 puts(value ? " (on)" : " (off)");
410 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
413 printf(" setting %s to %ld", s, arg);
418 static void print_value_on_off(const char *str, unsigned long argp)
420 printf(" %s\t= %2ld", str, argp);
424 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
425 static void print_ascii(const char *p, int length)
432 /* every 16bit word is big-endian (i.e. inverted) */
433 /* accessing bytes in 1,0, 3,2, 5,4... sequence */
438 /* find first non-space & print it */
439 while (length && p[ofs] != ' ') {
444 while (length && p[ofs]) {
454 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
457 printf("\t%-20s", string);
458 print_ascii((void*)&val[i], n);
462 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
467 for (ii = 0; ii <= MODE_MAX; ii++) {
468 if (mode_sel & 0x0001) {
469 printf("*%cdma%u ", cc, ii);
473 } else if (mode_sup & 0x0001)
474 printf("%cdma%u ", cc, ii);
482 static const char pkt_str[] ALIGN1 =
483 "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
484 "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
485 "Printer" "\0" /* word 0, bits 12-8 = 02 */
486 "Processor" "\0" /* word 0, bits 12-8 = 03 */
487 "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
488 "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
489 "Scanner" "\0" /* word 0, bits 12-8 = 06 */
490 "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
491 "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
492 "Communications device" "\0" /* word 0, bits 12-8 = 09 */
493 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
494 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
495 "Array controller" "\0" /* word 0, bits 12-8 = 0c */
496 "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
497 "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
498 "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
501 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
502 "reserved" "\0" /* bit 0 */
503 "hard sectored" "\0" /* bit 1 */
504 "soft sectored" "\0" /* bit 2 */
505 "not MFM encoded " "\0" /* bit 3 */
506 "head switch time > 15us" "\0" /* bit 4 */
507 "spindle motor control option" "\0" /* bit 5 */
508 "fixed drive" "\0" /* bit 6 */
509 "removable drive" "\0" /* bit 7 */
510 "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
511 "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
512 "disk xfer rate > 5Mbs" "\0" /* bit 10 */
513 "rotational speed tol." "\0" /* bit 11 */
514 "data strobe offset option" "\0" /* bit 12 */
515 "track offset option" "\0" /* bit 13 */
516 "format speed tolerance gap reqd" "\0" /* bit 14 */
520 static const char minor_str[] ALIGN1 =
522 "Unspecified" "\0" /* 0x0000 */
523 "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
524 "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
525 "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
526 "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
527 "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
528 "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
529 "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
530 "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
531 "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
532 "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
533 "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
534 "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
535 "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
536 "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
537 "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
538 "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
539 "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
540 "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
541 "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
542 "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
543 "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
544 "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
545 "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
546 "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
547 "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
548 "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
549 "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
550 "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
551 "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
552 "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
553 "reserved" "\0" /* 0x001f */
554 "reserved" "\0" /* 0x0020 */
555 "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
556 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
557 "reserved" /* 0x0023-0xfffe */
559 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
561 0, /* 0x0000 WARNING: actual_ver[] array */
562 1, /* 0x0001 WARNING: corresponds */
563 1, /* 0x0002 WARNING: *exactly* */
564 1, /* 0x0003 WARNING: to the ATA/ */
565 2, /* 0x0004 WARNING: ATAPI version */
566 2, /* 0x0005 WARNING: listed in */
567 3, /* 0x0006 WARNING: the */
568 2, /* 0x0007 WARNING: minor_str */
569 3, /* 0x0008 WARNING: array */
570 2, /* 0x0009 WARNING: above. */
571 3, /* 0x000a WARNING: */
572 3, /* 0x000b WARNING: If you change */
573 3, /* 0x000c WARNING: that one, */
574 4, /* 0x000d WARNING: change this one */
575 4, /* 0x000e WARNING: too!!! */
596 0 /* 0x0023-0xfffe */
599 static const char cmd_feat_str[] ALIGN1 =
600 "" "\0" /* word 82 bit 15: obsolete */
601 "NOP cmd" "\0" /* word 82 bit 14 */
602 "READ BUFFER cmd" "\0" /* word 82 bit 13 */
603 "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
604 "" "\0" /* word 82 bit 11: obsolete */
605 "Host Protected Area feature set" "\0" /* word 82 bit 10 */
606 "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
607 "SERVICE interrupt" "\0" /* word 82 bit 8 */
608 "Release interrupt" "\0" /* word 82 bit 7 */
609 "Look-ahead" "\0" /* word 82 bit 6 */
610 "Write cache" "\0" /* word 82 bit 5 */
611 "PACKET command feature set" "\0" /* word 82 bit 4 */
612 "Power Management feature set" "\0" /* word 82 bit 3 */
613 "Removable Media feature set" "\0" /* word 82 bit 2 */
614 "Security Mode feature set" "\0" /* word 82 bit 1 */
615 "SMART feature set" "\0" /* word 82 bit 0 */
617 "" "\0" /* word 83 bit 15: !valid bit */
618 "" "\0" /* word 83 bit 14: valid bit */
619 "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
620 "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
621 "Device Configuration Overlay feature set " "\0"
622 "48-bit Address feature set " "\0" /* word 83 bit 10 */
624 "SET MAX security extension" "\0" /* word 83 bit 8 */
625 "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
626 "SET FEATURES subcommand required to spinup after power up" "\0"
627 "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
628 "Removable Media Status Notification feature set" "\0"
629 "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
630 "CFA feature set" "\0" /* word 83 bit 2 */
631 "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
632 "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
634 "" "\0" /* word 84 bit 15: !valid bit */
635 "" "\0" /* word 84 bit 14: valid bit */
636 "" "\0" /* word 84 bit 13: reserved */
637 "" "\0" /* word 84 bit 12: reserved */
638 "" "\0" /* word 84 bit 11: reserved */
639 "" "\0" /* word 84 bit 10: reserved */
640 "" "\0" /* word 84 bit 9: reserved */
641 "" "\0" /* word 84 bit 8: reserved */
642 "" "\0" /* word 84 bit 7: reserved */
643 "" "\0" /* word 84 bit 6: reserved */
644 "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
645 "" "\0" /* word 84 bit 4: reserved */
646 "Media Card Pass Through Command feature set " "\0"
647 "Media serial number " "\0" /* word 84 bit 2 */
648 "SMART self-test " "\0" /* word 84 bit 1 */
649 "SMART error logging " /* word 84 bit 0 */
652 static const char secu_str[] ALIGN1 =
653 "supported" "\0" /* word 128, bit 0 */
654 "enabled" "\0" /* word 128, bit 1 */
655 "locked" "\0" /* word 128, bit 2 */
656 "frozen" "\0" /* word 128, bit 3 */
657 "expired: security count" "\0" /* word 128, bit 4 */
658 "supported: enhanced erase" /* word 128, bit 5 */
661 // Parse 512 byte disk identification block and print much crap.
662 static void identify(uint16_t *val) NORETURN;
663 static void identify(uint16_t *val)
666 uint16_t like_std = 1, std = 0, min_std = 0xffff;
667 uint16_t dev = NO_DEV, eqpt = NO_DEV;
668 uint8_t have_mode = 0, err_dma = 0;
670 uint32_t ll, mm, nn, oo;
671 uint64_t bbbig; /* (:) */
676 // Adjust for endianness
677 swab(val, buf, sizeof(buf));
680 /* check if we recognize the device type */
682 if (!(val[GEN_CONFIG] & NOT_ATA)) {
684 printf("ATA device, with ");
685 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
688 printf("CompactFlash ATA device, with ");
689 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
691 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
692 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
695 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
696 bb_error_msg_and_die("unknown device type");
698 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
699 /* Info from the specific configuration word says whether or not the
700 * ID command completed correctly. It is only defined, however in
701 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
702 * standards. Since the values allowed for this word are extremely
703 * specific, it should be safe to check it now, even though we don't
704 * know yet what standard this device is using.
706 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
707 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
710 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
711 printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
712 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
713 printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
716 /* output the model and serial numbers and the fw revision */
717 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
718 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
719 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
720 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
721 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
723 /* major & minor standards version number (Note: these words were not
724 * defined until ATA-3 & the CDROM std uses different words.) */
725 printf("Standards:");
727 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
728 if (like_std < 3) like_std = 3;
729 std = actual_ver[val[MINOR]];
730 if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
733 /* looks like when they up-issue the std, they obsolete one;
734 * thus, only the newest 4 issues need be supported. (That's
735 * what "kk" and "min_std" are all about.) */
736 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
737 printf("\n\tSupported: ");
738 jj = val[MAJOR] << 1;
739 kk = like_std >4 ? like_std-4: 0;
740 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
745 kk = like_std >4 ? like_std-4: 0;
747 if (min_std > ii) min_std = ii;
751 if (like_std < 3) like_std = 3;
753 /* Figure out what standard the device is using if it hasn't told
754 * us. If we know the std, check if the device is using any of
755 * the words from the next level up. It happens.
757 if (like_std < std) like_std = std;
759 if (((std == 5) || (!std && (like_std < 6))) &&
760 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
761 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
762 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
763 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
766 } else if (((std == 4) || (!std && (like_std < 5))) &&
767 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
768 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
769 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
770 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
773 } else if (((std == 3) || (!std && (like_std < 4))) &&
774 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
775 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
776 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
777 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
778 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
779 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
782 } else if (((std == 2) || (!std && (like_std < 3)))
783 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
786 } else if (((std == 1) || (!std && (like_std < 2))) &&
787 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
788 (val[WHATS_VALID] & OK_W64_70)) )
794 printf("\n\tLikely used: %u\n", like_std);
795 else if (like_std > std)
796 printf("& some of %u\n", like_std);
800 /* TBD: do CDROM stuff more thoroughly. For now... */
802 if (val[CDR_MINOR] == 9) {
804 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
806 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
808 printf("\n\tSupported: CD-ROM ATAPI");
809 jj = val[CDR_MAJOR] >> 1;
810 for (ii = 1; ii < 15; ii++) {
811 if (jj & 0x0001) printf("-%u ", ii);
815 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
816 /* the cdrom stuff is more like ATA-2 than anything else, so: */
820 if (min_std == 0xffff)
821 min_std = like_std > 4 ? like_std - 3 : 1;
823 printf("Configuration:\n");
824 /* more info from the general configuration word */
825 if ((eqpt != CDROM) && (like_std == 1)) {
826 jj = val[GEN_CONFIG] >> 1;
827 for (ii = 1; ii < 15; ii++) {
829 printf("\t%s\n", nth_string(ata1_cfg_str, ii));
833 if (dev == ATAPI_DEV) {
834 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
836 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
837 strng = "<=10ms with INTRQ";
838 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
842 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
844 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
846 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
852 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
853 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
856 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
857 printf("\tCHS addressing not supported\n");
859 jj = val[WHATS_VALID] & OK_W54_58;
860 printf("\tLogical\t\tmax\tcurrent\n"
861 "\tcylinders\t%u\t%u\n"
862 "\theads\t\t%u\t%u\n"
863 "\tsectors/track\t%u\t%u\n"
866 jj ? val[LCYLS_CUR] : 0,
868 jj ? val[LHEADS_CUR] : 0,
870 jj ? val[LSECTS_CUR] : 0);
872 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
873 printf("\tbytes/track: %u\tbytes/sector: %u\n",
874 val[TRACK_BYTES], val[SECT_BYTES]);
877 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
879 /* check Endian of capacity bytes */
880 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
881 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
882 if (abs(mm - nn) > abs(oo - nn))
885 printf("\tCHS current addressable sectors:%11u\n", mm);
889 printf("\tLBA user addressable sectors:%11u\n", ll);
890 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
891 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
893 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
894 (uint64_t)val[LBA_48_MSB] << 32 |
895 (uint64_t)val[LBA_MID] << 16 |
897 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
901 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
902 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
903 bbbig = (bbbig << 9) / 1000000;
904 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
907 printf("(%"PRIu64" GB)\n", bbbig/1000);
912 /* hw support of commands (capabilities) */
913 printf("Capabilities:\n\t");
915 if (dev == ATAPI_DEV) {
916 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP))
917 printf("Cmd queuing, ");
918 if (val[CAPAB_0] & OVLP_SUP)
919 printf("Cmd overlap, ");
921 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
924 printf("IORDY%s(can%s be disabled)\n",
925 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
926 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
928 printf("no IORDY\n");
930 if ((like_std == 1) && val[BUF_TYPE]) {
931 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
932 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
933 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
936 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
937 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
939 if ((min_std < 4) && (val[RW_LONG])) {
940 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
942 if ((eqpt != CDROM) && (like_std > 3)) {
943 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
946 if (dev == ATA_DEV) {
948 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
950 printf("\tStandby timer values: spec'd by %s",
951 (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor");
952 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
953 printf(", %s device specific minimum\n",
954 (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
958 printf("\tR/W multiple sector transfer: ");
959 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
960 printf("not supported\n");
962 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
963 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
964 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
968 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
969 /* We print out elsewhere whether the APM feature is enabled or
970 not. If it's not enabled, let's not repeat the info; just print
972 printf("\tAdvancedPM level: ");
973 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
974 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
975 printf("%u (0x%x)\n", apm_level, apm_level);
978 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
980 if (like_std > 5 && val[ACOUSTIC]) {
981 printf("\tRecommended acoustic management value: %u, current value: %u\n",
982 (val[ACOUSTIC] >> 8) & 0x00ff,
983 val[ACOUSTIC] & 0x00ff);
987 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
988 printf("\tATA sw reset required\n");
990 if (val[PKT_REL] || val[SVC_NBSY]) {
991 printf("\tOverlap support:");
993 printf(" %uus to release bus.", val[PKT_REL]);
995 printf(" %uus to clear BSY after SERVICE cmd.",
1001 /* DMA stuff. Check that only one DMA mode is selected. */
1003 if (!(val[CAPAB_0] & DMA_SUP))
1004 printf("not supported\n");
1006 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1007 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1008 if (val[SINGLE_DMA]) {
1009 jj = val[SINGLE_DMA];
1010 kk = val[SINGLE_DMA] >> 8;
1011 err_dma += mode_loop(jj, kk, 's', &have_mode);
1013 if (val[MULTI_DMA]) {
1014 jj = val[MULTI_DMA];
1015 kk = val[MULTI_DMA] >> 8;
1016 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1018 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1019 jj = val[ULTRA_DMA];
1020 kk = val[ULTRA_DMA] >> 8;
1021 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1023 if (err_dma || !have_mode) printf("(?)");
1026 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1027 printf("\t\tInterleaved DMA support\n");
1029 if ((val[WHATS_VALID] & OK_W64_70)
1030 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1032 printf("\t\tCycle time:");
1033 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1034 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1039 /* Programmed IO stuff */
1041 /* If a drive supports mode n (e.g. 3), it also supports all modes less
1042 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1043 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1044 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1045 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1046 if (jj & 0x0001) printf("pio%d ", ii);
1050 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1051 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1052 printf("pio%d ", ii);
1057 if (val[WHATS_VALID] & OK_W64_70) {
1058 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1059 printf("\t\tCycle time:");
1060 if (val[PIO_NO_FLOW])
1061 printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1063 printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1068 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1069 printf("Commands/features:\n"
1070 "\tEnabled\tSupported:\n");
1071 jj = val[CMDS_SUPP_0];
1072 kk = val[CMDS_EN_0];
1073 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1074 const char *feat_str = nth_string(cmd_feat_str, ii);
1075 if ((jj & 0x8000) && (*feat_str != '\0')) {
1076 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
1080 if (ii % 16 == 15) {
1081 jj = val[CMDS_SUPP_0+1+(ii/16)];
1082 kk = val[CMDS_EN_0+1+(ii/16)];
1085 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1090 /* Removable Media Status Notification feature set */
1091 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1092 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1095 if ((eqpt != CDROM) && (like_std > 3)
1096 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1098 printf("Security:\n");
1099 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1100 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1101 jj = val[SECU_STATUS];
1103 for (ii = 0; ii < NUM_SECU_STR; ii++) {
1104 printf("\t%s\t%s\n",
1105 (!(jj & 0x0001)) ? "not" : "",
1106 nth_string(secu_str, ii));
1109 if (val[SECU_STATUS] & SECU_ENABLED) {
1110 printf("\tSecurity level %s\n",
1111 (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1114 jj = val[ERASE_TIME] & ERASE_BITS;
1115 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1118 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1119 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1125 jj = val[HWRST_RSLT];
1126 if ((jj & VALID) == VALID_VAL) {
1130 if ((jj & DEV_DET) == JUMPER_VAL)
1131 strng = " determined by the jumper";
1132 else if ((jj & DEV_DET) == CSEL_VAL)
1133 strng = " determined by CSEL";
1136 printf("HW reset results:\n"
1138 "\tDevice num = %i%s\n",
1139 (val[HWRST_RSLT] & CBLID) ? "above" : "below",
1143 /* more stuff from std 5 */
1144 if ((like_std > 4) && (eqpt != CDROM)) {
1145 if (val[CFA_PWR_MODE] & VALID_W160) {
1146 printf("CFA power mode 1:\n"
1148 (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1149 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1150 if (val[CFA_PWR_MODE] & MAX_AMPS)
1151 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1153 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1154 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1162 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1163 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1164 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1165 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1166 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1167 // (which they should, but they should just return -EINVAL).
1169 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1170 // On a really old system, it will not, and we will be confused.
1173 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1174 static const char cfg_str[] ALIGN1 =
1175 """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
1176 "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
1177 "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1178 "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
1181 static const char BuffType[] ALIGN1 =
1182 "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
1185 static void dump_identity(const struct hd_driveid *id)
1188 const unsigned short *id_regs = (const void*) id;
1190 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1191 id->model, id->fw_rev, id->serial_no);
1192 for (i = 0; i <= 15; i++) {
1193 if (id->config & (1<<i))
1194 printf(" %s", nth_string(cfg_str, i));
1196 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1197 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1198 id->cyls, id->heads, id->sectors, id->track_bytes,
1199 id->sector_bytes, id->ecc_bytes,
1201 nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1202 id->buf_size/2, id->max_multsect);
1203 if (id->max_multsect) {
1204 printf(", MultSect=");
1205 if (!(id->multsect_valid & 1))
1206 printf("?%u?", id->multsect);
1207 else if (id->multsect)
1208 printf("%u", id->multsect);
1214 if (!(id->field_valid & 1))
1215 printf(" (maybe):");
1217 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1220 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1221 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1222 ((id->capability&2) == 0) ? "no" : "yes");
1224 if (id->capability & 2)
1225 printf(", LBAsects=%u", id->lba_capacity);
1227 printf("\n IORDY=%s",
1228 (id->capability & 8)
1229 ? ((id->capability & 4) ? "on/off" : "yes")
1232 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1233 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1235 if ((id->capability & 1) && (id->field_valid & 2))
1236 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1238 printf("\n PIO modes: ");
1239 if (id->tPIO <= 5) {
1241 if (id->tPIO >= 1) printf("pio1 ");
1242 if (id->tPIO >= 2) printf("pio2 ");
1244 if (id->field_valid & 2) {
1245 static const masks_labels_t pio_modes = {
1246 .masks = { 1, 2, ~3 },
1247 .labels = "pio3 \0""pio4 \0""pio? \0",
1249 print_flags(&pio_modes, id->eide_pio_modes);
1251 if (id->capability & 1) {
1252 if (id->dma_1word | id->dma_mword) {
1253 static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
1254 printf("\n DMA modes: ");
1255 print_flags_separated(dma_wmode_masks,
1256 "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
1257 id->dma_1word, NULL);
1258 print_flags_separated(dma_wmode_masks,
1259 "*\0""mdma0 \0""*\0""mdma1 \0""*\0""mdma2 \0""*\0""mdma? \0",
1260 id->dma_mword, NULL);
1263 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1264 static const masks_labels_t ultra_modes1 = {
1265 .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
1266 .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
1269 printf("\n UDMA modes: ");
1270 print_flags(&ultra_modes1, id->dma_ultra);
1271 #ifdef __NEW_HD_DRIVE_ID
1272 if (id->hw_config & 0x2000) {
1273 #else /* !__NEW_HD_DRIVE_ID */
1274 if (id->word93 & 0x2000) {
1275 #endif /* __NEW_HD_DRIVE_ID */
1276 static const masks_labels_t ultra_modes2 = {
1277 .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
1278 0x2000, 0x0020, 0x4000, 0x0040,
1280 .labels = "*\0""udma3 \0""*\0""udma4 \0"
1281 "*\0""udma5 \0""*\0""udma6 \0"
1284 print_flags(&ultra_modes2, id->dma_ultra);
1287 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1288 if (id_regs[83] & 8) {
1289 if (!(id_regs[86] & 8))
1290 printf(": disabled (255)");
1291 else if ((id_regs[91] & 0xFF00) != 0x4000)
1292 printf(": unknown setting");
1294 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1296 if (id_regs[82] & 0x20)
1297 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1298 #ifdef __NEW_HD_DRIVE_ID
1299 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1300 || (id->major_rev_num && id->minor_rev_num <= 31)
1302 printf("\n Drive conforms to: %s: ",
1303 (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1304 if (id->major_rev_num != 0x0000 /* NOVAL_0 */
1305 && id->major_rev_num != 0xFFFF /* NOVAL_1 */
1307 for (i = 0; i <= 15; i++) {
1308 if (id->major_rev_num & (1<<i))
1309 printf(" ATA/ATAPI-%u", i);
1313 #endif /* __NEW_HD_DRIVE_ID */
1314 printf("\n\n * current active mode\n\n");
1318 static void flush_buffer_cache(/*int fd*/ void)
1320 fsync(fd); /* flush buffers */
1321 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1322 #ifdef HDIO_DRIVE_CMD
1324 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1325 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1326 bb_perror_msg("HDIO_DRIVE_CMD");
1328 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1333 static void seek_to_zero(/*int fd*/ void)
1335 xlseek(fd, (off_t) 0, SEEK_SET);
1338 static void read_big_block(/*int fd,*/ char *buf)
1342 xread(fd, buf, TIMING_BUF_BYTES);
1343 /* access all sectors of buf to ensure the read fully completed */
1344 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1348 static unsigned dev_size_mb(/*int fd*/ void)
1351 unsigned long long blksize64;
1355 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1356 u.blksize64 /= (1024 * 1024);
1358 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1359 u.blksize64 = u.blksize32 / (2 * 1024);
1361 if (u.blksize64 > UINT_MAX)
1366 static void print_timing(unsigned m, unsigned elapsed_us)
1368 unsigned sec = elapsed_us / 1000000;
1369 unsigned hs = (elapsed_us % 1000000) / 10000;
1371 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1373 /* "| 1" prevents div-by-0 */
1374 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1375 // ~= (m * 1024) / (elapsed_us / 1000000)
1376 // = kb / elapsed_sec
1380 static void do_time(int cache /*,int fd*/)
1381 /* cache=1: time cache: repeatedly read N MB at offset 0
1382 * cache=0: time device: linear read, starting at offset 0
1385 unsigned max_iterations, iterations;
1386 unsigned start; /* doesn't need to be long long */
1387 unsigned elapsed, elapsed2;
1389 char *buf = xmalloc(TIMING_BUF_BYTES);
1391 if (mlock(buf, TIMING_BUF_BYTES))
1392 bb_perror_msg_and_die("mlock");
1394 /* Clear out the device request queues & give them time to complete.
1395 * NB: *small* delay. User is expected to have a clue and to not run
1396 * heavy io in parallel with measurements. */
1399 if (cache) { /* Time cache */
1401 read_big_block(buf);
1402 printf("Timing buffer-cache reads: ");
1403 } else { /* Time device */
1404 printf("Timing buffered disk reads:");
1408 /* Now do the timing */
1410 /* Max time to run (small for cache, avoids getting
1411 * huge total_MB which can overlow unsigned type) */
1412 elapsed2 = 510000; /* cache */
1413 max_iterations = UINT_MAX;
1415 elapsed2 = 3000000; /* not cache */
1416 /* Don't want to read past the end! */
1417 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1419 start = monotonic_us();
1423 read_big_block(buf);
1424 elapsed = (unsigned)monotonic_us() - start;
1426 } while (elapsed < elapsed2 && iterations < max_iterations);
1427 total_MB = iterations * TIMING_BUF_MB;
1428 //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1430 /* Cache: remove lseek() and monotonic_us() overheads
1432 start = monotonic_us();
1435 elapsed2 = (unsigned)monotonic_us() - start;
1436 } while (--iterations);
1437 //printf(" elapsed2:%u ", elapsed2);
1438 elapsed -= elapsed2;
1439 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1440 flush_buffer_cache();
1442 print_timing(total_MB, elapsed);
1443 munlock(buf, TIMING_BUF_BYTES);
1447 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1448 static void bus_state_value(unsigned value)
1450 if (value == BUSSTATE_ON)
1452 else if (value == BUSSTATE_OFF)
1454 else if (value == BUSSTATE_TRISTATE)
1455 printf(" (tristate)\n");
1457 printf(" (unknown: %d)\n", value);
1461 #ifdef HDIO_DRIVE_CMD
1462 static void interpret_standby(uint8_t standby)
1467 } else if (standby <= 240 || standby == 252 || standby == 255) {
1468 /* standby is in 5 sec units */
1469 unsigned t = standby * 5;
1470 printf("%u minutes %u seconds", t / 60, t % 60);
1471 } else if (standby <= 251) {
1472 unsigned t = (standby - 240); /* t is in 30 min units */;
1473 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0');
1476 printf("vendor-specific");
1482 static const uint8_t xfermode_val[] ALIGN1 = {
1483 8, 9, 10, 11, 12, 13, 14, 15,
1484 16, 17, 18, 19, 20, 21, 22, 23,
1485 32, 33, 34, 35, 36, 37, 38, 39,
1486 64, 65, 66, 67, 68, 69, 70, 71
1488 /* NB: we save size by _not_ storing terninating NUL! */
1489 static const char xfermode_name[][5] ALIGN1 = {
1490 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1491 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1492 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1493 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1496 static int translate_xfermode(const char *name)
1501 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1502 if (!strncmp(name, xfermode_name[i], 5))
1503 if (strlen(name) <= 5)
1504 return xfermode_val[i];
1506 /* Negative numbers are invalid and are caught later */
1507 val = bb_strtoi(name, NULL, 10);
1513 static void interpret_xfermode(unsigned xfermode)
1517 printf("default PIO mode");
1518 else if (xfermode == 1)
1519 printf("default PIO mode, disable IORDY");
1520 else if (xfermode >= 8 && xfermode <= 15)
1521 printf("PIO flow control mode%u", xfermode - 8);
1522 else if (xfermode >= 16 && xfermode <= 23)
1523 printf("singleword DMA mode%u", xfermode - 16);
1524 else if (xfermode >= 32 && xfermode <= 39)
1525 printf("multiword DMA mode%u", xfermode - 32);
1526 else if (xfermode >= 64 && xfermode <= 71)
1527 printf("UltraDMA mode%u", xfermode - 64);
1532 #endif /* HDIO_DRIVE_CMD */
1534 static void print_flag(int flag, const char *s, unsigned long value)
1537 printf(" setting %s to %ld\n", s, value);
1540 static void process_dev(char *devname)
1543 long parm, multcount;
1544 #ifndef HDIO_DRIVE_CMD
1545 int force_operation = 0;
1547 /* Please restore args[n] to these values after each ioctl
1548 except for args[2] */
1549 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1550 const char *fmt = " %s\t= %2ld";
1552 /*fd = xopen(devname, O_RDONLY | O_NONBLOCK);*/
1553 xmove_fd(xopen(devname, O_RDONLY | O_NONBLOCK), fd);
1554 printf("\n%s:\n", devname);
1556 if (getset_readahead == IS_SET) {
1557 print_flag(getset_readahead, "fs readahead", Xreadahead);
1558 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1560 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1561 if (unregister_hwif) {
1562 printf(" attempting to unregister hwif#%lu\n", hwif);
1563 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1566 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1567 if (scan_hwif == IS_SET) {
1568 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1569 args[0] = hwif_data;
1570 args[1] = hwif_ctrl;
1572 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1573 args[0] = WIN_SETFEATURES;
1578 if (noisy_piomode) {
1579 printf(" attempting to ");
1581 printf("auto-tune PIO mode\n");
1582 else if (piomode < 100)
1583 printf("set PIO mode to %d\n", piomode);
1584 else if (piomode < 200)
1585 printf("set MDMA mode to %d\n", (piomode-100));
1587 printf("set UDMA mode to %d\n", (piomode-200));
1589 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1591 if (getset_io32bit == IS_SET) {
1592 print_flag(getset_io32bit, "32-bit IO_support flag", io32bit);
1593 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1595 if (getset_mult == IS_SET) {
1596 print_flag(getset_mult, "multcount", mult);
1597 #ifdef HDIO_DRIVE_CMD
1598 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1600 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1603 if (getset_readonly == IS_SET) {
1604 print_flag_on_off(getset_readonly, "readonly", readonly);
1605 ioctl_or_warn(fd, BLKROSET, &readonly);
1607 if (getset_unmask == IS_SET) {
1608 print_flag_on_off(getset_unmask, "unmaskirq", unmask);
1609 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1611 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1612 if (getset_dma == IS_SET) {
1613 print_flag_on_off(getset_dma, "using_dma", dma);
1614 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1616 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1617 #ifdef HDIO_SET_QDMA
1618 if (getset_dma_q == IS_SET) {
1619 print_flag_on_off(getset_dma_q, "DMA queue_depth", dma_q);
1620 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1623 if (getset_nowerr == IS_SET) {
1624 print_flag_on_off(getset_nowerr, "nowerr", nowerr);
1625 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1627 if (getset_keep == IS_SET) {
1628 print_flag_on_off(getset_keep, "keep_settings", keep);
1629 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1631 #ifdef HDIO_DRIVE_CMD
1632 if (getset_doorlock == IS_SET) {
1633 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1635 print_flag_on_off(getset_doorlock, "drive doorlock", doorlock);
1636 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1637 args[0] = WIN_SETFEATURES;
1639 if (getset_dkeep == IS_SET) {
1640 /* lock/unlock the drive's "feature" settings */
1641 print_flag_on_off(getset_dkeep, "drive keep features", dkeep);
1642 args[2] = dkeep ? 0x66 : 0xcc;
1643 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1645 if (getset_defects == IS_SET) {
1646 args[2] = defects ? 0x04 : 0x84;
1647 print_flag(getset_defects, "drive defect-mgmt", defects);
1648 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1650 if (getset_prefetch == IS_SET) {
1653 print_flag(getset_prefetch, "drive prefetch", prefetch);
1654 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1658 args[1] = xfermode_requested;
1660 print_flag(1, "xfermode", xfermode_requested);
1661 interpret_xfermode(xfermode_requested);
1662 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1665 if (getset_lookahead == IS_SET) {
1666 args[2] = lookahead ? 0xaa : 0x55;
1667 print_flag_on_off(getset_lookahead, "drive read-lookahead", lookahead);
1668 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1670 if (getset_apmmode == IS_SET) {
1671 /* feature register */
1672 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */;
1673 args[1] = apmmode; /* sector count register 1-255 */
1674 printf(" setting APM level to %s 0x%02lX (%ld)\n",
1675 (apmmode == 255) ? "disabled" : "",
1677 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1680 if (getset_wcache == IS_SET) {
1681 #ifdef DO_FLUSHCACHE
1682 #ifndef WIN_FLUSHCACHE
1683 #define WIN_FLUSHCACHE 0xe7
1685 #endif /* DO_FLUSHCACHE */
1686 args[2] = wcache ? 0x02 : 0x82;
1687 print_flag_on_off(getset_wcache, "drive write-caching", wcache);
1688 #ifdef DO_FLUSHCACHE
1690 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1691 #endif /* DO_FLUSHCACHE */
1692 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1693 #ifdef DO_FLUSHCACHE
1695 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1696 #endif /* DO_FLUSHCACHE */
1699 /* In code below, we do not preserve args[0], but the rest
1700 is preserved, including args[2] */
1703 if (set_standbynow) {
1704 #ifndef WIN_STANDBYNOW1
1705 #define WIN_STANDBYNOW1 0xE0
1707 #ifndef WIN_STANDBYNOW2
1708 #define WIN_STANDBYNOW2 0x94
1710 printf(" issuing standby command\n");
1711 args[0] = WIN_STANDBYNOW1;
1712 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1715 #ifndef WIN_SLEEPNOW1
1716 #define WIN_SLEEPNOW1 0xE6
1718 #ifndef WIN_SLEEPNOW2
1719 #define WIN_SLEEPNOW2 0x99
1721 printf(" issuing sleep command\n");
1722 args[0] = WIN_SLEEPNOW1;
1723 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1727 printf(" disabling Seagate auto powersaving mode\n");
1728 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1730 if (getset_standby == IS_SET) {
1731 args[0] = WIN_SETIDLE1;
1732 args[1] = standby_requested;
1733 print_flag(1, "standby", standby_requested);
1734 interpret_standby(standby_requested);
1735 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1738 #else /* HDIO_DRIVE_CMD */
1739 if (force_operation) {
1741 flush_buffer_cache();
1742 if (-1 == read(fd, buf, sizeof(buf)))
1743 bb_perror_msg("read of 512 bytes failed");
1745 #endif /* HDIO_DRIVE_CMD */
1746 if (getset_mult || get_identity) {
1748 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1749 /* To be coherent with ioctl_or_warn. */
1750 if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1751 bb_perror_msg("HDIO_GET_MULTCOUNT");
1753 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1754 } else if (getset_mult) {
1755 printf(fmt, "multcount", multcount);
1756 on_off(multcount != 0);
1759 if (getset_io32bit) {
1760 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1761 printf(" IO_support\t=%3ld (", parm);
1763 printf("default 16-bit)\n");
1765 printf("16-bit)\n");
1767 printf("32-bit)\n");
1769 printf("32-bit w/sync)\n");
1771 printf("Request-Queue-Bypass)\n");
1773 printf("\?\?\?)\n");
1776 if (getset_unmask) {
1777 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
1778 print_value_on_off("unmaskirq", parm);
1780 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1782 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1783 printf(fmt, "using_dma", parm);
1785 printf(" (DMA-Assisted-PIO)\n");
1791 #ifdef HDIO_GET_QDMA
1793 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
1794 print_value_on_off("queue_depth", parm);
1798 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
1799 print_value_on_off("keepsettings", parm);
1801 if (getset_nowerr) {
1802 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
1803 print_value_on_off("nowerr", parm);
1805 if (getset_readonly) {
1806 if (!ioctl_or_warn(fd, BLKROGET, &parm))
1807 print_value_on_off("readonly", parm);
1809 if (getset_readahead) {
1810 if (!ioctl_or_warn(fd, BLKRAGET, &parm))
1811 print_value_on_off("readahead", parm);
1814 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1815 struct hd_geometry g;
1817 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1818 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1819 g.cylinders, g.heads, g.sectors, parm, g.start);
1822 #ifdef HDIO_DRIVE_CMD
1823 if (get_powermode) {
1824 #ifndef WIN_CHECKPOWERMODE1
1825 #define WIN_CHECKPOWERMODE1 0xE5
1827 #ifndef WIN_CHECKPOWERMODE2
1828 #define WIN_CHECKPOWERMODE2 0x98
1832 args[0] = WIN_CHECKPOWERMODE1;
1833 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1834 if (errno != EIO || args[0] != 0 || args[1] != 0)
1839 state = (args[2] == 255) ? "active/idle" : "standby";
1840 args[1] = args[2] = 0;
1842 printf(" drive state is: %s\n", state);
1845 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1846 if (perform_reset) {
1847 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1849 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1850 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1851 if (perform_tristate) {
1854 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1856 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1857 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1859 struct hd_driveid id;
1861 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1862 if (multcount != -1) {
1863 id.multsect = multcount;
1864 id.multsect_valid |= 1;
1866 id.multsect_valid &= ~1;
1868 } else if (errno == -ENOMSG)
1869 printf(" no identification info available\n");
1870 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1871 bb_perror_msg("HDIO_GET_IDENTITY");
1873 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1877 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1879 memset(args1, 0, sizeof(args1));
1880 args1[0] = WIN_IDENTIFY;
1882 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1883 identify((void *)(args1 + 4));
1886 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1887 if (getset_busstate == IS_SET) {
1888 print_flag(1, "bus state", busstate);
1889 bus_state_value(busstate);
1890 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1892 if (getset_busstate) {
1893 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1894 printf(fmt, "bus state", parm);
1895 bus_state_value(parm);
1900 ioctl_or_warn(fd, BLKRRPART, NULL);
1903 do_time(1 /*,fd*/); /* time cache */
1905 do_time(0 /*,fd*/); /* time device */
1907 flush_buffer_cache();
1911 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1912 static int fromhex(unsigned char c)
1916 if (c >= 'a' && c <= 'f')
1917 return (c - ('a' - 10));
1918 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1921 static void identify_from_stdin(void) NORETURN;
1922 static void identify_from_stdin(void)
1925 unsigned char buf[1280];
1926 unsigned char *b = (unsigned char *)buf;
1929 xread(STDIN_FILENO, buf, 1280);
1931 // Convert the newline-separated hex data into an identify block.
1933 for (i = 0; i < 256; i++) {
1935 for (j = 0; j < 4; j++)
1936 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1944 void identify_from_stdin(void);
1947 /* busybox specific stuff */
1948 static int parse_opts(unsigned long *value, int min, int max)
1951 *value = xatol_range(optarg, min, max);
1956 static int parse_opts_0_max(unsigned long *value, int max)
1958 return parse_opts(value, 0, max);
1960 static int parse_opts_0_1(unsigned long *value)
1962 return parse_opts(value, 0, 1);
1964 static int parse_opts_0_INTMAX(unsigned long *value)
1966 return parse_opts(value, 0, INT_MAX);
1969 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
1974 *value = translate_xfermode(optarg);
1975 *set = (*value > -1);
1980 /*------- getopt short options --------*/
1981 static const char hdparm_options[] ALIGN1 =
1982 "gfu::n::p:r::m::c::k::a::B:tT"
1983 IF_FEATURE_HDPARM_GET_IDENTITY("iI")
1984 IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
1985 #ifdef HDIO_DRIVE_CMD
1986 "S:D:P:X:K:A:L:W:CyYzZ"
1988 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
1989 #ifdef HDIO_GET_QDMA
1990 #ifdef HDIO_SET_QDMA
1996 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
1997 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
1998 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
1999 /*-------------------------------------*/
2001 /* our main() routine: */
2002 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2003 int hdparm_main(int argc, char **argv)
2008 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2010 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2011 IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2012 get_geom |= (c == 'g');
2013 do_flush |= (c == 'f');
2014 if (c == 'u') getset_unmask = parse_opts_0_1(&unmask);
2015 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
2016 if (c == 'd') getset_dma = parse_opts_0_max(&dma, 9);
2018 if (c == 'n') getset_nowerr = parse_opts_0_1(&nowerr);
2019 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2020 if (c == 'r') getset_readonly = parse_opts_0_1(&readonly);
2021 if (c == 'm') getset_mult = parse_opts_0_INTMAX(&mult /*32*/);
2022 if (c == 'c') getset_io32bit = parse_opts_0_INTMAX(&io32bit /*8*/);
2023 if (c == 'k') getset_keep = parse_opts_0_1(&keep);
2024 if (c == 'a') getset_readahead = parse_opts_0_INTMAX(&Xreadahead);
2025 if (c == 'B') getset_apmmode = parse_opts(&apmmode, 1, 255);
2026 do_flush |= do_timings |= (c == 't');
2027 do_flush |= do_ctimings |= (c == 'T');
2028 #ifdef HDIO_DRIVE_CMD
2029 if (c == 'S') getset_standby = parse_opts_0_max(&standby_requested, 255);
2030 if (c == 'D') getset_defects = parse_opts_0_INTMAX(&defects);
2031 if (c == 'P') getset_prefetch = parse_opts_0_INTMAX(&prefetch);
2032 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2033 if (c == 'K') getset_dkeep = parse_opts_0_1(&prefetch);
2034 if (c == 'A') getset_lookahead = parse_opts_0_1(&lookahead);
2035 if (c == 'L') getset_doorlock = parse_opts_0_1(&doorlock);
2036 if (c == 'W') getset_wcache = parse_opts_0_1(&wcache);
2037 get_powermode |= (c == 'C');
2038 set_standbynow |= (c == 'y');
2039 set_sleepnow |= (c == 'Y');
2040 reread_partn |= (c == 'z');
2041 set_seagate |= (c == 'Z');
2043 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') unregister_hwif = parse_opts_0_INTMAX(&hwif));
2044 #ifdef HDIO_GET_QDMA
2046 getset_dma_q = parse_opts_0_INTMAX(&dma_q);
2049 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2050 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') perform_tristate = parse_opts_0_1(&tristate));
2051 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') getset_busstate = parse_opts_0_max(&busstate, 2));
2052 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2054 scan_hwif = parse_opts_0_INTMAX(&hwif_data);
2055 hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
2056 hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
2057 /* Move past the 2 additional arguments */
2063 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2065 getset_mult = getset_io32bit = getset_unmask = getset_keep = getset_readonly = getset_readahead = get_geom = IS_GET;
2066 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(getset_dma = IS_GET);
2071 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2072 identify_from_stdin(); /* EXIT */
2077 process_dev(*argv++);
2080 return EXIT_SUCCESS;