Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/miscutils/hdparm.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/miscutils/hdparm.c
r1765 r2725 6 6 * Hacked by Tito <farmatito@tiscali.it> for size optimization. 7 7 * 8 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 9 9 * 10 10 * This program is based on the source code of hdparm: see below... … … 12 12 * - by Mark Lord (C) 1994-2002 -- freely distributable 13 13 */ 14 15 14 #include "libbb.h" 15 /* must be _after_ libbb.h: */ 16 16 #include <linux/hdreg.h> 17 #include <sys/mount.h> 18 #if !defined(BLKGETSIZE64) 19 # define BLKGETSIZE64 _IOR(0x12,114,size_t) 20 #endif 17 21 18 22 /* device types */ … … 60 64 /* multiword DMA xfer cycle time: */ 61 65 #define DMA_TIME_MIN 65 /* - minimum */ 62 #define DMA_TIME_NORM 66 /* - manufacturer's recommended 66 #define DMA_TIME_NORM 66 /* - manufacturer's recommended */ 63 67 /* minimum PIO xfer cycle time: */ 64 68 #define PIO_NO_FLOW 67 /* - without flow control */ … … 83 87 #define ADV_PWR 91 /* current advanced power management level 84 88 in low byte, 0x40 in high byte. */ 85 #define PSWD_CODE 92 /* master password revision code 89 #define PSWD_CODE 92 /* master password revision code */ 86 90 #define HWRST_RSLT 93 /* hardware reset result */ 87 91 #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */ … … 128 132 #define CDROM 0x0005 129 133 130 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY131 static const char *const pkt_str[] = {132 "Direct-access device", /* word 0, bits 12-8 = 00 */133 "Sequential-access device", /* word 0, bits 12-8 = 01 */134 "Printer", /* word 0, bits 12-8 = 02 */135 "Processor", /* word 0, bits 12-8 = 03 */136 "Write-once device", /* word 0, bits 12-8 = 04 */137 "CD-ROM", /* word 0, bits 12-8 = 05 */138 "Scanner", /* word 0, bits 12-8 = 06 */139 "Optical memory", /* word 0, bits 12-8 = 07 */140 "Medium changer", /* word 0, bits 12-8 = 08 */141 "Communications device", /* word 0, bits 12-8 = 09 */142 "ACS-IT8 device", /* word 0, bits 12-8 = 0a */143 "ACS-IT8 device", /* word 0, bits 12-8 = 0b */144 "Array controller", /* word 0, bits 12-8 = 0c */145 "Enclosure services", /* word 0, bits 12-8 = 0d */146 "Reduced block command device", /* word 0, bits 12-8 = 0e */147 "Optical card reader/writer", /* word 0, bits 12-8 = 0f */148 "", /* word 0, bits 12-8 = 10 */149 "", /* word 0, bits 12-8 = 11 */150 "", /* word 0, bits 12-8 = 12 */151 "", /* word 0, bits 12-8 = 13 */152 "", /* word 0, bits 12-8 = 14 */153 "", /* word 0, bits 12-8 = 15 */154 "", /* word 0, bits 12-8 = 16 */155 "", /* word 0, bits 12-8 = 17 */156 "", /* word 0, bits 12-8 = 18 */157 "", /* word 0, bits 12-8 = 19 */158 "", /* word 0, bits 12-8 = 1a */159 "", /* word 0, bits 12-8 = 1b */160 "", /* word 0, bits 12-8 = 1c */161 "", /* word 0, bits 12-8 = 1d */162 "", /* word 0, bits 12-8 = 1e */163 "Unknown", /* word 0, bits 12-8 = 1f */164 };165 166 static const char *const ata1_cfg_str[] = { /* word 0 in ATA-1 mode */167 "Reserved", /* bit 0 */168 "hard sectored", /* bit 1 */169 "soft sectored", /* bit 2 */170 "not MFM encoded ", /* bit 3 */171 "head switch time > 15us", /* bit 4 */172 "spindle motor control option", /* bit 5 */173 "fixed drive", /* bit 6 */174 "removable drive", /* bit 7 */175 "disk xfer rate <= 5Mbs", /* bit 8 */176 "disk xfer rate > 5Mbs, <= 10Mbs", /* bit 9 */177 "disk xfer rate > 5Mbs", /* bit 10 */178 "rotational speed tol.", /* bit 11 */179 "data strobe offset option", /* bit 12 */180 "track offset option", /* bit 13 */181 "format speed tolerance gap reqd", /* bit 14 */182 "ATAPI" /* bit 14 */183 };184 #endif185 186 134 /* word 1: number of logical cylinders */ 187 135 #define LCYLS_MAX 0x3fff /* maximum allowable value */ … … 239 187 /* word 81: minor version number */ 240 188 #define MINOR_MAX 0x22 189 /* words 82-84: cmds/feats supported */ 190 #define CMDS_W82 0x77ff /* word 82: defined command locations*/ 191 #define CMDS_W83 0x3fff /* word 83: defined command locations*/ 192 #define CMDS_W84 0x002f /* word 83: defined command locations*/ 193 #define SUPPORT_48_BIT 0x0400 194 #define NUM_CMD_FEAT_STR 48 195 196 /* words 85-87: cmds/feats enabled */ 197 /* use cmd_feat_str[] to display what commands and features have 198 * been enabled with words 85-87 199 */ 200 201 /* words 89, 90, SECU ERASE TIME */ 202 #define ERASE_BITS 0x00ff 203 204 /* word 92: master password revision */ 205 /* NOVAL_0 or NOVAL_1 means no support for master password revision */ 206 207 /* word 93: hw reset result */ 208 #define CBLID 0x2000 /* CBLID status */ 209 #define RST0 0x0001 /* 1=reset to device #0 */ 210 #define DEV_DET 0x0006 /* how device num determined */ 211 #define JUMPER_VAL 0x0002 /* device num determined by jumper */ 212 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */ 213 214 /* word 127: removable media status notification feature set support */ 215 #define RM_STAT_BITS 0x0003 216 #define RM_STAT_SUP 0x0001 217 218 /* word 128: security */ 219 #define SECU_ENABLED 0x0002 220 #define SECU_LEVEL 0x0010 221 #define NUM_SECU_STR 6 222 223 /* word 160: CFA power mode */ 224 #define VALID_W160 0x8000 /* 1=word valid */ 225 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/ 226 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */ 227 #define MAX_AMPS 0x0fff /* value = max current in ma */ 228 229 /* word 255: integrity */ 230 #define SIG 0x00ff /* signature location */ 231 #define SIG_VAL 0x00a5 /* signature value */ 232 233 #define TIMING_BUF_MB 1 234 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024) 235 236 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */ 237 238 239 #define IS_GET 1 240 #define IS_SET 2 241 242 243 enum { fd = 3 }; 244 245 246 struct globals { 247 smallint get_identity, get_geom; 248 smallint do_flush; 249 smallint do_ctimings, do_timings; 250 smallint reread_partn; 251 smallint set_piomode, noisy_piomode; 252 smallint getset_readahead; 253 smallint getset_readonly; 254 smallint getset_unmask; 255 smallint getset_mult; 256 #ifdef HDIO_GET_QDMA 257 smallint getset_dma_q; 258 #endif 259 smallint getset_nowerr; 260 smallint getset_keep; 261 smallint getset_io32bit; 262 int piomode; 263 unsigned long Xreadahead; 264 unsigned long readonly; 265 unsigned long unmask; 266 unsigned long mult; 267 #ifdef HDIO_SET_QDMA 268 unsigned long dma_q; 269 #endif 270 unsigned long nowerr; 271 unsigned long keep; 272 unsigned long io32bit; 273 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA 274 unsigned long dma; 275 smallint getset_dma; 276 #endif 277 #ifdef HDIO_DRIVE_CMD 278 smallint set_xfermode, get_xfermode; 279 smallint getset_dkeep; 280 smallint getset_standby; 281 smallint getset_lookahead; 282 smallint getset_prefetch; 283 smallint getset_defects; 284 smallint getset_wcache; 285 smallint getset_doorlock; 286 smallint set_seagate; 287 smallint set_standbynow; 288 smallint set_sleepnow; 289 smallint get_powermode; 290 smallint getset_apmmode; 291 int xfermode_requested; 292 unsigned long dkeep; 293 unsigned long standby_requested; /* 0..255 */ 294 unsigned long lookahead; 295 unsigned long prefetch; 296 unsigned long defects; 297 unsigned long wcache; 298 unsigned long doorlock; 299 unsigned long apmmode; 300 #endif 301 IF_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;) 302 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint getset_busstate;) 303 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;) 304 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;) 305 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;) 306 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;) 307 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;) 308 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;) 309 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;) 310 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF 311 unsigned long hwif_data; 312 unsigned long hwif_ctrl; 313 unsigned long hwif_irq; 314 #endif 315 #ifdef DO_FLUSHCACHE 316 unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 }; 317 #endif 318 } FIX_ALIASING; 319 #define G (*(struct globals*)&bb_common_bufsiz1) 320 struct BUG_G_too_big { 321 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; 322 }; 323 #define get_identity (G.get_identity ) 324 #define get_geom (G.get_geom ) 325 #define do_flush (G.do_flush ) 326 #define do_ctimings (G.do_ctimings ) 327 #define do_timings (G.do_timings ) 328 #define reread_partn (G.reread_partn ) 329 #define set_piomode (G.set_piomode ) 330 #define noisy_piomode (G.noisy_piomode ) 331 #define getset_readahead (G.getset_readahead ) 332 #define getset_readonly (G.getset_readonly ) 333 #define getset_unmask (G.getset_unmask ) 334 #define getset_mult (G.getset_mult ) 335 #define getset_dma_q (G.getset_dma_q ) 336 #define getset_nowerr (G.getset_nowerr ) 337 #define getset_keep (G.getset_keep ) 338 #define getset_io32bit (G.getset_io32bit ) 339 #define piomode (G.piomode ) 340 #define Xreadahead (G.Xreadahead ) 341 #define readonly (G.readonly ) 342 #define unmask (G.unmask ) 343 #define mult (G.mult ) 344 #define dma_q (G.dma_q ) 345 #define nowerr (G.nowerr ) 346 #define keep (G.keep ) 347 #define io32bit (G.io32bit ) 348 #define dma (G.dma ) 349 #define getset_dma (G.getset_dma ) 350 #define set_xfermode (G.set_xfermode ) 351 #define get_xfermode (G.get_xfermode ) 352 #define getset_dkeep (G.getset_dkeep ) 353 #define getset_standby (G.getset_standby ) 354 #define getset_lookahead (G.getset_lookahead ) 355 #define getset_prefetch (G.getset_prefetch ) 356 #define getset_defects (G.getset_defects ) 357 #define getset_wcache (G.getset_wcache ) 358 #define getset_doorlock (G.getset_doorlock ) 359 #define set_seagate (G.set_seagate ) 360 #define set_standbynow (G.set_standbynow ) 361 #define set_sleepnow (G.set_sleepnow ) 362 #define get_powermode (G.get_powermode ) 363 #define getset_apmmode (G.getset_apmmode ) 364 #define xfermode_requested (G.xfermode_requested ) 365 #define dkeep (G.dkeep ) 366 #define standby_requested (G.standby_requested ) 367 #define lookahead (G.lookahead ) 368 #define prefetch (G.prefetch ) 369 #define defects (G.defects ) 370 #define wcache (G.wcache ) 371 #define doorlock (G.doorlock ) 372 #define apmmode (G.apmmode ) 373 #define get_IDentity (G.get_IDentity ) 374 #define getset_busstate (G.getset_busstate ) 375 #define perform_reset (G.perform_reset ) 376 #define perform_tristate (G.perform_tristate ) 377 #define unregister_hwif (G.unregister_hwif ) 378 #define scan_hwif (G.scan_hwif ) 379 #define busstate (G.busstate ) 380 #define tristate (G.tristate ) 381 #define hwif (G.hwif ) 382 #define hwif_data (G.hwif_data ) 383 #define hwif_ctrl (G.hwif_ctrl ) 384 #define hwif_irq (G.hwif_irq ) 385 386 387 /* Busybox messages and functions */ 388 #if ENABLE_IOCTL_HEX2STR_ERROR 389 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string) 390 { 391 if (!ioctl(fd, cmd, args)) 392 return 0; 393 args[0] = alt; 394 return bb_ioctl_or_warn(fd, cmd, args, string); 395 } 396 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd) 397 #else 398 static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt) 399 { 400 if (!ioctl(fd, cmd, args)) 401 return 0; 402 args[0] = alt; 403 return bb_ioctl_or_warn(fd, cmd, args); 404 } 405 #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt) 406 #endif 407 408 static void on_off(int value) 409 { 410 puts(value ? " (on)" : " (off)"); 411 } 412 413 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg) 414 { 415 if (get_arg) { 416 printf(" setting %s to %ld", s, arg); 417 on_off(arg); 418 } 419 } 420 421 static void print_value_on_off(const char *str, unsigned long argp) 422 { 423 printf(" %s\t= %2ld", str, argp); 424 on_off(argp != 0); 425 } 426 241 427 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY 242 static const char *const minor_str[MINOR_MAX + 2] = { 428 static void print_ascii(const char *p, int length) 429 { 430 #if BB_BIG_ENDIAN 431 #define LE_ONLY(x) 432 enum { ofs = 0 }; 433 #else 434 #define LE_ONLY(x) x 435 /* every 16bit word is big-endian (i.e. inverted) */ 436 /* accessing bytes in 1,0, 3,2, 5,4... sequence */ 437 int ofs = 1; 438 #endif 439 440 length *= 2; 441 /* find first non-space & print it */ 442 while (length && p[ofs] != ' ') { 443 p++; 444 LE_ONLY(ofs = -ofs;) 445 length--; 446 } 447 while (length && p[ofs]) { 448 bb_putchar(p[ofs]); 449 p++; 450 LE_ONLY(ofs = -ofs;) 451 length--; 452 } 453 bb_putchar('\n'); 454 #undef LE_ONLY 455 } 456 457 static void xprint_ascii(uint16_t *val, int i, const char *string, int n) 458 { 459 if (val[i]) { 460 printf("\t%-20s", string); 461 print_ascii((void*)&val[i], n); 462 } 463 } 464 465 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode) 466 { 467 uint16_t ii; 468 uint8_t err_dma = 0; 469 470 for (ii = 0; ii <= MODE_MAX; ii++) { 471 if (mode_sel & 0x0001) { 472 printf("*%cdma%u ", cc, ii); 473 if (*have_mode) 474 err_dma = 1; 475 *have_mode = 1; 476 } else if (mode_sup & 0x0001) 477 printf("%cdma%u ", cc, ii); 478 479 mode_sup >>= 1; 480 mode_sel >>= 1; 481 } 482 return err_dma; 483 } 484 485 static const char pkt_str[] ALIGN1 = 486 "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */ 487 "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */ 488 "Printer" "\0" /* word 0, bits 12-8 = 02 */ 489 "Processor" "\0" /* word 0, bits 12-8 = 03 */ 490 "Write-once device" "\0" /* word 0, bits 12-8 = 04 */ 491 "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */ 492 "Scanner" "\0" /* word 0, bits 12-8 = 06 */ 493 "Optical memory" "\0" /* word 0, bits 12-8 = 07 */ 494 "Medium changer" "\0" /* word 0, bits 12-8 = 08 */ 495 "Communications device" "\0" /* word 0, bits 12-8 = 09 */ 496 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */ 497 "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */ 498 "Array controller" "\0" /* word 0, bits 12-8 = 0c */ 499 "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */ 500 "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */ 501 "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */ 502 ; 503 504 static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */ 505 "reserved" "\0" /* bit 0 */ 506 "hard sectored" "\0" /* bit 1 */ 507 "soft sectored" "\0" /* bit 2 */ 508 "not MFM encoded " "\0" /* bit 3 */ 509 "head switch time > 15us" "\0" /* bit 4 */ 510 "spindle motor control option" "\0" /* bit 5 */ 511 "fixed drive" "\0" /* bit 6 */ 512 "removable drive" "\0" /* bit 7 */ 513 "disk xfer rate <= 5Mbs" "\0" /* bit 8 */ 514 "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */ 515 "disk xfer rate > 5Mbs" "\0" /* bit 10 */ 516 "rotational speed tol." "\0" /* bit 11 */ 517 "data strobe offset option" "\0" /* bit 12 */ 518 "track offset option" "\0" /* bit 13 */ 519 "format speed tolerance gap reqd" "\0" /* bit 14 */ 520 "ATAPI" /* bit 14 */ 521 ; 522 523 static const char minor_str[] ALIGN1 = 243 524 /* word 81 value: */ 244 "Unspecified", /* 0x0000 */ 245 "ATA-1 X3T9.2 781D prior to rev.4", /* 0x0001 */ 246 "ATA-1 published, ANSI X3.221-1994", /* 0x0002 */ 247 "ATA-1 X3T9.2 781D rev.4", /* 0x0003 */ 248 "ATA-2 published, ANSI X3.279-1996", /* 0x0004 */ 249 "ATA-2 X3T10 948D prior to rev.2k", /* 0x0005 */ 250 "ATA-3 X3T10 2008D rev.1", /* 0x0006 */ 251 "ATA-2 X3T10 948D rev.2k", /* 0x0007 */ 252 "ATA-3 X3T10 2008D rev.0", /* 0x0008 */ 253 "ATA-2 X3T10 948D rev.3", /* 0x0009 */ 254 "ATA-3 published, ANSI X3.298-199x", /* 0x000a */ 255 "ATA-3 X3T10 2008D rev.6", /* 0x000b */ 256 "ATA-3 X3T13 2008D rev.7 and 7a", /* 0x000c */ 257 "ATA/ATAPI-4 X3T13 1153D rev.6", /* 0x000d */ 258 "ATA/ATAPI-4 T13 1153D rev.13", /* 0x000e */ 259 "ATA/ATAPI-4 X3T13 1153D rev.7", /* 0x000f */ 260 "ATA/ATAPI-4 T13 1153D rev.18", /* 0x0010 */ 261 "ATA/ATAPI-4 T13 1153D rev.15", /* 0x0011 */ 262 "ATA/ATAPI-4 published, ANSI INCITS 317-1998", /* 0x0012 */ 263 "ATA/ATAPI-5 T13 1321D rev.3", /* 0x0013 */ 264 "ATA/ATAPI-4 T13 1153D rev.14", /* 0x0014 */ 265 "ATA/ATAPI-5 T13 1321D rev.1", /* 0x0015 */ 266 "ATA/ATAPI-5 published, ANSI INCITS 340-2000", /* 0x0016 */ 267 "ATA/ATAPI-4 T13 1153D rev.17", /* 0x0017 */ 268 "ATA/ATAPI-6 T13 1410D rev.0", /* 0x0018 */ 269 "ATA/ATAPI-6 T13 1410D rev.3a", /* 0x0019 */ 270 "ATA/ATAPI-7 T13 1532D rev.1", /* 0x001a */ 271 "ATA/ATAPI-6 T13 1410D rev.2", /* 0x001b */ 272 "ATA/ATAPI-6 T13 1410D rev.1", /* 0x001c */ 273 "ATA/ATAPI-7 published, ANSI INCITS 397-2005", /* 0x001d */ 274 "ATA/ATAPI-7 T13 1532D rev.0", /* 0x001e */ 275 "Reserved" /* 0x001f */ 276 "Reserved" /* 0x0020 */ 277 "ATA/ATAPI-7 T13 1532D rev.4a", /* 0x0021 */ 278 "ATA/ATAPI-6 published, ANSI INCITS 361-2002", /* 0x0022 */ 279 "Reserved" /* 0x0023-0xfffe */ 280 }; 281 #endif 525 "Unspecified" "\0" /* 0x0000 */ 526 "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */ 527 "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */ 528 "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */ 529 "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */ 530 "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */ 531 "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */ 532 "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */ 533 "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */ 534 "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */ 535 "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */ 536 "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */ 537 "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */ 538 "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */ 539 "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */ 540 "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */ 541 "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */ 542 "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */ 543 "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */ 544 "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */ 545 "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */ 546 "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */ 547 "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */ 548 "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */ 549 "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */ 550 "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */ 551 "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */ 552 "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */ 553 "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */ 554 "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */ 555 "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */ 556 "reserved" "\0" /* 0x001f */ 557 "reserved" "\0" /* 0x0020 */ 558 "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */ 559 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */ 560 "reserved" /* 0x0023-0xfffe */ 561 ; 282 562 static const char actual_ver[MINOR_MAX + 2] ALIGN1 = { 283 563 /* word 81 value: */ … … 320 600 }; 321 601 322 /* words 82-84: cmds/feats supported */ 323 #define CMDS_W82 0x77ff /* word 82: defined command locations*/ 324 #define CMDS_W83 0x3fff /* word 83: defined command locations*/ 325 #define CMDS_W84 0x002f /* word 83: defined command locations*/ 326 #define SUPPORT_48_BIT 0x0400 327 #define NUM_CMD_FEAT_STR 48 328 329 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY 330 static const char *const cmd_feat_str[] = { 331 "", /* word 82 bit 15: obsolete */ 332 "NOP cmd", /* word 82 bit 14 */ 333 "READ BUFFER cmd", /* word 82 bit 13 */ 334 "WRITE BUFFER cmd", /* word 82 bit 12 */ 335 "", /* word 82 bit 11: obsolete */ 336 "Host Protected Area feature set", /* word 82 bit 10 */ 337 "DEVICE RESET cmd", /* word 82 bit 9 */ 338 "SERVICE interrupt", /* word 82 bit 8 */ 339 "Release interrupt", /* word 82 bit 7 */ 340 "Look-ahead", /* word 82 bit 6 */ 341 "Write cache", /* word 82 bit 5 */ 342 "PACKET command feature set", /* word 82 bit 4 */ 343 "Power Management feature set", /* word 82 bit 3 */ 344 "Removable Media feature set", /* word 82 bit 2 */ 345 "Security Mode feature set", /* word 82 bit 1 */ 346 "SMART feature set", /* word 82 bit 0 */ 347 /* -------------- */ 348 "", /* word 83 bit 15: !valid bit */ 349 "", /* word 83 bit 14: valid bit */ 350 "FLUSH CACHE EXT cmd", /* word 83 bit 13 */ 351 "Mandatory FLUSH CACHE cmd ", /* word 83 bit 12 */ 352 "Device Configuration Overlay feature set ", 353 "48-bit Address feature set ", /* word 83 bit 10 */ 354 "", 355 "SET MAX security extension", /* word 83 bit 8 */ 356 "Address Offset Reserved Area Boot", /* word 83 bit 7 */ 357 "SET FEATURES subcommand required to spinup after power up", 358 "Power-Up In Standby feature set", /* word 83 bit 5 */ 359 "Removable Media Status Notification feature set", 360 "Adv. Power Management feature set", /* word 83 bit 3 */ 361 "CFA feature set", /* word 83 bit 2 */ 362 "READ/WRITE DMA QUEUED", /* word 83 bit 1 */ 363 "DOWNLOAD MICROCODE cmd", /* word 83 bit 0 */ 364 /* -------------- */ 365 "", /* word 84 bit 15: !valid bit */ 366 "", /* word 84 bit 14: valid bit */ 367 "", /* word 84 bit 13: reserved */ 368 "", /* word 84 bit 12: reserved */ 369 "", /* word 84 bit 11: reserved */ 370 "", /* word 84 bit 10: reserved */ 371 "", /* word 84 bit 9: reserved */ 372 "", /* word 84 bit 8: reserved */ 373 "", /* word 84 bit 7: reserved */ 374 "", /* word 84 bit 6: reserved */ 375 "General Purpose Logging feature set", /* word 84 bit 5 */ 376 "", /* word 84 bit 4: reserved */ 377 "Media Card Pass Through Command feature set ", 378 "Media serial number ", /* word 84 bit 2 */ 379 "SMART self-test ", /* word 84 bit 1 */ 380 "SMART error logging " /* word 84 bit 0 */ 381 }; 382 383 static void identify(uint16_t *id_supplied) ATTRIBUTE_NORETURN; 384 static void identify_from_stdin(void) ATTRIBUTE_NORETURN; 385 #else 386 void identify_from_stdin(void); 387 #endif 388 389 390 /* words 85-87: cmds/feats enabled */ 391 /* use cmd_feat_str[] to display what commands and features have 392 * been enabled with words 85-87 393 */ 394 395 /* words 89, 90, SECU ERASE TIME */ 396 #define ERASE_BITS 0x00ff 397 398 /* word 92: master password revision */ 399 /* NOVAL_0 or NOVAL_1 means no support for master password revision */ 400 401 /* word 93: hw reset result */ 402 #define CBLID 0x2000 /* CBLID status */ 403 #define RST0 0x0001 /* 1=reset to device #0 */ 404 #define DEV_DET 0x0006 /* how device num determined */ 405 #define JUMPER_VAL 0x0002 /* device num determined by jumper */ 406 #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */ 407 408 /* word 127: removable media status notification feature set support */ 409 #define RM_STAT_BITS 0x0003 410 #define RM_STAT_SUP 0x0001 411 412 /* word 128: security */ 413 #define SECU_ENABLED 0x0002 414 #define SECU_LEVEL 0x0010 415 #define NUM_SECU_STR 6 416 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY 417 static const char *const secu_str[] = { 418 "supported", /* word 128, bit 0 */ 419 "enabled", /* word 128, bit 1 */ 420 "locked", /* word 128, bit 2 */ 421 "frozen", /* word 128, bit 3 */ 422 "expired: security count", /* word 128, bit 4 */ 423 "supported: enhanced erase" /* word 128, bit 5 */ 424 }; 425 #endif 426 427 /* word 160: CFA power mode */ 428 #define VALID_W160 0x8000 /* 1=word valid */ 429 #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/ 430 #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */ 431 #define MAX_AMPS 0x0fff /* value = max current in ma */ 432 433 /* word 255: integrity */ 434 #define SIG 0x00ff /* signature location */ 435 #define SIG_VAL 0x00a5 /* signature value */ 436 437 #define TIMING_MB 64 438 #define TIMING_BUF_MB 1 439 #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024) 440 #define BUFCACHE_FACTOR 2 441 442 #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */ 443 444 /* Busybox messages and functions */ 445 #if ENABLE_IOCTL_HEX2STR_ERROR 446 static int ioctl_alt_func(int fd, int cmd, unsigned char *args, int alt, const char *string) 447 { 448 if (!ioctl(fd, cmd, args)) 449 return 0; 450 args[0] = alt; 451 return bb_ioctl_or_warn(fd, cmd, args, string); 452 } 453 #define ioctl_alt_or_warn(fd,cmd,args,alt) ioctl_alt_func(fd,cmd,args,alt,#cmd) 454 #else 455 static int ioctl_alt_func(int fd, int cmd, unsigned char *args, int alt) 456 { 457 if (!ioctl(fd, cmd, args)) 458 return 0; 459 args[0] = alt; 460 return bb_ioctl_or_warn(fd, cmd, args); 461 } 462 #define ioctl_alt_or_warn(fd,cmd,args,alt) ioctl_alt_func(fd,cmd,args,alt) 463 #endif 464 465 static void on_off(int value) 466 { 467 puts(value ? " (on)" : " (off)"); 468 } 469 470 static void print_flag_on_off(int get_arg, const char *s, unsigned long arg) 471 { 472 if (get_arg) { 473 printf(" setting %s to %ld", s, arg); 474 on_off(arg); 475 } 476 } 477 478 static void print_value_on_off(const char *str, unsigned long argp) 479 { 480 printf(" %s\t= %2ld", str, argp); 481 on_off(argp != 0); 482 } 483 484 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY 485 static void print_ascii(uint16_t *p, uint8_t length); 486 487 static void xprint_ascii(uint16_t *val, int i, const char *string, int n) 488 { 489 if (val[i]) { 490 printf("\t%-20s", string); 491 print_ascii(&val[i], n); 492 } 493 } 494 #endif 495 /* end of busybox specific stuff */ 496 497 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY 498 static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode) 499 { 500 uint16_t ii; 501 uint8_t err_dma = 0; 502 503 for (ii = 0; ii <= MODE_MAX; ii++) { 504 if (mode_sel & 0x0001) { 505 printf("*%cdma%u ", cc, ii); 506 if (*have_mode) 507 err_dma = 1; 508 *have_mode = 1; 509 } else if (mode_sup & 0x0001) 510 printf("%cdma%u ", cc, ii); 511 512 mode_sup >>= 1; 513 mode_sel >>= 1; 514 } 515 return err_dma; 516 } 517 518 static void print_ascii(uint16_t *p, uint8_t length) 519 { 520 uint8_t ii; 521 char cl; 522 523 /* find first non-space & print it */ 524 for (ii = 0; ii < length; ii++) { 525 if ((char)((*p)>>8) != ' ') 526 break; 527 cl = (char)(*p); 528 if (cl != ' ') { 529 if (cl != '\0') 530 printf("%c", cl); 531 p++; 532 ii++; 533 break; 534 } 535 p++; 536 } 537 /* print the rest */ 538 for (; ii< length; ii++) { 539 if (!(*p)) 540 break; /* some older devices have NULLs */ 541 printf("%c%c", (char)((*p)>>8), (char)(*p)); 542 p++; 543 } 544 puts(""); 545 } 602 static const char cmd_feat_str[] ALIGN1 = 603 "" "\0" /* word 82 bit 15: obsolete */ 604 "NOP cmd" "\0" /* word 82 bit 14 */ 605 "READ BUFFER cmd" "\0" /* word 82 bit 13 */ 606 "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */ 607 "" "\0" /* word 82 bit 11: obsolete */ 608 "Host Protected Area feature set" "\0" /* word 82 bit 10 */ 609 "DEVICE RESET cmd" "\0" /* word 82 bit 9 */ 610 "SERVICE interrupt" "\0" /* word 82 bit 8 */ 611 "Release interrupt" "\0" /* word 82 bit 7 */ 612 "Look-ahead" "\0" /* word 82 bit 6 */ 613 "Write cache" "\0" /* word 82 bit 5 */ 614 "PACKET command feature set" "\0" /* word 82 bit 4 */ 615 "Power Management feature set" "\0" /* word 82 bit 3 */ 616 "Removable Media feature set" "\0" /* word 82 bit 2 */ 617 "Security Mode feature set" "\0" /* word 82 bit 1 */ 618 "SMART feature set" "\0" /* word 82 bit 0 */ 619 /* -------------- */ 620 "" "\0" /* word 83 bit 15: !valid bit */ 621 "" "\0" /* word 83 bit 14: valid bit */ 622 "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */ 623 "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */ 624 "Device Configuration Overlay feature set " "\0" 625 "48-bit Address feature set " "\0" /* word 83 bit 10 */ 626 "" "\0" 627 "SET MAX security extension" "\0" /* word 83 bit 8 */ 628 "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */ 629 "SET FEATURES subcommand required to spinup after power up" "\0" 630 "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */ 631 "Removable Media Status Notification feature set" "\0" 632 "Adv. Power Management feature set" "\0" /* word 83 bit 3 */ 633 "CFA feature set" "\0" /* word 83 bit 2 */ 634 "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */ 635 "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */ 636 /* -------------- */ 637 "" "\0" /* word 84 bit 15: !valid bit */ 638 "" "\0" /* word 84 bit 14: valid bit */ 639 "" "\0" /* word 84 bit 13: reserved */ 640 "" "\0" /* word 84 bit 12: reserved */ 641 "" "\0" /* word 84 bit 11: reserved */ 642 "" "\0" /* word 84 bit 10: reserved */ 643 "" "\0" /* word 84 bit 9: reserved */ 644 "" "\0" /* word 84 bit 8: reserved */ 645 "" "\0" /* word 84 bit 7: reserved */ 646 "" "\0" /* word 84 bit 6: reserved */ 647 "General Purpose Logging feature set" "\0" /* word 84 bit 5 */ 648 "" "\0" /* word 84 bit 4: reserved */ 649 "Media Card Pass Through Command feature set " "\0" 650 "Media serial number " "\0" /* word 84 bit 2 */ 651 "SMART self-test " "\0" /* word 84 bit 1 */ 652 "SMART error logging " /* word 84 bit 0 */ 653 ; 654 655 static const char secu_str[] ALIGN1 = 656 "supported" "\0" /* word 128, bit 0 */ 657 "enabled" "\0" /* word 128, bit 1 */ 658 "locked" "\0" /* word 128, bit 2 */ 659 "frozen" "\0" /* word 128, bit 3 */ 660 "expired: security count" "\0" /* word 128, bit 4 */ 661 "supported: enhanced erase" /* word 128, bit 5 */ 662 ; 546 663 547 664 // Parse 512 byte disk identification block and print much crap. 548 549 static void identify(uint16_t *id_supplied) 550 { 551 uint16_t buf[256]; 552 uint16_t *val, ii, jj, kk; 665 static void identify(uint16_t *val) NORETURN; 666 static void identify(uint16_t *val) 667 { 668 uint16_t ii, jj, kk; 553 669 uint16_t like_std = 1, std = 0, min_std = 0xffff; 554 670 uint16_t dev = NO_DEV, eqpt = NO_DEV; … … 558 674 uint64_t bbbig; /* (:) */ 559 675 const char *strng; 560 561 // Adjust for endianness if necessary. 562 563 if (BB_BIG_ENDIAN) { 564 swab(id_supplied, buf, sizeof(buf)); 565 val = buf; 566 } else 567 val = id_supplied; 568 569 chksum &= 0xff; 570 571 /* check if we recognise the device type */ 572 puts(""); 676 #if BB_BIG_ENDIAN 677 uint16_t buf[256]; 678 679 // Adjust for endianness 680 swab(val, buf, sizeof(buf)); 681 val = buf; 682 #endif 683 /* check if we recognize the device type */ 684 bb_putchar('\n'); 573 685 if (!(val[GEN_CONFIG] & NOT_ATA)) { 574 686 dev = ATA_DEV; … … 581 693 dev = ATAPI_DEV; 582 694 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT; 583 printf("ATAPI %s, with ", pkt_str[eqpt]);695 printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown"); 584 696 like_std = 3; 585 697 } else 586 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n"*/698 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */ 587 699 bb_error_msg_and_die("unknown device type"); 588 700 … … 619 731 if (like_std < 3) like_std = 3; 620 732 std = actual_ver[val[MINOR]]; 621 if (std) printf("\n\tUsed: %s ", minor_str[val[MINOR]]);622 733 if (std) 734 printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR])); 623 735 } 624 736 /* looks like when they up-issue the std, they obsolete one; … … 687 799 printf("& some of %u\n", like_std); 688 800 else 689 puts("");801 bb_putchar('\n'); 690 802 } else { 691 803 /* TBD: do CDROM stuff more thoroughly. For now... */ … … 704 816 } 705 817 } 706 p rintf("%s\n",kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");818 puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1"); 707 819 /* the cdrom stuff is more like ATA-2 than anything else, so: */ 708 820 like_std = 2; … … 718 830 for (ii = 1; ii < 15; ii++) { 719 831 if (jj & 0x0001) 720 printf("\t%s\n", ata1_cfg_str[ii]);832 printf("\t%s\n", nth_string(ata1_cfg_str, ii)); 721 833 jj >>=1; 722 834 } … … 730 842 strng ="50us"; 731 843 else 732 strng = " Unknown";844 strng = "unknown"; 733 845 printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */ 734 846 … … 738 850 strng = "16 bytes"; 739 851 else 740 strng = " Unknown";852 strng = "unknown"; 741 853 puts(strng); 742 854 } else { 743 855 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */ 744 856 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB]; 745 mm = 0; bbbig = 0; 857 mm = 0; 858 bbbig = 0; 746 859 if ((ll > 0x00FBFC10) && (!val[LCYLS])) 747 860 printf("\tCHS addressing not supported\n"); 748 861 else { 749 862 jj = val[WHATS_VALID] & OK_W54_58; 750 printf("\tLogical\t\tmax\tcurrent\n\tcylinders\t%u\t%u\n\theads\t\t%u\t%u\n\tsectors/track\t%u\t%u\n\t--\n", 751 val[LCYLS],jj?val[LCYLS_CUR]:0, val[LHEADS],jj?val[LHEADS_CUR]:0, val[LSECTS],jj?val[LSECTS_CUR]:0); 863 printf("\tLogical\t\tmax\tcurrent\n" 864 "\tcylinders\t%u\t%u\n" 865 "\theads\t\t%u\t%u\n" 866 "\tsectors/track\t%u\t%u\n" 867 "\t--\n", 868 val[LCYLS], 869 jj ? val[LCYLS_CUR] : 0, 870 val[LHEADS], 871 jj ? val[LHEADS_CUR] : 0, 872 val[LSECTS], 873 jj ? val[LSECTS_CUR] : 0); 752 874 753 875 if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES])) 754 printf("\tbytes/track: %u\tbytes/sector: %u\n", val[TRACK_BYTES], val[SECT_BYTES]); 876 printf("\tbytes/track: %u\tbytes/sector: %u\n", 877 val[TRACK_BYTES], val[SECT_BYTES]); 755 878 756 879 if (jj) { … … 787 910 printf("(%"PRIu64" GB)\n", bbbig/1000); 788 911 else 789 puts("");912 bb_putchar('\n'); 790 913 } 791 914 … … 794 917 795 918 if (dev == ATAPI_DEV) { 796 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP)) printf("Cmd queuing, "); 797 if (val[CAPAB_0] & OVLP_SUP) printf("Cmd overlap, "); 919 if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP)) 920 printf("Cmd queuing, "); 921 if (val[CAPAB_0] & OVLP_SUP) 922 printf("Cmd overlap, "); 798 923 } 799 924 if (val[CAPAB_0] & LBA_SUP) printf("LBA, "); … … 801 926 if (like_std != 1) { 802 927 printf("IORDY%s(can%s be disabled)\n", 803 804 928 !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "", 929 (val[CAPAB_0] & IORDY_OFF) ? "" :"not"); 805 930 } else 806 931 printf("no IORDY\n"); … … 808 933 if ((like_std == 1) && val[BUF_TYPE]) { 809 934 printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE], 810 811 935 (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector", 936 (val[BUF_TYPE] > 2) ? " with read caching ability" : ""); 812 937 } 813 938 … … 826 951 printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : ""); 827 952 else { 828 printf("\tStandby timer values: spec'd by %s", (val[CAPAB_0] & STD_STBY) ? "Standard" : "Vendor"); 953 printf("\tStandby timer values: spec'd by %s", 954 (val[CAPAB_0] & STD_STBY) ? "standard" : "vendor"); 829 955 if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL)) 830 printf(", %s device specific minimum\n", (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no"); 956 printf(", %s device specific minimum\n", 957 (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no"); 831 958 else 832 puts("");959 bb_putchar('\n'); 833 960 } 834 961 printf("\tR/W multiple sector transfer: "); … … 856 983 if (like_std > 5 && val[ACOUSTIC]) { 857 984 printf("\tRecommended acoustic management value: %u, current value: %u\n", 858 (val[ACOUSTIC] >> 8) & 0x00ff, val[ACOUSTIC] & 0x00ff); 985 (val[ACOUSTIC] >> 8) & 0x00ff, 986 val[ACOUSTIC] & 0x00ff); 859 987 } 860 988 } else { … … 865 993 if (val[PKT_REL] || val[SVC_NBSY]) { 866 994 printf("\tOverlap support:"); 867 if (val[PKT_REL]) printf(" %uus to release bus.", val[PKT_REL]); 868 if (val[SVC_NBSY]) printf(" %uus to clear BSY after SERVICE cmd.", val[SVC_NBSY]); 869 puts(""); 995 if (val[PKT_REL]) 996 printf(" %uus to release bus.", val[PKT_REL]); 997 if (val[SVC_NBSY]) 998 printf(" %uus to clear BSY after SERVICE cmd.", 999 val[SVC_NBSY]); 1000 bb_putchar('\n'); 870 1001 } 871 1002 } … … 894 1025 } 895 1026 if (err_dma || !have_mode) printf("(?)"); 896 puts("");1027 bb_putchar('\n'); 897 1028 898 1029 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP)) … … 905 1036 if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]); 906 1037 if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]); 907 puts("");1038 bb_putchar('\n'); 908 1039 } 909 1040 } … … 919 1050 jj >>=1; 920 1051 } 921 puts("");1052 bb_putchar('\n'); 922 1053 } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) { 923 1054 for (ii = 0; ii <= val[PIO_MODE]>>8; ii++) 924 1055 printf("pio%d ", ii); 925 puts("");1056 bb_putchar('\n'); 926 1057 } else 927 p rintf("unknown\n");1058 puts("unknown"); 928 1059 929 1060 if (val[WHATS_VALID] & OK_W64_70) { 930 1061 if (val[PIO_NO_FLOW] || val[PIO_FLOW]) { 931 1062 printf("\t\tCycle time:"); 932 if (val[PIO_NO_FLOW]) printf(" no flow control=%uns", val[PIO_NO_FLOW]); 933 if (val[PIO_FLOW]) printf(" IORDY flow control=%uns", val[PIO_FLOW]); 934 puts(""); 1063 if (val[PIO_NO_FLOW]) 1064 printf(" no flow control=%uns", val[PIO_NO_FLOW]); 1065 if (val[PIO_FLOW]) 1066 printf(" IORDY flow control=%uns", val[PIO_FLOW]); 1067 bb_putchar('\n'); 935 1068 } 936 1069 } 937 1070 938 1071 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) { 939 printf("Commands/features:\n\tEnabled\tSupported:\n"); 1072 printf("Commands/features:\n" 1073 "\tEnabled\tSupported:\n"); 940 1074 jj = val[CMDS_SUPP_0]; 941 1075 kk = val[CMDS_EN_0]; 942 1076 for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) { 943 if ((jj & 0x8000) && (*cmd_feat_str[ii] != '\0')) { 944 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", cmd_feat_str[ii]); 1077 const char *feat_str = nth_string(cmd_feat_str, ii); 1078 if ((jj & 0x8000) && (*feat_str != '\0')) { 1079 printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str); 945 1080 } 946 1081 jj <<= 1; … … 958 1093 /* Removable Media Status Notification feature set */ 959 1094 if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) 960 printf("\t%s supported\n", cmd_feat_str[27]);1095 printf("\t%s supported\n", nth_string(cmd_feat_str, 27)); 961 1096 962 1097 /* security */ … … 970 1105 if (jj) { 971 1106 for (ii = 0; ii < NUM_SECU_STR; ii++) { 972 printf("\t%s\t%s\n", (!(jj & 0x0001)) ? "not" : "", secu_str[ii]); 1107 printf("\t%s\t%s\n", 1108 (!(jj & 0x0001)) ? "not" : "", 1109 nth_string(secu_str, ii)); 973 1110 jj >>=1; 974 1111 } 975 1112 if (val[SECU_STATUS] & SECU_ENABLED) { 976 printf("\tSecurity level %s\n", (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high"); 1113 printf("\tSecurity level %s\n", 1114 (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high"); 977 1115 } 978 1116 } … … 980 1118 kk = val[ENH_ERASE_TIME] & ERASE_BITS; 981 1119 if (jj || kk) { 982 printf("\t");1120 bb_putchar('\t'); 983 1121 if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, ""); 984 1122 if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED "); 985 puts("");1123 bb_putchar('\n'); 986 1124 } 987 1125 } … … 990 1128 jj = val[HWRST_RSLT]; 991 1129 if ((jj & VALID) == VALID_VAL) { 992 if (!(oo = (jj & RST0))) 1130 oo = (jj & RST0); 1131 if (!oo) 993 1132 jj >>= 8; 994 1133 if ((jj & DEV_DET) == JUMPER_VAL) … … 998 1137 else 999 1138 strng = ""; 1000 printf("HW reset results:\n\tCBLID- %s Vih\n\tDevice num = %i%s\n", 1001 (val[HWRST_RSLT] & CBLID) ? "above" : "below", !(oo), strng); 1139 printf("HW reset results:\n" 1140 "\tCBLID- %s Vih\n" 1141 "\tDevice num = %i%s\n", 1142 (val[HWRST_RSLT] & CBLID) ? "above" : "below", 1143 !(oo), strng); 1002 1144 } 1003 1145 … … 1005 1147 if ((like_std > 4) && (eqpt != CDROM)) { 1006 1148 if (val[CFA_PWR_MODE] & VALID_W160) { 1007 printf("CFA power mode 1:\n\t%s%s\n", (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled", 1008 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : ""); 1009 1149 printf("CFA power mode 1:\n" 1150 "\t%s%s\n", 1151 (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled", 1152 (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : ""); 1010 1153 if (val[CFA_PWR_MODE] & MAX_AMPS) 1011 1154 printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS); … … 1018 1161 exit(EXIT_SUCCESS); 1019 1162 } 1020 #endif1021 1022 static smallint get_identity, get_geom;1023 static smallint do_flush;1024 static smallint do_ctimings, do_timings;1025 static smallint reread_partn;1026 1027 static smallint set_piomode, noisy_piomode;1028 static smallint set_readahead, get_readahead;1029 static smallint set_readonly, get_readonly;1030 static smallint set_unmask, get_unmask;1031 static smallint set_mult, get_mult;1032 static smallint set_dma_q, get_dma_q;1033 static smallint set_nowerr, get_nowerr;1034 static smallint set_keep, get_keep;1035 static smallint set_io32bit, get_io32bit;1036 static int piomode;1037 static unsigned long Xreadahead;1038 static unsigned long readonly;1039 static unsigned long unmask;1040 static unsigned long mult;1041 static unsigned long dma_q;1042 static unsigned long nowerr;1043 static unsigned long keep;1044 static unsigned long io32bit;1045 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA1046 static unsigned long dma;1047 static smallint set_dma, get_dma;1048 #endif1049 #ifdef HDIO_DRIVE_CMD1050 static smallint set_xfermode, get_xfermode;1051 static smallint set_dkeep, get_dkeep;1052 static smallint set_standby, get_standby;1053 static smallint set_lookahead, get_lookahead;1054 static smallint set_prefetch, get_prefetch;1055 static smallint set_defects, get_defects;1056 static smallint set_wcache, get_wcache;1057 static smallint set_doorlock, get_doorlock;1058 static smallint set_seagate, get_seagate;1059 static smallint set_standbynow, get_standbynow;1060 static smallint set_sleepnow, get_sleepnow;1061 static smallint get_powermode;1062 static smallint set_apmmode, get_apmmode;1063 static int xfermode_requested;1064 static unsigned long dkeep;1065 static unsigned long standby_requested;1066 static unsigned long lookahead;1067 static unsigned long prefetch;1068 static unsigned long defects;1069 static unsigned long wcache;1070 static unsigned long doorlock;1071 static unsigned long apmmode;1072 #endif1073 USE_FEATURE_HDPARM_GET_IDENTITY( static smallint get_IDentity;)1074 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( static smallint set_busstate, get_busstate;)1075 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET( static smallint perform_reset;)1076 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( static smallint perform_tristate;)1077 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(static smallint unregister_hwif;)1078 USE_FEATURE_HDPARM_HDIO_SCAN_HWIF( static smallint scan_hwif;)1079 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( static unsigned long busstate;)1080 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( static unsigned long tristate;)1081 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(static unsigned long hwif;)1082 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF1083 static unsigned long hwif_data;1084 static unsigned long hwif_ctrl;1085 static unsigned long hwif_irq;1086 1163 #endif 1087 1164 … … 1098 1175 1099 1176 #if ENABLE_FEATURE_HDPARM_GET_IDENTITY 1100 static const char *const cfg_str[] = {1101 "" , "HardSect", "SoftSect", "NotMFM",1102 "HdSw>15uSec" , "SpinMotCtl", "Fixed", "Removeable",1103 "DTR<=5Mbs" , "DTR>5Mbs", "DTR>10Mbs", "RotSpdTol>.5%",1104 "dStbOff" , "TrkOff", "FmtGapReq","nonMagnetic"1105 };1106 1107 static const char *const BuffType[] = {1108 " Unknown", "1Sect", "DualPort","DualPortCache"1109 };1110 1111 static void dump_identity(const struct hd_driveid *id)1177 static const char cfg_str[] ALIGN1 = 1178 """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0" 1179 "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0" 1180 "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0" 1181 "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic" 1182 ; 1183 1184 static const char BuffType[] ALIGN1 = 1185 "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache" 1186 ; 1187 1188 static NOINLINE void dump_identity(const struct hd_driveid *id) 1112 1189 { 1113 1190 int i; 1114 const unsigned short int*id_regs = (const void*) id;1191 const unsigned short *id_regs = (const void*) id; 1115 1192 1116 1193 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={", … … 1118 1195 for (i = 0; i <= 15; i++) { 1119 1196 if (id->config & (1<<i)) 1120 printf(" %s", cfg_str[i]);1197 printf(" %s", nth_string(cfg_str, i)); 1121 1198 } 1122 1199 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n" 1123 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u", 1124 id->cyls, id->heads, id->sectors, id->track_bytes, 1125 id->sector_bytes, id->ecc_bytes, 1126 id->buf_type, BuffType[(id->buf_type > 3) ? 0 : id->buf_type], 1127 id->buf_size/2, id->max_multsect); 1200 " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u", 1201 id->cyls, id->heads, id->sectors, id->track_bytes, 1202 id->sector_bytes, id->ecc_bytes, 1203 id->buf_type, 1204 nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type), 1205 id->buf_size/2, id->max_multsect); 1128 1206 if (id->max_multsect) { 1129 1207 printf(", MultSect="); … … 1135 1213 printf("off"); 1136 1214 } 1137 puts("");1215 bb_putchar('\n'); 1138 1216 1139 1217 if (!(id->field_valid & 1)) … … 1150 1228 printf(", LBAsects=%u", id->lba_capacity); 1151 1229 1152 printf("\n IORDY=%s", (id->capability & 8) ? (id->capability & 4) ? "on/off" : "yes" : "no"); 1230 printf("\n IORDY=%s", 1231 (id->capability & 8) 1232 ? ((id->capability & 4) ? "on/off" : "yes") 1233 : "no"); 1153 1234 1154 1235 if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2)) … … 1165 1246 } 1166 1247 if (id->field_valid & 2) { 1167 if (id->eide_pio_modes & 1) printf("pio3 "); 1168 if (id->eide_pio_modes & 2) printf("pio4 "); 1169 if (id->eide_pio_modes &~3) printf("pio? "); 1248 static const masks_labels_t pio_modes = { 1249 .masks = { 1, 2, ~3 }, 1250 .labels = "pio3 \0""pio4 \0""pio? \0", 1251 }; 1252 print_flags(&pio_modes, id->eide_pio_modes); 1170 1253 } 1171 1254 if (id->capability & 1) { 1172 1255 if (id->dma_1word | id->dma_mword) { 1256 static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 }; 1173 1257 printf("\n DMA modes: "); 1174 if (id->dma_1word & 0x100) printf("*"); 1175 if (id->dma_1word & 1) printf("sdma0 "); 1176 if (id->dma_1word & 0x200) printf("*"); 1177 if (id->dma_1word & 2) printf("sdma1 "); 1178 if (id->dma_1word & 0x400) printf("*"); 1179 if (id->dma_1word & 4) printf("sdma2 "); 1180 if (id->dma_1word & 0xf800) printf("*"); 1181 if (id->dma_1word & 0xf8) printf("sdma? "); 1182 if (id->dma_mword & 0x100) printf("*"); 1183 if (id->dma_mword & 1) printf("mdma0 "); 1184 if (id->dma_mword & 0x200) printf("*"); 1185 if (id->dma_mword & 2) printf("mdma1 "); 1186 if (id->dma_mword & 0x400) printf("*"); 1187 if (id->dma_mword & 4) printf("mdma2 "); 1188 if (id->dma_mword & 0xf800) printf("*"); 1189 if (id->dma_mword & 0xf8) printf("mdma? "); 1258 print_flags_separated(dma_wmode_masks, 1259 "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0", 1260 id->dma_1word, NULL); 1261 print_flags_separated(dma_wmode_masks, 1262 "*\0""mdma0 \0""*\0""mdma1 \0""*\0""mdma2 \0""*\0""mdma? \0", 1263 id->dma_mword, NULL); 1190 1264 } 1191 1265 } 1192 1266 if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) { 1267 static const masks_labels_t ultra_modes1 = { 1268 .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 }, 1269 .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0", 1270 }; 1271 1193 1272 printf("\n UDMA modes: "); 1194 if (id->dma_ultra & 0x100) printf("*"); 1195 if (id->dma_ultra & 0x001) printf("udma0 "); 1196 if (id->dma_ultra & 0x200) printf("*"); 1197 if (id->dma_ultra & 0x002) printf("udma1 "); 1198 if (id->dma_ultra & 0x400) printf("*"); 1199 if (id->dma_ultra & 0x004) printf("udma2 "); 1273 print_flags(&ultra_modes1, id->dma_ultra); 1200 1274 #ifdef __NEW_HD_DRIVE_ID 1201 1275 if (id->hw_config & 0x2000) { … … 1203 1277 if (id->word93 & 0x2000) { 1204 1278 #endif /* __NEW_HD_DRIVE_ID */ 1205 if (id->dma_ultra & 0x0800) printf("*"); 1206 if (id->dma_ultra & 0x0008) printf("udma3 "); 1207 if (id->dma_ultra & 0x1000) printf("*"); 1208 if (id->dma_ultra & 0x0010) printf("udma4 "); 1209 if (id->dma_ultra & 0x2000) printf("*"); 1210 if (id->dma_ultra & 0x0020) printf("udma5 "); 1211 if (id->dma_ultra & 0x4000) printf("*"); 1212 if (id->dma_ultra & 0x0040) printf("udma6 "); 1213 if (id->dma_ultra & 0x8000) printf("*"); 1214 if (id->dma_ultra & 0x0080) printf("udma7 "); 1279 static const masks_labels_t ultra_modes2 = { 1280 .masks = { 0x0800, 0x0008, 0x1000, 0x0010, 1281 0x2000, 0x0020, 0x4000, 0x0040, 1282 0x8000, 0x0080 }, 1283 .labels = "*\0""udma3 \0""*\0""udma4 \0" 1284 "*\0""udma5 \0""*\0""udma6 \0" 1285 "*\0""udma7 \0" 1286 }; 1287 print_flags(&ultra_modes2, id->dma_ultra); 1215 1288 } 1216 1289 } … … 1230 1303 || (id->major_rev_num && id->minor_rev_num <= 31) 1231 1304 ) { 1232 printf("\n Drive conforms to: %s: ", (id->minor_rev_num <= 31) ? minor_str[id->minor_rev_num] : "Unknown"); 1233 if (id->major_rev_num != 0x0000 && /* NOVAL_0 */ 1234 id->major_rev_num != 0xFFFF) { /* NOVAL_1 */ 1305 printf("\n Drive conforms to: %s: ", 1306 (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown"); 1307 if (id->major_rev_num != 0x0000 /* NOVAL_0 */ 1308 && id->major_rev_num != 0xFFFF /* NOVAL_1 */ 1309 ) { 1235 1310 for (i = 0; i <= 15; i++) { 1236 1311 if (id->major_rev_num & (1<<i)) 1237 1312 printf(" ATA/ATAPI-%u", i); 1238 1313 } 1239 1314 } … … 1244 1319 #endif 1245 1320 1246 static void flush_buffer_cache( int fd)1321 static void flush_buffer_cache(/*int fd*/ void) 1247 1322 { 1248 1323 fsync(fd); /* flush buffers */ … … 1259 1334 } 1260 1335 1261 static int seek_to_zero(int fd) 1262 { 1263 if (lseek(fd, (off_t) 0, SEEK_SET)) 1264 return 1; 1265 return 0; 1266 } 1267 1268 static int read_big_block(int fd, char *buf) 1336 static void seek_to_zero(/*int fd*/ void) 1337 { 1338 xlseek(fd, (off_t) 0, SEEK_SET); 1339 } 1340 1341 static void read_big_block(/*int fd,*/ char *buf) 1269 1342 { 1270 1343 int i; 1271 1344 1272 i = read(fd, buf, TIMING_BUF_BYTES); 1273 if (i != TIMING_BUF_BYTES) { 1274 bb_error_msg("read(%d bytes) failed (rc=%d)", TIMING_BUF_BYTES, i); 1275 return 1; 1276 } 1345 xread(fd, buf, TIMING_BUF_BYTES); 1277 1346 /* access all sectors of buf to ensure the read fully completed */ 1278 1347 for (i = 0; i < TIMING_BUF_BYTES; i += 512) 1279 1348 buf[i] &= 1; 1280 return 0; 1281 } 1282 1283 static int do_blkgetsize(int fd, unsigned long long *blksize64) 1284 { 1285 int rc; 1286 unsigned blksize32 = 0; 1287 1288 if (0 == ioctl(fd, BLKGETSIZE64, blksize64)) { // returns bytes 1289 *blksize64 /= 512; 1290 return 0; 1291 } 1292 rc = ioctl_or_warn(fd, BLKGETSIZE, &blksize32); // returns sectors 1293 *blksize64 = blksize32; 1294 return rc; 1295 } 1296 1297 static void print_timing(unsigned t, double e) 1298 { 1299 if (t >= e) /* more than 1MB/s */ 1300 printf("%4d MB in %.2f seconds = %.2f %cB/sec\n", t, e, t / e, 'M'); 1301 else 1302 printf("%4d MB in %.2f seconds = %.2f %cB/sec\n", t, e, t / e * 1024, 'k'); 1303 } 1304 1305 static void do_time(int flag, int fd) 1306 /* flag = 0 time_cache, 1 time_device */ 1307 { 1308 static const struct itimerval thousand = {{1000, 0}, {1000, 0}}; 1309 1310 struct itimerval itv; 1349 } 1350 1351 static unsigned dev_size_mb(/*int fd*/ void) 1352 { 1353 union { 1354 unsigned long long blksize64; 1355 unsigned blksize32; 1356 } u; 1357 1358 if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes 1359 u.blksize64 /= (1024 * 1024); 1360 } else { 1361 xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors 1362 u.blksize64 = u.blksize32 / (2 * 1024); 1363 } 1364 if (u.blksize64 > UINT_MAX) 1365 return UINT_MAX; 1366 return u.blksize64; 1367 } 1368 1369 static void print_timing(unsigned m, unsigned elapsed_us) 1370 { 1371 unsigned sec = elapsed_us / 1000000; 1372 unsigned hs = (elapsed_us % 1000000) / 10000; 1373 1374 printf("%5u MB in %u.%02u seconds = %u kB/s\n", 1375 m, sec, hs, 1376 /* "| 1" prevents div-by-0 */ 1377 (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1)) 1378 // ~= (m * 1024) / (elapsed_us / 1000000) 1379 // = kb / elapsed_sec 1380 ); 1381 } 1382 1383 static void do_time(int cache /*,int fd*/) 1384 /* cache=1: time cache: repeatedly read N MB at offset 0 1385 * cache=0: time device: linear read, starting at offset 0 1386 */ 1387 { 1388 unsigned max_iterations, iterations; 1389 unsigned start; /* doesn't need to be long long */ 1311 1390 unsigned elapsed, elapsed2; 1312 unsigned max_iterations, total_MB, iterations; 1313 unsigned long long blksize; 1314 RESERVE_CONFIG_BUFFER(buf, TIMING_BUF_BYTES); 1315 1316 if (mlock(buf, TIMING_BUF_BYTES)) { 1317 bb_perror_msg("mlock"); 1318 goto quit2; 1319 } 1320 1321 max_iterations = 1024; 1322 if (0 == do_blkgetsize(fd, &blksize)) { 1323 max_iterations = blksize / (2 * 1024) / TIMING_BUF_MB; 1324 } 1325 1326 /* Clear out the device request queues & give them time to complete */ 1391 unsigned total_MB; 1392 char *buf = xmalloc(TIMING_BUF_BYTES); 1393 1394 if (mlock(buf, TIMING_BUF_BYTES)) 1395 bb_perror_msg_and_die("mlock"); 1396 1397 /* Clear out the device request queues & give them time to complete. 1398 * NB: *small* delay. User is expected to have a clue and to not run 1399 * heavy io in parallel with measurements. */ 1327 1400 sync(); 1328 sleep(2); 1329 if (flag == 0) { /* Time cache */ 1330 if (seek_to_zero(fd)) 1331 goto quit; 1332 if (read_big_block(fd, buf)) 1333 goto quit; 1334 printf(" Timing buffer-cache reads: "); 1401 sleep(1); 1402 if (cache) { /* Time cache */ 1403 seek_to_zero(); 1404 read_big_block(buf); 1405 printf("Timing buffer-cache reads: "); 1335 1406 } else { /* Time device */ 1336 printf(" Timing buffered disk reads: "); 1337 } 1338 fflush(stdout); 1407 printf("Timing buffered disk reads:"); 1408 } 1409 fflush_all(); 1410 1411 /* Now do the timing */ 1339 1412 iterations = 0; 1340 /* 1341 * getitimer() is used rather than gettimeofday() because 1342 * it is much more consistent (on my machine, at least). 1343 */ 1344 setitimer(ITIMER_REAL, &thousand, NULL); 1345 /* Now do the timing */ 1413 /* Max time to run (small for cache, avoids getting 1414 * huge total_MB which can overlow unsigned type) */ 1415 elapsed2 = 510000; /* cache */ 1416 max_iterations = UINT_MAX; 1417 if (!cache) { 1418 elapsed2 = 3000000; /* not cache */ 1419 /* Don't want to read past the end! */ 1420 max_iterations = dev_size_mb() / TIMING_BUF_MB; 1421 } 1422 start = monotonic_us(); 1346 1423 do { 1424 if (cache) 1425 seek_to_zero(); 1426 read_big_block(buf); 1427 elapsed = (unsigned)monotonic_us() - start; 1347 1428 ++iterations; 1348 if ((flag == 0) && seek_to_zero(fd)) 1349 goto quit; 1350 if (read_big_block(fd, buf)) 1351 goto quit; 1352 getitimer(ITIMER_REAL, &itv); 1353 elapsed = (1000 - itv.it_value.tv_sec) * 1000000 1354 - itv.it_value.tv_usec; 1355 } while (elapsed < 3000000 && iterations < max_iterations); 1429 } while (elapsed < elapsed2 && iterations < max_iterations); 1356 1430 total_MB = iterations * TIMING_BUF_MB; 1357 if (flag == 0) { 1358 /* Now remove the lseek() and getitimer() overheads from the elapsed time */ 1359 setitimer(ITIMER_REAL, &thousand, NULL); 1431 //printf(" elapsed:%u iterations:%u ", elapsed, iterations); 1432 if (cache) { 1433 /* Cache: remove lseek() and monotonic_us() overheads 1434 * from elapsed */ 1435 start = monotonic_us(); 1360 1436 do { 1361 if (seek_to_zero(fd)) 1362 goto quit; 1363 getitimer(ITIMER_REAL, &itv); 1364 elapsed2 = (1000 - itv.it_value.tv_sec) * 1000000 1365 - itv.it_value.tv_usec; 1437 seek_to_zero(); 1438 elapsed2 = (unsigned)monotonic_us() - start; 1366 1439 } while (--iterations); 1440 //printf(" elapsed2:%u ", elapsed2); 1367 1441 elapsed -= elapsed2; 1368 total_MB *= BUFCACHE_FACTOR; 1369 flush_buffer_cache(fd); 1370 } 1371 print_timing(total_MB, elapsed / 1000000.0); 1372 quit: 1442 total_MB *= 2; // BUFCACHE_FACTOR (why?) 1443 flush_buffer_cache(); 1444 } 1445 print_timing(total_MB, elapsed); 1373 1446 munlock(buf, TIMING_BUF_BYTES); 1374 quit2: 1375 RELEASE_CONFIG_BUFFER(buf); 1447 free(buf); 1376 1448 } 1377 1449 … … 1391 1463 1392 1464 #ifdef HDIO_DRIVE_CMD 1393 static void interpret_standby(unsigned standby) 1394 { 1395 unsigned t; 1396 1465 static void interpret_standby(uint8_t standby) 1466 { 1397 1467 printf(" ("); 1398 if (standby == 0) 1468 if (standby == 0) { 1399 1469 printf("off"); 1400 else if (standby == 252) 1401 printf("21 minutes"); 1402 else if (standby == 253) 1470 } else if (standby <= 240 || standby == 252 || standby == 255) { 1471 /* standby is in 5 sec units */ 1472 unsigned t = standby * 5; 1473 printf("%u minutes %u seconds", t / 60, t % 60); 1474 } else if (standby <= 251) { 1475 unsigned t = (standby - 240); /* t is in 30 min units */; 1476 printf("%u.%c hours", t / 2, (t & 1) ? '5' : '0'); 1477 } 1478 if (standby == 253) 1403 1479 printf("vendor-specific"); 1404 else if (standby == 254) 1405 printf("Reserved"); 1406 else if (standby == 255) 1407 printf("21 minutes + 15 seconds"); 1408 else if (standby <= 240) { 1409 t = standby * 5; 1410 printf("%u minutes + %u seconds", t / 60, t % 60); 1411 } else if (standby <= 251) { 1412 t = (standby - 240) * 30; 1413 printf("%u hours + %u minutes", t / 60, t % 60); 1414 } else 1415 printf("illegal value"); 1480 if (standby == 254) 1481 printf("reserved"); 1416 1482 printf(")\n"); 1417 1483 } … … 1433 1499 static int translate_xfermode(const char *name) 1434 1500 { 1435 int val, i; 1501 int val; 1502 unsigned i; 1436 1503 1437 1504 for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) { … … 1463 1530 printf("UltraDMA mode%u", xfermode - 64); 1464 1531 else 1465 printf(" Unknown");1532 printf("unknown"); 1466 1533 printf(")\n"); 1467 1534 } … … 1476 1543 static void process_dev(char *devname) 1477 1544 { 1478 int fd;1545 /*int fd;*/ 1479 1546 long parm, multcount; 1480 1547 #ifndef HDIO_DRIVE_CMD … … 1486 1553 const char *fmt = " %s\t= %2ld"; 1487 1554 1488 fd = xopen(devname, O_RDONLY|O_NONBLOCK); 1555 /*fd = xopen_nonblocking(devname);*/ 1556 xmove_fd(xopen_nonblocking(devname), fd); 1489 1557 printf("\n%s:\n", devname); 1490 1558 1491 if ( set_readahead) {1492 print_flag(get _readahead, "fs readahead", Xreadahead);1559 if (getset_readahead == IS_SET) { 1560 print_flag(getset_readahead, "fs readahead", Xreadahead); 1493 1561 ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead); 1494 1562 } … … 1500 1568 #endif 1501 1569 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF 1502 if (scan_hwif ) {1570 if (scan_hwif == IS_SET) { 1503 1571 printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq); 1504 1572 args[0] = hwif_data; … … 1524 1592 ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode); 1525 1593 } 1526 if ( set_io32bit) {1527 print_flag(get _io32bit, "32-bit IO_support flag", io32bit);1594 if (getset_io32bit == IS_SET) { 1595 print_flag(getset_io32bit, "32-bit IO_support flag", io32bit); 1528 1596 ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit); 1529 1597 } 1530 if ( set_mult) {1531 print_flag(get _mult, "multcount", mult);1598 if (getset_mult == IS_SET) { 1599 print_flag(getset_mult, "multcount", mult); 1532 1600 #ifdef HDIO_DRIVE_CMD 1533 1601 ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult); … … 1536 1604 #endif 1537 1605 } 1538 if ( set_readonly) {1539 print_flag_on_off(get _readonly, "readonly", readonly);1606 if (getset_readonly == IS_SET) { 1607 print_flag_on_off(getset_readonly, "readonly", readonly); 1540 1608 ioctl_or_warn(fd, BLKROSET, &readonly); 1541 1609 } 1542 if ( set_unmask) {1543 print_flag_on_off(get _unmask, "unmaskirq", unmask);1610 if (getset_unmask == IS_SET) { 1611 print_flag_on_off(getset_unmask, "unmaskirq", unmask); 1544 1612 ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask); 1545 1613 } 1546 1614 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA 1547 if ( set_dma) {1548 print_flag_on_off(get _dma, "using_dma", dma);1615 if (getset_dma == IS_SET) { 1616 print_flag_on_off(getset_dma, "using_dma", dma); 1549 1617 ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma); 1550 1618 } 1551 1619 #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */ 1552 if (set_dma_q) { 1553 print_flag_on_off(get_dma_q, "DMA queue_depth", dma_q); 1620 #ifdef HDIO_SET_QDMA 1621 if (getset_dma_q == IS_SET) { 1622 print_flag_on_off(getset_dma_q, "DMA queue_depth", dma_q); 1554 1623 ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q); 1555 1624 } 1556 if (set_nowerr) { 1557 print_flag_on_off(get_nowerr, "nowerr", nowerr); 1625 #endif 1626 if (getset_nowerr == IS_SET) { 1627 print_flag_on_off(getset_nowerr, "nowerr", nowerr); 1558 1628 ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr); 1559 1629 } 1560 if ( set_keep) {1561 print_flag_on_off(get _keep, "keep_settings", keep);1630 if (getset_keep == IS_SET) { 1631 print_flag_on_off(getset_keep, "keep_settings", keep); 1562 1632 ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep); 1563 1633 } 1564 1634 #ifdef HDIO_DRIVE_CMD 1565 if ( set_doorlock) {1635 if (getset_doorlock == IS_SET) { 1566 1636 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK; 1567 1637 args[2] = 0; 1568 print_flag_on_off(get _doorlock, "drive doorlock", doorlock);1638 print_flag_on_off(getset_doorlock, "drive doorlock", doorlock); 1569 1639 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1570 1640 args[0] = WIN_SETFEATURES; 1571 1641 } 1572 if ( set_dkeep) {1642 if (getset_dkeep == IS_SET) { 1573 1643 /* lock/unlock the drive's "feature" settings */ 1574 print_flag_on_off(get _dkeep, "drive keep features", dkeep);1644 print_flag_on_off(getset_dkeep, "drive keep features", dkeep); 1575 1645 args[2] = dkeep ? 0x66 : 0xcc; 1576 1646 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1577 1647 } 1578 if ( set_defects) {1648 if (getset_defects == IS_SET) { 1579 1649 args[2] = defects ? 0x04 : 0x84; 1580 print_flag(get _defects, "drive defect-mgmt", defects);1650 print_flag(getset_defects, "drive defect-mgmt", defects); 1581 1651 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1582 1652 } 1583 if ( set_prefetch) {1653 if (getset_prefetch == IS_SET) { 1584 1654 args[1] = prefetch; 1585 1655 args[2] = 0xab; 1586 print_flag(get _prefetch, "drive prefetch", prefetch);1656 print_flag(getset_prefetch, "drive prefetch", prefetch); 1587 1657 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1588 1658 args[1] = 0; … … 1591 1661 args[1] = xfermode_requested; 1592 1662 args[2] = 3; 1593 if (get_xfermode) { 1594 print_flag(1, "xfermode", xfermode_requested); 1595 interpret_xfermode(xfermode_requested); 1596 } 1663 print_flag(1, "xfermode", xfermode_requested); 1664 interpret_xfermode(xfermode_requested); 1597 1665 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1598 1666 args[1] = 0; 1599 1667 } 1600 if ( set_lookahead) {1668 if (getset_lookahead == IS_SET) { 1601 1669 args[2] = lookahead ? 0xaa : 0x55; 1602 print_flag_on_off(get _lookahead, "drive read-lookahead", lookahead);1670 print_flag_on_off(getset_lookahead, "drive read-lookahead", lookahead); 1603 1671 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1604 1672 } 1605 if (set_apmmode) { 1606 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */; /* feature register */ 1673 if (getset_apmmode == IS_SET) { 1674 /* feature register */ 1675 args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */; 1607 1676 args[1] = apmmode; /* sector count register 1-255 */ 1608 if (get_apmmode) 1609 printf(" setting APM level to %s 0x%02lX (%ld)\n", (apmmode == 255) ? "disabled" : "", apmmode, apmmode); 1677 printf(" setting APM level to %s 0x%02lX (%ld)\n", 1678 (apmmode == 255) ? "disabled" : "", 1679 apmmode, apmmode); 1610 1680 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1611 1681 args[1] = 0; 1612 1682 } 1613 if ( set_wcache){1683 if (getset_wcache == IS_SET) { 1614 1684 #ifdef DO_FLUSHCACHE 1615 1685 #ifndef WIN_FLUSHCACHE 1616 1686 #define WIN_FLUSHCACHE 0xe7 1617 1687 #endif 1618 static unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };1619 1688 #endif /* DO_FLUSHCACHE */ 1620 1689 args[2] = wcache ? 0x02 : 0x82; 1621 print_flag_on_off(get _wcache, "drive write-caching", wcache);1690 print_flag_on_off(getset_wcache, "drive write-caching", wcache); 1622 1691 #ifdef DO_FLUSHCACHE 1623 1692 if (!wcache) … … 1642 1711 #define WIN_STANDBYNOW2 0x94 1643 1712 #endif 1644 if (get_standbynow)printf(" issuing standby command\n");1713 printf(" issuing standby command\n"); 1645 1714 args[0] = WIN_STANDBYNOW1; 1646 ioctl_alt_or_warn( fd,HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);1715 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2); 1647 1716 } 1648 1717 if (set_sleepnow) { … … 1653 1722 #define WIN_SLEEPNOW2 0x99 1654 1723 #endif 1655 if (get_sleepnow)printf(" issuing sleep command\n");1724 printf(" issuing sleep command\n"); 1656 1725 args[0] = WIN_SLEEPNOW1; 1657 ioctl_alt_or_warn( fd,HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);1726 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2); 1658 1727 } 1659 1728 if (set_seagate) { 1660 1729 args[0] = 0xfb; 1661 if (get_seagate)printf(" disabling Seagate auto powersaving mode\n");1730 printf(" disabling Seagate auto powersaving mode\n"); 1662 1731 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1663 1732 } 1664 if ( set_standby) {1733 if (getset_standby == IS_SET) { 1665 1734 args[0] = WIN_SETIDLE1; 1666 1735 args[1] = standby_requested; 1667 if (get_standby) { 1668 print_flag(1, "standby", standby_requested); 1669 interpret_standby(standby_requested); 1670 } 1736 print_flag(1, "standby", standby_requested); 1737 interpret_standby(standby_requested); 1671 1738 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1672 1739 args[1] = 0; … … 1675 1742 if (force_operation) { 1676 1743 char buf[512]; 1677 flush_buffer_cache( fd);1744 flush_buffer_cache(); 1678 1745 if (-1 == read(fd, buf, sizeof(buf))) 1679 bb_perror_msg("read(%d bytes) failed (rc=%d)", sizeof(buf), -1); 1680 } 1681 #endif /* HDIO_DRIVE_CMD */ 1682 1683 if (get_mult || get_identity) { 1746 bb_perror_msg("read of 512 bytes failed"); 1747 } 1748 #endif /* HDIO_DRIVE_CMD */ 1749 if (getset_mult || get_identity) { 1684 1750 multcount = -1; 1685 1751 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) { 1686 if (get_mult && ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn. */ 1752 /* To be coherent with ioctl_or_warn. */ 1753 if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR) 1687 1754 bb_perror_msg("HDIO_GET_MULTCOUNT"); 1688 1755 else 1689 1756 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT); 1690 } else if (get _mult) {1757 } else if (getset_mult) { 1691 1758 printf(fmt, "multcount", multcount); 1692 1759 on_off(multcount != 0); 1693 1760 } 1694 1761 } 1695 if (get _io32bit) {1762 if (getset_io32bit) { 1696 1763 if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) { 1697 1764 printf(" IO_support\t=%3ld (", parm); … … 1710 1777 } 1711 1778 } 1712 if (get _unmask) {1713 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, (unsigned long *)parm))1779 if (getset_unmask) { 1780 if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm)) 1714 1781 print_value_on_off("unmaskirq", parm); 1715 1782 } 1716 1717 1718 1783 #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA 1719 if (get _dma) {1784 if (getset_dma) { 1720 1785 if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) { 1721 1786 printf(fmt, "using_dma", parm); … … 1727 1792 } 1728 1793 #endif 1729 if (get_dma_q) { 1730 if(!ioctl_or_warn(fd, HDIO_GET_QDMA, (unsigned long *)parm)) 1794 #ifdef HDIO_GET_QDMA 1795 if (getset_dma_q) { 1796 if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm)) 1731 1797 print_value_on_off("queue_depth", parm); 1732 1798 } 1733 if (get_keep) { 1734 if(!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, (unsigned long *)parm)) 1799 #endif 1800 if (getset_keep) { 1801 if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm)) 1735 1802 print_value_on_off("keepsettings", parm); 1736 1803 } 1737 1738 if (get_nowerr) { 1739 if(!ioctl_or_warn(fd, HDIO_GET_NOWERR, (unsigned long *)parm)) 1804 if (getset_nowerr) { 1805 if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm)) 1740 1806 print_value_on_off("nowerr", parm); 1741 1807 } 1742 if (get _readonly) {1743 if (!ioctl_or_warn(fd, BLKROGET, (unsigned long *)parm))1808 if (getset_readonly) { 1809 if (!ioctl_or_warn(fd, BLKROGET, &parm)) 1744 1810 print_value_on_off("readonly", parm); 1745 1811 } 1746 if (get _readahead) {1747 if (!ioctl_or_warn(fd, BLKRAGET, (unsigned long *)parm))1812 if (getset_readahead) { 1813 if (!ioctl_or_warn(fd, BLKRAGET, &parm)) 1748 1814 print_value_on_off("readahead", parm); 1749 1815 } … … 1754 1820 if (!ioctl_or_warn(fd, HDIO_GETGEO, &g)) 1755 1821 printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n", 1756 1822 g.cylinders, g.heads, g.sectors, parm, g.start); 1757 1823 } 1758 1824 } … … 1768 1834 1769 1835 args[0] = WIN_CHECKPOWERMODE1; 1770 if (ioctl_alt_or_warn( fd,HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {1836 if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) { 1771 1837 if (errno != EIO || args[0] != 0 || args[1] != 0) 1772 1838 state = "unknown"; … … 1817 1883 args1[0] = WIN_IDENTIFY; 1818 1884 args1[3] = 1; 1819 if (!ioctl_alt_or_warn( fd,HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))1885 if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY)) 1820 1886 identify((void *)(args1 + 4)); 1821 1887 } 1822 1888 #endif 1823 1889 #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF 1824 if (set_busstate) { 1825 if (get_busstate) { 1826 print_flag(1, "bus state", busstate); 1827 bus_state_value(busstate); 1828 } 1890 if (getset_busstate == IS_SET) { 1891 print_flag(1, "bus state", busstate); 1892 bus_state_value(busstate); 1829 1893 ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate); 1830 1894 } 1831 if (get _busstate) {1895 if (getset_busstate) { 1832 1896 if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) { 1833 1897 printf(fmt, "bus state", parm); … … 1840 1904 1841 1905 if (do_ctimings) 1842 do_time( 0, fd); /* time cache */1906 do_time(1 /*,fd*/); /* time cache */ 1843 1907 if (do_timings) 1844 do_time( 1, fd); /* time device */1908 do_time(0 /*,fd*/); /* time device */ 1845 1909 if (do_flush) 1846 flush_buffer_cache( fd);1910 flush_buffer_cache(); 1847 1911 close(fd); 1848 1912 } … … 1858 1922 } 1859 1923 1924 static void identify_from_stdin(void) NORETURN; 1860 1925 static void identify_from_stdin(void) 1861 1926 { … … 1865 1930 int i; 1866 1931 1867 xread( 0, buf, 1280);1932 xread(STDIN_FILENO, buf, 1280); 1868 1933 1869 1934 // Convert the newline-separated hex data into an identify block. … … 1879 1944 identify(sbuf); 1880 1945 } 1946 #else 1947 void identify_from_stdin(void); 1881 1948 #endif 1882 1949 1883 1950 /* busybox specific stuff */ 1884 static void parse_opts(smallint *get, smallint *set, unsigned long *value, int min, int max) 1885 { 1886 if (get) { 1887 *get = 1; 1888 } 1951 static int parse_opts(unsigned long *value, int min, int max) 1952 { 1889 1953 if (optarg) { 1890 *set = 1;1891 1954 *value = xatol_range(optarg, min, max); 1892 } 1955 return IS_SET; 1956 } 1957 return IS_GET; 1958 } 1959 static int parse_opts_0_max(unsigned long *value, int max) 1960 { 1961 return parse_opts(value, 0, max); 1962 } 1963 static int parse_opts_0_1(unsigned long *value) 1964 { 1965 return parse_opts(value, 0, 1); 1966 } 1967 static int parse_opts_0_INTMAX(unsigned long *value) 1968 { 1969 return parse_opts(value, 0, INT_MAX); 1893 1970 } 1894 1971 … … 1896 1973 { 1897 1974 if (flag) { 1898 *get = 1;1975 *get = IS_GET; 1899 1976 if (optarg) { 1900 1977 *value = translate_xfermode(optarg); … … 1906 1983 /*------- getopt short options --------*/ 1907 1984 static const char hdparm_options[] ALIGN1 = 1908 "gfu::n::p:r::m::c::k::a::B:tT h"1909 USE_FEATURE_HDPARM_GET_IDENTITY("iI")1910 USE_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")1985 "gfu::n::p:r::m::c::k::a::B:tT" 1986 IF_FEATURE_HDPARM_GET_IDENTITY("iI") 1987 IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::") 1911 1988 #ifdef HDIO_DRIVE_CMD 1912 1989 "S:D:P:X:K:A:L:W:CyYzZ" 1913 1990 #endif 1914 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")1991 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:") 1915 1992 #ifdef HDIO_GET_QDMA 1916 1993 #ifdef HDIO_SET_QDMA … … 1920 1997 #endif 1921 1998 #endif 1922 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")1923 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")1924 USE_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");1999 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w") 2000 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:") 2001 IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:"); 1925 2002 /*-------------------------------------*/ 1926 2003 1927 2004 /* our main() routine: */ 1928 int hdparm_main(int argc, char **argv) ;2005 int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1929 2006 int hdparm_main(int argc, char **argv) 1930 2007 { … … 1934 2011 while ((c = getopt(argc, argv, hdparm_options)) >= 0) { 1935 2012 flagcount++; 1936 if (c == 'h') bb_show_usage(); /* EXIT */ 1937 USE_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I')); 1938 USE_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i')); 2013 IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I')); 2014 IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i')); 1939 2015 get_geom |= (c == 'g'); 1940 2016 do_flush |= (c == 'f'); 1941 if (c == 'u') parse_opts(&get_unmask, &set_unmask, &unmask, 0, 1); 1942 USE_FEATURE_HDPARM_HDIO_GETSET_DMA(if (c == 'd') parse_opts(&get_dma, &set_dma, &dma, 0, 9)); 1943 if (c == 'n') parse_opts(&get_nowerr, &set_nowerr, &nowerr, 0, 1); 2017 if (c == 'u') getset_unmask = parse_opts_0_1(&unmask); 2018 IF_FEATURE_HDPARM_HDIO_GETSET_DMA( 2019 if (c == 'd') getset_dma = parse_opts_0_max(&dma, 9); 2020 ) 2021 if (c == 'n') getset_nowerr = parse_opts_0_1(&nowerr); 1944 2022 parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode); 1945 if (c == 'r') parse_opts(&get_readonly, &set_readonly, &readonly, 0, 1);1946 if (c == 'm') parse_opts(&get_mult, &set_mult, &mult, 0, INT_MAX/*32*/);1947 if (c == 'c') parse_opts(&get_io32bit, &set_io32bit, &io32bit, 0, INT_MAX/*8*/);1948 if (c == 'k') parse_opts(&get_keep, &set_keep, &keep, 0, 1);1949 if (c == 'a') parse_opts(&get_readahead, &set_readahead, &Xreadahead, 0, INT_MAX);1950 if (c == 'B') parse_opts(&get_apmmode, &set_apmmode,&apmmode, 1, 255);2023 if (c == 'r') getset_readonly = parse_opts_0_1(&readonly); 2024 if (c == 'm') getset_mult = parse_opts_0_INTMAX(&mult /*32*/); 2025 if (c == 'c') getset_io32bit = parse_opts_0_INTMAX(&io32bit /*8*/); 2026 if (c == 'k') getset_keep = parse_opts_0_1(&keep); 2027 if (c == 'a') getset_readahead = parse_opts_0_INTMAX(&Xreadahead); 2028 if (c == 'B') getset_apmmode = parse_opts(&apmmode, 1, 255); 1951 2029 do_flush |= do_timings |= (c == 't'); 1952 2030 do_flush |= do_ctimings |= (c == 'T'); 1953 2031 #ifdef HDIO_DRIVE_CMD 1954 if (c == 'S') parse_opts(&get_standby, &set_standby, &standby_requested, 0, INT_MAX);1955 if (c == 'D') parse_opts(&get_defects, &set_defects, &defects, 0, INT_MAX);1956 if (c == 'P') parse_opts(&get_prefetch, &set_prefetch, &prefetch, 0, INT_MAX);2032 if (c == 'S') getset_standby = parse_opts_0_max(&standby_requested, 255); 2033 if (c == 'D') getset_defects = parse_opts_0_INTMAX(&defects); 2034 if (c == 'P') getset_prefetch = parse_opts_0_INTMAX(&prefetch); 1957 2035 parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested); 1958 if (c == 'K') parse_opts(&get_dkeep, &set_dkeep, &prefetch, 0, 1);1959 if (c == 'A') parse_opts(&get_lookahead, &set_lookahead, &lookahead, 0, 1);1960 if (c == 'L') parse_opts(&get_doorlock, &set_doorlock, &doorlock, 0, 1);1961 if (c == 'W') parse_opts(&get_wcache, &set_wcache, &wcache, 0, 1);2036 if (c == 'K') getset_dkeep = parse_opts_0_1(&prefetch); 2037 if (c == 'A') getset_lookahead = parse_opts_0_1(&lookahead); 2038 if (c == 'L') getset_doorlock = parse_opts_0_1(&doorlock); 2039 if (c == 'W') getset_wcache = parse_opts_0_1(&wcache); 1962 2040 get_powermode |= (c == 'C'); 1963 get_standbynow =set_standbynow |= (c == 'y');1964 get_sleepnow =set_sleepnow |= (c == 'Y');2041 set_standbynow |= (c == 'y'); 2042 set_sleepnow |= (c == 'Y'); 1965 2043 reread_partn |= (c == 'z'); 1966 get_seagate =set_seagate |= (c == 'Z');1967 #endif 1968 USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') parse_opts(NULL, &unregister_hwif, &hwif, 0, INT_MAX));2044 set_seagate |= (c == 'Z'); 2045 #endif 2046 IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') unregister_hwif = parse_opts_0_INTMAX(&hwif)); 1969 2047 #ifdef HDIO_GET_QDMA 1970 2048 if (c == 'Q') { 1971 #ifdef HDIO_SET_QDMA 1972 parse_opts(&get_dma_q, &set_dma_q, &dma_q, 0, INT_MAX); 1973 #else 1974 parse_opts(&get_dma_q, NULL, NULL, 0, 0); 1975 #endif 1976 } 1977 #endif 1978 USE_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r')); 1979 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') parse_opts(NULL, &perform_tristate, &tristate, 0, 1)); 1980 USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') parse_opts(&get_busstate, &set_busstate, &busstate, 0, 2)); 2049 getset_dma_q = parse_opts_0_INTMAX(&dma_q); 2050 } 2051 #endif 2052 IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r')); 2053 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') perform_tristate = parse_opts_0_1(&tristate)); 2054 IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') getset_busstate = parse_opts_0_max(&busstate, 2)); 1981 2055 #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF 1982 2056 if (c == 'R') { 1983 parse_opts(NULL, &scan_hwif, &hwif_data, 0, INT_MAX);1984 hwif_ctrl = xatoi_ u((argv[optind]) ? argv[optind] : "");1985 hwif_irq = xatoi_ u((argv[optind+1]) ? argv[optind+1] : "");2057 scan_hwif = parse_opts_0_INTMAX(&hwif_data); 2058 hwif_ctrl = xatoi_positive((argv[optind]) ? argv[optind] : ""); 2059 hwif_irq = xatoi_positive((argv[optind+1]) ? argv[optind+1] : ""); 1986 2060 /* Move past the 2 additional arguments */ 1987 2061 argv += 2; … … 1992 2066 /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */ 1993 2067 if (!flagcount) { 1994 get _mult = get_io32bit = get_unmask = get_keep = get_readonly = get_readahead = get_geom = 1;1995 USE_FEATURE_HDPARM_HDIO_GETSET_DMA(get_dma = 1);2068 getset_mult = getset_io32bit = getset_unmask = getset_keep = getset_readonly = getset_readahead = get_geom = IS_GET; 2069 IF_FEATURE_HDPARM_HDIO_GETSET_DMA(getset_dma = IS_GET); 1996 2070 } 1997 2071 argv += optind; … … 2000 2074 if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO)) 2001 2075 identify_from_stdin(); /* EXIT */ 2002 elsebb_show_usage();2076 bb_show_usage(); 2003 2077 } 2004 2078
Note:
See TracChangeset
for help on using the changeset viewer.