1 /* vi: set sw=4 ts=4: */
3 * hdparm implementation for busybox
5 * Copyright (C) [2003] by [Matteo Croce] <3297627799@wind.it>
6 * Hacked by Tito <farmatito@tiscali.it> for size optimization.
8 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
10 * This program is based on the source code of hdparm: see below...
11 * hdparm.c - Command line interface to get/set hard disk parameters
12 * - by Mark Lord (C) 1994-2002 -- freely distributable
15 #include <linux/hdreg.h>
20 #define ATA_DEV 0x0000
21 #define ATAPI_DEV 0x0001
23 /* word definitions */
24 /* ---------------- */
25 #define GEN_CONFIG 0 /* general configuration */
26 #define LCYLS 1 /* number of logical cylinders */
27 #define CONFIG 2 /* specific configuration */
28 #define LHEADS 3 /* number of logical heads */
29 #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
30 #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
31 #define LSECTS 6 /* number of logical sectors/track */
32 #define START_SERIAL 10 /* ASCII serial number */
33 #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
34 #define BUF_TYPE 20 /* buffer type (ATA-1) */
35 #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
36 #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
37 #define START_FW_REV 23 /* ASCII firmware revision */
38 #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
39 #define START_MODEL 27 /* ASCII model number */
40 #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
41 #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
42 #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
43 #define CAPAB_0 49 /* capabilities */
45 #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
46 #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
47 #define WHATS_VALID 53 /* what fields are valid */
48 #define LCYLS_CUR 54 /* current logical cylinders */
49 #define LHEADS_CUR 55 /* current logical heads */
50 #define LSECTS_CUR 56 /* current logical sectors/track */
51 #define CAPACITY_LSB 57 /* current capacity in sectors */
52 #define CAPACITY_MSB 58
53 #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
54 #define LBA_SECTS_LSB 60 /* LBA: total number of user */
55 #define LBA_SECTS_MSB 61 /* addressable sectors */
56 #define SINGLE_DMA 62 /* singleword DMA modes */
57 #define MULTI_DMA 63 /* multiword DMA modes */
58 #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
59 /* multiword DMA xfer cycle time: */
60 #define DMA_TIME_MIN 65 /* - minimum */
61 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
62 /* minimum PIO xfer cycle time: */
63 #define PIO_NO_FLOW 67 /* - without flow control */
64 #define PIO_FLOW 68 /* - with IORDY flow control */
65 #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
66 #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
67 #define CDR_MAJOR 73 /* CD ROM: major version number */
68 #define CDR_MINOR 74 /* CD ROM: minor version number */
69 #define QUEUE_DEPTH 75 /* queue depth */
70 #define MAJOR 80 /* major version number */
71 #define MINOR 81 /* minor version number */
72 #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
73 #define CMDS_SUPP_1 83
74 #define CMDS_SUPP_2 84
75 #define CMDS_EN_0 85 /* command/feature set(s) enabled */
78 #define ULTRA_DMA 88 /* ultra DMA modes */
79 /* time to complete security erase */
80 #define ERASE_TIME 89 /* - ordinary */
81 #define ENH_ERASE_TIME 90 /* - enhanced */
82 #define ADV_PWR 91 /* current advanced power management level
83 in low byte, 0x40 in high byte. */
84 #define PSWD_CODE 92 /* master password revision code */
85 #define HWRST_RSLT 93 /* hardware reset result */
86 #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
87 #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
88 #define LBA_MID 101 /* bits are used, but addr 103 */
89 #define LBA_48_MSB 102 /* has been reserved for LBA in */
90 #define LBA_64_MSB 103 /* the future. */
91 #define RM_STAT 127 /* removable media status notification feature set support */
92 #define SECU_STATUS 128 /* security status */
93 #define CFA_PWR_MODE 160 /* CFA power mode 1 */
94 #define START_MEDIA 176 /* media serial number */
95 #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
96 #define START_MANUF 196 /* media manufacturer I.D. */
97 #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
98 #define INTEGRITY 255 /* integrity word */
100 /* bit definitions within the words */
101 /* -------------------------------- */
103 /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
105 #define VALID_VAL 0x4000
106 /* many words are considered invalid if they are either all-0 or all-1 */
107 #define NOVAL_0 0x0000
108 #define NOVAL_1 0xffff
110 /* word 0: gen_config */
111 #define NOT_ATA 0x8000
112 #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
113 #define MEDIA_REMOVABLE 0x0080
114 #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
115 #define INCOMPLETE 0x0004
116 #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
117 #define DRQ_RESPONSE_TIME 0x0060
118 #define DRQ_3MS_VAL 0x0000
119 #define DRQ_INTR_VAL 0x0020
120 #define DRQ_50US_VAL 0x0040
121 #define PKT_SIZE_SUPPORTED 0x0003
122 #define PKT_SIZE_12_VAL 0x0000
123 #define PKT_SIZE_16_VAL 0x0001
124 #define EQPT_TYPE 0x1f00
129 /* word 1: number of logical cylinders */
130 #define LCYLS_MAX 0x3fff /* maximum allowable value */
132 /* word 2: specific configuration
133 * (a) require SET FEATURES to spin-up
134 * (b) require spin-up to fully reply to IDENTIFY DEVICE
136 #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
137 #define STBY_ID_VAL 0x738c /* (a) and not (b) */
138 #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
139 #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
141 /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
142 #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
143 #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
145 /* word 49: capabilities 0 */
146 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
147 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
148 #define IORDY_OFF 0x0400 /* 1=may be disabled */
149 #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
150 #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
151 #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
152 #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
153 #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
154 #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
156 /* word 50: capabilities 1 */
157 #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
159 /* words 51 & 52: PIO & DMA cycle times */
160 #define MODE 0xff00 /* the mode is in the MSBs */
162 /* word 53: whats_valid */
163 #define OK_W88 0x0004 /* the ultra_dma info is valid */
164 #define OK_W64_70 0x0002 /* see above for word descriptions */
165 #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
167 /*word 63,88: dma_mode, ultra_dma_mode*/
168 #define MODE_MAX 7 /* bit definitions force udma <=7 (when
169 * udma >=8 comes out it'll have to be
170 * defined in a new dma_mode word!) */
172 /* word 64: PIO transfer modes */
173 #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
174 #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
176 /* word 75: queue_depth */
177 #define DEPTH_BITS 0x001f /* bits used for queue depth */
179 /* words 80-81: version numbers */
180 /* NOVAL_0 or NOVAL_1 means device does not report version */
182 /* word 81: minor version number */
183 #define MINOR_MAX 0x22
184 /* words 82-84: cmds/feats supported */
185 #define CMDS_W82 0x77ff /* word 82: defined command locations*/
186 #define CMDS_W83 0x3fff /* word 83: defined command locations*/
187 #define CMDS_W84 0x002f /* word 83: defined command locations*/
188 #define SUPPORT_48_BIT 0x0400
189 #define NUM_CMD_FEAT_STR 48
191 /* words 85-87: cmds/feats enabled */
192 /* use cmd_feat_str[] to display what commands and features have
193 * been enabled with words 85-87
196 /* words 89, 90, SECU ERASE TIME */
197 #define ERASE_BITS 0x00ff
199 /* word 92: master password revision */
200 /* NOVAL_0 or NOVAL_1 means no support for master password revision */
202 /* word 93: hw reset result */
203 #define CBLID 0x2000 /* CBLID status */
204 #define RST0 0x0001 /* 1=reset to device #0 */
205 #define DEV_DET 0x0006 /* how device num determined */
206 #define JUMPER_VAL 0x0002 /* device num determined by jumper */
207 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
209 /* word 127: removable media status notification feature set support */
210 #define RM_STAT_BITS 0x0003
211 #define RM_STAT_SUP 0x0001
213 /* word 128: security */
214 #define SECU_ENABLED 0x0002
215 #define SECU_LEVEL 0x0010
216 #define NUM_SECU_STR 6
218 /* word 160: CFA power mode */
219 #define VALID_W160 0x8000 /* 1=word valid */
220 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
221 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
222 #define MAX_AMPS 0x0fff /* value = max current in ma */
224 /* word 255: integrity */
225 #define SIG 0x00ff /* signature location */
226 #define SIG_VAL 0x00a5 /* signature value */
228 #define TIMING_BUF_MB 1
229 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
231 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
242 smallint get_identity, get_geom;
244 smallint do_ctimings, do_timings;
245 smallint reread_partn;
246 smallint set_piomode, noisy_piomode;
247 smallint getset_readahead;
248 smallint getset_readonly;
249 smallint getset_unmask;
250 smallint getset_mult;
252 smallint getset_dma_q;
254 smallint getset_nowerr;
255 smallint getset_keep;
256 smallint getset_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
272 #ifdef HDIO_DRIVE_CMD
273 smallint set_xfermode, get_xfermode;
274 smallint getset_dkeep;
275 smallint getset_standby;
276 smallint getset_lookahead;
277 smallint getset_prefetch;
278 smallint getset_defects;
279 smallint getset_wcache;
280 smallint getset_doorlock;
281 smallint set_seagate;
282 smallint set_standbynow;
283 smallint set_sleepnow;
284 smallint get_powermode;
285 smallint getset_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 getset_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 getset_readahead (G.getset_readahead )
327 #define getset_readonly (G.getset_readonly )
328 #define getset_unmask (G.getset_unmask )
329 #define getset_mult (G.getset_mult )
330 #define getset_dma_q (G.getset_dma_q )
331 #define getset_nowerr (G.getset_nowerr )
332 #define getset_keep (G.getset_keep )
333 #define getset_io32bit (G.getset_io32bit )
334 #define piomode (G.piomode )
335 #define Xreadahead (G.Xreadahead )
336 #define readonly (G.readonly )
337 #define unmask (G.unmask )
338 #define mult (G.mult )
339 #define dma_q (G.dma_q )
340 #define nowerr (G.nowerr )
341 #define keep (G.keep )
342 #define io32bit (G.io32bit )
344 #define getset_dma (G.getset_dma )
345 #define set_xfermode (G.set_xfermode )
346 #define get_xfermode (G.get_xfermode )
347 #define getset_dkeep (G.getset_dkeep )
348 #define getset_standby (G.getset_standby )
349 #define getset_lookahead (G.getset_lookahead )
350 #define getset_prefetch (G.getset_prefetch )
351 #define getset_defects (G.getset_defects )
352 #define getset_wcache (G.getset_wcache )
353 #define getset_doorlock (G.getset_doorlock )
354 #define set_seagate (G.set_seagate )
355 #define set_standbynow (G.set_standbynow )
356 #define set_sleepnow (G.set_sleepnow )
357 #define get_powermode (G.get_powermode )
358 #define getset_apmmode (G.getset_apmmode )
359 #define xfermode_requested (G.xfermode_requested )
360 #define dkeep (G.dkeep )
361 #define standby_requested (G.standby_requested )
362 #define lookahead (G.lookahead )
363 #define prefetch (G.prefetch )
364 #define defects (G.defects )
365 #define wcache (G.wcache )
366 #define doorlock (G.doorlock )
367 #define apmmode (G.apmmode )
368 #define get_IDentity (G.get_IDentity )
369 #define getset_busstate (G.getset_busstate )
370 #define perform_reset (G.perform_reset )
371 #define perform_tristate (G.perform_tristate )
372 #define unregister_hwif (G.unregister_hwif )
373 #define scan_hwif (G.scan_hwif )
374 #define busstate (G.busstate )
375 #define tristate (G.tristate )
376 #define hwif (G.hwif )
377 #define hwif_data (G.hwif_data )
378 #define hwif_ctrl (G.hwif_ctrl )
379 #define hwif_irq (G.hwif_irq )
382 /* Busybox messages and functions */
383 #if ENABLE_IOCTL_HEX2STR_ERROR
384 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
386 if (!ioctl(fd, cmd, args))
389 return bb_ioctl_or_warn(fd, cmd, args, string);
391 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
393 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
395 if (!ioctl(fd, cmd, args))
398 return bb_ioctl_or_warn(fd, cmd, args);
400 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
403 static void on_off(int value)
405 puts(value ? " (on)" : " (off)");
408 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
411 printf(" setting %s to %ld", s, arg);
416 static void print_value_on_off(const char *str, unsigned long argp)
418 printf(" %s\t= %2ld", str, argp);
422 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
423 static void print_ascii(const char *p, int length)
430 /* every 16bit word is big-endian (i.e. inverted) */
431 /* accessing bytes in 1,0, 3,2, 5,4... sequence */
436 /* find first non-space & print it */
437 while (length && p[ofs] != ' ') {
442 while (length && p[ofs]) {
452 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
455 printf("\t%-20s", string);
456 print_ascii((void*)&val[i], n);
460 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
465 for (ii = 0; ii <= MODE_MAX; ii++) {
466 if (mode_sel & 0x0001) {
467 printf("*%cdma%u ", cc, ii);
471 } else if (mode_sup & 0x0001)
472 printf("%cdma%u ", cc, ii);
480 static const char pkt_str[] ALIGN1 =
481 "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
482 "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
483 "Printer" "\0" /* word 0, bits 12-8 = 02 */
484 "Processor" "\0" /* word 0, bits 12-8 = 03 */
485 "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
486 "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
487 "Scanner" "\0" /* word 0, bits 12-8 = 06 */
488 "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
489 "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
490 "Communications device" "\0" /* word 0, bits 12-8 = 09 */
491 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
492 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
493 "Array controller" "\0" /* word 0, bits 12-8 = 0c */
494 "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
495 "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
496 "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
499 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
500 "reserved" "\0" /* bit 0 */
501 "hard sectored" "\0" /* bit 1 */
502 "soft sectored" "\0" /* bit 2 */
503 "not MFM encoded " "\0" /* bit 3 */
504 "head switch time > 15us" "\0" /* bit 4 */
505 "spindle motor control option" "\0" /* bit 5 */
506 "fixed drive" "\0" /* bit 6 */
507 "removable drive" "\0" /* bit 7 */
508 "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
509 "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
510 "disk xfer rate > 5Mbs" "\0" /* bit 10 */
511 "rotational speed tol." "\0" /* bit 11 */
512 "data strobe offset option" "\0" /* bit 12 */
513 "track offset option" "\0" /* bit 13 */
514 "format speed tolerance gap reqd" "\0" /* bit 14 */
518 static const char minor_str[] ALIGN1 =
520 "Unspecified" "\0" /* 0x0000 */
521 "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
522 "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
523 "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
524 "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
525 "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
526 "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
527 "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
528 "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
529 "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
530 "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
531 "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
532 "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
533 "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
534 "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
535 "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
536 "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
537 "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
538 "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
539 "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
540 "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
541 "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
542 "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
543 "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
544 "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
545 "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
546 "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
547 "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
548 "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
549 "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
550 "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
551 "reserved" "\0" /* 0x001f */
552 "reserved" "\0" /* 0x0020 */
553 "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
554 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
555 "reserved" /* 0x0023-0xfffe */
557 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
559 0, /* 0x0000 WARNING: actual_ver[] array */
560 1, /* 0x0001 WARNING: corresponds */
561 1, /* 0x0002 WARNING: *exactly* */
562 1, /* 0x0003 WARNING: to the ATA/ */
563 2, /* 0x0004 WARNING: ATAPI version */
564 2, /* 0x0005 WARNING: listed in */
565 3, /* 0x0006 WARNING: the */
566 2, /* 0x0007 WARNING: minor_str */
567 3, /* 0x0008 WARNING: array */
568 2, /* 0x0009 WARNING: above. */
569 3, /* 0x000a WARNING: */
570 3, /* 0x000b WARNING: If you change */
571 3, /* 0x000c WARNING: that one, */
572 4, /* 0x000d WARNING: change this one */
573 4, /* 0x000e WARNING: too!!! */
594 0 /* 0x0023-0xfffe */
597 static const char cmd_feat_str[] ALIGN1 =
598 "" "\0" /* word 82 bit 15: obsolete */
599 "NOP cmd" "\0" /* word 82 bit 14 */
600 "READ BUFFER cmd" "\0" /* word 82 bit 13 */
601 "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
602 "" "\0" /* word 82 bit 11: obsolete */
603 "Host Protected Area feature set" "\0" /* word 82 bit 10 */
604 "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
605 "SERVICE interrupt" "\0" /* word 82 bit 8 */
606 "Release interrupt" "\0" /* word 82 bit 7 */
607 "Look-ahead" "\0" /* word 82 bit 6 */
608 "Write cache" "\0" /* word 82 bit 5 */
609 "PACKET command feature set" "\0" /* word 82 bit 4 */
610 "Power Management feature set" "\0" /* word 82 bit 3 */
611 "Removable Media feature set" "\0" /* word 82 bit 2 */
612 "Security Mode feature set" "\0" /* word 82 bit 1 */
613 "SMART feature set" "\0" /* word 82 bit 0 */
615 "" "\0" /* word 83 bit 15: !valid bit */
616 "" "\0" /* word 83 bit 14: valid bit */
617 "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
618 "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
619 "Device Configuration Overlay feature set " "\0"
620 "48-bit Address feature set " "\0" /* word 83 bit 10 */
622 "SET MAX security extension" "\0" /* word 83 bit 8 */
623 "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
624 "SET FEATURES subcommand required to spinup after power up" "\0"
625 "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
626 "Removable Media Status Notification feature set" "\0"
627 "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
628 "CFA feature set" "\0" /* word 83 bit 2 */
629 "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
630 "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
632 "" "\0" /* word 84 bit 15: !valid bit */
633 "" "\0" /* word 84 bit 14: valid bit */
634 "" "\0" /* word 84 bit 13: reserved */
635 "" "\0" /* word 84 bit 12: reserved */
636 "" "\0" /* word 84 bit 11: reserved */
637 "" "\0" /* word 84 bit 10: reserved */
638 "" "\0" /* word 84 bit 9: reserved */
639 "" "\0" /* word 84 bit 8: reserved */
640 "" "\0" /* word 84 bit 7: reserved */
641 "" "\0" /* word 84 bit 6: reserved */
642 "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
643 "" "\0" /* word 84 bit 4: reserved */
644 "Media Card Pass Through Command feature set " "\0"
645 "Media serial number " "\0" /* word 84 bit 2 */
646 "SMART self-test " "\0" /* word 84 bit 1 */
647 "SMART error logging " /* word 84 bit 0 */
650 static const char secu_str[] ALIGN1 =
651 "supported" "\0" /* word 128, bit 0 */
652 "enabled" "\0" /* word 128, bit 1 */
653 "locked" "\0" /* word 128, bit 2 */
654 "frozen" "\0" /* word 128, bit 3 */
655 "expired: security count" "\0" /* word 128, bit 4 */
656 "supported: enhanced erase" /* word 128, bit 5 */
659 // Parse 512 byte disk identification block and print much crap.
660 static void identify(uint16_t *val) NORETURN;
661 static void identify(uint16_t *val)
664 uint16_t like_std = 1, std = 0, min_std = 0xffff;
665 uint16_t dev = NO_DEV, eqpt = NO_DEV;
666 uint8_t have_mode = 0, err_dma = 0;
668 uint32_t ll, mm, nn, oo;
669 uint64_t bbbig; /* (:) */
674 // Adjust for endianness
675 swab(val, buf, sizeof(buf));
678 /* check if we recognize the device type */
680 if (!(val[GEN_CONFIG] & NOT_ATA)) {
682 printf("ATA device, with ");
683 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
686 printf("CompactFlash ATA device, with ");
687 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
689 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
690 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
693 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
694 bb_error_msg_and_die("unknown device type");
696 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
697 /* Info from the specific configuration word says whether or not the
698 * ID command completed correctly. It is only defined, however in
699 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
700 * standards. Since the values allowed for this word are extremely
701 * specific, it should be safe to check it now, even though we don't
702 * know yet what standard this device is using.
704 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
705 || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
708 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
709 printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
710 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
711 printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
714 /* output the model and serial numbers and the fw revision */
715 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
716 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
717 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
718 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
719 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
721 /* major & minor standards version number (Note: these words were not
722 * defined until ATA-3 & the CDROM std uses different words.) */
723 printf("Standards:");
725 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
726 if (like_std < 3) like_std = 3;
727 std = actual_ver[val[MINOR]];
728 if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
731 /* looks like when they up-issue the std, they obsolete one;
732 * thus, only the newest 4 issues need be supported. (That's
733 * what "kk" and "min_std" are all about.) */
734 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
735 printf("\n\tSupported: ");
736 jj = val[MAJOR] << 1;
737 kk = like_std >4 ? like_std-4: 0;
738 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
743 kk = like_std >4 ? like_std-4: 0;
745 if (min_std > ii) min_std = ii;
749 if (like_std < 3) like_std = 3;
751 /* Figure out what standard the device is using if it hasn't told
752 * us. If we know the std, check if the device is using any of
753 * the words from the next level up. It happens.
755 if (like_std < std) like_std = std;
757 if (((std == 5) || (!std && (like_std < 6))) &&
758 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
759 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
760 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
761 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
764 } else if (((std == 4) || (!std && (like_std < 5))) &&
765 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
766 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
767 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
768 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
771 } else if (((std == 3) || (!std && (like_std < 4))) &&
772 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
773 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
774 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
775 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
776 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
777 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
780 } else if (((std == 2) || (!std && (like_std < 3)))
781 && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
784 } else if (((std == 1) || (!std && (like_std < 2))) &&
785 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
786 (val[WHATS_VALID] & OK_W64_70)) )
792 printf("\n\tLikely used: %u\n", like_std);
793 else if (like_std > std)
794 printf("& some of %u\n", like_std);
798 /* TBD: do CDROM stuff more thoroughly. For now... */
800 if (val[CDR_MINOR] == 9) {
802 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
804 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
806 printf("\n\tSupported: CD-ROM ATAPI");
807 jj = val[CDR_MAJOR] >> 1;
808 for (ii = 1; ii < 15; ii++) {
809 if (jj & 0x0001) printf("-%u ", ii);
813 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
814 /* the cdrom stuff is more like ATA-2 than anything else, so: */
818 if (min_std == 0xffff)
819 min_std = like_std > 4 ? like_std - 3 : 1;
821 printf("Configuration:\n");
822 /* more info from the general configuration word */
823 if ((eqpt != CDROM) && (like_std == 1)) {
824 jj = val[GEN_CONFIG] >> 1;
825 for (ii = 1; ii < 15; ii++) {
827 printf("\t%s\n", nth_string(ata1_cfg_str, ii));
831 if (dev == ATAPI_DEV) {
832 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
834 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
835 strng = "<=10ms with INTRQ";
836 else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
840 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
842 if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
844 else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
850 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
851 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
854 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
855 printf("\tCHS addressing not supported\n");
857 jj = val[WHATS_VALID] & OK_W54_58;
858 printf("\tLogical\t\tmax\tcurrent\n"
859 "\tcylinders\t%u\t%u\n"
860 "\theads\t\t%u\t%u\n"
861 "\tsectors/track\t%u\t%u\n"
864 jj ? val[LCYLS_CUR] : 0,
866 jj ? val[LHEADS_CUR] : 0,
868 jj ? val[LSECTS_CUR] : 0);
870 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
871 printf("\tbytes/track: %u\tbytes/sector: %u\n",
872 val[TRACK_BYTES], val[SECT_BYTES]);
875 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
877 /* check Endian of capacity bytes */
878 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
879 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
880 if (abs(mm - nn) > abs(oo - nn))
883 printf("\tCHS current addressable sectors:%11u\n", mm);
887 printf("\tLBA user addressable sectors:%11u\n", ll);
888 if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
889 && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
891 bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
892 (uint64_t)val[LBA_48_MSB] << 32 |
893 (uint64_t)val[LBA_MID] << 16 |
895 printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
899 bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
900 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
901 bbbig = (bbbig << 9) / 1000000;
902 printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
905 printf("(%"PRIu64" GB)\n", bbbig/1000);
910 /* hw support of commands (capabilities) */
911 printf("Capabilities:\n\t");
913 if (dev == ATAPI_DEV) {
914 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP))
915 printf("Cmd queuing, ");
916 if (val[CAPAB_0] & OVLP_SUP)
917 printf("Cmd overlap, ");
919 if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
922 printf("IORDY%s(can%s be disabled)\n",
923 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
924 (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
926 printf("no IORDY\n");
928 if ((like_std == 1) && val[BUF_TYPE]) {
929 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
930 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
931 (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
934 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
935 printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
937 if ((min_std < 4) && (val[RW_LONG])) {
938 printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
940 if ((eqpt != CDROM) && (like_std > 3)) {
941 printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
944 if (dev == ATA_DEV) {
946 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
948 printf("\tStandby timer values: spec'd by %s",
949 (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor");
950 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
951 printf(", %s device specific minimum\n",
952 (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
956 printf("\tR/W multiple sector transfer: ");
957 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
958 printf("not supported\n");
960 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
961 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
962 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
966 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
967 /* We print out elsewhere whether the APM feature is enabled or
968 not. If it's not enabled, let's not repeat the info; just print
970 printf("\tAdvancedPM level: ");
971 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
972 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
973 printf("%u (0x%x)\n", apm_level, apm_level);
976 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
978 if (like_std > 5 && val[ACOUSTIC]) {
979 printf("\tRecommended acoustic management value: %u, current value: %u\n",
980 (val[ACOUSTIC] >> 8) & 0x00ff,
981 val[ACOUSTIC] & 0x00ff);
985 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
986 printf("\tATA sw reset required\n");
988 if (val[PKT_REL] || val[SVC_NBSY]) {
989 printf("\tOverlap support:");
991 printf(" %uus to release bus.", val[PKT_REL]);
993 printf(" %uus to clear BSY after SERVICE cmd.",
999 /* DMA stuff. Check that only one DMA mode is selected. */
1001 if (!(val[CAPAB_0] & DMA_SUP))
1002 printf("not supported\n");
1004 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1005 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1006 if (val[SINGLE_DMA]) {
1007 jj = val[SINGLE_DMA];
1008 kk = val[SINGLE_DMA] >> 8;
1009 err_dma += mode_loop(jj, kk, 's', &have_mode);
1011 if (val[MULTI_DMA]) {
1012 jj = val[MULTI_DMA];
1013 kk = val[MULTI_DMA] >> 8;
1014 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1016 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1017 jj = val[ULTRA_DMA];
1018 kk = val[ULTRA_DMA] >> 8;
1019 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1021 if (err_dma || !have_mode) printf("(?)");
1024 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1025 printf("\t\tInterleaved DMA support\n");
1027 if ((val[WHATS_VALID] & OK_W64_70)
1028 && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1030 printf("\t\tCycle time:");
1031 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1032 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1037 /* Programmed IO stuff */
1039 /* If a drive supports mode n (e.g. 3), it also supports all modes less
1040 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1041 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1042 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1043 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1044 if (jj & 0x0001) printf("pio%d ", ii);
1048 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1049 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1050 printf("pio%d ", ii);
1055 if (val[WHATS_VALID] & OK_W64_70) {
1056 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1057 printf("\t\tCycle time:");
1058 if (val[PIO_NO_FLOW])
1059 printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1061 printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1066 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1067 printf("Commands/features:\n"
1068 "\tEnabled\tSupported:\n");
1069 jj = val[CMDS_SUPP_0];
1070 kk = val[CMDS_EN_0];
1071 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1072 const char *feat_str = nth_string(cmd_feat_str, ii);
1073 if ((jj & 0x8000) && (*feat_str != '\0')) {
1074 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
1078 if (ii % 16 == 15) {
1079 jj = val[CMDS_SUPP_0+1+(ii/16)];
1080 kk = val[CMDS_EN_0+1+(ii/16)];
1083 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1088 /* Removable Media Status Notification feature set */
1089 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1090 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1093 if ((eqpt != CDROM) && (like_std > 3)
1094 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1096 printf("Security:\n");
1097 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1098 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1099 jj = val[SECU_STATUS];
1101 for (ii = 0; ii < NUM_SECU_STR; ii++) {
1102 printf("\t%s\t%s\n",
1103 (!(jj & 0x0001)) ? "not" : "",
1104 nth_string(secu_str, ii));
1107 if (val[SECU_STATUS] & SECU_ENABLED) {
1108 printf("\tSecurity level %s\n",
1109 (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1112 jj = val[ERASE_TIME] & ERASE_BITS;
1113 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1116 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1117 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1123 jj = val[HWRST_RSLT];
1124 if ((jj & VALID) == VALID_VAL) {
1128 if ((jj & DEV_DET) == JUMPER_VAL)
1129 strng = " determined by the jumper";
1130 else if ((jj & DEV_DET) == CSEL_VAL)
1131 strng = " determined by CSEL";
1134 printf("HW reset results:\n"
1136 "\tDevice num = %i%s\n",
1137 (val[HWRST_RSLT] & CBLID) ? "above" : "below",
1141 /* more stuff from std 5 */
1142 if ((like_std > 4) && (eqpt != CDROM)) {
1143 if (val[CFA_PWR_MODE] & VALID_W160) {
1144 printf("CFA power mode 1:\n"
1146 (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1147 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1148 if (val[CFA_PWR_MODE] & MAX_AMPS)
1149 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1151 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1152 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1160 // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1161 // then the HDIO_GET_IDENTITY only returned 142 bytes.
1162 // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1163 // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1164 // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1165 // (which they should, but they should just return -EINVAL).
1167 // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1168 // On a really old system, it will not, and we will be confused.
1171 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1172 static const char cfg_str[] ALIGN1 =
1173 """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
1174 "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
1175 "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1176 "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
1179 static const char BuffType[] ALIGN1 =
1180 "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
1183 static void dump_identity(const struct hd_driveid *id)
1186 const unsigned short *id_regs = (const void*) id;
1188 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1189 id->model, id->fw_rev, id->serial_no);
1190 for (i = 0; i <= 15; i++) {
1191 if (id->config & (1<<i))
1192 printf(" %s", nth_string(cfg_str, i));
1194 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1195 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1196 id->cyls, id->heads, id->sectors, id->track_bytes,
1197 id->sector_bytes, id->ecc_bytes,
1199 nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1200 id->buf_size/2, id->max_multsect);
1201 if (id->max_multsect) {
1202 printf(", MultSect=");
1203 if (!(id->multsect_valid & 1))
1204 printf("?%u?", id->multsect);
1205 else if (id->multsect)
1206 printf("%u", id->multsect);
1212 if (!(id->field_valid & 1))
1213 printf(" (maybe):");
1215 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1218 (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1219 (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1220 ((id->capability&2) == 0) ? "no" : "yes");
1222 if (id->capability & 2)
1223 printf(", LBAsects=%u", id->lba_capacity);
1225 printf("\n IORDY=%s",
1226 (id->capability & 8)
1227 ? ((id->capability & 4) ? "on/off" : "yes")
1230 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1231 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1233 if ((id->capability & 1) && (id->field_valid & 2))
1234 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1236 printf("\n PIO modes: ");
1237 if (id->tPIO <= 5) {
1239 if (id->tPIO >= 1) printf("pio1 ");
1240 if (id->tPIO >= 2) printf("pio2 ");
1242 if (id->field_valid & 2) {
1243 static const masks_labels_t pio_modes = {
1244 .masks = { 1, 2, ~3 },
1245 .labels = "pio3 \0""pio4 \0""pio? \0",
1247 print_flags(&pio_modes, id->eide_pio_modes);
1249 if (id->capability & 1) {
1250 if (id->dma_1word | id->dma_mword) {
1251 static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
1252 printf("\n DMA modes: ");
1253 print_flags_separated(dma_wmode_masks,
1254 "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
1255 id->dma_1word, NULL);
1256 print_flags_separated(dma_wmode_masks,
1257 "*\0""mdma0 \0""*\0""mdma1 \0""*\0""mdma2 \0""*\0""mdma? \0",
1258 id->dma_mword, NULL);
1261 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1262 static const masks_labels_t ultra_modes1 = {
1263 .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
1264 .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
1267 printf("\n UDMA modes: ");
1268 print_flags(&ultra_modes1, id->dma_ultra);
1269 #ifdef __NEW_HD_DRIVE_ID
1270 if (id->hw_config & 0x2000) {
1271 #else /* !__NEW_HD_DRIVE_ID */
1272 if (id->word93 & 0x2000) {
1273 #endif /* __NEW_HD_DRIVE_ID */
1274 static const masks_labels_t ultra_modes2 = {
1275 .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
1276 0x2000, 0x0020, 0x4000, 0x0040,
1278 .labels = "*\0""udma3 \0""*\0""udma4 \0"
1279 "*\0""udma5 \0""*\0""udma6 \0"
1282 print_flags(&ultra_modes2, id->dma_ultra);
1285 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1286 if (id_regs[83] & 8) {
1287 if (!(id_regs[86] & 8))
1288 printf(": disabled (255)");
1289 else if ((id_regs[91] & 0xFF00) != 0x4000)
1290 printf(": unknown setting");
1292 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1294 if (id_regs[82] & 0x20)
1295 printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1296 #ifdef __NEW_HD_DRIVE_ID
1297 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1298 || (id->major_rev_num && id->minor_rev_num <= 31)
1300 printf("\n Drive conforms to: %s: ",
1301 (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1302 if (id->major_rev_num != 0x0000 /* NOVAL_0 */
1303 && id->major_rev_num != 0xFFFF /* NOVAL_1 */
1305 for (i = 0; i <= 15; i++) {
1306 if (id->major_rev_num & (1<<i))
1307 printf(" ATA/ATAPI-%u", i);
1311 #endif /* __NEW_HD_DRIVE_ID */
1312 printf("\n\n * current active mode\n\n");
1316 static void flush_buffer_cache(/*int fd*/ void)
1318 fsync(fd); /* flush buffers */
1319 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1320 #ifdef HDIO_DRIVE_CMD
1322 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1323 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1324 bb_perror_msg("HDIO_DRIVE_CMD");
1326 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1331 static void seek_to_zero(/*int fd*/ void)
1333 xlseek(fd, (off_t) 0, SEEK_SET);
1336 static void read_big_block(/*int fd,*/ char *buf)
1340 xread(fd, buf, TIMING_BUF_BYTES);
1341 /* access all sectors of buf to ensure the read fully completed */
1342 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1346 static unsigned dev_size_mb(/*int fd*/ void)
1349 unsigned long long blksize64;
1353 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1354 u.blksize64 /= (1024 * 1024);
1356 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1357 u.blksize64 = u.blksize32 / (2 * 1024);
1359 if (u.blksize64 > UINT_MAX)
1364 static void print_timing(unsigned m, unsigned elapsed_us)
1366 unsigned sec = elapsed_us / 1000000;
1367 unsigned hs = (elapsed_us % 1000000) / 10000;
1369 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1371 /* "| 1" prevents div-by-0 */
1372 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1373 // ~= (m * 1024) / (elapsed_us / 1000000)
1374 // = kb / elapsed_sec
1378 static void do_time(int cache /*,int fd*/)
1379 /* cache=1: time cache: repeatedly read N MB at offset 0
1380 * cache=0: time device: linear read, starting at offset 0
1383 unsigned max_iterations, iterations;
1384 unsigned start; /* doesn't need to be long long */
1385 unsigned elapsed, elapsed2;
1387 char *buf = xmalloc(TIMING_BUF_BYTES);
1389 if (mlock(buf, TIMING_BUF_BYTES))
1390 bb_perror_msg_and_die("mlock");
1392 /* Clear out the device request queues & give them time to complete.
1393 * NB: *small* delay. User is expected to have a clue and to not run
1394 * heavy io in parallel with measurements. */
1397 if (cache) { /* Time cache */
1399 read_big_block(buf);
1400 printf("Timing buffer-cache reads: ");
1401 } else { /* Time device */
1402 printf("Timing buffered disk reads:");
1406 /* Now do the timing */
1408 /* Max time to run (small for cache, avoids getting
1409 * huge total_MB which can overlow unsigned type) */
1410 elapsed2 = 510000; /* cache */
1411 max_iterations = UINT_MAX;
1413 elapsed2 = 3000000; /* not cache */
1414 /* Don't want to read past the end! */
1415 max_iterations = dev_size_mb() / TIMING_BUF_MB;
1417 start = monotonic_us();
1421 read_big_block(buf);
1422 elapsed = (unsigned)monotonic_us() - start;
1424 } while (elapsed < elapsed2 && iterations < max_iterations);
1425 total_MB = iterations * TIMING_BUF_MB;
1426 //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1428 /* Cache: remove lseek() and monotonic_us() overheads
1430 start = monotonic_us();
1433 elapsed2 = (unsigned)monotonic_us() - start;
1434 } while (--iterations);
1435 //printf(" elapsed2:%u ", elapsed2);
1436 elapsed -= elapsed2;
1437 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1438 flush_buffer_cache();
1440 print_timing(total_MB, elapsed);
1441 munlock(buf, TIMING_BUF_BYTES);
1445 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1446 static void bus_state_value(unsigned value)
1448 if (value == BUSSTATE_ON)
1450 else if (value == BUSSTATE_OFF)
1452 else if (value == BUSSTATE_TRISTATE)
1453 printf(" (tristate)\n");
1455 printf(" (unknown: %d)\n", value);
1459 #ifdef HDIO_DRIVE_CMD
1460 static void interpret_standby(uint8_t standby)
1465 } else if (standby <= 240 || standby == 252 || standby == 255) {
1466 /* standby is in 5 sec units */
1467 unsigned t = standby * 5;
1468 printf("%u minutes %u seconds", t / 60, t % 60);
1469 } else if (standby <= 251) {
1470 unsigned t = (standby - 240); /* t is in 30 min units */;
1471 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0');
1474 printf("vendor-specific");
1480 static const uint8_t xfermode_val[] ALIGN1 = {
1481 8, 9, 10, 11, 12, 13, 14, 15,
1482 16, 17, 18, 19, 20, 21, 22, 23,
1483 32, 33, 34, 35, 36, 37, 38, 39,
1484 64, 65, 66, 67, 68, 69, 70, 71
1486 /* NB: we save size by _not_ storing terninating NUL! */
1487 static const char xfermode_name[][5] ALIGN1 = {
1488 "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1489 "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1490 "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1491 "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1494 static int translate_xfermode(const char *name)
1499 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1500 if (!strncmp(name, xfermode_name[i], 5))
1501 if (strlen(name) <= 5)
1502 return xfermode_val[i];
1504 /* Negative numbers are invalid and are caught later */
1505 val = bb_strtoi(name, NULL, 10);
1511 static void interpret_xfermode(unsigned xfermode)
1515 printf("default PIO mode");
1516 else if (xfermode == 1)
1517 printf("default PIO mode, disable IORDY");
1518 else if (xfermode >= 8 && xfermode <= 15)
1519 printf("PIO flow control mode%u", xfermode - 8);
1520 else if (xfermode >= 16 && xfermode <= 23)
1521 printf("singleword DMA mode%u", xfermode - 16);
1522 else if (xfermode >= 32 && xfermode <= 39)
1523 printf("multiword DMA mode%u", xfermode - 32);
1524 else if (xfermode >= 64 && xfermode <= 71)
1525 printf("UltraDMA mode%u", xfermode - 64);
1530 #endif /* HDIO_DRIVE_CMD */
1532 static void print_flag(int flag, const char *s, unsigned long value)
1535 printf(" setting %s to %ld\n", s, value);
1538 static void process_dev(char *devname)
1541 long parm, multcount;
1542 #ifndef HDIO_DRIVE_CMD
1543 int force_operation = 0;
1545 /* Please restore args[n] to these values after each ioctl
1546 except for args[2] */
1547 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1548 const char *fmt = " %s\t= %2ld";
1550 /*fd = xopen(devname, O_RDONLY | O_NONBLOCK);*/
1551 xmove_fd(xopen(devname, O_RDONLY | O_NONBLOCK), fd);
1552 printf("\n%s:\n", devname);
1554 if (getset_readahead == IS_SET) {
1555 print_flag(getset_readahead, "fs readahead", Xreadahead);
1556 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1558 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1559 if (unregister_hwif) {
1560 printf(" attempting to unregister hwif#%lu\n", hwif);
1561 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1564 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1565 if (scan_hwif == IS_SET) {
1566 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1567 args[0] = hwif_data;
1568 args[1] = hwif_ctrl;
1570 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1571 args[0] = WIN_SETFEATURES;
1576 if (noisy_piomode) {
1577 printf(" attempting to ");
1579 printf("auto-tune PIO mode\n");
1580 else if (piomode < 100)
1581 printf("set PIO mode to %d\n", piomode);
1582 else if (piomode < 200)
1583 printf("set MDMA mode to %d\n", (piomode-100));
1585 printf("set UDMA mode to %d\n", (piomode-200));
1587 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1589 if (getset_io32bit == IS_SET) {
1590 print_flag(getset_io32bit, "32-bit IO_support flag", io32bit);
1591 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1593 if (getset_mult == IS_SET) {
1594 print_flag(getset_mult, "multcount", mult);
1595 #ifdef HDIO_DRIVE_CMD
1596 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1598 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1601 if (getset_readonly == IS_SET) {
1602 print_flag_on_off(getset_readonly, "readonly", readonly);
1603 ioctl_or_warn(fd, BLKROSET, &readonly);
1605 if (getset_unmask == IS_SET) {
1606 print_flag_on_off(getset_unmask, "unmaskirq", unmask);
1607 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1609 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1610 if (getset_dma == IS_SET) {
1611 print_flag_on_off(getset_dma, "using_dma", dma);
1612 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1614 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1615 #ifdef HDIO_SET_QDMA
1616 if (getset_dma_q == IS_SET) {
1617 print_flag_on_off(getset_dma_q, "DMA queue_depth", dma_q);
1618 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1621 if (getset_nowerr == IS_SET) {
1622 print_flag_on_off(getset_nowerr, "nowerr", nowerr);
1623 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1625 if (getset_keep == IS_SET) {
1626 print_flag_on_off(getset_keep, "keep_settings", keep);
1627 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1629 #ifdef HDIO_DRIVE_CMD
1630 if (getset_doorlock == IS_SET) {
1631 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1633 print_flag_on_off(getset_doorlock, "drive doorlock", doorlock);
1634 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1635 args[0] = WIN_SETFEATURES;
1637 if (getset_dkeep == IS_SET) {
1638 /* lock/unlock the drive's "feature" settings */
1639 print_flag_on_off(getset_dkeep, "drive keep features", dkeep);
1640 args[2] = dkeep ? 0x66 : 0xcc;
1641 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1643 if (getset_defects == IS_SET) {
1644 args[2] = defects ? 0x04 : 0x84;
1645 print_flag(getset_defects, "drive defect-mgmt", defects);
1646 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1648 if (getset_prefetch == IS_SET) {
1651 print_flag(getset_prefetch, "drive prefetch", prefetch);
1652 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1656 args[1] = xfermode_requested;
1658 print_flag(1, "xfermode", xfermode_requested);
1659 interpret_xfermode(xfermode_requested);
1660 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1663 if (getset_lookahead == IS_SET) {
1664 args[2] = lookahead ? 0xaa : 0x55;
1665 print_flag_on_off(getset_lookahead, "drive read-lookahead", lookahead);
1666 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1668 if (getset_apmmode == IS_SET) {
1669 /* feature register */
1670 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */;
1671 args[1] = apmmode; /* sector count register 1-255 */
1672 printf(" setting APM level to %s 0x%02lX (%ld)\n",
1673 (apmmode == 255) ? "disabled" : "",
1675 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1678 if (getset_wcache == IS_SET) {
1679 #ifdef DO_FLUSHCACHE
1680 #ifndef WIN_FLUSHCACHE
1681 #define WIN_FLUSHCACHE 0xe7
1683 #endif /* DO_FLUSHCACHE */
1684 args[2] = wcache ? 0x02 : 0x82;
1685 print_flag_on_off(getset_wcache, "drive write-caching", wcache);
1686 #ifdef DO_FLUSHCACHE
1688 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1689 #endif /* DO_FLUSHCACHE */
1690 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1691 #ifdef DO_FLUSHCACHE
1693 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1694 #endif /* DO_FLUSHCACHE */
1697 /* In code below, we do not preserve args[0], but the rest
1698 is preserved, including args[2] */
1701 if (set_standbynow) {
1702 #ifndef WIN_STANDBYNOW1
1703 #define WIN_STANDBYNOW1 0xE0
1705 #ifndef WIN_STANDBYNOW2
1706 #define WIN_STANDBYNOW2 0x94
1708 printf(" issuing standby command\n");
1709 args[0] = WIN_STANDBYNOW1;
1710 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1713 #ifndef WIN_SLEEPNOW1
1714 #define WIN_SLEEPNOW1 0xE6
1716 #ifndef WIN_SLEEPNOW2
1717 #define WIN_SLEEPNOW2 0x99
1719 printf(" issuing sleep command\n");
1720 args[0] = WIN_SLEEPNOW1;
1721 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1725 printf(" disabling Seagate auto powersaving mode\n");
1726 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1728 if (getset_standby == IS_SET) {
1729 args[0] = WIN_SETIDLE1;
1730 args[1] = standby_requested;
1731 print_flag(1, "standby", standby_requested);
1732 interpret_standby(standby_requested);
1733 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1736 #else /* HDIO_DRIVE_CMD */
1737 if (force_operation) {
1739 flush_buffer_cache();
1740 if (-1 == read(fd, buf, sizeof(buf)))
1741 bb_perror_msg("read of 512 bytes failed");
1743 #endif /* HDIO_DRIVE_CMD */
1744 if (getset_mult || get_identity) {
1746 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1747 /* To be coherent with ioctl_or_warn. */
1748 if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1749 bb_perror_msg("HDIO_GET_MULTCOUNT");
1751 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1752 } else if (getset_mult) {
1753 printf(fmt, "multcount", multcount);
1754 on_off(multcount != 0);
1757 if (getset_io32bit) {
1758 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1759 printf(" IO_support\t=%3ld (", parm);
1761 printf("default 16-bit)\n");
1763 printf("16-bit)\n");
1765 printf("32-bit)\n");
1767 printf("32-bit w/sync)\n");
1769 printf("Request-Queue-Bypass)\n");
1771 printf("\?\?\?)\n");
1774 if (getset_unmask) {
1775 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
1776 print_value_on_off("unmaskirq", parm);
1778 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1780 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1781 printf(fmt, "using_dma", parm);
1783 printf(" (DMA-Assisted-PIO)\n");
1789 #ifdef HDIO_GET_QDMA
1791 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
1792 print_value_on_off("queue_depth", parm);
1796 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
1797 print_value_on_off("keepsettings", parm);
1799 if (getset_nowerr) {
1800 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
1801 print_value_on_off("nowerr", parm);
1803 if (getset_readonly) {
1804 if (!ioctl_or_warn(fd, BLKROGET, &parm))
1805 print_value_on_off("readonly", parm);
1807 if (getset_readahead) {
1808 if (!ioctl_or_warn(fd, BLKRAGET, &parm))
1809 print_value_on_off("readahead", parm);
1812 if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1813 struct hd_geometry g;
1815 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1816 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1817 g.cylinders, g.heads, g.sectors, parm, g.start);
1820 #ifdef HDIO_DRIVE_CMD
1821 if (get_powermode) {
1822 #ifndef WIN_CHECKPOWERMODE1
1823 #define WIN_CHECKPOWERMODE1 0xE5
1825 #ifndef WIN_CHECKPOWERMODE2
1826 #define WIN_CHECKPOWERMODE2 0x98
1830 args[0] = WIN_CHECKPOWERMODE1;
1831 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1832 if (errno != EIO || args[0] != 0 || args[1] != 0)
1837 state = (args[2] == 255) ? "active/idle" : "standby";
1838 args[1] = args[2] = 0;
1840 printf(" drive state is: %s\n", state);
1843 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1844 if (perform_reset) {
1845 ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1847 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1848 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1849 if (perform_tristate) {
1852 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1854 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1855 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1857 struct hd_driveid id;
1859 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1860 if (multcount != -1) {
1861 id.multsect = multcount;
1862 id.multsect_valid |= 1;
1864 id.multsect_valid &= ~1;
1866 } else if (errno == -ENOMSG)
1867 printf(" no identification info available\n");
1868 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1869 bb_perror_msg("HDIO_GET_IDENTITY");
1871 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1875 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1877 memset(args1, 0, sizeof(args1));
1878 args1[0] = WIN_IDENTIFY;
1880 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1881 identify((void *)(args1 + 4));
1884 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1885 if (getset_busstate == IS_SET) {
1886 print_flag(1, "bus state", busstate);
1887 bus_state_value(busstate);
1888 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1890 if (getset_busstate) {
1891 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1892 printf(fmt, "bus state", parm);
1893 bus_state_value(parm);
1898 ioctl_or_warn(fd, BLKRRPART, NULL);
1901 do_time(1 /*,fd*/); /* time cache */
1903 do_time(0 /*,fd*/); /* time device */
1905 flush_buffer_cache();
1909 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1910 static int fromhex(unsigned char c)
1914 if (c >= 'a' && c <= 'f')
1915 return (c - ('a' - 10));
1916 bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1919 static void identify_from_stdin(void) NORETURN;
1920 static void identify_from_stdin(void)
1923 unsigned char buf[1280];
1924 unsigned char *b = (unsigned char *)buf;
1927 xread(STDIN_FILENO, buf, 1280);
1929 // Convert the newline-separated hex data into an identify block.
1931 for (i = 0; i < 256; i++) {
1933 for (j = 0; j < 4; j++)
1934 sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1942 void identify_from_stdin(void);
1945 /* busybox specific stuff */
1946 static int parse_opts(unsigned long *value, int min, int max)
1949 *value = xatol_range(optarg, min, max);
1954 static int parse_opts_0_max(unsigned long *value, int max)
1956 return parse_opts(value, 0, max);
1958 static int parse_opts_0_1(unsigned long *value)
1960 return parse_opts(value, 0, 1);
1962 static int parse_opts_0_INTMAX(unsigned long *value)
1964 return parse_opts(value, 0, INT_MAX);
1967 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
1972 *value = translate_xfermode(optarg);
1973 *set = (*value > -1);
1978 /*------- getopt short options --------*/
1979 static const char hdparm_options[] ALIGN1 =
1980 "gfu::n::p:r::m::c::k::a::B:tT"
1981 IF_FEATURE_HDPARM_GET_IDENTITY("iI")
1982 IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
1983 #ifdef HDIO_DRIVE_CMD
1984 "S:D:P:X:K:A:L:W:CyYzZ"
1986 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
1987 #ifdef HDIO_GET_QDMA
1988 #ifdef HDIO_SET_QDMA
1994 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
1995 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
1996 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
1997 /*-------------------------------------*/
1999 /* our main() routine: */
2000 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2001 int hdparm_main(int argc, char **argv)
2006 while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2008 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2009 IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2010 get_geom |= (c == 'g');
2011 do_flush |= (c == 'f');
2012 if (c == 'u') getset_unmask = parse_opts_0_1(&unmask);
2013 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
2014 if (c == 'd') getset_dma = parse_opts_0_max(&dma, 9);
2016 if (c == 'n') getset_nowerr = parse_opts_0_1(&nowerr);
2017 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2018 if (c == 'r') getset_readonly = parse_opts_0_1(&readonly);
2019 if (c == 'm') getset_mult = parse_opts_0_INTMAX(&mult /*32*/);
2020 if (c == 'c') getset_io32bit = parse_opts_0_INTMAX(&io32bit /*8*/);
2021 if (c == 'k') getset_keep = parse_opts_0_1(&keep);
2022 if (c == 'a') getset_readahead = parse_opts_0_INTMAX(&Xreadahead);
2023 if (c == 'B') getset_apmmode = parse_opts(&apmmode, 1, 255);
2024 do_flush |= do_timings |= (c == 't');
2025 do_flush |= do_ctimings |= (c == 'T');
2026 #ifdef HDIO_DRIVE_CMD
2027 if (c == 'S') getset_standby = parse_opts_0_max(&standby_requested, 255);
2028 if (c == 'D') getset_defects = parse_opts_0_INTMAX(&defects);
2029 if (c == 'P') getset_prefetch = parse_opts_0_INTMAX(&prefetch);
2030 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2031 if (c == 'K') getset_dkeep = parse_opts_0_1(&prefetch);
2032 if (c == 'A') getset_lookahead = parse_opts_0_1(&lookahead);
2033 if (c == 'L') getset_doorlock = parse_opts_0_1(&doorlock);
2034 if (c == 'W') getset_wcache = parse_opts_0_1(&wcache);
2035 get_powermode |= (c == 'C');
2036 set_standbynow |= (c == 'y');
2037 set_sleepnow |= (c == 'Y');
2038 reread_partn |= (c == 'z');
2039 set_seagate |= (c == 'Z');
2041 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') unregister_hwif = parse_opts_0_INTMAX(&hwif));
2042 #ifdef HDIO_GET_QDMA
2044 getset_dma_q = parse_opts_0_INTMAX(&dma_q);
2047 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2048 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') perform_tristate = parse_opts_0_1(&tristate));
2049 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') getset_busstate = parse_opts_0_max(&busstate, 2));
2050 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2052 scan_hwif = parse_opts_0_INTMAX(&hwif_data);
2053 hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
2054 hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
2055 /* Move past the 2 additional arguments */
2061 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2063 getset_mult = getset_io32bit = getset_unmask = getset_keep = getset_readonly = getset_readahead = get_geom = IS_GET;
2064 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(getset_dma = IS_GET);
2069 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2070 identify_from_stdin(); /* EXIT */
2075 process_dev(*argv++);
2078 return EXIT_SUCCESS;