History log of /freebsd-10-stable/sbin/camcontrol/camcontrol.c
Revision Date Author Comments
# 320781 07-Jul-2017 asomers

MFC r319337:

Fix integer overflow in "camcontrol format"

Reported by: Coverity
CID: 1011426
Sponsored by: Spectra Logic Corp


# 317947 08-May-2017 ken

MFC r317774, r317776

r317774:
Add the ability to rescan or reset devices specified by peripheral
name and unit number in camcontrol(8).

Previously camcontrol(8) only supported rescanning or resetting
devices specified by bus:target:lun. This is because for
rescanning at least, you don't have a peripheral name and unit
number (e.g. da4) for devices that don't exist yet.

That is still the case after this change, but in other cases, when
the device does exist in the CAM EDT (Existing Device Table), we
do a careful lookup of the bus/target/lun if the user supplies a
peripheral name and unit number to find the bus:target:lun and then
issue the requested reset or rescan.

The lookup is done without actually opening the device in question,
since a rescan is often done to make a device go away after it has
been pulled. (This is especially true for busses/controllers, like
parallel SCSI controllers, that don't automatically detect changes
in topology.) Opening a device that is no longer there to
determine the bus/target/lun might result in error recovery actions
when the user really just wanted to make the device go away.

sbin/camcontrol/camcontrol.c:
In dorescan_or_reset(), if the use hasn't specified a
numeric argument, assume he has specified a device. Lookup
the pass(4) instance for that device using the transport
layer CAMGETPASSTHRU ioctl. If that is successful, we can
use the returned bus:target:lun to rescan or reset the
device.

Under the hood, resetting a device using XPT_RESET_DEV is
actually sent via the pass(4) device anyway. But this
provides a way for the user to specify devices in a more
convenient way, and can work on device rescans when the
device is going away, assuming it still exists in the EDT.

sbin/camcontrol/camcontrol.8:
Update the man page for the rescan and reset subcommands
to reflect that you can now use a device name and unit
number with them.

Sponsored by: Spectra Logic

r317776:
Bump the camcontrol(8) man page date.

Sponsored by: Spectra Logic


# 316138 29-Mar-2017 mav

MFC r315711: Fix printing bits above first eight.


# 314221 24-Feb-2017 ken

MFC r313893

------------------------------------------------------------------------
r313893 | ken | 2017-02-17 13:04:22 -0700 (Fri, 17 Feb 2017) | 48 lines

Add task attribute support to camcontrol(8).

Users can use the new generic argument, -Q task_attr, to specify a task
attribute (simple, ordered, head of queue, aca) for the commands issued.
The the default is simple, which works with all SCSI devices that support
tagged queueing.

This will mostly be useful for debugging target behavior in certain
situations.

You can try it out by compiling CTL with CTL_IO_DELAY turned on (in
sys/cam/ctl/ctl_io.h) and then do something like this with one of the CTL
LUNs:

ctladm delay 0:0 -l done -t 10
camcontrol tur da34 -v

And at then before the 10 second timer is up, in another terminal:

camcontrol inquiry da34 -Q ordered -v

The Inquiry should complete just after the TUR completes. Ordinarily
it would complete first because of the delay injection, but because the
task attribute is set to ordered in this case, CTL holds it up until the
previous command has completed.

sbin/camcontrol/camcontrol.c:
Add the new generic argument, -Q, which allows the user to specify
a SCSI task attribute. The user can specify task attributes by
name or numerically.

Add a new task_attr arguments to SCSI sub-functions.

sbin/camcontrol/attrib.c,
sbin/camcontrol/camcontrol.h,
sbin/camcontrol/fwdownload.c,
sbin/camcontrol/modeedit.c,
sbin/camcontrol/persist.c,
sbin/camcontrol/timestamp.c,
sbin/camcontrol/zone.c:
Add the new task_attr argument to SCSI sub-functions.

sbin/camcontrol/camcontrol.8:
Document the new -Q option, and add an example.

Sponsored by: Spectra Logic

------------------------------------------------------------------------


# 312951 29-Jan-2017 mav

MFC r312228: Make `camcontrol cmd ... -i ...` return only valid bytes.

Previously code ignored resid field and returned extra zeroes in case of
data underflow. Now it returns only real bytes received from target.


# 312567 21-Jan-2017 mav

MFC r311636: Make 'camcontrol modepage' support subpages.


# 309956 12-Dec-2016 ken

MFC r307684, r307747
------------------------------------------------------------------------
r307684 | ken | 2016-10-20 13:42:26 -0600 (Thu, 20 Oct 2016) | 13 lines

For CCBs allocated on the stack, we need to clear the entire CCB, not just
the header. Otherwise stack garbage can lead to random flags getting set.

This showed up as 'camcontrol rescan all' failing with EINVAL because the
address type wasn't CAM_DATA_VADDR.

sbin/camcontrol/camcontrol.c:
In rescan_or_reset_bus(), bzero the stack-allocated CCBs before
use instead of clearing the body.

Sponsored by: Spectra Logic

------------------------------------------------------------------------
r307747 | ken | 2016-10-21 12:54:56 -0600 (Fri, 21 Oct 2016) | 27 lines

Fix a problem in camcontrol(8) that cropped up with r307684.

In r307684, I changed rescan_or_reset_bus() to bzero stack-allocated CCBs
before sending them to the kernel because there was stack garbage in there
that wound up meaning that bogus CCB flags were set.

While this fixed the 'camcontrol rescan all' case (XPT_DEV_MATCH CCBs were
failing previously), it broke the 'camcontrol rescan 0' (or any other
number) case when INVARIANTS are turned on. Rescanning a single bus
reliably produced an assert in cam_periph_runccb():

panic: cam_periph_runccb: ccb=0xfffff80044ffe000, func_code=0x708, flags=0xffffdde0

The flags values don't make sense from the code. Changing the CCBs in
rescan_or_reset_bus() from stack to heap allocated avoids the problem.

It would be better to understand why userland stack allocated CCBs don't
work properly, since there may be other code that breaks if stack allocated
CCBs don't work.

sbin/camcontrol/camcontrol.c:
In rescan_or_reset_bus(), allocate the CCBs using malloc(3) instead
of on the stack to avoid an assertion in cam_periph_runccb().

Sponsored by: Spectra Logic

------------------------------------------------------------------------

Sponsored by: Spectra Logic


# 305118 31-Aug-2016 mav

MFC r304751: Fix minor copy/paste bug.


# 302377 06-Jul-2016 truckman

MFC r300547

Fix multiple Coverity Out-of-bounds access false postive issues in CAM

The currently used idiom for clearing the part of a ccb after its
header generates one or two Coverity errors for each time it is
used. All instances generate an Out-of-bounds access (ARRAY_VS_SINGLETON)
error because of the treatment of the header as a two element array,
with a pointer to the non-existent second element being passed as
the starting address to bzero(). Some instances also alsp generate
Out-of-bounds access (OVERRUN) errors, probably because the space
being cleared is larger than the sizeofstruct ccb_hdr).

In addition, this idiom is difficult for humans to understand and
it is error prone. The user has to chose the proper struct ccb_*
type (which does not appear in the surrounding code) for the sizeof()
in the length calculation. I found several instances where the
length was incorrect, which could cause either an actual out of
bounds write, or incompletely clear the ccb.

A better way is to write the code to clear the ccb itself starting
at sizeof(ccb_hdr) bytes from the start of the ccb, and calculate
the length based on the specific type of struct ccb_* being cleared
as specified by the union ccb member being used. The latter can
normally be seen in the nearby code. This is friendlier for Coverity
and other static analysis tools because they will see that the
intent is to clear the trailing part of the ccb.

Wrap all of the boilerplate code in a convenient macro that only
requires a pointer to the desired union ccb member (or a pointer
to the union ccb itself) as an argument.

Reported by: Coverity
CID: 1007578, 1008684, 1009724, 1009773, 1011304, 1011306
CID: 1011307, 1011308, 1011309, 1011310, 1011311, 1011312
CID: 1011313, 1011314, 1011315, 1011316, 1011317, 1011318
CID: 1011319, 1011320, 1011321, 1011322, 1011324, 1011325
CID: 1011326, 1011327, 1011328, 1011329, 1011330, 1011374
CID: 1011390, 1011391, 1011392, 1011393, 1011394, 1011395
CID: 1011396, 1011397, 1011398, 1011399, 1011400, 1011401
CID: 1011402, 1011403, 1011404, 1011405, 1011406, 1011408
CID: 1011409, 1011410, 1011411, 1011412, 1011413, 1011414
CID: 1017461, 1018387, 1086860, 1086874, 1194257, 1229897
CID: 1229968, 1306229, 1306234, 1331282, 1331283, 1331294
CID: 1331295, 1331535, 1331536, 1331539, 1331540, 1341623
CID: 1341624, 1341637, 1341638, 1355264, 1355324
Reviewed by: scottl, ken, delphij, imp
MFH: 1 month
Differential Revision: https://reviews.freebsd.org/D6496


# 302376 06-Jul-2016 truckman

MFC r299371 (by trasz)

Add "camcontrol reprobe" subcommand, and implement it for da(4).
This makes it possible to manually force updating capacity data
after the disk got resized. Without it it might be neccessary to
reboot before FreeBSD notices updated disk size under eg VMWare.

Differential Revision: https://reviews.freebsd.org/D6108


# 301786 10-Jun-2016 ngie

MFC r299489:
r299489 (by cem):

camcontrol(8): Fix trival double-free

CID: 1331223


# 299056 04-May-2016 ngie

MFC r298758:

Remove logically impossible test in scsidoinquiry(..)

It was already done 4 lines prior and the value of error didn't change

CID: 1011236


# 287203 27-Aug-2015 ken

MFC, r286965:

------------------------------------------------------------------------
r286965 | ken | 2015-08-20 10:07:51 -0600 (Thu, 20 Aug 2015) | 297 lines

Revamp camcontrol(8) fwdownload support and add the opcodes subcommand.

The significant changes and bugs fixed here are:

1. Fixed a bug in the progress display code:

When the user's filename is too big, or his terminal width is too
small, the progress code could wind up using a negative number for
the length of the "stars" that it uses to indicate progress.

This negative value was assigned to an unsigned variable, resulting
in a very large positive value.

The result is that we wound up writing garbage from memory to the
user's terminal.

With an 80 column terminal, a file name length of more than 35
characters would generate this problem.

To address this, we now set a minimum progress bar length, and
truncate the user's file name as needed.

This has been tested with large filenames and small terminals, and
at least produces reasonable results. If the terminal is too
narrow, the progress display takes up an additional line with each
update, but this is more user friendly than writing garbage to the
tty.

2. SATA drives connected via a SATA controller didn't have SCSI Inquiry
data populated in struct cam_device. This meant that the code in
fw_get_vendor() in fwdownload.c would try to match a zero-length
vendor ID, and so return the first entry in the vendor table. (Which
used to be HITACHI.) Fixed by grabbing identify data, passing the
identify buffer into fw_get_vendor(), and matching against the model
name.

3. SATA drives connected via a SAS controller do have Inquiry data
populated. The table included a couple of entries -- "ATA ST" and
"ATA HDS", intended to handle Seagate and Hitachi SATA drives attached
via a SAS controller. SCSI to ATA translation layers use a vendor
ID of "ATA" (which is standard), and then the model name from the ATA
identify data as the SCSI product name when they are returning data on
SATA disks. The cam_strmatch code will match the first part of the
string (because the length it is given is the length of the vendor,
"ATA"), and return 0 (i.e. a match). So all SATA drives attached to
a SAS controller would be programmed using the Seagate method
(WRITE BUFFER mode 7) of SCSI firmware downloading.

4. Issue #2 above covered up a bug in fw_download_img() -- if the
maximum packet size in the vendor table was 0, it tried to default
to a packet size of 32K. But then it didn't actually succeed in
doing that, because it set the packet size to the value that was
in the vendor table (0). Now that we actually have ATA attached
drives fall use the VENDOR_ATA case, we need a reasonable default
packet size. So this is fixed to properly set the default packet size.

5. Add support for downloading firmware to IBM LTO drives, and add a
firmware file validation method to make sure that the firmware
file matches the drive type. IBM tape drives include a Load ID and
RU name in their vendor-specific VPD page 0x3. Those should match
the IDs in the header of the firmware file to insure that the
proper firmware file is loaded.

6. This also adds a new -q option to the camcontrol fwdownload
subcommand to suppress informational output. When -q is used in
combination with -y, the firmware upgrade will happen without
prompting and without output except if an error condition occurs.

7. Re-add support for printing out SCSI inquiry information when
asking the user to confirm that they want to download firmware, and
add printing of ATA Identify data if it is a SATA disk. This was
removed in r237281 when support for flashing ATA disks was added.

8. Add a new camcontrol(8) "opcodes" subcommand, and use the
underlying code to get recommended timeout values for drive
firmware downloads.

Many SCSI devices support the REPORT SUPPORTED OPERATION CODES
command, and some support the optional timeout descriptor that
specifies nominal and recommended timeouts for the commands
supported by the device.

The new camcontrol opcodes subcommand allows displaying all
opcodes supported by a drive, information about which fields
in a SCSI CDB are actually used by a given SCSI device, and the
nominal and recommended timeout values for each command.

Since firmware downloads can take a long time in some devices, and
the time varies greatly between different types of devices, take
advantage of the infrastructure used by the camcontrol opcodes
subcommand to determine the best timeout to use for the WRITE
BUFFER command in SCSI device firmware downloads.

If the device recommends a timeout, it is likely to be more
accurate than the default 50 second timeout used by the firmware
download code. If the user specifies a timeout, it will override
the default or device recommended timeout. If the device doesn't
support timeout descriptors, we fall back to the default.

9. Instead of downloading firmware to SATA drives behind a SAS controller
using WRITE BUFFER, use the SCSI ATA PASS-THROUGH command to compose
an ATA DOWNLOAD MICROCODE command and it to the drive. The previous
version of this code attempted to send a SCSI WRITE BUFFER command to
SATA drives behind a SAS controller. Although that is part of the
SAT-3 spec, it doesn't work with the parameters used with LSI
controllers at least.

10.Add a new mechanism for making common ATA passthrough and
ATA-behind-SCSI passthrough commands.

The existing camcontrol(8) ATA command mechanism checks the device
type on every command executed. That works fine for individual
commands, but is cumbersome for things like a firmware download
that send a number of commands.

The fwdownload code detects the device type up front, and then
sends the appropriate commands.

11.In simulation mode (-s), if the user specifies the -v flag, print out
the SCSI CDB or ATA registers that would be sent to the drive. This will
aid in debugging any firmware download issues.

sbin/camcontrol/fwdownload.c:
Add a device type to the fw_vendor structure, so that we can
specify different download methods for different devices from the
same vendor. In this case, IBM hard drives (from when they
still made hard drives) and tape drives.

Add a tur_status field to the fw_vendor structure so that we can
specify whether the drive to be upgraded should be ready, not
ready, or whether it doesn't matter. Add the corresponding
capability in fw_download_img().

Add comments describing each of the vendor table fields.

Add HGST and SmrtStor to the supported SCSI vendors list.

In fw_get_vendor(), look at ATA identify data if we have a SATA
device to try to identify what the drive vendor is.

Add IBM firmware file validation. This gets VPD page 0x3, and
compares the Load ID and RU name in the page to the values
included in the header. The validation code will refuse to load
a firmware file if the values don't match. This does allow the
user to attempt a downgrade; whether or not it succeeds will
likely depend on the drive settings.

Add a -q option, and disable all informative output
(progress bars, etc.) when this is enabled.

Re-add the inquiry in the confirmation dialog so the user has
a better idea of which device he is talking to. Add support for
displaying ATA identify data.

Don't automatically disable confirmation in simulation (-s) mode.
This allows the user to see the inquiry or identify data in the
dialog, and see exactly what they would see when the command
actually runs. Also, in simulation mode, if the user specifies
the -v flag, print out the SCSI CDB or ATA registers that would
be sent to the drive. This will aid in debugging any firmware
download issues.

Add a timeout field and timeout type to the firmware download
vendor table. This allows specifying a default timeout and allows
specifying whether we should attempt to probe for a recommended
timeout from the drive.

Add a new fuction, fw_get_timeout(), that will determine
which timeout to use for the WRITE BUFFER command. If the
user specifies a timeout, we always use that. Otherwise,
we will use the drive recommended timeout, if available,
and fall back to the default when a drive recommended
timeout isn't available.

When we prompt the user, tell him what timeout we're going
to use, and the source of the timeout.

Revamp the way SATA devices are handled.

In fwdownload(), use the new get_device_type() function to
determine what kind of device we're talking to.

Allow firmware downloads to any SATA device, but restrict
SCSI downloads to known devices. (The latter is not a
change in behavior.)

Break out the "ready" check from fw_download_img() into a
new subfunction, fw_check_device_ready(). This sends the
appropriate command to the device in question -- a TEST
UNIT READY or an IDENTIFY. The IDENTIFY for SATA devices
a SAT layer is done using the SCSI ATA PASS-THROUGH
command.

Use the new build_ata_cmd() function to build either a SCSI or
ATA I/O CCB to issue the DOWNLOAD MICROCODE command to SATA
devices. build_ata_cmd() figures looks at the devtype argument
and fills in the correct CCB type and CDB or ATA registers.

Revamp the vendor table to remove the previous
vendor-specific ATA entries and use a generic ATA vendor
placeholder. We currently use the same method for all ATA
drives, although we may have to add vendor-specific
behavior once we test this with more drives.

sbin/camcontrol/progress.c:
In progress_draw(), make barlength a signed value so that
we can easily detect a negative value.

If barlength (the length of the progress bar) would wind up
negative due to a small TTY width or a large filename,
set the bar length to the new minimum (10 stars) and
truncate the user's filename. We will truncate it down to
0 characters if necessary.

Calculate a new prefix_len variable (user's filename length)
and use it as the precision when printing the filename.

sbin/camcontrol/camcontrol.c:
Implement a new camcontrol(8) subcommand, "opcodes". The
opcodes subcommand allows displaying the entire list of
SCSI commands supported by a device, or details on an
individual command. In either case, it can display
nominal and recommended timeout values.

Add the scsiopcodes() function, which calls the new
scsigetopcodes() function to fetch opcode data from a
drive.

Add two new functions, scsiprintoneopcode() and
scsiprintopcodes(), which print information about one
opcode or all opcodes, respectively.

Remove the get_disk_type() function. It is no longer used.

Add a new function, dev_has_vpd_page(), that fetches the
supported INQUIRY VPD list from a device and tells the
caller whether the requested VPD page is available.

Add a new function, get_device_type(), that returns a more
precise device type than the old get_disk_type() function.
The get_disk_type() function only distinguished between
SCSI and ATA devices, and SATA devices behind a SCSI to ATA
translation layer were considered to be "SCSI".

get_device_type() offers a third type, CC_DT_ATA_BEHIND_SCSI.
We need to know this to know whether to attempt to send ATA
passthrough commands. If the device has the ATA
Information VPD page (0x89), then it is an ATA device
behind a SCSI to ATA translation layer.

Remove the type argument from the fwdownload() subcommand.

Add a new function, build_ata_cmd(), that will take one set
of common arguments and build either a SCSI or ATA I/O CCB,
depending on the device type passed in.

sbin/camcontrol/camcontrol.h:
Add a prototype for scsigetopcodes().

Add a new enumeration, camcontrol_devtype.

Add prototypes for dev_has_vpd_page(), get_device_type()
and build_ata_cmd().

Remove the type argument from the fwdownload() subcommand.

sbin/camcontrol/camcontrol.8
Explain that the fwdownload subcommand will use the drive
recommended timeout if available, and that the user can
override the timeout.

Document the new opcodes subcommand.

Explain that we will attempt to download firmware to any
SATA device.

Document supported SCSI vendors, and models tested if known.

Explain the commands used to download firmware for the
three different drive and controller combinations.

Document that the -v flag in simulation mode for the fwdownload
subcommand will print out the SCSI CDBs or ATA registers that would
be used.

sys/cam/scsi/scsi_all.h:
Add new bit definitions for the one opcode descriptor for
the REPORT SUPPORTED OPCODES command.

Add a function prototype for scsi_report_supported_opcodes().

sys/cam/scsi/scsi_all.c:
Add a new CDB building function, scsi_report_supported_opcodes().

Sponsored by: Spectra Logic


# 285532 14-Jul-2015 brueffer

MFC: r285037

Add -b to the devlist usage info, forgotten in r260059.

PR: 195094
Submitted by: robin.hahling@gw-computing.net
Approved by: re (marius)


# 284435 16-Jun-2015 ken

MFC, r284192:

------------------------------------------------------------------------
r284192 | ken | 2015-06-09 15:39:38 -0600 (Tue, 09 Jun 2015) | 102 lines

Add support for reading MAM attributes to camcontrol(8) and libcam(3).

MAM is Medium Auxiliary Memory and is most commonly found as flash
chips on tapes.

This includes support for reading attributes and decoding most
known attributes, but does not yet include support for writing
attributes or reporting attributes in XML format.

libsbuf/Makefile:
Add subr_prf.c for the new sbuf_hexdump() function. This
function is essentially the same function.

libsbuf/Symbol.map:
Add a new shared library minor version, and include the
sbuf_hexdump() function.

libsbuf/Version.def:
Add version 1.4 of the libsbuf library.

libutil/hexdump.3:
Document sbuf_hexdump() alongside hexdump(3), since it is
essentially the same function.

camcontrol/Makefile:
Add attrib.c.

camcontrol/attrib.c:
Implementation of READ ATTRIBUTE support for camcontrol(8).

camcontrol/camcontrol.8:
Document the new 'camcontrol attrib' subcommand.

camcontrol/camcontrol.c:
Add the new 'camcontrol attrib' subcommand.

camcontrol/camcontrol.h:
Add a function prototype for scsiattrib().

share/man/man9/sbuf.9:
Document the existence of sbuf_hexdump() and point users to
the hexdump(3) man page for more details.

sys/cam/scsi/scsi_all.c:
Add a table of known attributes, text descriptions and
handler functions.

Add a new scsi_attrib_sbuf() function along with a number
of other related functions that help decode attributes.

scsi_attrib_ascii_sbuf() decodes ASCII format attributes.

scsi_attrib_int_sbuf() decodes binary format attributes, and
will pass them off to scsi_attrib_hexdump_sbuf() if they're
bigger than 8 bytes.

scsi_attrib_vendser_sbuf() decodes the vendor and drive
serial number attribute.

scsi_attrib_volcoh_sbuf() decodes the Volume Coherency
Information attribute that LTFS writes out.

sys/cam/scsi/scsi_all.h:
Add a number of attribute-related structure definitions and
other defines.

Add function prototypes for all of the functions added in
scsi_all.c.

sys/kern/subr_prf.c:
Add a new function, sbuf_hexdump(). This is the same as
the existing hexdump(9) function, except that it puts the
result in an sbuf.

This also changes subr_prf.c so that it can be compiled in
userland for includsion in libsbuf.

We should work to change this so that the kernel hexdump
implementation is a wrapper around sbuf_hexdump() with a
statically allocated sbuf with a drain. That will require
a drain function that goes to the kernel printf() buffer
that can take a non-NUL terminated string as input.
That is because an sbuf isn't NUL-terminated until it is
finished, and we don't want to finish it while we're still
using it.

We should also work to consolidate the userland hexdump and
kernel hexdump implemenatations, which are currently
separate. This would also mean making applications that
currently link in libutil link in libsbuf.

sys/sys/sbuf.h:
Add the prototype for sbuf_hexdump(), and add another copy
of the hexdump flag values if they aren't already defined.

Ideally the flags should be defined in one place but the
implemenation makes it difficult to do properly. (See
above.)

Sponsored by: Spectra Logic Corporation

------------------------------------------------------------------------


# 280896 31-Mar-2015 mav

MFC r280166:
Make ATA power management commands to work on SCSI HBAs via PASS THROUGH.


# 280679 26-Mar-2015 mav

MFC r280249: Add camcontrol subcommands to control APM and AAM levels.

Sponsored by: iXsystems, Inc.


# 279329 26-Feb-2015 ken

MFC r278964:

The __FreeBSD_version was changed to 1001510 to be appropriate for
stable/10.

I will followup with a commit to mpr(4) and mps(4) in head to reflect
the stable/10 __FreeBSD_version and merge the change back to stable/10.

------------------------------------------------------------------------
r278964 | ken | 2015-02-18 11:30:19 -0700 (Wed, 18 Feb 2015) | 46 lines

Make sure that the flags for the XPT_DEV_ADVINFO CCB are initialized
properly.

If there is garbage in the flags field, it can sometimes include a
set CDAI_FLAG_STORE flag, which may cause either an error or
perhaps result in overwriting the field that was intended to be
read.

sys/cam/cam_ccb.h:
Add a new flag to the XPT_DEV_ADVINFO CCB, CDAI_FLAG_NONE,
that callers can use to set the flags field when no store
is desired.

sys/cam/scsi/scsi_enc_ses.c:
In ses_setphyspath_callback(), explicitly set the
XPT_DEV_ADVINFO flags to CDAI_FLAG_NONE when fetching the
physical path information. Instead of ORing in the
CDAI_FLAG_STORE flag when storing the physical path, set
the flags field to CDAI_FLAG_STORE.

sys/cam/scsi/scsi_sa.c:
Set the XPT_DEV_ADVINFO flags field to CDAI_FLAG_NONE when
fetching extended inquiry information.

sys/cam/scsi/scsi_da.c:
When storing extended READ CAPACITY information, set the
XPT_DEV_ADVINFO flags field to CDAI_FLAG_STORE instead of
ORing it into a field that isn't initialized.

sys/dev/mpr/mpr_sas.c,
sys/dev/mps/mps_sas.c:
When fetching extended READ CAPACITY information, set the
XPT_DEV_ADVINFO flags field to CDAI_FLAG_NONE instead of
setting it to 0.

sbin/camcontrol/camcontrol.c:
When fetching a device ID, set the XPT_DEV_ADVINFO flags
field to CDAI_FLAG_NONE instead of 0.

sys/sys/param.h:
Bump __FreeBSD_version to 1100061 for the new XPT_DEV_ADVINFO
CCB flag, CDAI_FLAG_NONE.

Sponsored by: Spectra Logic


# 278170 03-Feb-2015 ken

MFC r276835:

r276835 | ken | 2015-01-08 09:58:40 -0700 (Thu, 08 Jan 2015) | 91 lines

Improve camcontrol(8) handling of drive defect data.

This includes a new summary mode (-s) for camcontrol defects that
quickly tells the user the most important thing: how many defects
are in the requested list. The actual location of the defects is
less important.

Modern drives frequently have more than the 8191 defects that can
be reported by the READ DEFECT DATA (10) command. If they don't
have that many grown defects, they certainly have more than 8191
defects in the primary (i.e. factory) defect list.

The READ DEFECT DATA (12) command allows for longer parameter
lists, as well as indexing into the list of defects, and so allows
reporting many more defects.

This has been tested with HGST drives and Seagate drives, but
does not fully work with Seagate drives. Once I have a Seagate
spec I may be able to determine whether it is possible to make it
work with Seagate drives.

scsi_da.h: Add a definition for the new long block defect
format.

Add bit and mask definitions for the new extended
physical sector and bytes from index defect
formats.

Add a prototype for the new scsi_read_defects() CDB
building function.

scsi_da.c: Add a new scsi_read_defects() CDB building function.
camcontrol(8) was previously composing CDBs manually.
This is long overdue.

camcontrol.c: Revamp the camcontrol defects subcommand. We now
go through multiple stages in trying to get defect
data off the drive while avoiding various drive
firmware quirks.

We start off by requesting the defect header with
the 10 byte command. If we're in summary mode (-s)
and the drive reports fewer defects than can be
represented in the 10 byte header, we're done.
Otherwise, we know that we need to issue the
12 byte command if the drive reports the maximum
number of defects.

If we're in summary mode, we're done if we get a
good response back when asking for the 12 byte header.

If the user has asked for the full list, then we
use the address descriptor index field in the 12
byte CDB to step through the list in 64K chunks.
64K is small enough to work with most any ancient
or modern SCSI controller.

Add support for printing the new long block defect
format, as well as the extended physical sector and
bytes from index formats. I don't have any drives
that support the new formats.

Add a hexadecimal output format that can be turned
on with -X.

Add a quiet mode (-q) that can be turned on with
the summary mode (-s) to just print out a number.

Revamp the error detection and recovery code for
the defects command to work with HGST drives.

Call the new scsi_read_defects() CDB building
function instead of rolling the CDB ourselves.

Pay attention to the residual from the defect list
request when printing it out, so we don't run off
the end of the list.

Use the new scsi_nv library routines to convert
from strings to numbers and back.

camcontrol.8: Document the new defect formats (longblock, extbfi,
extphys) and command line options (-q, -s, -S and
-X) for the defects subcommand.

Explain a little more about what drives generally
do and don't support.

Sponsored by: Spectra Logic


# 275630 09-Dec-2014 bryanv

MFC r274322:

Attempt to report a better error if sanitize is not supported


# 273078 14-Oct-2014 mav

MFC r271588: Update CAM CCB accounting for the new status quo.

devq_openings counter lost its meaning after allocation queues has gone.
held counter is still meaningful, but problematic to update due to separate
locking of CCB allocation and queuing.

To fix that replace devq_openings counter with allocated counter. held is
now calculated on request as difference between number of allocated, queued
and active CCBs.


# 268700 15-Jul-2014 mav

MFC r268240 (by ken):
Add persistent reservation support to camcontrol(8).

camcontrol(8) now supports a new 'persist' subcommand that allows users to
issue SCSI PERSISTENT RESERVE IN / OUT commands.


# 265652 08-May-2014 smh

MFC r264863

Add information about supported NCQ functionality to camcontrol identify.

Sponsored by: Multiplay


# 265632 08-May-2014 mav

MFC r260509:
Replace several instances of -1 with appropriate CAM_*_WILDCARD and types.

It was equal before r259397, but for good or bad, not any more for LUNs.

This change fixes at least CAM debugging.


# 260177 01-Jan-2014 scottl

MFC r260059, r260087:

Add the '-b' flag to 'camcontrol devlist'. This prints only the existing
buses and their parent sims, useful for creating a sim->bus->device map.

Obtained from: Netflix


# 259204 10-Dec-2013 nwhitehorn

MFC r257345,257382,257388:

Implement extended LUN support. If PIM_EXTLUNS is set by a SIM, encode
the upper 32-bits of the LUN, if possible, into the target_lun field as
passed directly from the REPORT LUNs response. This allows extended LUN
support to work for all LUNs with zeros in the lower 32-bits, which covers
most addressing modes without breaking KBI. Behavior for drivers not
setting PIM_EXTLUNS is unchanged. No user-facing interfaces are modified.

Extended LUNs are stored with swizzled 16-bit word order so that, for
devices implementing LUN addressing (like SCSI-2), the numerical
representation of the LUN is identical with and without PIM_EXTLUNS. Thus
setting PIM_EXTLUNS keeps most behavior, and user-facing LUN IDs, unchanged.
This follows the strategy used in Solaris. A macro (CAM_EXTLUN_BYTE_SWIZZLE)
is provided to transform a lun_id_t into a uint64_t ordered for the wire.

This is the second part of work for full 64-bit extended LUN support and is
designed to a bridge for stable/10 to the final 64-bit LUN code. The
third and final part will involve widening lun_id_t to 64 bits and will
not be MFCed. This third part will break the KBI but will keep the KPI
unchanged so that all drivers that will care about this can be updated now
and not require code changes between HEAD and stable/10.

Reviewed by: scottl


# 287203 27-Aug-2015 ken

MFC, r286965:

------------------------------------------------------------------------
r286965 | ken | 2015-08-20 10:07:51 -0600 (Thu, 20 Aug 2015) | 297 lines

Revamp camcontrol(8) fwdownload support and add the opcodes subcommand.

The significant changes and bugs fixed here are:

1. Fixed a bug in the progress display code:

When the user's filename is too big, or his terminal width is too
small, the progress code could wind up using a negative number for
the length of the "stars" that it uses to indicate progress.

This negative value was assigned to an unsigned variable, resulting
in a very large positive value.

The result is that we wound up writing garbage from memory to the
user's terminal.

With an 80 column terminal, a file name length of more than 35
characters would generate this problem.

To address this, we now set a minimum progress bar length, and
truncate the user's file name as needed.

This has been tested with large filenames and small terminals, and
at least produces reasonable results. If the terminal is too
narrow, the progress display takes up an additional line with each
update, but this is more user friendly than writing garbage to the
tty.

2. SATA drives connected via a SATA controller didn't have SCSI Inquiry
data populated in struct cam_device. This meant that the code in
fw_get_vendor() in fwdownload.c would try to match a zero-length
vendor ID, and so return the first entry in the vendor table. (Which
used to be HITACHI.) Fixed by grabbing identify data, passing the
identify buffer into fw_get_vendor(), and matching against the model
name.

3. SATA drives connected via a SAS controller do have Inquiry data
populated. The table included a couple of entries -- "ATA ST" and
"ATA HDS", intended to handle Seagate and Hitachi SATA drives attached
via a SAS controller. SCSI to ATA translation layers use a vendor
ID of "ATA" (which is standard), and then the model name from the ATA
identify data as the SCSI product name when they are returning data on
SATA disks. The cam_strmatch code will match the first part of the
string (because the length it is given is the length of the vendor,
"ATA"), and return 0 (i.e. a match). So all SATA drives attached to
a SAS controller would be programmed using the Seagate method
(WRITE BUFFER mode 7) of SCSI firmware downloading.

4. Issue #2 above covered up a bug in fw_download_img() -- if the
maximum packet size in the vendor table was 0, it tried to default
to a packet size of 32K. But then it didn't actually succeed in
doing that, because it set the packet size to the value that was
in the vendor table (0). Now that we actually have ATA attached
drives fall use the VENDOR_ATA case, we need a reasonable default
packet size. So this is fixed to properly set the default packet size.

5. Add support for downloading firmware to IBM LTO drives, and add a
firmware file validation method to make sure that the firmware
file matches the drive type. IBM tape drives include a Load ID and
RU name in their vendor-specific VPD page 0x3. Those should match
the IDs in the header of the firmware file to insure that the
proper firmware file is loaded.

6. This also adds a new -q option to the camcontrol fwdownload
subcommand to suppress informational output. When -q is used in
combination with -y, the firmware upgrade will happen without
prompting and without output except if an error condition occurs.

7. Re-add support for printing out SCSI inquiry information when
asking the user to confirm that they want to download firmware, and
add printing of ATA Identify data if it is a SATA disk. This was
removed in r237281 when support for flashing ATA disks was added.

8. Add a new camcontrol(8) "opcodes" subcommand, and use the
underlying code to get recommended timeout values for drive
firmware downloads.

Many SCSI devices support the REPORT SUPPORTED OPERATION CODES
command, and some support the optional timeout descriptor that
specifies nominal and recommended timeouts for the commands
supported by the device.

The new camcontrol opcodes subcommand allows displaying all
opcodes supported by a drive, information about which fields
in a SCSI CDB are actually used by a given SCSI device, and the
nominal and recommended timeout values for each command.

Since firmware downloads can take a long time in some devices, and
the time varies greatly between different types of devices, take
advantage of the infrastructure used by the camcontrol opcodes
subcommand to determine the best timeout to use for the WRITE
BUFFER command in SCSI device firmware downloads.

If the device recommends a timeout, it is likely to be more
accurate than the default 50 second timeout used by the firmware
download code. If the user specifies a timeout, it will override
the default or device recommended timeout. If the device doesn't
support timeout descriptors, we fall back to the default.

9. Instead of downloading firmware to SATA drives behind a SAS controller
using WRITE BUFFER, use the SCSI ATA PASS-THROUGH command to compose
an ATA DOWNLOAD MICROCODE command and it to the drive. The previous
version of this code attempted to send a SCSI WRITE BUFFER command to
SATA drives behind a SAS controller. Although that is part of the
SAT-3 spec, it doesn't work with the parameters used with LSI
controllers at least.

10.Add a new mechanism for making common ATA passthrough and
ATA-behind-SCSI passthrough commands.

The existing camcontrol(8) ATA command mechanism checks the device
type on every command executed. That works fine for individual
commands, but is cumbersome for things like a firmware download
that send a number of commands.

The fwdownload code detects the device type up front, and then
sends the appropriate commands.

11.In simulation mode (-s), if the user specifies the -v flag, print out
the SCSI CDB or ATA registers that would be sent to the drive. This will
aid in debugging any firmware download issues.

sbin/camcontrol/fwdownload.c:
Add a device type to the fw_vendor structure, so that we can
specify different download methods for different devices from the
same vendor. In this case, IBM hard drives (from when they
still made hard drives) and tape drives.

Add a tur_status field to the fw_vendor structure so that we can
specify whether the drive to be upgraded should be ready, not
ready, or whether it doesn't matter. Add the corresponding
capability in fw_download_img().

Add comments describing each of the vendor table fields.

Add HGST and SmrtStor to the supported SCSI vendors list.

In fw_get_vendor(), look at ATA identify data if we have a SATA
device to try to identify what the drive vendor is.

Add IBM firmware file validation. This gets VPD page 0x3, and
compares the Load ID and RU name in the page to the values
included in the header. The validation code will refuse to load
a firmware file if the values don't match. This does allow the
user to attempt a downgrade; whether or not it succeeds will
likely depend on the drive settings.

Add a -q option, and disable all informative output
(progress bars, etc.) when this is enabled.

Re-add the inquiry in the confirmation dialog so the user has
a better idea of which device he is talking to. Add support for
displaying ATA identify data.

Don't automatically disable confirmation in simulation (-s) mode.
This allows the user to see the inquiry or identify data in the
dialog, and see exactly what they would see when the command
actually runs. Also, in simulation mode, if the user specifies
the -v flag, print out the SCSI CDB or ATA registers that would
be sent to the drive. This will aid in debugging any firmware
download issues.

Add a timeout field and timeout type to the firmware download
vendor table. This allows specifying a default timeout and allows
specifying whether we should attempt to probe for a recommended
timeout from the drive.

Add a new fuction, fw_get_timeout(), that will determine
which timeout to use for the WRITE BUFFER command. If the
user specifies a timeout, we always use that. Otherwise,
we will use the drive recommended timeout, if available,
and fall back to the default when a drive recommended
timeout isn't available.

When we prompt the user, tell him what timeout we're going
to use, and the source of the timeout.

Revamp the way SATA devices are handled.

In fwdownload(), use the new get_device_type() function to
determine what kind of device we're talking to.

Allow firmware downloads to any SATA device, but restrict
SCSI downloads to known devices. (The latter is not a
change in behavior.)

Break out the "ready" check from fw_download_img() into a
new subfunction, fw_check_device_ready(). This sends the
appropriate command to the device in question -- a TEST
UNIT READY or an IDENTIFY. The IDENTIFY for SATA devices
a SAT layer is done using the SCSI ATA PASS-THROUGH
command.

Use the new build_ata_cmd() function to build either a SCSI or
ATA I/O CCB to issue the DOWNLOAD MICROCODE command to SATA
devices. build_ata_cmd() figures looks at the devtype argument
and fills in the correct CCB type and CDB or ATA registers.

Revamp the vendor table to remove the previous
vendor-specific ATA entries and use a generic ATA vendor
placeholder. We currently use the same method for all ATA
drives, although we may have to add vendor-specific
behavior once we test this with more drives.

sbin/camcontrol/progress.c:
In progress_draw(), make barlength a signed value so that
we can easily detect a negative value.

If barlength (the length of the progress bar) would wind up
negative due to a small TTY width or a large filename,
set the bar length to the new minimum (10 stars) and
truncate the user's filename. We will truncate it down to
0 characters if necessary.

Calculate a new prefix_len variable (user's filename length)
and use it as the precision when printing the filename.

sbin/camcontrol/camcontrol.c:
Implement a new camcontrol(8) subcommand, "opcodes". The
opcodes subcommand allows displaying the entire list of
SCSI commands supported by a device, or details on an
individual command. In either case, it can display
nominal and recommended timeout values.

Add the scsiopcodes() function, which calls the new
scsigetopcodes() function to fetch opcode data from a
drive.

Add two new functions, scsiprintoneopcode() and
scsiprintopcodes(), which print information about one
opcode or all opcodes, respectively.

Remove the get_disk_type() function. It is no longer used.

Add a new function, dev_has_vpd_page(), that fetches the
supported INQUIRY VPD list from a device and tells the
caller whether the requested VPD page is available.

Add a new function, get_device_type(), that returns a more
precise device type than the old get_disk_type() function.
The get_disk_type() function only distinguished between
SCSI and ATA devices, and SATA devices behind a SCSI to ATA
translation layer were considered to be "SCSI".

get_device_type() offers a third type, CC_DT_ATA_BEHIND_SCSI.
We need to know this to know whether to attempt to send ATA
passthrough commands. If the device has the ATA
Information VPD page (0x89), then it is an ATA device
behind a SCSI to ATA translation layer.

Remove the type argument from the fwdownload() subcommand.

Add a new function, build_ata_cmd(), that will take one set
of common arguments and build either a SCSI or ATA I/O CCB,
depending on the device type passed in.

sbin/camcontrol/camcontrol.h:
Add a prototype for scsigetopcodes().

Add a new enumeration, camcontrol_devtype.

Add prototypes for dev_has_vpd_page(), get_device_type()
and build_ata_cmd().

Remove the type argument from the fwdownload() subcommand.

sbin/camcontrol/camcontrol.8
Explain that the fwdownload subcommand will use the drive
recommended timeout if available, and that the user can
override the timeout.

Document the new opcodes subcommand.

Explain that we will attempt to download firmware to any
SATA device.

Document supported SCSI vendors, and models tested if known.

Explain the commands used to download firmware for the
three different drive and controller combinations.

Document that the -v flag in simulation mode for the fwdownload
subcommand will print out the SCSI CDBs or ATA registers that would
be used.

sys/cam/scsi/scsi_all.h:
Add new bit definitions for the one opcode descriptor for
the REPORT SUPPORTED OPCODES command.

Add a function prototype for scsi_report_supported_opcodes().

sys/cam/scsi/scsi_all.c:
Add a new CDB building function, scsi_report_supported_opcodes().

Sponsored by: Spectra Logic


# 285532 14-Jul-2015 brueffer

MFC: r285037

Add -b to the devlist usage info, forgotten in r260059.

PR: 195094
Submitted by: robin.hahling@gw-computing.net
Approved by: re (marius)


# 284435 16-Jun-2015 ken

MFC, r284192:

------------------------------------------------------------------------
r284192 | ken | 2015-06-09 15:39:38 -0600 (Tue, 09 Jun 2015) | 102 lines

Add support for reading MAM attributes to camcontrol(8) and libcam(3).

MAM is Medium Auxiliary Memory and is most commonly found as flash
chips on tapes.

This includes support for reading attributes and decoding most
known attributes, but does not yet include support for writing
attributes or reporting attributes in XML format.

libsbuf/Makefile:
Add subr_prf.c for the new sbuf_hexdump() function. This
function is essentially the same function.

libsbuf/Symbol.map:
Add a new shared library minor version, and include the
sbuf_hexdump() function.

libsbuf/Version.def:
Add version 1.4 of the libsbuf library.

libutil/hexdump.3:
Document sbuf_hexdump() alongside hexdump(3), since it is
essentially the same function.

camcontrol/Makefile:
Add attrib.c.

camcontrol/attrib.c:
Implementation of READ ATTRIBUTE support for camcontrol(8).

camcontrol/camcontrol.8:
Document the new 'camcontrol attrib' subcommand.

camcontrol/camcontrol.c:
Add the new 'camcontrol attrib' subcommand.

camcontrol/camcontrol.h:
Add a function prototype for scsiattrib().

share/man/man9/sbuf.9:
Document the existence of sbuf_hexdump() and point users to
the hexdump(3) man page for more details.

sys/cam/scsi/scsi_all.c:
Add a table of known attributes, text descriptions and
handler functions.

Add a new scsi_attrib_sbuf() function along with a number
of other related functions that help decode attributes.

scsi_attrib_ascii_sbuf() decodes ASCII format attributes.

scsi_attrib_int_sbuf() decodes binary format attributes, and
will pass them off to scsi_attrib_hexdump_sbuf() if they're
bigger than 8 bytes.

scsi_attrib_vendser_sbuf() decodes the vendor and drive
serial number attribute.

scsi_attrib_volcoh_sbuf() decodes the Volume Coherency
Information attribute that LTFS writes out.

sys/cam/scsi/scsi_all.h:
Add a number of attribute-related structure definitions and
other defines.

Add function prototypes for all of the functions added in
scsi_all.c.

sys/kern/subr_prf.c:
Add a new function, sbuf_hexdump(). This is the same as
the existing hexdump(9) function, except that it puts the
result in an sbuf.

This also changes subr_prf.c so that it can be compiled in
userland for includsion in libsbuf.

We should work to change this so that the kernel hexdump
implementation is a wrapper around sbuf_hexdump() with a
statically allocated sbuf with a drain. That will require
a drain function that goes to the kernel printf() buffer
that can take a non-NUL terminated string as input.
That is because an sbuf isn't NUL-terminated until it is
finished, and we don't want to finish it while we're still
using it.

We should also work to consolidate the userland hexdump and
kernel hexdump implemenatations, which are currently
separate. This would also mean making applications that
currently link in libutil link in libsbuf.

sys/sys/sbuf.h:
Add the prototype for sbuf_hexdump(), and add another copy
of the hexdump flag values if they aren't already defined.

Ideally the flags should be defined in one place but the
implemenation makes it difficult to do properly. (See
above.)

Sponsored by: Spectra Logic Corporation

------------------------------------------------------------------------


# 280896 31-Mar-2015 mav

MFC r280166:
Make ATA power management commands to work on SCSI HBAs via PASS THROUGH.


# 280679 26-Mar-2015 mav

MFC r280249: Add camcontrol subcommands to control APM and AAM levels.

Sponsored by: iXsystems, Inc.


# 279329 26-Feb-2015 ken

MFC r278964:

The __FreeBSD_version was changed to 1001510 to be appropriate for
stable/10.

I will followup with a commit to mpr(4) and mps(4) in head to reflect
the stable/10 __FreeBSD_version and merge the change back to stable/10.

------------------------------------------------------------------------
r278964 | ken | 2015-02-18 11:30:19 -0700 (Wed, 18 Feb 2015) | 46 lines

Make sure that the flags for the XPT_DEV_ADVINFO CCB are initialized
properly.

If there is garbage in the flags field, it can sometimes include a
set CDAI_FLAG_STORE flag, which may cause either an error or
perhaps result in overwriting the field that was intended to be
read.

sys/cam/cam_ccb.h:
Add a new flag to the XPT_DEV_ADVINFO CCB, CDAI_FLAG_NONE,
that callers can use to set the flags field when no store
is desired.

sys/cam/scsi/scsi_enc_ses.c:
In ses_setphyspath_callback(), explicitly set the
XPT_DEV_ADVINFO flags to CDAI_FLAG_NONE when fetching the
physical path information. Instead of ORing in the
CDAI_FLAG_STORE flag when storing the physical path, set
the flags field to CDAI_FLAG_STORE.

sys/cam/scsi/scsi_sa.c:
Set the XPT_DEV_ADVINFO flags field to CDAI_FLAG_NONE when
fetching extended inquiry information.

sys/cam/scsi/scsi_da.c:
When storing extended READ CAPACITY information, set the
XPT_DEV_ADVINFO flags field to CDAI_FLAG_STORE instead of
ORing it into a field that isn't initialized.

sys/dev/mpr/mpr_sas.c,
sys/dev/mps/mps_sas.c:
When fetching extended READ CAPACITY information, set the
XPT_DEV_ADVINFO flags field to CDAI_FLAG_NONE instead of
setting it to 0.

sbin/camcontrol/camcontrol.c:
When fetching a device ID, set the XPT_DEV_ADVINFO flags
field to CDAI_FLAG_NONE instead of 0.

sys/sys/param.h:
Bump __FreeBSD_version to 1100061 for the new XPT_DEV_ADVINFO
CCB flag, CDAI_FLAG_NONE.

Sponsored by: Spectra Logic


# 278170 03-Feb-2015 ken

MFC r276835:

r276835 | ken | 2015-01-08 09:58:40 -0700 (Thu, 08 Jan 2015) | 91 lines

Improve camcontrol(8) handling of drive defect data.

This includes a new summary mode (-s) for camcontrol defects that
quickly tells the user the most important thing: how many defects
are in the requested list. The actual location of the defects is
less important.

Modern drives frequently have more than the 8191 defects that can
be reported by the READ DEFECT DATA (10) command. If they don't
have that many grown defects, they certainly have more than 8191
defects in the primary (i.e. factory) defect list.

The READ DEFECT DATA (12) command allows for longer parameter
lists, as well as indexing into the list of defects, and so allows
reporting many more defects.

This has been tested with HGST drives and Seagate drives, but
does not fully work with Seagate drives. Once I have a Seagate
spec I may be able to determine whether it is possible to make it
work with Seagate drives.

scsi_da.h: Add a definition for the new long block defect
format.

Add bit and mask definitions for the new extended
physical sector and bytes from index defect
formats.

Add a prototype for the new scsi_read_defects() CDB
building function.

scsi_da.c: Add a new scsi_read_defects() CDB building function.
camcontrol(8) was previously composing CDBs manually.
This is long overdue.

camcontrol.c: Revamp the camcontrol defects subcommand. We now
go through multiple stages in trying to get defect
data off the drive while avoiding various drive
firmware quirks.

We start off by requesting the defect header with
the 10 byte command. If we're in summary mode (-s)
and the drive reports fewer defects than can be
represented in the 10 byte header, we're done.
Otherwise, we know that we need to issue the
12 byte command if the drive reports the maximum
number of defects.

If we're in summary mode, we're done if we get a
good response back when asking for the 12 byte header.

If the user has asked for the full list, then we
use the address descriptor index field in the 12
byte CDB to step through the list in 64K chunks.
64K is small enough to work with most any ancient
or modern SCSI controller.

Add support for printing the new long block defect
format, as well as the extended physical sector and
bytes from index formats. I don't have any drives
that support the new formats.

Add a hexadecimal output format that can be turned
on with -X.

Add a quiet mode (-q) that can be turned on with
the summary mode (-s) to just print out a number.

Revamp the error detection and recovery code for
the defects command to work with HGST drives.

Call the new scsi_read_defects() CDB building
function instead of rolling the CDB ourselves.

Pay attention to the residual from the defect list
request when printing it out, so we don't run off
the end of the list.

Use the new scsi_nv library routines to convert
from strings to numbers and back.

camcontrol.8: Document the new defect formats (longblock, extbfi,
extphys) and command line options (-q, -s, -S and
-X) for the defects subcommand.

Explain a little more about what drives generally
do and don't support.

Sponsored by: Spectra Logic


# 275630 09-Dec-2014 bryanv

MFC r274322:

Attempt to report a better error if sanitize is not supported


# 273078 14-Oct-2014 mav

MFC r271588: Update CAM CCB accounting for the new status quo.

devq_openings counter lost its meaning after allocation queues has gone.
held counter is still meaningful, but problematic to update due to separate
locking of CCB allocation and queuing.

To fix that replace devq_openings counter with allocated counter. held is
now calculated on request as difference between number of allocated, queued
and active CCBs.


# 268700 15-Jul-2014 mav

MFC r268240 (by ken):
Add persistent reservation support to camcontrol(8).

camcontrol(8) now supports a new 'persist' subcommand that allows users to
issue SCSI PERSISTENT RESERVE IN / OUT commands.


# 265652 08-May-2014 smh

MFC r264863

Add information about supported NCQ functionality to camcontrol identify.

Sponsored by: Multiplay


# 265632 08-May-2014 mav

MFC r260509:
Replace several instances of -1 with appropriate CAM_*_WILDCARD and types.

It was equal before r259397, but for good or bad, not any more for LUNs.

This change fixes at least CAM debugging.


# 260177 01-Jan-2014 scottl

MFC r260059, r260087:

Add the '-b' flag to 'camcontrol devlist'. This prints only the existing
buses and their parent sims, useful for creating a sim->bus->device map.

Obtained from: Netflix


# 259204 10-Dec-2013 nwhitehorn

MFC r257345,257382,257388:

Implement extended LUN support. If PIM_EXTLUNS is set by a SIM, encode
the upper 32-bits of the LUN, if possible, into the target_lun field as
passed directly from the REPORT LUNs response. This allows extended LUN
support to work for all LUNs with zeros in the lower 32-bits, which covers
most addressing modes without breaking KBI. Behavior for drivers not
setting PIM_EXTLUNS is unchanged. No user-facing interfaces are modified.

Extended LUNs are stored with swizzled 16-bit word order so that, for
devices implementing LUN addressing (like SCSI-2), the numerical
representation of the LUN is identical with and without PIM_EXTLUNS. Thus
setting PIM_EXTLUNS keeps most behavior, and user-facing LUN IDs, unchanged.
This follows the strategy used in Solaris. A macro (CAM_EXTLUN_BYTE_SWIZZLE)
is provided to transform a lun_id_t into a uint64_t ordered for the wire.

This is the second part of work for full 64-bit extended LUN support and is
designed to a bridge for stable/10 to the final 64-bit LUN code. The
third and final part will involve widening lun_id_t to 64 bits and will
not be MFCed. This third part will break the KBI but will keep the KPI
unchanged so that all drivers that will care about this can be updated now
and not require code changes between HEAD and stable/10.

Reviewed by: scottl