1 /* vi: set sw=4 ts=4: */
3 * hdparm implementation for busybox
5 * Copyright (C) [2003] by [Matteo Croce] <3297627799@wind.it>
6 * Hacked by Tito <farmatito@tiscali.it> for size optimization.
8 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
10 * This program is based on the source code of hdparm: see below...
11 * hdparm.c - Command line interface to get/set hard disk parameters
12 * - by Mark Lord (C) 1994-2002 -- freely distributable
16 #include <linux/hdreg.h>
21 #define ATA_DEV 0x0000
22 #define ATAPI_DEV 0x0001
24 /* word definitions */
25 /* ---------------- */
26 #define GEN_CONFIG 0 /* general configuration */
27 #define LCYLS 1 /* number of logical cylinders */
28 #define CONFIG 2 /* specific configuration */
29 #define LHEADS 3 /* number of logical heads */
30 #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
31 #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
32 #define LSECTS 6 /* number of logical sectors/track */
33 #define START_SERIAL 10 /* ASCII serial number */
34 #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
35 #define BUF_TYPE 20 /* buffer type (ATA-1) */
36 #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
37 #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
38 #define START_FW_REV 23 /* ASCII firmware revision */
39 #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
40 #define START_MODEL 27 /* ASCII model number */
41 #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
42 #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
43 #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
44 #define CAPAB_0 49 /* capabilities */
46 #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
47 #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
48 #define WHATS_VALID 53 /* what fields are valid */
49 #define LCYLS_CUR 54 /* current logical cylinders */
50 #define LHEADS_CUR 55 /* current logical heads */
51 #define LSECTS_CUR 56 /* current logical sectors/track */
52 #define CAPACITY_LSB 57 /* current capacity in sectors */
53 #define CAPACITY_MSB 58
54 #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
55 #define LBA_SECTS_LSB 60 /* LBA: total number of user */
56 #define LBA_SECTS_MSB 61 /* addressable sectors */
57 #define SINGLE_DMA 62 /* singleword DMA modes */
58 #define MULTI_DMA 63 /* multiword DMA modes */
59 #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
60 /* multiword DMA xfer cycle time: */
61 #define DMA_TIME_MIN 65 /* - minimum */
62 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
63 /* minimum PIO xfer cycle time: */
64 #define PIO_NO_FLOW 67 /* - without flow control */
65 #define PIO_FLOW 68 /* - with IORDY flow control */
66 #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
67 #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
68 #define CDR_MAJOR 73 /* CD ROM: major version number */
69 #define CDR_MINOR 74 /* CD ROM: minor version number */
70 #define QUEUE_DEPTH 75 /* queue depth */
71 #define MAJOR 80 /* major version number */
72 #define MINOR 81 /* minor version number */
73 #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
74 #define CMDS_SUPP_1 83
75 #define CMDS_SUPP_2 84
76 #define CMDS_EN_0 85 /* command/feature set(s) enabled */
79 #define ULTRA_DMA 88 /* ultra DMA modes */
80 /* time to complete security erase */
81 #define ERASE_TIME 89 /* - ordinary */
82 #define ENH_ERASE_TIME 90 /* - enhanced */
83 #define ADV_PWR 91 /* current advanced power management level
84 in low byte, 0x40 in high byte. */
85 #define PSWD_CODE 92 /* master password revision code */
86 #define HWRST_RSLT 93 /* hardware reset result */
87 #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
88 #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
89 #define LBA_MID 101 /* bits are used, but addr 103 */
90 #define LBA_48_MSB 102 /* has been reserved for LBA in */
91 #define LBA_64_MSB 103 /* the future. */
92 #define RM_STAT 127 /* removable media status notification feature set support */
93 #define SECU_STATUS 128 /* security status */
94 #define CFA_PWR_MODE 160 /* CFA power mode 1 */
95 #define START_MEDIA 176 /* media serial number */
96 #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
97 #define START_MANUF 196 /* media manufacturer I.D. */
98 #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
99 #define INTEGRITY 255 /* integrity word */
101 /* bit definitions within the words */
102 /* -------------------------------- */
104 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
106 #define VALID_VAL 0x4000
107 /* many words are considered invalid if they are either all-0 or all-1 */
108 #define NOVAL_0 0x0000
109 #define NOVAL_1 0xffff
111 /* word 0: gen_config */
112 #define NOT_ATA 0x8000
113 #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
114 #define MEDIA_REMOVABLE 0x0080
115 #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
116 #define INCOMPLETE 0x0004
117 #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
118 #define DRQ_RESPONSE_TIME 0x0060
119 #define DRQ_3MS_VAL 0x0000
120 #define DRQ_INTR_VAL 0x0020
121 #define DRQ_50US_VAL 0x0040
122 #define PKT_SIZE_SUPPORTED 0x0003
123 #define PKT_SIZE_12_VAL 0x0000
124 #define PKT_SIZE_16_VAL 0x0001
125 #define EQPT_TYPE 0x1f00
130 /* word 1: number of logical cylinders */
131 #define LCYLS_MAX 0x3fff /* maximum allowable value */
133 /* word 2: specific configuration
134 * (a) require SET FEATURES to spin-up
135 * (b) require spin-up to fully reply to IDENTIFY DEVICE
137 #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
138 #define STBY_ID_VAL 0x738c /* (a) and not (b) */
139 #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
140 #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
142 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
143 #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
144 #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
146 /* word 49: capabilities 0 */
147 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
148 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
149 #define IORDY_OFF 0x0400 /* 1=may be disabled */
150 #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
151 #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
152 #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
153 #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
154 #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
155 #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
157 /* word 50: capabilities 1 */
158 #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
160 /* words 51 & 52: PIO & DMA cycle times */
161 #define MODE 0xff00 /* the mode is in the MSBs */
163 /* word 53: whats_valid */
164 #define OK_W88 0x0004 /* the ultra_dma info is valid */
165 #define OK_W64_70 0x0002 /* see above for word descriptions */
166 #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
168 /*word 63,88: dma_mode, ultra_dma_mode*/
169 #define MODE_MAX 7 /* bit definitions force udma <=7 (when
170 * udma >=8 comes out it'll have to be
171 * defined in a new dma_mode word!) */
173 /* word 64: PIO transfer modes */
174 #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
175 #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
177 /* word 75: queue_depth */
178 #define DEPTH_BITS 0x001f /* bits used for queue depth */
180 /* words 80-81: version numbers */
181 /* NOVAL_0 or NOVAL_1 means device does not report version */
183 /* word 81: minor version number */
184 #define MINOR_MAX 0x22
185 /* words 82-84: cmds/feats supported */
186 #define CMDS_W82 0x77ff /* word 82: defined command locations*/
187 #define CMDS_W83 0x3fff /* word 83: defined command locations*/
188 #define CMDS_W84 0x002f /* word 83: defined command locations*/
189 #define SUPPORT_48_BIT 0x0400
190 #define NUM_CMD_FEAT_STR 48
192 /* words 85-87: cmds/feats enabled */
193 /* use cmd_feat_str[] to display what commands and features have
194 * been enabled with words 85-87
197 /* words 89, 90, SECU ERASE TIME */
198 #define ERASE_BITS 0x00ff
200 /* word 92: master password revision */
201 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
203 /* word 93: hw reset result */
204 #define CBLID 0x2000 /* CBLID status */
205 #define RST0 0x0001 /* 1=reset to device #0 */
206 #define DEV_DET 0x0006 /* how device num determined */
207 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
208 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
210 /* word 127: removable media status notification feature set support */
211 #define RM_STAT_BITS 0x0003
212 #define RM_STAT_SUP 0x0001
214 /* word 128: security */
215 #define SECU_ENABLED 0x0002
216 #define SECU_LEVEL 0x0010
217 #define NUM_SECU_STR 6
219 /* word 160: CFA power mode */
220 #define VALID_W160 0x8000 /* 1=word valid */
221 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
222 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
223 #define MAX_AMPS 0x0fff /* value = max current in ma */
225 /* word 255: integrity */
226 #define SIG 0x00ff /* signature location */
227 #define SIG_VAL 0x00a5 /* signature value */
229 #define TIMING_BUF_MB 1
230 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
232 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
239 smallint get_identity, get_geom;
241 smallint do_ctimings, do_timings;
242 smallint reread_partn;
243 smallint set_piomode, noisy_piomode;
244 smallint set_readahead, get_readahead;
245 smallint set_readonly, get_readonly;
246 smallint set_unmask, get_unmask;
247 smallint set_mult, get_mult;
254 smallint set_nowerr, get_nowerr;
255 smallint set_keep, get_keep;
256 smallint set_io32bit, get_io32bit;
258 unsigned long Xreadahead;
259 unsigned long readonly;
260 unsigned long unmask;
265 unsigned long nowerr;
267 unsigned long io32bit;
268 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
270 smallint set_dma, get_dma;
272 #ifdef HDIO_DRIVE_CMD
273 smallint set_xfermode, get_xfermode;
274 smallint set_dkeep, get_dkeep;
275 smallint set_standby, get_standby;
276 smallint set_lookahead, get_lookahead;
277 smallint set_prefetch, get_prefetch;
278 smallint set_defects, get_defects;
279 smallint set_wcache, get_wcache;
280 smallint set_doorlock, get_doorlock;
281 smallint set_seagate, get_seagate;
282 smallint set_standbynow, get_standbynow;
283 smallint set_sleepnow, get_sleepnow;
284 smallint get_powermode;
285 smallint set_apmmode, get_apmmode;
286 int xfermode_requested;
288 unsigned long standby_requested; /* 0..255 */
289 unsigned long lookahead;
290 unsigned long prefetch;
291 unsigned long defects;
292 unsigned long wcache;
293 unsigned long doorlock;
294 unsigned long apmmode;
296 IF_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
297 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint set_busstate, get_busstate;)
298 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
299 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
300 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
301 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
302 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
303 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
304 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
305 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
306 unsigned long hwif_data;
307 unsigned long hwif_ctrl;
308 unsigned long hwif_irq;
311 unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
314 #define G (*(struct globals*)&bb_common_bufsiz1)
315 struct BUG_G_too_big {
316 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
318 #define get_identity (G.get_identity )
319 #define get_geom (G.get_geom )
320 #define do_flush (G.do_flush )
321 #define do_ctimings (G.do_ctimings )
322 #define do_timings (G.do_timings )
323 #define reread_partn (G.reread_partn )
324 #define set_piomode (G.set_piomode )
325 #define noisy_piomode (G.noisy_piomode )
326 #define set_readahead (G.set_readahead )
327 #define get_readahead (G.get_readahead )
328 #define set_readonly (G.set_readonly )
329 #define get_readonly (G.get_readonly )
330 #define set_unmask (G.set_unmask )
331 #define get_unmask (G.get_unmask )
332 #define set_mult (G.set_mult )
333 #define get_mult (G.get_mult )
334 #define set_dma_q (G.set_dma_q )
335 #define get_dma_q (G.get_dma_q )
336 #define set_nowerr (G.set_nowerr )
337 #define get_nowerr (G.get_nowerr )
338 #define set_keep (G.set_keep )
339 #define get_keep (G.get_keep )
340 #define set_io32bit (G.set_io32bit )
341 #define get_io32bit (G.get_io32bit )
342 #define piomode (G.piomode )
343 #define Xreadahead (G.Xreadahead )
344 #define readonly (G.readonly )
345 #define unmask (G.unmask )
346 #define mult (G.mult )
347 #define dma_q (G.dma_q )
348 #define nowerr (G.nowerr )
349 #define keep (G.keep )
350 #define io32bit (G.io32bit )
352 #define set_dma (G.set_dma )
353 #define get_dma (G.get_dma )
354 #define set_xfermode (G.set_xfermode )
355 #define get_xfermode (G.get_xfermode )
356 #define set_dkeep (G.set_dkeep )
357 #define get_dkeep (G.get_dkeep )
358 #define set_standby (G.set_standby )
359 #define get_standby (G.get_standby )
360 #define set_lookahead (G.set_lookahead )
361 #define get_lookahead (G.get_lookahead )
362 #define set_prefetch (G.set_prefetch )
363 #define get_prefetch (G.get_prefetch )
364 #define set_defects (G.set_defects )
365 #define get_defects (G.get_defects )
366 #define set_wcache (G.set_wcache )
367 #define get_wcache (G.get_wcache )
368 #define set_doorlock (G.set_doorlock )
369 #define get_doorlock (G.get_doorlock )
370 #define set_seagate (G.set_seagate )
371 #define get_seagate (G.get_seagate )
372 #define set_standbynow (G.set_standbynow )
373 #define get_standbynow (G.get_standbynow )
374 #define set_sleepnow (G.set_sleepnow )
375 #define get_sleepnow (G.get_sleepnow )
376 #define get_powermode (G.get_powermode )
377 #define set_apmmode (G.set_apmmode )
378 #define get_apmmode (G.get_apmmode )
379 #define xfermode_requested (G.xfermode_requested )
380 #define dkeep (G.dkeep )
381 #define standby_requested (G.standby_requested )
382 #define lookahead (G.lookahead )
383 #define prefetch (G.prefetch )
384 #define defects (G.defects )
385 #define wcache (G.wcache )
386 #define doorlock (G.doorlock )
387 #define apmmode (G.apmmode )
388 #define get_IDentity (G.get_IDentity )
389 #define set_busstate (G.set_busstate )
390 #define get_busstate (G.get_busstate )
391 #define perform_reset (G.perform_reset )
392 #define perform_tristate (G.perform_tristate )
393 #define unregister_hwif (G.unregister_hwif )
394 #define scan_hwif (G.scan_hwif )
395 #define busstate (G.busstate )
396 #define tristate (G.tristate )
397 #define hwif (G.hwif )
398 #define hwif_data (G.hwif_data )
399 #define hwif_ctrl (G.hwif_ctrl )
400 #define hwif_irq (G.hwif_irq )
403 /* Busybox messages and functions */
404 #if ENABLE_IOCTL_HEX2STR_ERROR
405 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
407 if (!ioctl(fd, cmd, args))
410 return bb_ioctl_or_warn(fd, cmd, args, string);
412 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
414 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
416 if (!ioctl(fd, cmd, args))
419 return bb_ioctl_or_warn(fd, cmd, args);
421 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
424 static void on_off(int value)
426 puts(value ? " (on)" : " (off)");
429 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
432 printf(" setting %s to %ld", s, arg);
437 static void print_value_on_off(const char *str, unsigned long argp)
439 printf(" %s\t= %2ld", str, argp);
443 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
444 static void print_ascii(const char *p, int length)
451 /* every 16bit word is big-endian (i.e. inverted) */
452 /* accessing bytes in 1,0, 3,2, 5,4... sequence */
457 /* find first non-space & print it */
458 while (length && p[ofs] != ' ') {
463 while (length && p[ofs]) {
473 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
476 printf("\t%-20s", string);
477 print_ascii((void*)&val[i], n);
481 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
486 for (ii = 0; ii <= MODE_MAX; ii++) {
487 if (mode_sel & 0x0001) {
488 printf("*%cdma%u ", cc, ii);
492 } else if (mode_sup & 0x0001)
493 printf("%cdma%u ", cc, ii);
501 static const char pkt_str[] ALIGN1 =
502 "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
503 "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
504 "Printer" "\0" /* word 0, bits 12-8 = 02 */
505 "Processor" "\0" /* word 0, bits 12-8 = 03 */
506 "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
507 "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
508 "Scanner" "\0" /* word 0, bits 12-8 = 06 */
509 "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
510 "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
511 "Communications device" "\0" /* word 0, bits 12-8 = 09 */
512 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
513 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
514 "Array controller" "\0" /* word 0, bits 12-8 = 0c */
515 "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
516 "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
517 "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
520 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
521 "reserved" "\0" /* bit 0 */
522 "hard sectored" "\0" /* bit 1 */
523 "soft sectored" "\0" /* bit 2 */
524 "not MFM encoded " "\0" /* bit 3 */
525 "head switch time > 15us" "\0" /* bit 4 */
526 "spindle motor control option" "\0" /* bit 5 */
527 "fixed drive" "\0" /* bit 6 */
528 "removable drive" "\0" /* bit 7 */
529 "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
530 "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
531 "disk xfer rate > 5Mbs" "\0" /* bit 10 */
532 "rotational speed tol." "\0" /* bit 11 */
533 "data strobe offset option" "\0" /* bit 12 */
534 "track offset option" "\0" /* bit 13 */
535 "format speed tolerance gap reqd" "\0" /* bit 14 */
539 static const char minor_str[] ALIGN1 =
541 "Unspecified" "\0" /* 0x0000 */
542 "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
543 "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
544 "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
545 "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
546 "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
547 "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
548 "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
549 "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
550 "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
551 "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
552 "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
553 "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
554 "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
555 "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
556 "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
557 "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
558 "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
559 "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
560 "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
561 "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
562 "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
563 "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
564 "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
565 "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
566 "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
567 "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
568 "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
569 "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
570 "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
571 "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
572 "reserved" "\0" /* 0x001f */
573 "reserved" "\0" /* 0x0020 */
574 "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
575 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
576 "reserved" /* 0x0023-0xfffe */
578 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
580 0, /* 0x0000 WARNING: actual_ver[] array */
581 1, /* 0x0001 WARNING: corresponds */
582 1, /* 0x0002 WARNING: *exactly* */
583 1, /* 0x0003 WARNING: to the ATA/ */
584 2, /* 0x0004 WARNING: ATAPI version */
585 2, /* 0x0005 WARNING: listed in */
586 3, /* 0x0006 WARNING: the */
587 2, /* 0x0007 WARNING: minor_str */
588 3, /* 0x0008 WARNING: array */
589 2, /* 0x0009 WARNING: above. */
590 3, /* 0x000a WARNING: */
591 3, /* 0x000b WARNING: If you change */
592 3, /* 0x000c WARNING: that one, */
593 4, /* 0x000d WARNING: change this one */
594 4, /* 0x000e WARNING: too!!! */
615 0 /* 0x0023-0xfffe */
618 static const char cmd_feat_str[] ALIGN1 =
619 "" "\0" /* word 82 bit 15: obsolete */
620 "NOP cmd" "\0" /* word 82 bit 14 */
621 "READ BUFFER cmd" "\0" /* word 82 bit 13 */
622 "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
623 "" "\0" /* word 82 bit 11: obsolete */
624 "Host Protected Area feature set" "\0" /* word 82 bit 10 */
625 "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
626 "SERVICE interrupt" "\0" /* word 82 bit 8 */
627 "Release interrupt" "\0" /* word 82 bit 7 */
628 "Look-ahead" "\0" /* word 82 bit 6 */
629 "Write cache" "\0" /* word 82 bit 5 */
630 "PACKET command feature set" "\0" /* word 82 bit 4 */
631 "Power Management feature set" "\0" /* word 82 bit 3 */
632 "Removable Media feature set" "\0" /* word 82 bit 2 */
633 "Security Mode feature set" "\0" /* word 82 bit 1 */
634 "SMART feature set" "\0" /* word 82 bit 0 */
636 "" "\0" /* word 83 bit 15: !valid bit */
637 "" "\0" /* word 83 bit 14: valid bit */
638 "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
639 "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
640 "Device Configuration Overlay feature set " "\0"
641 "48-bit Address feature set " "\0" /* word 83 bit 10 */
643 "SET MAX security extension" "\0" /* word 83 bit 8 */
644 "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
645 "SET FEATURES subcommand required to spinup after power up" "\0"
646 "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
647 "Removable Media Status Notification feature set" "\0"
648 "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
649 "CFA feature set" "\0" /* word 83 bit 2 */
650 "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
651 "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
653 "" "\0" /* word 84 bit 15: !valid bit */
654 "" "\0" /* word 84 bit 14: valid bit */
655 "" "\0" /* word 84 bit 13: reserved */
656 "" "\0" /* word 84 bit 12: reserved */
657 "" "\0" /* word 84 bit 11: reserved */
658 "" "\0" /* word 84 bit 10: reserved */
659 "" "\0" /* word 84 bit 9: reserved */
660 "" "\0" /* word 84 bit 8: reserved */
661 "" "\0" /* word 84 bit 7: reserved */
662 "" "\0" /* word 84 bit 6: reserved */
663 "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
664 "" "\0" /* word 84 bit 4: reserved */
665 "Media Card Pass Through Command feature set " "\0"
666 "Media serial number " "\0" /* word 84 bit 2 */
667 "SMART self-test " "\0" /* word 84 bit 1 */
668 "SMART error logging " /* word 84 bit 0 */
671 static const char secu_str[] ALIGN1 =
672 "supported" "\0" /* word 128, bit 0 */
673 "enabled" "\0" /* word 128, bit 1 */
674 "locked" "\0" /* word 128, bit 2 */
675 "frozen" "\0" /* word 128, bit 3 */
676 "expired: security count" "\0" /* word 128, bit 4 */
677 "supported: enhanced erase" /* word 128, bit 5 */
680 // Parse 512 byte disk identification block and print much crap.
681 static void identify(uint16_t *val) NORETURN;
682 static void identify(uint16_t *val)
685 uint16_t like_std = 1, std = 0, min_std = 0xffff;
686 uint16_t dev = NO_DEV, eqpt = NO_DEV;
687 uint8_t have_mode = 0, err_dma = 0;
689 uint32_t ll, mm, nn, oo;
690 uint64_t bbbig; /* (:) */
695 // Adjust for endianness
696 swab(val, buf, sizeof(buf));
699 /* check if we recognise the device type */
701 if (!(val[GEN_CONFIG] & NOT_ATA)) {
703 printf("ATA device, with ");
704 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
707 printf("CompactFlash ATA device, with ");
708 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
710 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
711 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
714 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
715 bb_error_msg_and_die("unknown device type");
717 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
718 /* Info from the specific configuration word says whether or not the
719 * ID command completed correctly. It is only defined, however in
720 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
721 * standards. Since the values allowed for this word are extremely
722 * specific, it should be safe to check it now, even though we don't
723 * know yet what standard this device is using.
725 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
726 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
729 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
730 printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
731 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
732 printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
735 /* output the model and serial numbers and the fw revision */
736 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
737 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
738 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
739 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
740 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
742 /* major & minor standards version number (Note: these words were not
743 * defined until ATA-3 & the CDROM std uses different words.) */
744 printf("Standards:");
746 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
747 if (like_std < 3) like_std = 3;
748 std = actual_ver[val[MINOR]];
749 if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
752 /* looks like when they up-issue the std, they obsolete one;
753 * thus, only the newest 4 issues need be supported. (That's
754 * what "kk" and "min_std" are all about.) */
755 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
756 printf("\n\tSupported: ");
757 jj = val[MAJOR] << 1;
758 kk = like_std >4 ? like_std-4: 0;
759 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
764 kk = like_std >4 ? like_std-4: 0;
766 if (min_std > ii) min_std = ii;
770 if (like_std < 3) like_std = 3;
772 /* Figure out what standard the device is using if it hasn't told
773 * us. If we know the std, check if the device is using any of
774 * the words from the next level up. It happens.
776 if (like_std < std) like_std = std;
778 if (((std == 5) || (!std && (like_std < 6))) &&
779 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
780 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
781 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
782 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
785 } else if (((std == 4) || (!std && (like_std < 5))) &&
786 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
787 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
788 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
789 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
792 } else if (((std == 3) || (!std && (like_std < 4))) &&
793 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
794 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
795 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
796 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
797 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
798 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
801 } else if (((std == 2) || (!std && (like_std < 3)))
802 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
805 } else if (((std == 1) || (!std && (like_std < 2))) &&
806 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
807 (val[WHATS_VALID] & OK_W64_70)) )
813 printf("\n\tLikely used: %u\n", like_std);
814 else if (like_std > std)
815 printf("& some of %u\n", like_std);
819 /* TBD: do CDROM stuff more thoroughly. For now... */
821 if (val[CDR_MINOR] == 9) {
823 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
825 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
827 printf("\n\tSupported: CD-ROM ATAPI");
828 jj = val[CDR_MAJOR] >> 1;
829 for (ii = 1; ii < 15; ii++) {
830 if (jj & 0x0001) printf("-%u ", ii);
834 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
835 /* the cdrom stuff is more like ATA-2 than anything else, so: */
839 if (min_std == 0xffff)
840 min_std = like_std > 4 ? like_std - 3 : 1;
842 printf("Configuration:\n");
843 /* more info from the general configuration word */
844 if ((eqpt != CDROM) && (like_std == 1)) {
845 jj = val[GEN_CONFIG] >> 1;
846 for (ii = 1; ii < 15; ii++) {
848 printf("\t%s\n", nth_string(ata1_cfg_str, ii));
852 if (dev == ATAPI_DEV) {
853 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
855 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
856 strng = "<=10ms with INTRQ";
857 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
861 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
863 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
865 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
871 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
872 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
875 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
876 printf("\tCHS addressing not supported\n");
878 jj = val[WHATS_VALID] & OK_W54_58;
879 printf("\tLogical\t\tmax\tcurrent\n"
880 "\tcylinders\t%u\t%u\n"
881 "\theads\t\t%u\t%u\n"
882 "\tsectors/track\t%u\t%u\n"
885 jj ? val[LCYLS_CUR] : 0,
887 jj ? val[LHEADS_CUR] : 0,
889 jj ? val[LSECTS_CUR] : 0);
891 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
892 printf("\tbytes/track: %u\tbytes/sector: %u\n",
893 val[TRACK_BYTES], val[SECT_BYTES]);
896 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
898 /* check Endian of capacity bytes */
899 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
900 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
901 if (abs(mm - nn) > abs(oo - nn))
904 printf("\tCHS current addressable sectors:%11u\n", mm);
908 printf("\tLBA user addressable sectors:%11u\n", ll);
909 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
910 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
912 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
913 (uint64_t)val[LBA_48_MSB] << 32 |
914 (uint64_t)val[LBA_MID] << 16 |
916 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
920 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
921 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
922 bbbig = (bbbig << 9) / 1000000;
923 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
926 printf("(%"PRIu64" GB)\n", bbbig/1000);
931 /* hw support of commands (capabilities) */
932 printf("Capabilities:\n\t");
934 if (dev == ATAPI_DEV) {
935 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP))
936 printf("Cmd queuing, ");
937 if (val[CAPAB_0] & OVLP_SUP)
938 printf("Cmd overlap, ");
940 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
943 printf("IORDY%s(can%s be disabled)\n",
944 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
945 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
947 printf("no IORDY\n");
949 if ((like_std == 1) && val[BUF_TYPE]) {
950 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
951 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
952 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
955 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
956 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
958 if ((min_std < 4) && (val[RW_LONG])) {
959 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
961 if ((eqpt != CDROM) && (like_std > 3)) {
962 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
965 if (dev == ATA_DEV) {
967 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
969 printf("\tStandby timer values: spec'd by %s",
970 (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor");
971 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
972 printf(", %s device specific minimum\n",
973 (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
977 printf("\tR/W multiple sector transfer: ");
978 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
979 printf("not supported\n");
981 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
982 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
983 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
987 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
988 /* We print out elsewhere whether the APM feature is enabled or
989 not. If it's not enabled, let's not repeat the info; just print
991 printf("\tAdvancedPM level: ");
992 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
993 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
994 printf("%u (0x%x)\n", apm_level, apm_level);
997 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
999 if (like_std > 5 && val[ACOUSTIC]) {
1000 printf("\tRecommended acoustic management value: %u, current value: %u\n",
1001 (val[ACOUSTIC] >> 8) & 0x00ff,
1002 val[ACOUSTIC] & 0x00ff);
1006 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
1007 printf("\tATA sw reset required\n");
1009 if (val[PKT_REL] || val[SVC_NBSY]) {
1010 printf("\tOverlap support:");
1012 printf(" %uus to release bus.", val[PKT_REL]);
1014 printf(" %uus to clear BSY after SERVICE cmd.",
1020 /* DMA stuff. Check that only one DMA mode is selected. */
1022 if (!(val[CAPAB_0] & DMA_SUP))
1023 printf("not supported\n");
1025 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1026 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1027 if (val[SINGLE_DMA]) {
1028 jj = val[SINGLE_DMA];
1029 kk = val[SINGLE_DMA] >> 8;
1030 err_dma += mode_loop(jj, kk, 's', &have_mode);
1032 if (val[MULTI_DMA]) {
1033 jj = val[MULTI_DMA];
1034 kk = val[MULTI_DMA] >> 8;
1035 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1037 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1038 jj = val[ULTRA_DMA];
1039 kk = val[ULTRA_DMA] >> 8;
1040 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1042 if (err_dma || !have_mode) printf("(?)");
1045 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1046 printf("\t\tInterleaved DMA support\n");
1048 if ((val[WHATS_VALID] & OK_W64_70)
1049 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1051 printf("\t\tCycle time:");
1052 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1053 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1058 /* Programmed IO stuff */
1060 /* If a drive supports mode n (e.g. 3), it also supports all modes less
1061 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1062 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1063 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1064 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1065 if (jj & 0x0001) printf("pio%d ", ii);
1069 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1070 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1071 printf("pio%d ", ii);
1076 if (val[WHATS_VALID] & OK_W64_70) {
1077 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1078 printf("\t\tCycle time:");
1079 if (val[PIO_NO_FLOW])
1080 printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1082 printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1087 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1088 printf("Commands/features:\n"
1089 "\tEnabled\tSupported:\n");
1090 jj = val[CMDS_SUPP_0];
1091 kk = val[CMDS_EN_0];
1092 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1093 const char *feat_str = nth_string(cmd_feat_str, ii);
1094 if ((jj & 0x8000) && (*feat_str != '\0')) {
1095 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
1099 if (ii % 16 == 15) {
1100 jj = val[CMDS_SUPP_0+1+(ii/16)];
1101 kk = val[CMDS_EN_0+1+(ii/16)];
1104 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1109 /* Removable Media Status Notification feature set */
1110 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1111 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1114 if ((eqpt != CDROM) && (like_std > 3)
1115 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1117 printf("Security:\n");
1118 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1119 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1120 jj = val[SECU_STATUS];
1122 for (ii = 0; ii < NUM_SECU_STR; ii++) {
1123 printf("\t%s\t%s\n",
1124 (!(jj & 0x0001)) ? "not" : "",
1125 nth_string(secu_str, ii));
1128 if (val[SECU_STATUS] & SECU_ENABLED) {
1129 printf("\tSecurity level %s\n",
1130 (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1133 jj = val[ERASE_TIME] & ERASE_BITS;
1134 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1137 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1138 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1144 jj = val[HWRST_RSLT];
1145 if ((jj & VALID) == VALID_VAL) {
1149 if ((jj & DEV_DET) == JUMPER_VAL)
1150 strng = " determined by the jumper";
1151 else if ((jj & DEV_DET) == CSEL_VAL)
1152 strng = " determined by CSEL";
1155 printf("HW reset results:\n"
1157 "\tDevice num = %i%s\n",
1158 (val[HWRST_RSLT] & CBLID) ? "above" : "below",
1162 /* more stuff from std 5 */
1163 if ((like_std > 4) && (eqpt != CDROM)) {
1164 if (val[CFA_PWR_MODE] & VALID_W160) {
1165 printf("CFA power mode 1:\n"
1167 (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1168 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1169 if (val[CFA_PWR_MODE] & MAX_AMPS)
1170 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1172 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1173 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1181 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1182 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1183 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1184 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1185 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1186 // (which they should, but they should just return -EINVAL).
1188 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1189 // On a really old system, it will not, and we will be confused.
1192 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1193 static const char cfg_str[] ALIGN1 =
1194 """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
1195 "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
1196 "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1197 "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
1200 static const char BuffType[] ALIGN1 =
1201 "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
1204 static void dump_identity(const struct hd_driveid *id)
1207 const unsigned short *id_regs = (const void*) id;
1209 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1210 id->model, id->fw_rev, id->serial_no);
1211 for (i = 0; i <= 15; i++) {
1212 if (id->config & (1<<i))
1213 printf(" %s", nth_string(cfg_str, i));
1215 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1216 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1217 id->cyls, id->heads, id->sectors, id->track_bytes,
1218 id->sector_bytes, id->ecc_bytes,
1220 nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1221 id->buf_size/2, id->max_multsect);
1222 if (id->max_multsect) {
1223 printf(", MultSect=");
1224 if (!(id->multsect_valid & 1))
1225 printf("?%u?", id->multsect);
1226 else if (id->multsect)
1227 printf("%u", id->multsect);
1233 if (!(id->field_valid & 1))
1234 printf(" (maybe):");
1236 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1239 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1240 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1241 ((id->capability&2) == 0) ? "no" : "yes");
1243 if (id->capability & 2)
1244 printf(", LBAsects=%u", id->lba_capacity);
1246 printf("\n IORDY=%s",
1247 (id->capability & 8)
1248 ? ((id->capability & 4) ? "on/off" : "yes")
1251 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1252 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1254 if ((id->capability & 1) && (id->field_valid & 2))
1255 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1257 printf("\n PIO modes: ");
1258 if (id->tPIO <= 5) {
1260 if (id->tPIO >= 1) printf("pio1 ");
1261 if (id->tPIO >= 2) printf("pio2 ");
1263 if (id->field_valid & 2) {
1264 static const masks_labels_t pio_modes = {
1265 .masks = { 1, 2, ~3 },
1266 .labels = "pio3 \0""pio4 \0""pio? \0",
1268 print_flags(&pio_modes, id->eide_pio_modes);
1270 if (id->capability & 1) {
1271 if (id->dma_1word | id->dma_mword) {
1272 static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
1273 printf("\n DMA modes: ");
1274 print_flags_separated(dma_wmode_masks,
1275 "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
1276 id->dma_1word, NULL);
1277 print_flags_separated(dma_wmode_masks,
1278 "*\0""mdma0\0""*\0""mdma1\0""*\0""mdma2\0""*\0""mdma?\0",
1279 id->dma_mword, NULL);
1282 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1283 static const masks_labels_t ultra_modes1 = {
1284 .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
1285 .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
1288 printf("\n UDMA modes: ");
1289 print_flags(&ultra_modes1, id->dma_ultra);
1290 #ifdef __NEW_HD_DRIVE_ID
1291 if (id->hw_config & 0x2000) {
1292 #else /* !__NEW_HD_DRIVE_ID */
1293 if (id->word93 & 0x2000) {
1294 #endif /* __NEW_HD_DRIVE_ID */
1295 static const masks_labels_t ultra_modes2 = {
1296 .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
1297 0x2000, 0x0020, 0x4000, 0x0040,
1299 .labels = "*\0""udma3 \0""*\0""udma4 \0"
1300 "*\0""udma5 \0""*\0""udma6 \0"
1303 print_flags(&ultra_modes2, id->dma_ultra);
1306 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1307 if (id_regs[83] & 8) {
1308 if (!(id_regs[86] & 8))
1309 printf(": disabled (255)");
1310 else if ((id_regs[91] & 0xFF00) != 0x4000)
1311 printf(": unknown setting");
1313 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1315 if (id_regs[82] & 0x20)
1316 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1317 #ifdef __NEW_HD_DRIVE_ID
1318 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1319 || (id->major_rev_num && id->minor_rev_num <= 31)
1321 printf("\n Drive conforms to: %s: ",
1322 (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1323 if (id->major_rev_num != 0x0000 /* NOVAL_0 */
1324 && id->major_rev_num != 0xFFFF /* NOVAL_1 */
1326 for (i = 0; i <= 15; i++) {
1327 if (id->major_rev_num & (1<<i))
1328 printf(" ATA/ATAPI-%u", i);
1332 #endif /* __NEW_HD_DRIVE_ID */
1333 printf("\n\n * current active mode\n\n");
1337 static void flush_buffer_cache(/*int fd*/ void)
1339 fsync(fd); /* flush buffers */
1340 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1341 #ifdef HDIO_DRIVE_CMD
1343 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1344 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1345 bb_perror_msg("HDIO_DRIVE_CMD");
1347 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1352 static void seek_to_zero(/*int fd*/ void)
1354 xlseek(fd, (off_t) 0, SEEK_SET);
1357 static void read_big_block(/*int fd,*/ char *buf)
1361 xread(fd, buf, TIMING_BUF_BYTES);
1362 /* access all sectors of buf to ensure the read fully completed */
1363 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1367 static unsigned dev_size_mb(/*int fd*/ void)
1370 unsigned long long blksize64;
1374 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1375 u.blksize64 /= (1024 * 1024);
1377 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1378 u.blksize64 = u.blksize32 / (2 * 1024);
1380 if (u.blksize64 > UINT_MAX)
1385 static void print_timing(unsigned m, unsigned elapsed_us)
1387 unsigned sec = elapsed_us / 1000000;
1388 unsigned hs = (elapsed_us % 1000000) / 10000;
1390 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1392 /* "| 1" prevents div-by-0 */
1393 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1394 // ~= (m * 1024) / (elapsed_us / 1000000)
1395 // = kb / elapsed_sec
1399 static void do_time(int cache /*,int fd*/)
1400 /* cache=1: time cache: repeatedly read N MB at offset 0
1401 * cache=0: time device: linear read, starting at offset 0
1404 unsigned max_iterations, iterations;
1405 unsigned start; /* doesn't need to be long long */
1406 unsigned elapsed, elapsed2;
1408 char *buf = xmalloc(TIMING_BUF_BYTES);
1410 if (mlock(buf, TIMING_BUF_BYTES))
1411 bb_perror_msg_and_die("mlock");
1413 /* Clear out the device request queues & give them time to complete.
1414 * NB: *small* delay. User is expected to have a clue and to not run
1415 * heavy io in parallel with measurements. */
1418 if (cache) { /* Time cache */
1420 read_big_block(buf);
1421 printf("Timing buffer-cache reads: ");
1422 } else { /* Time device */
1423 printf("Timing buffered disk reads:");
1427 /* Now do the timing */
1429 /* Max time to run (small for cache, avoids getting
1430 * huge total_MB which can overlow unsigned type) */
1431 elapsed2 = 510000; /* cache */
1432 max_iterations = UINT_MAX;
1434 elapsed2 = 3000000; /* not cache */
1435 /* Don't want to read past the end! */
1436 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1438 start = monotonic_us();
1442 read_big_block(buf);
1443 elapsed = (unsigned)monotonic_us() - start;
1445 } while (elapsed < elapsed2 && iterations < max_iterations);
1446 total_MB = iterations * TIMING_BUF_MB;
1447 //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1449 /* Cache: remove lseek() and monotonic_us() overheads
1451 start = monotonic_us();
1454 elapsed2 = (unsigned)monotonic_us() - start;
1455 } while (--iterations);
1456 //printf(" elapsed2:%u ", elapsed2);
1457 elapsed -= elapsed2;
1458 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1459 flush_buffer_cache();
1461 print_timing(total_MB, elapsed);
1462 munlock(buf, TIMING_BUF_BYTES);
1466 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1467 static void bus_state_value(unsigned value)
1469 if (value == BUSSTATE_ON)
1471 else if (value == BUSSTATE_OFF)
1473 else if (value == BUSSTATE_TRISTATE)
1474 printf(" (tristate)\n");
1476 printf(" (unknown: %d)\n", value);
1480 #ifdef HDIO_DRIVE_CMD
1481 static void interpret_standby(uint8_t standby)
1486 } else if (standby <= 240 || standby == 252 || standby == 255) {
1487 /* standby is in 5 sec units */
1488 printf("%u minutes %u seconds", standby / (60/5), standby % (60/5));
1489 } else if (standby <= 251) {
1490 unsigned t = (standby - 240); /* t is in 30 min units */;
1491 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0');
1494 printf("vendor-specific");
1500 static const uint8_t xfermode_val[] ALIGN1 = {
1501 8, 9, 10, 11, 12, 13, 14, 15,
1502 16, 17, 18, 19, 20, 21, 22, 23,
1503 32, 33, 34, 35, 36, 37, 38, 39,
1504 64, 65, 66, 67, 68, 69, 70, 71
1506 /* NB: we save size by _not_ storing terninating NUL! */
1507 static const char xfermode_name[][5] ALIGN1 = {
1508 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1509 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1510 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1511 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1514 static int translate_xfermode(const char *name)
1519 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1520 if (!strncmp(name, xfermode_name[i], 5))
1521 if (strlen(name) <= 5)
1522 return xfermode_val[i];
1524 /* Negative numbers are invalid and are caught later */
1525 val = bb_strtoi(name, NULL, 10);
1531 static void interpret_xfermode(unsigned xfermode)
1535 printf("default PIO mode");
1536 else if (xfermode == 1)
1537 printf("default PIO mode, disable IORDY");
1538 else if (xfermode >= 8 && xfermode <= 15)
1539 printf("PIO flow control mode%u", xfermode - 8);
1540 else if (xfermode >= 16 && xfermode <= 23)
1541 printf("singleword DMA mode%u", xfermode - 16);
1542 else if (xfermode >= 32 && xfermode <= 39)
1543 printf("multiword DMA mode%u", xfermode - 32);
1544 else if (xfermode >= 64 && xfermode <= 71)
1545 printf("UltraDMA mode%u", xfermode - 64);
1550 #endif /* HDIO_DRIVE_CMD */
1552 static void print_flag(int flag, const char *s, unsigned long value)
1555 printf(" setting %s to %ld\n", s, value);
1558 static void process_dev(char *devname)
1561 long parm, multcount;
1562 #ifndef HDIO_DRIVE_CMD
1563 int force_operation = 0;
1565 /* Please restore args[n] to these values after each ioctl
1566 except for args[2] */
1567 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1568 const char *fmt = " %s\t= %2ld";
1570 /*fd = xopen(devname, O_RDONLY | O_NONBLOCK);*/
1571 xmove_fd(xopen(devname, O_RDONLY | O_NONBLOCK), fd);
1572 printf("\n%s:\n", devname);
1574 if (set_readahead) {
1575 print_flag(get_readahead, "fs readahead", Xreadahead);
1576 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1578 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1579 if (unregister_hwif) {
1580 printf(" attempting to unregister hwif#%lu\n", hwif);
1581 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1584 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1586 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1587 args[0] = hwif_data;
1588 args[1] = hwif_ctrl;
1590 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1591 args[0] = WIN_SETFEATURES;
1596 if (noisy_piomode) {
1597 printf(" attempting to ");
1599 printf("auto-tune PIO mode\n");
1600 else if (piomode < 100)
1601 printf("set PIO mode to %d\n", piomode);
1602 else if (piomode < 200)
1603 printf("set MDMA mode to %d\n", (piomode-100));
1605 printf("set UDMA mode to %d\n", (piomode-200));
1607 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1610 print_flag(get_io32bit, "32-bit IO_support flag", io32bit);
1611 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1614 print_flag(get_mult, "multcount", mult);
1615 #ifdef HDIO_DRIVE_CMD
1616 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1618 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1622 print_flag_on_off(get_readonly, "readonly", readonly);
1623 ioctl_or_warn(fd, BLKROSET, &readonly);
1626 print_flag_on_off(get_unmask, "unmaskirq", unmask);
1627 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1629 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1631 print_flag_on_off(get_dma, "using_dma", dma);
1632 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1634 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1635 #ifdef HDIO_SET_QDMA
1637 print_flag_on_off(get_dma_q, "DMA queue_depth", dma_q);
1638 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1642 print_flag_on_off(get_nowerr, "nowerr", nowerr);
1643 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1646 print_flag_on_off(get_keep, "keep_settings", keep);
1647 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1649 #ifdef HDIO_DRIVE_CMD
1651 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1653 print_flag_on_off(get_doorlock, "drive doorlock", doorlock);
1654 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1655 args[0] = WIN_SETFEATURES;
1658 /* lock/unlock the drive's "feature" settings */
1659 print_flag_on_off(get_dkeep, "drive keep features", dkeep);
1660 args[2] = dkeep ? 0x66 : 0xcc;
1661 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1664 args[2] = defects ? 0x04 : 0x84;
1665 print_flag(get_defects, "drive defect-mgmt", defects);
1666 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1671 print_flag(get_prefetch, "drive prefetch", prefetch);
1672 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1676 args[1] = xfermode_requested;
1679 print_flag(1, "xfermode", xfermode_requested);
1680 interpret_xfermode(xfermode_requested);
1682 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1685 if (set_lookahead) {
1686 args[2] = lookahead ? 0xaa : 0x55;
1687 print_flag_on_off(get_lookahead, "drive read-lookahead", lookahead);
1688 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1691 /* feature register */
1692 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */;
1693 args[1] = apmmode; /* sector count register 1-255 */
1695 printf(" setting APM level to %s 0x%02lX (%ld)\n",
1696 (apmmode == 255) ? "disabled" : "",
1698 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1702 #ifdef DO_FLUSHCACHE
1703 #ifndef WIN_FLUSHCACHE
1704 #define WIN_FLUSHCACHE 0xe7
1706 #endif /* DO_FLUSHCACHE */
1707 args[2] = wcache ? 0x02 : 0x82;
1708 print_flag_on_off(get_wcache, "drive write-caching", wcache);
1709 #ifdef DO_FLUSHCACHE
1711 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1712 #endif /* DO_FLUSHCACHE */
1713 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1714 #ifdef DO_FLUSHCACHE
1716 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1717 #endif /* DO_FLUSHCACHE */
1720 /* In code below, we do not preserve args[0], but the rest
1721 is preserved, including args[2] */
1724 if (set_standbynow) {
1725 #ifndef WIN_STANDBYNOW1
1726 #define WIN_STANDBYNOW1 0xE0
1728 #ifndef WIN_STANDBYNOW2
1729 #define WIN_STANDBYNOW2 0x94
1731 if (get_standbynow) printf(" issuing standby command\n");
1732 args[0] = WIN_STANDBYNOW1;
1733 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1736 #ifndef WIN_SLEEPNOW1
1737 #define WIN_SLEEPNOW1 0xE6
1739 #ifndef WIN_SLEEPNOW2
1740 #define WIN_SLEEPNOW2 0x99
1742 if (get_sleepnow) printf(" issuing sleep command\n");
1743 args[0] = WIN_SLEEPNOW1;
1744 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1749 printf(" disabling Seagate auto powersaving mode\n");
1750 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1753 args[0] = WIN_SETIDLE1;
1754 args[1] = standby_requested;
1756 print_flag(1, "standby", standby_requested);
1757 interpret_standby(standby_requested);
1759 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1762 #else /* HDIO_DRIVE_CMD */
1763 if (force_operation) {
1765 flush_buffer_cache();
1766 if (-1 == read(fd, buf, sizeof(buf)))
1767 bb_perror_msg("read of 512 bytes failed");
1769 #endif /* HDIO_DRIVE_CMD */
1771 if (get_mult || get_identity) {
1773 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1774 /* To be coherent with ioctl_or_warn. */
1775 if (get_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1776 bb_perror_msg("HDIO_GET_MULTCOUNT");
1778 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1779 } else if (get_mult) {
1780 printf(fmt, "multcount", multcount);
1781 on_off(multcount != 0);
1785 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1786 printf(" IO_support\t=%3ld (", parm);
1788 printf("default 16-bit)\n");
1790 printf("16-bit)\n");
1792 printf("32-bit)\n");
1794 printf("32-bit w/sync)\n");
1796 printf("Request-Queue-Bypass)\n");
1798 printf("\?\?\?)\n");
1802 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
1803 print_value_on_off("unmaskirq", parm);
1807 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1809 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1810 printf(fmt, "using_dma", parm);
1812 printf(" (DMA-Assisted-PIO)\n");
1818 #ifdef HDIO_GET_QDMA
1820 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
1821 print_value_on_off("queue_depth", parm);
1825 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
1826 print_value_on_off("keepsettings", parm);
1830 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
1831 print_value_on_off("nowerr", parm);
1834 if (!ioctl_or_warn(fd, BLKROGET, &parm))
1835 print_value_on_off("readonly", parm);
1837 if (get_readahead) {
1838 if (!ioctl_or_warn(fd, BLKRAGET, &parm))
1839 print_value_on_off("readahead", parm);
1842 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1843 struct hd_geometry g;
1845 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1846 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1847 g.cylinders, g.heads, g.sectors, parm, g.start);
1850 #ifdef HDIO_DRIVE_CMD
1851 if (get_powermode) {
1852 #ifndef WIN_CHECKPOWERMODE1
1853 #define WIN_CHECKPOWERMODE1 0xE5
1855 #ifndef WIN_CHECKPOWERMODE2
1856 #define WIN_CHECKPOWERMODE2 0x98
1860 args[0] = WIN_CHECKPOWERMODE1;
1861 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1862 if (errno != EIO || args[0] != 0 || args[1] != 0)
1867 state = (args[2] == 255) ? "active/idle" : "standby";
1868 args[1] = args[2] = 0;
1870 printf(" drive state is: %s\n", state);
1873 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1874 if (perform_reset) {
1875 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1877 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1878 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1879 if (perform_tristate) {
1882 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1884 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1885 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1887 struct hd_driveid id;
1889 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1890 if (multcount != -1) {
1891 id.multsect = multcount;
1892 id.multsect_valid |= 1;
1894 id.multsect_valid &= ~1;
1896 } else if (errno == -ENOMSG)
1897 printf(" no identification info available\n");
1898 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1899 bb_perror_msg("HDIO_GET_IDENTITY");
1901 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1905 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1907 memset(args1, 0, sizeof(args1));
1908 args1[0] = WIN_IDENTIFY;
1910 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1911 identify((void *)(args1 + 4));
1914 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1917 print_flag(1, "bus state", busstate);
1918 bus_state_value(busstate);
1920 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1923 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1924 printf(fmt, "bus state", parm);
1925 bus_state_value(parm);
1930 ioctl_or_warn(fd, BLKRRPART, NULL);
1933 do_time(1 /*,fd*/); /* time cache */
1935 do_time(0 /*,fd*/); /* time device */
1937 flush_buffer_cache();
1941 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1942 static int fromhex(unsigned char c)
1946 if (c >= 'a' && c <= 'f')
1947 return (c - ('a' - 10));
1948 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1951 static void identify_from_stdin(void) NORETURN;
1952 static void identify_from_stdin(void)
1955 unsigned char buf[1280];
1956 unsigned char *b = (unsigned char *)buf;
1959 xread(STDIN_FILENO, buf, 1280);
1961 // Convert the newline-separated hex data into an identify block.
1963 for (i = 0; i < 256; i++) {
1965 for (j = 0; j < 4; j++)
1966 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1974 void identify_from_stdin(void);
1977 /* busybox specific stuff */
1978 static void parse_opts(smallint *get, smallint *set, unsigned long *value, int min, int max)
1985 *value = xatol_range(optarg, min, max);
1989 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
1994 *value = translate_xfermode(optarg);
1995 *set = (*value > -1);
2000 /*------- getopt short options --------*/
2001 static const char hdparm_options[] ALIGN1 =
2002 "gfu::n::p:r::m::c::k::a::B:tT"
2003 IF_FEATURE_HDPARM_GET_IDENTITY("iI")
2004 IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
2005 #ifdef HDIO_DRIVE_CMD
2006 "S:D:P:X:K:A:L:W:CyYzZ"
2008 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
2009 #ifdef HDIO_GET_QDMA
2010 #ifdef HDIO_SET_QDMA
2016 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
2017 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
2018 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
2019 /*-------------------------------------*/
2021 /* our main() routine: */
2022 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2023 int hdparm_main(int argc, char **argv)
2028 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2030 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2031 IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2032 get_geom |= (c == 'g');
2033 do_flush |= (c == 'f');
2034 if (c == 'u') parse_opts(&get_unmask, &set_unmask, &unmask, 0, 1);
2035 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(if (c == 'd') parse_opts(&get_dma, &set_dma, &dma, 0, 9));
2036 if (c == 'n') parse_opts(&get_nowerr, &set_nowerr, &nowerr, 0, 1);
2037 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2038 if (c == 'r') parse_opts(&get_readonly, &set_readonly, &readonly, 0, 1);
2039 if (c == 'm') parse_opts(&get_mult, &set_mult, &mult, 0, INT_MAX /*32*/);
2040 if (c == 'c') parse_opts(&get_io32bit, &set_io32bit, &io32bit, 0, INT_MAX /*8*/);
2041 if (c == 'k') parse_opts(&get_keep, &set_keep, &keep, 0, 1);
2042 if (c == 'a') parse_opts(&get_readahead, &set_readahead, &Xreadahead, 0, INT_MAX);
2043 if (c == 'B') parse_opts(&get_apmmode, &set_apmmode, &apmmode, 1, 255);
2044 do_flush |= do_timings |= (c == 't');
2045 do_flush |= do_ctimings |= (c == 'T');
2046 #ifdef HDIO_DRIVE_CMD
2047 if (c == 'S') parse_opts(&get_standby, &set_standby, &standby_requested, 0, 255);
2048 if (c == 'D') parse_opts(&get_defects, &set_defects, &defects, 0, INT_MAX);
2049 if (c == 'P') parse_opts(&get_prefetch, &set_prefetch, &prefetch, 0, INT_MAX);
2050 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2051 if (c == 'K') parse_opts(&get_dkeep, &set_dkeep, &prefetch, 0, 1);
2052 if (c == 'A') parse_opts(&get_lookahead, &set_lookahead, &lookahead, 0, 1);
2053 if (c == 'L') parse_opts(&get_doorlock, &set_doorlock, &doorlock, 0, 1);
2054 if (c == 'W') parse_opts(&get_wcache, &set_wcache, &wcache, 0, 1);
2055 get_powermode |= (c == 'C');
2056 get_standbynow = set_standbynow |= (c == 'y');
2057 get_sleepnow = set_sleepnow |= (c == 'Y');
2058 reread_partn |= (c == 'z');
2059 get_seagate = set_seagate |= (c == 'Z');
2061 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') parse_opts(NULL, &unregister_hwif, &hwif, 0, INT_MAX));
2062 #ifdef HDIO_GET_QDMA
2064 #ifdef HDIO_SET_QDMA
2065 parse_opts(&get_dma_q, &set_dma_q, &dma_q, 0, INT_MAX);
2067 parse_opts(&get_dma_q, NULL, NULL, 0, 0);
2071 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2072 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') parse_opts(NULL, &perform_tristate, &tristate, 0, 1));
2073 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') parse_opts(&get_busstate, &set_busstate, &busstate, 0, 2));
2074 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2076 parse_opts(NULL, &scan_hwif, &hwif_data, 0, INT_MAX);
2077 hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
2078 hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
2079 /* Move past the 2 additional arguments */
2085 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2087 get_mult = get_io32bit = get_unmask = get_keep = get_readonly = get_readahead = get_geom = 1;
2088 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(get_dma = 1);
2093 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2094 identify_from_stdin(); /* EXIT */
2099 process_dev(*argv++);
2102 return EXIT_SUCCESS;