Subject: Mangled struct hd_driveid with MIPSEB.

From: Ken Aaker <[email-masked]>
Date: Wed, 15 May 2002 15:42:28 -0500

I've just run across an interesting problem building a big-endian MIPS 
kernel against the kernel source from the cvs tree. When the drive 
identity record is presented to the ide_fix_driveid() function in 
include/asm-mips/ide.h, it looks like its been byteswapped in 16 bit 
chunks. Needless to say, this causes a certain amount of confusion.  I 
tried following the process back to the point where the data is read in, 
but I failed to find anything that seemed to be explicitly swapping the 
code. The older kernel that I have 2.4.3 works Ok, so it's something 
that's happened recently.  Here's a little bit of debug information that 
I collected.. I messed around with the ide_fix_driveid function till I 
got the system to work, but I'm be embarassed to see that code escape 
into the wild.

This is a dump of the id record before the call to ide_fix_driveid() in 
the 2.4.3 kernel.
0000: 7a42ff3f 00001000 00e15802 3f001000   "zB.?......X.?..."
0010: 00000e00 4457572d 41435441 34343430   "....DWW.ACTA4440"
0020: 33340034 00000000 03000010 28003630   "34.4..........60"
0030: 302e4734 36304457 20434457 30334530   "0.G460DW.CDW03E0"
0040: 2d423030 50433046 20202020 20202020   ".B00PC0F........"
0050: 20202020 20202020 20202020 20201080   "................"
0060: 0000002f 01408002 00000700 ff3f1000   ".....@.......?.."
0070: 3f0010fc fb000001 80ac7e03 00000704   "?.........~....."
0080: 03007800 78007800 78000000 00000000   "..x.x.x.x......."
0090: 00000000 00000000 00000000 00000000   "................"
00a0: 3e000000 6b34014b 00406934 01080040   ">...k4.K.@i4...@"
00b0: 3f000000 00000000 00004b60 fe800000   "?.........K`...."
00c0: 00000000 00000000 00000000 00000000   "................"
00d0: 00000000 00000000 00000000 00000000   "................"
00e0: 00000000 00000000 00000000 00000000   "................"
00f0: 00000000 00000000 00000000 00000000   "................"
0100: 01000000 00000000 00003300 00000000   "..........3....."
0110: 00000000 00000000 00000000 00000000   "................"
0120: 00000000 00000000 00000000 00000000   "................"
0130: 00000000 00000000 00000000 00001f00   "................"
0140: 00000000 00000000 00000000 00000000   "................"
0150: 00000000 00000000 00000000 00000000   "................"
0160: 00000000 00000000 00000000 00000000   "................"
0170: 00000000 00000000 00000000 00000000   "................"
0180: 00000000 00000000 00000000 00000000   "................"
0190: 00000000 00000000 00000000 00000000   "................"
01a0: 00000000 00000000 00000000 00000000   "................"
01b0: 00000000 00000000 00000000 00000000   "................"
01c0: 00000000 00000000 00000000 00000000   "................"
01d0: 00000000 00000000 00000000 00000000   "................"
01e0: 00000000 00000000 00000000 00000000   "................"
01f0: 00000000 00000000 00000000 0000a56e   "...............n"

This is a dump of the id record before the call to ide_fix_drived() in 
the 2.4.18 kernel from cvs.

0000: 427a3fff 00000010 e1000258 003f0010   "Bz?........X.?.."
0010: 0000000e 57442d57 43414154 34343034   "....WD.WCAAT4404"
0020: 34333400 00000000 00031000 00283036   "434...........06"
0030: 2e303447 30365744 43205744 33303045   ".04G06WDC.WD300E"
0040: 422d3030 43504630 20202020 20202020   "B.00CPF0........"
0050: 20202020 20202020 20202020 20208010   "................"
0060: 00002f00 40010280 00000007 3fff0010   "....@.......?..."
0070: 003ffc10 00fb0100 ac80037e 00000407   ".?.........~...."
0080: 00030078 00780078 00780000 00000000   "...x.x.x.x......"
0090: 00000000 00000000 00000000 00000000   "................"
00a0: 003e0000 346b4b01 40003469 08014000   ".>..4kK.@.4i..@."
00b0: 003f0000 00000000 0000604b 80fe0000   ".?........`K...."
00c0: 00000000 00000000 00000000 00000000   "................"
00d0: 00000000 00000000 00000000 00000000   "................"
00e0: 00000000 00000000 00000000 00000000   "................"
00f0: 00000000 00000000 00000000 00000000   "................"
0100: 00010000 00000000 00000033 00000000   "...........3...."
0110: 00000000 00000000 00000000 00000000   "................"
0120: 00000000 00000000 00000000 00000000   "................"
0130: 00000000 00000000 00000000 0000001f   "................"
0140: 00000000 00000000 00000000 00000000   "................"
0150: 00000000 00000000 00000000 00000000   "................"
0160: 00000000 00000000 00000000 00000000   "................"
0170: 00000000 00000000 00000000 00000000   "................"
0180: 00000000 00000000 00000000 00000000   "................"
0190: 00000000 00000000 00000000 00000000   "................"
01a0: 00000000 00000000 00000000 00000000   "................"
01b0: 00000000 00000000 00000000 00000000   "................"
01c0: 00000000 00000000 00000000 00000000   "................"
01d0: 00000000 00000000 00000000 00000000   "................"
01e0: 00000000 00000000 00000000 00000000   "................"
01f0: 00000000 00000000 00000000 00006ea5   "..............n."

-- 
work -> [email-masked]	(507) 289-6910 ext 1
home -> [email-masked]

---

From: Carsten Langgaard <[email-masked]>
Date: Thu, 16 May 2002 08:54:04 +0200

I send Ralf a fix a couple of weeks ago, which introduced the byteswapping,
which really is necessary.
This fix is probably only necessary for bigendian systems with large IDE
disks (>8GB), which support LBA mode.
I send this patch over a year ago. I discovered that when I ran on a disk,
which was larger than 8GB, it was only treated as 8GB.
The problem with the fix is, it is not backward compatible. After the fix
I needed to reinstall my bigendian system.
As I told Ralf, this fix will be a pain for everyone, but I guess we need
the fix eventually.

If you don't want to reinstall your system then get rid of the code in the
"ifdef __MIPSEB__" statements in include/asm-mips/ide.h

/Carsten

--
_    _ ____  ___   Carsten Langgaard   Mailto:[email-masked]
|\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
| \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
  TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
                   Denmark             http://www.mips.com

---

From: Geert Uytterhoeven <[email-masked]>
Date: Thu, 16 May 2002 10:39:16 +0200 (MEST)

> As I told Ralf, this fix will be a pain for everyone, but I guess we need

Why would you have to reinstall the system?
Isn't this just a problem with ide_fix_driveid() (new field for disks larger
than 8 GiB, which we don't byteswap yet)?

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email-masked]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

---

From: Carsten Langgaard <[email-masked]>
Date: Thu, 16 May 2002 12:06:37 +0200

> than 8 GiB, which we don't byteswap yet)?

I'm trying to do things like other bigendian architectures. I can see your mail
address is linux-m68k and the fix is more or less stolen from the m68k part.

---

From: Geert Uytterhoeven <[email-masked]>
Date: Thu, 16 May 2002 12:57:41 +0200 (MEST)

> address is linux-m68k and the fix is more or less stolen from the m68k part.

However, I'm not sure anyone ever used a +8 GiB disk on Linux/m68k.

IIRC, LBA uses an extra field in the drive info struct, which was initially not
byteswapped. You can compare the MIPS/m68k ide_fix_driveid() with the version
on PPC, which most probably works correctly with +8 GiB disks.

Gr{oetje,eeting}s,

						Geert

---

From: Ken Aaker <[email-masked]>
Date: Thu, 16 May 2002 10:07:02 -0500

The problem with the difference isn't that it's byte swapped, its that 
the byte swapping isn't respecting the data types inside the structure. 
It fixes all of the "short" entities, but it re-orders the fields that 
happen to be two chars next to each other, and the "shorts" that are 
part of the two "ints" for lba capacity and capacity values are in the 
wrong order, even though the bytes within the "shorts" are in the right 
order. So, when the fixup code in ide.h is run, the values are still wrong.

old ----
new---

proper--- (after fix up).
0070: 003f00fb fc100001 037eac80 00000407   ".?.......~......"
0080: 00030078 00780078 00780000 00000000   "...x.x.x.x......"

Ken

---

From: Carsten Langgaard <[email-masked]>
Date: Tue, 21 May 2002 10:12:14 +0200

I just noticed that Ralf hadn't merged in the full IDE patch I send, so that's
why it doesn't work for you.
Ralf has just checked in the rest yesterday, so try check out the latest
sources and see if that helps.

/Carsten