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