March 21, 2019

The Linux Kernel's SCSI Subsystem

Introducing the Linux Kernel's SCSI Subsystem

  • September 3, 2002
  • By Dee-Ann LeBlanc

Many Linux users don't have any SCSI hardware, so may not even be aware that there is anything amiss with the SCSI subsystem. SCSI is mostly used amongst businesses, developers, and higher end power users who need access to the additional write speed and reliability SCSI provides, and are capable of paying the higher price for those features.

Some people predict that SCSI will fade over time as IDE drives get faster and remain cheaper, or bow to newer protocols like USB 2.0. Whether you agree with this or not, this doesn't change the fact that the SCSI devices in existence will be around for some time, and Linux needs to support them as well as it can especially to improve its enterprise-level capabilities. Not to mention the fact that the USB mass storage system actually functions under the kernel hood as a Lower Layer (more about this soon) SCSI driver!

Plus, let's face it. If there's a weakness, it needs to be fixed. Often each of the different Linux kernel development teams can learn from the others' triumphs, as well.

I'm not going to spend a lot of time on SCSI itself here, except where necessary to explain the various issues the kernel team is contending with. But I do have to get you up to speed on some Linux kernel basics, and some SCSI subsystem basics, before we can proceed.

Remember that the Linux kernel, or any kernel really, is the base operating system itself. The kernel is what makes Linux Linux, just as a Windows or FreeBSD kernel is what makes those operating systems what they are. One function of a kernel is to find a way to interact with the various hardware devices attached to a machine, and this is typically done with "device drivers," which we hear about pretty regularly in the Linux world.

SCSI is made up of devices, so what we're interested in first is how the Linux kernel interacts with devices in general, and then specifically how it interacts with SCSI devices. Most device drivers in Linux are kernel modules, though they can (usually) also be compiled directly into the kernel itself. All modules are files, and so is everything else as far as Linux is concerned: one of the first things you learn when you're really trying to dig into Linux filesystems is that everything is a file. Everything.

Every device on your system and many that aren't physically thereis represented by a file in the /dev directory. There are three types of devices: block, character, and network. Block devices are dealt with in chunks, and typically are storage items, such as disks. Character devices, on the other hand, deal with individual bits and bytes usually processed right away. In the character device world you'll find anything from monitors to keyboards. Network devices are, well, Ethernet cards and so on, as you might expect.

You can often recognize a SCSI device in the /dev directory by the fact that its entry begins with "s", but that's not a hard and fast rule and applies mostly to storage devices such as hard drives.

Think of each of these files as a door that the kernel uses to talk back and forth with the hardware in your machine. For example, if you have a SCSI hard drive, it's probably /dev/sda, and then it's probably broken down further into partitions: perhaps /dev/sda1, /dev/sda2, and /dev/sda3.

If the kernel sends instructions to do anything--maybe to write some data to /dev/sda2it sends the instructions and the data through the door in that location. That door leads to the module that's handling /dev/sda2, which is the device driver for that specific make and model of SCSI drive. Now that we've reached the device driver, we're finally getting into the SCSI subsystem itself.

Let me start here by saying that I'm referring to the kernel 2.4.x SCSI subsystem. This subsystem functions on three separate levels, creatively named Upper, Middle, and Lower (hey, the idea is to be straightforward, right?). The higher up you go, the closer to the user you get, and (almost) any interaction with the SCSI subsystem involves a chain reaction either going down from Upper to Middle to Lower in the case of something sparked by the user, or up from Lower to Middle to Upper if it's sending feedback. So you're dealing with three different drivers for any SCSI interaction.

To return to the metaphor I was using before, the door, the /dev location for your driver, is the entrance to the Upper level driver. There are four of these Upper level SCSI drivers: two for block devices (sd for disks and sr for CD-ROMs), and two for character devices (st for tapes and sg for other character devices). Note that your door points the way, since these four two-letter combinations signal the starting letters for your /dev names, like /dev/sda3 and /dev/sr0.

No matter what kind of SCSI device you're using, the Middle level driver is essentially the same. This is called the "unifying layer" and is the Swiss Army Knife of the Linux kernel's SCSI subsystem. The Middle levelheavily simplifiedcoordinates the efforts of loading the appropriate device drivers at boot time, runs the SCSI command queue for all commands coming to and from devices, handles errors from the devices, and more.

The Lower level drivers are the ones that you have to go out and find at times. These are the actual kernel modules, with names like aic7xxx (type