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