SCSA HBA Interfaces

SCSA HBA Entry Point Summary

SCSA defines a number of HBA driver entry
points. These entry points are listed in the following table. The entry points
are called by the system when a target driver instance connected to the HBA
driver is configured. The entry points are also called when the target driver
makes a SCSA request. See Entry Points for SCSA HBA Drivers for more information.

scsi_hba_tran() Structure

Each instance of an HBA driver must allocate a scsi_hba_tran(9S) structure
by using the scsi_hba_tran_alloc(9F) function in the attach(9E) entry point. The scsi_hba_tran_alloc() function initializes the scsi_hba_tran structure.
The HBA driver must initialize specific vectors in the transport structure
to point to entry points within the HBA driver. After the scsi_hba_tran structure is initialized, the HBA driver exports the transport
structure to SCSA by calling the scsi_hba_attach_setup(9F) function.

Caution –

Because SCSA keeps a pointer to the transport structure in
the driver-private field on the devinfo node, HBA drivers
must not use ddi_set_driver_private(9F). HBA drivers can, however, use ddi_get_driver_private(9F) to retrieve the pointer to the transport structure.

The SCSA interfaces require the HBA driver to supply a number of entry
points that are callable through the scsi_hba_tran structure.
See Entry Points for SCSA HBA Drivers for
more information.

Pointer to private data maintained by the HBA driver. Usually, tran_hba_private contains a pointer to the state structure of
the HBA driver.

tran_tgt_private

Pointer to private data maintained by the HBA driver when
using cloning. By specifying SCSI_HBA_TRAN_CLONE when calling
scsi_hba_attach_setup(9F), the scsi_hba_tran(9S) structure is cloned once
per target. This approach enables the HBA to initialize this field to point
to a per-target instance data structure in the tran_tgt_init(9E) entry point. If SCSI_HBA_TRAN_CLONE is not specified, tran_tgt_private is NULL, and tran_tgt_private must not be
referenced. See Transport Structure Cloning for
more information.

tran_sd

Pointer to a per-target instance scsi_device(9S) structure used when cloning.
If SCSI_HBA_TRAN_CLONE is passed to scsi_hba_attach_setup(9F), tran_sd is initialized
to point to the per-target scsi_device structure.
This initialization takes place before any HBA functions are called on behalf
of that target. If SCSI_HBA_TRAN_CLONE is not specified, tran_sd is NULL, and tran_sd must
not be referenced. See Transport Structure Cloning for
more information.

tran_tgt_init

Pointer to the HBA driver entry point that is called when
initializing a target device instance. If no per-target initialization is
required, the HBA can leave tran_tgt_init set to NULL.

tran_tgt_probe

Pointer to the HBA driver entry point that is called when
a target driver instance calls scsi_probe(9F). This routine is called to
probe for the existence of a target device. If no target probing customization
is required for this HBA, the HBA should set tran_tgt_probe to
scsi_hba_probe(9F).

tran_tgt_free

Pointer to the HBA driver entry point that is called when
a target device instance is destroyed. If no per-target deallocation is necessary,
the HBA can leave tran_tgt_free set to NULL.

tran_start

Pointer to the HBA driver entry point that is called when
a target driver calls scsi_transport(9F).

tran_reset

Pointer to the HBA driver entry point that is called when
a target driver calls scsi_reset(9F).

tran_abort

Pointer to the HBA driver entry point that is called when
a target driver calls scsi_abort(9F).

tran_getcap

Pointer to the HBA driver entry point that is called when
a target driver calls scsi_ifgetcap(9F).

tran_setcap

Pointer to the HBA driver entry point that is called when
a target driver calls scsi_ifsetcap(9F).

tran_init_pkt

Pointer to the HBA driver entry point that is called when
a target driver calls scsi_init_pkt(9F).

tran_destroy_pkt

Pointer to the HBA driver entry point that is called when
a target driver calls scsi_destroy_pkt(9F).

tran_dmafree

Pointer to the HBA driver entry point that is called when
a target driver calls scsi_dmafree(9F).

tran_sync_pkt

Pointer to the HBA driver entry point that is called when
a target driver calls scsi_sync_pkt(9F).

Pointer to the scsi_hba_tran(9S) structure, as allocated and
initialized by the HBA driver. If SCSI_HBA_TRAN_CLONE was
specified as the flag to scsi_hba_attach_setup(9F), a_hba_tran points to a copy of that structure.

a_target

Identifies the SCSI target on the SCSI bus.

a_lun

Identifies the SCSI logical unit on the SCSI target.

scsi_device Structure

The HBA framework allocates and initializes a scsi_device(9S) structure
for each instance of a target device. The allocation and initialization occur
before the framework calls the HBA driver's tran_tgt_init(9E) entry point. This structure
stores information about each SCSI logical unit, including pointers to information
areas that contain both generic and device-specific information. One scsi_device(9S) structure
exists for each target device instance that is attached to the system.

If the per-target initialization is successful, the HBA framework sets
the target driver's per-instance private data to point to the scsi_device(9S) structure,
using ddi_set_driver_private(9F). Note that an initialization is successful if tran_tgt_init() returns success or if the vector is null.

Data structure that is passed to the routines for SCSI resource
allocation.

sd_dev

Pointer to the target's dev_info structure.

sd_mutex

Mutex for use by the target driver. This mutex is initialized
by the HBA framework. The mutex can be used by the target driver as a per-device
mutex. This mutex should not be held across a call to scsi_transport(9F) or scsi_poll(9F). See Chapter 3, Multithreading for more information on mutexes.

sd_inq

Pointer for the target device's SCSI inquiry data. The scsi_probe(9F) routine allocates
a buffer, fills the buffer in, and attaches the buffer to this field.

sd_sense

Pointer to a buffer to contain request sense data from the
device. The target driver must allocate and manage this buffer itself. See
the target driver's attach(9E) routine
in attach() Entry Point for more
information.

sd_private

Pointer field for use by the target driver. This field is
commonly used to store a pointer to a private target driver state structure.

scsi_pkt Structure (HBA)

To
execute SCSI commands, a target driver must first allocate a scsi_pkt(9S) structure
for the command. The target driver must then specify its own private data
area length, the command status, and the command length. The HBA driver is
responsible for implementing the packet allocation in the tran_init_pkt(9E) entry point.
The HBA driver is also responsible for freeing the packet in its tran_destroy_pkt(9E) entry point. See scsi_pkt Structure (Target Drivers) for more information.

Pointer to the scsi_address(9S) structure providing address
information for this command.

pkt_private

Pointer to per-packet target-driver private data.

pkt_comp

Pointer to the target-driver completion routine called by
the HBA driver when the transport layer has completed this command.

pkt_flags

Flags for the command.

pkt_time

Specifies the completion timeout in seconds for the command.

pkt_scbp

Pointer to the status completion block for the command.

pkt_cdbp

Pointer to the command descriptor block (CDB) for the command.

pkt_resid

Count of the data bytes that were not transferred
when the command completed. This field can also be used to specify the amount
of data for which resources have not been allocated. The HBA must modify this
field during transport.

pkt_state

State of the command. The HBA must modify this field during
transport.

pkt_statistics

Provides a history of the events that the command experienced
while in the transport layer. The HBA must modify this field during transport.

pkt_reason

Reason for command completion. The HBA must modify this field
during transport.

Per-Target Instance Data

An
HBA driver must allocate a scsi_hba_tran(9S) structure during attach(9E). The HBA driver must then
initialize the vectors in this transport structure to point to the required
entry points for the HBA driver. This scsi_hba_tran structure
is then passed into scsi_hba_attach_setup(9F).

The scsi_hba_tran structure contains a tran_hba_private field, which can be used to refer to the HBA
driver's per-instance state.

Each scsi_address(9S) structure contains a pointer to the scsi_hba_tran structure. In addition, the scsi_address structure
provides the target, that is, a_target, and logical unit
(a_lun) addresses for the particular target device.
Each entry point for the HBA driver is passed a pointer to the scsi_address structure, either directly or indirectly through the scsi_device(9S) structure.
As a result, the HBA driver can reference its own state. The HBA driver can
also identify the target device that is addressed.

The following figure illustrates the HBA data structures for transport
operations.

Figure 18–3 HBA Transport Structures

Transport Structure Cloning

Cloning
can be useful if an HBA driver needs to maintain per-target private data in
the scsi_hba_tran(9S) structure. Cloning can also be used to maintain a
more complex address than is provided in the scsi_address(9S) structure.

In the cloning process, the HBA driver must still allocate a scsi_hba_tran structure at attach(9E) time.
The HBA driver must also initialize the tran_hba_private soft
state pointer and the entry point vectors for the HBA driver. The difference
occurs when the framework begins to connect an instance of a target driver
to the HBA driver. Before calling the HBA driver's tran_tgt_init(9E) entry point, the framework
clones the scsi_hba_tran structure that is associated
with that instance of the HBA. Accordingly, each scsi_address structure
that is allocated and initialized for a particular target device instance
points to a per-target instance copy of the scsi_hba_tran structure. The scsi_address structures
do not point to the scsi_hba_tran structure that
is allocated by the HBA driver at attach() time.

An HBA driver can use two important pointers when cloning is specified.
These pointers are contained in the scsi_hba_tran structure.
The first pointer is the tran_tgt_private field,
which the driver can use to point to per-target HBA private data. The tran_tgt_private pointer is useful, for example, if an HBA driver
needs to maintain a more complex address than a_target and a_lun provide. The second pointer is the tran_sd field,
which is a pointer to the scsi_device(9S) structure referring to the particular target device.

When specifying cloning, the HBA driver must allocate and initialize
the per-target data. The HBA driver must then initialize the tran_tgt_private field to point to this data during its tran_tgt_init(9E) entry point.
The HBA driver must free this per-target data during its tran_tgt_free(9E) entry point.

When cloning, the framework initializes the tran_sd field
to point to the scsi_device structure before the
HBA driver tran_tgt_init() entry point is called. The
driver requests cloning by passing the SCSI_HBA_TRAN_CLONE flag
to scsi_hba_attach_setup(9F). The following figure illustrates the HBA data structures
for cloning transport operations.

Figure 18–4 Cloning Transport Operation

SCSA HBA Functions

SCSA also provides a number
of functions. The functions are listed in the following table, for use by
HBA drivers.