Skip to content

Commit

Permalink
Merge pull request #25 from J-Twin/master
Browse files Browse the repository at this point in the history
Various additions and fixes
  • Loading branch information
Ognian authored Mar 20, 2024
2 parents 768a075 + a9be06b commit f492365
Showing 1 changed file with 175 additions and 74 deletions.
249 changes: 175 additions & 74 deletions src/sdmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,56 +252,78 @@ int main(int argc, const char *argv[]) {
exit(0);
}

//try adata argument
cmd56_arg = 0x110005f1;
// try innodisk argument
cmd56_arg = 0x110005fd;
ret = CMD56_data_in(fd, cmd56_arg, data_in);
// we assume success when the call was successful AND the signature is not 0xff 0xff
if (ret == 0 && !((data_in[0] == 0xff && data_in[1] == 0xff) || (data_in[0] == 0x00 && data_in[1] == 0x00))) {
printf("\"signature\":\"0x%x 0x%x\",\n", data_in[0], data_in[1]);
if (data_in[0] == 0x09 && data_in[1] == 0x41) {
printf("\"Adata\":\"true\",\n");
printf("\"Factory bad block cnt\": %d,\n", (int)((data_in[24] << 8) + data_in[25]));
printf("\"Grown bad block cnt\": %d,\n", (int)(data_in[26]));
printf("\"Spare SLC block cnt\": %d,\n", (int)(data_in[27]));
printf("\"Spare block cnt\": %d,\n", (int)((data_in[30] << 8) + data_in[31]));
printf("\"Data area minimum erase cnt\": %ld,\n", (long)((data_in[32] << 24) + (data_in[33] << 16) + (data_in[34] << 8) + data_in[35]));
printf("\"Data area maximum erase cnt\": %ld,\n", (long)((data_in[36] << 24) + (data_in[37] << 16) + (data_in[38] << 8) + data_in[39]));
printf("\"Data area total erase cnt\": %ld,\n", (long)((data_in[40] << 24) + (data_in[41] << 16) + (data_in[42] << 8) + data_in[43]));
printf("\"Data area average erase cnt\": %ld,\n", (long)((data_in[44] << 24) + (data_in[45] << 16) + (data_in[46] << 8) + data_in[47]));
printf("\"System area minimum erase cnt\": %ld,\n", (long)((data_in[48] << 24) + (data_in[49] << 16) + (data_in[50] << 8) + data_in[51]));
printf("\"System area maximum erase cnt\": %ld,\n", (long)((data_in[52] << 24) + (data_in[53] << 16) + (data_in[54] << 8) + data_in[55]));
printf("\"System area total erase count\": %ld,\n", (long)((data_in[56] << 24) + (data_in[57] << 16) + (data_in[58] << 8) + data_in[59]));
printf("\"System area average erase cnt\": %ld,\n", (long)((data_in[60] << 24) + (data_in[61] << 16) + (data_in[62] << 8) + data_in[63]));
printf("\"Raw card capacity\": %ld MB,\n", (long)((data_in[64] << 24) + (data_in[65] << 16) + (data_in[66] << 8) + data_in[67]));
printf("\"PE Cycle life\": %ld,\n", (long)((data_in[68] << 8) + data_in[69]));
printf("\"Remaining life\": %d%%,\n", (int)data_in[70]);
printf("\"Power cucle cnt\": %ld,\n", (long)((data_in[76] << 24) + (data_in[77] << 16) + (data_in[78] << 8) + data_in[79]));
printf("\"Flash ID\": 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", data_in[80], data_in[81], data_in[82], data_in[83], data_in[84], data_in[85], data_in[86]);
printf("\"Controller\": %c%c%c%c%c%c,\n", (char)data_in[88], (char)data_in[89], (char)data_in[90], (char)data_in[91], (char)data_in[92], (char)data_in[93]);
printf("\"TLC read reclaim\": %ld,\n", (long)((data_in[96] << 8) + data_in[97]));
printf("\"SLC read reclaim\": %ld,\n", (long)((data_in[98] << 8) + data_in[99]));
printf("\"Firmware block refresh\": %ld,\n", (long)((data_in[100] << 8) + data_in[101]));
printf("\"TLC read threshold\": %ld,\n", (long)((data_in[104] << 24) + (data_in[105] << 16) + (data_in[106] << 8) + data_in[107]));
printf("\"SLC read threshold\": %ld,\n", (long)((data_in[108] << 24) + (data_in[109] << 16) + (data_in[110] << 8) + data_in[111]));
printf("\"FW version\": %c%c%c%c%c%c,\n", (char)data_in[128], (char)data_in[129], (char)data_in[130], (char)data_in[131], (char)data_in[132], (char)data_in[133]);
printf("\"TLC refresh cnt\": %d,\n", (int)((data_in[136] << 24) + (data_in[137] << 16) + (data_in[138] << 8) + data_in[139]));
printf("\"SLC refresh cnt\": %d,\n", (int)((data_in[140] << 24) + (data_in[141] << 16) + (data_in[143] << 8) + data_in[144]));
close(fd);
printf("\" signature2 \":\"0x%x 0x%x\",\n", data_in[0], data_in[1]);
if (data_in[0] == 0x4c && data_in[1] == 0x58) {
printf("\"Innodisk\":\"true\",\n");
switch (data_in[16])
{
case 0x00:
printf("\"Bus width\": 1 bit\n");
break;
case 0x10:
printf("\"Bus width\": 4 bits\n");
break;
}
switch (data_in[18])
{
case 0x00:
printf("\"Speed mode\": Class 0\n");
break;
case 0x01:
printf("\"Speed mode\": Class 2\n");
break;
case 0x02:
printf("\"Speed mode\": Class 4\n");
break;
case 0x03:
printf("\"Speed mode\": Class 6\n");
break;
case 0x04:
printf("\"Speed mode\": Class 10\n");
break;
}
switch (data_in[19])
{
case 0x00:
printf("\"UHS speed grade\": Less than 10MB/s\n");
break;
case 0x01:
printf("\"UHS speed grade\": 10MB/s and higher\n");
break;
case 0x03:
printf("\"UHS speed grade\": 30MB/s and higher\n");
break;
}
printf("\"Total spare blocks cnt\": %d,\n", data_in[24]);
printf("\"Factory bad blocks cnt\": %d,\n", data_in[25]);
printf("\"Runtime bad blocks cnt\": %d,\n", data_in[26]);
printf("\"Spare utilization rate\": %d%,\n", data_in[27]);
printf("\"SPOR failure cnt\": %d,\n", bytes_to_int(data_in[28], data_in[29], data_in[30], data_in[31]));
printf("\"Minimum erase cnt\": %d,\n", (long)((data_in[35]) + (data_in[34]) + (data_in[33]) + data_in[32]));
printf("\"Maximum erase cnt\": %d,\n", (long)((data_in[39]) + (data_in[38]) + (data_in[37]) + data_in[36]));
printf("\"Total erase cnt\": %d,\n", (long)((data_in[43]) + (data_in[42]) + (data_in[41]) + data_in[40]));
printf("\"Average erase cnt\": %d,\n", (long)((data_in[47]) + (data_in[46]) + (data_in[45]) + data_in[44]));
printf("\"FW version\": %c%c%c%c%c%c%c,\n", data_in[53], data_in[54], data_in[55], data_in[56], data_in[57], data_in[58], data_in[59]);
close(fd);
printf("\"success\":true\n}\n");
exit(0);
}
}
//try transcend argument
cmd56_arg = 0x110005f9;
}
}

//try ADATA, ATP argument
cmd56_arg = 0x110005f1;
ret = CMD56_data_in(fd, cmd56_arg, data_in);
// we assume success when the call was successful AND the signature is not 0xff 0xff
if (ret == 0 && !((data_in[0] == 0xff && data_in[1] == 0xff) || (data_in[0] == 0x00 && data_in[1] == 0x00))) {
printf("\"signature\":\"0x%x 0x%x\",\n", data_in[0], data_in[1]);
if (data_in[0] == 0x54 && data_in[1] == 0x72) {
printf("\"Transcend\":\"true\",\n");
printf("\"Secured mode\": %d,\n", (int)(data_in[11]));
switch (data_in[16])
if (data_in[0] == 0x09 && data_in[1] == 0x41) {
printf("\"ADATA, ATP\":\"true\",\n");
switch (data_in[16])
{
case 0x00:
printf("\"Bus width\": 1 bit\n");
Expand Down Expand Up @@ -340,43 +362,38 @@ int main(int argc, const char *argv[]) {
printf("\"UHS speed grade\": 30MB/s and higher\n");
break;
}
printf("\"New bad blocks cnt\": 0x%02x,\n", data_in[26]);
printf("\"Runtime spare blocks cnt\": 0x%02x,\n", data_in[27]);
printf("\"Abnormal power loss\": %ld,\n", (long)((data_in[31] << 24) + (data_in[30] << 16) + (data_in[29] << 8) + data_in[28]));
printf("\"Minimum erase cnt\": %ld,\n", (long)((data_in[35] << 24) + (data_in[34] << 16) + (data_in[33] << 8) + data_in[32]));
printf("\"Maximum erase cnt\": %d,\n", (long)((data_in[36]<< 24) + (data_in[37]<< 16) + (data_in[38]<< 8) + data_in[39]));
printf("\"Average erase cnt\": %ld,\n", (long)((data_in[47] << 24) + (data_in[46] << 16) + (data_in[45] << 8) + data_in[44]));

printf("\"Remaining card life\": %d%%,\n", (int)(data_in[70]));
printf("\"Total write CRC cnt\": %d,\n", bytes_to_int(data_in[72], data_in[73], data_in[74], data_in[75]));
printf("\"Power cycle cnt\": %d,\n", bytes_to_int(0, 0, data_in[76], data_in[77]));

printf("\"NAND flash ID\": 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", data_in[80], data_in[81], data_in[82], data_in[83], data_in[84], data_in[85]);
printf("\"IC\": %c%c%c%c%c%c%c%c,\n", data_in[87], data_in[88], data_in[89], data_in[90], data_in[91], data_in[92], data_in[93], data_in[94]);
printf("\"fw version\": %c%c%c%c%c%c,\n", data_in[128], data_in[129], data_in[130], data_in[131], data_in[132], data_in[133]);

close(fd);
printf("\"Factory bad block cnt\": %d,\n", (int)((data_in[24] << 8) + data_in[25]));
printf("\"Grown bad block cnt\": %d,\n", (int)(data_in[26]));
printf("\"Spare SLC block cnt\": %d,\n", (int)(data_in[27]));
printf("\"Spare block cnt\": %d,\n", (int)((data_in[30] << 8) + data_in[31]));
printf("\"Data area minimum erase cnt\": %ld,\n", (long)((data_in[32] << 24) + (data_in[33] << 16) + (data_in[34] << 8) + data_in[35]));
printf("\"Data area maximum erase cnt\": %ld,\n", (long)((data_in[36] << 24) + (data_in[37] << 16) + (data_in[38] << 8) + data_in[39]));
printf("\"Data area total erase cnt\": %ld,\n", (long)((data_in[40] << 24) + (data_in[41] << 16) + (data_in[42] << 8) + data_in[43]));
printf("\"Data area average erase cnt\": %ld,\n", (long)((data_in[44] << 24) + (data_in[45] << 16) + (data_in[46] << 8) + data_in[47]));
printf("\"System area minimum erase cnt\": %ld,\n", (long)((data_in[48] << 24) + (data_in[49] << 16) + (data_in[50] << 8) + data_in[51]));
printf("\"System area maximum erase cnt\": %ld,\n", (long)((data_in[52] << 24) + (data_in[53] << 16) + (data_in[54] << 8) + data_in[55]));
printf("\"System area total erase count\": %ld,\n", (long)((data_in[56] << 24) + (data_in[57] << 16) + (data_in[58] << 8) + data_in[59]));
printf("\"System area average erase cnt\": %ld,\n", (long)((data_in[60] << 24) + (data_in[61] << 16) + (data_in[62] << 8) + data_in[63]));
printf("\"Raw card capacity\": %ld MB,\n", (long)((data_in[64] << 24) + (data_in[65] << 16) + (data_in[66] << 8) + data_in[67]));
printf("\"PE Cycle life\": %ld,\n", (long)((data_in[68] << 8) + data_in[69]));
printf("\"Remaining life\": %d%%,\n", (int)data_in[70]);
printf("\"Power cycle cnt\": %ld,\n", (long)((data_in[76] << 24) + (data_in[77] << 16) + (data_in[78] << 8) + data_in[79]));
printf("\"Flash ID\": 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", data_in[80], data_in[81], data_in[82], data_in[83], data_in[84], data_in[85], data_in[86]);
printf("\"Controller\": %c%c%c%c%c%c,\n", (char)data_in[88], (char)data_in[89], (char)data_in[90], (char)data_in[91], (char)data_in[92], (char)data_in[93]);
printf("\"TLC read reclaim\": %ld,\n", (long)((data_in[96] << 8) + data_in[97]));
printf("\"SLC read reclaim\": %ld,\n", (long)((data_in[98] << 8) + data_in[99]));
printf("\"Firmware block refresh\": %ld,\n", (long)((data_in[100] << 8) + data_in[101]));
printf("\"TLC read threshold\": %ld,\n", (long)((data_in[104] << 24) + (data_in[105] << 16) + (data_in[106] << 8) + data_in[107]));
printf("\"SLC read threshold\": %ld,\n", (long)((data_in[108] << 24) + (data_in[109] << 16) + (data_in[110] << 8) + data_in[111]));
printf("\"FW version\": %c%c%c%c%c%c,\n", (char)data_in[128], (char)data_in[129], (char)data_in[130], (char)data_in[131], (char)data_in[132], (char)data_in[133]);
printf("\"TLC refresh cnt\": %ld,\n", (long)((data_in[136] << 24) + (data_in[137] << 16) + (data_in[138] << 8) + data_in[139]));
printf("\"SLC refresh cnt\": %ld,\n", (long)((data_in[140] << 24) + (data_in[141] << 16) + (data_in[143] << 8) + data_in[144]));
close(fd);
printf("\"success\":true\n}\n");
exit(0);
}
}

// try micron argument
cmd56_arg = 0x110005fb;
ret = CMD56_data_in(fd, cmd56_arg, data_in);
// we assume success when the call was successful AND the signature is not 0xff 0xff
if (ret == 0 && !((data_in[0] == 0xff && data_in[1] == 0xff) || (data_in[0] == 0x00 && data_in[1] == 0x00))) {
printf("\" signature \":\"0x%x 0x%x\",\n", data_in[0], data_in[1]);
if (data_in[0] == 0x4d && data_in[1] == 0x45) {
printf("\"Micron\":\"true\",\n");
printf("\"Percentange step utilization\": %d,\n", (int)(data_in[7]));
printf("\"TLC area utilization\": %d,\n", (int)(data_in[8]));
printf("\"SLC area utilization\": %d,\n", (int)(data_in[9]));
close(fd);
printf("\"success\":true\n}\n");
exit(0);
}
}

// try swissbit argument
cmd56_arg = 0x53420001;
Expand All @@ -387,7 +404,7 @@ int main(int argc, const char *argv[]) {

if (data_in[0] == 0x53 && data_in[1] == 0x77) {
printf("\"Swissbit\":\"true\",\n");
printf("\"fwVersion\": [%c,%c,%c,%c,%c,%c,%c,%c,%c,%c,%c,%c,%c,%c,%c,%c],\n", data_in[32], data_in[33], data_in[34], data_in[35], data_in[36], data_in[37], data_in[38], data_in[39], data_in[40],
printf("\"FW version\": [%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c],\n", data_in[32], data_in[33], data_in[34], data_in[35], data_in[36], data_in[37], data_in[38], data_in[39], data_in[40],
data_in[41], data_in[42], data_in[43], data_in[44], data_in[45], data_in[46], data_in[47]); // show char
printf("\"User area rated cycles\": [\"0x%02x\",\"0x%02x\",\"0x%02x\",\"0x%02x\"],\n", data_in[48], data_in[49], data_in[50], data_in[51]);
printf("\"User area max cycle cnt\": [\"0x%02x\",\"0x%02x\",\"0x%02x\",\"0x%02x\"],\n", data_in[52], data_in[53], data_in[54], data_in[55]);
Expand Down Expand Up @@ -441,6 +458,90 @@ int main(int argc, const char *argv[]) {
exit(0);
}
}

//try transcend argument
cmd56_arg = 0x110005f9;
ret = CMD56_data_in(fd, cmd56_arg, data_in);
// we assume success when the call was successful AND the signature is not 0xff 0xff
if (ret == 0 && !((data_in[0] == 0xff && data_in[1] == 0xff) || (data_in[0] == 0x00 && data_in[1] == 0x00))) {
printf("\"signature\":\"0x%x 0x%x\",\n", data_in[0], data_in[1]);
if (data_in[0] == 0x54 && data_in[1] == 0x72) {
printf("\"Transcend\":\"true\",\n");
printf("\"Secured mode\": %d,\n", (int)(data_in[11]));
switch (data_in[16])
{
case 0x00:
printf("\"Bus width\": 1 bit\n");
break;
case 0x10:
printf("\"Bus width\": 4 bits\n");
break;
}
switch (data_in[18])
{
case 0x00:
printf("\"Speed mode\": Class 0\n");
break;
case 0x01:
printf("\"Speed mode\": Class 2\n");
break;
case 0x02:
printf("\"Speed mode\": Class 4\n");
break;
case 0x03:
printf("\"Speed mode\": Class 6\n");
break;
case 0x04:
printf("\"Speed mode\": Class 10\n");
break;
}
switch (data_in[19])
{
case 0x00:
printf("\"UHS speed grade\": Less than 10MB/s\n");
break;
case 0x01:
printf("\"UHS speed grade\": 10MB/s and higher\n");
break;
case 0x03:
printf("\"UHS speed grade\": 30MB/s and higher\n");
break;
}
printf("\"New bad blocks cnt\": 0x%02x,\n", data_in[26]);
printf("\"Runtime spare blocks cnt\": 0x%02x,\n", data_in[27]);
printf("\"Abnormal power loss\": %ld,\n", (long)((data_in[31] << 24) + (data_in[30] << 16) + (data_in[29] << 8) + data_in[28]));
printf("\"Minimum erase cnt\": %ld,\n", (long)((data_in[35] << 24) + (data_in[34] << 16) + (data_in[33] << 8) + data_in[32]));
printf("\"Maximum erase cnt\": %ld,\n", (long)((data_in[36]<< 24) + (data_in[37]<< 16) + (data_in[38]<< 8) + data_in[39]));
printf("\"Average erase cnt\": %ld,\n", (long)((data_in[47] << 24) + (data_in[46] << 16) + (data_in[45] << 8) + data_in[44]));
printf("\"Remaining card life\": %d%%,\n", (int)(data_in[70]));
printf("\"Total write CRC cnt\": %d,\n", bytes_to_int(data_in[72], data_in[73], data_in[74], data_in[75]));
printf("\"Power cycle cnt\": %d,\n", bytes_to_int(0, 0, data_in[76], data_in[77]));
printf("\"NAND flash ID\": 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", data_in[80], data_in[81], data_in[82], data_in[83], data_in[84], data_in[85]);
printf("\"IC\": %c%c%c%c%c%c%c%c,\n", data_in[87], data_in[88], data_in[89], data_in[90], data_in[91], data_in[92], data_in[93], data_in[94]);
printf("\"FW version\": %c%c%c%c%c%c,\n", data_in[128], data_in[129], data_in[130], data_in[131], data_in[132], data_in[133]);

close(fd);
printf("\"success\":true\n}\n");
exit(0);
}
}

// try micron argument
cmd56_arg = 0x110005fb;
ret = CMD56_data_in(fd, cmd56_arg, data_in);
// we assume success when the call was successful AND the signature is not 0xff 0xff
if (ret == 0 && !((data_in[0] == 0xff && data_in[1] == 0xff) || (data_in[0] == 0x00 && data_in[1] == 0x00))) {
printf("\" signature \":\"0x%x 0x%x\",\n", data_in[0], data_in[1]);
if (data_in[0] == 0x4d && data_in[1] == 0x45) {
printf("\"Micron\":\"true\",\n");
printf("\"Percentange step utilization\": %d,\n", (int)(data_in[7]));
printf("\"TLC area utilization\": %d,\n", (int)(data_in[8]));
printf("\"SLC area utilization\": %d,\n", (int)(data_in[9]));
close(fd);
printf("\"success\":true\n}\n");
exit(0);
}
}

if (ret == 0) {
printf("\"read_via_cmd56_arg_1\":\"read successful but signature 0x%x 0x%x\",\n", data_in[0], data_in[1]);
Expand Down

0 comments on commit f492365

Please sign in to comment.