resolve merge conflicts of 01c1129fe6 to master.
Change-Id: I84f862b4858ecc97461750833a0e6f9cf96c34c4
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 53bbeb2..cd03e68 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -305,6 +305,7 @@
dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
run_command("UPTIME", 10, "uptime", NULL);
dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
+ dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
dump_file("MEMORY INFO", "/proc/meminfo");
run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL);
run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL);
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 9623e36..df9721d 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -146,4 +146,7 @@
}
#endif
+/* dump eMMC Extended CSD data */
+void dump_emmc_ecsd(const char *ext_csd_path);
+
#endif /* _DUMPSTATE_H_ */
diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc
index cd5d6c4..4cd1803 100644
--- a/cmds/dumpstate/dumpstate.rc
+++ b/cmds/dumpstate/dumpstate.rc
@@ -1,3 +1,8 @@
+on boot
+ # Allow bugreports access to eMMC 5.0 stats
+ chown root mount /sys/kernel/debug/mmc0/mmc0:0001/ext_csd
+ chmod 0440 /sys/kernel/debug/mmc0/mmc0:0001/ext_csd
+
service dumpstate /system/bin/dumpstate -s
class main
socket dumpstate stream 0660 shell log
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index d939779..0363c7c 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -884,3 +884,120 @@
const char *args[] = { "/system/bin/screencap", "-p", path.c_str(), NULL };
run_command_always(NULL, 10, args);
}
+
+void dump_emmc_ecsd(const char *ext_csd_path) {
+ static const size_t EXT_CSD_REV = 192;
+ static const size_t EXT_PRE_EOL_INFO = 267;
+ static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268;
+ static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269;
+ struct hex {
+ char str[2];
+ } buffer[512];
+ int fd, ext_csd_rev, ext_pre_eol_info;
+ ssize_t bytes_read;
+ static const char *ver_str[] = {
+ "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0"
+ };
+ static const char *eol_str[] = {
+ "Undefined",
+ "Normal",
+ "Warning (consumed 80% of reserve)",
+ "Urgent (consumeed 90% of reserve)"
+ };
+
+ printf("------ %s Extended CSD ------\n", ext_csd_path);
+
+ fd = TEMP_FAILURE_RETRY(open(ext_csd_path,
+ O_RDONLY | O_NONBLOCK | O_CLOEXEC));
+ if (fd < 0) {
+ printf("*** %s: %s\n\n", ext_csd_path, strerror(errno));
+ return;
+ }
+
+ bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
+ close(fd);
+ if (bytes_read < 0) {
+ printf("*** %s: %s\n\n", ext_csd_path, strerror(errno));
+ return;
+ }
+ if (bytes_read < (ssize_t)(EXT_CSD_REV * sizeof(hex))) {
+ printf("*** %s: truncated content %zd\n\n", ext_csd_path, bytes_read);
+ return;
+ }
+
+ ext_csd_rev = 0;
+ if (sscanf(buffer[EXT_CSD_REV].str, "%02x", &ext_csd_rev) != 1) {
+ printf("*** %s: EXT_CSD_REV parse error \"%.2s\"\n\n",
+ ext_csd_path, buffer[EXT_CSD_REV].str);
+ return;
+ }
+
+ printf("rev 1.%d (MMC %s)\n",
+ ext_csd_rev,
+ (ext_csd_rev < (int)(sizeof(ver_str) / sizeof(ver_str[0]))) ?
+ ver_str[ext_csd_rev] :
+ "Unknown");
+ if (ext_csd_rev < 7) {
+ printf("\n");
+ return;
+ }
+
+ if (bytes_read < (ssize_t)(EXT_PRE_EOL_INFO * sizeof(hex))) {
+ printf("*** %s: truncated content %zd\n\n", ext_csd_path, bytes_read);
+ return;
+ }
+
+ ext_pre_eol_info = 0;
+ if (sscanf(buffer[EXT_PRE_EOL_INFO].str, "%02x", &ext_pre_eol_info) != 1) {
+ printf("*** %s: PRE_EOL_INFO parse error \"%.2s\"\n\n",
+ ext_csd_path, buffer[EXT_PRE_EOL_INFO].str);
+ return;
+ }
+ printf("PRE_EOL_INFO %d (MMC %s)\n",
+ ext_pre_eol_info,
+ eol_str[(ext_pre_eol_info < (int)
+ (sizeof(eol_str) / sizeof(eol_str[0]))) ?
+ ext_pre_eol_info : 0]);
+
+ for (size_t lifetime = EXT_DEVICE_LIFE_TIME_EST_TYP_A;
+ lifetime <= EXT_DEVICE_LIFE_TIME_EST_TYP_B;
+ ++lifetime) {
+ int ext_device_life_time_est;
+ static const char *est_str[] = {
+ "Undefined",
+ "0-10% of device lifetime used",
+ "10-20% of device lifetime used",
+ "20-30% of device lifetime used",
+ "30-40% of device lifetime used",
+ "40-50% of device lifetime used",
+ "50-60% of device lifetime used",
+ "60-70% of device lifetime used",
+ "70-80% of device lifetime used",
+ "80-90% of device lifetime used",
+ "90-100% of device lifetime used",
+ "Exceeded the maximum estimated device lifetime",
+ };
+
+ if (bytes_read < (ssize_t)(lifetime * sizeof(hex))) {
+ printf("*** %s: truncated content %zd\n", ext_csd_path, bytes_read);
+ break;
+ }
+
+ ext_device_life_time_est = 0;
+ if (sscanf(buffer[lifetime].str, "%02x", &ext_device_life_time_est) != 1) {
+ printf("*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%.2s\"\n",
+ ext_csd_path,
+ (unsigned)(lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) + 'A',
+ buffer[lifetime].str);
+ continue;
+ }
+ printf("DEVICE_LIFE_TIME_EST_TYP_%c %d (MMC %s)\n",
+ (unsigned)(lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) + 'A',
+ ext_device_life_time_est,
+ est_str[(ext_device_life_time_est < (int)
+ (sizeof(est_str) / sizeof(est_str[0]))) ?
+ ext_device_life_time_est : 0]);
+ }
+
+ printf("\n");
+}