X-Git-Url: http://git.xnk.nu/?p=JMraidcon.git;a=blobdiff_plain;f=src%2FJMraidcon.c;h=dd7bc689592a76cb8e1359f941e689e87575b312;hp=e51918d3573ea7dba1b64fa6796fc6fb88b5d90c;hb=c07f774e7bd50c06429b644312e7fff847e00f33;hpb=2d4767dca51d906d77ae8ac646225128abb93a8c diff --git a/src/JMraidcon.c b/src/JMraidcon.c index e51918d..dd7bc68 100644 --- a/src/JMraidcon.c +++ b/src/JMraidcon.c @@ -26,47 +26,52 @@ #include #include "jm_crc.h" #include "sata_xor.h" -#include +#include // For __le32_to_cpu etc #define SECTORSIZE (512) #define READ_CMD (0x28) #define WRITE_CMD (0x2a) #define RW_CMD_LEN (10) -const uint8_t probe1[] = { 0x25, 0x03, 0x7b, 0x19, 0x0b, 0xa8, 0x75, 0x3c, 0,0,0,0,0,0,0,0 }; -const uint8_t probe1end[] = { 0xdb, 0xa1, 0xec, 0x10, 0xd9, 0x10, 0x6d, 0x70 }; - -const uint8_t probe2[] = { 0x25, 0x03, 0x7b, 0x19, 0x37, 0xe3, 0x88, 0x03, 0,0,0,0,0,0,0,0 }; -const uint8_t probe2end[] = { 0xdb, 0xa1, 0xec, 0x10, 0x1e, 0x51, 0x58, 0x69 }; - -const uint8_t probe3[] = { 0x25, 0x03, 0x7b, 0x19, 0xf3, 0x05, 0x97, 0x68, 0,0,0,0,0,0,0,0 }; -const uint8_t probe3end[] = { 0xdb, 0xa1, 0xec, 0x10, 0x07, 0x4b, 0x23, 0xfe }; - -const uint8_t probe4[] = { 0x25, 0x03, 0x7b, 0x19, 0x3a, 0x52, 0x0c, 0xe0, 0,0,0,0,0,0,0,0 }; -const uint8_t probe4end[] = { 0xdb, 0xa1, 0xec, 0x10, 0xdb, 0x7a, 0xe5, 0x5b }; +#define JM_RAID_WAKEUP_CMD ( 0x197b0325 ) +#define JM_RAID_SCRAMBLED_CMD ( 0x197b0322 ) // First 4 bytes are always the same for all the scrambled commands, next 4 bytes forms an incrementing command id -const uint8_t probe6[]={ 0x22, 0x03, 0x7b, 0x19, 0x06,0x00,0x00,0x00, 0x00, 0x01, 0x02, 0xff, 0x01 }; // This returns very little info (at the end)? -const uint8_t probe7[]={ 0x22, 0x03, 0x7b, 0x19, 0x0b,0x00,0x00,0x00, 0x00, 0x01, 0x01, 0xff }; // This cmd returns the "RAID Manager" name -const uint8_t probe8[]={ 0x22, 0x03, 0x7b, 0x19, 0x0c,0x00,0x00,0x00, 0x00, 0x01, 0x02, 0xff, 0x0a }; -const uint8_t probe9[]={ 0x22, 0x03, 0x7b, 0x19, 0x0e,0x00,0x00,0x00, 0x00, 0x02, 0x01, 0xff }; // This returns the names of disks attached (or in a specific RAID volume?) -const uint8_t probe11[]={ 0x22, 0x03, 0x7b, 0x19, 0x10,0x00,0x00,0x00, 0x00, 0x02, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Identify disk0? -const uint8_t probe12[]={ 0x22, 0x03, 0x7b, 0x19, 0x11,0x00,0x00,0x00, 0x00, 0x02, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01 }; // Identify disk1? -const uint8_t probe13[]={ 0x22, 0x03, 0x7b, 0x19, 0x12,0x00,0x00,0x00, 0x00, 0x02, 0x02, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02 }; // Identify disk2? -const uint8_t probe14[]={ 0x22, 0x03, 0x7b, 0x19, 0x13,0x00,0x00,0x00, 0x00, 0x02, 0x02, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03 }; // Identify disk3? -const uint8_t probe15[]={ 0x22, 0x03, 0x7b, 0x19, 0x14,0x00,0x00,0x00, 0x00, 0x02, 0x02, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04 }; // Identify disk4? -const uint8_t probe16[]={ 0x22, 0x03, 0x7b, 0x19, 0x15,0x00,0x00,0x00, 0x00, 0x03, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }; // AWARD I5, wtf?? -const uint8_t probe17[]={ 0x22, 0x03, 0x7b, 0x19, 0x16,0x00,0x00,0x00, 0x00, 0x03, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01 }; // ?? -const uint8_t probe18[]={ 0x22, 0x03, 0x7b, 0x19, 0x17,0x00,0x00,0x00, 0x00, 0x03, 0x02, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02 }; // ?? -const uint8_t probe19[]={ 0x22, 0x03, 0x7b, 0x19, 0x18,0x00,0x00,0x00, 0x00, 0x03, 0x02, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03 }; // ?? -const uint8_t probe20[]={ 0x22, 0x03, 0x7b, 0x19, 0x19,0x00,0x00,0x00, 0x00, 0x03, 0x02, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04 }; // ?? -const uint8_t probe21[]={ 0x22, 0x03, 0x7b, 0x19, 0x1a,0x00,0x00,0x00, 0x00, 0x01, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; // Returns nothing? -const uint8_t probe23[]={ 0x22, 0x03, 0x7b, 0x19, 0x1c,0x00,0x00,0x00, 0x00, 0x02, 0x03, 0xff, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0 }; // SMART data disk0? -const uint8_t probe24[]={ 0x22, 0x03, 0x7b, 0x19, 0x1d,0x00,0x00,0x00, 0x00, 0x02, 0x03, 0xff, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0 }; // SMART data disk0 part2? -const uint8_t probe25[]={ 0x22, 0x03, 0x7b, 0x19, 0x1e,0x00,0x00,0x00, 0x00, 0x02, 0x03, 0xff, 0x01, 0x02, 0x00, 0xe0, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0 }; // SMART data disk1? -const uint8_t probe26[]={ 0x22, 0x03, 0x7b, 0x19, 0x1f,0x00,0x00,0x00, 0x00, 0x02, 0x03, 0xff, 0x01, 0x02, 0x00, 0xe0, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0 }; // SMART data disk1 part2? -const uint8_t probe27[]={ 0x22, 0x03, 0x7b, 0x19, 0x20,0x00,0x00,0x00, 0x00, 0x02, 0x03, 0xff, 0x02, 0x02, 0x00, 0xe0, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0 }; // SMART data disk2? -const uint8_t probe28[]={ 0x22, 0x03, 0x7b, 0x19, 0x21,0x00,0x00,0x00, 0x00, 0x02, 0x03, 0xff, 0x02, 0x02, 0x00, 0xe0, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0 }; // SMART data disk2 part2? +// (and these 8 bytes are now automatically prepended and no longer listed here) +const uint8_t probe6[]={ 0x00, 0x01, 0x02, 0xff, 0x01 }; // This returns very little info (at the end)? +const uint8_t probe7[]={ 0x00, 0x01, 0x01, 0xff }; // This cmd returns the "RAID Manager" name +const uint8_t probe8[]={ 0x00, 0x01, 0x02, 0xff, 0x0a }; +const uint8_t probe9[]={ 0x00, 0x02, 0x01, 0xff }; // This returns the names of disks attached (or in a specific RAID volume?) + +// The Identify disk commands does not return the data in the same format as the normal IDENTIFY DEVICE!?? +const uint8_t probe11[]={ 0x00, 0x02, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Identify disk0 +const uint8_t probe12[]={ 0x00, 0x02, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01 }; // Identify disk1 +const uint8_t probe13[]={ 0x00, 0x02, 0x02, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02 }; // Identify disk2 +const uint8_t probe14[]={ 0x00, 0x02, 0x02, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03 }; // Identify disk3 +const uint8_t probe15[]={ 0x00, 0x02, 0x02, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04 }; // Identify disk4 +const uint8_t probe16[]={ 0x00, 0x03, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }; // AWARD I5, wtf?? +const uint8_t probe17[]={ 0x00, 0x03, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01 }; // ?? +const uint8_t probe18[]={ 0x00, 0x03, 0x02, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02 }; // ?? +const uint8_t probe19[]={ 0x00, 0x03, 0x02, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03 }; // ?? +const uint8_t probe20[]={ 0x00, 0x03, 0x02, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04 }; // ?? +const uint8_t probe21[]={ 0x00, 0x01, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; // Returns nothing? +const uint8_t probe23[]={ 0x00, 0x02, 0x03, 0xff, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x00, // disk0 ata passthrough + 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0, 0x00 }; // SMART READ ATTRIBUTE VALUE ata cmd + +const uint8_t probe24[]={ 0x00, 0x02, 0x03, 0xff, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x00, // disk0 ata passthrough, again + 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0, 0x00 }; // SMART READ ATTRIBUTE THRESHOLDS ata cmd + +const uint8_t probe25[]={ 0x00, 0x02, 0x03, 0xff, 0x01, 0x02, 0x00, 0xe0, 0x00, 0x00, // disk1 ata passthrough + 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0, 0x00 }; // SMART READ ATTRIBUTE VALUE ata cmd + +const uint8_t probe26[]={ 0x00, 0x02, 0x03, 0xff, 0x01, 0x02, 0x00, 0xe0, 0x00, 0x00, // disk1 ata passthrough, again + 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0, 0x00 }; // SMART READ ATTRIBUTE THRESHOLDS ata cmd + +const uint8_t probe27[]={ 0x00, 0x02, 0x03, 0xff, 0x02, 0x02, 0x00, 0xe0, 0x00, 0x00, // disk2 ata passthrough + 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0, 0x00 }; // SMART READ ATTRIBUTE VALUE ata cmd + +const uint8_t probe28[]={ 0x00, 0x02, 0x03, 0xff, 0x02, 0x02, 0x00, 0xe0, 0x00, 0x00, // disk2 ata passthrough, again + 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xc2, 0x00, 0xa0, 0x00, 0xb0, 0x00 }; // SMART READ ATTRIBUTE THRESHOLDS ata cmd sg_io_hdr_t io_hdr; #warning FIXME: Should not use a hard-coded sector number (0x21), even though it is backed up and restored afterwards @@ -80,8 +85,7 @@ uint32_t Do_JM_Cmd( int theFD, uint32_t* theCmd, uint32_t* theResp ) { uint32_t myCRC = JM_CRC( theCmd, 0x7f ); // Stash the CRC at the end -#warning FIXME: CRC in request must be little-endian, no matter what the host arch is - theCmd[0x7f] = myCRC; + theCmd[0x7f] = __cpu_to_le32( myCRC ); // printf("Command CRC: 0x%08x\n", myCRC); // Make the data look really 31337 (or not) @@ -101,9 +105,8 @@ uint32_t Do_JM_Cmd( int theFD, uint32_t* theCmd, uint32_t* theResp ) { SATA_XOR( theResp ); myCRC = JM_CRC( theResp, 0x7f); -#warning FIXME: CRC in response is little-endian, no matter what the host arch is - if( myCRC != theResp[0x7f] ) { - printf( "Warning: Response CRC 0x%08x does not match the calculated 0x%08x!!\n", theResp[0x7f], myCRC ); + if( myCRC != __le32_to_cpu( theResp[0x7f] ) ) { + printf( "Warning: Response CRC 0x%08x does not match the calculated 0x%08x!!\n", __le32_to_cpu( theResp[0x7f] ), myCRC ); retval=1; } return retval; @@ -115,7 +118,7 @@ static void hexdump(uint8_t* thePtr, uint32_t theLen) { printf("0x%02x, ", thePtr[looper]); if((looper&0x0f)==0x0f) { int asc; - for(asc=looper-0x0f; asc0x7f) theOut='.'; printf("%c",theOut); @@ -128,11 +131,17 @@ static void hexdump(uint8_t* thePtr, uint32_t theLen) { static void TestCmd( int theFD, uint8_t* theCmd, uint32_t theLen) { uint8_t tempBuf1[SECTORSIZE]; + uint32_t* tempBuf1_32 = (uint32_t*)tempBuf1; uint8_t tempBuf2[SECTORSIZE]; + static uint32_t cmdNum = 1; // Entire sector is always sent, so zero fill cmd memset( tempBuf1, 0, SECTORSIZE ); - memcpy( tempBuf1, theCmd, theLen ); + memcpy( tempBuf1+0x08, theCmd, theLen ); + + tempBuf1_32[0] = __cpu_to_le32( JM_RAID_SCRAMBLED_CMD ); + tempBuf1_32[1] = __cpu_to_le32( cmdNum++ ); + theLen+=0x08; // Adding the SCRAMBLED_CMD and command number printf( "Sending command:\n"); hexdump( tempBuf1, (theLen+0x0f)&0x1f0 ); @@ -189,8 +198,16 @@ int main(int argc, char * argv[]) } // Generate and send the initial "wakeup" data - // I haven't gotten the CRC figured out on these ones yet + // No idea what the second dword represents at this point // Note that these (and all other writes) should be directed to an unused sector!! + memset( probeBuf, 0, SECTORSIZE ); + + // For wide access + uint32_t* probeBuf32 = (uint32_t*)probeBuf; + + // Populate with the static data + probeBuf32[0 >> 2] = __cpu_to_le32( JM_RAID_WAKEUP_CMD ); + probeBuf32[0x1f8 >> 2] = __cpu_to_le32( 0x10eca1db ); for( uint32_t i=0x10; i<0x1f8; i++ ) { probeBuf[i] = i&0xff; } @@ -199,17 +216,25 @@ int main(int argc, char * argv[]) rwCmdBlk[0] = WRITE_CMD; io_hdr.dxferp = probeBuf; - memcpy(probeBuf, probe1, 0x10); - memcpy(probeBuf+0x1f8, probe1end, 0x08); + // The only value (except the CRC at the end) that changes between the 4 wakeup sectors + probeBuf32[4 >> 2] = __cpu_to_le32( 0x3c75a80b ); + uint32_t myCRC = JM_CRC( probeBuf32, 0x1fc >> 2 ); + probeBuf32[0x1fc >> 2] = __cpu_to_le32( myCRC ); ioctl(sg_fd, SG_IO, &io_hdr); - memcpy(probeBuf, probe2, 0x10); - memcpy(probeBuf+0x1f8, probe2end, 0x08); + + probeBuf32[4 >> 2] = __cpu_to_le32( 0x0388e337 ); + myCRC = JM_CRC( probeBuf32, 0x1fc >> 2 ); + probeBuf32[0x1fc >> 2] = __cpu_to_le32( myCRC ); ioctl(sg_fd, SG_IO, &io_hdr); - memcpy(probeBuf, probe3, 0x10); - memcpy(probeBuf+0x1f8, probe3end, 0x08); + + probeBuf32[4 >> 2] = __cpu_to_le32( 0x689705f3 ); + myCRC = JM_CRC( probeBuf32, 0x1fc >> 2 ); + probeBuf32[0x1fc >> 2] = __cpu_to_le32( myCRC ); ioctl(sg_fd, SG_IO, &io_hdr); - memcpy(probeBuf, probe4, 0x10); - memcpy(probeBuf+0x1f8, probe4end, 0x08); + + probeBuf32[4 >> 2] = __cpu_to_le32( 0xe00c523a ); + myCRC = JM_CRC( probeBuf32, 0x1fc >> 2 ); + probeBuf32[0x1fc >> 2] = __cpu_to_le32( myCRC ); ioctl(sg_fd, SG_IO, &io_hdr); // Initial probe complete, now send scrambled commands to the same sector