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
16 #include <linux/hdreg.h>
21 #define ATA_DEV 0x0000
22 #define ATAPI_DEV 0x0001
24 /* word definitions */
25 /* ---------------- */
26 #define GEN_CONFIG 0 /* general configuration */
27 #define LCYLS 1 /* number of logical cylinders */
28 #define CONFIG 2 /* specific configuration */
29 #define LHEADS 3 /* number of logical heads */
30 #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
31 #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
32 #define LSECTS 6 /* number of logical sectors/track */
33 #define START_SERIAL 10 /* ASCII serial number */
34 #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
35 #define BUF_TYPE 20 /* buffer type (ATA-1) */
36 #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
37 #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
38 #define START_FW_REV 23 /* ASCII firmware revision */
39 #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
40 #define START_MODEL 27 /* ASCII model number */
41 #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
42 #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
43 #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
44 #define CAPAB_0 49 /* capabilities */
46 #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
47 #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
48 #define WHATS_VALID 53 /* what fields are valid */
49 #define LCYLS_CUR 54 /* current logical cylinders */
50 #define LHEADS_CUR 55 /* current logical heads */
51 #define LSECTS_CUR 56 /* current logical sectors/track */
52 #define CAPACITY_LSB 57 /* current capacity in sectors */
53 #define CAPACITY_MSB 58
54 #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
55 #define LBA_SECTS_LSB 60 /* LBA: total number of user */
56 #define LBA_SECTS_MSB 61 /* addressable sectors */
57 #define SINGLE_DMA 62 /* singleword DMA modes */
58 #define MULTI_DMA 63 /* multiword DMA modes */
59 #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
60 /* multiword DMA xfer cycle time: */
61 #define DMA_TIME_MIN 65 /* - minimum */
62 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
63 /* minimum PIO xfer cycle time: */
64 #define PIO_NO_FLOW 67 /* - without flow control */
65 #define PIO_FLOW 68 /* - with IORDY flow control */
66 #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
67 #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
68 #define CDR_MAJOR 73 /* CD ROM: major version number */
69 #define CDR_MINOR 74 /* CD ROM: minor version number */
70 #define QUEUE_DEPTH 75 /* queue depth */
71 #define MAJOR 80 /* major version number */
72 #define MINOR 81 /* minor version number */
73 #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
74 #define CMDS_SUPP_1 83
75 #define CMDS_SUPP_2 84
76 #define CMDS_EN_0 85 /* command/feature set(s) enabled */
79 #define ULTRA_DMA 88 /* ultra DMA modes */
80 /* time to complete security erase */
81 #define ERASE_TIME 89 /* - ordinary */
82 #define ENH_ERASE_TIME 90 /* - enhanced */
83 #define ADV_PWR 91 /* current advanced power management level
84 in low byte, 0x40 in high byte. */
85 #define PSWD_CODE 92 /* master password revision code */
86 #define HWRST_RSLT 93 /* hardware reset result */
87 #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
88 #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
89 #define LBA_MID 101 /* bits are used, but addr 103 */
90 #define LBA_48_MSB 102 /* has been reserved for LBA in */
91 #define LBA_64_MSB 103 /* the future. */
92 #define RM_STAT 127 /* removable media status notification feature set support */
93 #define SECU_STATUS 128 /* security status */
94 #define CFA_PWR_MODE 160 /* CFA power mode 1 */
95 #define START_MEDIA 176 /* media serial number */
96 #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
97 #define START_MANUF 196 /* media manufacturer I.D. */
98 #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
99 #define INTEGRITY 255 /* integrity word */
101 /* bit definitions within the words */
102 /* -------------------------------- */
104 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
106 #define VALID_VAL 0x4000
107 /* many words are considered invalid if they are either all-0 or all-1 */
108 #define NOVAL_0 0x0000
109 #define NOVAL_1 0xffff
111 /* word 0: gen_config */
112 #define NOT_ATA 0x8000
113 #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
114 #define MEDIA_REMOVABLE 0x0080
115 #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
116 #define INCOMPLETE 0x0004
117 #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
118 #define DRQ_RESPONSE_TIME 0x0060
119 #define DRQ_3MS_VAL 0x0000
120 #define DRQ_INTR_VAL 0x0020
121 #define DRQ_50US_VAL 0x0040
122 #define PKT_SIZE_SUPPORTED 0x0003
123 #define PKT_SIZE_12_VAL 0x0000
124 #define PKT_SIZE_16_VAL 0x0001
125 #define EQPT_TYPE 0x1f00
130 /* word 1: number of logical cylinders */
131 #define LCYLS_MAX 0x3fff /* maximum allowable value */
133 /* word 2: specific configuration
134 * (a) require SET FEATURES to spin-up
135 * (b) require spin-up to fully reply to IDENTIFY DEVICE
137 #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
138 #define STBY_ID_VAL 0x738c /* (a) and not (b) */
139 #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
140 #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
142 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
143 #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
144 #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
146 /* word 49: capabilities 0 */
147 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
148 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
149 #define IORDY_OFF 0x0400 /* 1=may be disabled */
150 #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
151 #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
152 #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
153 #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
154 #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
155 #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
157 /* word 50: capabilities 1 */
158 #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
160 /* words 51 & 52: PIO & DMA cycle times */
161 #define MODE 0xff00 /* the mode is in the MSBs */
163 /* word 53: whats_valid */
164 #define OK_W88 0x0004 /* the ultra_dma info is valid */
165 #define OK_W64_70 0x0002 /* see above for word descriptions */
166 #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
168 /*word 63,88: dma_mode, ultra_dma_mode*/
169 #define MODE_MAX 7 /* bit definitions force udma <=7 (when
170 * udma >=8 comes out it'll have to be
171 * defined in a new dma_mode word!) */
173 /* word 64: PIO transfer modes */
174 #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
175 #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
177 /* word 75: queue_depth */
178 #define DEPTH_BITS 0x001f /* bits used for queue depth */
180 /* words 80-81: version numbers */
181 /* NOVAL_0 or NOVAL_1 means device does not report version */
183 /* word 81: minor version number */
184 #define MINOR_MAX 0x22
185 /* words 82-84: cmds/feats supported */
186 #define CMDS_W82 0x77ff /* word 82: defined command locations*/
187 #define CMDS_W83 0x3fff /* word 83: defined command locations*/
188 #define CMDS_W84 0x002f /* word 83: defined command locations*/
189 #define SUPPORT_48_BIT 0x0400
190 #define NUM_CMD_FEAT_STR 48
192 /* words 85-87: cmds/feats enabled */
193 /* use cmd_feat_str[] to display what commands and features have
194 * been enabled with words 85-87
197 /* words 89, 90, SECU ERASE TIME */
198 #define ERASE_BITS 0x00ff
200 /* word 92: master password revision */
201 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
203 /* word 93: hw reset result */
204 #define CBLID 0x2000 /* CBLID status */
205 #define RST0 0x0001 /* 1=reset to device #0 */
206 #define DEV_DET 0x0006 /* how device num determined */
207 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
208 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
210 /* word 127: removable media status notification feature set support */
211 #define RM_STAT_BITS 0x0003
212 #define RM_STAT_SUP 0x0001
214 /* word 128: security */
215 #define SECU_ENABLED 0x0002
216 #define SECU_LEVEL 0x0010
217 #define NUM_SECU_STR 6
219 /* word 160: CFA power mode */
220 #define VALID_W160 0x8000 /* 1=word valid */
221 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
222 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
223 #define MAX_AMPS 0x0fff /* value = max current in ma */
225 /* word 255: integrity */
226 #define SIG 0x00ff /* signature location */
227 #define SIG_VAL 0x00a5 /* signature value */
229 #define TIMING_BUF_MB 1
230 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
232 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
239 smallint get_identity, get_geom;
241 smallint do_ctimings, do_timings;
242 smallint reread_partn;
243 smallint set_piomode, noisy_piomode;
244 smallint set_readahead, get_readahead;
245 smallint set_readonly, get_readonly;
246 smallint set_unmask, get_unmask;
247 smallint set_mult, get_mult;
248 smallint set_dma_q, get_dma_q;
249 smallint set_nowerr, get_nowerr;
250 smallint set_keep, get_keep;
251 smallint set_io32bit, get_io32bit;
253 unsigned long Xreadahead;
254 unsigned long readonly;
255 unsigned long unmask;
258 unsigned long nowerr;
260 unsigned long io32bit;
261 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
263 smallint set_dma, get_dma;
265 #ifdef HDIO_DRIVE_CMD
266 smallint set_xfermode, get_xfermode;
267 smallint set_dkeep, get_dkeep;
268 smallint set_standby, get_standby;
269 smallint set_lookahead, get_lookahead;
270 smallint set_prefetch, get_prefetch;
271 smallint set_defects, get_defects;
272 smallint set_wcache, get_wcache;
273 smallint set_doorlock, get_doorlock;
274 smallint set_seagate, get_seagate;
275 smallint set_standbynow, get_standbynow;
276 smallint set_sleepnow, get_sleepnow;
277 smallint get_powermode;
278 smallint set_apmmode, get_apmmode;
279 int xfermode_requested;
281 unsigned long standby_requested;
282 unsigned long lookahead;
283 unsigned long prefetch;
284 unsigned long defects;
285 unsigned long wcache;
286 unsigned long doorlock;
287 unsigned long apmmode;
289 USE_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
290 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint set_busstate, get_busstate;)
291 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
292 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
293 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
294 USE_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
295 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
296 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
297 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
298 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
299 unsigned long hwif_data;
300 unsigned long hwif_ctrl;
301 unsigned long hwif_irq;
304 unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
307 #define G (*(struct globals*)&bb_common_bufsiz1)
308 struct BUG_G_too_big {
309 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
311 #define get_identity (G.get_identity )
312 #define get_geom (G.get_geom )
313 #define do_flush (G.do_flush )
314 #define do_ctimings (G.do_ctimings )
315 #define do_timings (G.do_timings )
316 #define reread_partn (G.reread_partn )
317 #define set_piomode (G.set_piomode )
318 #define noisy_piomode (G.noisy_piomode )
319 #define set_readahead (G.set_readahead )
320 #define get_readahead (G.get_readahead )
321 #define set_readonly (G.set_readonly )
322 #define get_readonly (G.get_readonly )
323 #define set_unmask (G.set_unmask )
324 #define get_unmask (G.get_unmask )
325 #define set_mult (G.set_mult )
326 #define get_mult (G.get_mult )
327 #define set_dma_q (G.set_dma_q )
328 #define get_dma_q (G.get_dma_q )
329 #define set_nowerr (G.set_nowerr )
330 #define get_nowerr (G.get_nowerr )
331 #define set_keep (G.set_keep )
332 #define get_keep (G.get_keep )
333 #define set_io32bit (G.set_io32bit )
334 #define get_io32bit (G.get_io32bit )
335 #define piomode (G.piomode )
336 #define Xreadahead (G.Xreadahead )
337 #define readonly (G.readonly )
338 #define unmask (G.unmask )
339 #define mult (G.mult )
340 #define dma_q (G.dma_q )
341 #define nowerr (G.nowerr )
342 #define keep (G.keep )
343 #define io32bit (G.io32bit )
345 #define set_dma (G.set_dma )
346 #define get_dma (G.get_dma )
347 #define set_xfermode (G.set_xfermode )
348 #define get_xfermode (G.get_xfermode )
349 #define set_dkeep (G.set_dkeep )
350 #define get_dkeep (G.get_dkeep )
351 #define set_standby (G.set_standby )
352 #define get_standby (G.get_standby )
353 #define set_lookahead (G.set_lookahead )
354 #define get_lookahead (G.get_lookahead )
355 #define set_prefetch (G.set_prefetch )
356 #define get_prefetch (G.get_prefetch )
357 #define set_defects (G.set_defects )
358 #define get_defects (G.get_defects )
359 #define set_wcache (G.set_wcache )
360 #define get_wcache (G.get_wcache )
361 #define set_doorlock (G.set_doorlock )
362 #define get_doorlock (G.get_doorlock )
363 #define set_seagate (G.set_seagate )
364 #define get_seagate (G.get_seagate )
365 #define set_standbynow (G.set_standbynow )
366 #define get_standbynow (G.get_standbynow )
367 #define set_sleepnow (G.set_sleepnow )
368 #define get_sleepnow (G.get_sleepnow )
369 #define get_powermode (G.get_powermode )
370 #define set_apmmode (G.set_apmmode )
371 #define get_apmmode (G.get_apmmode )
372 #define xfermode_requested (G.xfermode_requested )
373 #define dkeep (G.dkeep )
374 #define standby_requested (G.standby_requested )
375 #define lookahead (G.lookahead )
376 #define prefetch (G.prefetch )
377 #define defects (G.defects )
378 #define wcache (G.wcache )
379 #define doorlock (G.doorlock )
380 #define apmmode (G.apmmode )
381 #define get_IDentity (G.get_IDentity )
382 #define set_busstate (G.set_busstate )
383 #define get_busstate (G.get_busstate )
384 #define perform_reset (G.perform_reset )
385 #define perform_tristate (G.perform_tristate )
386 #define unregister_hwif (G.unregister_hwif )
387 #define scan_hwif (G.scan_hwif )
388 #define busstate (G.busstate )
389 #define tristate (G.tristate )
390 #define hwif (G.hwif )
391 #define hwif_data (G.hwif_data )
392 #define hwif_ctrl (G.hwif_ctrl )
393 #define hwif_irq (G.hwif_irq )
396 /* Busybox messages and functions */
397 #if ENABLE_IOCTL_HEX2STR_ERROR
398 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
400 if (!ioctl(fd, cmd, args))
403 return bb_ioctl_or_warn(fd, cmd, args, string);
405 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
407 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
409 if (!ioctl(fd, cmd, args))
412 return bb_ioctl_or_warn(fd, cmd, args);
414 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
417 static void on_off(int value)
419 puts(value ? " (on)" : " (off)");
422 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
425 printf(" setting %s to %ld", s, arg);
430 static void print_value_on_off(const char *str, unsigned long argp)
432 printf(" %s\t= %2ld", str, argp);
436 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
437 static void print_ascii(const char *p, int length)
444 /* every 16bit word is big-endian (i.e. inverted) */
445 /* accessing bytes in 1,0, 3,2, 5,4... sequence */
450 /* find first non-space & print it */
451 while (length && p[ofs] != ' ') {
456 while (length && p[ofs]) {
466 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
469 printf("\t%-20s", string);
470 print_ascii((void*)&val[i], n);
474 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
479 for (ii = 0; ii <= MODE_MAX; ii++) {
480 if (mode_sel & 0x0001) {
481 printf("*%cdma%u ", cc, ii);
485 } else if (mode_sup & 0x0001)
486 printf("%cdma%u ", cc, ii);
494 static const char pkt_str[] ALIGN1 =
495 "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
496 "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
497 "Printer" "\0" /* word 0, bits 12-8 = 02 */
498 "Processor" "\0" /* word 0, bits 12-8 = 03 */
499 "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
500 "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
501 "Scanner" "\0" /* word 0, bits 12-8 = 06 */
502 "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
503 "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
504 "Communications device" "\0" /* word 0, bits 12-8 = 09 */
505 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
506 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
507 "Array controller" "\0" /* word 0, bits 12-8 = 0c */
508 "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
509 "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
510 "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
513 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
514 "reserved" "\0" /* bit 0 */
515 "hard sectored" "\0" /* bit 1 */
516 "soft sectored" "\0" /* bit 2 */
517 "not MFM encoded " "\0" /* bit 3 */
518 "head switch time > 15us" "\0" /* bit 4 */
519 "spindle motor control option" "\0" /* bit 5 */
520 "fixed drive" "\0" /* bit 6 */
521 "removable drive" "\0" /* bit 7 */
522 "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
523 "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
524 "disk xfer rate > 5Mbs" "\0" /* bit 10 */
525 "rotational speed tol." "\0" /* bit 11 */
526 "data strobe offset option" "\0" /* bit 12 */
527 "track offset option" "\0" /* bit 13 */
528 "format speed tolerance gap reqd" "\0" /* bit 14 */
532 static const char minor_str[] ALIGN1 =
534 "Unspecified" "\0" /* 0x0000 */
535 "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
536 "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
537 "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
538 "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
539 "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
540 "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
541 "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
542 "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
543 "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
544 "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
545 "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
546 "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
547 "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
548 "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
549 "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
550 "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
551 "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
552 "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
553 "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
554 "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
555 "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
556 "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
557 "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
558 "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
559 "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
560 "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
561 "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
562 "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
563 "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
564 "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
565 "reserved" "\0" /* 0x001f */
566 "reserved" "\0" /* 0x0020 */
567 "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
568 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
569 "reserved" /* 0x0023-0xfffe */
571 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
573 0, /* 0x0000 WARNING: actual_ver[] array */
574 1, /* 0x0001 WARNING: corresponds */
575 1, /* 0x0002 WARNING: *exactly* */
576 1, /* 0x0003 WARNING: to the ATA/ */
577 2, /* 0x0004 WARNING: ATAPI version */
578 2, /* 0x0005 WARNING: listed in */
579 3, /* 0x0006 WARNING: the */
580 2, /* 0x0007 WARNING: minor_str */
581 3, /* 0x0008 WARNING: array */
582 2, /* 0x0009 WARNING: above. */
583 3, /* 0x000a WARNING: */
584 3, /* 0x000b WARNING: If you change */
585 3, /* 0x000c WARNING: that one, */
586 4, /* 0x000d WARNING: change this one */
587 4, /* 0x000e WARNING: too!!! */
608 0 /* 0x0023-0xfffe */
611 static const char cmd_feat_str[] ALIGN1 =
612 "" "\0" /* word 82 bit 15: obsolete */
613 "NOP cmd" "\0" /* word 82 bit 14 */
614 "READ BUFFER cmd" "\0" /* word 82 bit 13 */
615 "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
616 "" "\0" /* word 82 bit 11: obsolete */
617 "Host Protected Area feature set" "\0" /* word 82 bit 10 */
618 "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
619 "SERVICE interrupt" "\0" /* word 82 bit 8 */
620 "Release interrupt" "\0" /* word 82 bit 7 */
621 "Look-ahead" "\0" /* word 82 bit 6 */
622 "Write cache" "\0" /* word 82 bit 5 */
623 "PACKET command feature set" "\0" /* word 82 bit 4 */
624 "Power Management feature set" "\0" /* word 82 bit 3 */
625 "Removable Media feature set" "\0" /* word 82 bit 2 */
626 "Security Mode feature set" "\0" /* word 82 bit 1 */
627 "SMART feature set" "\0" /* word 82 bit 0 */
629 "" "\0" /* word 83 bit 15: !valid bit */
630 "" "\0" /* word 83 bit 14: valid bit */
631 "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
632 "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
633 "Device Configuration Overlay feature set " "\0"
634 "48-bit Address feature set " "\0" /* word 83 bit 10 */
636 "SET MAX security extension" "\0" /* word 83 bit 8 */
637 "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
638 "SET FEATURES subcommand required to spinup after power up" "\0"
639 "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
640 "Removable Media Status Notification feature set" "\0"
641 "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
642 "CFA feature set" "\0" /* word 83 bit 2 */
643 "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
644 "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
646 "" "\0" /* word 84 bit 15: !valid bit */
647 "" "\0" /* word 84 bit 14: valid bit */
648 "" "\0" /* word 84 bit 13: reserved */
649 "" "\0" /* word 84 bit 12: reserved */
650 "" "\0" /* word 84 bit 11: reserved */
651 "" "\0" /* word 84 bit 10: reserved */
652 "" "\0" /* word 84 bit 9: reserved */
653 "" "\0" /* word 84 bit 8: reserved */
654 "" "\0" /* word 84 bit 7: reserved */
655 "" "\0" /* word 84 bit 6: reserved */
656 "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
657 "" "\0" /* word 84 bit 4: reserved */
658 "Media Card Pass Through Command feature set " "\0"
659 "Media serial number " "\0" /* word 84 bit 2 */
660 "SMART self-test " "\0" /* word 84 bit 1 */
661 "SMART error logging " /* word 84 bit 0 */
664 static const char secu_str[] ALIGN1 =
665 "supported" "\0" /* word 128, bit 0 */
666 "enabled" "\0" /* word 128, bit 1 */
667 "locked" "\0" /* word 128, bit 2 */
668 "frozen" "\0" /* word 128, bit 3 */
669 "expired: security count" "\0" /* word 128, bit 4 */
670 "supported: enhanced erase" /* word 128, bit 5 */
673 // Parse 512 byte disk identification block and print much crap.
674 static void identify(uint16_t *val) ATTRIBUTE_NORETURN;
675 static void identify(uint16_t *val)
678 uint16_t like_std = 1, std = 0, min_std = 0xffff;
679 uint16_t dev = NO_DEV, eqpt = NO_DEV;
680 uint8_t have_mode = 0, err_dma = 0;
682 uint32_t ll, mm, nn, oo;
683 uint64_t bbbig; /* (:) */
688 // Adjust for endianness
689 swab(val, buf, sizeof(buf));
692 /* check if we recognise the device type */
694 if (!(val[GEN_CONFIG] & NOT_ATA)) {
696 printf("ATA device, with ");
697 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
700 printf("CompactFlash ATA device, with ");
701 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
703 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
704 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
707 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
708 bb_error_msg_and_die("unknown device type");
710 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
711 /* Info from the specific configuration word says whether or not the
712 * ID command completed correctly. It is only defined, however in
713 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
714 * standards. Since the values allowed for this word are extremely
715 * specific, it should be safe to check it now, even though we don't
716 * know yet what standard this device is using.
718 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
719 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
722 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
723 printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
724 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
725 printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
728 /* output the model and serial numbers and the fw revision */
729 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
730 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
731 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
732 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
733 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
735 /* major & minor standards version number (Note: these words were not
736 * defined until ATA-3 & the CDROM std uses different words.) */
737 printf("Standards:");
739 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
740 if (like_std < 3) like_std = 3;
741 std = actual_ver[val[MINOR]];
742 if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
745 /* looks like when they up-issue the std, they obsolete one;
746 * thus, only the newest 4 issues need be supported. (That's
747 * what "kk" and "min_std" are all about.) */
748 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
749 printf("\n\tSupported: ");
750 jj = val[MAJOR] << 1;
751 kk = like_std >4 ? like_std-4: 0;
752 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
757 kk = like_std >4 ? like_std-4: 0;
759 if (min_std > ii) min_std = ii;
763 if (like_std < 3) like_std = 3;
765 /* Figure out what standard the device is using if it hasn't told
766 * us. If we know the std, check if the device is using any of
767 * the words from the next level up. It happens.
769 if (like_std < std) like_std = std;
771 if (((std == 5) || (!std && (like_std < 6))) &&
772 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
773 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
774 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
775 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
778 } else if (((std == 4) || (!std && (like_std < 5))) &&
779 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
780 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
781 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
782 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
785 } else if (((std == 3) || (!std && (like_std < 4))) &&
786 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
787 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
788 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
789 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
790 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
791 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
794 } else if (((std == 2) || (!std && (like_std < 3)))
795 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
798 } else if (((std == 1) || (!std && (like_std < 2))) &&
799 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
800 (val[WHATS_VALID] & OK_W64_70)) )
806 printf("\n\tLikely used: %u\n", like_std);
807 else if (like_std > std)
808 printf("& some of %u\n", like_std);
812 /* TBD: do CDROM stuff more thoroughly. For now... */
814 if (val[CDR_MINOR] == 9) {
816 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
818 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
820 printf("\n\tSupported: CD-ROM ATAPI");
821 jj = val[CDR_MAJOR] >> 1;
822 for (ii = 1; ii < 15; ii++) {
823 if (jj & 0x0001) printf("-%u ", ii);
827 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
828 /* the cdrom stuff is more like ATA-2 than anything else, so: */
832 if (min_std == 0xffff)
833 min_std = like_std > 4 ? like_std - 3 : 1;
835 printf("Configuration:\n");
836 /* more info from the general configuration word */
837 if ((eqpt != CDROM) && (like_std == 1)) {
838 jj = val[GEN_CONFIG] >> 1;
839 for (ii = 1; ii < 15; ii++) {
841 printf("\t%s\n", nth_string(ata1_cfg_str, ii));
845 if (dev == ATAPI_DEV) {
846 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
848 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
849 strng = "<=10ms with INTRQ";
850 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
854 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
856 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
858 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
864 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
865 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
867 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
868 printf("\tCHS addressing not supported\n");
870 jj = val[WHATS_VALID] & OK_W54_58;
871 printf("\tLogical\t\tmax\tcurrent\n\tcylinders\t%u\t%u\n\theads\t\t%u\t%u\n\tsectors/track\t%u\t%u\n\t--\n",
872 val[LCYLS],jj?val[LCYLS_CUR]:0, val[LHEADS],jj?val[LHEADS_CUR]:0, val[LSECTS],jj?val[LSECTS_CUR]:0);
874 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
875 printf("\tbytes/track: %u\tbytes/sector: %u\n", val[TRACK_BYTES], val[SECT_BYTES]);
878 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
880 /* check Endian of capacity bytes */
881 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
882 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
883 if (abs(mm - nn) > abs(oo - nn))
886 printf("\tCHS current addressable sectors:%11u\n", mm);
890 printf("\tLBA user addressable sectors:%11u\n", ll);
891 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
892 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
894 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
895 (uint64_t)val[LBA_48_MSB] << 32 |
896 (uint64_t)val[LBA_MID] << 16 |
898 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
902 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
903 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
904 bbbig = (bbbig << 9) / 1000000;
905 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
908 printf("(%"PRIu64" GB)\n", bbbig/1000);
913 /* hw support of commands (capabilities) */
914 printf("Capabilities:\n\t");
916 if (dev == ATAPI_DEV) {
917 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP)) printf("Cmd queuing, ");
918 if (val[CAPAB_0] & OVLP_SUP) printf("Cmd overlap, ");
920 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
923 printf("IORDY%s(can%s be disabled)\n",
924 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
925 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
927 printf("no IORDY\n");
929 if ((like_std == 1) && val[BUF_TYPE]) {
930 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
931 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
932 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
935 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
936 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
938 if ((min_std < 4) && (val[RW_LONG])) {
939 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
941 if ((eqpt != CDROM) && (like_std > 3)) {
942 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
945 if (dev == ATA_DEV) {
947 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
949 printf("\tStandby timer values: spec'd by %s", (val[CAPAB_0] & STD_STBY) ? "Standard" : "Vendor");
950 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
951 printf(", %s device specific minimum\n", (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
955 printf("\tR/W multiple sector transfer: ");
956 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
957 printf("not supported\n");
959 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
960 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
961 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
965 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
966 /* We print out elsewhere whether the APM feature is enabled or
967 not. If it's not enabled, let's not repeat the info; just print
969 printf("\tAdvancedPM level: ");
970 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
971 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
972 printf("%u (0x%x)\n", apm_level, apm_level);
975 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
977 if (like_std > 5 && val[ACOUSTIC]) {
978 printf("\tRecommended acoustic management value: %u, current value: %u\n",
979 (val[ACOUSTIC] >> 8) & 0x00ff, val[ACOUSTIC] & 0x00ff);
983 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
984 printf("\tATA sw reset required\n");
986 if (val[PKT_REL] || val[SVC_NBSY]) {
987 printf("\tOverlap support:");
988 if (val[PKT_REL]) printf(" %uus to release bus.", val[PKT_REL]);
989 if (val[SVC_NBSY]) printf(" %uus to clear BSY after SERVICE cmd.", val[SVC_NBSY]);
994 /* DMA stuff. Check that only one DMA mode is selected. */
996 if (!(val[CAPAB_0] & DMA_SUP))
997 printf("not supported\n");
999 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1000 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1001 if (val[SINGLE_DMA]) {
1002 jj = val[SINGLE_DMA];
1003 kk = val[SINGLE_DMA] >> 8;
1004 err_dma += mode_loop(jj, kk, 's', &have_mode);
1006 if (val[MULTI_DMA]) {
1007 jj = val[MULTI_DMA];
1008 kk = val[MULTI_DMA] >> 8;
1009 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1011 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1012 jj = val[ULTRA_DMA];
1013 kk = val[ULTRA_DMA] >> 8;
1014 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1016 if (err_dma || !have_mode) printf("(?)");
1019 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1020 printf("\t\tInterleaved DMA support\n");
1022 if ((val[WHATS_VALID] & OK_W64_70)
1023 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1025 printf("\t\tCycle time:");
1026 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1027 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1032 /* Programmed IO stuff */
1034 /* If a drive supports mode n (e.g. 3), it also supports all modes less
1035 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1036 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1037 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1038 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1039 if (jj & 0x0001) printf("pio%d ", ii);
1043 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1044 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1045 printf("pio%d ", ii);
1050 if (val[WHATS_VALID] & OK_W64_70) {
1051 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1052 printf("\t\tCycle time:");
1053 if (val[PIO_NO_FLOW]) printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1054 if (val[PIO_FLOW]) printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1059 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1060 printf("Commands/features:\n\tEnabled\tSupported:\n");
1061 jj = val[CMDS_SUPP_0];
1062 kk = val[CMDS_EN_0];
1063 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1064 const char *feat_str = nth_string(cmd_feat_str, ii);
1065 if ((jj & 0x8000) && (*feat_str != '\0')) {
1066 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
1070 if (ii % 16 == 15) {
1071 jj = val[CMDS_SUPP_0+1+(ii/16)];
1072 kk = val[CMDS_EN_0+1+(ii/16)];
1075 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1080 /* Removable Media Status Notification feature set */
1081 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1082 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1085 if ((eqpt != CDROM) && (like_std > 3)
1086 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1088 printf("Security:\n");
1089 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1090 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1091 jj = val[SECU_STATUS];
1093 for (ii = 0; ii < NUM_SECU_STR; ii++) {
1094 printf("\t%s\t%s\n", (!(jj & 0x0001)) ? "not" : "", nth_string(secu_str, ii));
1097 if (val[SECU_STATUS] & SECU_ENABLED) {
1098 printf("\tSecurity level %s\n", (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1101 jj = val[ERASE_TIME] & ERASE_BITS;
1102 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1105 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1106 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1112 jj = val[HWRST_RSLT];
1113 if ((jj & VALID) == VALID_VAL) {
1114 if (!(oo = (jj & RST0)))
1116 if ((jj & DEV_DET) == JUMPER_VAL)
1117 strng = " determined by the jumper";
1118 else if ((jj & DEV_DET) == CSEL_VAL)
1119 strng = " determined by CSEL";
1122 printf("HW reset results:\n\tCBLID- %s Vih\n\tDevice num = %i%s\n",
1123 (val[HWRST_RSLT] & CBLID) ? "above" : "below", !(oo), strng);
1126 /* more stuff from std 5 */
1127 if ((like_std > 4) && (eqpt != CDROM)) {
1128 if (val[CFA_PWR_MODE] & VALID_W160) {
1129 printf("CFA power mode 1:\n\t%s%s\n", (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1130 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1132 if (val[CFA_PWR_MODE] & MAX_AMPS)
1133 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1135 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1136 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1144 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1145 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1146 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1147 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1148 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1149 // (which they should, but they should just return -EINVAL).
1151 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1152 // On a really old system, it will not, and we will be confused.
1155 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1156 static const char cfg_str[] ALIGN1 =
1157 """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
1158 "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
1159 "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1160 "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
1163 static const char BuffType[] ALIGN1 =
1164 "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
1167 static void dump_identity(const struct hd_driveid *id)
1170 const unsigned short int *id_regs = (const void*) id;
1172 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1173 id->model, id->fw_rev, id->serial_no);
1174 for (i = 0; i <= 15; i++) {
1175 if (id->config & (1<<i))
1176 printf(" %s", nth_string(cfg_str, i));
1178 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1179 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1180 id->cyls, id->heads, id->sectors, id->track_bytes,
1181 id->sector_bytes, id->ecc_bytes,
1182 id->buf_type, nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1183 id->buf_size/2, id->max_multsect);
1184 if (id->max_multsect) {
1185 printf(", MultSect=");
1186 if (!(id->multsect_valid & 1))
1187 printf("?%u?", id->multsect);
1188 else if (id->multsect)
1189 printf("%u", id->multsect);
1195 if (!(id->field_valid & 1))
1196 printf(" (maybe):");
1198 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1201 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1202 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1203 ((id->capability&2) == 0) ? "no" : "yes");
1205 if (id->capability & 2)
1206 printf(", LBAsects=%u", id->lba_capacity);
1208 printf("\n IORDY=%s", (id->capability & 8) ? (id->capability & 4) ? "on/off" : "yes" : "no");
1210 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1211 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1213 if ((id->capability & 1) && (id->field_valid & 2))
1214 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1216 printf("\n PIO modes: ");
1217 if (id->tPIO <= 5) {
1219 if (id->tPIO >= 1) printf("pio1 ");
1220 if (id->tPIO >= 2) printf("pio2 ");
1222 if (id->field_valid & 2) {
1223 if (id->eide_pio_modes & 1) printf("pio3 ");
1224 if (id->eide_pio_modes & 2) printf("pio4 ");
1225 if (id->eide_pio_modes &~3) printf("pio? ");
1227 if (id->capability & 1) {
1228 if (id->dma_1word | id->dma_mword) {
1229 printf("\n DMA modes: ");
1230 if (id->dma_1word & 0x100) printf("*");
1231 if (id->dma_1word & 1) printf("sdma0 ");
1232 if (id->dma_1word & 0x200) printf("*");
1233 if (id->dma_1word & 2) printf("sdma1 ");
1234 if (id->dma_1word & 0x400) printf("*");
1235 if (id->dma_1word & 4) printf("sdma2 ");
1236 if (id->dma_1word & 0xf800) printf("*");
1237 if (id->dma_1word & 0xf8) printf("sdma? ");
1238 if (id->dma_mword & 0x100) printf("*");
1239 if (id->dma_mword & 1) printf("mdma0 ");
1240 if (id->dma_mword & 0x200) printf("*");
1241 if (id->dma_mword & 2) printf("mdma1 ");
1242 if (id->dma_mword & 0x400) printf("*");
1243 if (id->dma_mword & 4) printf("mdma2 ");
1244 if (id->dma_mword & 0xf800) printf("*");
1245 if (id->dma_mword & 0xf8) printf("mdma? ");
1248 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1249 printf("\n UDMA modes: ");
1250 if (id->dma_ultra & 0x100) printf("*");
1251 if (id->dma_ultra & 0x001) printf("udma0 ");
1252 if (id->dma_ultra & 0x200) printf("*");
1253 if (id->dma_ultra & 0x002) printf("udma1 ");
1254 if (id->dma_ultra & 0x400) printf("*");
1255 if (id->dma_ultra & 0x004) printf("udma2 ");
1256 #ifdef __NEW_HD_DRIVE_ID
1257 if (id->hw_config & 0x2000) {
1258 #else /* !__NEW_HD_DRIVE_ID */
1259 if (id->word93 & 0x2000) {
1260 #endif /* __NEW_HD_DRIVE_ID */
1261 if (id->dma_ultra & 0x0800) printf("*");
1262 if (id->dma_ultra & 0x0008) printf("udma3 ");
1263 if (id->dma_ultra & 0x1000) printf("*");
1264 if (id->dma_ultra & 0x0010) printf("udma4 ");
1265 if (id->dma_ultra & 0x2000) printf("*");
1266 if (id->dma_ultra & 0x0020) printf("udma5 ");
1267 if (id->dma_ultra & 0x4000) printf("*");
1268 if (id->dma_ultra & 0x0040) printf("udma6 ");
1269 if (id->dma_ultra & 0x8000) printf("*");
1270 if (id->dma_ultra & 0x0080) printf("udma7 ");
1273 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1274 if (id_regs[83] & 8) {
1275 if (!(id_regs[86] & 8))
1276 printf(": disabled (255)");
1277 else if ((id_regs[91] & 0xFF00) != 0x4000)
1278 printf(": unknown setting");
1280 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1282 if (id_regs[82] & 0x20)
1283 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1284 #ifdef __NEW_HD_DRIVE_ID
1285 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1286 || (id->major_rev_num && id->minor_rev_num <= 31)
1288 printf("\n Drive conforms to: %s: ", (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1289 if (id->major_rev_num != 0x0000 && /* NOVAL_0 */
1290 id->major_rev_num != 0xFFFF) { /* NOVAL_1 */
1291 for (i = 0; i <= 15; i++) {
1292 if (id->major_rev_num & (1<<i))
1293 printf(" ATA/ATAPI-%u", i);
1297 #endif /* __NEW_HD_DRIVE_ID */
1298 printf("\n\n * current active mode\n\n");
1302 static void flush_buffer_cache(/*int fd*/ void)
1304 fsync(fd); /* flush buffers */
1305 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1306 #ifdef HDIO_DRIVE_CMD
1308 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1309 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1310 bb_perror_msg("HDIO_DRIVE_CMD");
1312 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1317 static void seek_to_zero(/*int fd*/ void)
1319 xlseek(fd, (off_t) 0, SEEK_SET);
1322 static void read_big_block(/*int fd,*/ char *buf)
1326 xread(fd, buf, TIMING_BUF_BYTES);
1327 /* access all sectors of buf to ensure the read fully completed */
1328 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1332 static unsigned dev_size_mb(/*int fd*/ void)
1335 unsigned long long blksize64;
1339 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1340 u.blksize64 /= (1024 * 1024);
1342 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1343 u.blksize64 = u.blksize32 / (2 * 1024);
1345 if (u.blksize64 > UINT_MAX)
1350 static void print_timing(unsigned m, unsigned elapsed_us)
1352 unsigned sec = elapsed_us / 1000000;
1353 unsigned hs = (elapsed_us % 1000000) / 10000;
1355 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1357 /* "| 1" prevents div-by-0 */
1358 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1359 // ~= (m * 1024) / (elapsed_us / 1000000)
1360 // = kb / elapsed_sec
1364 static void do_time(int cache /*,int fd*/)
1365 /* cache=1: time cache: repeatedly read N MB at offset 0
1366 * cache=0: time device: linear read, starting at offset 0
1369 unsigned max_iterations, iterations;
1370 unsigned start; /* doesn't need to be long long */
1371 unsigned elapsed, elapsed2;
1373 char *buf = xmalloc(TIMING_BUF_BYTES);
1375 if (mlock(buf, TIMING_BUF_BYTES))
1376 bb_perror_msg_and_die("mlock");
1378 /* Clear out the device request queues & give them time to complete.
1379 * NB: *small* delay. User is expected to have a clue and to not run
1380 * heavy io in parallel with measurements. */
1383 if (cache) { /* Time cache */
1385 read_big_block(buf);
1386 printf("Timing buffer-cache reads: ");
1387 } else { /* Time device */
1388 printf("Timing buffered disk reads:");
1392 /* Now do the timing */
1394 /* Max time to run (small for cache, avoids getting
1395 * huge total_MB which can overlow unsigned type) */
1396 elapsed2 = 510000; /* cache */
1397 max_iterations = UINT_MAX;
1399 elapsed2 = 3000000; /* not cache */
1400 /* Don't want to read past the end! */
1401 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1403 start = monotonic_us();
1407 read_big_block(buf);
1408 elapsed = (unsigned)monotonic_us() - start;
1410 } while (elapsed < elapsed2 && iterations < max_iterations);
1411 total_MB = iterations * TIMING_BUF_MB;
1412 //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1414 /* Cache: remove lseek() and monotonic_us() overheads
1416 start = monotonic_us();
1419 elapsed2 = (unsigned)monotonic_us() - start;
1420 } while (--iterations);
1421 //printf(" elapsed2:%u ", elapsed2);
1422 elapsed -= elapsed2;
1423 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1424 flush_buffer_cache();
1426 print_timing(total_MB, elapsed);
1427 munlock(buf, TIMING_BUF_BYTES);
1431 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1432 static void bus_state_value(unsigned value)
1434 if (value == BUSSTATE_ON)
1436 else if (value == BUSSTATE_OFF)
1438 else if (value == BUSSTATE_TRISTATE)
1439 printf(" (tristate)\n");
1441 printf(" (unknown: %d)\n", value);
1445 #ifdef HDIO_DRIVE_CMD
1446 static void interpret_standby(unsigned standby)
1453 else if (standby == 252)
1454 printf("21 minutes");
1455 else if (standby == 253)
1456 printf("vendor-specific");
1457 else if (standby == 254)
1459 else if (standby == 255)
1460 printf("21 minutes + 15 seconds");
1461 else if (standby <= 240) {
1463 printf("%u minutes + %u seconds", t / 60, t % 60);
1464 } else if (standby <= 251) {
1465 t = (standby - 240) * 30;
1466 printf("%u hours + %u minutes", t / 60, t % 60);
1468 printf("illegal value");
1472 static const uint8_t xfermode_val[] ALIGN1 = {
1473 8, 9, 10, 11, 12, 13, 14, 15,
1474 16, 17, 18, 19, 20, 21, 22, 23,
1475 32, 33, 34, 35, 36, 37, 38, 39,
1476 64, 65, 66, 67, 68, 69, 70, 71
1478 /* NB: we save size by _not_ storing terninating NUL! */
1479 static const char xfermode_name[][5] ALIGN1 = {
1480 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1481 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1482 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1483 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1486 static int translate_xfermode(const char *name)
1490 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1491 if (!strncmp(name, xfermode_name[i], 5))
1492 if (strlen(name) <= 5)
1493 return xfermode_val[i];
1495 /* Negative numbers are invalid and are caught later */
1496 val = bb_strtoi(name, NULL, 10);
1502 static void interpret_xfermode(unsigned xfermode)
1506 printf("default PIO mode");
1507 else if (xfermode == 1)
1508 printf("default PIO mode, disable IORDY");
1509 else if (xfermode >= 8 && xfermode <= 15)
1510 printf("PIO flow control mode%u", xfermode - 8);
1511 else if (xfermode >= 16 && xfermode <= 23)
1512 printf("singleword DMA mode%u", xfermode - 16);
1513 else if (xfermode >= 32 && xfermode <= 39)
1514 printf("multiword DMA mode%u", xfermode - 32);
1515 else if (xfermode >= 64 && xfermode <= 71)
1516 printf("UltraDMA mode%u", xfermode - 64);
1521 #endif /* HDIO_DRIVE_CMD */
1523 static void print_flag(int flag, const char *s, unsigned long value)
1526 printf(" setting %s to %ld\n", s, value);
1529 static void process_dev(char *devname)
1532 long parm, multcount;
1533 #ifndef HDIO_DRIVE_CMD
1534 int force_operation = 0;
1536 /* Please restore args[n] to these values after each ioctl
1537 except for args[2] */
1538 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1539 const char *fmt = " %s\t= %2ld";
1541 /*fd = xopen(devname, O_RDONLY | O_NONBLOCK);*/
1542 xmove_fd(xopen(devname, O_RDONLY | O_NONBLOCK), fd);
1543 printf("\n%s:\n", devname);
1545 if (set_readahead) {
1546 print_flag(get_readahead, "fs readahead", Xreadahead);
1547 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1549 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1550 if (unregister_hwif) {
1551 printf(" attempting to unregister hwif#%lu\n", hwif);
1552 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1555 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1557 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1558 args[0] = hwif_data;
1559 args[1] = hwif_ctrl;
1561 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1562 args[0] = WIN_SETFEATURES;
1567 if (noisy_piomode) {
1568 printf(" attempting to ");
1570 printf("auto-tune PIO mode\n");
1571 else if (piomode < 100)
1572 printf("set PIO mode to %d\n", piomode);
1573 else if (piomode < 200)
1574 printf("set MDMA mode to %d\n", (piomode-100));
1576 printf("set UDMA mode to %d\n", (piomode-200));
1578 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1581 print_flag(get_io32bit, "32-bit IO_support flag", io32bit);
1582 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1585 print_flag(get_mult, "multcount", mult);
1586 #ifdef HDIO_DRIVE_CMD
1587 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1589 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1593 print_flag_on_off(get_readonly, "readonly", readonly);
1594 ioctl_or_warn(fd, BLKROSET, &readonly);
1597 print_flag_on_off(get_unmask, "unmaskirq", unmask);
1598 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1600 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1602 print_flag_on_off(get_dma, "using_dma", dma);
1603 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1605 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1607 print_flag_on_off(get_dma_q, "DMA queue_depth", dma_q);
1608 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1611 print_flag_on_off(get_nowerr, "nowerr", nowerr);
1612 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1615 print_flag_on_off(get_keep, "keep_settings", keep);
1616 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1618 #ifdef HDIO_DRIVE_CMD
1620 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1622 print_flag_on_off(get_doorlock, "drive doorlock", doorlock);
1623 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1624 args[0] = WIN_SETFEATURES;
1627 /* lock/unlock the drive's "feature" settings */
1628 print_flag_on_off(get_dkeep, "drive keep features", dkeep);
1629 args[2] = dkeep ? 0x66 : 0xcc;
1630 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1633 args[2] = defects ? 0x04 : 0x84;
1634 print_flag(get_defects, "drive defect-mgmt", defects);
1635 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1640 print_flag(get_prefetch, "drive prefetch", prefetch);
1641 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1645 args[1] = xfermode_requested;
1648 print_flag(1, "xfermode", xfermode_requested);
1649 interpret_xfermode(xfermode_requested);
1651 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1654 if (set_lookahead) {
1655 args[2] = lookahead ? 0xaa : 0x55;
1656 print_flag_on_off(get_lookahead, "drive read-lookahead", lookahead);
1657 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1660 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */; /* feature register */
1661 args[1] = apmmode; /* sector count register 1-255 */
1663 printf(" setting APM level to %s 0x%02lX (%ld)\n", (apmmode == 255) ? "disabled" : "", apmmode, apmmode);
1664 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1668 #ifdef DO_FLUSHCACHE
1669 #ifndef WIN_FLUSHCACHE
1670 #define WIN_FLUSHCACHE 0xe7
1672 #endif /* DO_FLUSHCACHE */
1673 args[2] = wcache ? 0x02 : 0x82;
1674 print_flag_on_off(get_wcache, "drive write-caching", wcache);
1675 #ifdef DO_FLUSHCACHE
1677 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1678 #endif /* DO_FLUSHCACHE */
1679 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1680 #ifdef DO_FLUSHCACHE
1682 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1683 #endif /* DO_FLUSHCACHE */
1686 /* In code below, we do not preserve args[0], but the rest
1687 is preserved, including args[2] */
1690 if (set_standbynow) {
1691 #ifndef WIN_STANDBYNOW1
1692 #define WIN_STANDBYNOW1 0xE0
1694 #ifndef WIN_STANDBYNOW2
1695 #define WIN_STANDBYNOW2 0x94
1697 if (get_standbynow) printf(" issuing standby command\n");
1698 args[0] = WIN_STANDBYNOW1;
1699 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1702 #ifndef WIN_SLEEPNOW1
1703 #define WIN_SLEEPNOW1 0xE6
1705 #ifndef WIN_SLEEPNOW2
1706 #define WIN_SLEEPNOW2 0x99
1708 if (get_sleepnow) printf(" issuing sleep command\n");
1709 args[0] = WIN_SLEEPNOW1;
1710 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1714 if (get_seagate) printf(" disabling Seagate auto powersaving mode\n");
1715 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1718 args[0] = WIN_SETIDLE1;
1719 args[1] = standby_requested;
1721 print_flag(1, "standby", standby_requested);
1722 interpret_standby(standby_requested);
1724 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1727 #else /* HDIO_DRIVE_CMD */
1728 if (force_operation) {
1730 flush_buffer_cache();
1731 if (-1 == read(fd, buf, sizeof(buf)))
1732 bb_perror_msg("read(%d bytes) failed (rc=-1)", sizeof(buf));
1734 #endif /* HDIO_DRIVE_CMD */
1736 if (get_mult || get_identity) {
1738 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1739 if (get_mult && ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn. */
1740 bb_perror_msg("HDIO_GET_MULTCOUNT");
1742 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1743 } else if (get_mult) {
1744 printf(fmt, "multcount", multcount);
1745 on_off(multcount != 0);
1749 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1750 printf(" IO_support\t=%3ld (", parm);
1752 printf("default 16-bit)\n");
1754 printf("16-bit)\n");
1756 printf("32-bit)\n");
1758 printf("32-bit w/sync)\n");
1760 printf("Request-Queue-Bypass)\n");
1762 printf("\?\?\?)\n");
1766 if(!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, (unsigned long *)parm))
1767 print_value_on_off("unmaskirq", parm);
1771 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1773 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1774 printf(fmt, "using_dma", parm);
1776 printf(" (DMA-Assisted-PIO)\n");
1783 if(!ioctl_or_warn(fd, HDIO_GET_QDMA, (unsigned long *)parm))
1784 print_value_on_off("queue_depth", parm);
1787 if(!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, (unsigned long *)parm))
1788 print_value_on_off("keepsettings", parm);
1792 if(!ioctl_or_warn(fd, HDIO_GET_NOWERR, (unsigned long *)parm))
1793 print_value_on_off("nowerr", parm);
1796 if(!ioctl_or_warn(fd, BLKROGET, (unsigned long *)parm))
1797 print_value_on_off("readonly", parm);
1799 if (get_readahead) {
1800 if(!ioctl_or_warn(fd, BLKRAGET, (unsigned long *)parm))
1801 print_value_on_off("readahead", parm);
1804 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1805 struct hd_geometry g;
1807 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1808 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1809 g.cylinders, g.heads, g.sectors, parm, g.start);
1812 #ifdef HDIO_DRIVE_CMD
1813 if (get_powermode) {
1814 #ifndef WIN_CHECKPOWERMODE1
1815 #define WIN_CHECKPOWERMODE1 0xE5
1817 #ifndef WIN_CHECKPOWERMODE2
1818 #define WIN_CHECKPOWERMODE2 0x98
1822 args[0] = WIN_CHECKPOWERMODE1;
1823 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1824 if (errno != EIO || args[0] != 0 || args[1] != 0)
1829 state = (args[2] == 255) ? "active/idle" : "standby";
1830 args[1] = args[2] = 0;
1832 printf(" drive state is: %s\n", state);
1835 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1836 if (perform_reset) {
1837 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1839 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1840 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1841 if (perform_tristate) {
1844 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1846 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1847 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1849 struct hd_driveid id;
1851 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1852 if (multcount != -1) {
1853 id.multsect = multcount;
1854 id.multsect_valid |= 1;
1856 id.multsect_valid &= ~1;
1858 } else if (errno == -ENOMSG)
1859 printf(" no identification info available\n");
1860 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1861 bb_perror_msg("HDIO_GET_IDENTITY");
1863 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1867 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1869 memset(args1, 0, sizeof(args1));
1870 args1[0] = WIN_IDENTIFY;
1872 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1873 identify((void *)(args1 + 4));
1876 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1879 print_flag(1, "bus state", busstate);
1880 bus_state_value(busstate);
1882 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1885 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1886 printf(fmt, "bus state", parm);
1887 bus_state_value(parm);
1892 ioctl_or_warn(fd, BLKRRPART, NULL);
1895 do_time(1 /*,fd*/); /* time cache */
1897 do_time(0 /*,fd*/); /* time device */
1899 flush_buffer_cache();
1903 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1904 static int fromhex(unsigned char c)
1908 if (c >= 'a' && c <= 'f')
1909 return (c - ('a' - 10));
1910 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1913 static void identify_from_stdin(void) ATTRIBUTE_NORETURN;
1914 static void identify_from_stdin(void)
1917 unsigned char buf[1280];
1918 unsigned char *b = (unsigned char *)buf;
1921 xread(0, buf, 1280);
1923 // Convert the newline-separated hex data into an identify block.
1925 for (i = 0; i < 256; i++) {
1927 for (j = 0; j < 4; j++)
1928 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1936 void identify_from_stdin(void);
1939 /* busybox specific stuff */
1940 static void parse_opts(smallint *get, smallint *set, unsigned long *value, int min, int max)
1947 *value = xatol_range(optarg, min, max);
1951 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
1956 *value = translate_xfermode(optarg);
1957 *set = (*value > -1);
1962 /*------- getopt short options --------*/
1963 static const char hdparm_options[] ALIGN1 =
1964 "gfu::n::p:r::m::c::k::a::B:tT"
1965 USE_FEATURE_HDPARM_GET_IDENTITY("iI")
1966 USE_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
1967 #ifdef HDIO_DRIVE_CMD
1968 "S:D:P:X:K:A:L:W:CyYzZ"
1970 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
1971 #ifdef HDIO_GET_QDMA
1972 #ifdef HDIO_SET_QDMA
1978 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
1979 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
1980 USE_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
1981 /*-------------------------------------*/
1983 /* our main() routine: */
1984 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1985 int hdparm_main(int argc, char **argv)
1990 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
1992 USE_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
1993 USE_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
1994 get_geom |= (c == 'g');
1995 do_flush |= (c == 'f');
1996 if (c == 'u') parse_opts(&get_unmask, &set_unmask, &unmask, 0, 1);
1997 USE_FEATURE_HDPARM_HDIO_GETSET_DMA(if (c == 'd') parse_opts(&get_dma, &set_dma, &dma, 0, 9));
1998 if (c == 'n') parse_opts(&get_nowerr, &set_nowerr, &nowerr, 0, 1);
1999 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2000 if (c == 'r') parse_opts(&get_readonly, &set_readonly, &readonly, 0, 1);
2001 if (c == 'm') parse_opts(&get_mult, &set_mult, &mult, 0, INT_MAX /*32*/);
2002 if (c == 'c') parse_opts(&get_io32bit, &set_io32bit, &io32bit, 0, INT_MAX /*8*/);
2003 if (c == 'k') parse_opts(&get_keep, &set_keep, &keep, 0, 1);
2004 if (c == 'a') parse_opts(&get_readahead, &set_readahead, &Xreadahead, 0, INT_MAX);
2005 if (c == 'B') parse_opts(&get_apmmode, &set_apmmode, &apmmode, 1, 255);
2006 do_flush |= do_timings |= (c == 't');
2007 do_flush |= do_ctimings |= (c == 'T');
2008 #ifdef HDIO_DRIVE_CMD
2009 if (c == 'S') parse_opts(&get_standby, &set_standby, &standby_requested, 0, INT_MAX);
2010 if (c == 'D') parse_opts(&get_defects, &set_defects, &defects, 0, INT_MAX);
2011 if (c == 'P') parse_opts(&get_prefetch, &set_prefetch, &prefetch, 0, INT_MAX);
2012 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2013 if (c == 'K') parse_opts(&get_dkeep, &set_dkeep, &prefetch, 0, 1);
2014 if (c == 'A') parse_opts(&get_lookahead, &set_lookahead, &lookahead, 0, 1);
2015 if (c == 'L') parse_opts(&get_doorlock, &set_doorlock, &doorlock, 0, 1);
2016 if (c == 'W') parse_opts(&get_wcache, &set_wcache, &wcache, 0, 1);
2017 get_powermode |= (c == 'C');
2018 get_standbynow = set_standbynow |= (c == 'y');
2019 get_sleepnow = set_sleepnow |= (c == 'Y');
2020 reread_partn |= (c == 'z');
2021 get_seagate = set_seagate |= (c == 'Z');
2023 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') parse_opts(NULL, &unregister_hwif, &hwif, 0, INT_MAX));
2024 #ifdef HDIO_GET_QDMA
2026 #ifdef HDIO_SET_QDMA
2027 parse_opts(&get_dma_q, &set_dma_q, &dma_q, 0, INT_MAX);
2029 parse_opts(&get_dma_q, NULL, NULL, 0, 0);
2033 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2034 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') parse_opts(NULL, &perform_tristate, &tristate, 0, 1));
2035 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') parse_opts(&get_busstate, &set_busstate, &busstate, 0, 2));
2036 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2038 parse_opts(NULL, &scan_hwif, &hwif_data, 0, INT_MAX);
2039 hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
2040 hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
2041 /* Move past the 2 additional arguments */
2047 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2049 get_mult = get_io32bit = get_unmask = get_keep = get_readonly = get_readahead = get_geom = 1;
2050 USE_FEATURE_HDPARM_HDIO_GETSET_DMA(get_dma = 1);
2055 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2056 identify_from_stdin(); /* EXIT */
2061 process_dev(*argv++);
2064 return EXIT_SUCCESS;