diff options
author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-05-22 21:46:11 +0000 |
---|---|---|
committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-05-22 21:46:11 +0000 |
commit | 0cb21f3a49d93ea4c502626ca65d373fa9c240ac (patch) | |
tree | 361baf533faf6e73043d1b5b639d215a2060af8a | |
parent | 2ca038f79ca5b9e1830a20bf8314021123f8d95c (diff) | |
download | busybox-w32-0cb21f3a49d93ea4c502626ca65d373fa9c240ac.tar.gz busybox-w32-0cb21f3a49d93ea4c502626ca65d373fa9c240ac.tar.bz2 busybox-w32-0cb21f3a49d93ea4c502626ca65d373fa9c240ac.zip |
hdparm: make -T -t code smaller (-194 bytes), and output prettier
git-svn-id: svn://busybox.net/trunk/busybox@18669 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | miscutils/hdparm.c | 172 |
1 files changed, 75 insertions, 97 deletions
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index c540ff93c..0a689d87e 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c | |||
@@ -393,26 +393,26 @@ void identify_from_stdin(void); | |||
393 | */ | 393 | */ |
394 | 394 | ||
395 | /* words 89, 90, SECU ERASE TIME */ | 395 | /* words 89, 90, SECU ERASE TIME */ |
396 | #define ERASE_BITS 0x00ff | 396 | #define ERASE_BITS 0x00ff |
397 | 397 | ||
398 | /* word 92: master password revision */ | 398 | /* word 92: master password revision */ |
399 | /* NOVAL_0 or NOVAL_1 means no support for master password revision */ | 399 | /* NOVAL_0 or NOVAL_1 means no support for master password revision */ |
400 | 400 | ||
401 | /* word 93: hw reset result */ | 401 | /* word 93: hw reset result */ |
402 | #define CBLID 0x2000 /* CBLID status */ | 402 | #define CBLID 0x2000 /* CBLID status */ |
403 | #define RST0 0x0001 /* 1=reset to device #0 */ | 403 | #define RST0 0x0001 /* 1=reset to device #0 */ |
404 | #define DEV_DET 0x0006 /* how device num determined */ | 404 | #define DEV_DET 0x0006 /* how device num determined */ |
405 | #define JUMPER_VAL 0x0002 /* device num determined by jumper */ | 405 | #define JUMPER_VAL 0x0002 /* device num determined by jumper */ |
406 | #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */ | 406 | #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */ |
407 | 407 | ||
408 | /* word 127: removable media status notification feature set support */ | 408 | /* word 127: removable media status notification feature set support */ |
409 | #define RM_STAT_BITS 0x0003 | 409 | #define RM_STAT_BITS 0x0003 |
410 | #define RM_STAT_SUP 0x0001 | 410 | #define RM_STAT_SUP 0x0001 |
411 | 411 | ||
412 | /* word 128: security */ | 412 | /* word 128: security */ |
413 | #define SECU_ENABLED 0x0002 | 413 | #define SECU_ENABLED 0x0002 |
414 | #define SECU_LEVEL 0x0010 | 414 | #define SECU_LEVEL 0x0010 |
415 | #define NUM_SECU_STR 6 | 415 | #define NUM_SECU_STR 6 |
416 | #if ENABLE_FEATURE_HDPARM_GET_IDENTITY | 416 | #if ENABLE_FEATURE_HDPARM_GET_IDENTITY |
417 | static const char * const secu_str[] = { | 417 | static const char * const secu_str[] = { |
418 | "supported", /* word 128, bit 0 */ | 418 | "supported", /* word 128, bit 0 */ |
@@ -425,22 +425,21 @@ static const char * const secu_str[] = { | |||
425 | #endif | 425 | #endif |
426 | 426 | ||
427 | /* word 160: CFA power mode */ | 427 | /* word 160: CFA power mode */ |
428 | #define VALID_W160 0x8000 /* 1=word valid */ | 428 | #define VALID_W160 0x8000 /* 1=word valid */ |
429 | #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/ | 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 */ | 430 | #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */ |
431 | #define MAX_AMPS 0x0fff /* value = max current in ma */ | 431 | #define MAX_AMPS 0x0fff /* value = max current in ma */ |
432 | 432 | ||
433 | /* word 255: integrity */ | 433 | /* word 255: integrity */ |
434 | #define SIG 0x00ff /* signature location */ | 434 | #define SIG 0x00ff /* signature location */ |
435 | #define SIG_VAL 0x00A5 /* signature value */ | 435 | #define SIG_VAL 0x00a5 /* signature value */ |
436 | 436 | ||
437 | #define TIMING_MB 64 | 437 | #define TIMING_MB 64 |
438 | #define TIMING_BUF_MB 1 | 438 | #define TIMING_BUF_MB 1 |
439 | #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024) | 439 | #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024) |
440 | #define TIMING_BUF_COUNT (timing_MB / TIMING_BUF_MB) | 440 | #define BUFCACHE_FACTOR 2 |
441 | #define BUFCACHE_FACTOR 2 | ||
442 | 441 | ||
443 | #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */ | 442 | #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */ |
444 | 443 | ||
445 | /* Busybox messages and functions */ | 444 | /* Busybox messages and functions */ |
446 | static int bb_ioctl(int fd, int request, void *argp, const char *string) | 445 | static int bb_ioctl(int fd, int request, void *argp, const char *string) |
@@ -775,7 +774,7 @@ static void identify(uint16_t *id_supplied) | |||
775 | bbbig = (uint64_t)val[LBA_64_MSB] << 48 | | 774 | bbbig = (uint64_t)val[LBA_64_MSB] << 48 | |
776 | (uint64_t)val[LBA_48_MSB] << 32 | | 775 | (uint64_t)val[LBA_48_MSB] << 32 | |
777 | (uint64_t)val[LBA_MID] << 16 | | 776 | (uint64_t)val[LBA_MID] << 16 | |
778 | val[LBA_LSB] ; | 777 | val[LBA_LSB]; |
779 | printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig); | 778 | printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig); |
780 | } | 779 | } |
781 | 780 | ||
@@ -916,7 +915,7 @@ static void identify(uint16_t *id_supplied) | |||
916 | * than n (e.g. 3, 2, 1 and 0). Print all the modes. */ | 915 | * than n (e.g. 3, 2, 1 and 0). Print all the modes. */ |
917 | if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) { | 916 | if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) { |
918 | jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007; | 917 | jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007; |
919 | for (ii = 0; ii <= PIO_MODE_MAX ; ii++) { | 918 | for (ii = 0; ii <= PIO_MODE_MAX; ii++) { |
920 | if (jj & 0x0001) printf("pio%d ", ii); | 919 | if (jj & 0x0001) printf("pio%d ", ii); |
921 | jj >>=1; | 920 | jj >>=1; |
922 | } | 921 | } |
@@ -1246,7 +1245,7 @@ static void dump_identity(const struct hd_driveid *id) | |||
1246 | static void flush_buffer_cache(int fd) | 1245 | static void flush_buffer_cache(int fd) |
1247 | { | 1246 | { |
1248 | fsync(fd); /* flush buffers */ | 1247 | fsync(fd); /* flush buffers */ |
1249 | bb_ioctl(fd, BLKFLSBUF, NULL, "BLKFLSBUF") ;/* do it again, big time */ | 1248 | bb_ioctl(fd, BLKFLSBUF, NULL, "BLKFLSBUF"); /* do it again, big time */ |
1250 | #ifdef HDIO_DRIVE_CMD | 1249 | #ifdef HDIO_DRIVE_CMD |
1251 | sleep(1); | 1250 | sleep(1); |
1252 | if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) /* await completion */ | 1251 | if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) /* await completion */ |
@@ -1276,14 +1275,6 @@ static int read_big_block(int fd, char *buf) | |||
1276 | return 0; | 1275 | return 0; |
1277 | } | 1276 | } |
1278 | 1277 | ||
1279 | static void print_timing(int t, double e) | ||
1280 | { | ||
1281 | if (t >= e) /* more than 1MB/s */ | ||
1282 | printf("%2d MB in %5.2f seconds =%6.2f %cB/sec\n", t, e, t / e, 'M'); | ||
1283 | else | ||
1284 | printf("%2d MB in %5.2f seconds =%6.2f %cB/sec\n", t, e, t / e * 1024, 'k'); | ||
1285 | } | ||
1286 | |||
1287 | static int do_blkgetsize(int fd, unsigned long long *blksize64) | 1278 | static int do_blkgetsize(int fd, unsigned long long *blksize64) |
1288 | { | 1279 | { |
1289 | int rc; | 1280 | int rc; |
@@ -1300,17 +1291,22 @@ static int do_blkgetsize(int fd, unsigned long long *blksize64) | |||
1300 | return rc; | 1291 | return rc; |
1301 | } | 1292 | } |
1302 | 1293 | ||
1294 | static void print_timing(unsigned t, double e) | ||
1295 | { | ||
1296 | if (t >= e) /* more than 1MB/s */ | ||
1297 | printf("%4d MB in %.2f seconds = %.2f %cB/sec\n", t, e, t / e, 'M'); | ||
1298 | else | ||
1299 | printf("%4d MB in %.2f seconds = %.2f %cB/sec\n", t, e, t / e * 1024, 'k'); | ||
1300 | } | ||
1301 | |||
1303 | static void do_time(int flag, int fd) | 1302 | static void do_time(int flag, int fd) |
1304 | /* | 1303 | /* flag = 0 time_cache, 1 time_device */ |
1305 | flag = 0 time_cache | ||
1306 | flag = 1 time_device | ||
1307 | */ | ||
1308 | { | 1304 | { |
1309 | static const struct itimerval thousand = {{1000, 0}, {1000, 0}}; | 1305 | static const struct itimerval thousand = {{1000, 0}, {1000, 0}}; |
1310 | 1306 | ||
1311 | struct itimerval e1, e2; | 1307 | struct itimerval itv; |
1312 | double elapsed, elapsed2; | 1308 | unsigned elapsed, elapsed2; |
1313 | unsigned max_iterations = 1024, total_MB, iterations; | 1309 | unsigned max_iterations, total_MB, iterations; |
1314 | unsigned long long blksize; | 1310 | unsigned long long blksize; |
1315 | RESERVE_CONFIG_BUFFER(buf, TIMING_BUF_BYTES); | 1311 | RESERVE_CONFIG_BUFFER(buf, TIMING_BUF_BYTES); |
1316 | 1312 | ||
@@ -1319,78 +1315,60 @@ static void do_time(int flag, int fd) | |||
1319 | goto quit2; | 1315 | goto quit2; |
1320 | } | 1316 | } |
1321 | 1317 | ||
1318 | max_iterations = 1024; | ||
1322 | if (0 == do_blkgetsize(fd, &blksize)) { | 1319 | if (0 == do_blkgetsize(fd, &blksize)) { |
1323 | max_iterations = blksize / (2 * 1024) / TIMING_BUF_MB; | 1320 | max_iterations = blksize / (2 * 1024) / TIMING_BUF_MB; |
1324 | } | 1321 | } |
1325 | 1322 | ||
1326 | /* Clear out the device request queues & give them time to complete */ | 1323 | /* Clear out the device request queues & give them time to complete */ |
1327 | sync(); | 1324 | sync(); |
1328 | sleep(3); | 1325 | sleep(2); |
1329 | 1326 | if (flag == 0) { /* Time cache */ | |
1327 | if (seek_to_zero(fd)) | ||
1328 | goto quit; | ||
1329 | if (read_big_block(fd, buf)) | ||
1330 | goto quit; | ||
1331 | printf(" Timing buffer-cache reads: "); | ||
1332 | } else { /* Time device */ | ||
1333 | printf(" Timing buffered disk reads: "); | ||
1334 | } | ||
1335 | fflush(stdout); | ||
1336 | iterations = 0; | ||
1337 | /* | ||
1338 | * getitimer() is used rather than gettimeofday() because | ||
1339 | * it is much more consistent (on my machine, at least). | ||
1340 | */ | ||
1330 | setitimer(ITIMER_REAL, &thousand, NULL); | 1341 | setitimer(ITIMER_REAL, &thousand, NULL); |
1331 | 1342 | /* Now do the timing */ | |
1332 | if (flag == 0) { | 1343 | do { |
1333 | /* Time cache */ | 1344 | ++iterations; |
1334 | 1345 | if ((flag == 0) && seek_to_zero(fd)) | |
1335 | if (seek_to_zero(fd)) return; | 1346 | goto quit; |
1336 | if (read_big_block(fd, buf)) return; | 1347 | if (read_big_block(fd, buf)) |
1337 | printf(" Timing cached reads: "); | 1348 | goto quit; |
1338 | fflush(stdout); | 1349 | getitimer(ITIMER_REAL, &itv); |
1339 | 1350 | elapsed = (1000 - itv.it_value.tv_sec) * 1000000 | |
1340 | /* Now do the timing */ | 1351 | - itv.it_value.tv_usec; |
1341 | iterations = 0; | 1352 | } while (elapsed < 3000000 && iterations < max_iterations); |
1342 | getitimer(ITIMER_REAL, &e1); | 1353 | total_MB = iterations * TIMING_BUF_MB; |
1343 | do { | 1354 | if (flag == 0) { |
1344 | ++iterations; | ||
1345 | if (seek_to_zero(fd) || read_big_block(fd, buf)) | ||
1346 | goto quit; | ||
1347 | getitimer(ITIMER_REAL, &e2); | ||
1348 | elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec) | ||
1349 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); | ||
1350 | } while (elapsed < 2.0); | ||
1351 | total_MB = iterations * TIMING_BUF_MB; | ||
1352 | |||
1353 | /* Now remove the lseek() and getitimer() overheads from the elapsed time */ | 1355 | /* Now remove the lseek() and getitimer() overheads from the elapsed time */ |
1354 | getitimer(ITIMER_REAL, &e1); | 1356 | setitimer(ITIMER_REAL, &thousand, NULL); |
1355 | do { | 1357 | do { |
1356 | if (seek_to_zero(fd)) | 1358 | if (seek_to_zero(fd)) |
1357 | goto quit; | 1359 | goto quit; |
1358 | getitimer(ITIMER_REAL, &e2); | 1360 | getitimer(ITIMER_REAL, &itv); |
1359 | elapsed2 = (e1.it_value.tv_sec - e2.it_value.tv_sec) | 1361 | elapsed2 = (1000 - itv.it_value.tv_sec) * 1000000 |
1360 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); | 1362 | - itv.it_value.tv_usec; |
1361 | } while (--iterations); | 1363 | } while (--iterations); |
1362 | |||
1363 | elapsed -= elapsed2; | 1364 | elapsed -= elapsed2; |
1364 | print_timing(BUFCACHE_FACTOR * total_MB, elapsed); | 1365 | total_MB *= BUFCACHE_FACTOR; |
1365 | flush_buffer_cache(fd); | 1366 | flush_buffer_cache(fd); |
1366 | sleep(1); | ||
1367 | } else { | ||
1368 | /* Time device */ | ||
1369 | |||
1370 | printf(" Timing buffered disk reads: "); | ||
1371 | fflush(stdout); | ||
1372 | /* | ||
1373 | * getitimer() is used rather than gettimeofday() because | ||
1374 | * it is much more consistent (on my machine, at least). | ||
1375 | */ | ||
1376 | /* Now do the timings for real */ | ||
1377 | iterations = 0; | ||
1378 | getitimer(ITIMER_REAL, &e1); | ||
1379 | do { | ||
1380 | ++iterations; | ||
1381 | if (read_big_block(fd, buf)) | ||
1382 | goto quit; | ||
1383 | getitimer(ITIMER_REAL, &e2); | ||
1384 | elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec) | ||
1385 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); | ||
1386 | } while (elapsed < 3.0 && iterations < max_iterations); | ||
1387 | |||
1388 | total_MB = iterations * TIMING_BUF_MB; | ||
1389 | print_timing(total_MB, elapsed); | ||
1390 | } | 1367 | } |
1391 | quit: | 1368 | print_timing(total_MB, elapsed / 1000000.0); |
1369 | quit: | ||
1392 | munlock(buf, TIMING_BUF_BYTES); | 1370 | munlock(buf, TIMING_BUF_BYTES); |
1393 | quit2: | 1371 | quit2: |
1394 | RELEASE_CONFIG_BUFFER(buf); | 1372 | RELEASE_CONFIG_BUFFER(buf); |
1395 | } | 1373 | } |
1396 | 1374 | ||