Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/miscutils/hdparm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 984 - (hide annotations) (download)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 70657 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * hdparm implementation for busybox
4     *
5     * Copyright (C) [2003] by [Matteo Croce] <3297627799@wind.it>
6     * Hacked by Tito <farmatito@tiscali.it> for size optimization.
7     *
8     * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
9     *
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
13     */
14 niro 816 #include "libbb.h"
15 niro 984 /* must be _after_ libbb.h: */
16 niro 532 #include <linux/hdreg.h>
17 niro 984 #include <sys/mount.h>
18     #if !defined(BLKGETSIZE64)
19     # define BLKGETSIZE64 _IOR(0x12,114,size_t)
20     #endif
21 niro 532
22     /* device types */
23     /* ------------ */
24     #define NO_DEV 0xffff
25     #define ATA_DEV 0x0000
26     #define ATAPI_DEV 0x0001
27    
28     /* word definitions */
29     /* ---------------- */
30     #define GEN_CONFIG 0 /* general configuration */
31     #define LCYLS 1 /* number of logical cylinders */
32     #define CONFIG 2 /* specific configuration */
33     #define LHEADS 3 /* number of logical heads */
34     #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
35     #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
36     #define LSECTS 6 /* number of logical sectors/track */
37     #define START_SERIAL 10 /* ASCII serial number */
38     #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
39     #define BUF_TYPE 20 /* buffer type (ATA-1) */
40     #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
41     #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
42     #define START_FW_REV 23 /* ASCII firmware revision */
43     #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
44     #define START_MODEL 27 /* ASCII model number */
45     #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
46 niro 816 #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
47 niro 532 #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
48     #define CAPAB_0 49 /* capabilities */
49     #define CAPAB_1 50
50     #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
51     #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
52     #define WHATS_VALID 53 /* what fields are valid */
53     #define LCYLS_CUR 54 /* current logical cylinders */
54     #define LHEADS_CUR 55 /* current logical heads */
55 niro 816 #define LSECTS_CUR 56 /* current logical sectors/track */
56 niro 532 #define CAPACITY_LSB 57 /* current capacity in sectors */
57     #define CAPACITY_MSB 58
58     #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
59     #define LBA_SECTS_LSB 60 /* LBA: total number of user */
60     #define LBA_SECTS_MSB 61 /* addressable sectors */
61     #define SINGLE_DMA 62 /* singleword DMA modes */
62     #define MULTI_DMA 63 /* multiword DMA modes */
63     #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
64     /* multiword DMA xfer cycle time: */
65     #define DMA_TIME_MIN 65 /* - minimum */
66 niro 984 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
67 niro 532 /* minimum PIO xfer cycle time: */
68     #define PIO_NO_FLOW 67 /* - without flow control */
69     #define PIO_FLOW 68 /* - with IORDY flow control */
70     #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
71     #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
72     #define CDR_MAJOR 73 /* CD ROM: major version number */
73     #define CDR_MINOR 74 /* CD ROM: minor version number */
74     #define QUEUE_DEPTH 75 /* queue depth */
75     #define MAJOR 80 /* major version number */
76     #define MINOR 81 /* minor version number */
77     #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
78     #define CMDS_SUPP_1 83
79     #define CMDS_SUPP_2 84
80     #define CMDS_EN_0 85 /* command/feature set(s) enabled */
81     #define CMDS_EN_1 86
82     #define CMDS_EN_2 87
83     #define ULTRA_DMA 88 /* ultra DMA modes */
84     /* time to complete security erase */
85     #define ERASE_TIME 89 /* - ordinary */
86     #define ENH_ERASE_TIME 90 /* - enhanced */
87     #define ADV_PWR 91 /* current advanced power management level
88     in low byte, 0x40 in high byte. */
89 niro 984 #define PSWD_CODE 92 /* master password revision code */
90 niro 532 #define HWRST_RSLT 93 /* hardware reset result */
91     #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
92     #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
93     #define LBA_MID 101 /* bits are used, but addr 103 */
94     #define LBA_48_MSB 102 /* has been reserved for LBA in */
95     #define LBA_64_MSB 103 /* the future. */
96     #define RM_STAT 127 /* removable media status notification feature set support */
97     #define SECU_STATUS 128 /* security status */
98     #define CFA_PWR_MODE 160 /* CFA power mode 1 */
99     #define START_MEDIA 176 /* media serial number */
100     #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
101     #define START_MANUF 196 /* media manufacturer I.D. */
102     #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
103     #define INTEGRITY 255 /* integrity word */
104    
105     /* bit definitions within the words */
106     /* -------------------------------- */
107    
108     /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
109     #define VALID 0xc000
110     #define VALID_VAL 0x4000
111     /* many words are considered invalid if they are either all-0 or all-1 */
112     #define NOVAL_0 0x0000
113     #define NOVAL_1 0xffff
114    
115     /* word 0: gen_config */
116     #define NOT_ATA 0x8000
117     #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
118     #define MEDIA_REMOVABLE 0x0080
119     #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
120     #define INCOMPLETE 0x0004
121     #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
122     #define DRQ_RESPONSE_TIME 0x0060
123     #define DRQ_3MS_VAL 0x0000
124     #define DRQ_INTR_VAL 0x0020
125     #define DRQ_50US_VAL 0x0040
126     #define PKT_SIZE_SUPPORTED 0x0003
127     #define PKT_SIZE_12_VAL 0x0000
128     #define PKT_SIZE_16_VAL 0x0001
129     #define EQPT_TYPE 0x1f00
130     #define SHIFT_EQPT 8
131    
132     #define CDROM 0x0005
133    
134     /* word 1: number of logical cylinders */
135     #define LCYLS_MAX 0x3fff /* maximum allowable value */
136    
137     /* word 2: specific configuration
138     * (a) require SET FEATURES to spin-up
139     * (b) require spin-up to fully reply to IDENTIFY DEVICE
140     */
141     #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
142     #define STBY_ID_VAL 0x738c /* (a) and not (b) */
143     #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
144     #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
145    
146     /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
147     #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
148     #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
149    
150     /* word 49: capabilities 0 */
151 niro 816 #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
152 niro 532 #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
153     #define IORDY_OFF 0x0400 /* 1=may be disabled */
154     #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
155     #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
156     #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
157     #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
158     #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
159     #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
160    
161     /* word 50: capabilities 1 */
162     #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
163    
164     /* words 51 & 52: PIO & DMA cycle times */
165     #define MODE 0xff00 /* the mode is in the MSBs */
166    
167     /* word 53: whats_valid */
168     #define OK_W88 0x0004 /* the ultra_dma info is valid */
169     #define OK_W64_70 0x0002 /* see above for word descriptions */
170     #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
171    
172     /*word 63,88: dma_mode, ultra_dma_mode*/
173     #define MODE_MAX 7 /* bit definitions force udma <=7 (when
174     * udma >=8 comes out it'll have to be
175     * defined in a new dma_mode word!) */
176    
177     /* word 64: PIO transfer modes */
178     #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
179     #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
180    
181     /* word 75: queue_depth */
182     #define DEPTH_BITS 0x001f /* bits used for queue depth */
183    
184     /* words 80-81: version numbers */
185     /* NOVAL_0 or NOVAL_1 means device does not report version */
186    
187     /* word 81: minor version number */
188     #define MINOR_MAX 0x22
189     /* words 82-84: cmds/feats supported */
190     #define CMDS_W82 0x77ff /* word 82: defined command locations*/
191     #define CMDS_W83 0x3fff /* word 83: defined command locations*/
192     #define CMDS_W84 0x002f /* word 83: defined command locations*/
193     #define SUPPORT_48_BIT 0x0400
194     #define NUM_CMD_FEAT_STR 48
195    
196     /* words 85-87: cmds/feats enabled */
197     /* use cmd_feat_str[] to display what commands and features have
198     * been enabled with words 85-87
199     */
200    
201     /* words 89, 90, SECU ERASE TIME */
202 niro 816 #define ERASE_BITS 0x00ff
203 niro 532
204     /* word 92: master password revision */
205     /* NOVAL_0 or NOVAL_1 means no support for master password revision */
206    
207     /* word 93: hw reset result */
208 niro 816 #define CBLID 0x2000 /* CBLID status */
209     #define RST0 0x0001 /* 1=reset to device #0 */
210     #define DEV_DET 0x0006 /* how device num determined */
211     #define JUMPER_VAL 0x0002 /* device num determined by jumper */
212     #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
213 niro 532
214     /* word 127: removable media status notification feature set support */
215 niro 816 #define RM_STAT_BITS 0x0003
216     #define RM_STAT_SUP 0x0001
217 niro 532
218     /* word 128: security */
219 niro 816 #define SECU_ENABLED 0x0002
220     #define SECU_LEVEL 0x0010
221     #define NUM_SECU_STR 6
222 niro 532
223     /* word 160: CFA power mode */
224 niro 816 #define VALID_W160 0x8000 /* 1=word valid */
225     #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
226     #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
227     #define MAX_AMPS 0x0fff /* value = max current in ma */
228 niro 532
229     /* word 255: integrity */
230 niro 816 #define SIG 0x00ff /* signature location */
231     #define SIG_VAL 0x00a5 /* signature value */
232 niro 532
233 niro 816 #define TIMING_BUF_MB 1
234     #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
235 niro 532
236 niro 816 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
237 niro 532
238 niro 816
239 niro 984 #define IS_GET 1
240     #define IS_SET 2
241    
242    
243 niro 816 enum { fd = 3 };
244    
245    
246     struct globals {
247     smallint get_identity, get_geom;
248     smallint do_flush;
249     smallint do_ctimings, do_timings;
250     smallint reread_partn;
251     smallint set_piomode, noisy_piomode;
252 niro 984 smallint getset_readahead;
253     smallint getset_readonly;
254     smallint getset_unmask;
255     smallint getset_mult;
256 niro 816 #ifdef HDIO_GET_QDMA
257 niro 984 smallint getset_dma_q;
258 niro 816 #endif
259 niro 984 smallint getset_nowerr;
260     smallint getset_keep;
261     smallint getset_io32bit;
262 niro 816 int piomode;
263     unsigned long Xreadahead;
264     unsigned long readonly;
265     unsigned long unmask;
266     unsigned long mult;
267     #ifdef HDIO_SET_QDMA
268     unsigned long dma_q;
269     #endif
270     unsigned long nowerr;
271     unsigned long keep;
272     unsigned long io32bit;
273     #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
274     unsigned long dma;
275 niro 984 smallint getset_dma;
276 niro 816 #endif
277     #ifdef HDIO_DRIVE_CMD
278     smallint set_xfermode, get_xfermode;
279 niro 984 smallint getset_dkeep;
280     smallint getset_standby;
281     smallint getset_lookahead;
282     smallint getset_prefetch;
283     smallint getset_defects;
284     smallint getset_wcache;
285     smallint getset_doorlock;
286     smallint set_seagate;
287     smallint set_standbynow;
288     smallint set_sleepnow;
289 niro 816 smallint get_powermode;
290 niro 984 smallint getset_apmmode;
291 niro 816 int xfermode_requested;
292     unsigned long dkeep;
293     unsigned long standby_requested; /* 0..255 */
294     unsigned long lookahead;
295     unsigned long prefetch;
296     unsigned long defects;
297     unsigned long wcache;
298     unsigned long doorlock;
299     unsigned long apmmode;
300     #endif
301 niro 984 IF_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
302     IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint getset_busstate;)
303     IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
304     IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
305     IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
306     IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
307     IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
308     IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
309     IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
310 niro 816 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
311     unsigned long hwif_data;
312     unsigned long hwif_ctrl;
313     unsigned long hwif_irq;
314     #endif
315     #ifdef DO_FLUSHCACHE
316     unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
317     #endif
318     };
319     #define G (*(struct globals*)&bb_common_bufsiz1)
320     struct BUG_G_too_big {
321     char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
322     };
323     #define get_identity (G.get_identity )
324     #define get_geom (G.get_geom )
325     #define do_flush (G.do_flush )
326     #define do_ctimings (G.do_ctimings )
327     #define do_timings (G.do_timings )
328     #define reread_partn (G.reread_partn )
329     #define set_piomode (G.set_piomode )
330     #define noisy_piomode (G.noisy_piomode )
331 niro 984 #define getset_readahead (G.getset_readahead )
332     #define getset_readonly (G.getset_readonly )
333     #define getset_unmask (G.getset_unmask )
334     #define getset_mult (G.getset_mult )
335     #define getset_dma_q (G.getset_dma_q )
336     #define getset_nowerr (G.getset_nowerr )
337     #define getset_keep (G.getset_keep )
338     #define getset_io32bit (G.getset_io32bit )
339 niro 816 #define piomode (G.piomode )
340     #define Xreadahead (G.Xreadahead )
341     #define readonly (G.readonly )
342     #define unmask (G.unmask )
343     #define mult (G.mult )
344     #define dma_q (G.dma_q )
345     #define nowerr (G.nowerr )
346     #define keep (G.keep )
347     #define io32bit (G.io32bit )
348     #define dma (G.dma )
349 niro 984 #define getset_dma (G.getset_dma )
350 niro 816 #define set_xfermode (G.set_xfermode )
351     #define get_xfermode (G.get_xfermode )
352 niro 984 #define getset_dkeep (G.getset_dkeep )
353     #define getset_standby (G.getset_standby )
354     #define getset_lookahead (G.getset_lookahead )
355     #define getset_prefetch (G.getset_prefetch )
356     #define getset_defects (G.getset_defects )
357     #define getset_wcache (G.getset_wcache )
358     #define getset_doorlock (G.getset_doorlock )
359 niro 816 #define set_seagate (G.set_seagate )
360     #define set_standbynow (G.set_standbynow )
361     #define set_sleepnow (G.set_sleepnow )
362     #define get_powermode (G.get_powermode )
363 niro 984 #define getset_apmmode (G.getset_apmmode )
364 niro 816 #define xfermode_requested (G.xfermode_requested )
365     #define dkeep (G.dkeep )
366     #define standby_requested (G.standby_requested )
367     #define lookahead (G.lookahead )
368     #define prefetch (G.prefetch )
369     #define defects (G.defects )
370     #define wcache (G.wcache )
371     #define doorlock (G.doorlock )
372     #define apmmode (G.apmmode )
373     #define get_IDentity (G.get_IDentity )
374 niro 984 #define getset_busstate (G.getset_busstate )
375 niro 816 #define perform_reset (G.perform_reset )
376     #define perform_tristate (G.perform_tristate )
377     #define unregister_hwif (G.unregister_hwif )
378     #define scan_hwif (G.scan_hwif )
379     #define busstate (G.busstate )
380     #define tristate (G.tristate )
381     #define hwif (G.hwif )
382     #define hwif_data (G.hwif_data )
383     #define hwif_ctrl (G.hwif_ctrl )
384     #define hwif_irq (G.hwif_irq )
385    
386    
387 niro 532 /* Busybox messages and functions */
388 niro 816 #if ENABLE_IOCTL_HEX2STR_ERROR
389     static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
390 niro 532 {
391 niro 816 if (!ioctl(fd, cmd, args))
392     return 0;
393     args[0] = alt;
394     return bb_ioctl_or_warn(fd, cmd, args, string);
395 niro 532 }
396 niro 816 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
397     #else
398     static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
399 niro 532 {
400     if (!ioctl(fd, cmd, args))
401     return 0;
402     args[0] = alt;
403 niro 816 return bb_ioctl_or_warn(fd, cmd, args);
404 niro 532 }
405 niro 816 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
406     #endif
407 niro 532
408 niro 816 static void on_off(int value)
409     {
410     puts(value ? " (on)" : " (off)");
411     }
412 niro 532
413 niro 816 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
414 niro 532 {
415 niro 816 if (get_arg) {
416 niro 532 printf(" setting %s to %ld", s, arg);
417     on_off(arg);
418     }
419     }
420    
421 niro 816 static void print_value_on_off(const char *str, unsigned long argp)
422 niro 532 {
423 niro 816 printf(" %s\t= %2ld", str, argp);
424     on_off(argp != 0);
425     }
426    
427     #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
428     static void print_ascii(const char *p, int length)
429     {
430     #if BB_BIG_ENDIAN
431     #define LE_ONLY(x)
432     enum { ofs = 0 };
433     #else
434     #define LE_ONLY(x) x
435     /* every 16bit word is big-endian (i.e. inverted) */
436     /* accessing bytes in 1,0, 3,2, 5,4... sequence */
437     int ofs = 1;
438     #endif
439    
440     length *= 2;
441     /* find first non-space & print it */
442     while (length && p[ofs] != ' ') {
443     p++;
444     LE_ONLY(ofs = -ofs;)
445     length--;
446 niro 532 }
447 niro 816 while (length && p[ofs]) {
448     bb_putchar(p[ofs]);
449     p++;
450     LE_ONLY(ofs = -ofs;)
451     length--;
452     }
453     bb_putchar('\n');
454     #undef LE_ONLY
455 niro 532 }
456    
457 niro 816 static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
458 niro 532 {
459 niro 816 if (val[i]) {
460     printf("\t%-20s", string);
461     print_ascii((void*)&val[i], n);
462 niro 532 }
463     }
464    
465     static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
466     {
467     uint16_t ii;
468     uint8_t err_dma = 0;
469    
470 niro 816 for (ii = 0; ii <= MODE_MAX; ii++) {
471     if (mode_sel & 0x0001) {
472     printf("*%cdma%u ", cc, ii);
473 niro 532 if (*have_mode)
474     err_dma = 1;
475     *have_mode = 1;
476 niro 816 } else if (mode_sup & 0x0001)
477     printf("%cdma%u ", cc, ii);
478 niro 532
479 niro 816 mode_sup >>= 1;
480     mode_sel >>= 1;
481 niro 532 }
482     return err_dma;
483     }
484    
485 niro 816 static const char pkt_str[] ALIGN1 =
486     "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
487     "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
488     "Printer" "\0" /* word 0, bits 12-8 = 02 */
489     "Processor" "\0" /* word 0, bits 12-8 = 03 */
490     "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
491     "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
492     "Scanner" "\0" /* word 0, bits 12-8 = 06 */
493     "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
494     "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
495     "Communications device" "\0" /* word 0, bits 12-8 = 09 */
496     "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
497     "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
498     "Array controller" "\0" /* word 0, bits 12-8 = 0c */
499     "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
500     "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
501     "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
502     ;
503 niro 532
504 niro 816 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
505     "reserved" "\0" /* bit 0 */
506     "hard sectored" "\0" /* bit 1 */
507     "soft sectored" "\0" /* bit 2 */
508     "not MFM encoded " "\0" /* bit 3 */
509     "head switch time > 15us" "\0" /* bit 4 */
510     "spindle motor control option" "\0" /* bit 5 */
511     "fixed drive" "\0" /* bit 6 */
512     "removable drive" "\0" /* bit 7 */
513     "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
514     "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
515     "disk xfer rate > 5Mbs" "\0" /* bit 10 */
516     "rotational speed tol." "\0" /* bit 11 */
517     "data strobe offset option" "\0" /* bit 12 */
518     "track offset option" "\0" /* bit 13 */
519     "format speed tolerance gap reqd" "\0" /* bit 14 */
520     "ATAPI" /* bit 14 */
521     ;
522 niro 532
523 niro 816 static const char minor_str[] ALIGN1 =
524     /* word 81 value: */
525     "Unspecified" "\0" /* 0x0000 */
526     "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
527     "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
528     "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
529     "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
530     "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
531     "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
532     "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
533     "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
534     "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
535     "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
536     "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
537     "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
538     "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
539     "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
540     "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
541     "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
542     "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
543     "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
544     "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
545     "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
546     "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
547     "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
548     "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
549     "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
550     "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
551     "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
552     "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
553     "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
554     "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
555     "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
556     "reserved" "\0" /* 0x001f */
557     "reserved" "\0" /* 0x0020 */
558     "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
559     "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
560     "reserved" /* 0x0023-0xfffe */
561     ;
562     static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
563     /* word 81 value: */
564     0, /* 0x0000 WARNING: actual_ver[] array */
565     1, /* 0x0001 WARNING: corresponds */
566     1, /* 0x0002 WARNING: *exactly* */
567     1, /* 0x0003 WARNING: to the ATA/ */
568     2, /* 0x0004 WARNING: ATAPI version */
569     2, /* 0x0005 WARNING: listed in */
570     3, /* 0x0006 WARNING: the */
571     2, /* 0x0007 WARNING: minor_str */
572     3, /* 0x0008 WARNING: array */
573     2, /* 0x0009 WARNING: above. */
574     3, /* 0x000a WARNING: */
575     3, /* 0x000b WARNING: If you change */
576     3, /* 0x000c WARNING: that one, */
577     4, /* 0x000d WARNING: change this one */
578     4, /* 0x000e WARNING: too!!! */
579     4, /* 0x000f */
580     4, /* 0x0010 */
581     4, /* 0x0011 */
582     4, /* 0x0012 */
583     5, /* 0x0013 */
584     4, /* 0x0014 */
585     5, /* 0x0015 */
586     5, /* 0x0016 */
587     4, /* 0x0017 */
588     6, /* 0x0018 */
589     6, /* 0x0019 */
590     7, /* 0x001a */
591     6, /* 0x001b */
592     6, /* 0x001c */
593     7, /* 0x001d */
594     7, /* 0x001e */
595     0, /* 0x001f */
596     0, /* 0x0020 */
597     7, /* 0x0021 */
598     6, /* 0x0022 */
599     0 /* 0x0023-0xfffe */
600     };
601    
602     static const char cmd_feat_str[] ALIGN1 =
603     "" "\0" /* word 82 bit 15: obsolete */
604     "NOP cmd" "\0" /* word 82 bit 14 */
605     "READ BUFFER cmd" "\0" /* word 82 bit 13 */
606     "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
607     "" "\0" /* word 82 bit 11: obsolete */
608     "Host Protected Area feature set" "\0" /* word 82 bit 10 */
609     "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
610     "SERVICE interrupt" "\0" /* word 82 bit 8 */
611     "Release interrupt" "\0" /* word 82 bit 7 */
612     "Look-ahead" "\0" /* word 82 bit 6 */
613     "Write cache" "\0" /* word 82 bit 5 */
614     "PACKET command feature set" "\0" /* word 82 bit 4 */
615     "Power Management feature set" "\0" /* word 82 bit 3 */
616     "Removable Media feature set" "\0" /* word 82 bit 2 */
617     "Security Mode feature set" "\0" /* word 82 bit 1 */
618     "SMART feature set" "\0" /* word 82 bit 0 */
619     /* -------------- */
620     "" "\0" /* word 83 bit 15: !valid bit */
621     "" "\0" /* word 83 bit 14: valid bit */
622     "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
623     "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
624     "Device Configuration Overlay feature set " "\0"
625     "48-bit Address feature set " "\0" /* word 83 bit 10 */
626     "" "\0"
627     "SET MAX security extension" "\0" /* word 83 bit 8 */
628     "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
629     "SET FEATURES subcommand required to spinup after power up" "\0"
630     "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
631     "Removable Media Status Notification feature set" "\0"
632     "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
633     "CFA feature set" "\0" /* word 83 bit 2 */
634     "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
635     "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
636     /* -------------- */
637     "" "\0" /* word 84 bit 15: !valid bit */
638     "" "\0" /* word 84 bit 14: valid bit */
639     "" "\0" /* word 84 bit 13: reserved */
640     "" "\0" /* word 84 bit 12: reserved */
641     "" "\0" /* word 84 bit 11: reserved */
642     "" "\0" /* word 84 bit 10: reserved */
643     "" "\0" /* word 84 bit 9: reserved */
644     "" "\0" /* word 84 bit 8: reserved */
645     "" "\0" /* word 84 bit 7: reserved */
646     "" "\0" /* word 84 bit 6: reserved */
647     "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
648     "" "\0" /* word 84 bit 4: reserved */
649     "Media Card Pass Through Command feature set " "\0"
650     "Media serial number " "\0" /* word 84 bit 2 */
651     "SMART self-test " "\0" /* word 84 bit 1 */
652     "SMART error logging " /* word 84 bit 0 */
653     ;
654    
655     static const char secu_str[] ALIGN1 =
656     "supported" "\0" /* word 128, bit 0 */
657     "enabled" "\0" /* word 128, bit 1 */
658     "locked" "\0" /* word 128, bit 2 */
659     "frozen" "\0" /* word 128, bit 3 */
660     "expired: security count" "\0" /* word 128, bit 4 */
661     "supported: enhanced erase" /* word 128, bit 5 */
662     ;
663    
664 niro 532 // Parse 512 byte disk identification block and print much crap.
665 niro 816 static void identify(uint16_t *val) NORETURN;
666     static void identify(uint16_t *val)
667 niro 532 {
668 niro 816 uint16_t ii, jj, kk;
669 niro 532 uint16_t like_std = 1, std = 0, min_std = 0xffff;
670     uint16_t dev = NO_DEV, eqpt = NO_DEV;
671     uint8_t have_mode = 0, err_dma = 0;
672     uint8_t chksum = 0;
673     uint32_t ll, mm, nn, oo;
674     uint64_t bbbig; /* (:) */
675     const char *strng;
676 niro 816 #if BB_BIG_ENDIAN
677     uint16_t buf[256];
678 niro 532
679 niro 816 // Adjust for endianness
680     swab(val, buf, sizeof(buf));
681     val = buf;
682     #endif
683 niro 984 /* check if we recognize the device type */
684 niro 816 bb_putchar('\n');
685     if (!(val[GEN_CONFIG] & NOT_ATA)) {
686 niro 532 dev = ATA_DEV;
687     printf("ATA device, with ");
688 niro 816 } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
689 niro 532 dev = ATA_DEV;
690     like_std = 4;
691     printf("CompactFlash ATA device, with ");
692 niro 816 } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
693 niro 532 dev = ATAPI_DEV;
694     eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
695 niro 816 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
696 niro 532 like_std = 3;
697 niro 816 } else
698     /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
699 niro 532 bb_error_msg_and_die("unknown device type");
700    
701     printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
702     /* Info from the specific configuration word says whether or not the
703     * ID command completed correctly. It is only defined, however in
704     * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
705     * standards. Since the values allowed for this word are extremely
706     * specific, it should be safe to check it now, even though we don't
707     * know yet what standard this device is using.
708     */
709 niro 816 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
710     || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
711     ) {
712 niro 532 like_std = 5;
713     if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
714     printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
715     if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
716     printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
717     }
718    
719     /* output the model and serial numbers and the fw revision */
720     xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
721     xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
722     xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
723     xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
724     xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
725    
726     /* major & minor standards version number (Note: these words were not
727     * defined until ATA-3 & the CDROM std uses different words.) */
728     printf("Standards:");
729 niro 816 if (eqpt != CDROM) {
730     if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
731 niro 532 if (like_std < 3) like_std = 3;
732     std = actual_ver[val[MINOR]];
733 niro 816 if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
734 niro 532
735     }
736     /* looks like when they up-issue the std, they obsolete one;
737     * thus, only the newest 4 issues need be supported. (That's
738     * what "kk" and "min_std" are all about.) */
739 niro 816 if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
740 niro 532 printf("\n\tSupported: ");
741     jj = val[MAJOR] << 1;
742     kk = like_std >4 ? like_std-4: 0;
743 niro 816 for (ii = 14; (ii >0)&&(ii>kk); ii--) {
744     if (jj & 0x8000) {
745 niro 532 printf("%u ", ii);
746 niro 816 if (like_std < ii) {
747 niro 532 like_std = ii;
748     kk = like_std >4 ? like_std-4: 0;
749     }
750     if (min_std > ii) min_std = ii;
751     }
752     jj <<= 1;
753     }
754     if (like_std < 3) like_std = 3;
755     }
756     /* Figure out what standard the device is using if it hasn't told
757     * us. If we know the std, check if the device is using any of
758     * the words from the next level up. It happens.
759     */
760     if (like_std < std) like_std = std;
761    
762     if (((std == 5) || (!std && (like_std < 6))) &&
763     ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
764     (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
765     ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
766 niro 816 ( val[CMDS_SUPP_2] & CMDS_W84) ) )
767     ) {
768 niro 532 like_std = 6;
769 niro 816 } else if (((std == 4) || (!std && (like_std < 5))) &&
770 niro 532 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
771     (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
772     ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
773     (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
774     {
775     like_std = 5;
776 niro 816 } else if (((std == 3) || (!std && (like_std < 4))) &&
777 niro 532 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
778     ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
779     (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
780     (( val[CAPAB_1] & VALID) == VALID_VAL) ||
781     (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
782 niro 816 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
783     ) {
784 niro 532 like_std = 4;
785 niro 816 } else if (((std == 2) || (!std && (like_std < 3)))
786     && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
787     ) {
788 niro 532 like_std = 3;
789 niro 816 } else if (((std == 1) || (!std && (like_std < 2))) &&
790 niro 532 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
791     (val[WHATS_VALID] & OK_W64_70)) )
792     {
793     like_std = 2;
794     }
795 niro 816
796 niro 532 if (!std)
797 niro 816 printf("\n\tLikely used: %u\n", like_std);
798 niro 532 else if (like_std > std)
799 niro 816 printf("& some of %u\n", like_std);
800 niro 532 else
801 niro 816 bb_putchar('\n');
802     } else {
803 niro 532 /* TBD: do CDROM stuff more thoroughly. For now... */
804     kk = 0;
805 niro 816 if (val[CDR_MINOR] == 9) {
806 niro 532 kk = 1;
807     printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
808     }
809 niro 816 if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
810 niro 532 kk = 1;
811     printf("\n\tSupported: CD-ROM ATAPI");
812     jj = val[CDR_MAJOR] >> 1;
813 niro 816 for (ii = 1; ii < 15; ii++) {
814 niro 532 if (jj & 0x0001) printf("-%u ", ii);
815     jj >>= 1;
816     }
817     }
818 niro 816 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
819 niro 532 /* the cdrom stuff is more like ATA-2 than anything else, so: */
820     like_std = 2;
821     }
822    
823     if (min_std == 0xffff)
824     min_std = like_std > 4 ? like_std - 3 : 1;
825    
826     printf("Configuration:\n");
827     /* more info from the general configuration word */
828 niro 816 if ((eqpt != CDROM) && (like_std == 1)) {
829 niro 532 jj = val[GEN_CONFIG] >> 1;
830 niro 816 for (ii = 1; ii < 15; ii++) {
831     if (jj & 0x0001)
832     printf("\t%s\n", nth_string(ata1_cfg_str, ii));
833 niro 532 jj >>=1;
834     }
835     }
836 niro 816 if (dev == ATAPI_DEV) {
837 niro 532 if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
838     strng = "3ms";
839     else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
840     strng = "<=10ms with INTRQ";
841     else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
842     strng ="50us";
843     else
844 niro 816 strng = "unknown";
845 niro 532 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
846    
847     if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
848     strng = "12 bytes";
849     else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
850     strng = "16 bytes";
851     else
852 niro 816 strng = "unknown";
853 niro 532 puts(strng);
854 niro 816 } else {
855 niro 532 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
856     ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
857 niro 984 mm = 0;
858     bbbig = 0;
859 niro 816 if ((ll > 0x00FBFC10) && (!val[LCYLS]))
860 niro 532 printf("\tCHS addressing not supported\n");
861 niro 816 else {
862 niro 532 jj = val[WHATS_VALID] & OK_W54_58;
863 niro 984 printf("\tLogical\t\tmax\tcurrent\n"
864     "\tcylinders\t%u\t%u\n"
865     "\theads\t\t%u\t%u\n"
866     "\tsectors/track\t%u\t%u\n"
867     "\t--\n",
868     val[LCYLS],
869     jj ? val[LCYLS_CUR] : 0,
870     val[LHEADS],
871     jj ? val[LHEADS_CUR] : 0,
872     val[LSECTS],
873     jj ? val[LSECTS_CUR] : 0);
874 niro 532
875     if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
876 niro 984 printf("\tbytes/track: %u\tbytes/sector: %u\n",
877     val[TRACK_BYTES], val[SECT_BYTES]);
878 niro 532
879 niro 816 if (jj) {
880 niro 532 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
881 niro 816 if (like_std < 3) {
882     /* check Endian of capacity bytes */
883 niro 532 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
884     oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
885     if (abs(mm - nn) > abs(oo - nn))
886     mm = oo;
887     }
888 niro 816 printf("\tCHS current addressable sectors:%11u\n", mm);
889 niro 532 }
890     }
891     /* LBA addressing */
892 niro 816 printf("\tLBA user addressable sectors:%11u\n", ll);
893     if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
894     && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
895     ) {
896     bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
897     (uint64_t)val[LBA_48_MSB] << 32 |
898     (uint64_t)val[LBA_MID] << 16 |
899     val[LBA_LSB];
900     printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
901 niro 532 }
902    
903     if (!bbbig)
904     bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
905 niro 816 printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
906     bbbig = (bbbig << 9) / 1000000;
907     printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
908 niro 532
909     if (bbbig > 1000)
910     printf("(%"PRIu64" GB)\n", bbbig/1000);
911     else
912 niro 816 bb_putchar('\n');
913 niro 532 }
914    
915     /* hw support of commands (capabilities) */
916     printf("Capabilities:\n\t");
917    
918 niro 816 if (dev == ATAPI_DEV) {
919 niro 984 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP))
920     printf("Cmd queuing, ");
921     if (val[CAPAB_0] & OVLP_SUP)
922     printf("Cmd overlap, ");
923 niro 532 }
924     if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
925    
926 niro 816 if (like_std != 1) {
927 niro 532 printf("IORDY%s(can%s be disabled)\n",
928 niro 984 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
929     (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
930 niro 816 } else
931 niro 532 printf("no IORDY\n");
932    
933 niro 816 if ((like_std == 1) && val[BUF_TYPE]) {
934 niro 532 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
935 niro 984 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
936     (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
937 niro 532 }
938    
939 niro 816 if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
940     printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
941 niro 532 }
942 niro 816 if ((min_std < 4) && (val[RW_LONG])) {
943     printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
944 niro 532 }
945 niro 816 if ((eqpt != CDROM) && (like_std > 3)) {
946     printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
947 niro 532 }
948    
949 niro 816 if (dev == ATA_DEV) {
950 niro 532 if (like_std == 1)
951 niro 816 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
952     else {
953 niro 984 printf("\tStandby timer values: spec'd by %s",
954     (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor");
955 niro 532 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
956 niro 984 printf(", %s device specific minimum\n",
957     (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
958 niro 532 else
959 niro 816 bb_putchar('\n');
960 niro 532 }
961     printf("\tR/W multiple sector transfer: ");
962     if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
963     printf("not supported\n");
964 niro 816 else {
965     printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
966 niro 532 if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
967     printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
968     else
969     printf("?\n");
970     }
971 niro 816 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
972 niro 532 /* We print out elsewhere whether the APM feature is enabled or
973     not. If it's not enabled, let's not repeat the info; just print
974     nothing here. */
975     printf("\tAdvancedPM level: ");
976 niro 816 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
977 niro 532 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
978     printf("%u (0x%x)\n", apm_level, apm_level);
979     }
980     else
981     printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
982     }
983     if (like_std > 5 && val[ACOUSTIC]) {
984     printf("\tRecommended acoustic management value: %u, current value: %u\n",
985 niro 984 (val[ACOUSTIC] >> 8) & 0x00ff,
986     val[ACOUSTIC] & 0x00ff);
987 niro 532 }
988 niro 816 } else {
989 niro 532 /* ATAPI */
990     if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
991     printf("\tATA sw reset required\n");
992    
993 niro 816 if (val[PKT_REL] || val[SVC_NBSY]) {
994 niro 532 printf("\tOverlap support:");
995 niro 984 if (val[PKT_REL])
996     printf(" %uus to release bus.", val[PKT_REL]);
997     if (val[SVC_NBSY])
998     printf(" %uus to clear BSY after SERVICE cmd.",
999     val[SVC_NBSY]);
1000 niro 816 bb_putchar('\n');
1001 niro 532 }
1002     }
1003    
1004     /* DMA stuff. Check that only one DMA mode is selected. */
1005     printf("\tDMA: ");
1006     if (!(val[CAPAB_0] & DMA_SUP))
1007     printf("not supported\n");
1008 niro 816 else {
1009 niro 532 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
1010 niro 816 printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
1011     if (val[SINGLE_DMA]) {
1012 niro 532 jj = val[SINGLE_DMA];
1013     kk = val[SINGLE_DMA] >> 8;
1014 niro 816 err_dma += mode_loop(jj, kk, 's', &have_mode);
1015 niro 532 }
1016 niro 816 if (val[MULTI_DMA]) {
1017 niro 532 jj = val[MULTI_DMA];
1018     kk = val[MULTI_DMA] >> 8;
1019 niro 816 err_dma += mode_loop(jj, kk, 'm', &have_mode);
1020 niro 532 }
1021 niro 816 if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
1022 niro 532 jj = val[ULTRA_DMA];
1023     kk = val[ULTRA_DMA] >> 8;
1024 niro 816 err_dma += mode_loop(jj, kk, 'u', &have_mode);
1025 niro 532 }
1026     if (err_dma || !have_mode) printf("(?)");
1027 niro 816 bb_putchar('\n');
1028 niro 532
1029     if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
1030     printf("\t\tInterleaved DMA support\n");
1031    
1032 niro 816 if ((val[WHATS_VALID] & OK_W64_70)
1033     && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
1034     ) {
1035 niro 532 printf("\t\tCycle time:");
1036 niro 816 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
1037     if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
1038     bb_putchar('\n');
1039 niro 532 }
1040     }
1041    
1042     /* Programmed IO stuff */
1043     printf("\tPIO: ");
1044     /* If a drive supports mode n (e.g. 3), it also supports all modes less
1045     * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
1046 niro 816 if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
1047 niro 532 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
1048 niro 816 for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
1049     if (jj & 0x0001) printf("pio%d ", ii);
1050 niro 532 jj >>=1;
1051     }
1052 niro 816 bb_putchar('\n');
1053     } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
1054 niro 532 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
1055 niro 816 printf("pio%d ", ii);
1056     bb_putchar('\n');
1057     } else
1058     puts("unknown");
1059 niro 532
1060 niro 816 if (val[WHATS_VALID] & OK_W64_70) {
1061     if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
1062 niro 532 printf("\t\tCycle time:");
1063 niro 984 if (val[PIO_NO_FLOW])
1064     printf(" no flow control=%uns", val[PIO_NO_FLOW]);
1065     if (val[PIO_FLOW])
1066     printf(" IORDY flow control=%uns", val[PIO_FLOW]);
1067 niro 816 bb_putchar('\n');
1068 niro 532 }
1069     }
1070    
1071 niro 816 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
1072 niro 984 printf("Commands/features:\n"
1073     "\tEnabled\tSupported:\n");
1074 niro 532 jj = val[CMDS_SUPP_0];
1075     kk = val[CMDS_EN_0];
1076 niro 816 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
1077     const char *feat_str = nth_string(cmd_feat_str, ii);
1078     if ((jj & 0x8000) && (*feat_str != '\0')) {
1079     printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
1080 niro 532 }
1081 niro 816 jj <<= 1;
1082     kk <<= 1;
1083     if (ii % 16 == 15) {
1084 niro 532 jj = val[CMDS_SUPP_0+1+(ii/16)];
1085     kk = val[CMDS_EN_0+1+(ii/16)];
1086     }
1087 niro 816 if (ii == 31) {
1088 niro 532 if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1089     ii +=16;
1090     }
1091     }
1092     }
1093     /* Removable Media Status Notification feature set */
1094     if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
1095 niro 816 printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
1096 niro 532
1097     /* security */
1098 niro 816 if ((eqpt != CDROM) && (like_std > 3)
1099     && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
1100     ) {
1101 niro 532 printf("Security:\n");
1102     if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
1103 niro 816 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
1104 niro 532 jj = val[SECU_STATUS];
1105 niro 816 if (jj) {
1106     for (ii = 0; ii < NUM_SECU_STR; ii++) {
1107 niro 984 printf("\t%s\t%s\n",
1108     (!(jj & 0x0001)) ? "not" : "",
1109     nth_string(secu_str, ii));
1110 niro 532 jj >>=1;
1111     }
1112 niro 816 if (val[SECU_STATUS] & SECU_ENABLED) {
1113 niro 984 printf("\tSecurity level %s\n",
1114     (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
1115 niro 532 }
1116     }
1117     jj = val[ERASE_TIME] & ERASE_BITS;
1118     kk = val[ENH_ERASE_TIME] & ERASE_BITS;
1119 niro 816 if (jj || kk) {
1120     bb_putchar('\t');
1121 niro 532 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
1122     if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
1123 niro 816 bb_putchar('\n');
1124 niro 532 }
1125     }
1126    
1127     /* reset result */
1128     jj = val[HWRST_RSLT];
1129 niro 816 if ((jj & VALID) == VALID_VAL) {
1130     oo = (jj & RST0);
1131     if (!oo)
1132 niro 532 jj >>= 8;
1133     if ((jj & DEV_DET) == JUMPER_VAL)
1134     strng = " determined by the jumper";
1135     else if ((jj & DEV_DET) == CSEL_VAL)
1136     strng = " determined by CSEL";
1137     else
1138     strng = "";
1139 niro 984 printf("HW reset results:\n"
1140     "\tCBLID- %s Vih\n"
1141     "\tDevice num = %i%s\n",
1142     (val[HWRST_RSLT] & CBLID) ? "above" : "below",
1143     !(oo), strng);
1144 niro 532 }
1145    
1146     /* more stuff from std 5 */
1147 niro 816 if ((like_std > 4) && (eqpt != CDROM)) {
1148     if (val[CFA_PWR_MODE] & VALID_W160) {
1149 niro 984 printf("CFA power mode 1:\n"
1150     "\t%s%s\n",
1151     (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
1152     (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
1153 niro 816 if (val[CFA_PWR_MODE] & MAX_AMPS)
1154     printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
1155 niro 532 }
1156 niro 816 if ((val[INTEGRITY] & SIG) == SIG_VAL) {
1157 niro 532 printf("Checksum: %scorrect\n", chksum ? "in" : "");
1158     }
1159     }
1160    
1161     exit(EXIT_SUCCESS);
1162     }
1163     #endif
1164    
1165     // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
1166     // then the HDIO_GET_IDENTITY only returned 142 bytes.
1167     // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
1168     // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
1169     // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
1170     // (which they should, but they should just return -EINVAL).
1171     //
1172     // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
1173     // On a really old system, it will not, and we will be confused.
1174     // Too bad, really.
1175    
1176 niro 816 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1177     static const char cfg_str[] ALIGN1 =
1178     """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
1179     "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
1180     "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
1181     "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
1182     ;
1183 niro 532
1184 niro 816 static const char BuffType[] ALIGN1 =
1185     "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
1186     ;
1187 niro 532
1188 niro 984 static NOINLINE void dump_identity(const struct hd_driveid *id)
1189 niro 532 {
1190     int i;
1191 niro 816 const unsigned short *id_regs = (const void*) id;
1192 niro 532
1193     printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1194     id->model, id->fw_rev, id->serial_no);
1195 niro 816 for (i = 0; i <= 15; i++) {
1196 niro 532 if (id->config & (1<<i))
1197 niro 816 printf(" %s", nth_string(cfg_str, i));
1198 niro 532 }
1199 niro 816 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
1200 niro 984 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
1201     id->cyls, id->heads, id->sectors, id->track_bytes,
1202     id->sector_bytes, id->ecc_bytes,
1203     id->buf_type,
1204     nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
1205     id->buf_size/2, id->max_multsect);
1206 niro 816 if (id->max_multsect) {
1207 niro 532 printf(", MultSect=");
1208 niro 816 if (!(id->multsect_valid & 1))
1209 niro 532 printf("?%u?", id->multsect);
1210     else if (id->multsect)
1211     printf("%u", id->multsect);
1212     else
1213     printf("off");
1214     }
1215 niro 816 bb_putchar('\n');
1216 niro 532
1217 niro 816 if (!(id->field_valid & 1))
1218 niro 532 printf(" (maybe):");
1219    
1220 niro 816 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
1221     id->cur_sectors,
1222     (BB_BIG_ENDIAN) ?
1223     (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
1224     (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
1225     ((id->capability&2) == 0) ? "no" : "yes");
1226 niro 532
1227 niro 816 if (id->capability & 2)
1228 niro 532 printf(", LBAsects=%u", id->lba_capacity);
1229    
1230 niro 984 printf("\n IORDY=%s",
1231     (id->capability & 8)
1232     ? ((id->capability & 4) ? "on/off" : "yes")
1233     : "no");
1234 niro 532
1235 niro 816 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
1236 niro 532 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1237    
1238 niro 816 if ((id->capability & 1) && (id->field_valid & 2))
1239 niro 532 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1240    
1241     printf("\n PIO modes: ");
1242 niro 816 if (id->tPIO <= 5) {
1243 niro 532 printf("pio0 ");
1244     if (id->tPIO >= 1) printf("pio1 ");
1245     if (id->tPIO >= 2) printf("pio2 ");
1246     }
1247 niro 816 if (id->field_valid & 2) {
1248     static const masks_labels_t pio_modes = {
1249     .masks = { 1, 2, ~3 },
1250     .labels = "pio3 \0""pio4 \0""pio? \0",
1251     };
1252     print_flags(&pio_modes, id->eide_pio_modes);
1253 niro 532 }
1254 niro 816 if (id->capability & 1) {
1255     if (id->dma_1word | id->dma_mword) {
1256     static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
1257 niro 532 printf("\n DMA modes: ");
1258 niro 816 print_flags_separated(dma_wmode_masks,
1259     "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
1260     id->dma_1word, NULL);
1261     print_flags_separated(dma_wmode_masks,
1262 niro 984 "*\0""mdma0 \0""*\0""mdma1 \0""*\0""mdma2 \0""*\0""mdma? \0",
1263 niro 816 id->dma_mword, NULL);
1264 niro 532 }
1265     }
1266 niro 816 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
1267     static const masks_labels_t ultra_modes1 = {
1268     .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
1269     .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
1270     };
1271    
1272 niro 532 printf("\n UDMA modes: ");
1273 niro 816 print_flags(&ultra_modes1, id->dma_ultra);
1274 niro 532 #ifdef __NEW_HD_DRIVE_ID
1275 niro 816 if (id->hw_config & 0x2000) {
1276 niro 532 #else /* !__NEW_HD_DRIVE_ID */
1277 niro 816 if (id->word93 & 0x2000) {
1278 niro 532 #endif /* __NEW_HD_DRIVE_ID */
1279 niro 816 static const masks_labels_t ultra_modes2 = {
1280     .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
1281     0x2000, 0x0020, 0x4000, 0x0040,
1282     0x8000, 0x0080 },
1283     .labels = "*\0""udma3 \0""*\0""udma4 \0"
1284     "*\0""udma5 \0""*\0""udma6 \0"
1285     "*\0""udma7 \0"
1286     };
1287     print_flags(&ultra_modes2, id->dma_ultra);
1288 niro 532 }
1289     }
1290 niro 816 printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
1291     if (id_regs[83] & 8) {
1292     if (!(id_regs[86] & 8))
1293 niro 532 printf(": disabled (255)");
1294 niro 816 else if ((id_regs[91] & 0xFF00) != 0x4000)
1295 niro 532 printf(": unknown setting");
1296     else
1297 niro 816 printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
1298 niro 532 }
1299 niro 816 if (id_regs[82] & 0x20)
1300     printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
1301 niro 532 #ifdef __NEW_HD_DRIVE_ID
1302 niro 816 if ((id->minor_rev_num && id->minor_rev_num <= 31)
1303     || (id->major_rev_num && id->minor_rev_num <= 31)
1304     ) {
1305 niro 984 printf("\n Drive conforms to: %s: ",
1306     (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
1307     if (id->major_rev_num != 0x0000 /* NOVAL_0 */
1308     && id->major_rev_num != 0xFFFF /* NOVAL_1 */
1309     ) {
1310 niro 816 for (i = 0; i <= 15; i++) {
1311 niro 532 if (id->major_rev_num & (1<<i))
1312 niro 984 printf(" ATA/ATAPI-%u", i);
1313 niro 532 }
1314     }
1315     }
1316     #endif /* __NEW_HD_DRIVE_ID */
1317     printf("\n\n * current active mode\n\n");
1318     }
1319     #endif
1320    
1321 niro 816 static void flush_buffer_cache(/*int fd*/ void)
1322 niro 532 {
1323     fsync(fd); /* flush buffers */
1324 niro 816 ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
1325 niro 532 #ifdef HDIO_DRIVE_CMD
1326     sleep(1);
1327 niro 816 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1328     if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1329     bb_perror_msg("HDIO_DRIVE_CMD");
1330     else
1331     bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1332     }
1333 niro 532 #endif
1334     }
1335    
1336 niro 816 static void seek_to_zero(/*int fd*/ void)
1337 niro 532 {
1338 niro 816 xlseek(fd, (off_t) 0, SEEK_SET);
1339 niro 532 }
1340    
1341 niro 816 static void read_big_block(/*int fd,*/ char *buf)
1342 niro 532 {
1343     int i;
1344    
1345 niro 816 xread(fd, buf, TIMING_BUF_BYTES);
1346 niro 532 /* access all sectors of buf to ensure the read fully completed */
1347     for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1348     buf[i] &= 1;
1349     }
1350    
1351 niro 816 static unsigned dev_size_mb(/*int fd*/ void)
1352 niro 532 {
1353 niro 816 union {
1354     unsigned long long blksize64;
1355     unsigned blksize32;
1356     } u;
1357    
1358     if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
1359     u.blksize64 /= (1024 * 1024);
1360     } else {
1361     xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
1362     u.blksize64 = u.blksize32 / (2 * 1024);
1363     }
1364     if (u.blksize64 > UINT_MAX)
1365     return UINT_MAX;
1366     return u.blksize64;
1367 niro 532 }
1368    
1369 niro 816 static void print_timing(unsigned m, unsigned elapsed_us)
1370 niro 532 {
1371 niro 816 unsigned sec = elapsed_us / 1000000;
1372     unsigned hs = (elapsed_us % 1000000) / 10000;
1373 niro 532
1374 niro 816 printf("%5u MB in %u.%02u seconds = %u kB/s\n",
1375     m, sec, hs,
1376     /* "| 1" prevents div-by-0 */
1377     (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
1378     // ~= (m * 1024) / (elapsed_us / 1000000)
1379     // = kb / elapsed_sec
1380     );
1381 niro 532 }
1382    
1383 niro 816 static void do_time(int cache /*,int fd*/)
1384     /* cache=1: time cache: repeatedly read N MB at offset 0
1385     * cache=0: time device: linear read, starting at offset 0
1386     */
1387 niro 532 {
1388 niro 816 unsigned max_iterations, iterations;
1389     unsigned start; /* doesn't need to be long long */
1390     unsigned elapsed, elapsed2;
1391     unsigned total_MB;
1392     char *buf = xmalloc(TIMING_BUF_BYTES);
1393 niro 532
1394 niro 816 if (mlock(buf, TIMING_BUF_BYTES))
1395     bb_perror_msg_and_die("mlock");
1396    
1397     /* Clear out the device request queues & give them time to complete.
1398     * NB: *small* delay. User is expected to have a clue and to not run
1399     * heavy io in parallel with measurements. */
1400     sync();
1401     sleep(1);
1402     if (cache) { /* Time cache */
1403     seek_to_zero();
1404     read_big_block(buf);
1405     printf("Timing buffer-cache reads: ");
1406     } else { /* Time device */
1407     printf("Timing buffered disk reads:");
1408 niro 532 }
1409 niro 984 fflush_all();
1410 niro 532
1411 niro 816 /* Now do the timing */
1412     iterations = 0;
1413     /* Max time to run (small for cache, avoids getting
1414     * huge total_MB which can overlow unsigned type) */
1415     elapsed2 = 510000; /* cache */
1416     max_iterations = UINT_MAX;
1417     if (!cache) {
1418     elapsed2 = 3000000; /* not cache */
1419     /* Don't want to read past the end! */
1420     max_iterations = dev_size_mb() / TIMING_BUF_MB;
1421 niro 532 }
1422 niro 816 start = monotonic_us();
1423     do {
1424     if (cache)
1425     seek_to_zero();
1426     read_big_block(buf);
1427     elapsed = (unsigned)monotonic_us() - start;
1428     ++iterations;
1429     } while (elapsed < elapsed2 && iterations < max_iterations);
1430     total_MB = iterations * TIMING_BUF_MB;
1431     //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
1432     if (cache) {
1433     /* Cache: remove lseek() and monotonic_us() overheads
1434     * from elapsed */
1435     start = monotonic_us();
1436 niro 532 do {
1437 niro 816 seek_to_zero();
1438     elapsed2 = (unsigned)monotonic_us() - start;
1439 niro 532 } while (--iterations);
1440 niro 816 //printf(" elapsed2:%u ", elapsed2);
1441 niro 532 elapsed -= elapsed2;
1442 niro 816 total_MB *= 2; // BUFCACHE_FACTOR (why?)
1443     flush_buffer_cache();
1444 niro 532 }
1445 niro 816 print_timing(total_MB, elapsed);
1446 niro 532 munlock(buf, TIMING_BUF_BYTES);
1447 niro 816 free(buf);
1448 niro 532 }
1449    
1450 niro 816 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1451     static void bus_state_value(unsigned value)
1452 niro 532 {
1453     if (value == BUSSTATE_ON)
1454     on_off(1);
1455     else if (value == BUSSTATE_OFF)
1456     on_off(0);
1457     else if (value == BUSSTATE_TRISTATE)
1458     printf(" (tristate)\n");
1459     else
1460     printf(" (unknown: %d)\n", value);
1461     }
1462     #endif
1463    
1464     #ifdef HDIO_DRIVE_CMD
1465 niro 816 static void interpret_standby(uint8_t standby)
1466 niro 532 {
1467     printf(" (");
1468 niro 816 if (standby == 0) {
1469 niro 532 printf("off");
1470 niro 816 } else if (standby <= 240 || standby == 252 || standby == 255) {
1471     /* standby is in 5 sec units */
1472 niro 984 unsigned t = standby * 5;
1473     printf("%u minutes %u seconds", t / 60, t % 60);
1474 niro 816 } else if (standby <= 251) {
1475     unsigned t = (standby - 240); /* t is in 30 min units */;
1476 niro 984 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0');
1477 niro 816 }
1478     if (standby == 253)
1479 niro 532 printf("vendor-specific");
1480 niro 816 if (standby == 254)
1481     printf("reserved");
1482 niro 532 printf(")\n");
1483     }
1484    
1485 niro 816 static const uint8_t xfermode_val[] ALIGN1 = {
1486     8, 9, 10, 11, 12, 13, 14, 15,
1487     16, 17, 18, 19, 20, 21, 22, 23,
1488     32, 33, 34, 35, 36, 37, 38, 39,
1489     64, 65, 66, 67, 68, 69, 70, 71
1490 niro 532 };
1491 niro 816 /* NB: we save size by _not_ storing terninating NUL! */
1492     static const char xfermode_name[][5] ALIGN1 = {
1493     "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
1494     "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
1495     "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
1496     "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
1497 niro 532 };
1498    
1499 niro 816 static int translate_xfermode(const char *name)
1500 niro 532 {
1501 niro 816 int val;
1502     unsigned i;
1503 niro 532
1504 niro 816 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
1505     if (!strncmp(name, xfermode_name[i], 5))
1506     if (strlen(name) <= 5)
1507     return xfermode_val[i];
1508 niro 532 }
1509 niro 816 /* Negative numbers are invalid and are caught later */
1510     val = bb_strtoi(name, NULL, 10);
1511     if (!errno)
1512 niro 532 return val;
1513     return -1;
1514     }
1515    
1516 niro 816 static void interpret_xfermode(unsigned xfermode)
1517 niro 532 {
1518     printf(" (");
1519     if (xfermode == 0)
1520     printf("default PIO mode");
1521     else if (xfermode == 1)
1522     printf("default PIO mode, disable IORDY");
1523     else if (xfermode >= 8 && xfermode <= 15)
1524 niro 816 printf("PIO flow control mode%u", xfermode - 8);
1525 niro 532 else if (xfermode >= 16 && xfermode <= 23)
1526 niro 816 printf("singleword DMA mode%u", xfermode - 16);
1527 niro 532 else if (xfermode >= 32 && xfermode <= 39)
1528 niro 816 printf("multiword DMA mode%u", xfermode - 32);
1529 niro 532 else if (xfermode >= 64 && xfermode <= 71)
1530 niro 816 printf("UltraDMA mode%u", xfermode - 64);
1531 niro 532 else
1532 niro 816 printf("unknown");
1533 niro 532 printf(")\n");
1534     }
1535     #endif /* HDIO_DRIVE_CMD */
1536    
1537 niro 816 static void print_flag(int flag, const char *s, unsigned long value)
1538 niro 532 {
1539     if (flag)
1540     printf(" setting %s to %ld\n", s, value);
1541     }
1542    
1543     static void process_dev(char *devname)
1544     {
1545 niro 816 /*int fd;*/
1546     long parm, multcount;
1547 niro 532 #ifndef HDIO_DRIVE_CMD
1548     int force_operation = 0;
1549     #endif
1550     /* Please restore args[n] to these values after each ioctl
1551     except for args[2] */
1552 niro 816 unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
1553 niro 532 const char *fmt = " %s\t= %2ld";
1554    
1555 niro 984 /*fd = xopen_nonblocking(devname);*/
1556     xmove_fd(xopen_nonblocking(devname), fd);
1557 niro 532 printf("\n%s:\n", devname);
1558    
1559 niro 984 if (getset_readahead == IS_SET) {
1560     print_flag(getset_readahead, "fs readahead", Xreadahead);
1561 niro 816 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
1562 niro 532 }
1563 niro 816 #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1564     if (unregister_hwif) {
1565 niro 532 printf(" attempting to unregister hwif#%lu\n", hwif);
1566 niro 816 ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
1567 niro 532 }
1568     #endif
1569 niro 816 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
1570 niro 984 if (scan_hwif == IS_SET) {
1571 niro 532 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
1572     args[0] = hwif_data;
1573     args[1] = hwif_ctrl;
1574     args[2] = hwif_irq;
1575 niro 816 ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
1576 niro 532 args[0] = WIN_SETFEATURES;
1577     args[1] = 0;
1578     }
1579     #endif
1580 niro 816 if (set_piomode) {
1581     if (noisy_piomode) {
1582 niro 532 printf(" attempting to ");
1583     if (piomode == 255)
1584     printf("auto-tune PIO mode\n");
1585     else if (piomode < 100)
1586     printf("set PIO mode to %d\n", piomode);
1587     else if (piomode < 200)
1588     printf("set MDMA mode to %d\n", (piomode-100));
1589     else
1590     printf("set UDMA mode to %d\n", (piomode-200));
1591     }
1592 niro 816 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
1593 niro 532 }
1594 niro 984 if (getset_io32bit == IS_SET) {
1595     print_flag(getset_io32bit, "32-bit IO_support flag", io32bit);
1596 niro 816 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
1597 niro 532 }
1598 niro 984 if (getset_mult == IS_SET) {
1599     print_flag(getset_mult, "multcount", mult);
1600 niro 532 #ifdef HDIO_DRIVE_CMD
1601 niro 816 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
1602 niro 532 #else
1603 niro 816 force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
1604 niro 532 #endif
1605     }
1606 niro 984 if (getset_readonly == IS_SET) {
1607     print_flag_on_off(getset_readonly, "readonly", readonly);
1608 niro 816 ioctl_or_warn(fd, BLKROSET, &readonly);
1609 niro 532 }
1610 niro 984 if (getset_unmask == IS_SET) {
1611     print_flag_on_off(getset_unmask, "unmaskirq", unmask);
1612 niro 816 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
1613 niro 532 }
1614 niro 816 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1615 niro 984 if (getset_dma == IS_SET) {
1616     print_flag_on_off(getset_dma, "using_dma", dma);
1617 niro 816 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
1618 niro 532 }
1619 niro 816 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
1620     #ifdef HDIO_SET_QDMA
1621 niro 984 if (getset_dma_q == IS_SET) {
1622     print_flag_on_off(getset_dma_q, "DMA queue_depth", dma_q);
1623 niro 816 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
1624 niro 532 }
1625 niro 816 #endif
1626 niro 984 if (getset_nowerr == IS_SET) {
1627     print_flag_on_off(getset_nowerr, "nowerr", nowerr);
1628 niro 816 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
1629 niro 532 }
1630 niro 984 if (getset_keep == IS_SET) {
1631     print_flag_on_off(getset_keep, "keep_settings", keep);
1632 niro 816 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
1633 niro 532 }
1634     #ifdef HDIO_DRIVE_CMD
1635 niro 984 if (getset_doorlock == IS_SET) {
1636 niro 532 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1637     args[2] = 0;
1638 niro 984 print_flag_on_off(getset_doorlock, "drive doorlock", doorlock);
1639 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1640 niro 532 args[0] = WIN_SETFEATURES;
1641     }
1642 niro 984 if (getset_dkeep == IS_SET) {
1643 niro 532 /* lock/unlock the drive's "feature" settings */
1644 niro 984 print_flag_on_off(getset_dkeep, "drive keep features", dkeep);
1645 niro 532 args[2] = dkeep ? 0x66 : 0xcc;
1646 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1647 niro 532 }
1648 niro 984 if (getset_defects == IS_SET) {
1649 niro 532 args[2] = defects ? 0x04 : 0x84;
1650 niro 984 print_flag(getset_defects, "drive defect-mgmt", defects);
1651 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1652 niro 532 }
1653 niro 984 if (getset_prefetch == IS_SET) {
1654 niro 532 args[1] = prefetch;
1655     args[2] = 0xab;
1656 niro 984 print_flag(getset_prefetch, "drive prefetch", prefetch);
1657 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1658 niro 532 args[1] = 0;
1659     }
1660 niro 816 if (set_xfermode) {
1661 niro 532 args[1] = xfermode_requested;
1662     args[2] = 3;
1663 niro 984 print_flag(1, "xfermode", xfermode_requested);
1664     interpret_xfermode(xfermode_requested);
1665 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1666 niro 532 args[1] = 0;
1667     }
1668 niro 984 if (getset_lookahead == IS_SET) {
1669 niro 532 args[2] = lookahead ? 0xaa : 0x55;
1670 niro 984 print_flag_on_off(getset_lookahead, "drive read-lookahead", lookahead);
1671 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1672 niro 532 }
1673 niro 984 if (getset_apmmode == IS_SET) {
1674     /* feature register */
1675     args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */;
1676 niro 532 args[1] = apmmode; /* sector count register 1-255 */
1677 niro 984 printf(" setting APM level to %s 0x%02lX (%ld)\n",
1678     (apmmode == 255) ? "disabled" : "",
1679     apmmode, apmmode);
1680 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1681 niro 532 args[1] = 0;
1682     }
1683 niro 984 if (getset_wcache == IS_SET) {
1684 niro 532 #ifdef DO_FLUSHCACHE
1685     #ifndef WIN_FLUSHCACHE
1686     #define WIN_FLUSHCACHE 0xe7
1687     #endif
1688     #endif /* DO_FLUSHCACHE */
1689     args[2] = wcache ? 0x02 : 0x82;
1690 niro 984 print_flag_on_off(getset_wcache, "drive write-caching", wcache);
1691 niro 532 #ifdef DO_FLUSHCACHE
1692     if (!wcache)
1693 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1694 niro 532 #endif /* DO_FLUSHCACHE */
1695 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1696 niro 532 #ifdef DO_FLUSHCACHE
1697     if (!wcache)
1698 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
1699 niro 532 #endif /* DO_FLUSHCACHE */
1700     }
1701    
1702     /* In code below, we do not preserve args[0], but the rest
1703     is preserved, including args[2] */
1704     args[2] = 0;
1705    
1706 niro 816 if (set_standbynow) {
1707 niro 532 #ifndef WIN_STANDBYNOW1
1708     #define WIN_STANDBYNOW1 0xE0
1709     #endif
1710     #ifndef WIN_STANDBYNOW2
1711     #define WIN_STANDBYNOW2 0x94
1712     #endif
1713 niro 984 printf(" issuing standby command\n");
1714 niro 532 args[0] = WIN_STANDBYNOW1;
1715 niro 816 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
1716 niro 532 }
1717 niro 816 if (set_sleepnow) {
1718 niro 532 #ifndef WIN_SLEEPNOW1
1719     #define WIN_SLEEPNOW1 0xE6
1720     #endif
1721     #ifndef WIN_SLEEPNOW2
1722     #define WIN_SLEEPNOW2 0x99
1723     #endif
1724 niro 984 printf(" issuing sleep command\n");
1725 niro 532 args[0] = WIN_SLEEPNOW1;
1726 niro 816 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
1727 niro 532 }
1728 niro 816 if (set_seagate) {
1729 niro 532 args[0] = 0xfb;
1730 niro 984 printf(" disabling Seagate auto powersaving mode\n");
1731 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1732 niro 532 }
1733 niro 984 if (getset_standby == IS_SET) {
1734 niro 532 args[0] = WIN_SETIDLE1;
1735     args[1] = standby_requested;
1736 niro 984 print_flag(1, "standby", standby_requested);
1737     interpret_standby(standby_requested);
1738 niro 816 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
1739 niro 532 args[1] = 0;
1740     }
1741     #else /* HDIO_DRIVE_CMD */
1742 niro 816 if (force_operation) {
1743 niro 532 char buf[512];
1744 niro 816 flush_buffer_cache();
1745 niro 532 if (-1 == read(fd, buf, sizeof(buf)))
1746 niro 984 bb_perror_msg("read of 512 bytes failed");
1747 niro 532 }
1748     #endif /* HDIO_DRIVE_CMD */
1749 niro 984 if (getset_mult || get_identity) {
1750 niro 532 multcount = -1;
1751 niro 816 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1752 niro 984 /* To be coherent with ioctl_or_warn. */
1753     if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1754 niro 532 bb_perror_msg("HDIO_GET_MULTCOUNT");
1755 niro 816 else
1756     bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1757 niro 984 } else if (getset_mult) {
1758 niro 532 printf(fmt, "multcount", multcount);
1759 niro 816 on_off(multcount != 0);
1760 niro 532 }
1761     }
1762 niro 984 if (getset_io32bit) {
1763 niro 816 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
1764 niro 532 printf(" IO_support\t=%3ld (", parm);
1765     if (parm == 0)
1766     printf("default 16-bit)\n");
1767     else if (parm == 2)
1768     printf("16-bit)\n");
1769     else if (parm == 1)
1770     printf("32-bit)\n");
1771     else if (parm == 3)
1772     printf("32-bit w/sync)\n");
1773     else if (parm == 8)
1774     printf("Request-Queue-Bypass)\n");
1775     else
1776     printf("\?\?\?)\n");
1777     }
1778     }
1779 niro 984 if (getset_unmask) {
1780 niro 816 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
1781     print_value_on_off("unmaskirq", parm);
1782 niro 532 }
1783 niro 816 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
1784 niro 984 if (getset_dma) {
1785 niro 816 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
1786 niro 532 printf(fmt, "using_dma", parm);
1787     if (parm == 8)
1788     printf(" (DMA-Assisted-PIO)\n");
1789     else
1790 niro 816 on_off(parm != 0);
1791 niro 532 }
1792     }
1793     #endif
1794 niro 816 #ifdef HDIO_GET_QDMA
1795 niro 984 if (getset_dma_q) {
1796 niro 816 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
1797     print_value_on_off("queue_depth", parm);
1798 niro 532 }
1799 niro 816 #endif
1800 niro 984 if (getset_keep) {
1801 niro 816 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
1802     print_value_on_off("keepsettings", parm);
1803 niro 532 }
1804 niro 984 if (getset_nowerr) {
1805 niro 816 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
1806     print_value_on_off("nowerr", parm);
1807 niro 532 }
1808 niro 984 if (getset_readonly) {
1809 niro 816 if (!ioctl_or_warn(fd, BLKROGET, &parm))
1810     print_value_on_off("readonly", parm);
1811 niro 532 }
1812 niro 984 if (getset_readahead) {
1813 niro 816 if (!ioctl_or_warn(fd, BLKRAGET, &parm))
1814     print_value_on_off("readahead", parm);
1815 niro 532 }
1816 niro 816 if (get_geom) {
1817     if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
1818 niro 532 struct hd_geometry g;
1819    
1820 niro 816 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
1821 niro 532 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
1822 niro 984 g.cylinders, g.heads, g.sectors, parm, g.start);
1823 niro 532 }
1824     }
1825     #ifdef HDIO_DRIVE_CMD
1826 niro 816 if (get_powermode) {
1827 niro 532 #ifndef WIN_CHECKPOWERMODE1
1828     #define WIN_CHECKPOWERMODE1 0xE5
1829     #endif
1830     #ifndef WIN_CHECKPOWERMODE2
1831     #define WIN_CHECKPOWERMODE2 0x98
1832     #endif
1833     const char *state;
1834    
1835     args[0] = WIN_CHECKPOWERMODE1;
1836 niro 816 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
1837 niro 532 if (errno != EIO || args[0] != 0 || args[1] != 0)
1838 niro 816 state = "unknown";
1839 niro 532 else
1840     state = "sleeping";
1841 niro 816 } else
1842 niro 532 state = (args[2] == 255) ? "active/idle" : "standby";
1843     args[1] = args[2] = 0;
1844    
1845     printf(" drive state is: %s\n", state);
1846     }
1847     #endif
1848 niro 816 #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
1849     if (perform_reset) {
1850     ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
1851 niro 532 }
1852 niro 816 #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
1853     #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1854     if (perform_tristate) {
1855 niro 532 args[0] = 0;
1856     args[1] = tristate;
1857 niro 816 ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
1858 niro 532 }
1859 niro 816 #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
1860     #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1861     if (get_identity) {
1862     struct hd_driveid id;
1863 niro 532
1864 niro 816 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
1865     if (multcount != -1) {
1866 niro 532 id.multsect = multcount;
1867     id.multsect_valid |= 1;
1868 niro 816 } else
1869 niro 532 id.multsect_valid &= ~1;
1870     dump_identity(&id);
1871 niro 816 } else if (errno == -ENOMSG)
1872 niro 532 printf(" no identification info available\n");
1873 niro 816 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1874     bb_perror_msg("HDIO_GET_IDENTITY");
1875 niro 532 else
1876 niro 816 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1877 niro 532 }
1878    
1879 niro 816 if (get_IDentity) {
1880 niro 532 unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
1881    
1882     memset(args1, 0, sizeof(args1));
1883     args1[0] = WIN_IDENTIFY;
1884     args1[3] = 1;
1885 niro 816 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
1886 niro 532 identify((void *)(args1 + 4));
1887     }
1888     #endif
1889 niro 816 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
1890 niro 984 if (getset_busstate == IS_SET) {
1891     print_flag(1, "bus state", busstate);
1892     bus_state_value(busstate);
1893 niro 816 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
1894 niro 532 }
1895 niro 984 if (getset_busstate) {
1896 niro 816 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
1897 niro 532 printf(fmt, "bus state", parm);
1898     bus_state_value(parm);
1899     }
1900     }
1901     #endif
1902     if (reread_partn)
1903 niro 816 ioctl_or_warn(fd, BLKRRPART, NULL);
1904 niro 532
1905     if (do_ctimings)
1906 niro 816 do_time(1 /*,fd*/); /* time cache */
1907 niro 532 if (do_timings)
1908 niro 816 do_time(0 /*,fd*/); /* time device */
1909 niro 532 if (do_flush)
1910 niro 816 flush_buffer_cache();
1911 niro 532 close(fd);
1912     }
1913    
1914 niro 816 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
1915 niro 532 static int fromhex(unsigned char c)
1916     {
1917     if (isdigit(c))
1918     return (c - '0');
1919     if (c >= 'a' && c <= 'f')
1920     return (c - ('a' - 10));
1921     bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
1922     }
1923    
1924 niro 816 static void identify_from_stdin(void) NORETURN;
1925 niro 532 static void identify_from_stdin(void)
1926     {
1927     uint16_t sbuf[256];
1928     unsigned char buf[1280];
1929     unsigned char *b = (unsigned char *)buf;
1930     int i;
1931    
1932 niro 816 xread(STDIN_FILENO, buf, 1280);
1933 niro 532
1934     // Convert the newline-separated hex data into an identify block.
1935    
1936 niro 816 for (i = 0; i < 256; i++) {
1937 niro 532 int j;
1938     for (j = 0; j < 4; j++)
1939     sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
1940     }
1941    
1942     // Parse the data.
1943    
1944     identify(sbuf);
1945     }
1946 niro 816 #else
1947     void identify_from_stdin(void);
1948 niro 532 #endif
1949    
1950     /* busybox specific stuff */
1951 niro 984 static int parse_opts(unsigned long *value, int min, int max)
1952 niro 532 {
1953     if (optarg) {
1954     *value = xatol_range(optarg, min, max);
1955 niro 984 return IS_SET;
1956 niro 532 }
1957 niro 984 return IS_GET;
1958 niro 532 }
1959 niro 984 static int parse_opts_0_max(unsigned long *value, int max)
1960     {
1961     return parse_opts(value, 0, max);
1962     }
1963     static int parse_opts_0_1(unsigned long *value)
1964     {
1965     return parse_opts(value, 0, 1);
1966     }
1967     static int parse_opts_0_INTMAX(unsigned long *value)
1968     {
1969     return parse_opts(value, 0, INT_MAX);
1970     }
1971 niro 532
1972 niro 816 static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
1973 niro 532 {
1974     if (flag) {
1975 niro 984 *get = IS_GET;
1976 niro 532 if (optarg) {
1977 niro 816 *value = translate_xfermode(optarg);
1978     *set = (*value > -1);
1979 niro 532 }
1980     }
1981     }
1982    
1983     /*------- getopt short options --------*/
1984 niro 816 static const char hdparm_options[] ALIGN1 =
1985     "gfu::n::p:r::m::c::k::a::B:tT"
1986 niro 984 IF_FEATURE_HDPARM_GET_IDENTITY("iI")
1987     IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
1988 niro 532 #ifdef HDIO_DRIVE_CMD
1989     "S:D:P:X:K:A:L:W:CyYzZ"
1990     #endif
1991 niro 984 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
1992 niro 532 #ifdef HDIO_GET_QDMA
1993     #ifdef HDIO_SET_QDMA
1994     "Q:"
1995     #else
1996     "Q"
1997     #endif
1998     #endif
1999 niro 984 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
2000     IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
2001     IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
2002 niro 532 /*-------------------------------------*/
2003    
2004     /* our main() routine: */
2005 niro 816 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2006 niro 532 int hdparm_main(int argc, char **argv)
2007     {
2008     int c;
2009     int flagcount = 0;
2010    
2011     while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
2012     flagcount++;
2013 niro 984 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
2014     IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
2015 niro 532 get_geom |= (c == 'g');
2016     do_flush |= (c == 'f');
2017 niro 984 if (c == 'u') getset_unmask = parse_opts_0_1(&unmask);
2018     IF_FEATURE_HDPARM_HDIO_GETSET_DMA(
2019     if (c == 'd') getset_dma = parse_opts_0_max(&dma, 9);
2020     )
2021     if (c == 'n') getset_nowerr = parse_opts_0_1(&nowerr);
2022 niro 816 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
2023 niro 984 if (c == 'r') getset_readonly = parse_opts_0_1(&readonly);
2024     if (c == 'm') getset_mult = parse_opts_0_INTMAX(&mult /*32*/);
2025     if (c == 'c') getset_io32bit = parse_opts_0_INTMAX(&io32bit /*8*/);
2026     if (c == 'k') getset_keep = parse_opts_0_1(&keep);
2027     if (c == 'a') getset_readahead = parse_opts_0_INTMAX(&Xreadahead);
2028     if (c == 'B') getset_apmmode = parse_opts(&apmmode, 1, 255);
2029 niro 532 do_flush |= do_timings |= (c == 't');
2030     do_flush |= do_ctimings |= (c == 'T');
2031     #ifdef HDIO_DRIVE_CMD
2032 niro 984 if (c == 'S') getset_standby = parse_opts_0_max(&standby_requested, 255);
2033     if (c == 'D') getset_defects = parse_opts_0_INTMAX(&defects);
2034     if (c == 'P') getset_prefetch = parse_opts_0_INTMAX(&prefetch);
2035 niro 532 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
2036 niro 984 if (c == 'K') getset_dkeep = parse_opts_0_1(&prefetch);
2037     if (c == 'A') getset_lookahead = parse_opts_0_1(&lookahead);
2038     if (c == 'L') getset_doorlock = parse_opts_0_1(&doorlock);
2039     if (c == 'W') getset_wcache = parse_opts_0_1(&wcache);
2040 niro 532 get_powermode |= (c == 'C');
2041 niro 984 set_standbynow |= (c == 'y');
2042     set_sleepnow |= (c == 'Y');
2043 niro 532 reread_partn |= (c == 'z');
2044 niro 984 set_seagate |= (c == 'Z');
2045 niro 532 #endif
2046 niro 984 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') unregister_hwif = parse_opts_0_INTMAX(&hwif));
2047 niro 532 #ifdef HDIO_GET_QDMA
2048     if (c == 'Q') {
2049 niro 984 getset_dma_q = parse_opts_0_INTMAX(&dma_q);
2050 niro 532 }
2051     #endif
2052 niro 984 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
2053     IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') perform_tristate = parse_opts_0_1(&tristate));
2054     IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') getset_busstate = parse_opts_0_max(&busstate, 2));
2055 niro 532 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2056     if (c == 'R') {
2057 niro 984 scan_hwif = parse_opts_0_INTMAX(&hwif_data);
2058 niro 532 hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
2059     hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
2060     /* Move past the 2 additional arguments */
2061     argv += 2;
2062     argc -= 2;
2063     }
2064     #endif
2065     }
2066     /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
2067     if (!flagcount) {
2068 niro 984 getset_mult = getset_io32bit = getset_unmask = getset_keep = getset_readonly = getset_readahead = get_geom = IS_GET;
2069     IF_FEATURE_HDPARM_HDIO_GETSET_DMA(getset_dma = IS_GET);
2070 niro 532 }
2071     argv += optind;
2072    
2073 niro 816 if (!*argv) {
2074 niro 532 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
2075     identify_from_stdin(); /* EXIT */
2076 niro 816 bb_show_usage();
2077 niro 532 }
2078    
2079 niro 816 do {
2080     process_dev(*argv++);
2081     } while (*argv);
2082    
2083     return EXIT_SUCCESS;
2084 niro 532 }