Re: Command Tag Queueing

Doug Ledford (dledford@dialnet.net)
Mon, 24 Nov 1997 20:11:41 -0600 (CST)


On 24-Nov-97 David S. Miller wrote:
> Date: Mon, 24 Nov 1997 15:10:08 -0800 (PST)
> From: "SethMeister G." <seth@home.com>
>
> I was wondering if anyone knew of any papers regarding the
> implementation of command tag queueing as it relates to the SCSI
> disk device drivers.
>
>Unfortunately the best places for info is the actual code. Command
>tag queueing is (I think) implemented best in the BusLogic and
>qlogicpti drivers. So those two drivers are a good place to look.

As it relates to the linux kernel implementation, the best place is the
code. As to command tagged queueing in general, you can always look in the
SCSI 2 spec or later. As far as linux is concerned, here are a few of the
major points:

The low-level driver controls the queue depth on a per device basis through
the use of the select_queue_depth function.

Only devices that indicate they support tagged queueing in their mode pages
can use tagged queueing, others should be treated as non-tagged devices.

The mid level SCSI code makes no attempt to keep track of the particular
command number assigned to tagged commands, this is stricltly done in the
low level driver.

It is sufficient to assign arbitrary unique tag values to tagged commands
within the valid range of the command identifier byte. The driver must be
responsible for keeping track of assigned command values and releasing those
values back for use when the command is complete.

The way to get the mid level code to treat a driver in a fasion that allows
for tagged queueing is to make sure that the device->queue_depth value is
whatever queue depth you want for that device (set at the
select_queue_depth time), and also make sure that the host adapter is
registered with a reasonable queue depth (host->can_queue is the total
number of commands that this controller can handle for all devices at one
time, which can be arbitrarily high). As a side note, the can_queue depth
set by the driver may never be reached if the combined device->queue_depth
for all devices on that controller is not sufficient to reach the
host->can_queue limit. In other words, the can_queue value is an upper
bound on the number of commands that will go out to this controller at one
time, but the device->queue_depth value is the upper bound for each
individual device. The actual maximum number of commands sent to the driver
could be expressed as follows:

MINIMUM(host->can_queue, SUM(device->queue_depth)) for all devices attached
to this controller

Once this is done, then all that remains is for the adapter's queue routine
to accept the incoming SCSI requests from the mid level code. Upon receipt
of a command from the mid level code, there is a boolean value set in the
Scsi_Cmnd structure to indicate if tagged queueing should be used. If set,
you need to make sure that the actual SCSI command passed to the device is
built with the proper TAGGED_COMMAND bits set and a value specified. This
is purely host controller dependant. Additionally, since it is not valid
for the SCSI controller to issue both tagged and untagged commands to a
device at the same time (except during a contingent allegience situation),
once a device starts using tagged commands, it should be using them from
that point on with no exceptions from the mid level SCSI code. If a driver
ever receives an untagged command for a device with outstanding tagged
commands, that command *MUST* be held until after the tagged commands have
completed unless you want to blow apart the established I_T_L_x nexuses you
already have.

A quick note about the difference between tagged and untagged commands. The
SCSI bus uses what is referred to as I_T_L and I_T_L_x nexus arenas to keep
track of commands between the controller and the device. In the above
acronyms, I is initiator (or host controller), T is target (usually
expressed as the SCSI ID of the target device), and L is the lun of the
target. As is evident, the only difference between tagged and untagged
commands is the type of nexus used. Untagged uses an I_T_L nexus and tagged
commands use an I_T_L_x nexus, where the x is the tagged command identifier
(an unsigned char representation is appropriate here). Without the tagged
command, then only one I_T_L nexus can exist between the host controller and
a device at a time, hence only one command can be outstanding to the device
at one time.

----------------------------------
E-Mail: Doug Ledford <dledford@dialnet.net>
Date: 24-Nov-97
Time: 20:11:42
----------------------------------