aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-05-22 21:46:11 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-05-22 21:46:11 +0000
commit0cb21f3a49d93ea4c502626ca65d373fa9c240ac (patch)
tree361baf533faf6e73043d1b5b639d215a2060af8a
parent2ca038f79ca5b9e1830a20bf8314021123f8d95c (diff)
downloadbusybox-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.c172
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
417static const char * const secu_str[] = { 417static 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 */
446static int bb_ioctl(int fd, int request, void *argp, const char *string) 445static 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)
1246static void flush_buffer_cache(int fd) 1245static 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
1279static 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
1287static int do_blkgetsize(int fd, unsigned long long *blksize64) 1278static 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
1294static 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
1303static void do_time(int flag, int fd) 1302static 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 }
1391quit: 1368 print_timing(total_MB, elapsed / 1000000.0);
1369 quit:
1392 munlock(buf, TIMING_BUF_BYTES); 1370 munlock(buf, TIMING_BUF_BYTES);
1393quit2: 1371 quit2:
1394 RELEASE_CONFIG_BUFFER(buf); 1372 RELEASE_CONFIG_BUFFER(buf);
1395} 1373}
1396 1374