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 */
385 /* words 85-87: cmds/feats enabled */
386 /* use cmd_feat_str[] to display what commands and features have
387 * been enabled with words 85-87
390 /* words 89, 90, SECU ERASE TIME */
391 #define ERASE_BITS 0x00ff
393 /* word 92: master password revision */
394 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
396 /* word 93: hw reset result */
397 #define CBLID 0x2000 /* CBLID status */
398 #define RST0 0x0001 /* 1=reset to device #0 */
399 #define DEV_DET 0x0006 /* how device num determined */
400 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
401 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
403 /* word 127: removable media status notification feature set support */
404 #define RM_STAT_BITS 0x0003
405 #define RM_STAT_SUP 0x0001
407 /* word 128: security */
408 #define SECU_ENABLED 0x0002
409 #define SECU_LEVEL 0x0010
410 #define NUM_SECU_STR 6
411 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
412 static const char *const secu_str[] = {
413 "supported", /* word 128, bit 0 */
414 "enabled", /* word 128, bit 1 */
415 "locked", /* word 128, bit 2 */
416 "frozen", /* word 128, bit 3 */
417 "expired: security count", /* word 128, bit 4 */
418 "supported: enhanced erase" /* word 128, bit 5 */
422 /* word 160: CFA power mode */
423 #define VALID_W160 0x8000 /* 1=word valid */
424 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
425 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
426 #define MAX_AMPS 0x0fff /* value = max current in ma */
428 /* word 255: integrity */
429 #define SIG 0x00ff /* signature location */
430 #define SIG_VAL 0x00a5 /* signature value */
432 #define TIMING_BUF_MB 1
433 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
435 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
442 smallint get_identity, get_geom;
444 smallint do_ctimings, do_timings;
445 smallint reread_partn;
446 smallint set_piomode, noisy_piomode;
447 smallint set_readahead, get_readahead;
448 smallint set_readonly, get_readonly;
449 smallint set_unmask, get_unmask;
450 smallint set_mult, get_mult;
451 smallint set_dma_q, get_dma_q;
452 smallint set_nowerr, get_nowerr;
453 smallint set_keep, get_keep;
454 smallint set_io32bit, get_io32bit;
456 unsigned long Xreadahead;
457 unsigned long readonly;
458 unsigned long unmask;
461 unsigned long nowerr;
463 unsigned long io32bit;
464 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
466 smallint set_dma, get_dma;
468 #ifdef HDIO_DRIVE_CMD
469 smallint set_xfermode, get_xfermode;
470 smallint set_dkeep, get_dkeep;
471 smallint set_standby, get_standby;
472 smallint set_lookahead, get_lookahead;
473 smallint set_prefetch, get_prefetch;
474 smallint set_defects, get_defects;
475 smallint set_wcache, get_wcache;
476 smallint set_doorlock, get_doorlock;
477 smallint set_seagate, get_seagate;
478 smallint set_standbynow, get_standbynow;
479 smallint set_sleepnow, get_sleepnow;
480 smallint get_powermode;
481 smallint set_apmmode, get_apmmode;
482 int xfermode_requested;
484 unsigned long standby_requested;
485 unsigned long lookahead;
486 unsigned long prefetch;
487 unsigned long defects;
488 unsigned long wcache;
489 unsigned long doorlock;
490 unsigned long apmmode;
492 USE_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
493 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint set_busstate, get_busstate;)
494 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
495 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
496 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
497 USE_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
498 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
499 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
500 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
501 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
502 unsigned long hwif_data;
503 unsigned long hwif_ctrl;
504 unsigned long hwif_irq;
507 unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
510 #define G (*(struct globals*)&bb_common_bufsiz1)
511 struct BUG_G_too_big {
512 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
514 #define get_identity (G.get_identity )
515 #define get_geom (G.get_geom )
516 #define do_flush (G.do_flush )
517 #define do_ctimings (G.do_ctimings )
518 #define do_timings (G.do_timings )
519 #define reread_partn (G.reread_partn )
520 #define set_piomode (G.set_piomode )
521 #define noisy_piomode (G.noisy_piomode )
522 #define set_readahead (G.set_readahead )
523 #define get_readahead (G.get_readahead )
524 #define set_readonly (G.set_readonly )
525 #define get_readonly (G.get_readonly )
526 #define set_unmask (G.set_unmask )
527 #define get_unmask (G.get_unmask )
528 #define set_mult (G.set_mult )
529 #define get_mult (G.get_mult )
530 #define set_dma_q (G.set_dma_q )
531 #define get_dma_q (G.get_dma_q )
532 #define set_nowerr (G.set_nowerr )
533 #define get_nowerr (G.get_nowerr )
534 #define set_keep (G.set_keep )
535 #define get_keep (G.get_keep )
536 #define set_io32bit (G.set_io32bit )
537 #define get_io32bit (G.get_io32bit )
538 #define piomode (G.piomode )
539 #define Xreadahead (G.Xreadahead )
540 #define readonly (G.readonly )
541 #define unmask (G.unmask )
542 #define mult (G.mult )
543 #define dma_q (G.dma_q )
544 #define nowerr (G.nowerr )
545 #define keep (G.keep )
546 #define io32bit (G.io32bit )
548 #define set_dma (G.set_dma )
549 #define get_dma (G.get_dma )
550 #define set_xfermode (G.set_xfermode )
551 #define get_xfermode (G.get_xfermode )
552 #define set_dkeep (G.set_dkeep )
553 #define get_dkeep (G.get_dkeep )
554 #define set_standby (G.set_standby )
555 #define get_standby (G.get_standby )
556 #define set_lookahead (G.set_lookahead )
557 #define get_lookahead (G.get_lookahead )
558 #define set_prefetch (G.set_prefetch )
559 #define get_prefetch (G.get_prefetch )
560 #define set_defects (G.set_defects )
561 #define get_defects (G.get_defects )
562 #define set_wcache (G.set_wcache )
563 #define get_wcache (G.get_wcache )
564 #define set_doorlock (G.set_doorlock )
565 #define get_doorlock (G.get_doorlock )
566 #define set_seagate (G.set_seagate )
567 #define get_seagate (G.get_seagate )
568 #define set_standbynow (G.set_standbynow )
569 #define get_standbynow (G.get_standbynow )
570 #define set_sleepnow (G.set_sleepnow )
571 #define get_sleepnow (G.get_sleepnow )
572 #define get_powermode (G.get_powermode )
573 #define set_apmmode (G.set_apmmode )
574 #define get_apmmode (G.get_apmmode )
575 #define xfermode_requested (G.xfermode_requested )
576 #define dkeep (G.dkeep )
577 #define standby_requested (G.standby_requested )
578 #define lookahead (G.lookahead )
579 #define prefetch (G.prefetch )
580 #define defects (G.defects )
581 #define wcache (G.wcache )
582 #define doorlock (G.doorlock )
583 #define apmmode (G.apmmode )
584 #define get_IDentity (G.get_IDentity )
585 #define set_busstate (G.set_busstate )
586 #define get_busstate (G.get_busstate )
587 #define perform_reset (G.perform_reset )
588 #define perform_tristate (G.perform_tristate )
589 #define unregister_hwif (G.unregister_hwif )
590 #define scan_hwif (G.scan_hwif )
591 #define busstate (G.busstate )
592 #define tristate (G.tristate )
593 #define hwif (G.hwif )
594 #define hwif_data (G.hwif_data )
595 #define hwif_ctrl (G.hwif_ctrl )
596 #define hwif_irq (G.hwif_irq )
599 /* Busybox messages and functions */
600 #if ENABLE_IOCTL_HEX2STR_ERROR
601 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
603 if (!ioctl(fd, cmd, args))
606 return bb_ioctl_or_warn(fd, cmd, args, string);
608 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
610 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
612 if (!ioctl(fd, cmd, args))
615 return bb_ioctl_or_warn(fd, cmd, args);
617 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
620 static void on_off(int value)
622 puts(value ? " (on)" : " (off)");
625 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
628 printf(" setting %s to %ld", s, arg);
633 static void print_value_on_off(const char *str, unsigned long argp)
635 printf(" %s\t= %2ld", str, argp);
639 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
640 static void print_ascii(const char *p, int length)
647 /* every 16bit word is big-endian (i.e. inverted) */
648 /* accessing bytes in 1,0, 3,2, 5,4... sequence */
653 /* find first non-space & print it */
654 while (length && p[ofs] != ' ') {
659 while (length && p[ofs]) {
669 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
672 printf("\t%-20s", string);
673 print_ascii((void*)&val[i], n);
677 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
682 for (ii = 0; ii <= MODE_MAX; ii++) {
683 if (mode_sel & 0x0001) {
684 printf("*%cdma%u ", cc, ii);
688 } else if (mode_sup & 0x0001)
689 printf("%cdma%u ", cc, ii);
697 // Parse 512 byte disk identification block and print much crap.
699 static void identify(uint16_t *val) ATTRIBUTE_NORETURN;
700 static void identify(uint16_t *val)
703 uint16_t like_std = 1, std = 0, min_std = 0xffff;
704 uint16_t dev = NO_DEV, eqpt = NO_DEV;
705 uint8_t have_mode = 0, err_dma = 0;
707 uint32_t ll, mm, nn, oo;
708 uint64_t bbbig; /* (:) */
713 // Adjust for endianness
714 swab(val, buf, sizeof(buf));
717 /* check if we recognise the device type */
719 if (!(val[GEN_CONFIG] & NOT_ATA)) {
721 printf("ATA device, with ");
722 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
725 printf("CompactFlash ATA device, with ");
726 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
728 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
729 printf("ATAPI %s, with ", pkt_str[eqpt]);
732 /*"Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n"*/
733 bb_error_msg_and_die("unknown device type");
735 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
736 /* Info from the specific configuration word says whether or not the
737 * ID command completed correctly. It is only defined, however in
738 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
739 * standards. Since the values allowed for this word are extremely
740 * specific, it should be safe to check it now, even though we don't
741 * know yet what standard this device is using.
743 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
744 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
747 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
748 printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
749 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
750 printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
753 /* output the model and serial numbers and the fw revision */
754 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
755 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
756 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
757 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
758 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
760 /* major & minor standards version number (Note: these words were not
761 * defined until ATA-3 & the CDROM std uses different words.) */
762 printf("Standards:");
764 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
765 if (like_std < 3) like_std = 3;
766 std = actual_ver[val[MINOR]];
767 if (std) printf("\n\tUsed: %s ", minor_str[val[MINOR]]);
770 /* looks like when they up-issue the std, they obsolete one;
771 * thus, only the newest 4 issues need be supported. (That's
772 * what "kk" and "min_std" are all about.) */
773 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
774 printf("\n\tSupported: ");
775 jj = val[MAJOR] << 1;
776 kk = like_std >4 ? like_std-4: 0;
777 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
782 kk = like_std >4 ? like_std-4: 0;
784 if (min_std > ii) min_std = ii;
788 if (like_std < 3) like_std = 3;
790 /* Figure out what standard the device is using if it hasn't told
791 * us. If we know the std, check if the device is using any of
792 * the words from the next level up. It happens.
794 if (like_std < std) like_std = std;
796 if (((std == 5) || (!std && (like_std < 6))) &&
797 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
798 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
799 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
800 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
803 } else if (((std == 4) || (!std && (like_std < 5))) &&
804 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
805 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
806 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
807 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
810 } else if (((std == 3) || (!std && (like_std < 4))) &&
811 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
812 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
813 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
814 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
815 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
816 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
819 } else if (((std == 2) || (!std && (like_std < 3)))
820 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
823 } else if (((std == 1) || (!std && (like_std < 2))) &&
824 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
825 (val[WHATS_VALID] & OK_W64_70)) )
831 printf("\n\tLikely used: %u\n", like_std);
832 else if (like_std > std)
833 printf("& some of %u\n", like_std);
837 /* TBD: do CDROM stuff more thoroughly. For now... */
839 if (val[CDR_MINOR] == 9) {
841 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
843 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
845 printf("\n\tSupported: CD-ROM ATAPI");
846 jj = val[CDR_MAJOR] >> 1;
847 for (ii = 1; ii < 15; ii++) {
848 if (jj & 0x0001) printf("-%u ", ii);
852 printf("%s\n", kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
853 /* the cdrom stuff is more like ATA-2 than anything else, so: */
857 if (min_std == 0xffff)
858 min_std = like_std > 4 ? like_std - 3 : 1;
860 printf("Configuration:\n");
861 /* more info from the general configuration word */
862 if ((eqpt != CDROM) && (like_std == 1)) {
863 jj = val[GEN_CONFIG] >> 1;
864 for (ii = 1; ii < 15; ii++) {
866 printf("\t%s\n", ata1_cfg_str[ii]);
870 if (dev == ATAPI_DEV) {
871 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
873 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
874 strng = "<=10ms with INTRQ";
875 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
879 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
881 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
883 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
889 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
890 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
892 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
893 printf("\tCHS addressing not supported\n");
895 jj = val[WHATS_VALID] & OK_W54_58;
896 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",
897 val[LCYLS],jj?val[LCYLS_CUR]:0, val[LHEADS],jj?val[LHEADS_CUR]:0, val[LSECTS],jj?val[LSECTS_CUR]:0);
899 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
900 printf("\tbytes/track: %u\tbytes/sector: %u\n", val[TRACK_BYTES], val[SECT_BYTES]);
903 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
905 /* check Endian of capacity bytes */
906 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
907 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
908 if (abs(mm - nn) > abs(oo - nn))
911 printf("\tCHS current addressable sectors:%11u\n", mm);
915 printf("\tLBA user addressable sectors:%11u\n", ll);
916 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
917 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
919 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
920 (uint64_t)val[LBA_48_MSB] << 32 |
921 (uint64_t)val[LBA_MID] << 16 |
923 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
927 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
928 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
929 bbbig = (bbbig << 9) / 1000000;
930 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
933 printf("(%"PRIu64" GB)\n", bbbig/1000);
938 /* hw support of commands (capabilities) */
939 printf("Capabilities:\n\t");
941 if (dev == ATAPI_DEV) {
942 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP)) printf("Cmd queuing, ");
943 if (val[CAPAB_0] & OVLP_SUP) printf("Cmd overlap, ");
945 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
948 printf("IORDY%s(can%s be disabled)\n",
949 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
950 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
952 printf("no IORDY\n");
954 if ((like_std == 1) && val[BUF_TYPE]) {
955 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
956 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
957 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
960 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
961 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
963 if ((min_std < 4) && (val[RW_LONG])) {
964 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
966 if ((eqpt != CDROM) && (like_std > 3)) {
967 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
970 if (dev == ATA_DEV) {
972 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
974 printf("\tStandby timer values: spec'd by %s", (val[CAPAB_0] & STD_STBY) ? "Standard" : "Vendor");
975 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
976 printf(", %s device specific minimum\n", (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
980 printf("\tR/W multiple sector transfer: ");
981 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
982 printf("not supported\n");
984 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
985 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
986 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
990 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
991 /* We print out elsewhere whether the APM feature is enabled or
992 not. If it's not enabled, let's not repeat the info; just print
994 printf("\tAdvancedPM level: ");
995 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
996 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
997 printf("%u (0x%x)\n", apm_level, apm_level);
1000 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
1002 if (like_std > 5 && val[ACOUSTIC]) {
1003 printf("\tRecommended acoustic management value: %u, current value: %u\n",
1004 (val[ACOUSTIC] >> 8) & 0x00ff, val[ACOUSTIC] & 0x00ff);
1008 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
1009 printf("\tATA sw reset required\n");
1011 if (val[PKT_REL] || val[SVC_NBSY]) {
1012 printf("\tOverlap support:");
1013 if (val[PKT_REL]) printf(" %uus to release bus.", val[PKT_REL]);
1014 if (val[SVC_NBSY]) printf(" %uus to clear BSY after SERVICE cmd.", val[SVC_NBSY]);
1019 /* DMA stuff. Check that only one DMA mode is selected. */
1021 if (!(val[CAPAB_0] & DMA_SUP))
1022 printf("not supported\n");
1024 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1025 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1026 if (val[SINGLE_DMA]) {
1027 jj = val[SINGLE_DMA];
1028 kk = val[SINGLE_DMA] >> 8;
1029 err_dma += mode_loop(jj, kk, 's', &have_mode);
1031 if (val[MULTI_DMA]) {
1032 jj = val[MULTI_DMA];
1033 kk = val[MULTI_DMA] >> 8;
1034 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1036 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1037 jj = val[ULTRA_DMA];
1038 kk = val[ULTRA_DMA] >> 8;
1039 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1041 if (err_dma || !have_mode) printf("(?)");
1044 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1045 printf("\t\tInterleaved DMA support\n");
1047 if ((val[WHATS_VALID] & OK_W64_70)
1048 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1050 printf("\t\tCycle time:");
1051 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1052 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1057 /* Programmed IO stuff */
1059 /* If a drive supports mode n (e.g. 3), it also supports all modes less
1060 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1061 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1062 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1063 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1064 if (jj & 0x0001) printf("pio%d ", ii);
1068 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1069 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1070 printf("pio%d ", ii);
1073 printf("unknown\n");
1075 if (val[WHATS_VALID] & OK_W64_70) {
1076 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1077 printf("\t\tCycle time:");
1078 if (val[PIO_NO_FLOW]) printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1079 if (val[PIO_FLOW]) printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1084 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1085 printf("Commands/features:\n\tEnabled\tSupported:\n");
1086 jj = val[CMDS_SUPP_0];
1087 kk = val[CMDS_EN_0];
1088 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1089 if ((jj & 0x8000) && (*cmd_feat_str[ii] != '\0')) {
1090 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", cmd_feat_str[ii]);
1094 if (ii % 16 == 15) {
1095 jj = val[CMDS_SUPP_0+1+(ii/16)];
1096 kk = val[CMDS_EN_0+1+(ii/16)];
1099 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1104 /* Removable Media Status Notification feature set */
1105 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1106 printf("\t%s supported\n", cmd_feat_str[27]);
1109 if ((eqpt != CDROM) && (like_std > 3)
1110 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1112 printf("Security:\n");
1113 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1114 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1115 jj = val[SECU_STATUS];
1117 for (ii = 0; ii < NUM_SECU_STR; ii++) {
1118 printf("\t%s\t%s\n", (!(jj & 0x0001)) ? "not" : "", secu_str[ii]);
1121 if (val[SECU_STATUS] & SECU_ENABLED) {
1122 printf("\tSecurity level %s\n", (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1125 jj = val[ERASE_TIME] & ERASE_BITS;
1126 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1129 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1130 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1136 jj = val[HWRST_RSLT];
1137 if ((jj & VALID) == VALID_VAL) {
1138 if (!(oo = (jj & RST0)))
1140 if ((jj & DEV_DET) == JUMPER_VAL)
1141 strng = " determined by the jumper";
1142 else if ((jj & DEV_DET) == CSEL_VAL)
1143 strng = " determined by CSEL";
1146 printf("HW reset results:\n\tCBLID- %s Vih\n\tDevice num = %i%s\n",
1147 (val[HWRST_RSLT] & CBLID) ? "above" : "below", !(oo), strng);
1150 /* more stuff from std 5 */
1151 if ((like_std > 4) && (eqpt != CDROM)) {
1152 if (val[CFA_PWR_MODE] & VALID_W160) {
1153 printf("CFA power mode 1:\n\t%s%s\n", (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1154 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1156 if (val[CFA_PWR_MODE] & MAX_AMPS)
1157 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1159 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1160 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1168 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1169 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1170 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1171 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1172 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1173 // (which they should, but they should just return -EINVAL).
1175 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1176 // On a really old system, it will not, and we will be confused.
1179 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1180 static const char *const cfg_str[] = {
1181 "", "HardSect", "SoftSect", "NotMFM",
1182 "HdSw>15uSec", "SpinMotCtl", "Fixed", "Removeable",
1183 "DTR<=5Mbs", "DTR>5Mbs", "DTR>10Mbs", "RotSpdTol>.5%",
1184 "dStbOff", "TrkOff", "FmtGapReq", "nonMagnetic"
1187 static const char *const BuffType[] = {
1188 "Unknown", "1Sect", "DualPort", "DualPortCache"
1191 static void dump_identity(const struct hd_driveid *id)
1194 const unsigned short int *id_regs = (const void*) id;
1196 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1197 id->model, id->fw_rev, id->serial_no);
1198 for (i = 0; i <= 15; i++) {
1199 if (id->config & (1<<i))
1200 printf(" %s", cfg_str[i]);
1202 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1203 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1204 id->cyls, id->heads, id->sectors, id->track_bytes,
1205 id->sector_bytes, id->ecc_bytes,
1206 id->buf_type, BuffType[(id->buf_type > 3) ? 0 : id->buf_type],
1207 id->buf_size/2, id->max_multsect);
1208 if (id->max_multsect) {
1209 printf(", MultSect=");
1210 if (!(id->multsect_valid & 1))
1211 printf("?%u?", id->multsect);
1212 else if (id->multsect)
1213 printf("%u", id->multsect);
1219 if (!(id->field_valid & 1))
1220 printf(" (maybe):");
1222 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1225 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1226 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1227 ((id->capability&2) == 0) ? "no" : "yes");
1229 if (id->capability & 2)
1230 printf(", LBAsects=%u", id->lba_capacity);
1232 printf("\n IORDY=%s", (id->capability & 8) ? (id->capability & 4) ? "on/off" : "yes" : "no");
1234 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1235 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1237 if ((id->capability & 1) && (id->field_valid & 2))
1238 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1240 printf("\n PIO modes: ");
1241 if (id->tPIO <= 5) {
1243 if (id->tPIO >= 1) printf("pio1 ");
1244 if (id->tPIO >= 2) printf("pio2 ");
1246 if (id->field_valid & 2) {
1247 if (id->eide_pio_modes & 1) printf("pio3 ");
1248 if (id->eide_pio_modes & 2) printf("pio4 ");
1249 if (id->eide_pio_modes &~3) printf("pio? ");
1251 if (id->capability & 1) {
1252 if (id->dma_1word | id->dma_mword) {
1253 printf("\n DMA modes: ");
1254 if (id->dma_1word & 0x100) printf("*");
1255 if (id->dma_1word & 1) printf("sdma0 ");
1256 if (id->dma_1word & 0x200) printf("*");
1257 if (id->dma_1word & 2) printf("sdma1 ");
1258 if (id->dma_1word & 0x400) printf("*");
1259 if (id->dma_1word & 4) printf("sdma2 ");
1260 if (id->dma_1word & 0xf800) printf("*");
1261 if (id->dma_1word & 0xf8) printf("sdma? ");
1262 if (id->dma_mword & 0x100) printf("*");
1263 if (id->dma_mword & 1) printf("mdma0 ");
1264 if (id->dma_mword & 0x200) printf("*");
1265 if (id->dma_mword & 2) printf("mdma1 ");
1266 if (id->dma_mword & 0x400) printf("*");
1267 if (id->dma_mword & 4) printf("mdma2 ");
1268 if (id->dma_mword & 0xf800) printf("*");
1269 if (id->dma_mword & 0xf8) printf("mdma? ");
1272 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1273 printf("\n UDMA modes: ");
1274 if (id->dma_ultra & 0x100) printf("*");
1275 if (id->dma_ultra & 0x001) printf("udma0 ");
1276 if (id->dma_ultra & 0x200) printf("*");
1277 if (id->dma_ultra & 0x002) printf("udma1 ");
1278 if (id->dma_ultra & 0x400) printf("*");
1279 if (id->dma_ultra & 0x004) printf("udma2 ");
1280 #ifdef __NEW_HD_DRIVE_ID
1281 if (id->hw_config & 0x2000) {
1282 #else /* !__NEW_HD_DRIVE_ID */
1283 if (id->word93 & 0x2000) {
1284 #endif /* __NEW_HD_DRIVE_ID */
1285 if (id->dma_ultra & 0x0800) printf("*");
1286 if (id->dma_ultra & 0x0008) printf("udma3 ");
1287 if (id->dma_ultra & 0x1000) printf("*");
1288 if (id->dma_ultra & 0x0010) printf("udma4 ");
1289 if (id->dma_ultra & 0x2000) printf("*");
1290 if (id->dma_ultra & 0x0020) printf("udma5 ");
1291 if (id->dma_ultra & 0x4000) printf("*");
1292 if (id->dma_ultra & 0x0040) printf("udma6 ");
1293 if (id->dma_ultra & 0x8000) printf("*");
1294 if (id->dma_ultra & 0x0080) printf("udma7 ");
1297 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1298 if (id_regs[83] & 8) {
1299 if (!(id_regs[86] & 8))
1300 printf(": disabled (255)");
1301 else if ((id_regs[91] & 0xFF00) != 0x4000)
1302 printf(": unknown setting");
1304 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1306 if (id_regs[82] & 0x20)
1307 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1308 #ifdef __NEW_HD_DRIVE_ID
1309 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1310 || (id->major_rev_num && id->minor_rev_num <= 31)
1312 printf("\n Drive conforms to: %s: ", (id->minor_rev_num <= 31) ? minor_str[id->minor_rev_num] : "Unknown");
1313 if (id->major_rev_num != 0x0000 && /* NOVAL_0 */
1314 id->major_rev_num != 0xFFFF) { /* NOVAL_1 */
1315 for (i = 0; i <= 15; i++) {
1316 if (id->major_rev_num & (1<<i))
1317 printf(" ATA/ATAPI-%u", i);
1321 #endif /* __NEW_HD_DRIVE_ID */
1322 printf("\n\n * current active mode\n\n");
1326 static void flush_buffer_cache(/*int fd*/ void)
1328 fsync(fd); /* flush buffers */
1329 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1330 #ifdef HDIO_DRIVE_CMD
1332 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1333 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1334 bb_perror_msg("HDIO_DRIVE_CMD");
1336 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1341 static void seek_to_zero(/*int fd*/ void)
1343 xlseek(fd, (off_t) 0, SEEK_SET);
1346 static void read_big_block(/*int fd,*/ char *buf)
1350 xread(fd, buf, TIMING_BUF_BYTES);
1351 /* access all sectors of buf to ensure the read fully completed */
1352 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1356 static unsigned dev_size_mb(/*int fd*/ void)
1359 unsigned long long blksize64;
1363 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1364 u.blksize64 /= (1024 * 1024);
1366 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1367 u.blksize64 = u.blksize32 / (2 * 1024);
1369 if (u.blksize64 > UINT_MAX)
1374 static void print_timing(unsigned m, unsigned elapsed_us)
1376 unsigned sec = elapsed_us / 1000000;
1377 unsigned hs = (elapsed_us % 1000000) / 10000;
1379 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1381 /* + 1 prevents div-by-0 */
1382 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us + 1))
1383 // ~= (m * 1024) / (elapsed_us / 1000000)
1384 // = kb / elapsed_sec
1388 static void do_time(int cache /*,int fd*/)
1389 /* cache=1: time cache: repeatedly read N MB at offset 0
1390 * cache=0: time device: linear read, starting at offset 0
1393 unsigned max_iterations, iterations;
1394 unsigned start; /* doesn't need to be long long */
1395 unsigned elapsed, elapsed2;
1397 char *buf = xmalloc(TIMING_BUF_BYTES);
1399 if (mlock(buf, TIMING_BUF_BYTES))
1400 bb_perror_msg_and_die("mlock");
1402 /* Clear out the device request queues & give them time to complete.
1403 * NB: *small* delay. User is expected to have a clue and to not run
1404 * heavy io in parallel with measurements. */
1407 if (cache) { /* Time cache */
1409 read_big_block(buf);
1410 printf("Timing buffer-cache reads: ");
1411 } else { /* Time device */
1412 printf("Timing buffered disk reads:");
1416 /* Now do the timing */
1418 /* Max time to run (small for cache, avoids getting
1419 * huge total_MB which can overlow unsigned type) */
1420 elapsed2 = 510000; /* cache */
1421 max_iterations = UINT_MAX;
1423 elapsed2 = 3000000; /* not cache */
1424 /* Don't want to read past the end! */
1425 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1427 start = monotonic_us();
1431 read_big_block(buf);
1432 elapsed = (unsigned)monotonic_us() - start;
1434 } while (elapsed < elapsed2 && iterations < max_iterations);
1435 total_MB = iterations * TIMING_BUF_MB;
1436 //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1438 /* Cache: remove lseek() and monotonic_us() overheads
1440 start = monotonic_us();
1443 elapsed2 = (unsigned)monotonic_us() - start;
1444 } while (--iterations);
1445 //printf(" elapsed2:%u ", elapsed2);
1446 elapsed -= elapsed2;
1447 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1448 flush_buffer_cache();
1450 print_timing(total_MB, elapsed);
1451 munlock(buf, TIMING_BUF_BYTES);
1455 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1456 static void bus_state_value(unsigned value)
1458 if (value == BUSSTATE_ON)
1460 else if (value == BUSSTATE_OFF)
1462 else if (value == BUSSTATE_TRISTATE)
1463 printf(" (tristate)\n");
1465 printf(" (unknown: %d)\n", value);
1469 #ifdef HDIO_DRIVE_CMD
1470 static void interpret_standby(unsigned standby)
1477 else if (standby == 252)
1478 printf("21 minutes");
1479 else if (standby == 253)
1480 printf("vendor-specific");
1481 else if (standby == 254)
1483 else if (standby == 255)
1484 printf("21 minutes + 15 seconds");
1485 else if (standby <= 240) {
1487 printf("%u minutes + %u seconds", t / 60, t % 60);
1488 } else if (standby <= 251) {
1489 t = (standby - 240) * 30;
1490 printf("%u hours + %u minutes", t / 60, t % 60);
1492 printf("illegal value");
1496 static const uint8_t xfermode_val[] ALIGN1 = {
1497 8, 9, 10, 11, 12, 13, 14, 15,
1498 16, 17, 18, 19, 20, 21, 22, 23,
1499 32, 33, 34, 35, 36, 37, 38, 39,
1500 64, 65, 66, 67, 68, 69, 70, 71
1502 /* NB: we save size by _not_ storing terninating NUL! */
1503 static const char xfermode_name[][5] ALIGN1 = {
1504 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1505 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1506 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1507 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1510 static int translate_xfermode(const char *name)
1514 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1515 if (!strncmp(name, xfermode_name[i], 5))
1516 if (strlen(name) <= 5)
1517 return xfermode_val[i];
1519 /* Negative numbers are invalid and are caught later */
1520 val = bb_strtoi(name, NULL, 10);
1526 static void interpret_xfermode(unsigned xfermode)
1530 printf("default PIO mode");
1531 else if (xfermode == 1)
1532 printf("default PIO mode, disable IORDY");
1533 else if (xfermode >= 8 && xfermode <= 15)
1534 printf("PIO flow control mode%u", xfermode - 8);
1535 else if (xfermode >= 16 && xfermode <= 23)
1536 printf("singleword DMA mode%u", xfermode - 16);
1537 else if (xfermode >= 32 && xfermode <= 39)
1538 printf("multiword DMA mode%u", xfermode - 32);
1539 else if (xfermode >= 64 && xfermode <= 71)
1540 printf("UltraDMA mode%u", xfermode - 64);
1545 #endif /* HDIO_DRIVE_CMD */
1547 static void print_flag(int flag, const char *s, unsigned long value)
1550 printf(" setting %s to %ld\n", s, value);
1553 static void process_dev(char *devname)
1556 long parm, multcount;
1557 #ifndef HDIO_DRIVE_CMD
1558 int force_operation = 0;
1560 /* Please restore args[n] to these values after each ioctl
1561 except for args[2] */
1562 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1563 const char *fmt = " %s\t= %2ld";
1565 /*fd = xopen(devname, O_RDONLY | O_NONBLOCK);*/
1566 xmove_fd(xopen(devname, O_RDONLY | O_NONBLOCK), fd);
1567 printf("\n%s:\n", devname);
1569 if (set_readahead) {
1570 print_flag(get_readahead, "fs readahead", Xreadahead);
1571 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1573 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1574 if (unregister_hwif) {
1575 printf(" attempting to unregister hwif#%lu\n", hwif);
1576 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1579 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1581 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1582 args[0] = hwif_data;
1583 args[1] = hwif_ctrl;
1585 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1586 args[0] = WIN_SETFEATURES;
1591 if (noisy_piomode) {
1592 printf(" attempting to ");
1594 printf("auto-tune PIO mode\n");
1595 else if (piomode < 100)
1596 printf("set PIO mode to %d\n", piomode);
1597 else if (piomode < 200)
1598 printf("set MDMA mode to %d\n", (piomode-100));
1600 printf("set UDMA mode to %d\n", (piomode-200));
1602 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1605 print_flag(get_io32bit, "32-bit IO_support flag", io32bit);
1606 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1609 print_flag(get_mult, "multcount", mult);
1610 #ifdef HDIO_DRIVE_CMD
1611 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1613 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1617 print_flag_on_off(get_readonly, "readonly", readonly);
1618 ioctl_or_warn(fd, BLKROSET, &readonly);
1621 print_flag_on_off(get_unmask, "unmaskirq", unmask);
1622 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1624 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1626 print_flag_on_off(get_dma, "using_dma", dma);
1627 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1629 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1631 print_flag_on_off(get_dma_q, "DMA queue_depth", dma_q);
1632 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1635 print_flag_on_off(get_nowerr, "nowerr", nowerr);
1636 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1639 print_flag_on_off(get_keep, "keep_settings", keep);
1640 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1642 #ifdef HDIO_DRIVE_CMD
1644 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1646 print_flag_on_off(get_doorlock, "drive doorlock", doorlock);
1647 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1648 args[0] = WIN_SETFEATURES;
1651 /* lock/unlock the drive's "feature" settings */
1652 print_flag_on_off(get_dkeep, "drive keep features", dkeep);
1653 args[2] = dkeep ? 0x66 : 0xcc;
1654 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1657 args[2] = defects ? 0x04 : 0x84;
1658 print_flag(get_defects, "drive defect-mgmt", defects);
1659 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1664 print_flag(get_prefetch, "drive prefetch", prefetch);
1665 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1669 args[1] = xfermode_requested;
1672 print_flag(1, "xfermode", xfermode_requested);
1673 interpret_xfermode(xfermode_requested);
1675 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1678 if (set_lookahead) {
1679 args[2] = lookahead ? 0xaa : 0x55;
1680 print_flag_on_off(get_lookahead, "drive read-lookahead", lookahead);
1681 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1684 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */; /* feature register */
1685 args[1] = apmmode; /* sector count register 1-255 */
1687 printf(" setting APM level to %s 0x%02lX (%ld)\n", (apmmode == 255) ? "disabled" : "", apmmode, apmmode);
1688 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1692 #ifdef DO_FLUSHCACHE
1693 #ifndef WIN_FLUSHCACHE
1694 #define WIN_FLUSHCACHE 0xe7
1696 #endif /* DO_FLUSHCACHE */
1697 args[2] = wcache ? 0x02 : 0x82;
1698 print_flag_on_off(get_wcache, "drive write-caching", wcache);
1699 #ifdef DO_FLUSHCACHE
1701 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1702 #endif /* DO_FLUSHCACHE */
1703 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1704 #ifdef DO_FLUSHCACHE
1706 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1707 #endif /* DO_FLUSHCACHE */
1710 /* In code below, we do not preserve args[0], but the rest
1711 is preserved, including args[2] */
1714 if (set_standbynow) {
1715 #ifndef WIN_STANDBYNOW1
1716 #define WIN_STANDBYNOW1 0xE0
1718 #ifndef WIN_STANDBYNOW2
1719 #define WIN_STANDBYNOW2 0x94
1721 if (get_standbynow) printf(" issuing standby command\n");
1722 args[0] = WIN_STANDBYNOW1;
1723 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1726 #ifndef WIN_SLEEPNOW1
1727 #define WIN_SLEEPNOW1 0xE6
1729 #ifndef WIN_SLEEPNOW2
1730 #define WIN_SLEEPNOW2 0x99
1732 if (get_sleepnow) printf(" issuing sleep command\n");
1733 args[0] = WIN_SLEEPNOW1;
1734 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1738 if (get_seagate) printf(" disabling Seagate auto powersaving mode\n");
1739 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1742 args[0] = WIN_SETIDLE1;
1743 args[1] = standby_requested;
1745 print_flag(1, "standby", standby_requested);
1746 interpret_standby(standby_requested);
1748 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1751 #else /* HDIO_DRIVE_CMD */
1752 if (force_operation) {
1754 flush_buffer_cache();
1755 if (-1 == read(fd, buf, sizeof(buf)))
1756 bb_perror_msg("read(%d bytes) failed (rc=-1)", sizeof(buf));
1758 #endif /* HDIO_DRIVE_CMD */
1760 if (get_mult || get_identity) {
1762 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1763 if (get_mult && ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn. */
1764 bb_perror_msg("HDIO_GET_MULTCOUNT");
1766 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1767 } else if (get_mult) {
1768 printf(fmt, "multcount", multcount);
1769 on_off(multcount != 0);
1773 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1774 printf(" IO_support\t=%3ld (", parm);
1776 printf("default 16-bit)\n");
1778 printf("16-bit)\n");
1780 printf("32-bit)\n");
1782 printf("32-bit w/sync)\n");
1784 printf("Request-Queue-Bypass)\n");
1786 printf("\?\?\?)\n");
1790 if(!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, (unsigned long *)parm))
1791 print_value_on_off("unmaskirq", parm);
1795 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1797 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1798 printf(fmt, "using_dma", parm);
1800 printf(" (DMA-Assisted-PIO)\n");
1807 if(!ioctl_or_warn(fd, HDIO_GET_QDMA, (unsigned long *)parm))
1808 print_value_on_off("queue_depth", parm);
1811 if(!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, (unsigned long *)parm))
1812 print_value_on_off("keepsettings", parm);
1816 if(!ioctl_or_warn(fd, HDIO_GET_NOWERR, (unsigned long *)parm))
1817 print_value_on_off("nowerr", parm);
1820 if(!ioctl_or_warn(fd, BLKROGET, (unsigned long *)parm))
1821 print_value_on_off("readonly", parm);
1823 if (get_readahead) {
1824 if(!ioctl_or_warn(fd, BLKRAGET, (unsigned long *)parm))
1825 print_value_on_off("readahead", parm);
1828 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1829 struct hd_geometry g;
1831 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1832 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1833 g.cylinders, g.heads, g.sectors, parm, g.start);
1836 #ifdef HDIO_DRIVE_CMD
1837 if (get_powermode) {
1838 #ifndef WIN_CHECKPOWERMODE1
1839 #define WIN_CHECKPOWERMODE1 0xE5
1841 #ifndef WIN_CHECKPOWERMODE2
1842 #define WIN_CHECKPOWERMODE2 0x98
1846 args[0] = WIN_CHECKPOWERMODE1;
1847 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1848 if (errno != EIO || args[0] != 0 || args[1] != 0)
1853 state = (args[2] == 255) ? "active/idle" : "standby";
1854 args[1] = args[2] = 0;
1856 printf(" drive state is: %s\n", state);
1859 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1860 if (perform_reset) {
1861 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1863 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1864 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1865 if (perform_tristate) {
1868 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1870 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1871 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1873 struct hd_driveid id;
1875 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1876 if (multcount != -1) {
1877 id.multsect = multcount;
1878 id.multsect_valid |= 1;
1880 id.multsect_valid &= ~1;
1882 } else if (errno == -ENOMSG)
1883 printf(" no identification info available\n");
1884 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1885 bb_perror_msg("HDIO_GET_IDENTITY");
1887 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1891 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1893 memset(args1, 0, sizeof(args1));
1894 args1[0] = WIN_IDENTIFY;
1896 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1897 identify((void *)(args1 + 4));
1900 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1903 print_flag(1, "bus state", busstate);
1904 bus_state_value(busstate);
1906 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1909 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1910 printf(fmt, "bus state", parm);
1911 bus_state_value(parm);
1916 ioctl_or_warn(fd, BLKRRPART, NULL);
1919 do_time(1 /*,fd*/); /* time cache */
1921 do_time(0 /*,fd*/); /* time device */
1923 flush_buffer_cache();
1927 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1928 static int fromhex(unsigned char c)
1932 if (c >= 'a' && c <= 'f')
1933 return (c - ('a' - 10));
1934 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1937 static void identify_from_stdin(void) ATTRIBUTE_NORETURN;
1938 static void identify_from_stdin(void)
1941 unsigned char buf[1280];
1942 unsigned char *b = (unsigned char *)buf;
1945 xread(0, buf, 1280);
1947 // Convert the newline-separated hex data into an identify block.
1949 for (i = 0; i < 256; i++) {
1951 for (j = 0; j < 4; j++)
1952 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1960 void identify_from_stdin(void);
1963 /* busybox specific stuff */
1964 static void parse_opts(smallint *get, smallint *set, unsigned long *value, int min, int max)
1971 *value = xatol_range(optarg, min, max);
1975 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
1980 *value = translate_xfermode(optarg);
1981 *set = (*value > -1);
1986 /*------- getopt short options --------*/
1987 static const char hdparm_options[] ALIGN1 =
1988 "gfu::n::p:r::m::c::k::a::B:tT"
1989 USE_FEATURE_HDPARM_GET_IDENTITY("iI")
1990 USE_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
1991 #ifdef HDIO_DRIVE_CMD
1992 "S:D:P:X:K:A:L:W:CyYzZ"
1994 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
1995 #ifdef HDIO_GET_QDMA
1996 #ifdef HDIO_SET_QDMA
2002 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
2003 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
2004 USE_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
2005 /*-------------------------------------*/
2007 /* our main() routine: */
2008 int hdparm_main(int argc, char **argv);
2009 int hdparm_main(int argc, char **argv)
2014 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2016 USE_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2017 USE_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2018 get_geom |= (c == 'g');
2019 do_flush |= (c == 'f');
2020 if (c == 'u') parse_opts(&get_unmask, &set_unmask, &unmask, 0, 1);
2021 USE_FEATURE_HDPARM_HDIO_GETSET_DMA(if (c == 'd') parse_opts(&get_dma, &set_dma, &dma, 0, 9));
2022 if (c == 'n') parse_opts(&get_nowerr, &set_nowerr, &nowerr, 0, 1);
2023 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2024 if (c == 'r') parse_opts(&get_readonly, &set_readonly, &readonly, 0, 1);
2025 if (c == 'm') parse_opts(&get_mult, &set_mult, &mult, 0, INT_MAX /*32*/);
2026 if (c == 'c') parse_opts(&get_io32bit, &set_io32bit, &io32bit, 0, INT_MAX /*8*/);
2027 if (c == 'k') parse_opts(&get_keep, &set_keep, &keep, 0, 1);
2028 if (c == 'a') parse_opts(&get_readahead, &set_readahead, &Xreadahead, 0, INT_MAX);
2029 if (c == 'B') parse_opts(&get_apmmode, &set_apmmode, &apmmode, 1, 255);
2030 do_flush |= do_timings |= (c == 't');
2031 do_flush |= do_ctimings |= (c == 'T');
2032 #ifdef HDIO_DRIVE_CMD
2033 if (c == 'S') parse_opts(&get_standby, &set_standby, &standby_requested, 0, INT_MAX);
2034 if (c == 'D') parse_opts(&get_defects, &set_defects, &defects, 0, INT_MAX);
2035 if (c == 'P') parse_opts(&get_prefetch, &set_prefetch, &prefetch, 0, INT_MAX);
2036 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2037 if (c == 'K') parse_opts(&get_dkeep, &set_dkeep, &prefetch, 0, 1);
2038 if (c == 'A') parse_opts(&get_lookahead, &set_lookahead, &lookahead, 0, 1);
2039 if (c == 'L') parse_opts(&get_doorlock, &set_doorlock, &doorlock, 0, 1);
2040 if (c == 'W') parse_opts(&get_wcache, &set_wcache, &wcache, 0, 1);
2041 get_powermode |= (c == 'C');
2042 get_standbynow = set_standbynow |= (c == 'y');
2043 get_sleepnow = set_sleepnow |= (c == 'Y');
2044 reread_partn |= (c == 'z');
2045 get_seagate = set_seagate |= (c == 'Z');
2047 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') parse_opts(NULL, &unregister_hwif, &hwif, 0, INT_MAX));
2048 #ifdef HDIO_GET_QDMA
2050 #ifdef HDIO_SET_QDMA
2051 parse_opts(&get_dma_q, &set_dma_q, &dma_q, 0, INT_MAX);
2053 parse_opts(&get_dma_q, NULL, NULL, 0, 0);
2057 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2058 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') parse_opts(NULL, &perform_tristate, &tristate, 0, 1));
2059 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') parse_opts(&get_busstate, &set_busstate, &busstate, 0, 2));
2060 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2062 parse_opts(NULL, &scan_hwif, &hwif_data, 0, INT_MAX);
2063 hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
2064 hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
2065 /* Move past the 2 additional arguments */
2071 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2073 get_mult = get_io32bit = get_unmask = get_keep = get_readonly = get_readahead = get_geom = 1;
2074 USE_FEATURE_HDPARM_HDIO_GETSET_DMA(get_dma = 1);
2079 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2080 identify_from_stdin(); /* EXIT */
2085 process_dev(*argv++);
2088 return EXIT_SUCCESS;