Search:  
Gentoo Wiki

Adaptec_aic94xx_RAID_controller

This article is part of the Hardware series.
Laptops TV Tuner Cards Wireless Servers Storage Other Hardware Motherboards Related

Contents

Overview

This article will only show how to get the bootable RAID1 on the aic94xx controller with SATA drivers working, thus it is assumed that the reader is familiar with software RAID1 under Linux. If not the following pages give an excellent overview and introduction: HOWTO Install on Software RAID and HOWTO Migrate To RAID.

Warning: This article shows how to get the job done - it breaks the upgrade path!

Why is to so problematic?

At the time of editing the newest kernel release is 2.6.22. Unfortunately, it does not provide support for SATA drives in the aic94xx module. On top of that, the driver relies on an external firmware file that has to be loaded when the module is inserted. While it is trivial to do it for non-root devices, it becomes rather tricky for root devices. More about that will be shown later on. The other thing is the installation process - you need to see your disks to do anything. That is quite tricky. We used an USB hard drive where we installed Gentoo and compiled the right kernel first. After that we moved the thing on newly created RAID1 partitions.


Tip: You do not need to perform modifications of the initramfs and genkernel scripts just to be able to see the disks! For that it is enough you compile the kernel mentioned in this article, get the firmware and boot the machine from the USB disk. You can load the module manually - then you will see all the disks - from that point this manual is something you need.

How was it tested?

Gentoo 2007.0 Minimal Install CD for amd64, Adapted aic9410 controller (Supermicro motherboard) equipped with 7 SATA disks. Kernel and base installation performed on the USB disk, then transferred to the target machine (when the disks were visible).

Getting the right kernel

As it was mentioned before the 2.6.22 kernel release does not support SATA drivers (the non-SATA aware driver will complain saying: "Unidentified device type 5"). To get the right kernel you should follow the first step as shown on the forum. Necessary steps are also presented below. You should firstly get cogito and genkernel:

Code: emerging cogito
# emerge -av cogito
# emerge genkernel

Once you have cogito follow these steps to get the right kernel (taken from the forum referenced above):

Code: Obtaining the kernel
$ cg-clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
$ cd linux-2.6
$ cg-branch-add scsi-misc git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
$ cg-branch-add scsi-rc git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git
$ cg-branch-add aic94xx git://git.kernel.org/pub/scm/linux/kernel/git/jejb/aic94xx-sas-2.6.git
$ cg-update scsi-misc
$ cg-update scsi-rc
$ cg-update aic94xx

Compiling the kernel

You should definitely use genkernel to compile your new kernel. Move the newly downloaded kernel into /usr/src and make shure you create the proper symbolic link to the directory (which will be called Linux-2.6. Before you start you should modify a little bit genkernel's scripts. Yes - this is the dangerous part that breaks the upgrade path. More to come...

Modifying genkernel's scripts

To load the firmware you need either hotplug support or udev - none of them is available at the time when SCSI drivers are loaded. Apart from that you need the sysfs - otherwise there is no way for the script to load the firmware.

Note: The sysfs loading structure APPEARS only when the module is inserted. The script is using environment variables to figure out the upload path and firmware file. Please see the source of /sbin/hotplug script for more details.

With your favourite editor open the following file: /usr/share/genkernel/generic/linuxrc. Find the following part:

File: /usr/share/genkernel/generic/linuxrc
# Mount sysfs
mount_sysfs

# Delay if needed for USB hardware
sdelay

It is just enough if you look for the phrase "mount_sysfs". You have to put three more lines there so that it looks like that:

File: /usr/share/genkernel/generic/linuxrc
# Mount sysfs
mount_sysfs

echo /sbin/hotplug > /proc/sys/kernel/hotplug
echo -n "   :: Starting aic94xx magic..."
modprobe aic94xx

# Delay if needed for USB hardware
sdelay

The default action to handle firmware loading (used by the FW_LOADER in the kernel) is to let hotplug do it. At that point the /proc/sys/kernel/hotplug does not contain any path. The /sbin/hotplug script should look like that (where to put it will be shown later on - do not worry!):

File: /sbin/hotplug
#!/bin/sh

# Simple hotplug script sample:
# 
# Both $DEVPATH and $FIRMWARE are already provided in the environment.

HOTPLUG_FW_DIR=/lib/firmware/

if [ ! -e /sys/$DEVPATH/loading ]; then 
   echo /sys not found
   exit 1
fi

echo 1 > /sys/$DEVPATH/loading
cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
echo 0 > /sys/$DEVPATH/loading

# To cancel the load in case of error:
#
#       echo -1 > /sys/$DEVPATH/loading
#

Now the tricky part: you have to modify the list of loaded modules, so that your aic94xx module is put on the initramfs. The problem is that afterwards you can't use the "doscsi" kernel parameter, because then the script will try to load the aic94xx module when there is neither hotplug nor sysfs.

FIXME: Would be nice if somebody figured out how to do it so that tha aic94xx is put on the initramfs, but isn't loaded when passing doscsi as kernel arg.

To do so you modify the /usr/share/genkernel/YOUR_ARCH/modules_load file - just add aic94xx at the end of MODULES_SCSI variable. Substitute YOUR_ARCH with your architecture (in my case x86_64). Now you can start compiling the kernel.

Compiling with genkernel

Code: Invoking genkernel
# genkernel --menuconfig all

You want to use `--menuconfig` switch, because you HAVE TO set some things manually. Be sure that you select the following modules:

Once you've done that - finish configuring the kernel and let genkernel do the remaining job for you. If the configuration breaks and you notice references to sas and libsas - it means you are missing SATA support (you were supposed to add it? :).

Firmware and initramfs modifications

Adaptec's firmware is available on their web pages. You need to accept the license before you can download it. It can be fetched from Adaptec's site.

FIXME: Can this link be here? Is it OK with Adaptec's license?

There are some rumours about available firmware versions - the final conclusion is that the newest one is not the best one. I did not have any problems with the firmware referenced above (at least not until now). There is also a GPL'ed version of the firmware - hopefully it will be merged with the kernel in future releases.

Adding firmware and hotplug script to the initramfs

My friend (and boss :) Lars created a very nice script that does this thing automatically. Please do the following just to get it working:

Code: Installing Lars' script
# cd /root
# mkdir aic_support 

Copy the firmware and hotplug script to /root/aic_support. Be sure, that the hotplug script has executable bit set! The /root/aic_support/add_firmware script looks as follows:

File: add_firmware script
#!/bin/bash
 
if test $# -ne 1
then
   echo Usage: add_firmware initramfs_file
   exit 1
fi

if ! test -f $1
then
   echo initramfs file [$1] not found
   exit 1
fi

if test -f $1.orig
then
   echo initramfs file backup file [$1.orig] already exists
   exit 1
fi


mkdir /tmp/initrd
cd /tmp/initrd
zcat $1 | cpio -i
if test -f lib/firmware/aic94xx-seq.fw
then
   echo lib/firmware/aic94xx-seq.fw already present in initramfs
   exit 1
fi
mkdir -p lib/firmware
cp /root/aic_support/aic94xx-seq.fw lib/firmware
cp /root/aic_support/hotplug sbin/hotplug
mv $1 $1.orig
find . | cpio --quiet -o -H newc | gzip -9 > $1
cd /tmp
rm -r initrd

Once you have that you can run the script so that the firmware and the hotplug scripts are added to the initramfs image:

Code: Running the script
# cd /root/aic_support/
# ./add_firmware /boot/initramfs-YOUR_INITRAMFS_FILE

The script will unpack the initramfs, modify it, compress again and put back into /boot. The original initramfs will be renamed to WHATEVER_IT_WAS.orig. Reboot and hope it works ;) You can also check if it was REALLY modified afterwards.

Code: Checking the initramfs
# mkdir /tmp/initramfs-test
# cd /tmp/initramfs-test
# zcat /boot/your-initramfs | cpio -i
# cat init | grep aic94xx 
# ls lib/modules/YOUR-KERNEL/kernel/drivers/scsi/aic94xx/aic94xx.ko
# ls sbin/hotplug
# ls lib/firmware/aic94xx-seq.fw

If all files exist and modifications are present - you can proceed with a reboot.

Final comments

The method described here is not upgrade-safe, as it modifies some core scripts and so on. It is possible to get mdev (busybox's udev-hotplug-thingy) to do the same (there is a patch) - but that involves many more steps and patching BusyBox's source file (more mess means in general more problems). We got it working also this way - but you are on your own.

Warning: You DO NEED any kind of RAID because somehow every time we reboot the machine disks get DIFFERENT device names. Only RAID is able to assemble such circus back into a working state. What I mean here is that: before reboot you have the first disk at /dev/sda, after a reboot it can be /dev/sdh or /dev/sdb... or who knows. RAID is looking on superblocks, checking UUIDs and assembling the thing back regardless of device names. Your /dev/md[0-9]+ will always be the one you want. mdadm in this case is your best friend.

<math>Insert formula here</math>


/ # !! Could not find the root block device in . Please specify another value or: press Enter for the same, type "shell" for a sh ell, or "q" to skip... root block device() :: _

Retrieved from "http://www.gentoo-wiki.info/Adaptec_aic94xx_RAID_controller"

Last modified: Sun, 31 Aug 2008 08:18:00 +0000 Hits: 4,779