Anyone managed to permanently disable Advanced Power Management in WD10JPVX?

Some updates on my code :

  1. Changing Mod 02 Record 13 Offset 36 is trivial. This will enable/disable autopark at 20 seconds.

  2. Reading and writing Offsets 36-39 looks to working fine now, but my code is rather amateurish. Took me quite a while to convert the char to array (since we’re dealing with 4 bytes now instead of 1 byte in idle3) and to get it to work with pointers, but finally I got it. Verified with Nazyura’s dump.

Next TODO is to read/convert/write Offsets 36-39 from/to desiseconds. I don’t see any point setting it beyond half an hour (might as well disable it), but what the heck.

Nice work!

BTW, if one day you would like to play with MHDD, I have written a tutorial here:

Tutorial: Using MHDD to send ATA commands to a HDD:
http://malthus.zapto.org/viewtopic.php?t=987

Thanks Franc. That might be handy.

Almost there.

[root@localhost apm]#./idle3ctl -s2578103244 /dev/sdc

User input : 2578103244                < For debugging purposes
atof tmptime : 2578103244            < For debugging purposes
After parsing to timer array : cc bb aa 99    < For debugging purposes
VSC_Set_Timer 1 : 204 187 170 153        < For debugging purposes
VSC_Set_Timer 2 : -52 -69 -86 -103        < For debugging purposes
APM timer set to 257810324.4s (0xccbbaa99)
Please power cycle your drive for the new setting to take effect. A reboot will not be enough!

[root@localhost apm]#./idle3ctl -g /dev/sdc

APM timer set to 257810324.4s (0xccbbaa99)

C:>mod2dump.exe 02_99aabbcc.MOD 13
ROYL header found

Module 02 consists of 47 sections

Section 13     Length 103 bytes

Addr  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0000  00 01 98 3A 0F 0F 01 02 02 0A 01 01 0A 02 02 04
0010  0A 00 FF FF 02 03 00 01 1E 0A 60 08 04 40 0B 02
0020  00 00 00 00 00 FF FF 10 00 00 00 00 03 0A 40 42
0030  0F 00 E0 C8 10 00 CC BB AA 99 05 0A A0 0F A0 05
0040  46 3C 02 00 05 05 B0 D0 10 00 00 00 C8 00 00 00
0050  D0 07 00 00 0A 00 00 00 01 01 1E 64 00 10 00 00
0060  60 27 3C 00 00 00 00

 

Update : The first 2 bytes are meant for the APM timer. The last 2 bytes are possibly meant for spindown or whatever that makes the drive goes to Standby. By setting it to 0x000000FF the drive starts and remains in permanent Standby mode and cannot be brought up by the OS. It’s totally not recognized by Linux. hdparm -C shows that it’s in Standby after several minutes. HDAT2 also shows that it’s in standby mode with APM at 0x60.

 

hdparm -C also shows Standby for 0x0000FF00 and APM at 0x60.

 

At 0x00FF0000, hdparm -C shows it’s Active.

 

This certainly makes more sense as no one would need a few years for a timer.

1 Like

WD3200BEKT / March 2012

Section 13     Length 59 bytes

Addr  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0000  00 01 98 3A 0F 0F 01 02 02 0A 01 01 00 02 02 04
0010  01 00 FF FF 02 03 8A 01 1E 0A 80 08 04 40 0B 02
0020  00 E8 03 64 00 FF FF 10 00 00 00 00 01 0A 80 96
0030  98 00 C0 D8 A7 00 00 00 00 00 05

Code has been completed since over a week ago. Been busy with work while I update the idle3-tools docs before I post it to SourceForge.

FYI, the demo version of SeDiv for WD enables you to retrieve the drive’s resources:
http://sediv2008.narod.ru/Easy3.9Password01234567890.rar

It won’t allow you to write SA modules, though.

Finally, here goes nothing : http://apmtimer.sourceforge.net/

Thanks for everything Franc. I spent more time in the docs than the actual code itself.

Oh yeah, I saved the SeDiv you get, but have yet to explore it yet. Been really busy with my work. But thanks!

1 Like

Thanks very much for that.

In fact the feedback that you provided in this thread proved to be very useful in formulating a procedure to facilitate the recovery of data from certain WD drives with the well known “slow issue”. The fix involves modifying a single byte in MOD 02, and clearing the contents of MOD 32. Unfortunately I’m not much of a programmer, so we had to apply the fix by way of an MHDD script (plus a FreeBasic program). So far, two users have been successful. If we had not modified the firmware, it would have taken several months at 24/7 to clone the drives, assuming they could have survived the ordeal. Instead it required only a matter of hours.

It would be nice if a real programmer could produce a simple “slow-fix” tool …

I couldn’t have done this without your help :slight_smile:

I think I read that article somewhere in HDDguru. If you could tell me which Record and offset of Mod 02 to patch, I can make one. Clearing Mod 32 will be a bit tricky since what we currently have is Record, Offset, and bytes. I can explore further though. I can see one of my Mod 32 has 0x00 from 0x84 onwards.

And I’m not a programmer, but I could explore editing a bit of codes here and there. I’ve tried compiling with Watcom to have it running in DOS but failed. So even if I could make the code for you, it’ll be in Unix. Are you ok with that?

This is one of the threads I am referring to:
http://forum.hddguru.com/viewtopic.php?f=1&t=29187&start=20

The main part of the “slow fix” is to write a single byte (0x00) to section 0x1b at offset 0x02 in SA module 02.

The other part is to read MOD 32, clear certain data structures within it, and then write it back to the SA.

Perhaps a Linux tool that does the first part of the job could suffice. I could then use your proof-of-concept code to approach professional programmers to fill in the extras for us.

Patching Mod 02 should not be a problem.

I compared the Before and After of Mod 32. Looks like I should not touch anything between 00-8F correct? And if I were to touch that portion, it’d only be the 4 bytes of checksum. Remaining part of the mod should be zeroed out.

Let me see what I can do.

Update : I checked my list of Mod 32 (all good hard disks from 80GB - 1TB) and it appears that everything is zero from 0x84 onwards.

From your code, the 10th byte is the length of the module.

wrt_021b.bin :

2A 00 02 00 02 00 1B 00 02 00 01

idle3ctl / apmtimer code :

   buffer[0]=0x2a;
   buffer[2]=rw;       >>>>> Read==01 Write==02
   buffer[4]=0x02;   >>>>> Mod 02 ?
   buffer[6]=0x0d;   >>>>> 1B / Record 27
   buffer[8]=0x36;   >>>>> 02 / Offset 2
   buffer[10]=0x02; >>>>> 01 / 1 Byte

But wrt_32.bin :

08 00 02 00 32

Can you tell me what are the 3 values? Is 02 == Write and 32 == Mod 32? I can probably modify the code to something like this :

   buffer[0]=0x8;
   buffer[2]=rw;       >>>>> Read=01 Write=02
   buffer[4]=0x32;   >>>>> Mod 32 ?

Yes, that’s it. However, you need to first determine the size of MOD 32 and then write as many sectors back to the drive. It’s a completely different VSC. It may be best to stick with just MOD 02 and see how far we can get with it.

The other day I read your code and wanted to confirm if “the 10th byte is the length of the module”.

I can get Mod 02 for you in no time. It’s just a matter of altering a couple of lines in the code. We can speed things up if you could help test Mod 02 on your end. You just need to get idle3-tools and modify idle3ctl.c from :

   buffer[0]=0x2a;
   buffer[2]=rw;
   buffer[4]=0x02;
   buffer[6]=0x0d;
   buffer[8]=0x16;
   buffer[10]=0x01;

To :

   buffer[0]=0x2a;
   buffer[2]=rw;
   buffer[4]=0x02;
   buffer[6]=0x1b;  // >>>>> 1B / Record 27
   buffer[8]=0x02;  // >>>>> Offset 0x2
   buffer[10]=0x01;

Recompile and use the -g option to retrieve its value and compare against the output of Sediv or other tools.

My idle3ctl-modified code is able to read Mod 32’s length as well as correctly write the first 1024 bytes onto a file for backing up. For some reason, data beyond 1024 is not correctly read and thus written. Unsure if the disk is acting up since it’s a very old one. Need to solve this before I work on the write module.

Managed to read the whole file now. Since the 11th byte is the number of sectors, I’m curious how it handles Advanced Format drives. Do we multiply the value of byte 11 with 4096 for AF drives or still 512.

Trying to do some tests to understand “The checksum bytes are chosen so that the 32-bit little endian sum of all the 32-bit double words, including the checksum bytes, is 0x00000000”. If we have 4 bytes of 0xFFFFFFFF, does the checksum go at 0x01010101 or 0x01000000. Will try with chksum2.exe

Update : It’s the latter

I don’t have access to a suitable WD drive at the moment, so I can’t help with testing.

I believe all AF drives still use 512-byte sectoring in the System Area.

As for the checksum, in the following example …

52 4F 59 4C 01 00 30 00 32 00 20 00 FF 9B BF DA

… you would compute the sum as …

0x4C594F52 + 0x00300001 + 0x00200032 + 0xDABF9BFF + …

BTW, the only way that I know to determine the size of a module is to begin with a sector count of 1 and read its first sector. Then change the sector count to reflect the size of the module, and read the entire module.

Thanks Franc, that’s what I did actually. Read the first sector, grab the sector count from Byte number 11 (if we start from 0x00 then it is 0xA, i.e. 2 bytes before the first checksum byte), then read the whole mod by multiplying it with 512.

Currently it is able to :

  1. Read the whole Mod 0x32 and save it into a file.

  2. Set offsets 0x84 - EOF to 00

  3. Clear the checksum in order to calculate the total of each 32 bits value.

  4. Recalculate the checksum and store it in offsets 0xC-0xF

  5. Save the modified Mod 32 into a new file.

*** Since my drive is good, both original and new files’ md5sum are identical ***

  1. Read the new file, determine its length and number of sectors (filesize divide by 512 - a bit lazy to code to read it from Byte 11) into memory buffer and write from memory back to a third file (instead of writing to my hard disk)

*** Validated that the third file’s md5sum is identical with the first two ***

I think we are almost there. Let me think carefully if I want to lose my 160GB if things go unexpectedly :slight_smile: Or perhaps generate some non-0 values in 0x84-EOF, write to the hard disk, retrieve and see if my program gets to fix them.

I believe all AF drives still use 512-byte sectoring in the System Area.

Thanks for this one too.

Think I’m done coding for Mod 32h. Now for Mod 02.

I’ve read http://malthus.zapto.org/viewtopic.php?f=86&t=848 and it was mentioned that it’s Mod 02 Record 1A Offset 2, but in the example you gave earlier, it was Record 1B Offset 2. Which is correct?

Also, my code will zero fill anything from 0x84 onwards. If this is incorrect, I need you to tell me where to start.

Thanks Franc.

Please give me some time to get my head around MOD 32 (and MOD 02).

Just today I received some feedback from someone who is using a professional tool. There are some differences between what the tool does and what the thread at the HDD Oracle is suggesting. I have also been offered a broken WD drive for testing.

MOD 32 cleared

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 AC 6B FD E5 ROYL............
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000........
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030 A4 00 00 00 98 01 00 00 88 1A 00 00 C4 20 00 00
00000040 00 27 00 00 78 33 00 00 F0 3F 00 00 B9 05 00 00
00000050 76 00 B9 05 00 00 00 00 00 00 00 00 00 00 00 00
00000060 00 00 00 00 00 00 00 00 72 29 AC 74 3D B4 9B 74
00000070 78 29 03 00 05 00 00 00 B9 05 00 00 93 18 13 01
00000080 D0 CC AE 75 00 00 00 00 00 00 00 00 00 00 00 00
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000A0 00 00 00 00




MOD 32 with bad sectors.

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 FF 9B BF DA ROYL............
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000........
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030 A4 00 00 00 98 01 00 00 88 1A 00 00 C4 20 00 00
00000040 00 27 00 00 78 33 00 00 F0 3F 00 00 BA 04 00 00
00000050 76 00 B9 05 00 00 00 00 5D 03 FF 00 5E 02 00 00
00000060 5E 02 00 00 00 00 00 00 60 85 B1 74 C8 09 9D 74
00000070 F8 28 03 00 03 00 00 00 B9 05 00 00 D8 7E 22 01
00000080 A0 88 BF 75 00 00 02 47 65 00 63 00 00 00 00 00
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000A0 00 00 00 00

No worries, take your time.

Some output from my good drives. Now the challenge is to determine values before 0x84 that were changed and not zeroed.

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 A6 32 EF E5 ROYL .0.2. . 2  
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000 1.....
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 A4 00 00 00 98 01 00 00 88 1A 00 00 C4 20 00 00 ... .. .. ..
00000040 00 27 00 00 78 33 00 00 F0 3F 00 00 B9 05 00 00 .'..x3.. ?.. ..
00000050 76 00 B9 05 00 00 00 00 00 00 00 00 00 00 00 00 v. ............
00000060 00 00 00 00 00 00 00 00 FE F3 09 75 FD 11 F1 74 ........ u t
00000070 05 A4 03 00 02 00 00 00 B9 05 00 00 CB B4 95 00 . ... .. .
00000080 C8 C6 86 75 u

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 5F 21 30 29 ROYL .0.2. ._!0)
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000 1.....
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 A4 00 00 00 C0 00 00 00 08 1A 00 00 5C 20 00 00 ... ... ..\ ..
00000040 B0 26 00 00 54 33 00 00 F8 3F 00 00 B9 05 00 00 &..T3.. ?.. ..
00000050 0A 00 B9 05 00 00 00 00 00 00 00 00 00 00 00 00 . ............
00000060 00 00 00 00 00 00 00 00 CB C5 94 09 0B 0D 92 09 ........        
00000070 85 E4 01 00 00 80 00 00 B9 05 00 00 87 7A 0F 00 .. .. .. z .
00000080 92 87 A1 09

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 3C 00 DA CD AE C2 ROYL .0.2.<.    
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000 1.....
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 A4 00 00 00 20 01 00 00 A8 30 00 00 8C 3C 00 00 ... .. 0.. <..
00000040 70 48 00 00 34 60 00 00 F8 77 00 00 E1 0B 00 00 pH..4`.. w.. ..
00000050 3B 00 E1 0B 00 00 00 00 00 00 00 00 00 00 00 00 ;. ............
00000060 00 00 00 00 00 00 00 00 B6 1D AB 07 98 AF 9A 3A ........ :
00000070 06 B2 03 00 00 00 00 00 E1 0B 00 00 15 9F 05 00 ..... .. .
00000080 3F A8 C7 3A ? :

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 94 24 0C D8 ROYL .0.2. . $  
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000 1.....
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 A4 00 00 00 F8 00 00 00 28 1A 00 00 74 20 00 00 ... ...( ..t ..
00000040 C0 26 00 00 58 33 00 00 F0 3F 00 00 F9 02 00 00 &..X3.. ?.. ..
00000050 26 00 F9 02 00 00 00 00 00 00 00 00 00 00 00 00 &. ............
00000060 00 00 00 00 00 00 00 00 E9 E5 7B 25 15 EC 74 25 ........ {% t%
00000070 86 BD 02 00 00 00 00 00 F9 02 00 00 C7 DF 2A 00 ..... .. *.
00000080 DC CB 9F 25 %

(4Ch and 4Dh) could be copied from (52h and 53h) or (78h and 79h)