smp_* - invoke a SAS Serial Management Protocol (SMP) function
] [ --raw
] [ --version
Serial Attached SCSI (SAS) is a transport (also known as a interconnect) used by
storage systems. A SAS system is made up of Host Bus Adapters (HBAs typically
containing SCSI initiators), disks (referred to in SCSI as both targets and
logical units) and optionally some switching hardware called
"expanders". Expanders are not SCSI devices so a new protocol was
required to control and monitor them. Its full name is the SAS Serial
Management Protocol which is abbreviated to SMP.
smp_utils is a package of utilities. Each utility sends an SMP function request
to a SMP_DEVICE
(an SMP target). Some utilities may invoke the same
function more than once. If an error occurs then an error message is sent to
stderr. If no error occurs, the response is decoded (the default), output in
ASCII hex (when --hex
is given) or output in binary to stdout (when the
option is given).
is not given then the value in the environment variable
SMP_UTILS_DEVICE is used.
This package was originally written for Linux and has been ported to FreeBSD and
Currently there are multiple interfaces that allow SMP functions to be passed
through to an SMP target.
One method is to have a SMP_DEVICE
which is actually the SMP initiator
(e.g. '/dev/mptctl,0'). In this case the SMP target's SAS address must be
supplied with the --sa=SAS_ADDR
Another method is to have a SMP_DEVICE
which represents the SMP target.
In this case no SAS_ADDRESS
needs to be given (since it is implicit).
Each utility in smp_utils attempts to work out which interface it has been given
by examining the SMP_DEVICE
file. There are three interfaces supported
- This specifies the aacraid SAS pass-through associated with
Adaptec/PMC RAID products. The SMP_DEVICE[,N] argument takes the
form /dev/aac[N[,E_ID]] where "N" is the raid controller
number (typically 0) and "E_ID" is the expander identifier
(typically 0); both default to 0 so /dev/aac is equivalent to
/dev/aac0 and /dev/aac0,0 . The "N" is the
unique_id found in /sys/class/scsi_host<HN>/unique_id . The
"HN" is the host number which is the first number to appear on
each line in the lsscsi utility which by default uses one line to list
each accessible SCSI device (typically SCSI or ATA disks). The
"E_ID" is the expander identifier which can be found with the
Adaptec/PMC arcconf utility using the form "arcconf expanderlist
<ControllerNum>". The <ControllerNum>s start at 1 . If an
aac RAID controller is present then the /dev/acc device node will be
created by the first smp utility to use this interface.
- This specifies the MPT fusion SAS pass-through. The mptsas
driver uses the '/dev/mptctl' device node (character device major 10,
minor 220) while the mpt2sas driver uses '/dev/mpt2ctl' device node (major
10, minor 221). For the mpt3sas driver the corresponding device node is
'/dev/mpt3ctl'. The 'modprobe mptctl' or 'modprobe mpt2ctl' command may be
needed. If there are multiple mpt fusion controllers (HBAs) in the
computer, then the user will need to specify which one to use with the
syntax: '/dev/mptctl,<n>' where <n> is the
"ioc_num". This number can be found with dmesg after the mptsas
driver is registered and appears as a suffix to the driver name (e.g.
mpt2sas0). It can also be found in
'/sys/class/scsi_host/host<n>/unique_id'. When this interface is
used the --sa=SAS_ADDR option must be given to specify the SAS
address of the SMP target.
- sgv4 (sg)
- This interface is more generic and supported by several SAS
HBA drivers including mptsas (and mpt2sas). It was introduced in the Linux
2.6.24 kernel. The SMP functions are passed to the kernel via the bsg
driver using a format known as "SCSI Generic Version 4" which
gives this interface its name: "sgv4" or just "sg".
The SAS transport layer within the SCSI sub-system unpacks the SMP
requests and forwards them to SAS low level drivers that support this
interface. The SMP_DEVICE is either a member of the
'/sys/class/bsg' directory (e.g. /sys/class/bsg/expander-6:0 ) or a device
node made for the bsg driver (e.g. /dev/bsg/expander-6:0 ). Such device
nodes are dynamic (i.e. they don't have fixed major and minor numbers) and
should correspond to the major and minor numbers found in the
The CAM subsystem has been enhanced in FreeBSD 9 to pass-through SMP requests
and return the corresponding responses. However CAM does not directly access
expander devices because they are not SCSI devices. It makes the assumption
that each SAS expander has an integrated SES (enclosure) device and that is
addressed. This assumption seems to be true for SAS-2 expanders but not some
SAS-1 expanders. Thus invocations look like this:
# smp_discover /dev/ses0
where /dev/ses0 is a SES device associated with a SAS expander.
The USMP pass-through mechanism is used. Invocations look like this:
# smp_rep_manufacturer /dev/smp/expd0
If the device name is not given then the SMP_UTILS_DEVICE environment variable
is checked and if present its contents are used as the device name.
If the SAS address (of the SMP target) is not given and it is required (i.e. it
is not implicit in the device name) then the SMP_UTILS_SAS_ADDR environment
variable is checked and if present its contents are used as the SAS address.
SAS addresses are usually given in hex indicated by a leading '0x' or trailing
If either or both environment variables and the corresponding command line
options are given, then the command line options take precedence.
Mandatory arguments to long options are mandatory for short options as well. If
an option takes a numeric argument then that argument is assumed to be decimal
unless otherwise indicated (e.g. with a leading "0x" or a trailing
- -E, --expected=EX
- revision 4a of the SAS-2 draft introduced an 'expected
expander change count' field in some SMP requests. The idea is to detect
other SMP initiators trying to change the state of an expander. The value
EX is from 0 to 65535 inclusive with 0 being the default value.
When EX is greater than zero then if the value doesn't match the
expander change count of the SMP target (i.e. the expander) when the
request arrives then the target ignores the request and sets a function
result of "invalid expander change count" in the response.
- -h, --help
- output the usage message for the utility then exit.
- -H, --hex
- output the response in hexadecimal. This does not include
the trailing CRC field.
- -I, --interface=PARAMS
- interface specific parameters. This option is usually not
needed since the interface type is guessed by a utility based on the
characteristics of the given SMP_DEVICE argument or what is in the
corresponding environment variables. PARAMS is of the form:
INTF[,force]. If the guess doesn't work then the interface can be
specified by giving a INTF of either 'mpt' or 'sgv4'. Sanity checks
are still performed and a utility may refuse if it doesn't agree with the
given INTF. If the user is really sure then adding a ',force' will
force the utility to use the given interface.
- -r, --raw
- send the response to stdout in binary. This does not
include the trailing CRC field. All error messages are sent to
- -s, --sa=SAS_ADDR
- specifies the SAS address of the SMP target device.
Typically this is an expander. This option may not be needed if the
SMP_DEVICE has the target's SAS address associated with it. The
SAS_ADDR is in decimal but most SAS addresses are shown in
hexadecimal. To give a number in hexadecimal either prefix it with '0x' or
put a trailing 'h' on it. If this option is not given then the value in
the environment variable SMP_UTILS_SAS_ADDR is used.
- -v, --verbose
- increase the verbosity of the output. Can be used multiple
- -V, --version
- print the version string and then exit.
To aid scripts that call these utilities, the exit status is set to indicate
success (0) or failure (1 or more):
- 1 - 63
- reserved for SMP function result codes. See the SAS-2 (or
later) draft, in the section on the application layer, drilling down
further: management application layer then SMP functions. Here are some
common function result codes: 1 [unknown SMP function], 2 [SMP function
failed], 16 [phy does not exist], 17 [index does not exist], 18 [phy does
not support SATA], 19 [unknown phy operation], 22 [phy vacant] and 35
[zone lock violation].
- syntax error. Either illegal options, options with bad
arguments or a combination of options that is not permitted.
- the utility is unable to open, close or use the given
SMP_DEVICE. The given file name could be incorrect or there may be
file permission problems. Adding the --verbose option may give more
- the response to an SMP function failed sanity checks.
- any error that can't be categorized into values 1 to 97 may
yield this value. This includes transport and operating system
Finding the SAS address of an expander can be a challenge in some environments.
An enclosure containing one or more expanders may have the expander SAS
address(es) printed on the back of the device, a bit like Ethernet MAC
In the Linux 2.6 kernel series the expander SAS address may well be in the sysfs
tree but it is not always easy to find. Doing this search may help:
# find /sys -name "*expander*"
That should show the suffix on any expanders that have been detected. Then a
command like 'cat /sys/class/sas_device/expander-6:0/sas_address' should show
its SAS address.
Another approach is to work backwards from SCSI devices (i.e. logical units).
The protocol specific port log page (log page 18h) contains fields for the
"attached SAS address". The sg_logs utility from the sg3_utils
package could be used like this:
# sg_logs --page=18h /dev/sdb
Any given "attached SAS address" is either a HBA, an expander or 0
indicating that port is not connected. An expander is indicated by
"attached device type: expander device". A SAS disk's target port
identifiers (also known as SAS addresses), device name and logical unit name
(all NAA 5 format) can be found with the sg_vpd utility (e.g. 'sg_vpd -i
<disk_dev>'). The sdparm utility can provide the same information (e.g.
'sdparm -i <disk_dev>').
A SAS expander is often associated with a SCSI Enclosure Services (SES) device
sometimes on the same silicon attached via a virtual phy to the expander. That
SES device may be able to access and control an attached enclosure or
backplane via SGPIO or I2C on sideband signals (e.g. in a SFF-8087 cable). To
interact with a SES device, see the sg_ses utility.
Often expander phys are grouped in fours on the same connector (e.g. SFF-8088).
Care needs to be taken when multiple expanders are interconnected. An
port is one in which the "table to table
supported" attribute is set (in the REPORT GENERAL response) and the
associated phys have the table routing attribute (in the DISCOVER response).
ports were introduced in SAS-2 and have few
restrictions when used to interconnect expanders or connect SAS or SATA
devices. An enclosure out
port is one in which the "table to table
supported" attribute is clear and the associated phys have the table
routing attribute. An enclosure in
port is one in which the associated
phys have the subtractive routing attribute. When universal
not available, an expander interconnect should be between an in
and an out
See "Examples" section in http://sg.danny.cz/sg/smp_utils.html .
SAS has multiple generations. The early standards are: the original SAS (ANSI
INCITS 376-2003), SAS 1.1 (INCITS 417-2006) and SAS-2 (ANSI INCITS 457-2010) .
SAS-2.1 work was split into an electrical and physical layers document
(standardized as SAS-2.1 ANSI INCITS 478-2011) with the upper level layers
placed in a document called the SAS Protocol Layer and it was standardized as
SPL ANSI INCITS 476-2011. Next came SPL-2 which was standardized as SPL-2 ANSI
INCITS 505-2013. SPL-3 is near standardization and its most recent draft is
spl3r07.pdf. To avoid confusion, the multiple generations of SAS will be
referred to in these man pages as SAS 1, 1.1, 2, 2.1 (SPL) and 3 (SPL-2 and
SPL-3). Roughly speaking SAS-1 runs at 3 Gbps, SAS-2 at 6 Gbps and SAS-3 at 12
Gbps. Drafts, including those just prior to standardization can be found at
the http://www.t10.org site (e.g. spl-r07.pdf and spl2r04c.pdf). INCITS policy
now requires a registration to view these drafts, a break from t10.org
The two utilities for reading and writing to GPIO registers, smp_read_gpio and
smp_write_gpio, are defined in the Small Form Factor document SFF-8485 found
at http://www.sffcommittee.com . "Enhanced" versions of the
corresponding SMP functions have been mentioned in some drafts but no
definitions have been published and the references have been removed in more
In this section of each utility's man page is the first standard in which the
associated SMP function appeared and whether there have been significant
additions in later standards.
The COVERAGE file in the smp_utils source tarball shows a table of all SMP
function names defined in the drafts, the versions of those standards in which
those SMP functions first appeared and the corresponding smp_utils utility
names. A lot of extra SMP functions have been added in SAS-2 associated with
Written by Douglas Gilbert.
Report bugs to <dgilbert at interlog dot com>.
Copyright © 2006-2014 Douglas Gilbert
This software is distributed under a FreeBSD license. There is NO warranty; not
even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
sg_logs, sg_vpd, sg_ses(sg3_utils); sdparm(sdparm); lsscsi(lsscsi)