Solaris 7 Software Developer Supplement

Chapter 2 Software Developer

This chapter describes the following software development information:


Note -

For the most up-to-date man pages, use the man command. The Solaris 7 11/99 man pages include new feature information not found in the Solaris 7 Reference Manual Collection.


SPARC: DR Support for SCSI HBA Drivers

This functionality is new in the Solaris 7 11/99 software release.

In this release, dynamic reconfiguration (DR) support has been updated for SCSI devices. SCSI HBA drivers no longer require a cb_ops structure to support dynamic reconfiguration, as was previously described in, "Converting Device Drivers to Support Hot-plugging" in Writing Device Drivers.

New Default SCSI HBA Driver Entry Points

To support the minimal set of hot-plugging operations, drivers might need to implement support for bus quiesce, bus unquiesce, and reset. The scsi_hba_tran(9S) structure has been extended to support these new operations. If quiesce/unquiesce/reset is not required by hardware, no driver changes are needed.

The following new fields have been added to the scsi_hba_tran structure:

		int (*tran_quiesce)(dev_info_t *hba_dip);
		int (*tran_unquiesce)(dev_info_t *hba_dip);
		int (*tran_bus_reset)(dev_info_t *hba_dip, int level);

The new driver entry points are introduced in the following sections.

tran_quiesce() and tran_unquiesce()

Quiesce and unquiesce a SCSI bus.

		#include <sys/scsi/scsi.h>

		int prefixtran_quiesce(dev_info_t *hba_dip);

		int prefixtran_unquiesce(dev_info_t *hba_dip);

tran_quiesce(9E) and tran_unquiesce(9E) are required to be implemented by an HBA driver to support dynamic reconfiguration (DR) of SCSI devices on buses that were not designed to support hot-plugging.

The tran_quiesce() and tran_unquiesce() vectors in the scsi_hba_tran(9S) structure should be initialized during the HBA driver's attach(9E) to point to HBA entry points so they are called when a user initiates quiesce and unquiesce operations.

tran_quiesce(9E) is called by the SCSA framework to stop all activity on a SCSI bus prior to and during the reconfiguration of devices attached to the SCSI bus. tran_unquiesce(9E) is called by the SCSA framework to resume activity on the SCSI bus after the reconfiguration operation has been completed.

HBA drivers are required to handle tran_quiesce(9E) by waiting for all outstanding commands to complete before returning success. After the HBA has quiesced the bus, it must queue any new I/O requests from target drivers until the SCSA framework calls the corresponding tran_unquiesce(9E) entry point.

HBA drivers handle calls to tran_unquiesce(9E) by starting any target driver I/O requests that were queued by the HBA during the time the bus was quiesced.

tran_bus_reset()

tran_bus_reset(9E) must reset the SCSI bus without resetting targets.

		#include <sys/scsi/scsi.h>

		int prefixtran_bus_reset(dev_info_t *hba_dip, int level);

Where level is:

RESET_BUS

reset the SCSI bus only, not the targets

The tran_bus_reset() vector in the scsi_hba_tran(9S) structure should be initialized during the HBA driver's attach(9E) to point to an HBA entry point to be called when a user initiates a bus reset.

Implementation is hardware specific. If it is not possible to reset the SCSI bus without affecting the targets, the HBA driver should fail RESET_BUS or not initialize this vector.

For more information, see "Converting Device Drivers to Support Hot-plugging" in the book Writing Device Drivers.

Special Issues with PCI Hot-plugging Drivers

This functionality is new in the Solaris 7 11/99 software release.

Some PCI device drivers for the Intel platform are written with the assumption that the values in the registers are valid after the POWER ON cycle. However, you cannot assume that the BIOS has correctly initialized the hardware.

For more information on hot-plugging, see "Converting Device Drivers to Support Hot-plugging" in the book Writing Device Drivers.

8-bit Visual Support

This functionality is new in the Solaris 7 8/99 software release.

The 8-bit visual shared library provides a set of translation functions, enabling 8-bit visual applications to run on hardware that only provides support for 24-bit visual depth. The functions use the device driver's native 24-bit rendering function calls for applications requesting 8-bit visual support. This is done by translating 8-bit pseudocolor colormap pixel data into 24-bit truecolor colormap pixel data before rendering an image on the 24-bit hardware visual supported platform.

64-bit Developer's Guide Updates

This information was new in the Solaris 7 3/99 software release.

The following updates are in the Solaris 7 64-bit Developer's Guide.

DDI Interfaces for Cluster-Aware Drivers

This feature was new in the Solaris 7 3/99 software release.

The device node types supported by the Solaris operating environment can be divided into two categories: physical and pseudo devices. This categorization is important when the device nodes are created and used by SunTM Cluster.

The concept of device classes and the necessary interface modifications and additions are introduced in the 3/99 release of the Solaris operating environment so that device driver writers can adopt the new interfaces for use with future versions of Sun Cluster. The device classes will not have an impact on Solaris operation because they are ignored by the base kernel without Sun Cluster software installed.

For more information regarding device drivers, see Writing Device Drivers.

Device Classification

Sun Cluster introduces four new device classes. These new classifications are based on the extended behavior of the devices in a Sun Cluster environment.

Enumerated Devices

ENUMERATED_DEV

Node Specific Devices

NODESPECIFIC_DEV

Global Devices

GLOBAL_DEV

Node Bound Devices

NODEBOUND_DEV

The ddi_create_minor_node(9F) routine has been enhanced to add the capability of reporting the additional device classification of the device minor nodes created by the device driver. The device categories are described in the following sections.

Enumerated Devices

Enumerated Devices are physical devices with a one-to-one correspondence between a particular device node and a host where that device node is present. Examples of this category include various disk and tape devices, such as /dev/dsk/c0t0d0s0 and /dev/rmt/0l. Nearly all physical devices belong to this category. This is the default category for all non-pseudo devices.

Node Specific Devices

Node Specific Devices include devices that report particular information about the host where the device node is opened. An example of such a device is the /dev/kmem device. Opening this device gives access to host-specific information on the local host. Administrative pseudo device nodes used in configuring or gathering information about a particular device driver also fit this category. The Sun Cluster software ensures the creation of two user device nodes for each instance of a kernel device node in the cluster, so that the intended device node can be accessed both locally and remotely.

Global Devices

Global Devices are node invariant pseudo devices such as /dev/ip. In principle, the open instance of a device, such as ip or tcp, does not depend on which host, in the cluster, the open occurs. A single copy of each device is in the kernel. All device I/O requests for this device class are performed locally and the device node can be accessed by a remote host within the cluster. This is the default behavior for all pseudo devices in the system.

Node Bound Devices

A node bound device is a pseudo device that maintains a cluster-wide state. This device should, in principle, be opened on one node only. Devices such as /dev/ticotsord belong to this class. Highly available devices with automatic fail-over also belong to this class. Only one pseudo node is present but all opens are directed to the same node, with the exception of HA devices, where the hosting node might change transparently to the device user.

Minor Number Space Management

dev_t consists of a major and a minor number space. Major number space is managed by Solaris and the minor number space is managed by the device driver space. With Sun Cluster, the minor number behaves differently within the user space and the kernel space.

Cluster Wide dev_t

For historical reasons each device node, in addition to its path, is identified by an integral type dev_t. The dev_t is a part of the system interface expected by programmers and system administrators. stat(2) system calls and backup utilities deal directly with dev_ts. dev_t is also a programming interface for device driver writers.

Sun Cluster preserves the assumption that two equal dev_ts point to the same device regardless of the host where the process is executed. This model satisfies the expectations of programs that depend on this feature to establish the equivalence of two devices. Sun Cluster introduces a dual view of minor numbers and the necessary interfaces to implement this dual view. In kernel dev_ts correspond to the major number of the driver in addition to the minor number that the driver has created using ddi_create_minor_node(9F). External minor numbers (viewed from the user space) are managed and assigned unique cluster-wide numbers by the device configuration manager in Sun Cluster.

This dual numbering scheme has one unfortunate side effect, namely that a particular minor number created in the kernel can result in creation of a different minor number in the user space. This discrepancy might be unexpected by user space programs that expect to be able to ascertain some device characteristics from the minor number pattern.

An example of the discrepancy is the use of minor number bit patterns in specifying the particular slice of a disk or the density of a tape device. This class of problems is primarily alleviated by the use of globally unique instance numbers. By encoding the instance number of a device in the minor, the driver can guarantee the creation of cluster-wide unique dev_t values; this avoids minor numbers that do not have the same value between the kernel and the user space.

All dev_t values that are passed in through the standard Solaris entry points such as open, close and ioctl, encode the kernel minor number. The getminor(9F) interface can be used to extract this minor number. However, if the dev_t value is passed as a part of the ioctl data from the user space, the dev_t value has the minor number from the user space encoded. A new DDI interface, ddi_getiminor(9F), has been introduced to ensure that the driver can map between internal and external minor numbers.

Device Interfaces

The following interface sets up a driver and prepares it for use:

int ddi_create_minor_node(dev_info_t *dip, char *name, 
			int spec_type, int minor_num, char *node_type, int flag);

ddi_create_minor_node(9F) advertises a minor device node, which will eventually appear in the /devices directory and refer to the device specified by dip. If the device is a clone device, then flag is set to CLONE_DEV. If it is not a clone device, then flag is set to 0. For device drivers intended for use in a clustered environment, flag must specify the device node class of GLOBAL_DEV, NODEBOUND_DEV, NODESPECIFIC_DEV, or ENUMERATE_DEV.

The following new interface is used to translate between user-visible device numbers and in kernel device numbers:

minor_t ddi_getiminor(dev_t dev);

ddi_getiminor(9F) extracts the minor number as a device number.