Please consider a donation to the Higher Intellect project. See or the Donate to Higher Intellect page for more info.

Adaptec 2944 WD SCSI Adapter Hack

From Higher Intellect Wiki
Jump to navigation Jump to search

The following "Bad Idea" was written up and placed on this page by me, but it was thought up and originally documented by Robert Banz and is reprinted here with his permission.

Also, Robert would like it pointed out that he does not think this is a "Bad Idea." And quite honestly, I agree. Of course, if you didn't know what you were doing when you decided to attempt to modify your kernel object modules with the included PERL script, it would indeed be a BAD idea. But other than that, I'd have to say this far exceeds anything else I've got on my page in overall usefulness. Please use and enjoy.

From: [email protected] (Robert Banz)
Newsgroups: comp.sys.sgi.hardware
Subject: 2944 on an O2 -- "hack of the week"
Date: 19 Apr 1999 08:20:08 -0400

Here's my hack of the week for everyone :)

The question: How to get an Adaptec 2944 WD SCSI adapter to work on an O2.

First, the 2944 is pretty much identical to the 2940 (which is supported), with the exception of it's differential-ness. Same chipset, etc. So, the question isn't necessarily getting it to deal with the chipset, the problem is getting the driver to recognize the PCI device as an adaptec card...

After playing for awhile, I found out that the embedded PCI device ID (we'll stay away from the vendor IDs right now, since they're all going to be the same anyhow, Adaptec's (0x9004)) was 0x8078 (that's 32888 in hex, from the hinv -v, also found in /hw/.id/pci !), and my AHA2944's ID was 0x8478. After grubbing though the ahc78.o object file with "od", I found the vendor code for the embedded controller, and in close vicinity, the makings of what seemed to be another device ID for a supported controller, 0x8178 (* found later to be the 2940U).

So, I wrote the cheezy little perl script, included in the end here, to grub through the object file and replace the 2940U's ID with the 2944U's ID, rebuilt my kernel, and, wow, it actually detected the device. What's more exciting, is, it actually seemed to work -- hooked a few disks up to it and began pounding away without fail :)

I figured afterwards I'd check out the validity of what I was doing, by taking a look at the FreeBSD aha78xx family device driver, to look for possible differences in the accessing of the 2940U & the 2944U, and found nothing in the code that seems to "care" about which one it's using.

It's reasonable to assume that it'll probably work for other aic7880, Adaptec branded controllers (398xU, 394xU & 294xU) models -- for reference, here's the appropriate device ID's from the FreeBSD code:

#define PCI_DEVICE_ID_ADAPTEC_398XU     0x83789004ul 
#define PCI_DEVICE_ID_ADAPTEC_3940U     0x82789004ul 
#define PCI_DEVICE_ID_ADAPTEC_2944U     0x84789004ul 
#define PCI_DEVICE_ID_ADAPTEC_2940U     0x81789004ul

....and here's a little perl script that will munge through the object file for you and replace the first occurrence of 0x8178 with 0x8478. Run it on /var/sysgen/boot/adp78.o.


$in = $ARGV[0]; 
$out = $ARGV[1];

open(IN, "<$in"); 
open(OUT, ">$out");

$j = 0;

while( (read(IN, $buf, 2 ) > 0 )){ 
        ( $a, $b ) = unpack("CC", $buf ); 
        if (( $a == 0x81 ) && ( $b == 0x78 ) && ( $j == 0 )) { 
                print "replaced...\n"; 
                $a = 0x84; 
        print OUT pack("CC", $a, $b); 
close IN; 
close OUT;

(of course, no guarantees, expressed or implied -- it could very well ruin your data, or set your disk on fire. All I know is it's working flawlessly for me...)

if the first occurrence of 0x8178 just needs to be replaced with 0x8478 you could modify it via a hex editor.

[Megumi:~] neko 13% od -x /var/sysgen/boot/adp78.o | grep 8178
0014420 3405 8178 0000 3825 3c06 0000 0c00 0000
0015260 3409 8178 1049 0065 0240 2025 0000 2825

See Also