FreeBSD Handbook : Managing hardware : SCSI : Using SCSI with FreeBSD
Previous: Components of SCSI
Next: Tracking down problems

9.2.2. Using SCSI with FreeBSD

9.2.2.1. About translations, BIOSes and magic...

As stated before, you should first make sure that you have a electrically sound bus.

When you want to use a SCSI disk on your PC as boot disk, you must aware of some quirks related to PC BIOSes. The PC BIOS in it's first incarnation used a low level physical interface to the hard disk. So, you had to tell the BIOS (using a setup tool or a BIOS built-in setup) how your disk physically looked like. This involved stating number of heads, number of cylinders, number of sectors per track, obscure things like precompensation and reduced write current cylinder etc.

One might be inclined to think that since SCSI disks are smart you can forget about this. Alas, the arcane setup issue is still present today. The system BIOS needs to know how to access your SCSI disk with the head/cyl/sector method.

The SCSI host adapter or SCSI controller you have put in your AT/EISA/PCI/whatever bus to connect your disk therefore has it's own on-board BIOS. During system startup, the SCSI BIOS takes over the hard disk interface routines from the system BIOS. To fool the system BIOS, the system setup is normally set to No hard disk present. Obvious, isn't it?

The SCSI BIOS itself presents to the system a so called translated drive. This means that a fake drive table is constructed that allows the PC to boot the drive. This translation is often (but not always) done using a pseudo drive with 32 heads and 64 sectors per track. By varying the number of cylinders, the SCSI BIOS adapts to the actual drive size. It is useful to note that 32 * 64 / 2 = the size of your drive in megabytes. The division by 2 is to get from disk blocks that are normally 512 bytes in size to Kbytes.

Right.. All is well now?! No, it isn't. The system BIOS has another quirk you might run into. The number of cylinders of a bootable hard disk cannot be greater than 1024. Using the translation above, this is a show-stopper for disks greater than 1 Gb. With disk capacities going up all the time this is causing problems.

Fortunately, the solution is simple: just use another translation, e.g. with 128 heads instead of 32. In most cases new SCSI BIOS versions are available to upgrade older SCSI host adapters. Some newer adapters have an option, in the form of a jumper or software setup selection, to switch the translation the SCSI BIOS uses.

It is very important that all operating systems on the disk use the same translation to get the right idea about where to find the relevant partitions. So, when installing FreeBSD you must answer any questions about heads/cylinders etc using the translated values your host adapter uses.

Failing to observe the translation issue might be un-bootable systems or operating systems overwriting each others partitions. Using fdisk you should be able to see all partitions.

As promised earlier: what is this talk about 'lying' devices? As you might already know, the FreeBSD kernel reports the geometry of SCSI disks when booting. An example from one of my systems:

Feb  9 19:33:46 yedi /386bsd: aha0 targ 0 lun 0: <MICROP  1588-15MB1057404HSP4>
Feb  9 19:33:46 yedi /386bsd: sd0: 636MB (1303250 total sec), 1632 cyl, 15 head,
 53 sec, bytes/sec 512
          

This info is retrieved from the SCSI disk itself. Newer disks often use a technique called zone bit recording. The idea is that on the outer cylinders of the drive there is more space so more sectors per track can be put on them. This results in disks that have more tracks on outer cylinders than on the inner cylinders and, last but not least, have more capacity. You can imagine that the value reported by the drive when inquiring about the geometry now becomes fake.

9.2.2.2. SCSI subsystem design

FreeBSD uses a layered SCSI subsystem. For each different controller card a device driver is written. This driver knows all the intimate details about the hardware it controls. The driver has a interface to the upper layers of the SCSI subsystem through which it receives it's commands and reports back any status.

On top of the card drivers there are a number of more generic drivers for a class of devices. More specific: a driver for tape devices (abbreviation: st), magnetic disks (sd), cdroms (cd) etc. In case you are wondering where you can find this stuff, it all lives in /sys/scsi. See the man pages in section 4 for more details.

The multi level design allows a decoupling of low-level bit banging and more high level stuff. Adding support for another piece of hardware is a much more managable problem.

9.2.2.3. Kernel configuration

Dependent on your hardware, the kernel configuration file must contain one or more lines describing your host adapter(s). This includes I/O addresses, interrupts etc. Consult the man page for your adapter driver to get more info. Apart from that, check out /sys/i386/conf/LINT for an overview of a kernel config file. LINT contains every possible option you can dream of. It does not imply LINT will actually get you to a working kernel at all.

Although it is probably stating the obvious: the kernel config file should reflect your actual hardware setup. So, interrupts, I/O addresses etc must match the kernel config file. During system boot messages will be displayed to indicate whether the configured hardware was actually found.

An example loosely based on the FreeBSD 2.0.5-Release kernel config file LINT with some added comments (between []):

		
# SCSI host adapters: `aha', `ahb', `aic', `bt', `nca'
#
# aha: Adaptec 154x
# ahb: Adaptec 174x
# ahc: Adaptec 274x/284x/294x
# aic: Adaptec 152x and sound cards using the Adaptec AIC-6360 (slow!)
# bt: Most Buslogic controllers
# nca: ProAudioSpectrum cards using the NCR 5380 or Trantor T130
# uha: UltraStore 14F and 34F
# sea: Seagate ST01/02 8 bit controller (slow!)
# wds: Western Digital WD7000 controller (no scatter/gather!).
#

[For an Adaptec AHA274x, 284x etc controller]
controller	ahc0	at isa? bio irq ? vector ahcintr # port??? iomem?

[For an Adaptec AHA174x controller]
controller	ahb0	at isa? bio irq ? vector ahbintr

[For an Ultrastor adapter]
controller	uha0	at isa? port "IO_UHA0" bio irq ? drq 5 vector uhaintr

# Map SCSI buses to specific SCSI adapters
controller	scbus0	at ahc0
controller	scbus2  at ahb0
controller	scbus1  at uha0

# The actual SCSI devices
disk sd0 at scbus0 target 0 unit 0	[SCSI disk 0 is at scbus 0, LUN 0]
disk sd1 at scbus0 target 1		[implicit LUN 0 if omitted]
disk sd2 at scbus1 target 3		[SCSI disk on the uha0]
disk sd3 at scbus2 target 4		[SCSI disk on the ahb0]
tape st1 at scbus0 target 6		[SCSI tape at target 6]
device cd0 at scbus?			[the first ever CDROM found, no wiring]

	  

The example above tells the kernel to look for a ahc (Adaptec 274x) controller, then for an Adaptec 174x board, and so on. The lines following the controller specifications tell the kernel to configure specific devices but only attach them when they match the target ID and LUN specified on the corresponding bus.

So, if you had a SCSI tape at target ID 2 it would not be configured, but it will attach when it is at target ID 6.

Below is another example of a kernel config file as used by FreeBSD version < 2.0.5. The difference with the first example is that devices are not 'wired down'. 'Wired down' means that you specify which SCSI target belongs to which device.

A kernel built to the config file below will attach the first SCSI disk it finds to sd0, the second disk to sd1 etc. If you ever removed or added a disk, all other devices of the same type (disk in this case) would 'move around'. This implies you have to change /etc/fstab each time.

Although the old style still works, you are strongly recommended to use this new feature. It will save you a lot of grief whenever you shift your hardware around on the SCSI buses. So, when you re-use your old trusty config file after upgrading from a pre-FreeBSD2.0.5.R system check this out.

controller      ahb0    at isa? bio irq 11 vector ahbintr	[driver for Adaptec 174x]
controller      aha0    at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr [for Adaptec 154x]
controller      sea0    at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector seaintr [for Seagate
ST01/02]
controller      scbus0

device          sd0	[support for 4 SCSI harddisks, sd0 up sd3]
device          sd1
device          sd2
device          sd3

device          st0	[support for 2 SCSI tapes]
device          st1

device          cd0     #Only need one of these, the code dynamically grows [for the cdrom]
          

Both examples support 4 SCSI disks. If during boot more devices of a specific type (e.g. sd disks) are found than are configured in the booting kernel, the system will complain. You will have to build and boot a new kernel (after adapting the kernel configuration file) before you can use all of the devices. It does not hurt to have 'extra' devices in the kernel, the example above will work fine when you have only 2 SCSI disks.

Use man 4 scsi to check for the latest info on the SCSI subsystem. For more detailed info on host adapter drivers use eg man 4 aha for info on the Adaptec 154x driver.

9.2.2.4. Tuning your SCSI kernel setup

Experience has shown that some devices are slow to respond to INQUIRY commands after a SCSI bus reset. An INQUIRY command is sent by the kernel on boot to see what kind of device (disk, tape, cdrom etc) is connected to a specific target ID. This process is called device probing by the way.

To work around this problem, FreeBSD allows a tunable delay time before the SCSI devices are probed following a SCSI bus reset. You can set this delay time in your kernel configuration file using a line like:

options         "SCSI_DELAY=15"         #Be pessimistic about Joe SCSI device
	  
This line sets the delay time to 15 seconds. On my own system I had to use 3 seconds minimum to get my trusty old CDROM drive to be recognized. Start with a high value (say 30 seconds or so) when you have problems with device recognition. If this helps, tune it back until it just stays working.

9.2.2.5. Rogue SCSI devices

Although the SCSI standard tries to be complete and concise, it is a complex standard and implementing things correctly is no easy task. Some vendors do a better job then others.

This is exactly where the 'rogue' devices come into view. Rogues are devices that are recognized by the FreeBSD kernel as behaving slightly (...) non-standard. Rogue devices are reported by the kernel when booting. An example for two of my cartridge tape units:

Feb 25 21:03:34 yedi /386bsd: ahb0 targ 5 lun 0: <TANDBERG TDC 3600       -06:>
Feb 25 21:03:34 yedi /386bsd: st0: Tandberg tdc3600 is a known rogue

Mar 29 21:16:37 yedi /386bsd: aha0 targ 5 lun 0: <ARCHIVE VIPER 150  21247-005>
Mar 29 21:16:37 yedi /386bsd: st1: Archive  Viper 150 is a known rogue
	 

For instance, there are devices that respond to all LUNs on a certain target ID, even if they are actually only one device. It is easy to see that the kernel might be fooled into believing that there are 8 LUNs at that particular target ID. The confusion this causes is left as an exercise to the user.

The SCSI subsystem of FreeBSD recognizes devices with bad habits by looking at the INQUIRY response they send when probed. Because the INQUIRY response also includes the version number of the device firmware, it is even possible that for different firmware versions different workarounds are used.

This scheme works fine, but keep in mind that it of course only works for devices that are KNOWN to be weird. If you are the first to connect your bogus Mumbletech SCSI cdrom you might be the one that has to define which workaround is needed.

9.2.2.6. Busmaster host adapters

Most, but not all, SCSI host adapters are bus mastering controllers. This means that they can do I/O on their own without putting load onto the host CPU for data movement.

This is of course an advantage for a multitasking operating system like FreeBSD. It must be noted however that there might be some rough edges.

For instance an Adaptec 1542 controller can be set to use different transfer speeds on the host bus (ISA or AT in this case). The controller is settable to different rates because not all motherboards can handle the higher speeds. Problems like hangups, bad data etc might be the result of using a higher data transfer rate then your motherboard can stomach.

The solution is of course obvious: switch to a lower data transfer rate and try if that works better.

In the case of a Adaptec 1542, there is an option that can be put into the kernel config file to allow dynamic determination of the right, read: fastest feasible, transfer rate. This option is disabled by default:

options        "TUNE_1542"             #dynamic tune of bus DMA speed
	  

Check the man pages for the host adapter that you use. Or better still, use the ultimate documentation (read: driver source).


FreeBSD Handbook : Managing hardware : SCSI : Using SCSI with FreeBSD
Previous: Components of SCSI
Next: Tracking down problems