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 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
131 static const char *const pkt_str[] = {
132 "Direct-access device", /* word 0, bits 12-8 = 00 */
133 "Sequential-access device", /* word 0, bits 12-8 = 01 */
134 "Printer", /* word 0, bits 12-8 = 02 */
135 "Processor", /* word 0, bits 12-8 = 03 */
136 "Write-once device", /* word 0, bits 12-8 = 04 */
137 "CD-ROM", /* word 0, bits 12-8 = 05 */
138 "Scanner", /* word 0, bits 12-8 = 06 */
139 "Optical memory", /* word 0, bits 12-8 = 07 */
140 "Medium changer", /* word 0, bits 12-8 = 08 */
141 "Communications device", /* word 0, bits 12-8 = 09 */
142 "ACS-IT8 device", /* word 0, bits 12-8 = 0a */
143 "ACS-IT8 device", /* word 0, bits 12-8 = 0b */
144 "Array controller", /* word 0, bits 12-8 = 0c */
145 "Enclosure services", /* word 0, bits 12-8 = 0d */
146 "Reduced block command device", /* word 0, bits 12-8 = 0e */
147 "Optical card reader/writer", /* word 0, bits 12-8 = 0f */
148 "", /* word 0, bits 12-8 = 10 */
149 "", /* word 0, bits 12-8 = 11 */
150 "", /* word 0, bits 12-8 = 12 */
151 "", /* word 0, bits 12-8 = 13 */
152 "", /* word 0, bits 12-8 = 14 */
153 "", /* word 0, bits 12-8 = 15 */
154 "", /* word 0, bits 12-8 = 16 */
155 "", /* word 0, bits 12-8 = 17 */
156 "", /* word 0, bits 12-8 = 18 */
157 "", /* word 0, bits 12-8 = 19 */
158 "", /* word 0, bits 12-8 = 1a */
159 "", /* word 0, bits 12-8 = 1b */
160 "", /* word 0, bits 12-8 = 1c */
161 "", /* word 0, bits 12-8 = 1d */
162 "", /* word 0, bits 12-8 = 1e */
163 "Unknown", /* word 0, bits 12-8 = 1f */
166 static const char *const ata1_cfg_str[] = { /* word 0 in ATA-1 mode */
167 "Reserved", /* bit 0 */
168 "hard sectored", /* bit 1 */
169 "soft sectored", /* bit 2 */
170 "not MFM encoded ", /* bit 3 */
171 "head switch time > 15us", /* bit 4 */
172 "spindle motor control option", /* bit 5 */
173 "fixed drive", /* bit 6 */
174 "removable drive", /* bit 7 */
175 "disk xfer rate <= 5Mbs", /* bit 8 */
176 "disk xfer rate > 5Mbs, <= 10Mbs", /* bit 9 */
177 "disk xfer rate > 5Mbs", /* bit 10 */
178 "rotational speed tol.", /* bit 11 */
179 "data strobe offset option", /* bit 12 */
180 "track offset option", /* bit 13 */
181 "format speed tolerance gap reqd", /* bit 14 */
186 /* word 1: number of logical cylinders */
187 #define LCYLS_MAX 0x3fff /* maximum allowable value */
189 /* word 2: specific configuration
190 * (a) require SET FEATURES to spin-up
191 * (b) require spin-up to fully reply to IDENTIFY DEVICE
193 #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
194 #define STBY_ID_VAL 0x738c /* (a) and not (b) */
195 #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
196 #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
198 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
199 #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
200 #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
202 /* word 49: capabilities 0 */
203 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
204 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
205 #define IORDY_OFF 0x0400 /* 1=may be disabled */
206 #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
207 #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
208 #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
209 #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
210 #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
211 #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
213 /* word 50: capabilities 1 */
214 #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
216 /* words 51 & 52: PIO & DMA cycle times */
217 #define MODE 0xff00 /* the mode is in the MSBs */
219 /* word 53: whats_valid */
220 #define OK_W88 0x0004 /* the ultra_dma info is valid */
221 #define OK_W64_70 0x0002 /* see above for word descriptions */
222 #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
224 /*word 63,88: dma_mode, ultra_dma_mode*/
225 #define MODE_MAX 7 /* bit definitions force udma <=7 (when
226 * udma >=8 comes out it'll have to be
227 * defined in a new dma_mode word!) */
229 /* word 64: PIO transfer modes */
230 #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
231 #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
233 /* word 75: queue_depth */
234 #define DEPTH_BITS 0x001f /* bits used for queue depth */
236 /* words 80-81: version numbers */
237 /* NOVAL_0 or NOVAL_1 means device does not report version */
239 /* word 81: minor version number */
240 #define MINOR_MAX 0x22
241 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
242 static const char *const minor_str[MINOR_MAX + 2] = {
244 "Unspecified", /* 0x0000 */
245 "ATA-1 X3T9.2 781D prior to rev.4", /* 0x0001 */
246 "ATA-1 published, ANSI X3.221-1994", /* 0x0002 */
247 "ATA-1 X3T9.2 781D rev.4", /* 0x0003 */
248 "ATA-2 published, ANSI X3.279-1996", /* 0x0004 */
249 "ATA-2 X3T10 948D prior to rev.2k", /* 0x0005 */
250 "ATA-3 X3T10 2008D rev.1", /* 0x0006 */
251 "ATA-2 X3T10 948D rev.2k", /* 0x0007 */
252 "ATA-3 X3T10 2008D rev.0", /* 0x0008 */
253 "ATA-2 X3T10 948D rev.3", /* 0x0009 */
254 "ATA-3 published, ANSI X3.298-199x", /* 0x000a */
255 "ATA-3 X3T10 2008D rev.6", /* 0x000b */
256 "ATA-3 X3T13 2008D rev.7 and 7a", /* 0x000c */
257 "ATA/ATAPI-4 X3T13 1153D rev.6", /* 0x000d */
258 "ATA/ATAPI-4 T13 1153D rev.13", /* 0x000e */
259 "ATA/ATAPI-4 X3T13 1153D rev.7", /* 0x000f */
260 "ATA/ATAPI-4 T13 1153D rev.18", /* 0x0010 */
261 "ATA/ATAPI-4 T13 1153D rev.15", /* 0x0011 */
262 "ATA/ATAPI-4 published, ANSI INCITS 317-1998", /* 0x0012 */
263 "ATA/ATAPI-5 T13 1321D rev.3", /* 0x0013 */
264 "ATA/ATAPI-4 T13 1153D rev.14", /* 0x0014 */
265 "ATA/ATAPI-5 T13 1321D rev.1", /* 0x0015 */
266 "ATA/ATAPI-5 published, ANSI INCITS 340-2000", /* 0x0016 */
267 "ATA/ATAPI-4 T13 1153D rev.17", /* 0x0017 */
268 "ATA/ATAPI-6 T13 1410D rev.0", /* 0x0018 */
269 "ATA/ATAPI-6 T13 1410D rev.3a", /* 0x0019 */
270 "ATA/ATAPI-7 T13 1532D rev.1", /* 0x001a */
271 "ATA/ATAPI-6 T13 1410D rev.2", /* 0x001b */
272 "ATA/ATAPI-6 T13 1410D rev.1", /* 0x001c */
273 "ATA/ATAPI-7 published, ANSI INCITS 397-2005", /* 0x001d */
274 "ATA/ATAPI-7 T13 1532D rev.0", /* 0x001e */
275 "Reserved" /* 0x001f */
276 "Reserved" /* 0x0020 */
277 "ATA/ATAPI-7 T13 1532D rev.4a", /* 0x0021 */
278 "ATA/ATAPI-6 published, ANSI INCITS 361-2002", /* 0x0022 */
279 "Reserved" /* 0x0023-0xfffe */
282 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
284 0, /* 0x0000 WARNING: actual_ver[] array */
285 1, /* 0x0001 WARNING: corresponds */
286 1, /* 0x0002 WARNING: *exactly* */
287 1, /* 0x0003 WARNING: to the ATA/ */
288 2, /* 0x0004 WARNING: ATAPI version */
289 2, /* 0x0005 WARNING: listed in */
290 3, /* 0x0006 WARNING: the */
291 2, /* 0x0007 WARNING: minor_str */
292 3, /* 0x0008 WARNING: array */
293 2, /* 0x0009 WARNING: above. */
294 3, /* 0x000a WARNING: */
295 3, /* 0x000b WARNING: If you change */
296 3, /* 0x000c WARNING: that one, */
297 4, /* 0x000d WARNING: change this one */
298 4, /* 0x000e WARNING: too!!! */
319 0 /* 0x0023-0xfffe */
322 /* words 82-84: cmds/feats supported */
323 #define CMDS_W82 0x77ff /* word 82: defined command locations*/
324 #define CMDS_W83 0x3fff /* word 83: defined command locations*/
325 #define CMDS_W84 0x002f /* word 83: defined command locations*/
326 #define SUPPORT_48_BIT 0x0400
327 #define NUM_CMD_FEAT_STR 48
329 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
330 static const char *const cmd_feat_str[] = {
331 "", /* word 82 bit 15: obsolete */
332 "NOP cmd", /* word 82 bit 14 */
333 "READ BUFFER cmd", /* word 82 bit 13 */
334 "WRITE BUFFER cmd", /* word 82 bit 12 */
335 "", /* word 82 bit 11: obsolete */
336 "Host Protected Area feature set", /* word 82 bit 10 */
337 "DEVICE RESET cmd", /* word 82 bit 9 */
338 "SERVICE interrupt", /* word 82 bit 8 */
339 "Release interrupt", /* word 82 bit 7 */
340 "Look-ahead", /* word 82 bit 6 */
341 "Write cache", /* word 82 bit 5 */
342 "PACKET command feature set", /* word 82 bit 4 */
343 "Power Management feature set", /* word 82 bit 3 */
344 "Removable Media feature set", /* word 82 bit 2 */
345 "Security Mode feature set", /* word 82 bit 1 */
346 "SMART feature set", /* word 82 bit 0 */
348 "", /* word 83 bit 15: !valid bit */
349 "", /* word 83 bit 14: valid bit */
350 "FLUSH CACHE EXT cmd", /* word 83 bit 13 */
351 "Mandatory FLUSH CACHE cmd ", /* word 83 bit 12 */
352 "Device Configuration Overlay feature set ",
353 "48-bit Address feature set ", /* word 83 bit 10 */
355 "SET MAX security extension", /* word 83 bit 8 */
356 "Address Offset Reserved Area Boot", /* word 83 bit 7 */
357 "SET FEATURES subcommand required to spinup after power up",
358 "Power-Up In Standby feature set", /* word 83 bit 5 */
359 "Removable Media Status Notification feature set",
360 "Adv. Power Management feature set", /* word 83 bit 3 */
361 "CFA feature set", /* word 83 bit 2 */
362 "READ/WRITE DMA QUEUED", /* word 83 bit 1 */
363 "DOWNLOAD MICROCODE cmd", /* word 83 bit 0 */
365 "", /* word 84 bit 15: !valid bit */
366 "", /* word 84 bit 14: valid bit */
367 "", /* word 84 bit 13: reserved */
368 "", /* word 84 bit 12: reserved */
369 "", /* word 84 bit 11: reserved */
370 "", /* word 84 bit 10: reserved */
371 "", /* word 84 bit 9: reserved */
372 "", /* word 84 bit 8: reserved */
373 "", /* word 84 bit 7: reserved */
374 "", /* word 84 bit 6: reserved */
375 "General Purpose Logging feature set", /* word 84 bit 5 */
376 "", /* word 84 bit 4: reserved */
377 "Media Card Pass Through Command feature set ",
378 "Media serial number ", /* word 84 bit 2 */
379 "SMART self-test ", /* word 84 bit 1 */
380 "SMART error logging " /* word 84 bit 0 */
383 static void identify(uint16_t *id_supplied) ATTRIBUTE_NORETURN;
384 static void identify_from_stdin(void) ATTRIBUTE_NORETURN;
386 void identify_from_stdin(void);
390 /* words 85-87: cmds/feats enabled */
391 /* use cmd_feat_str[] to display what commands and features have
392 * been enabled with words 85-87
395 /* words 89, 90, SECU ERASE TIME */
396 #define ERASE_BITS 0x00ff
398 /* word 92: master password revision */
399 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
401 /* word 93: hw reset result */
402 #define CBLID 0x2000 /* CBLID status */
403 #define RST0 0x0001 /* 1=reset to device #0 */
404 #define DEV_DET 0x0006 /* how device num determined */
405 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
406 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
408 /* word 127: removable media status notification feature set support */
409 #define RM_STAT_BITS 0x0003
410 #define RM_STAT_SUP 0x0001
412 /* word 128: security */
413 #define SECU_ENABLED 0x0002
414 #define SECU_LEVEL 0x0010
415 #define NUM_SECU_STR 6
416 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
417 static const char *const secu_str[] = {
418 "supported", /* word 128, bit 0 */
419 "enabled", /* word 128, bit 1 */
420 "locked", /* word 128, bit 2 */
421 "frozen", /* word 128, bit 3 */
422 "expired: security count", /* word 128, bit 4 */
423 "supported: enhanced erase" /* word 128, bit 5 */
427 /* word 160: CFA power mode */
428 #define VALID_W160 0x8000 /* 1=word valid */
429 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
430 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
431 #define MAX_AMPS 0x0fff /* value = max current in ma */
433 /* word 255: integrity */
434 #define SIG 0x00ff /* signature location */
435 #define SIG_VAL 0x00a5 /* signature value */
438 #define TIMING_BUF_MB 1
439 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
440 #define BUFCACHE_FACTOR 2
442 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
444 /* Busybox messages and functions */
445 #if ENABLE_IOCTL_HEX2STR_ERROR
446 static int ioctl_alt_func(int fd, int cmd, unsigned char *args, int alt, const char *string)
448 if (!ioctl(fd, cmd, args))
451 return bb_ioctl_or_warn(fd, cmd, args, string);
453 #define ioctl_alt_or_warn(fd,cmd,args,alt) ioctl_alt_func(fd,cmd,args,alt,#cmd)
455 static int ioctl_alt_func(int fd, int cmd, unsigned char *args, int alt)
457 if (!ioctl(fd, cmd, args))
460 return bb_ioctl_or_warn(fd, cmd, args);
462 #define ioctl_alt_or_warn(fd,cmd,args,alt) ioctl_alt_func(fd,cmd,args,alt)
465 static void on_off(int value)
467 puts(value ? " (on)" : " (off)");
470 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
473 printf(" setting %s to %ld", s, arg);
478 static void print_value_on_off(const char *str, unsigned long argp)
480 printf(" %s\t= %2ld", str, argp);
484 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
485 static void print_ascii(uint16_t *p, uint8_t length);
487 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
490 printf("\t%-20s", string);
491 print_ascii(&val[i], n);
495 /* end of busybox specific stuff */
497 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
498 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
503 for (ii = 0; ii <= MODE_MAX; ii++) {
504 if (mode_sel & 0x0001) {
505 printf("*%cdma%u ", cc, ii);
509 } else if (mode_sup & 0x0001)
510 printf("%cdma%u ", cc, ii);
518 static void print_ascii(uint16_t *p, uint8_t length)
523 /* find first non-space & print it */
524 for (ii = 0; ii < length; ii++) {
525 if ((char)((*p)>>8) != ' ')
538 for (; ii< length; ii++) {
540 break; /* some older devices have NULLs */
541 printf("%c%c", (char)((*p)>>8), (char)(*p));
547 // Parse 512 byte disk identification block and print much crap.
549 static void identify(uint16_t *id_supplied)
552 uint16_t *val, ii, jj, kk;
553 uint16_t like_std = 1, std = 0, min_std = 0xffff;
554 uint16_t dev = NO_DEV, eqpt = NO_DEV;
555 uint8_t have_mode = 0, err_dma = 0;
557 uint32_t ll, mm, nn, oo;
558 uint64_t bbbig; /* (:) */
561 // Adjust for endianness if necessary.
564 swab(id_supplied, buf, sizeof(buf));
571 /* check if we recognise the device type */
573 if (!(val[GEN_CONFIG] & NOT_ATA)) {
575 printf("ATA device, with ");
576 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
579 printf("CompactFlash ATA device, with ");
580 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
582 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
583 printf("ATAPI %s, with ", pkt_str[eqpt]);
586 /*"Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n"*/
587 bb_error_msg_and_die("unknown device type");
589 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
590 /* Info from the specific configuration word says whether or not the
591 * ID command completed correctly. It is only defined, however in
592 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
593 * standards. Since the values allowed for this word are extremely
594 * specific, it should be safe to check it now, even though we don't
595 * know yet what standard this device is using.
597 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
598 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
601 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
602 printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
603 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
604 printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
607 /* output the model and serial numbers and the fw revision */
608 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
609 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
610 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
611 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
612 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
614 /* major & minor standards version number (Note: these words were not
615 * defined until ATA-3 & the CDROM std uses different words.) */
616 printf("Standards:");
618 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
619 if (like_std < 3) like_std = 3;
620 std = actual_ver[val[MINOR]];
621 if (std) printf("\n\tUsed: %s ", minor_str[val[MINOR]]);
624 /* looks like when they up-issue the std, they obsolete one;
625 * thus, only the newest 4 issues need be supported. (That's
626 * what "kk" and "min_std" are all about.) */
627 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
628 printf("\n\tSupported: ");
629 jj = val[MAJOR] << 1;
630 kk = like_std >4 ? like_std-4: 0;
631 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
636 kk = like_std >4 ? like_std-4: 0;
638 if (min_std > ii) min_std = ii;
642 if (like_std < 3) like_std = 3;
644 /* Figure out what standard the device is using if it hasn't told
645 * us. If we know the std, check if the device is using any of
646 * the words from the next level up. It happens.
648 if (like_std < std) like_std = std;
650 if (((std == 5) || (!std && (like_std < 6))) &&
651 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
652 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
653 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
654 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
657 } else if (((std == 4) || (!std && (like_std < 5))) &&
658 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
659 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
660 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
661 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
664 } else if (((std == 3) || (!std && (like_std < 4))) &&
665 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
666 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
667 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
668 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
669 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
670 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
673 } else if (((std == 2) || (!std && (like_std < 3)))
674 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
677 } else if (((std == 1) || (!std && (like_std < 2))) &&
678 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
679 (val[WHATS_VALID] & OK_W64_70)) )
685 printf("\n\tLikely used: %u\n", like_std);
686 else if (like_std > std)
687 printf("& some of %u\n", like_std);
691 /* TBD: do CDROM stuff more thoroughly. For now... */
693 if (val[CDR_MINOR] == 9) {
695 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
697 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
699 printf("\n\tSupported: CD-ROM ATAPI");
700 jj = val[CDR_MAJOR] >> 1;
701 for (ii = 1; ii < 15; ii++) {
702 if (jj & 0x0001) printf("-%u ", ii);
706 printf("%s\n", kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
707 /* the cdrom stuff is more like ATA-2 than anything else, so: */
711 if (min_std == 0xffff)
712 min_std = like_std > 4 ? like_std - 3 : 1;
714 printf("Configuration:\n");
715 /* more info from the general configuration word */
716 if ((eqpt != CDROM) && (like_std == 1)) {
717 jj = val[GEN_CONFIG] >> 1;
718 for (ii = 1; ii < 15; ii++) {
720 printf("\t%s\n", ata1_cfg_str[ii]);
724 if (dev == ATAPI_DEV) {
725 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
727 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
728 strng = "<=10ms with INTRQ";
729 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
733 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
735 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
737 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
743 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
744 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
746 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
747 printf("\tCHS addressing not supported\n");
749 jj = val[WHATS_VALID] & OK_W54_58;
750 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",
751 val[LCYLS],jj?val[LCYLS_CUR]:0, val[LHEADS],jj?val[LHEADS_CUR]:0, val[LSECTS],jj?val[LSECTS_CUR]:0);
753 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
754 printf("\tbytes/track: %u\tbytes/sector: %u\n", val[TRACK_BYTES], val[SECT_BYTES]);
757 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
759 /* check Endian of capacity bytes */
760 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
761 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
762 if (abs(mm - nn) > abs(oo - nn))
765 printf("\tCHS current addressable sectors:%11u\n", mm);
769 printf("\tLBA user addressable sectors:%11u\n", ll);
770 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
771 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
773 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
774 (uint64_t)val[LBA_48_MSB] << 32 |
775 (uint64_t)val[LBA_MID] << 16 |
777 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
781 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
782 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
783 bbbig = (bbbig << 9) / 1000000;
784 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
787 printf("(%"PRIu64" GB)\n", bbbig/1000);
792 /* hw support of commands (capabilities) */
793 printf("Capabilities:\n\t");
795 if (dev == ATAPI_DEV) {
796 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP)) printf("Cmd queuing, ");
797 if (val[CAPAB_0] & OVLP_SUP) printf("Cmd overlap, ");
799 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
802 printf("IORDY%s(can%s be disabled)\n",
803 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
804 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
806 printf("no IORDY\n");
808 if ((like_std == 1) && val[BUF_TYPE]) {
809 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
810 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
811 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
814 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
815 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
817 if ((min_std < 4) && (val[RW_LONG])) {
818 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
820 if ((eqpt != CDROM) && (like_std > 3)) {
821 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
824 if (dev == ATA_DEV) {
826 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
828 printf("\tStandby timer values: spec'd by %s", (val[CAPAB_0] & STD_STBY) ? "Standard" : "Vendor");
829 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
830 printf(", %s device specific minimum\n", (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
834 printf("\tR/W multiple sector transfer: ");
835 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
836 printf("not supported\n");
838 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
839 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
840 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
844 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
845 /* We print out elsewhere whether the APM feature is enabled or
846 not. If it's not enabled, let's not repeat the info; just print
848 printf("\tAdvancedPM level: ");
849 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
850 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
851 printf("%u (0x%x)\n", apm_level, apm_level);
854 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
856 if (like_std > 5 && val[ACOUSTIC]) {
857 printf("\tRecommended acoustic management value: %u, current value: %u\n",
858 (val[ACOUSTIC] >> 8) & 0x00ff, val[ACOUSTIC] & 0x00ff);
862 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
863 printf("\tATA sw reset required\n");
865 if (val[PKT_REL] || val[SVC_NBSY]) {
866 printf("\tOverlap support:");
867 if (val[PKT_REL]) printf(" %uus to release bus.", val[PKT_REL]);
868 if (val[SVC_NBSY]) printf(" %uus to clear BSY after SERVICE cmd.", val[SVC_NBSY]);
873 /* DMA stuff. Check that only one DMA mode is selected. */
875 if (!(val[CAPAB_0] & DMA_SUP))
876 printf("not supported\n");
878 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
879 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
880 if (val[SINGLE_DMA]) {
881 jj = val[SINGLE_DMA];
882 kk = val[SINGLE_DMA] >> 8;
883 err_dma += mode_loop(jj, kk, 's', &have_mode);
885 if (val[MULTI_DMA]) {
887 kk = val[MULTI_DMA] >> 8;
888 err_dma += mode_loop(jj, kk, 'm', &have_mode);
890 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
892 kk = val[ULTRA_DMA] >> 8;
893 err_dma += mode_loop(jj, kk, 'u', &have_mode);
895 if (err_dma || !have_mode) printf("(?)");
898 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
899 printf("\t\tInterleaved DMA support\n");
901 if ((val[WHATS_VALID] & OK_W64_70)
902 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
904 printf("\t\tCycle time:");
905 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
906 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
911 /* Programmed IO stuff */
913 /* If a drive supports mode n (e.g. 3), it also supports all modes less
914 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
915 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
916 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
917 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
918 if (jj & 0x0001) printf("pio%d ", ii);
922 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
923 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
924 printf("pio%d ", ii);
929 if (val[WHATS_VALID] & OK_W64_70) {
930 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
931 printf("\t\tCycle time:");
932 if (val[PIO_NO_FLOW]) printf(" no flow control=%uns", val[PIO_NO_FLOW]);
933 if (val[PIO_FLOW]) printf(" IORDY flow control=%uns", val[PIO_FLOW]);
938 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
939 printf("Commands/features:\n\tEnabled\tSupported:\n");
940 jj = val[CMDS_SUPP_0];
942 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
943 if ((jj & 0x8000) && (*cmd_feat_str[ii] != '\0')) {
944 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", cmd_feat_str[ii]);
949 jj = val[CMDS_SUPP_0+1+(ii/16)];
950 kk = val[CMDS_EN_0+1+(ii/16)];
953 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
958 /* Removable Media Status Notification feature set */
959 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
960 printf("\t%s supported\n", cmd_feat_str[27]);
963 if ((eqpt != CDROM) && (like_std > 3)
964 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
966 printf("Security:\n");
967 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
968 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
969 jj = val[SECU_STATUS];
971 for (ii = 0; ii < NUM_SECU_STR; ii++) {
972 printf("\t%s\t%s\n", (!(jj & 0x0001)) ? "not" : "", secu_str[ii]);
975 if (val[SECU_STATUS] & SECU_ENABLED) {
976 printf("\tSecurity level %s\n", (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
979 jj = val[ERASE_TIME] & ERASE_BITS;
980 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
983 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
984 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
990 jj = val[HWRST_RSLT];
991 if ((jj & VALID) == VALID_VAL) {
992 if (!(oo = (jj & RST0)))
994 if ((jj & DEV_DET) == JUMPER_VAL)
995 strng = " determined by the jumper";
996 else if ((jj & DEV_DET) == CSEL_VAL)
997 strng = " determined by CSEL";
1000 printf("HW reset results:\n\tCBLID- %s Vih\n\tDevice num = %i%s\n",
1001 (val[HWRST_RSLT] & CBLID) ? "above" : "below", !(oo), strng);
1004 /* more stuff from std 5 */
1005 if ((like_std > 4) && (eqpt != CDROM)) {
1006 if (val[CFA_PWR_MODE] & VALID_W160) {
1007 printf("CFA power mode 1:\n\t%s%s\n", (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1008 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1010 if (val[CFA_PWR_MODE] & MAX_AMPS)
1011 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1013 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1014 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1022 static smallint get_identity, get_geom;
1023 static smallint do_flush;
1024 static smallint do_ctimings, do_timings;
1025 static smallint reread_partn;
1027 static smallint set_piomode, noisy_piomode;
1028 static smallint set_readahead, get_readahead;
1029 static smallint set_readonly, get_readonly;
1030 static smallint set_unmask, get_unmask;
1031 static smallint set_mult, get_mult;
1032 static smallint set_dma_q, get_dma_q;
1033 static smallint set_nowerr, get_nowerr;
1034 static smallint set_keep, get_keep;
1035 static smallint set_io32bit, get_io32bit;
1037 static unsigned long Xreadahead;
1038 static unsigned long readonly;
1039 static unsigned long unmask;
1040 static unsigned long mult;
1041 static unsigned long dma_q;
1042 static unsigned long nowerr;
1043 static unsigned long keep;
1044 static unsigned long io32bit;
1045 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1046 static unsigned long dma;
1047 static smallint set_dma, get_dma;
1049 #ifdef HDIO_DRIVE_CMD
1050 static smallint set_xfermode, get_xfermode;
1051 static smallint set_dkeep, get_dkeep;
1052 static smallint set_standby, get_standby;
1053 static smallint set_lookahead, get_lookahead;
1054 static smallint set_prefetch, get_prefetch;
1055 static smallint set_defects, get_defects;
1056 static smallint set_wcache, get_wcache;
1057 static smallint set_doorlock, get_doorlock;
1058 static smallint set_seagate, get_seagate;
1059 static smallint set_standbynow, get_standbynow;
1060 static smallint set_sleepnow, get_sleepnow;
1061 static smallint get_powermode;
1062 static smallint set_apmmode, get_apmmode;
1063 static int xfermode_requested;
1064 static unsigned long dkeep;
1065 static unsigned long standby_requested;
1066 static unsigned long lookahead;
1067 static unsigned long prefetch;
1068 static unsigned long defects;
1069 static unsigned long wcache;
1070 static unsigned long doorlock;
1071 static unsigned long apmmode;
1073 USE_FEATURE_HDPARM_GET_IDENTITY( static smallint get_IDentity;)
1074 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( static smallint set_busstate, get_busstate;)
1075 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET( static smallint perform_reset;)
1076 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( static smallint perform_tristate;)
1077 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(static smallint unregister_hwif;)
1078 USE_FEATURE_HDPARM_HDIO_SCAN_HWIF( static smallint scan_hwif;)
1079 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( static unsigned long busstate;)
1080 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( static unsigned long tristate;)
1081 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(static unsigned long hwif;)
1082 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1083 static unsigned long hwif_data;
1084 static unsigned long hwif_ctrl;
1085 static unsigned long hwif_irq;
1088 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1089 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1090 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1091 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1092 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1093 // (which they should, but they should just return -EINVAL).
1095 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1096 // On a really old system, it will not, and we will be confused.
1099 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1100 static const char *const cfg_str[] = {
1101 "", "HardSect", "SoftSect", "NotMFM",
1102 "HdSw>15uSec", "SpinMotCtl", "Fixed", "Removeable",
1103 "DTR<=5Mbs", "DTR>5Mbs", "DTR>10Mbs", "RotSpdTol>.5%",
1104 "dStbOff", "TrkOff", "FmtGapReq", "nonMagnetic"
1107 static const char *const BuffType[] = {
1108 "Unknown", "1Sect", "DualPort", "DualPortCache"
1111 static void dump_identity(const struct hd_driveid *id)
1114 const unsigned short int *id_regs = (const void*) id;
1116 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1117 id->model, id->fw_rev, id->serial_no);
1118 for (i = 0; i <= 15; i++) {
1119 if (id->config & (1<<i))
1120 printf(" %s", cfg_str[i]);
1122 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1123 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1124 id->cyls, id->heads, id->sectors, id->track_bytes,
1125 id->sector_bytes, id->ecc_bytes,
1126 id->buf_type, BuffType[(id->buf_type > 3) ? 0 : id->buf_type],
1127 id->buf_size/2, id->max_multsect);
1128 if (id->max_multsect) {
1129 printf(", MultSect=");
1130 if (!(id->multsect_valid & 1))
1131 printf("?%u?", id->multsect);
1132 else if (id->multsect)
1133 printf("%u", id->multsect);
1139 if (!(id->field_valid & 1))
1140 printf(" (maybe):");
1142 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1145 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1146 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1147 ((id->capability&2) == 0) ? "no" : "yes");
1149 if (id->capability & 2)
1150 printf(", LBAsects=%u", id->lba_capacity);
1152 printf("\n IORDY=%s", (id->capability & 8) ? (id->capability & 4) ? "on/off" : "yes" : "no");
1154 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1155 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1157 if ((id->capability & 1) && (id->field_valid & 2))
1158 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1160 printf("\n PIO modes: ");
1161 if (id->tPIO <= 5) {
1163 if (id->tPIO >= 1) printf("pio1 ");
1164 if (id->tPIO >= 2) printf("pio2 ");
1166 if (id->field_valid & 2) {
1167 if (id->eide_pio_modes & 1) printf("pio3 ");
1168 if (id->eide_pio_modes & 2) printf("pio4 ");
1169 if (id->eide_pio_modes &~3) printf("pio? ");
1171 if (id->capability & 1) {
1172 if (id->dma_1word | id->dma_mword) {
1173 printf("\n DMA modes: ");
1174 if (id->dma_1word & 0x100) printf("*");
1175 if (id->dma_1word & 1) printf("sdma0 ");
1176 if (id->dma_1word & 0x200) printf("*");
1177 if (id->dma_1word & 2) printf("sdma1 ");
1178 if (id->dma_1word & 0x400) printf("*");
1179 if (id->dma_1word & 4) printf("sdma2 ");
1180 if (id->dma_1word & 0xf800) printf("*");
1181 if (id->dma_1word & 0xf8) printf("sdma? ");
1182 if (id->dma_mword & 0x100) printf("*");
1183 if (id->dma_mword & 1) printf("mdma0 ");
1184 if (id->dma_mword & 0x200) printf("*");
1185 if (id->dma_mword & 2) printf("mdma1 ");
1186 if (id->dma_mword & 0x400) printf("*");
1187 if (id->dma_mword & 4) printf("mdma2 ");
1188 if (id->dma_mword & 0xf800) printf("*");
1189 if (id->dma_mword & 0xf8) printf("mdma? ");
1192 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1193 printf("\n UDMA modes: ");
1194 if (id->dma_ultra & 0x100) printf("*");
1195 if (id->dma_ultra & 0x001) printf("udma0 ");
1196 if (id->dma_ultra & 0x200) printf("*");
1197 if (id->dma_ultra & 0x002) printf("udma1 ");
1198 if (id->dma_ultra & 0x400) printf("*");
1199 if (id->dma_ultra & 0x004) printf("udma2 ");
1200 #ifdef __NEW_HD_DRIVE_ID
1201 if (id->hw_config & 0x2000) {
1202 #else /* !__NEW_HD_DRIVE_ID */
1203 if (id->word93 & 0x2000) {
1204 #endif /* __NEW_HD_DRIVE_ID */
1205 if (id->dma_ultra & 0x0800) printf("*");
1206 if (id->dma_ultra & 0x0008) printf("udma3 ");
1207 if (id->dma_ultra & 0x1000) printf("*");
1208 if (id->dma_ultra & 0x0010) printf("udma4 ");
1209 if (id->dma_ultra & 0x2000) printf("*");
1210 if (id->dma_ultra & 0x0020) printf("udma5 ");
1211 if (id->dma_ultra & 0x4000) printf("*");
1212 if (id->dma_ultra & 0x0040) printf("udma6 ");
1213 if (id->dma_ultra & 0x8000) printf("*");
1214 if (id->dma_ultra & 0x0080) printf("udma7 ");
1217 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1218 if (id_regs[83] & 8) {
1219 if (!(id_regs[86] & 8))
1220 printf(": disabled (255)");
1221 else if ((id_regs[91] & 0xFF00) != 0x4000)
1222 printf(": unknown setting");
1224 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1226 if (id_regs[82] & 0x20)
1227 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1228 #ifdef __NEW_HD_DRIVE_ID
1229 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1230 || (id->major_rev_num && id->minor_rev_num <= 31)
1232 printf("\n Drive conforms to: %s: ", (id->minor_rev_num <= 31) ? minor_str[id->minor_rev_num] : "Unknown");
1233 if (id->major_rev_num != 0x0000 && /* NOVAL_0 */
1234 id->major_rev_num != 0xFFFF) { /* NOVAL_1 */
1235 for (i = 0; i <= 15; i++) {
1236 if (id->major_rev_num & (1<<i))
1237 printf(" ATA/ATAPI-%u", i);
1241 #endif /* __NEW_HD_DRIVE_ID */
1242 printf("\n\n * current active mode\n\n");
1246 static void flush_buffer_cache(int fd)
1248 fsync(fd); /* flush buffers */
1249 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1250 #ifdef HDIO_DRIVE_CMD
1252 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1253 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1254 bb_perror_msg("HDIO_DRIVE_CMD");
1256 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1261 static int seek_to_zero(int fd)
1263 if (lseek(fd, (off_t) 0, SEEK_SET))
1268 static int read_big_block(int fd, char *buf)
1272 i = read(fd, buf, TIMING_BUF_BYTES);
1273 if (i != TIMING_BUF_BYTES) {
1274 bb_error_msg("read(%d bytes) failed (rc=%d)", TIMING_BUF_BYTES, i);
1277 /* access all sectors of buf to ensure the read fully completed */
1278 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1283 static int do_blkgetsize(int fd, unsigned long long *blksize64)
1286 unsigned blksize32 = 0;
1288 if (0 == ioctl(fd, BLKGETSIZE64, blksize64)) { // returns bytes
1292 rc = ioctl_or_warn(fd, BLKGETSIZE, &blksize32); // returns sectors
1293 *blksize64 = blksize32;
1297 static void print_timing(unsigned t, double e)
1299 if (t >= e) /* more than 1MB/s */
1300 printf("%4d MB in %.2f seconds = %.2f %cB/sec\n", t, e, t / e, 'M');
1302 printf("%4d MB in %.2f seconds = %.2f %cB/sec\n", t, e, t / e * 1024, 'k');
1305 static void do_time(int flag, int fd)
1306 /* flag = 0 time_cache, 1 time_device */
1308 static const struct itimerval thousand = {{1000, 0}, {1000, 0}};
1310 struct itimerval itv;
1311 unsigned elapsed, elapsed2;
1312 unsigned max_iterations, total_MB, iterations;
1313 unsigned long long blksize;
1314 RESERVE_CONFIG_BUFFER(buf, TIMING_BUF_BYTES);
1316 if (mlock(buf, TIMING_BUF_BYTES)) {
1317 bb_perror_msg("mlock");
1321 max_iterations = 1024;
1322 if (0 == do_blkgetsize(fd, &blksize)) {
1323 max_iterations = blksize / (2 * 1024) / TIMING_BUF_MB;
1326 /* Clear out the device request queues & give them time to complete */
1329 if (flag == 0) { /* Time cache */
1330 if (seek_to_zero(fd))
1332 if (read_big_block(fd, buf))
1334 printf(" Timing buffer-cache reads: ");
1335 } else { /* Time device */
1336 printf(" Timing buffered disk reads: ");
1341 * getitimer() is used rather than gettimeofday() because
1342 * it is much more consistent (on my machine, at least).
1344 setitimer(ITIMER_REAL, &thousand, NULL);
1345 /* Now do the timing */
1348 if ((flag == 0) && seek_to_zero(fd))
1350 if (read_big_block(fd, buf))
1352 getitimer(ITIMER_REAL, &itv);
1353 elapsed = (1000 - itv.it_value.tv_sec) * 1000000
1354 - itv.it_value.tv_usec;
1355 } while (elapsed < 3000000 && iterations < max_iterations);
1356 total_MB = iterations * TIMING_BUF_MB;
1358 /* Now remove the lseek() and getitimer() overheads from the elapsed time */
1359 setitimer(ITIMER_REAL, &thousand, NULL);
1361 if (seek_to_zero(fd))
1363 getitimer(ITIMER_REAL, &itv);
1364 elapsed2 = (1000 - itv.it_value.tv_sec) * 1000000
1365 - itv.it_value.tv_usec;
1366 } while (--iterations);
1367 elapsed -= elapsed2;
1368 total_MB *= BUFCACHE_FACTOR;
1369 flush_buffer_cache(fd);
1371 print_timing(total_MB, elapsed / 1000000.0);
1373 munlock(buf, TIMING_BUF_BYTES);
1375 RELEASE_CONFIG_BUFFER(buf);
1378 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1379 static void bus_state_value(unsigned value)
1381 if (value == BUSSTATE_ON)
1383 else if (value == BUSSTATE_OFF)
1385 else if (value == BUSSTATE_TRISTATE)
1386 printf(" (tristate)\n");
1388 printf(" (unknown: %d)\n", value);
1392 #ifdef HDIO_DRIVE_CMD
1393 static void interpret_standby(unsigned standby)
1400 else if (standby == 252)
1401 printf("21 minutes");
1402 else if (standby == 253)
1403 printf("vendor-specific");
1404 else if (standby == 254)
1406 else if (standby == 255)
1407 printf("21 minutes + 15 seconds");
1408 else if (standby <= 240) {
1410 printf("%u minutes + %u seconds", t / 60, t % 60);
1411 } else if (standby <= 251) {
1412 t = (standby - 240) * 30;
1413 printf("%u hours + %u minutes", t / 60, t % 60);
1415 printf("illegal value");
1419 static const uint8_t xfermode_val[] ALIGN1 = {
1420 8, 9, 10, 11, 12, 13, 14, 15,
1421 16, 17, 18, 19, 20, 21, 22, 23,
1422 32, 33, 34, 35, 36, 37, 38, 39,
1423 64, 65, 66, 67, 68, 69, 70, 71
1425 /* NB: we save size by _not_ storing terninating NUL! */
1426 static const char xfermode_name[][5] ALIGN1 = {
1427 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1428 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1429 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1430 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1433 static int translate_xfermode(const char *name)
1437 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1438 if (!strncmp(name, xfermode_name[i], 5))
1439 if (strlen(name) <= 5)
1440 return xfermode_val[i];
1442 /* Negative numbers are invalid and are caught later */
1443 val = bb_strtoi(name, NULL, 10);
1449 static void interpret_xfermode(unsigned xfermode)
1453 printf("default PIO mode");
1454 else if (xfermode == 1)
1455 printf("default PIO mode, disable IORDY");
1456 else if (xfermode >= 8 && xfermode <= 15)
1457 printf("PIO flow control mode%u", xfermode - 8);
1458 else if (xfermode >= 16 && xfermode <= 23)
1459 printf("singleword DMA mode%u", xfermode - 16);
1460 else if (xfermode >= 32 && xfermode <= 39)
1461 printf("multiword DMA mode%u", xfermode - 32);
1462 else if (xfermode >= 64 && xfermode <= 71)
1463 printf("UltraDMA mode%u", xfermode - 64);
1468 #endif /* HDIO_DRIVE_CMD */
1470 static void print_flag(int flag, const char *s, unsigned long value)
1473 printf(" setting %s to %ld\n", s, value);
1476 static void process_dev(char *devname)
1479 long parm, multcount;
1480 #ifndef HDIO_DRIVE_CMD
1481 int force_operation = 0;
1483 /* Please restore args[n] to these values after each ioctl
1484 except for args[2] */
1485 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1486 const char *fmt = " %s\t= %2ld";
1488 fd = xopen(devname, O_RDONLY|O_NONBLOCK);
1489 printf("\n%s:\n", devname);
1491 if (set_readahead) {
1492 print_flag(get_readahead, "fs readahead", Xreadahead);
1493 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1495 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1496 if (unregister_hwif) {
1497 printf(" attempting to unregister hwif#%lu\n", hwif);
1498 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1501 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1503 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1504 args[0] = hwif_data;
1505 args[1] = hwif_ctrl;
1507 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1508 args[0] = WIN_SETFEATURES;
1513 if (noisy_piomode) {
1514 printf(" attempting to ");
1516 printf("auto-tune PIO mode\n");
1517 else if (piomode < 100)
1518 printf("set PIO mode to %d\n", piomode);
1519 else if (piomode < 200)
1520 printf("set MDMA mode to %d\n", (piomode-100));
1522 printf("set UDMA mode to %d\n", (piomode-200));
1524 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1527 print_flag(get_io32bit, "32-bit IO_support flag", io32bit);
1528 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1531 print_flag(get_mult, "multcount", mult);
1532 #ifdef HDIO_DRIVE_CMD
1533 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1535 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1539 print_flag_on_off(get_readonly, "readonly", readonly);
1540 ioctl_or_warn(fd, BLKROSET, &readonly);
1543 print_flag_on_off(get_unmask, "unmaskirq", unmask);
1544 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1546 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1548 print_flag_on_off(get_dma, "using_dma", dma);
1549 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1551 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1553 print_flag_on_off(get_dma_q, "DMA queue_depth", dma_q);
1554 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1557 print_flag_on_off(get_nowerr, "nowerr", nowerr);
1558 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1561 print_flag_on_off(get_keep, "keep_settings", keep);
1562 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1564 #ifdef HDIO_DRIVE_CMD
1566 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1568 print_flag_on_off(get_doorlock, "drive doorlock", doorlock);
1569 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1570 args[0] = WIN_SETFEATURES;
1573 /* lock/unlock the drive's "feature" settings */
1574 print_flag_on_off(get_dkeep, "drive keep features", dkeep);
1575 args[2] = dkeep ? 0x66 : 0xcc;
1576 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1579 args[2] = defects ? 0x04 : 0x84;
1580 print_flag(get_defects, "drive defect-mgmt", defects);
1581 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1586 print_flag(get_prefetch, "drive prefetch", prefetch);
1587 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1591 args[1] = xfermode_requested;
1594 print_flag(1, "xfermode", xfermode_requested);
1595 interpret_xfermode(xfermode_requested);
1597 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1600 if (set_lookahead) {
1601 args[2] = lookahead ? 0xaa : 0x55;
1602 print_flag_on_off(get_lookahead, "drive read-lookahead", lookahead);
1603 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1606 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */; /* feature register */
1607 args[1] = apmmode; /* sector count register 1-255 */
1609 printf(" setting APM level to %s 0x%02lX (%ld)\n", (apmmode == 255) ? "disabled" : "", apmmode, apmmode);
1610 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1614 #ifdef DO_FLUSHCACHE
1615 #ifndef WIN_FLUSHCACHE
1616 #define WIN_FLUSHCACHE 0xe7
1618 static unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
1619 #endif /* DO_FLUSHCACHE */
1620 args[2] = wcache ? 0x02 : 0x82;
1621 print_flag_on_off(get_wcache, "drive write-caching", wcache);
1622 #ifdef DO_FLUSHCACHE
1624 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1625 #endif /* DO_FLUSHCACHE */
1626 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1627 #ifdef DO_FLUSHCACHE
1629 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1630 #endif /* DO_FLUSHCACHE */
1633 /* In code below, we do not preserve args[0], but the rest
1634 is preserved, including args[2] */
1637 if (set_standbynow) {
1638 #ifndef WIN_STANDBYNOW1
1639 #define WIN_STANDBYNOW1 0xE0
1641 #ifndef WIN_STANDBYNOW2
1642 #define WIN_STANDBYNOW2 0x94
1644 if (get_standbynow) printf(" issuing standby command\n");
1645 args[0] = WIN_STANDBYNOW1;
1646 ioctl_alt_or_warn(fd, HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1649 #ifndef WIN_SLEEPNOW1
1650 #define WIN_SLEEPNOW1 0xE6
1652 #ifndef WIN_SLEEPNOW2
1653 #define WIN_SLEEPNOW2 0x99
1655 if (get_sleepnow) printf(" issuing sleep command\n");
1656 args[0] = WIN_SLEEPNOW1;
1657 ioctl_alt_or_warn(fd, HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1661 if (get_seagate) printf(" disabling Seagate auto powersaving mode\n");
1662 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1665 args[0] = WIN_SETIDLE1;
1666 args[1] = standby_requested;
1668 print_flag(1, "standby", standby_requested);
1669 interpret_standby(standby_requested);
1671 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1674 #else /* HDIO_DRIVE_CMD */
1675 if (force_operation) {
1677 flush_buffer_cache(fd);
1678 if (-1 == read(fd, buf, sizeof(buf)))
1679 bb_perror_msg("read(%d bytes) failed (rc=%d)", sizeof(buf), -1);
1681 #endif /* HDIO_DRIVE_CMD */
1683 if (get_mult || get_identity) {
1685 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1686 if (get_mult && ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn. */
1687 bb_perror_msg("HDIO_GET_MULTCOUNT");
1689 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1690 } else if (get_mult) {
1691 printf(fmt, "multcount", multcount);
1692 on_off(multcount != 0);
1696 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1697 printf(" IO_support\t=%3ld (", parm);
1699 printf("default 16-bit)\n");
1701 printf("16-bit)\n");
1703 printf("32-bit)\n");
1705 printf("32-bit w/sync)\n");
1707 printf("Request-Queue-Bypass)\n");
1709 printf("\?\?\?)\n");
1713 if(!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, (unsigned long *)parm))
1714 print_value_on_off("unmaskirq", parm);
1718 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1720 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1721 printf(fmt, "using_dma", parm);
1723 printf(" (DMA-Assisted-PIO)\n");
1730 if(!ioctl_or_warn(fd, HDIO_GET_QDMA, (unsigned long *)parm))
1731 print_value_on_off("queue_depth", parm);
1734 if(!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, (unsigned long *)parm))
1735 print_value_on_off("keepsettings", parm);
1739 if(!ioctl_or_warn(fd, HDIO_GET_NOWERR, (unsigned long *)parm))
1740 print_value_on_off("nowerr", parm);
1743 if(!ioctl_or_warn(fd, BLKROGET, (unsigned long *)parm))
1744 print_value_on_off("readonly", parm);
1746 if (get_readahead) {
1747 if(!ioctl_or_warn(fd, BLKRAGET, (unsigned long *)parm))
1748 print_value_on_off("readahead", parm);
1751 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1752 struct hd_geometry g;
1754 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1755 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1756 g.cylinders, g.heads, g.sectors, parm, g.start);
1759 #ifdef HDIO_DRIVE_CMD
1760 if (get_powermode) {
1761 #ifndef WIN_CHECKPOWERMODE1
1762 #define WIN_CHECKPOWERMODE1 0xE5
1764 #ifndef WIN_CHECKPOWERMODE2
1765 #define WIN_CHECKPOWERMODE2 0x98
1769 args[0] = WIN_CHECKPOWERMODE1;
1770 if (ioctl_alt_or_warn(fd, HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1771 if (errno != EIO || args[0] != 0 || args[1] != 0)
1776 state = (args[2] == 255) ? "active/idle" : "standby";
1777 args[1] = args[2] = 0;
1779 printf(" drive state is: %s\n", state);
1782 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1783 if (perform_reset) {
1784 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1786 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1787 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1788 if (perform_tristate) {
1791 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1793 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1794 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1796 struct hd_driveid id;
1798 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1799 if (multcount != -1) {
1800 id.multsect = multcount;
1801 id.multsect_valid |= 1;
1803 id.multsect_valid &= ~1;
1805 } else if (errno == -ENOMSG)
1806 printf(" no identification info available\n");
1807 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1808 bb_perror_msg("HDIO_GET_IDENTITY");
1810 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1814 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1816 memset(args1, 0, sizeof(args1));
1817 args1[0] = WIN_IDENTIFY;
1819 if (!ioctl_alt_or_warn(fd, HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1820 identify((void *)(args1 + 4));
1823 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1826 print_flag(1, "bus state", busstate);
1827 bus_state_value(busstate);
1829 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1832 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1833 printf(fmt, "bus state", parm);
1834 bus_state_value(parm);
1839 ioctl_or_warn(fd, BLKRRPART, NULL);
1842 do_time(0, fd); /* time cache */
1844 do_time(1, fd); /* time device */
1846 flush_buffer_cache(fd);
1850 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1851 static int fromhex(unsigned char c)
1855 if (c >= 'a' && c <= 'f')
1856 return (c - ('a' - 10));
1857 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1860 static void identify_from_stdin(void)
1863 unsigned char buf[1280];
1864 unsigned char *b = (unsigned char *)buf;
1867 xread(0, buf, 1280);
1869 // Convert the newline-separated hex data into an identify block.
1871 for (i = 0; i < 256; i++) {
1873 for (j = 0; j < 4; j++)
1874 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1883 /* busybox specific stuff */
1884 static void parse_opts(smallint *get, smallint *set, unsigned long *value, int min, int max)
1891 *value = xatol_range(optarg, min, max);
1895 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
1900 *value = translate_xfermode(optarg);
1901 *set = (*value > -1);
1906 /*------- getopt short options --------*/
1907 static const char hdparm_options[] ALIGN1 =
1908 "gfu::n::p:r::m::c::k::a::B:tTh"
1909 USE_FEATURE_HDPARM_GET_IDENTITY("iI")
1910 USE_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
1911 #ifdef HDIO_DRIVE_CMD
1912 "S:D:P:X:K:A:L:W:CyYzZ"
1914 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
1915 #ifdef HDIO_GET_QDMA
1916 #ifdef HDIO_SET_QDMA
1922 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
1923 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
1924 USE_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
1925 /*-------------------------------------*/
1927 /* our main() routine: */
1928 int hdparm_main(int argc, char **argv);
1929 int hdparm_main(int argc, char **argv)
1934 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
1936 if (c == 'h') bb_show_usage(); /* EXIT */
1937 USE_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
1938 USE_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
1939 get_geom |= (c == 'g');
1940 do_flush |= (c == 'f');
1941 if (c == 'u') parse_opts(&get_unmask, &set_unmask, &unmask, 0, 1);
1942 USE_FEATURE_HDPARM_HDIO_GETSET_DMA(if (c == 'd') parse_opts(&get_dma, &set_dma, &dma, 0, 9));
1943 if (c == 'n') parse_opts(&get_nowerr, &set_nowerr, &nowerr, 0, 1);
1944 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
1945 if (c == 'r') parse_opts(&get_readonly, &set_readonly, &readonly, 0, 1);
1946 if (c == 'm') parse_opts(&get_mult, &set_mult, &mult, 0, INT_MAX /*32*/);
1947 if (c == 'c') parse_opts(&get_io32bit, &set_io32bit, &io32bit, 0, INT_MAX /*8*/);
1948 if (c == 'k') parse_opts(&get_keep, &set_keep, &keep, 0, 1);
1949 if (c == 'a') parse_opts(&get_readahead, &set_readahead, &Xreadahead, 0, INT_MAX);
1950 if (c == 'B') parse_opts(&get_apmmode, &set_apmmode, &apmmode, 1, 255);
1951 do_flush |= do_timings |= (c == 't');
1952 do_flush |= do_ctimings |= (c == 'T');
1953 #ifdef HDIO_DRIVE_CMD
1954 if (c == 'S') parse_opts(&get_standby, &set_standby, &standby_requested, 0, INT_MAX);
1955 if (c == 'D') parse_opts(&get_defects, &set_defects, &defects, 0, INT_MAX);
1956 if (c == 'P') parse_opts(&get_prefetch, &set_prefetch, &prefetch, 0, INT_MAX);
1957 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
1958 if (c == 'K') parse_opts(&get_dkeep, &set_dkeep, &prefetch, 0, 1);
1959 if (c == 'A') parse_opts(&get_lookahead, &set_lookahead, &lookahead, 0, 1);
1960 if (c == 'L') parse_opts(&get_doorlock, &set_doorlock, &doorlock, 0, 1);
1961 if (c == 'W') parse_opts(&get_wcache, &set_wcache, &wcache, 0, 1);
1962 get_powermode |= (c == 'C');
1963 get_standbynow = set_standbynow |= (c == 'y');
1964 get_sleepnow = set_sleepnow |= (c == 'Y');
1965 reread_partn |= (c == 'z');
1966 get_seagate = set_seagate |= (c == 'Z');
1968 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') parse_opts(NULL, &unregister_hwif, &hwif, 0, INT_MAX));
1969 #ifdef HDIO_GET_QDMA
1971 #ifdef HDIO_SET_QDMA
1972 parse_opts(&get_dma_q, &set_dma_q, &dma_q, 0, INT_MAX);
1974 parse_opts(&get_dma_q, NULL, NULL, 0, 0);
1978 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
1979 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') parse_opts(NULL, &perform_tristate, &tristate, 0, 1));
1980 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') parse_opts(&get_busstate, &set_busstate, &busstate, 0, 2));
1981 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1983 parse_opts(NULL, &scan_hwif, &hwif_data, 0, INT_MAX);
1984 hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
1985 hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
1986 /* Move past the 2 additional arguments */
1992 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
1994 get_mult = get_io32bit = get_unmask = get_keep = get_readonly = get_readahead = get_geom = 1;
1995 USE_FEATURE_HDPARM_HDIO_GETSET_DMA(get_dma = 1);
2000 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2001 identify_from_stdin(); /* EXIT */
2002 else bb_show_usage();
2006 process_dev(*argv++);
2009 return EXIT_SUCCESS;