mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
main
100
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
68ba58a064 |
camcontrol: Fix -Wcast-align errors in the NVMe reservation report
Casting the byte buffer that holds the Reservation Report payload to
the status structures trips -Wcast-align on strict-alignment
architectures, which broke the CI builds there. Put the buffer in a
union with the two status structures instead, so it is properly
aligned and no casts are needed.
Reported by: FreeBSD CI
Fixes:
|
||
|
|
6eae951cd5 |
camcontrol: Add a feature subcommand for NVMe Get/Set Features
Add a feature subcommand for the NVMe Get Features and Set Features
commands:
camcontrol feature ndaX -a <get|set> -f feature [-d data]
[-s num] [-U]
There is no transport-specific prefix in the name: SCSI has no
feature command (the closest equivalents are mode pages), and the
ATA SET FEATURES subcommands are already exposed through dedicated
camcontrol subcommands (apm, aam, epc and the power commands), so
the name is unclaimed. The subcommand returns an error for
non-NVMe devices.
Currently, only the hostid feature is fully implemented. The
hostid value for set is specified with -d as a UUID or an integer
in decimal, hex, or octal, and -U outputs the hostid as a UUID on
get.
The -s argument exposes the feature select / save fields from the
NVMe specification. If bit 4 of the Optional NVM Command Support
(ONCS) field of the Identify Controller data is set, each feature
has a default, saved and current value, plus a capabilities mask:
- For get, -s selects which to display: 0 (current),
1 (default), 2 (saved) or 3 (capabilities).
- For set, -s is the save flag; a value of 1 sets the saved
value as well as the current value, so the feature
persists across an NVMe reset. Setting the save flag only
works if the feature's capability mask includes saveable.
sbin/camcontrol/nvfeature.c:
New file, the camcontrol(8) feature subcommand for getting
and setting NVMe features.
sbin/camcontrol/camcontrol.c:
Add the feature subcommand, dispatched only to NVMe devices.
sbin/camcontrol/camcontrol.h:
Add the nvmefeature() prototype.
sbin/camcontrol/Makefile:
Add nvfeature.c to the build.
sbin/camcontrol/camcontrol.8:
Document the feature subcommand.
Co-authored-by: Reid Linnemann <[email protected]>
Co-authored-by: Dave Baukus <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
Reviewed by: imp
MFC after: 1 week
Sponsored by: Spectra Logic
Differential Revision: https://reviews.freebsd.org/D59536
|
||
|
|
80f090111a |
camcontrol: Support NVMe namespace formatting via the format subcommand
Support formatting NVMe namespaces through the existing format subcommand. The format subcommand now dispatches on the device protocol, in the same way the identify and persist subcommands do, and issues the NVMe FORMAT NVM command for NVMe devices. The SCSI syntax and behavior are unchanged. The NVMe-specific options are -e (secure erase setting), -G (format all namespaces), -f (LBA format), -l (protection information location), -m (metadata setting) and -p (protection information type). The -q and -y options work for both protocols; NVMe formats gain the same confirmation question that SCSI formats have always had. The -r and -w options are SCSI only; -r returns an error for NVMe devices and -w has no effect, since the NVMe format command does not complete until the format is finished. The default timeout for NVMe is 30 seconds for a cryptographic erase and 30 minutes otherwise; the generic -t option overrides it. sbin/camcontrol/nvformat.c: New file, the NVMe format backend for the format subcommand. sbin/camcontrol/camcontrol.c: Dispatch the format subcommand to scsiformat() or nvmeformat() based on the device protocol. sbin/camcontrol/camcontrol.h: Add the nvmeformat() prototype. sbin/camcontrol/Makefile: Add nvformat.c to the build. sbin/camcontrol/camcontrol.8: Document NVMe support in the format subcommand section, and note the differences from SCSI where they occur. Co-authored-by: Claude Fable 5 <[email protected]> Reviewed by: imp MFC after: 1 week Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D59535 |
||
|
|
ba75cf0572 |
camcontrol: Support NVMe reservations via the persist subcommand
The NVMe reservation model is closely patterned after SCSI Persistent Reservations, so support NVMe devices through the existing persist subcommand rather than adding a transport-specific subcommand. The persist subcommand now dispatches on the device protocol, in the same way the identify subcommand does. The SCSI syntax is unchanged. For NVMe devices, the -i modes all map to the Reservation Report command (read_full_status requests the extended data structure, which contains 128-bit Host Identifiers), and the -o service actions map to the corresponding NVMe reservation operations: register, register_ignore, reserve, preempt, preempt_abort, release and clear, plus two NVMe-only actions, unregister and replace. The reservation type names for -T are shared between SCSI and NVMe. A new -c option gives explicit control over the NVMe Persist Through Power Loss State; -p is equivalent to -c enable. SCSI-only options return an error for NVMe devices. Tested against a PASCARI X200 series SSD (reservation capabilities: WR_EX, PTPL, IEKEY13): register, reserve, release, replace, unregister, -c enable/disable (Persist Through Power Loss State change verified in the report output), reservation report, and the error paths. register_ignore is rejected by drives that implement NVMe 1.3 IEKEY semantics, as expected. SCSI persist against a da(4) device is unchanged. sbin/camcontrol/nvres.c: New file, the NVMe reservation backend for the persist subcommand. sbin/camcontrol/camcontrol.c: Dispatch the persist subcommand to scsipersist() or nvmepersist() based on the device protocol. sbin/camcontrol/camcontrol.h: Add the nvmepersist() prototype. sbin/camcontrol/Makefile: Add nvres.c to the build. sbin/camcontrol/camcontrol.8: Document NVMe support in the persist subcommand section, and note the differences from SCSI where they occur. Co-authored-by: Reid Linnemann <[email protected]> Co-authored-by: Claude Fable 5 <[email protected]> Reviewed by: imp MFC after: 1 week Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D59534 |
||
|
|
961fa195b3 |
camcontrol: Add support for NVMe namespace Identify
Add a -N argument to camcontrol identify. This will fetch and display namespace Identify data for NVMe drives, using nvme_print_namespace() from nvmecontrol(8). This gets the namespace Identify data via XPT_DEV_ADVINFO (i.e. data cached in the kernel) like the standard NVMe identify command does, and so works even on NVMe devices that do not support NVMe Namespace Management. sbin/camcontrol/camcontrol.c: Add a -N argument to camcontrol identify. Rename nvme_get_cdata() to nvme_get_data(), and give it the ability to fetch controller or namespace Identify data. While here, improve its error reporting with cam_error_print(), and only look at the CAM status bits of the returned CCB. Change identify(), ataidentify(), and nvmeidentify() to handle the extra arguments. Give nvmeidentify() the ability to fetch and print NVMe namespace data, using nvme_print_namespace() from nvmecontrol(8). sbin/camcontrol/camcontrol.h: Add the nvme_get_data() prototype, for use by future NVMe subcommands living outside camcontrol.c. sbin/camcontrol/camcontrol.8: Document camcontrol identify -N. Make it clear that the NVMe data is from data cached in the kernel. Add a cross reference to nvmecontrol(8). Co-authored-by: Claude Fable 5 <[email protected]> Reviewed by: imp MFC after: 1 week Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D59533 |
||
|
|
9814633f63 |
cam: Add NVMe reservation, format and features CCB building functions
Add NVMe CCB (union ccb / struct ccb_nvmeio) building functions for the four NVMe reservation opcodes, Format NVM, and Get Features / Set Features. These use the nvme_command building blocks added to sys/dev/nvme/nvme.h, and are used by the new camcontrol(8) nvres, nvformat and nvfeature subcommands that will be added separately. sys/cam/nvme/nvme_all.c: Add NVMe CCB building functions for the four NVMe reservation opcodes: nvme_resv_report(), nvme_resv_register(), nvme_resv_acquire() and nvme_resv_release(). Data direction is set internally (CAM_DIR_IN or CAM_DIR_OUT as appropriate), so no flags parameter is needed. Add a new nvme_format() CCB building function. Add nvme_get_feature() and nvme_set_feature() CCB building functions, along with nvme_get_feature_hostid() and nvme_set_feature_hostid() convenience wrappers for the hostid feature. nvme_set_feature_hostid() takes an sv argument so the caller can request that the hostid persist across reset. sys/cam/nvme/nvme_all.h: Add prototypes for the above. Wrap the declarations in __BEGIN_DECLS / __END_DECLS so C++ compilers don't mangle the names of the C symbols. Co-authored-by: Reid Linnemann <[email protected]> Co-authored-by: Dave Baukus <[email protected]> Co-authored-by: Claude Fable 5 <[email protected]> Reviewed by: imp MFC after: 1 week Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D59532 |
||
|
|
7a9e437531 |
nvme: Add reservation, format and features command building support
Add command (struct nvme_command) building functions for the four NVMe reservation opcodes (Report, Register, Acquire and Release), Format NVM, and Get Features / Set Features, along with the enumerations and data structures that go with them. These are shared between the kernel and userland, and are the underpinnings for new camcontrol(8) subcommands (nvres, nvformat, nvfeature) that will be added separately. The reservation type names are intentionally similar to the SCSI names for the same reservation types. sys/dev/nvme/nvme.h: Add NVMe command building functions for the four NVMe reservation opcodes: nvme_ns_resv_report_cmd(), nvme_ns_resv_register_cmd(), nvme_ns_resv_acquire_cmd() and nvme_ns_resv_release_cmd(). Add enumerated types for the various NVMe reservation subcommand actions (acquire, register, release), reservation types, and Change Persist Through Power Loss State values. Add struct nvme_resv_acq_data and struct nvme_resv_reg_data, the data payloads for reservation Acquire and Register. Add a new NVMe Format NVM command building function, nvme_admin_format_cmd(), and an enumeration for the Secure Erase Setting parameter for format. Add nvme_admin_get_feature_cmd() and nvme_admin_set_feature_cmd() functions to fill a struct nvme_command for Get Features / Set Features. Add macros for bitfields in the ctratt and mic dwords of the NVMe Identify Controller data structure. Add a prototype for nvme_hostid_sbuf(). Stop byte swapping the hostid fields in nvme_resv_status_swapbytes() and nvme_resv_status_ext_swapbytes(), and document the fields as little endian. The hostid is an opaque 8 or 16 byte value; keep it in the byte order the device returns it in instead of interpreting it at this level. Widen the nvme_ctrlr_cmd_get_feature() and nvme_ctrlr_cmd_set_feature() prototypes as described below. While here, fix the entry count clamp in the reservation status swapbytes functions to use sizeof(*s) rather than sizeof(s); using the pointer size made the clamp one entry too permissive. sys/dev/nvme/nvme_util.c: Add nvme_hostid_sbuf(), which formats an 8 or 16 byte hostid (from the Get Features hostid feature, in the little-endian byte order the device returns it in) into an sbuf as an integer value in base 16, most significant byte first. sbin/nvmecontrol/resv.c: Decode the now little-endian hostid fields explicitly when printing, and zero pad the printed 64-bit values. Previously the extended hostid printed in a different byte order on big and little endian machines, and without zero padding between the two halves. sys/dev/nvme/nvme_ctrlr_cmd.c: Refactor nvme_ctrlr_cmd_get_feature() and nvme_ctrlr_cmd_set_feature() to use the new command building functions from nvme.h and accept a namespace ID parameter. Refactor nvme_ctrlr_cmd_set_feature() to also accept the sv (save) parameter to persist a feature value across reset. sys/dev/nvme/nvme_ctrlr.c: Update the temperature threshold, autonomous power state transition and host memory buffer callers for the new nvme_ctrlr_cmd_get_feature() and nvme_ctrlr_cmd_set_feature() arguments. Co-authored-by: Reid Linnemann <[email protected]> Co-authored-by: Dave Baukus <[email protected]> Co-authored-by: Claude Fable 5 <[email protected]> Reviewed by: imp MFC after: 1 week Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D59531 |
||
|
|
46198fba6d |
nvmecontrol: Factor out namespace Identify printing
Move print_namespace() from identify.c to identify_ext.c and rename it to nvme_print_namespace(), to match nvme_print_controller(). This allows other consumers (notably camcontrol(8)) to print NVMe namespace Identify data. No functional changes intended. sbin/nvmecontrol/identify.c: Remove print_namespace(), and call nvme_print_namespace() instead. sbin/nvmecontrol/identify_ext.c: Add nvme_print_namespace(), moved here from identify.c. sbin/nvmecontrol/nvmecontrol.h: Remove the print_namespace() prototype. sbin/nvmecontrol/nvmecontrol_ext.h: Add the nvme_print_namespace() prototype. sbin/nvmecontrol/ns.c: Include nvmecontrol_ext.h, and rename print_namespace() calls to nvme_print_namespace(). Co-authored-by: Claude Fable 5 <[email protected]> Reviewed by: imp MFC after: 1 week Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D59530 |
||
|
|
930486f9be |
mt(1)/libmt: Add LTO-10 density codes and specs.
These were obtained from IBM specs and actual tapes/drives. Standard LTO-10 cartriges hold 30TB raw, 75TB with 2.5:1 compression. Premium LTO-10 cartridges hold 40TB raw, 100TB with 2.5:1 compression. LTO-10 tape drives are not backward compatible with previous generation LTO tapes. (This is a change from older generation drives.) Since the Premium tape is a new thing for LTO, we'll call this density code LTO-10P vs. the standard LTO-10. The barcode identifier for LTO-10 tapes is "LA"; the barcode identifier for LTO-10P tapes is "PA". LTO-10 cartridges contain 1035m of tape, while LTO-10 Premium cartridges contain 1337m of tape and have slightly higher density. (Obtained from MAM data on actual tape cartridges and the density report, obtained via 'mt getdensity'.) LTO-10 cartridges use a polyethylene naphthalate (PEN) film substrate. LTO-10 Premium cartridges use an Aramid (aromatic polyamide) substrate that is thinner and stronger, allowing a longer tape to fit in the same cartridge form factor. usr.bin/mt/mt.1: Add density codes and specs for LTO-10 and LTO-10P. lib/libmt/mtlib.c: Add density codes for LTO-10 and LTO-10P. Sponsored by: Spectra Logic MFC after: 3 days |
||
|
|
31354813f3 |
Add an isp(4) tunable to default to ispfw(4) firmware.
ispfw(4) recently gained firmware for Qlogic 27XX and 28XX FC controllers, and isp(4) now selects the newer of firmware in flash or in ispfw(4) to load for those controllers. This differs from the previous behavior (which remains for older controllers), which was to always load the ispfw(4) firmware if it is available. This adds a loader tunable, hint.isp.N.fwload_force to default to loading the ispfw(4) firmware, whether or not it is newer than the firmware in flash. This allows the user to always use the known firmware version included with the kernel. Note that there is an existing fwload_disable tunable that tells the driver to always load the firmware from flash and ignore ispfw(4). If fwload_disable is set, fwload_force will be ignored. So users with existing fwload_disable tunables will have the same behavior. If a user specifies both fwload_force and fwload_disable for the same controller, the isp(4) driver prints a warning message, and fwload_disable will be honored. The user can see which firmware is active through the dev.isp.N.fw_version* sysctl variables. share/man/man4/isp.4: Document the new loader tunable. sys/dev/isp/isp.c: In isp_load_risc_flash(), changet the decision logic to also consider ISP_CFG_FWLOAD_ONLY. Load the flash firmware and get the version, so the user knows what it is, but if the user set fwload_force, honor that. If the user didn't set fwload_force, the behavior remains to select the newer firmware version. sys/dev/isp/isp_pci.c: Add a new fwload_force tunable. Print out a warning if the user sets both fwload_disable and fwload_force. sys/dev/isp/ispvar.h: Add a new ISP_CFG_FWLOAD_FORCE configuration bit. Reviewed by: mav MFC after: 1 week Sponsored by: Spectra Logic Differential Revision: <https://reviews.freebsd.org/D45688> |
||
|
|
137b004e2b |
Fix the isp(4) driver with 9.x firmware.
The isp(4) driver (and ispfw(4) firmware) previously only included firmware for Qlogic controllers up to 8Gb. It recently gained firmware for the 27XX and 28XX series controllers along with improved firmware loading capabilities. The 9.x firmware available for the 27XX and 28XX controllers in ispfw(4) adds login state for NVMe devices in the top nibble of the login state in the port database (isp_pdb_24xx_t in ispmbox.h). This breaks the check at the end of isp_getpdb() to make sure the device is in the right login state. As a result, it breaks device discovery for many (perhaps all?) FC devices. In my testing with IBM LTO-6 drives attached to a quad port 16Gb Qlogic 2714, they don't show up when they are directly connected (and in loop mode) or connected via a switch (and in fabric mode). So, mask off the top bits of of the login state before checking it. This shouldn't break anything, because all of the existing login states defined in ispmbox.h are in the low nibble. sys/dev/isp/ispmbox.h: Add a FCP login state mask define, and a NVMe login state shift. sys/dev/isp/isp.c: In isp_getpdb(), make sure we're only looking at the FCP login state bits when we try to determine whether a device is in the right login state. MFC after: 1 week Sponsored by: Spectra Logic Reviewed by: mav Differential Revision: <https://reviews.freebsd.org/D45660> |
||
|
|
cd95f18c47 |
camcontrol: add support for Toshiba drive firmware update
Thanks to Toshiba for providing the SCSI spec for their latest generation drives so I could confirm how they operate. The firmware download works in a pretty standard way, so this is a straightforward table addition. sbin/camcontrol/camcontrol.8: Document that Toshiba drives are supported for fwdownload, and that it was tested on TOSHIBA MG10SFA22TE 22TB drives. sbin/camcontrol/fwdownload.c: Add TOSHIBA to the known SCSI vendors list for fwdownload. Sponsored by: Spectra Logic MFC after: 3 days |
||
|
|
40a492d38e |
camcontrol: Add a sense subcommand
As the name suggests, this sends a SCSI REQUEST SENSE to a device, and prints out decoded sense information. It can also print out a hexdump of the sense data. sbin/camcontrol/camcontrol.c: Add the new sense subcommand. sbin/camcontrol/camcontrol.8: Document camcontrol sense. Sponsored by: Spectra Logic Reviewed by: mav MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D43225 |
||
|
|
264610a86e |
mpr, mps: Establish busdma boundaries for memory pools
Most all of the memory used by the cards in the mpr(4) and mps(4) drivers is required, according to the specs and Broadcom developers, to be within a 4GB segment of memory. This includes: System Request Message Frames pool Reply Free Queues pool ReplyDescriptorPost Queues pool Chain Segments pool Sense Buffers pool SystemReply message pool We got a bug report from Dwight Engen, who ran into data corruption in the BAE port of FreeBSD: > We have a port of the FreeBSD mpr driver to our kernel and recently > I found an issue under heavy load where a DMA may go to the wrong > address. The test system is a Supermicro X10SRH-CLN4F with the > onboard SAS3008 controller setup with 2 enterprise Micron SSDs in > RAID 0 (striped). I have debugged the issue and narrowed down that > the errant DMA is one that has a segment that crosses a 4GB > physical boundary. There are more details I can provide if you'd > like, but with the attached patch in place I can no longer > re-create the issue. > I'm not sure if this is a known limit of the card (have not found a > datasheet/programming docs for the chip) or our system is just > doing something a bit different. Any helpful info or insight would > be welcome. > Anyway, just thought this might be helpful info if you want to > apply a similar fix to FreeBSD. You can ignore/discard the commit > message as it is my internal commit (blkio is our own tool we use > to write/read every block of a device with CRC verification which > is how I found the problem). The commit message was: > [PATCH 8/9] mpr: fix memory corrupting DMA when sg segment crosses > 4GB boundary > Test case was two SSD's in RAID 0 (stripe). The logical disk was > then partitioned into two partitions. One partition had lots of > filesystem I/O and the other was initially filled using blkio with > CRCable data and then read back with blkio CRC verify in a loop. > Eventually blkio would report a bad CRC block because the physical > page being read-ahead into didn't contain the right data. If the > physical address in the arq/segs was for example 0x500003000 the > data would actually be DMAed to 0x400003000. The original patch was against mpr(4) before busdma templates were introduced, and only affected the buffer pool (sc->buffer_dmat) in the mpr(4) driver. After some discussion with Dwight and the LSI/Broadcom developers and looking through the driver, it looks like most of the queues in the driver are ok, because they limit the memory used to memory below 4GB. The buffer queue and the chain frames seem to be the exceptions. This is pretty much the same between the mpr(4) and mps(4) drivers. So, apply a 4GB boundary limitation for the buffer and chain frame pools in the mpr(4) and mps(4) drivers. Reported by: Dwight Engen <[email protected]> Reviewed by: imp Obtained from: Dwight Engen <[email protected]> Differential Revision: <https://reviews.freebsd.org/D43008> |
||
|
|
83823d063a |
Add IBM TS1170 density codes and specs.
These were obtained from a drive, but they agree with the IBM documentation. The bpi/bpmm values are the same as TS1160, but the number of tracks is much larger (18944 tracks vs 8704 for TS1160). The tapes are also longer, 1337m total. (According to the MAM on a sample JF tape. I don't have a JE tape handy to compare.) The end result is a 50TB raw capacity (150TB compressed) for TS1170 with a JF cartridge vs 20TB raw capacity (60TB compressed) for TS1160 with a JE cartridge. lib/libmt/mtlib.c: Add the TS1170 density codes to the denstiy table in libmt. usr.bin/mt/mt.1: Add the TS1170 density codes and specs to the density table in the mt(1) man page. As usual for TS drives, there is an encrypted and non-encrypted density code (0x79 and 0x59 respectively). MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
11778fca4a |
Fix mpr(4) panic during a firmware update.
Issue Description: The RequestCredits field of IOCFacts got changed between the Phase23 firmware to Phase24 firmware. So as part of firmware update operation, driver has to free the resources & pools which are created with the Phase23 Firmware's IOCFacts data (i.e. during driver load time) and has to reallocate the resources and pools using Phase24's IOCFacts data. Here driver has freed the interrupts but missed to reallocate the interrupts and hence config page read operation is getting timed out and controller is going for recursive reinit (controller reset) operations and leading to kernel panic. Fix: Reallocate the interrupts if the interrupts are disabled as part of firmware update/downgrade operation. Submitted by: Sreekanth Ready <[email protected]> Tested by: ken MFC after: 3 days |
||
|
|
3090d5045a |
Fix non-printable characters in NVMe model and serial numbers.
The NVMe 1.4 spec simply says that Model and Serial numbers are ASCII strings. Unlike SCSI, it doesn't prohibit non-printable characters or say that the strings should be padded with spaces. Since 2014, we have had cam_strvis_sbuf(), which gives additional options for handling non-ASCII characters. That behavior hasn't been available for non-sbuf consumers, so users of cam_strvis() were left with having octal ASCII codes inserted. So, to avoid having garbage or octal chracters in the strings, use cam_strvis_sbuf() to create a new function, cam_strvis_flag(), and re-implement cam_strvis() using cam_strvis_flag(). Now, for the NVMe drives, we can use cam_strvis_flag with the CAM_STRVIS_FLAG_NONASCII_SPC flag. This transforms non-printable characters into spaces. sys/cam/cam.c: Add a new function, cam_strvis_flag(), that creates an sbuf on the stack with the user's destination buffer, and calls cam_strvis_sbuf() with the given flag argument. Re-implement cam_strvis() to call cam_strvis_flag with the CAM_STRVIS_FLAG_NONASCII_ESC argument. This should be the equivalent of the old cam_strvis() function, except for the overhead of creating the sbuf and calling sbuf_putc/printf. sys/cam/cam.h: Declaration for cam_strvis_flag. sys/cam/nvme/nvme_all.c: In nvme_print_ident, use the NONASCII_SPC flag with cam_strvis_flag(). sys/cam/nvme/nvme_da.c: In ndaregister(), use cam_strvis_flag() with the NONASCII_SPC flag for the disk description and serial number we report to GEOM. sys/cam/nvme/nvme_xpt.c: In nvme_probe_done(), use cam_strvis_flag with the NONASCII_SPC flag when storing the drive serial number in the CAM EDT. MFC after: 1 week Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D33973 |
||
|
|
6e8a2f0400 |
Update sa(4) comments and man page after review.
sys/cam/scsi/scsi_sa.c: Add comments explaining the priority order of the various sources of timeout values. Also, explain that the probe that pulls in drive recommended timeouts via the REPORT SUPPORTED OPERATION CODES command is in a race with the thread that creates the sysctl variables. Because of that race, it is important that the sysctl thread not load any timeout values from the kernel environment. share/man/man4/sa.4: Use the Sy macro to emphasize thousandths of a second instead of capitalizing it. Requested by: Warner Losh <[email protected]> Requested by: Daniel Ebdrup Jensen <[email protected]> Sponsored by: Spectra Logic MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D33883 |
||
|
|
bcff64c54a |
Clarify loader tunable usage when tape drives arrive after boot.
Tape drives that arrive after boot will still use any loader tunables that apply to that instance. Requested by: Pau Amma <[email protected]> MFC After: 1 week Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D33883 |
||
|
|
5719b5a1bb |
Switch to using drive-supplied timeouts for the sa(4) driver.
Summary: The sa(4) driver has historically used tape drive timeouts that were one-size fits all, with compile-time options to adjust a few of them. LTO-9 drives (and presumably other tape drives in the future) implement a tape characterization process that happens the first time a tape is loaded. The characterization process formats the tape to account for the temperature and humidity in the environment it is being used in. The process for LTO-9 tapes can take from 20 minutes (I have observed 17-18 minutes) to 2 hours according to the documentation. As a result, LTO-9 drives have significantly longer recommended load times than previous LTO generations. To handle this, change the sa(4) driver over to using timeouts supplied by the tape drive using the timeout descriptors obtained through the REPORT SUPPORTED OPERATION CODES command. That command was introduced in SPC-4. IBM tape drives going back to at least LTO-5 report timeout values. Oracle/Sun/StorageTek tape drives going back to at least the T10000C report timeout values. HP LTO-5 and newer drives report timeout values. The sa(4) driver only queries drives that claim to support SPC-4. This makes the timeout settings automatic and accurate for newer tape drives. Also, add loader tunable and sysctl support so that the user can override individual command type timeouts for all tape drives in the system, or only for specific drives. The new global (these affect all tape drives) loader tunables are: kern.cam.sa.timeout.erase kern.cam.sa.timeout.load kern.cam.sa.timeout.locate kern.cam.sa.timeout.mode_select kern.cam.sa.timeout.mode_sense kern.cam.sa.timeout.prevent kern.cam.sa.timeout.read kern.cam.sa.timeout.read_position kern.cam.sa.timeout.read_block_limits kern.cam.sa.timeout.report_density kern.cam.sa.timeout.reserve kern.cam.sa.timeout.rewind kern.cam.sa.timeout.space kern.cam.sa.timeout.tur kern.cam.sa.timeout.write kern.cam.sa.timeout.write_filemarks The new per-instance loader tunable / sysctl variables are: kern.cam.sa.%d.timeout.erase kern.cam.sa.%d.timeout.load kern.cam.sa.%d.timeout.locate kern.cam.sa.%d.timeout.mode_select kern.cam.sa.%d.timeout.mode_sense kern.cam.sa.%d.timeout.prevent kern.cam.sa.%d.timeout.read kern.cam.sa.%d.timeout.read_position kern.cam.sa.%d.timeout.read_block_limits kern.cam.sa.%d.timeout.report_density kern.cam.sa.%d.timeout.reserve kern.cam.sa.%d.timeout.rewind kern.cam.sa.%d.timeout.space kern.cam.sa.%d.timeout.tur kern.cam.sa.%d.timeout.write kern.cam.sa.%d.timeout.write_filemarks The values are reported and set in units of thousandths of a second. share/man/man4/sa.4: Document the new loader tunables in the sa(4) man page. sys/cam/scsi/scsi_sa.c: Add a new timeout_info array to the softc. Add a default timeouts array, along with descriptions. Add a new sysctl tree to the softc to handle the timeout sysctl values. Add a new function, saloadtotunables(), that will load the global loader tunables first and then any per-instance loader tunables second. Add creation of the new timeout sysctl variables in sasysctlinit(). Add a new, optional probe state to the sa(4) driver. We previously didn't do any probing, but now we probe for timeout descriptors if the drive claims to support SPC-4 or later. In saregister(), we check the SCSI revision and either launch the probe state machine, or announce the device and become ready. In sastart() and sadone(), add support for the new SA_STATE_PROBE. If we're probing, we don't go through saerror(), since that is currently only written to handle I/O errors in the normal state. Change every place in the sa(4) driver that fills in timeout values in a CCB to use the new timeout_info[] array in the softc. Add a new saloadtimeouts() routine to parse the returned timeout descriptors from a completed REPORT SUPPORTED OPERATION CODES command, and set the values for the commands we support. MFC after: 1 week Sponsored by: Spectra Logic Test Plan: Try this out with a variety of tape drives and make sure the timeouts that result (sysctl kern.cam.sa to see them) are reasonable. Reviewers: #manpages, #cam Subscribers: imp Differential Revision: https://reviews.freebsd.org/D33883 |
||
|
|
ca2a7262df |
Free UMA zones when a pass(4) instance goes away.
If the UMA zones are not freed, we get warnings about re-using the sysctl variables associated with the UMA zones, and we're leaking the other memory associated with the zone structures. e.g.: sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.size)! sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.flags)! sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.bucket_size)! sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.bucket_size_max)! sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.keg.name)! sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.keg.rsize)! sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.keg.ppera)! sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.keg.ipers)! Also, correctly clear the PASS_FLAG_ZONE_INPROG flag in passcreatezone(). The way it was previously done, it would have had set the flag and cleared all other flags that were set at that point. MFC after: 1 week Sponsored by: Spectra Logic |
||
|
|
175ad3d003 |
Fix mpr(4) and mps(4) state transitions and a use-after-free panic.
When the mpr(4) and mps(4) drivers probe a SATA device, they issue an
ATA Identify command (via mp{s,r}sas_get_sata_identify()) before the
target is fully setup in the driver. The drivers wait for completion of
the identify command, and have a 5 second timeout. If the timeout
fires, the command is marked with the SATA_ID_TIMEOUT flag so it can be
freed later.
That is where the use-after-free problem comes in. Once the ATA
Identify times out, the driver sends a target reset, and then frees any
identify commands that have timed out. But, once the target reset
completes, commands that were queued to the drive are returned to the
driver by the controller.
At that point, the driver (in mp{s,r}_intr_locked()) looks up the
command descriptor for that particular SMID, marks it CM_STATE_BUSY and
sends it on for completion handling.
The problem at this stage is that the command has already been freed,
and put on the free queue, so its state is CM_STATE_FREE. If INVARIANTS
are turned on, we get a panic as soon as this command is allocated,
because its state is no longer CM_STATE_FREE, but rather CM_STATE_BUSY.
So, the solution is to not free ATA Identify commands that get stuck
until they actually return from the controller. Hopefully this works
correctly on older firmware versions. If not, it could result in
commands hanging around indefinitely. But, the alternative is a
use-after-free panic or assertion (in the INVARIANTS case).
This also tightens up the state transitions between CM_STATE_FREE,
CM_STATE_BUSY and CM_STATE_INQUEUE, so that the state transitions happen
once, and we have assertions to make sure that commands are in the
correct state before transitioning to the next state. Also, for each
state assertion, we print out the current state of the command if it is
incorrect.
mp{s,r}.c: Add a new sysctl variable, dump_reqs_alltypes,
that controls the behavior of the dump_reqs sysctl.
If dump_reqs_alltypes is non-zero, it will dump
all commands, not just the commands that are in the
CM_STATE_INQUEUE state. (You can see the commands
that are in the queue by using mp{s,r}util debug
dumpreqs.)
Make sure that the INQUEUE -> BUSY state transition
happens in one place, the mp{s,r}_complete_command
routine.
mp{s,r}_sas.c: Make sure we print the current command type in
command state assertions.
mp{s,r}_sas_lsi.c:
Add a new completion handler,
mp{s,r}sas_ata_id_complete. This completion
handler will free data allocated for an ATA
Identify command and free the command structure.
In mp{s,r}_ata_id_timeout, do not set the command
state to CM_STATE_BUSY. The command is still in
queue in the controller. Since we were blocking
waiting for this command to complete, there was
no completion handler previously. Set the
completion handler, so that whenever the command
does come back, it will get freed properly.
Do not free ATA Identify commands that have timed
out in mp{s,r}sas_add_device(). Wait for them
to actually come back from the controller.
mp{s,r}var.h: Add a dump_reqs_alltypes variable for the new
dump_reqs_alltypes sysctl.
Make sure we print the current state for state
transition asserts.
This was tested in the Spectra Logic test bed (as described in the
review), as well Netflix's Open Connect fleet (where panics dropped from
a dozen or two a month to zero).
Reviewed by: imp@ (who is handling the commit with ken's OK)
Sponsored by: Spectra Logic
Differential Revision: https://reviews.freebsd.org/D25476
|
||
|
|
78adacd4ea |
Add the LTO-9 density code to libmt and the mt(1) man page.
These values are taken directly from the density report from an
IBM LTO-9 tape drive. (Using mt getdensity)
A LTO-9 drive stores 18TB raw (45TB with compression) on an LTO-9 tape.
lib/libmt/mtlib.c:
Add the LTO-9 density code, and bpmm/bpi values.
usr.bin/mt/mt.1:
Add the LTO-9 density code, bpmm/bpi values and number of
tracks. Bump the man page date.
MFC after: 3 days
Sponsored by: Spectra Logic
|
||
|
|
03caca368a |
Hold the mutex when releasing a callout.
In xpt_release_device(), callout_stop() was being called without holding the mutex (send_mtx) that is used to protect the callout. So, move the mtx_unlock() call so that it is protected. MFC after: 1 week Sponsored by: Spectra Logic |
||
|
|
0c8f059c29 |
Fix a hang introduced in r351599.
My changes in 351599 (kindly committed by avg) made the cd(4) media check asynchronous to avoid a sleep while holding a mutex. There was a difficult to reproduce bug with those changes that caused a hang on boot on some single processor machines/VMs. Leandro Lupori managed to reproduce the bug, diagnose it, and supplied a patch! Here is his analysis, from the PR: ====== I was able to reproduce the problem described in comment#14. Actually, I wasn't trying to reproduce it, I just started seeing it a few weeks ago, in CURRENT. I can reproduce it consistently, by using QEMU to run a PowerPC64 VM with a single core/thread (-smp 1). It happens only when there is no media in the emulated CD-ROM, a device that QEMU adds by default, unless -nodefaults is specified in command line. I've debugged it and this is what I've found: 1- After the CD probe is successful, GEOM will try to open the device, which will end up calling cdcheckmedia(), that sets CD state to CD_STATE_MEDIA_PREVENT. 2- Next, scsi_prevent() is executed and succeeds, the CD_FLAG_DISC_LOCKED flag is set and CD state moves to CD_STATE_MEDIA_SIZE. 3- Next, scsi_read_capacity() is executed and fails, state is set to CD_STATE_MEDIA_ALLOW, cdmediaprobedone() is called and wakes up cdcheckmedia(). 4- Then, when cdstart() is invoked to process CD_STATE_MEDIA_ALLOW, it first checks if CD_FLAG_DISC_LOCKED is set, and if so skips directly to CD_STATE_MEDIA_SIZE state. This will repeat the steps of bullet 3, entering an infinite MEDIA_SIZE command loop. When there is a least another core/thread, the GEOM thread that performed the initial cdopen() will get scheduled again, closing the CD device, that will call cdprevent(PR_ALLOW) that clears the CD_FLAG_DISC_LOCKED flag and breaks the loop. So, apparently, the problem is CD_STATE_MEDIA_ALLOW being skipped when CD_FLAG_DISC_LOCKED is set. If I understand correctly, in this case, the state should be advanced to CD_STATE_MEDIA size only when the current state is CD_STATE_MEDIA_PREVENT. ===== PR: kern/219857 Submitted by: Leandro Lupori <[email protected]> MFC after: 1 week |
||
|
|
e26059ca18 |
Fix FC-Tape bugs caused in part by r345008.
The point of r345008 was to reset the Command Reference Number (CRN) in some situations where a device stayed in the topology, but had changed somehow. This can include moving from a switch connection to a direct connection or vice versa, or a device that temporarily goes away and comes back. (e.g. moving to a different switch port) There were a couple of bugs in that change: - We were reporting that a device had not changed whenever the Establish Image Pair bit was not set. That is not quite correct. Instead, if the Establish Image Pair bit stays the same (set or not), the device hasn't changed in that way. - We weren't setting PRLI Word0 in the port database when a new device arrived, so comparisons with the old value for the Establish Image Pair bit weren't really possible. So, make sure PRLI Word0 is set in the port database for new devices. - We were resetting the CRN whenever the Establish Image Pair bit was set for a device, even when the device had stayed the same and the value of the bit hadn't changed. Now, only reset the CRN for devices that have changed, not devices that sayed the same. The result of all of this was that if we had a single FC device on an FC port and it went away and came back, we would wind up correctly resetting the CRN. But, if we had multiple devices connected via a switch, and there was any change in one or more of those devices, all of the devices that stayed the same would also have their CRN values reset. The result, from a user standpoint, is that the tape drives, etc. would all start to time out commands and the initiator would send aborts. sys/dev/isp/isp.c: In isp_pdb_add_update(), look at whether the Establish Image Pair bit has changed as part of the check to determine whether a device is still the same. This was causing erroneous change notifications. Also, when creating a new port database entry, initialize the PRLI Word 0 values. sys/dev/isp/isp_freebsd.c: In isp_async(), in the changed/stayed case, instead of looking at the Establish Image Pair bit to determine whether to reset the CRN, look at the command value. (Changed vs. Stayed.) Only reset the CRN for devices that have changed. Sponsored by: Spectra Logic MFC after: 3 days |
||
|
|
6f9dbc0e6e |
Fix CRN resets in the isp(4) driver in certain situations.
The Command Reference Number (CRN) is part of the FC-Tape features that we enable when talking to tape drives. It starts at 1, and goes to 255 and wraps around to 1. There are a number of reset type conditions that result in the CRN getting reset to 1. These are detailed in section 4.10 (table 8) of the FCP-4r02b specification. One of the conditions is when a PRLI (Process Login) is sent by the initiator, and the Establish Image Pair bit is set in Word 0 of the PRLI. Previously, the isp(4) driver core sent a notification via isp_async() that the target had changed or stayed in place, but there was no indication of whether a PRLI was sent and whether the Establish Image Pair bit was set. The result of this was that in some situations, notably switching back and forth between a direct connection and a switch connection to a tape drive, the isp(4) driver would fail to reset the CRN in situations that require it according to the spec. When the CRN isn't reset in a situation that requires it, the tape drive then rejects every subsequent command that is sent to the drive. It is assuming that the commands are being sent out of order. So, modify the isp(4) driver to include Word 0 of the PRLI command when it sends isp_async() notifications of target changes. Look at the Establish Image Pair bit, and reset the CRN if that bit is set. With this change, I am able to switch a tape drive back and forth between a direct connection and a switch connection, and the isp(4) driver resets the CRN when it should. sys/dev/isp_stds.h: Add bit definitions for PRLI Word 0. sys/dev/ispmbox.h: Add PRLI Word 0 to the port database type, isp_pdb_t. sys/dev/ispvar.h Add PRLI Word 0 to fcportdb_t. sys/dev/isp.c: Populate the new prli_word0 parameter in the port database. In isp_pdb_add_update(), add a check to see if the Establish Image Pair bit is set in PRLI Word 0. If it is, then that is an additional reason to create a change notification. sys/dev/isp_freebsd.c: In isp_async(), if the device changed or stayed, look at PRLI Word 0 to see if the Establish Image Pair bit is set. If it is, reset the CRN if we haven't already. MFC after: 1 week Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D19472 |
||
|
|
0caf9bf62d |
Add IBM TS1160 density codes to libmt and the mt(1) man page.
These are taken directly from the density report from a TS1160 tape drive. (Using mt getdensity) A TS1160 drive stores 20TB raw (60TB with compression) on a JE tape. lib/libmt/mtlib.c: Add 3592A6 encrypted/unencrypted density codes, and bpmm/bpi values. usr.bin/mt/mt.1: Add 3592B5 encrypted/unencrypted density codes, bpmm/bpi values and number of tracks. Bump the man page date. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
aabac0c176 |
Fix a da(4) driver memory leak for SCSI SMR devices.
In the probe case for SCSI SMR Host Aware or Most Managed drives, be sure to free allocated memory. sys/cam/scsi/scsi_da.c: In dadone_probezone(), free the data pointer before returning. MFC after: 3 days Sponsored by: Spectra Logic Approved by: re (kib) |
||
|
|
e4b58dfe33 |
Fix da(4) locking when probing SMR drives.
Probing host aware and host managed SMR drives got broken in revision 330796. The added cam_periph_lock() calls were in areas in dadone() where the peripheral lock was already held. Since then, dadone() has been split into separate functions that are dedicated to each probe state. The result is that when probing a host aware drive, I ran into a recursive lock acquisition in dadone_probeatalogdir(). I would have run into the same problem in dadone_probeataiddir(), and in dadone_probeatasup() and dadone_probeatazone() in the error paths had the probe continued. The solution is to take out all of the extra cam_periph_lock() calls. I also added cam_periph_assert(periph, MA_OWNED) near the top of each of the dadone_* calls. These make it clear to anyone coming along in the the future that the lock is held in the probe done functions. Also add a locking assert in daprobedone(), to make it clear that it must be called with the periph lock held. Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D15764 |
||
|
|
e440863e06 |
Clear out the entire structure, not just the size of a pointer to it.
sys/dev/ocs/ocs_os.c: In ocs_thread_create(), use sizeof(*thread) (instead of sizeof(thread)) as the size argument to memset so that we clear out the entire thread structure instead of just a few bytes of it. Submitted by: jtl MFC after: 3 days |
||
|
|
fc774835cb |
Handle Programmable Early Warning for control commands in sa(4).
When the tape position is inside the Early Warning area, the tape
drive will return a sense key of NO SENSE, and an ASC/ASCQ of
0x00,0x02, which means: End-of-partition/medium detected". If
this was in response to a control command like WRITE FILEMARKS,
we correctly translate this as informational status and return
0 from saerror().
Programmable Early Warning should be handled the same way, but
we weren't handling it that way. As a result, if a PEW status
(sense key of NO SENSE, ASC/ASCQ of 0x00,0x07, "Programmable early
warning detected") came back in response to a WRITE FILEMARKS,
we returned an error.
The impact of this was that if an application was writing to a
sa(4) device, and a PEW area was set (in the Device Configuration
Extension subpage -- mode page 0x10, subpage 1), and a filemark
needed to be written on close, we could wind up returning an error
to the user on close because of a "failure" to write the filemarks.
It actually isn't a failure, but rather just a status report from
the drive, and shouldn't be treated as a failure.
sys/cam/scsi/scsi_sa.c:
For control commands in saerror(), treat asc/ascq 0x00,0x07
the same as 0x00,{0-5} -- not an error. Return 0, since
the command actually did succeed.
Reported by: Dr. Andreas Haakh <[email protected]>
Tested by: Dr. Andreas Haakh <[email protected]>
Sponsored by: Spectra Logic
MFC after: 3 days
|
||
|
|
ef270ab1b6 |
Bring in the Broadcom/Emulex Fibre Channel driver, ocs_fc(4).
The ocs_fc(4) driver supports the following hardware: Emulex 16/8G FC GEN 5 HBAS LPe15004 FC Host Bus Adapters LPe160XX FC Host Bus Adapters Emulex 32/16G FC GEN 6 HBAS LPe3100X FC Host Bus Adapters LPe3200X FC Host Bus Adapters The driver supports target and initiator mode, and also supports FC-Tape. Note that the driver only currently works on little endian platforms. It is only included in the module build for amd64 and i386, and in GENERIC on amd64 only. Submitted by: Ram Kishore Vegesna <[email protected]> Reviewed by: mav MFC after: 5 days Relnotes: yes Sponsored by: Broadcom Differential Revision: https://reviews.freebsd.org/D11423 |
||
|
|
8881681b24 |
Disable T10 Protection Information / EEDP handling for type 2 protection.
The mps(4) and mpr(4) drivers and hardware handle T10 Protection Information, which is a system of checksums and guard blocks to protect data while it is being transferred and while it is on disk. It is also known as T10 DIF. For more details, see section 4.22 of the SBC-4 spec. Supporting Type 2 protection requires using 32 byte CDBs, and filling in the fields in those CDBs. We don't yet support that in the da(4) driver. Type 1 and Type 3 protection don't require that, and can be handled by the mps(4)/mpr(4) driver's code and firmware without any additional input from the da(4) driver. If a drive has Type 2 protection enabled (you frequently see this with SAS drives shipped from Dell), don't set the various EEDP fields in the mps(4)/mpr(4) driver command fields. Otherwise, you wind up with errors like this that would otherwise make no sense: (da9:mpr0:0:18:0): READ(10). CDB: 28 00 00 00 00 00 00 02 00 00 (da9:mpr0:0:18:0): CAM status: SCSI Status Error (da9:mpr0:0:18:0): SCSI status: Check Condition (da9:mpr0:0:18:0): SCSI sense: ILLEGAL REQUEST asc:20,0 (Invalid command operation code) (da9:mpr0:0:18:0): (da9:mpr0:0:18:0): Field Replaceable Unit: 0 (da9:mpr0:0:18:0): Command Specific Info: 0 (da9:mpr0:0:18:0): (da9:mpr0:0:18:0): Descriptor 0x80: f8 21 (da9:mpr0:0:18:0): Descriptor 0x81: 00 00 00 00 00 00 (da9:mpr0:0:18:0): Error 22, Unretryable error In other words, what kind of strange SAS hard drive doesn't support a standard 10 byte SCSI READ command? In this case, one that has Type 2 protection enabled. We can revisit this when we put Type 2 protection support in the da(4) driver, but for now this will help people who put Type 2 formatted drives in a system and wonder what in the world is going on. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
0afdc47158 |
cam_periph_acquire() now returns an errno.
The ch(4) driver was missed in change 328918, which changed cam_periph_acquire() to return an errno instead of cam_status. As a result, ch(4) failed to attach. Sponsored by: Spectra Logic |
||
|
|
e2997a03b7 |
Diagnostic buffer fixes for the mps(4) and mpr(4) drivers.
In mp{r,s}_diag_register(), which is used to register diagnostic
buffers with the mp{r,s}(4) firmware, we allocate DMAable memory.
There were several issues here:
o No checking of the bus_dmamap_load() return value. If the load
failed or got deferred, mp{r,s}_diag_register() continued on as if
nothing had happened. We now check the return value and bail
out if it fails.
o No waiting for a deferred load callback. bus_dmamap_load()
calls a supplied callback when the mapping is done. This is
generally done immediately, but it can be deferred.
mp{r,s}_diag_register() did not check to see whether the callback
was already done before proceeding on. We now sleep until the
callback is done if it is deferred.
o No call to bus_dmamap_sync(... BUS_DMASYNC_PREREAD) after the
memory is allocated and loaded. This is necessary on some
platforms to synchronize host memory that is going to be updated
by a device.
Both drivers would also panic if the firmware was reinitialized while
a diagnostic buffer operation was in progress. This fixes that problem
as well. (The driver will reinitialize the firmware in various
circumstances, but the problem I ran into was that the firmware would
generate an IOC Fault due to a PCIe error.)
mp{r,s}var.h:
Add a new structure, struct mpr_busdma_context, that is
used for deferred busdma load callbacks.
Add a prototype for mp{r,s}_memaddr_wait_cb().
mp{r,s}.c:
Add a new busdma callback function, mp{r,s}_memaddr_wait_cb().
This provides synchronization for callers that want to
wait on a deferred bus_dmamap_load() callback.
mp{r,s}_user.c:
In bus_dmamap_register(), add a call to bus_dmamap_sync()
with the BUS_DMASYNC_PREREAD flag set after an allocation
is loaded.
Also, check the return value of bus_dmamap_load(). If it
fails, bail out. If it is EINPROGRESS, wait for the
callback to happen. We use an interruptible sleep (msleep
with PCATCH) and let the callback clean things up if we get
interrupted.
In mpr_diag_read_buffer() and mps_diag_read_buffer(), call
bus_dmamap_sync(..., BUS_DMASYNC_POSTREAD) before copying
the data out to make sure the data is in stable storage.
In mp{r,s}_post_fw_diag_buffer() and
mp{r,s}_release_fw_diag_buffer(), check the reply to see
whether it is NULL. It can be NULL (and the command non-NULL)
if the controller gets reinitialized while we're waiting for
the command to complete but the driver structures aren't
reallocated. The driver structures generally won't be
reallocated unless there is a firmware upgrade that changes
one of the IOCFacts.
When freeing diagnostic buffers in mp{r,s}_diag_register()
and mp{r,s}_diag_unregister(), zero/NULL out the buffer after
freeing it. This will prevent a duplicate free in some
situations.
Sponsored by: Spectra Logic
Reviewed by: mav, scottl
MFC after: 1 week
Differential Revision: D13453
|
||
|
|
70a8349311 |
Add the LTO-8 Type M density code (0x5d, LTO-8M) to libmt and the
mt(1) man page. LTO-8 Type M (also known as M8) is a pristine LTO-7 cartridge formatted in a LTO-8 drive in a new, higher density format. It has a separate density code, and is only readable in an LTO-8 drive. lib/libmt/mtlib.c: Add the LTO-8 Type M density code to the density table in libmt. usr.bin/mt/mt.1: Add the LTO-8 Type M density code to the density table in the mt(1) man page. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
2d73f7e208 |
Fix a resource leak in an error case in camdd_buf_sg_create().
Submitted by: Coverity CID: 1341622 MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
988bd0d72b |
Restructure camdd(8) slightly to make it easier to add support for
additional protocols. Submitted by: Chuck Tuffli <[email protected]> MFC after: 1 week Differential Revision: D11230 |
||
|
|
74a90ba38a |
Add historical notes on QIC tape drives and fix a couple of issues in mt(1).
o Density code 0x5 is also known as QIC-11, and should have a footnote reference. o Add notes on QIC tape drives from the bug report. These may help anyone trying to use a QIC drive. o Take out a "more more" instance found by igor. o Bump the man page date. The PR is 14 years old, so it's past time to retire it. PR: doc/53596 Submitted by: [email protected] Reviewed by: bcr Sponsored by: Spectra Logic |
||
|
|
6d4ffcb4ac |
Changes to make mps(4) and mpr(4) handle reinit with reallocation.
When the mps(4) and mpr(4) drivers need to reinitialize the firmware, they sometimes need to reallocate all of the memory allocated by the driver. The reallocation happens whenever the IOC Facts change. That should only happen after a firmware upgrade. If the reinitialization happens as a result of a timed out command sent to the card, the command that timed out and triggered the reinit may have been freed if iocfacts_allocate() reallocated all memory. If the caller attempts to access the command after that, the kernel will panic because the caller will be dereferencing freed memory. The solution is to set a flag in the softc when we reallocate, and avoid dereferencing the command strucure if we've reallocated. The changes are largely the same in both drivers, since mpr(4) is a derivative of mps(4). o In iocfacts_allocate(), if the IOC Facts have changed and we need to reallocate, set the REALLOCATED flag in the softc. o Change wait_command() to take a struct mps_command ** instead of a struct mps_command *. This allows us to NULL out the caller's command pointer if we have to reinit the controller and the data structures get reallocated. (The REALLOCATED flag will be set in the softc if that has happened.) o In every place that calls wait_command(), make sure we handle the case where the command is NULL after the call. o The mpr(4) driver has mpr_request_polled() which can also reinitialize the card. Also check for reallocation there. Reviewed by: scottl, slm MFC after: 1 week Sponsored by: Spectra Logic |
||
|
|
5762d1b11d |
Oracle T10000 tape drives use PRML encoding.
Source: Oracle T10000 SCSI reference guide. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
fefd924a01 |
Remove duplicate assignments from r321622.
Submitted by: mav MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
a0acb3512c |
Fix probing FC targets with hard addressing turned on.
This largely reverts FreeBSD SVN change 289937 from October 25th, 2015. The intent of that change was to keep loop IDs persistent across chip reinits. The problem is that the change turned on the PREVLOOP / PREV_ADDRESS bit (bit 7 in Firmware Options 2), which tells the Qlogic chip to not participate in the loop if it can't get the requested loop address. It also turned off soft addressing on 2400 (4Gb) and newer controllers. The isp(4) driver defaults to loop address 0, and the tape drives I have tested default to loop address 0 if hard addressing is turned on. So when hard loop addressing is turned on on the drive, the isp(4) driver just refuses to participate in the loop. The solution is to largely revert that change. I left some elements in place that are related to virtual ports, since they were new. This does work with IBM tape drives with hard and soft addressing turned on. I have tested it with 4Gb, 8Gb, and 16Gb controllers. sys/dev/isp.c: Largely revert FreeBSD SVN change 289937. I left the ispmbox.h changes in place. Don't use the PREV_ADDRESS bit on initialization. It tells the chip to not participate if it can't get the requested loop ID. Do use soft addressing on 2400 and newer chips. Use hard addressing when the user has requested a specific initiator ID. (hint.isp.X.iid=N in /boot/loader.conf) Leave some of the virtual port options from that change in place, but don't turn on the PREV_ADDRESS bit. Reviewed by: mav MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
417aa6b850 |
Fix spurious timeouts on commands sent to mps(4) and mpr(4) controllers.
mps_wait_command() and mpr_wait_command() were using getmicrotime() to determine elapsed time when checking for a timeout in polled mode. getmicrotime() isn't guaranteed to monotonically increase, and that caused spurious timeouts occasionally. Switch to using getmicrouptime(), which does increase monotonically. This fixes the spurious timeouts in my test case. Reviewed by: slm, scottl MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
683b025ade |
Add IBM TS1155 density codes to libmt and the mt(1) man page.
These are taken directly from the density report from a TS1155 tape drive. (Using mt getdensity) lib/libmt/mtlib.c: Add 3592B5 encrypted/unencrypted density codes, and bpmm/bpi values. The bpmm/bpi values are the same as TS1150, but there are 50% more tracks. usr.bin/mt/mt.1: Add 3592B5 encrypted/unencrypted density codes, bpmm/bpi values and number of tracks. Bump the man page date. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
59fe76647c |
Fix a panic in camperiphfree().
If a peripheral driver (e.g. da, sa, cd) is added or removed from the
peripheral driver list while an unrelated peripheral driver instance (e.g.
da0, sa5, cd2) is going away and is inside camperiphfree(), we could
dereference an invalid pointer.
When peripheral drivers are added or removed (see periphdriver_register()
and periphdriver_unregister()), the peripheral driver array is resized
and existing entries are moved.
Although we hold the topology lock while we traverse the peripheral driver
list, we retain a pointer to the location of the peripheral driver pointer
and then drop the topology lock. So we are still vulnerable to the list
getting moved around while the lock is dropped.
To solve the problem, cache a copy of the peripheral driver pointer. If
its storage location in the list changes while we have the lock dropped, it
won't have any effect.
This doesn't solve the issue that peripheral drivers ("da", "cd", as opposed
to individual instances like "da0", "cd0") are not generally part of a
reference counting scheme to guard against deregistering them while there
are instances active. The caller (generally the person unloading a module)
has to be aware of active drivers and not unload something that is in use.
sys/cam/cam_periph.c:
In camperiphfree(), cache a pointer to the peripheral driver
instance to avoid holding a pointer to an invalid memory location
in the event that the peripheral driver list changes while we have
the topology lock dropped.
PR: kern/219701
Submitted by: avg
MFC after: 3 days
Sponsored by: Spectra Logic
|
||
|
|
89763b3f8e |
In scsi_zbc_in(), fill in the length in the ZBC IN CDB.
Without the allocation length set, the target will either reject the command or complete it without transferring any data. This fixes the REPORT ZONES command for SCSI ZBC protocol devices, as well as ATA ZAC protocol devices that are behind a SCSI to ATA translation layer. (LSI/Broadcom's 12Gb SAS adapters translate ZBC commands to ZAC commands.) Those are Host Aware and Host Managed SMR drives. This will fix REPORT ZONE commands sent to the da(4) driver via the GEOM bio interface and zonectl, and REPORT ZONE commands sent from camcontrol(8). Note that in the case of camcontrol(8), we currently only send SCSI ZBC commands to native SCSI protocol devices, not ATA devices behind a SAT layer. sys/cam/scsi/scsi_da.c: Fill in the length field in scsi_zbc_in(). MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
6f579fdb17 |
Fix a potential sleep while holding a mutex in the sa(4) driver.
If the user issues a MTIOCEXTGET ioctl, and the tape drive in question has a serial number that is longer than 80 characters, we malloc a buffer in saextget() to hold the output of cam_strvis(). Since a mutex is held in that codepath, doing a M_WAITOK malloc could lead to sleeping while holding a mutex. Change it to a M_NOWAIT malloc and bail out if we fail to allocate the memory. Devices with serial numbers longer than 80 bytes are very rare (I don't recall seeing one), so this should be a very unusual case to hit. But it is a bug that should be fixed. sys/cam/scsi/scsi_sa.c: In saextget(), if we need to malloc a buffer to hold the output of cam_strvis(), don't wait for the memory. Fail and return an error if we can't allocate the memory immediately. PR: kern/220094 Submitted by: Jia-Ju Bai <[email protected]> MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
0183e01516 |
Add LTO-8 density codes.
lib/libmt/mtlib.c: Add the LTO-8 density code to the density table in libmt. usr.bin/mt/mt.1: Add the LTO-8 density code, tracks, bpmm, and bpi to the density table in the mt(1) man page. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
1e773aeb99 |
When editing a mode page on a tape drive, do not clear the device
specific parameter. Tape drives include write protect (WP), Buffered Mode and Speed settings in the device-specific parameter. Clearing this parameter on a mode select can have the effect of turning off write protect or buffered mode, or changing the speed setting of the tape drive. Disks report DPO/FUA support via the device specific parameter for MODE SENSE, but the bit is reserved for MODE SELECT. So we clear this for disks (and other non-tape devices) to avoid potential errors from the target device. sbin/camcontrol/modeedit.c: Clear the device-specific parameter in the mode page header if we're not operating on a tape drive. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
64409eeee7 |
Add basic programmable early warning error injection to the sa(4) driver.
This will help application developers simulate end of tape conditions. To inject an error in sa0: sysctl kern.cam.sa.0.inject_eom=1 This will return the next read or write request queued with 0 bytes written. Any subsequent writes or reads will go along as usual. This will also cause the early warning position flag to get set for the next position query. So, 'mt status' will show the BPEW (Beyond Programmable Early Warning) flag on the first query after an error injection. After that, the position flags will be as they are in the underlying tape drive. Also, update the sa(4) man page to describe tape parameters, which can be set via 'mt param'. sys/cam/scsi/scsi_sa.c: In saregister(), create the inject_eom sysctl variable. In sastart(), check to see whether inject_eom is set. If so, return the read or write with 0 bytes written to indicate EOM. Set the set_pews_status flag so that we fake PEWS status in the next position call for reads, and the next 3 calls for writes. This allows the user to see the BPEW flag one time via 'mt status'. In sagetpos(), check the set_pews_status flag and fake PEWS status and decrement the counter if it is set. share/man/man4/sa.4: Document the inject_eom sysctl variable. Document all of the parameters currently supported via 'mt param'. usr.bin/mt/mt.1: Point the user to the sa(4) man page for more details on supported parameters. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
6da3b2f7f0 |
Add the SCSI Solid State Media Log page (0x11) definition.
sys/cam/scsi/scsi_all.h: Add the SCSI Solid State Media log page (0x11) structure definition. This gives the percentage used (in terms of lifetime flash wear) of an SSD. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
aefae9c7bb |
Bump the camcontrol(8) man page date.
MFC after: 3 days X-MFC-with: r317774 Sponsored by: Spectra Logic |
||
|
|
6953d22b15 |
Fix error recovery behavior in the pass(4) driver.
After FreeBSD SVN revision 236814, the pass(4) driver changed from
only doing error recovery when the CAM_PASS_ERR_RECOVER flag was
set on a CCB to sometimes doing error recovery if the passed in
retry count was non-zero.
Error recovery would happen if two conditions were met:
1. The error recovery action was simply a retry. (Which is most
cases.)
2. The retry_count is non-zero. (Which happened a lot because of
cut-and-pasted code.)
This explains a bug I noticed in with camcontrol:
# camcontrol tur da34 -v
Unit is ready
# camcontrol reset da34
Reset of 1:172:0 was successful
At this point, there should be a Unit Attention:
# camcontrol tur da34 -v
Unit is ready
No Unit Attention.
Try it again:
# camcontrol reset da34
Reset of 1:172:0 was successful
Now set the retry_count to 0 for the TUR:
# camcontrol tur da34 -v -C 0
Unit is not ready
(pass42:mps1:0:172:0): TEST UNIT READY. CDB: 00 00 00 00 00 00
(pass42:mps1:0:172:0): CAM status: SCSI Status Error
(pass42:mps1:0:172:0): SCSI status: Check Condition
(pass42:mps1:0:172:0): SCSI sense: UNIT ATTENTION asc:29,2 (SCSI bus reset occurred)
(pass42:mps1:0:172:0): Field Replaceable Unit: 2
There is the unit attention. camcontrol(8) has a default
retry_count of 1, in case someone sets the -E flag without
setting -C.
The CAM_PASS_ERR_RECOVER behavior was only broken with the
CAMIOCOMMAND ioctl, which is the synchronous pass(4) API. It has
worked as intended (error recovery is only done when the flag
is set) in the asynchronous API (CAMIOQUEUE ioctl).
sys/cam/scsi/scsi_pass.c:
In passsendccb(), when calling cam_periph_runccb(), only
specify the error routine when CAM_PASS_ERR_RECOVER is set.
share/man/man4/pass.4:
Document that CAM_PASS_ERR_RECOVER is needed to enable
error recovery.
Reported by: Terry Kennedy <[email protected]>
PR: kern/218572
MFC after: 1 week
Sponsored by: Spectra Logic
|
||
|
|
36d0fa44e2 |
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 MFC after: 3 days |
||
|
|
c36036beff |
Don't bother retrying errors for encrypted drives that are locked.
sys/cam/scsi/scsi_all.c:
In the asc_table, if we get a 0x20,0x02 error ("Access denied -
no access rights"), don't bother retrying. Instead, immediately
fail the command.
This is the error returned by Self Encrypting Drives (SED) when
they are locked.
MFC after: 3 days
Sponsored by: Spectra Logic
|
||
|
|
57b6261f94 |
Correct loop mode CRN resets to adhere to FCP-4 section 4.10
Prior to this change, the CRN (Command Reference Number) is reset on any firmware LIP, LOOP DOWN, or LOOP RESET event in violation of FCP-4 which specifies that the CRN should only be reset in response to a LIP Reset (LIPyx) primitive. FCP-4 also indicates PLOGI/LOGO and PRLI/PRLO ELS actions as conditions for resetting the CRN for the associated initiator port. These violations manifest themselves when the HBA is removed from the loop, or a target device is removed (especially during an outstanding command) without power cycling. If the HBA and and the target device determine upon re-establishing the loop that no PLOGI or PRLI is required, and the target does not issue a LIPxy to the initiator, the CRN for the target will have been improperly reset by the isp driver. As a result, the target port will silently ignore all FCP commands issued during the device probe (which will time out) preventing the device from attaching. This change corrects thie CRN reset behavior in response to loop state changes, also introduces CRN resets for the above mentioned ELS actions as encountered through async PDB change events. This change also adds cleanup of outstanding commands in isp_loop_dead() that was previously missing. sys/dev/isp/isp.c Add the last login state to debug output when syncing the pdb sys/dev/isp/isp_freebsd.c Replace binary statement setting aborted ccb status in isp_watchdog() with the XS_SETERR macro used elsewhere In isp_loop_dead(), abort or complete pending commands as done in isp_watchdog() In isp_async(), segregate the ISPASYNC_LOOP_RESET action from ISPASYNC_LIP, ISPASYNC_LOOP_DOWN, and ISPASYNC_LOOP_UP fallthroughs, and only reset the CRN in the RESET case. Also add checks to handle false LOOP RESET actions that do not have a proper associated LIP primitive, and log the primitive in the debug messages In isp_async(), remove the goto from ISP_ASYNC_DEV_STAYED, and only reset the CRN in the DEV_CHANGED action In isp_async(), when processing an ISPASYNC_CHANGE_PDB status, reset CRN(s) for the associated nphdl (or all ports) if the change reason is some form of ELS login/logout. Also remove assignment to fc since it is not used in the scope sys/dev/isp/ispmbox.h Add macro definition for the global N-Port handle, and correct a macro typo 'PDB24XX_AE_PRLI_DONJE' sys/dev/isp/ispvar.h Add macros FCP_AL_DA_ALL, FCP_AL_PA, and FCP_IS_DEST_ALPD for more legible code when determining if an AL_PD port matches the portid for a given struct fcparam* by value or by virtue of the AL_PD port being 0xFF Submitted by: Reid Linnemann Sponsored by: Spectra Logic MFC after: 1 week |
||
|
|
4ab558860e |
Add the SCSI SSC Manufacturer assigned serial number VPD page.
This is current as of SSC-5r03. Submitted by: Sam Klopsch MFC after: 3 days |
||
|
|
d618624cbd |
Fix camcontrol timestamp setting and update the man page.
camcontrol timestamp -s would somtimes fail due to stack garbage. Zero out
the timestamp parameters to fix it.
Fix another nearby bug, and update the man page.
sbin/camcontrol/timestamp.c:
In set_timestamp(), bzero ts_p prior to creating the timestamp.
Previously stack garbage could cause some tape drives to reject the
timestamp.
In set_timestamp(), check for failures from strptime().
sbin/camcontrol/camcontrol.8:
Add the time argument to the -T option to camcontrol timestamp -s
in the long description.
Change the time/date format used in the camcontrol timestamp
example to RFC 2822 format. This fixes a time zone issue with the
original example by specifying the time zone as -0600. Otherwise,
the time zone seems to default to standard time in the current
locale, which makes the time, when reported back from the drive,
1 hour off from the intended setting. This also fixes a duplicate
day of the week ("Wednesday Wed") in the previous example.
Submitted by: Sam Klopsch
MFC after: 3 days
Sponsored by: Spectra Logic
|
||
|
|
e9200a6cc2 |
Make ctl(4) build with CTL_IO_DELAY defined.
sys/cam/ctl/ctl.c: In ctl_datamove(), inside CTL_IO_DELAY, add a lun variable and fill it in before trying to dereference it. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
492a2ef556 |
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 MFC after: 1 week |
||
|
|
28ef82eb7b |
Change the isp(4) driver to not adjust the tag type for REQUEST SENSE.
The isp(4) driver was changing the tag type for REQUEST SENSE
commands to Head of Queue, when the CAM CCB flag
CAM_TAG_ACTION_VALID was NOT set. CAM_TAG_ACTION_VALID is set
when the tag action in the XPT_SCSI_IO is not CAM_TAG_ACTION_NONE
and when the target has tagged queueing turned on.
In most cases when CAM_TAG_ACTION_VALID is not set, it is because
the target is not doing tagged queueing. In those cases, trying to
send a Head of Queue tag may cause problems. Instead, default to
sending a simple tag.
IBM tape drives claim to support tagged queueing in their standard
Inquiry data, but have the DQue bit set in the control mode page
(mode page 10). CAM correctly detects that these drives do not
support tagged queueing, and clears the CAM_TAG_ACTION_VALID flag
on CCBs sent down to the drives.
This caused the isp(4) driver to go down the path of setting the
tag action to a default value, and for Request Sense commands only,
set the tag action to Head of Queue.
If an IBM tape drive does get a Head of Queue tag, it rejects it with
Invalid Message Error (0x49,0x00). (The Qlogic firmware translates that
to a Transport Error, which the driver translates to an Unrecoverable
HBA Error, or CAM_UNREC_HBA_ERROR.) So, by default, it wasn't possible
to get a good response from a REQUEST SENSE to an FC-attached IBM
tape drive with the isp(4) driver.
IBM tape drives (tested on an LTO-5 with G9N1 firmware and a TS1150
with 4470 firmware) also have a bug in that sending a command with a
non-simple tag attribute breaks the tape drive's Command Reference
Number (CRN) accounting and causes it to ignore all subsequent
commands because it and the initiator disagree about the next
expected CRN. The drives do reject the initial command with a head
of queue tag with an Invalid Message Error (0x49,0x00), but after that
they ignore any subsequent commands. IBM confirmed that it is a bug,
and sent me test firmware that fixes the bug. However tape drives in
the field will still exhibit the bug until they are upgraded.
Request Sense is not often sent to targets because most errors are
reported automatically through autosense in Fibre Channel and other
modern transports. ("Modern" meaning post SCSI-2.) So this is not
an error that would crop up frequently. But Request Sense is useful on
tape devices to report status information, aside from error reporting.
This problem is less serious without FC-Tape features turned on,
specifically precise delivery of commands (which enables Command
Reference Numbers), enabled on the target and initiator. Without
FC-Tape features turned on, the target would return an error and
things would continue on.
And it also does not cause problems for targets that do tagged
queueing, because in those cases the isp(4) driver just uses the
tag type that is specified in the CCB, assuming the
CAM_TAG_ACTION_VALID flag is set, and defaults to sending a Simple
tag action if it isn't an ordered or head of queue tag.
sys/dev/isp/isp.c:
In isp_start(), don't try to send Request Sense commands
with the Head of Queue tag attribute if the CCB doesn't
have a valid tag action. The tag action likely isn't valid
because the target doesn't support tagged queueing.
Sponsored by: Spectra Logic
MFC after: 3 days
|
||
|
|
08167db8d6 |
Turn on FC-Tape by default in the isp(4) driver.
FC-Tape provides additional link level error recovery, and is highly recommended for tape devices. It will only be turned on for a given target if the target supports it. Without this setting, we default to whatever FC-Tape setting is in NVRAM on the card. This can be overridden by setting the following loader tunable, for example for isp0: hint.isp.0.nofctape=1 sys/conf/options: Add a new kernel config option, ISP_FCTAPE_OFF, that defaults the FC-Tape configuration to off. sys/dev/isp/isp_pci.c: If ISP_FCTAPE_OFF is defined, turn off FC-Tape. Otherwise, turn it on if the card supports it. share/man/man4/isp.4: Add a description of FC-Tape to the isp(4) man page. Add descriptions of the fctape and nofctape options, as well as the ISP_FCTAPE_OFF kernel configuration option. Add the ispfw module and kernel drivers to the suggested configurations at the top of the man page so that users are less likely to leave it out. The driver works well with the included firmware, but may not work at all with whatever firmware the user has flashed on their card. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
28db0a5e74 |
Add SCSI REPORT TIMESTAMP and SET TIMESTAMP support.
This adds support to camcontrol(8) and libcam(3) for getting and setting the time on SCSI protocol drives. This is more commonly found on tape drives, but is a SPC (SCSI Primary Commands) command, and may be found on any device that speaks SCSI. The new camcontrol timestamp subcommand allows getting the current device time or setting the time to the current system time or any arbitrary time. sbin/camcontrol/Makefile: Add timestamp.c. sbin/camcontrol/camcontrol.8: Document the new timestamp subcommand. sbin/camcontrol/camcontrol.c: Add the timestamp subcommand to camcontrol. sbin/camcontrol/camcontrol.h: Add the timestamp() function prototype. sbin/camcontrol/timestamp.c: Timestamp setting and reporting functionality. sys/cam/scsi/scsi_all.c: Add two new CCB building functions, scsi_set_timestamp() and scsi_report_timestamp(). Also, add a new helper function, scsi_create_timestamp(). sys/cam/scsi/scsi_all.h: Add CDB and parameter data for the the set and report timestamp commands. Add function declarations for the new CCB building and helper functions. Submitted by: Sam Klopsch Sponsored by: Spectra Logic MFC After: 2 weeks |
||
|
|
38fb20e2ac |
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(). MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
8220f9ac52 |
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. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
a02e196edd |
Switch geom_disk over to using a pool mutex.
The GEOM disk d_mtx is only acquired on disk creation and destruction. It is a good candidate for replacement with a pool mutex. This eliminates the mutex initialization and teardown and the mutex and name variables themselves from struct disk. sys/geom/geom_disk.h: Take d_mtx and d_mtx_name out of struct disk. sys/geom/geom_disk.c: Use mtx_pool_lock() and mtx_pool_unlock() to guard the disk initialization state instead of a dedicated mutex. This allows removing the initialization and destruction of d_mtx. sys/sys/param.h: Bump __FreeBSD_version to 1100119 for the change to struct disk. Suggested by: jhb Sponsored by: Spectra Logic Approved by: re (gjb) |
||
|
|
e5616d65d0 |
Fix a bug that caused da(4) peripheral drivers to not fully go away
after the underlying device went away. The problem was that callers who queue the GEOM resize provider event didn't check to make sure that the provider had not been withered. For the other equivalent case, g_new_provider_event(), the code checks to see whether the provider has been withered before queueing a g_new_provider_event() to the event thread. In some cases, a resize provider event would come through after the provider had been withered and all of the existing consumers had been orphaned. When the resize event triggered a taste of the provider, that would attach a new consumer to the now withered provider. The wither washer (g_wither_washer() would never be able to completely tear down the GEOM because of the consumers that were hanging around. The solution was to check the G_PF_WITHER provider flag before queueing the g_resize_provider_event(), and add an assert to g_resize_provider_event() to insure that it isn't called on a withered provider. sys/geom/geom_subr.c: In g_resize_provider(), don't try to continue if the G_PF_WITHER flag is set. In g_resize_provider_event(), add an assert that the G_PF_WITHER flag is not set. In g_access(), if a provider has an error, print out the name of the provider with the error. Sponsored by: Spectra Logic Approved by: re (marius) MFC after: 3 days |
||
|
|
51b68003d9 |
Bump __FreeBSD_version to 1100118 for r302069, which breaks binary
compatibility for loadable modules that depend on struct disk. Approved by: re (delphij) Sponsored by: Spectra Logic |
||
|
|
1ff824e786 |
Fix a bug that caused da(4) instances to hang around after the underlying
device is gone. The problem was that when disk_gone() is called, if the GEOM disk creation process has not yet happened, the withering process couldn't start. We didn't record any state in the GEOM disk code, and so the d_gone() callback to the da(4) driver never happened. The solution is to track the state of the creation process, and initiate the withering process from g_disk_create() if the disk is being created. This change does add fields to struct disk, and so I have bumped DISK_VERSION. geom_disk.c: Track where we are in the disk creation process, and check to see whether our underlying disk has gone away or not. In disk_gone(), set a new d_goneflag variable that g_disk_create() can check to see if it needs to clean up the disk instance. geom_disk.h: Add a mutex to struct disk (for internal use) disk init level, and a gone flag. Bump DISK_VERSION because the size of struct disk has changed and fields have been added at the beginning. Sponsored by: Spectra Logic Approved by: re (marius) |
||
|
|
600fd98ff3 |
Fix a few ada(4) driver issues:
o Some Samsung drives do not support the ATA READ LOG EXT or READ LOG DMA EXT commands, despite indicating that they do in their IDENTIFY data. So, fix this in two ways: 1. Only start the log directory probe (ADA_STATE_LOGDIR) if the drive claims to be an SMR drive in the first place. We don't need to do the extra probing for other devices. This will also serve to prevent problems with other drives that have the same issue. 2. Add quirks for the two Samsung drives that have been reported so far (thanks to Oleg Nauman and Alex Petrov). If there is a reason to do a Read Log later on, we will know that it doesn't work on these drives. o Add a quirk entry to mark Seagate Lamarr Drive Managed drives as drive managed. They don't report this in their Identify data. sys/cam/ata/ata_da.c: Add two new quirks: 1. ADA_Q_LOG_BROKEN, for drives that claim to support Read Log but don't really. 2. ADA_Q_SMR_DM, for drives that are Drive Managed SMR, but don't report it. This can matter for software that wants to know when it should make an extra effort to write sequentially. Record two Samsung drives that don't support Read Log, and one Seagate drive that doesn't report that it is a SMR drive. The Seagate drive is already recorded in the da(4) driver. We may have to come up with a similar solution in the da(4) driver for SATA drives that don't properly support Read Log. In adasetflags(), Dont' set the ADA_FLAG_CAN_LOG bit if the device has the LOG_BROKEN quirk set. Also, look at the SMR_DM quirk and set the device type accordingly if it is actually a drive managed drive. When deciding whether to go into the LOGDIR probe state, look to see whether the device claims to be an SMR device. If not, don't bother with the LOGDIR probe state. Sponsored by: Spectra Logic |
||
|
|
3f54ec85e8 |
Fix ada(4) trim support quirk setting.
I broke broke the quirk in the ada(4) driver disabling NCQ trim support in revision 300207. The support flags were set before the quirks were loaded. sys/cam/ata/ata_da.c: Call adasetflags() after loading quirks, so that we'll set the flags accurately. Sponsored by: Spectra Logic |
||
|
|
f4bf2442a0 |
Add the density code for LTO-7 to libmt and the mt(1) man page.
The density code and bits per mm values were obtained from an actual drive density report. The number of tracks were obtained from an LTO-7 hardware announcement on IBM's web site. Sponsored by: Spectra Logic MFC after: 3 days |
||
|
|
d3683d27cf |
Adjust a couple of error cases in camdd(8).
usr.sbin/camdd/camdd.c: In camdd_probe_file(), fix an error case after fstat where we were bailing out and leaving two lines of cleanup code unexecuted. Instead, just goto bailout_error. In camdd_probe_pass(), fail if the sector size is 0. Sponsored by: Spectra Logic MFC after: 3 days |
||
|
|
9a6844d55f |
Add support for managing Shingled Magnetic Recording (SMR) drives.
This change includes support for SCSI SMR drives (which conform to the Zoned Block Commands or ZBC spec) and ATA SMR drives (which conform to the Zoned ATA Command Set or ZAC spec) behind SAS expanders. This includes full management support through the GEOM BIO interface, and through a new userland utility, zonectl(8), and through camcontrol(8). This is now ready for filesystems to use to detect and manage zoned drives. (There is no work in progress that I know of to use this for ZFS or UFS, if anyone is interested, let me know and I may have some suggestions.) Also, improve ATA command passthrough and dispatch support, both via ATA and ATA passthrough over SCSI. Also, add support to camcontrol(8) for the ATA Extended Power Conditions feature set. You can now manage ATA device power states, and set various idle time thresholds for a drive to enter lower power states. Note that this change cannot be MFCed in full, because it depends on changes to the struct bio API that break compatilibity. In order to avoid breaking the stable API, only changes that don't touch or depend on the struct bio changes can be merged. For example, the camcontrol(8) changes don't depend on the new bio API, but zonectl(8) and the probe changes to the da(4) and ada(4) drivers do depend on it. Also note that the SMR changes have not yet been tested with an actual SCSI ZBC device, or a SCSI to ATA translation layer (SAT) that supports ZBC to ZAC translation. I have not yet gotten a suitable drive or SAT layer, so any testing help would be appreciated. These changes have been tested with Seagate Host Aware SATA drives attached to both SAS and SATA controllers. Also, I do not have any SATA Host Managed devices, and I suspect that it may take additional (hopefully minor) changes to support them. Thanks to Seagate for supplying the test hardware and answering questions. sbin/camcontrol/Makefile: Add epc.c and zone.c. sbin/camcontrol/camcontrol.8: Document the zone and epc subcommands. sbin/camcontrol/camcontrol.c: Add the zone and epc subcommands. Add auxiliary register support to build_ata_cmd(). Make sure to set the CAM_ATAIO_NEEDRESULT, CAM_ATAIO_DMA, and CAM_ATAIO_FPDMA flags as appropriate for ATA commands. Add a new get_ata_status() function to parse ATA result from SCSI sense descriptors (for ATA passthrough over SCSI) and ATA I/O requests. sbin/camcontrol/camcontrol.h: Update the build_ata_cmd() prototype Add get_ata_status(), zone(), and epc(). sbin/camcontrol/epc.c: Support for ATA Extended Power Conditions features. This includes support for all features documented in the ACS-4 Revision 12 specification from t13.org (dated February 18, 2016). The EPC feature set allows putting a drive into a power power mode immediately, or setting timeouts so that the drive will automatically enter progressively lower power states after various idle times. sbin/camcontrol/fwdownload.c: Update the firmware download code for the new build_ata_cmd() arguments. sbin/camcontrol/zone.c: Implement support for Shingled Magnetic Recording (SMR) drives via SCSI Zoned Block Commands (ZBC) and ATA Zoned Device ATA Command Set (ZAC). These specs were developed in concert, and are functionally identical. The primary differences are due to SCSI and ATA differences. (SCSI is big endian, ATA is little endian, for example.) This includes support for all commands defined in the ZBC and ZAC specs. sys/cam/ata/ata_all.c: Decode a number of additional ATA command names in ata_op_string(). Add a new CCB building function, ata_read_log(). Add ata_zac_mgmt_in() and ata_zac_mgmt_out() CCB building functions. These support both DMA and NCQ encapsulation. sys/cam/ata/ata_all.h: Add prototypes for ata_read_log(), ata_zac_mgmt_out(), and ata_zac_mgmt_in(). sys/cam/ata/ata_da.c: Revamp the ada(4) driver to support zoned devices. Add four new probe states to gather information needed for zone support. Add a new adasetflags() function to avoid duplication of large blocks of flag setting between the async handler and register functions. Add new sysctl variables that describe zone support and paramters. Add support for the new BIO_ZONE bio, and all of its subcommands: DISK_ZONE_OPEN, DISK_ZONE_CLOSE, DISK_ZONE_FINISH, DISK_ZONE_RWP, DISK_ZONE_REPORT_ZONES, and DISK_ZONE_GET_PARAMS. sys/cam/scsi/scsi_all.c: Add command descriptions for the ZBC IN/OUT commands. Add descriptions for ZBC Host Managed devices. Add a new function, scsi_ata_pass() to do ATA passthrough over SCSI. This will eventually replace scsi_ata_pass_16() -- it can create the 12, 16, and 32-byte variants of the ATA PASS-THROUGH command, and supports setting all of the registers defined as of SAT-4, Revision 5 (March 11, 2016). Change scsi_ata_identify() to use scsi_ata_pass() instead of scsi_ata_pass_16(). Add a new scsi_ata_read_log() function to facilitate reading ATA logs via SCSI. sys/cam/scsi/scsi_all.h: Add the new ATA PASS-THROUGH(32) command CDB. Add extended and variable CDB opcodes. Add Zoned Block Device Characteristics VPD page. Add ATA Return SCSI sense descriptor. Add prototypes for scsi_ata_read_log() and scsi_ata_pass(). sys/cam/scsi/scsi_da.c: Revamp the da(4) driver to support zoned devices. Add five new probe states, four of which are needed for ATA devices. Add five new sysctl variables that describe zone support and parameters. The da(4) driver supports SCSI ZBC devices, as well as ATA ZAC devices when they are attached via a SCSI to ATA Translation (SAT) layer. Since ZBC -> ZAC translation is a new feature in the T10 SAT-4 spec, most SATA drives will be supported via ATA commands sent via the SCSI ATA PASS-THROUGH command. The da(4) driver will prefer the ZBC interface, if it is available, for performance reasons, but will use the ATA PASS-THROUGH interface to the ZAC command set if the SAT layer doesn't support translation yet. As I mentioned above, ZBC command support is untested. Add support for the new BIO_ZONE bio, and all of its subcommands: DISK_ZONE_OPEN, DISK_ZONE_CLOSE, DISK_ZONE_FINISH, DISK_ZONE_RWP, DISK_ZONE_REPORT_ZONES, and DISK_ZONE_GET_PARAMS. Add scsi_zbc_in() and scsi_zbc_out() CCB building functions. Add scsi_ata_zac_mgmt_out() and scsi_ata_zac_mgmt_in() CCB/CDB building functions. Note that these have return values, unlike almost all other CCB building functions in CAM. The reason is that they can fail, depending upon the particular combination of input parameters. The primary failure case is if the user wants NCQ, but fails to specify additional CDB storage. NCQ requires using the 32-byte version of the SCSI ATA PASS-THROUGH command, and the current CAM CDB size is 16 bytes. sys/cam/scsi/scsi_da.h: Add ZBC IN and ZBC OUT CDBs and opcodes. Add SCSI Report Zones data structures. Add scsi_zbc_in(), scsi_zbc_out(), scsi_ata_zac_mgmt_out(), and scsi_ata_zac_mgmt_in() prototypes. sys/dev/ahci/ahci.c: Fix SEND / RECEIVE FPDMA QUEUED in the ahci(4) driver. ahci_setup_fis() previously set the top bits of the sector count register in the FIS to 0 for FPDMA commands. This is okay for read and write, because the PRIO field is in the only thing in those bits, and we don't implement that further up the stack. But, for SEND and RECEIVE FPDMA QUEUED, the subcommand is in that byte, so it needs to be transmitted to the drive. In ahci_setup_fis(), always set the the top 8 bits of the sector count register. We need it in both the standard and NCQ / FPDMA cases. sys/geom/eli/g_eli.c: Pass BIO_ZONE commands through the GELI class. sys/geom/geom.h: Add g_io_zonecmd() prototype. sys/geom/geom_dev.c: Add new DIOCZONECMD ioctl, which allows sending zone commands to disks. sys/geom/geom_disk.c: Add support for BIO_ZONE commands. sys/geom/geom_disk.h: Add a new flag, DISKFLAG_CANZONE, that indicates that a given GEOM disk client can handle BIO_ZONE commands. sys/geom/geom_io.c: Add a new function, g_io_zonecmd(), that handles execution of BIO_ZONE commands. Add permissions check for BIO_ZONE commands. Add command decoding for BIO_ZONE commands. sys/geom/geom_subr.c: Add DDB command decoding for BIO_ZONE commands. sys/kern/subr_devstat.c: Record statistics for REPORT ZONES commands. Note that the number of bytes transferred for REPORT ZONES won't quite match what is received from the harware. This is because we're necessarily counting bytes coming from the da(4) / ada(4) drivers, which are using the disk_zone.h interface to communicate up the stack. The structure sizes it uses are slightly different than the SCSI and ATA structure sizes. sys/sys/ata.h: Add many bit and structure definitions for ZAC, NCQ, and EPC command support. sys/sys/bio.h: Convert the bio_cmd field to a straight enumeration. This will yield more space for additional commands in the future. After change r297955 and other related changes, this is now possible. Converting to an enumeration will also prevent use as a bitmask in the future. sys/sys/disk.h: Define the DIOCZONECMD ioctl. sys/sys/disk_zone.h: Add a new API for managing zoned disks. This is very close to the SCSI ZBC and ATA ZAC standards, but uses integers in native byte order instead of big endian (SCSI) or little endian (ATA) byte arrays. This is intended to offer to the complete feature set of the ZBC and ZAC disk management without requiring the application developer to include SCSI or ATA headers. We also use one set of headers for ioctl consumers and kernel bio-level consumers. sys/sys/param.h: Bump __FreeBSD_version for sys/bio.h command changes, and inclusion of SMR support. usr.sbin/Makefile: Add the zonectl utility. usr.sbin/diskinfo/diskinfo.c Add disk zoning capability to the 'diskinfo -v' output. usr.sbin/zonectl/Makefile: Add zonectl makefile. usr.sbin/zonectl/zonectl.8 zonectl(8) man page. usr.sbin/zonectl/zonectl.c The zonectl(8) utility. This allows managing SCSI or ATA zoned disks via the disk_zone.h API. You can report zones, reset write pointers, get parameters, etc. Sponsored by: Spectra Logic Differential Revision: https://reviews.freebsd.org/D6147 Reviewed by: wblock (documentation) |
||
|
|
07b1ab582b |
Fix the SCSI Extended INQUIRY probe case when an error is returned
and a retry is scheduled. Instead of leaving the device queue frozen, unfreeze the device queue so that the retry can happen. Sponsored by: Spectra Logic MFC after: 3 days |
||
|
|
23d63288c2 |
The ccb_xflags enumeration was removed from FreeBSD/head in
r259397 (it contained the CAM_EXTLUN_VALID bit) and I added the same type name with a different set of values back in r291716. The old ccb_xflags enumeration still exists in FreeBSD stable/10. Shift all of the new values by one bit to avoid compatibility issues when merged to stable/10. MFC after: 3 days Sponsored by: Spectra Logic |
||
|
|
985108aeb1 |
Fix a style issue in g_disk_limit().
Noticed by: bdrewery MFC after: 1 week |
||
|
|
42fbdde413 |
Fix g_disk_vlist_limit() to work properly with deletes.
Add a new bp argument to g_disk_maxsegs(), and add a new function, g_disk_maxsize() tha will properly determine the maximum I/O size for a delete or non-delete bio. Submitted by: will MFC after: 1 week Sponsored by: Spectra Logic |
||
|
|
52c98bc2fd |
Fix typos in the camdd(8) usage() function output caused by an error in
my diff filter script. Sponsored by: Spectra Logic MFC after: 1 week |
||
|
|
a9934668aa |
Add asynchronous command support to the pass(4) driver, and the new
camdd(8) utility.
CCBs may be queued to the driver via the new CAMIOQUEUE ioctl, and
completed CCBs may be retrieved via the CAMIOGET ioctl. User
processes can use poll(2) or kevent(2) to get notification when
I/O has completed.
While the existing CAMIOCOMMAND blocking ioctl interface only
supports user virtual data pointers in a CCB (generally only
one per CCB), the new CAMIOQUEUE ioctl supports user virtual and
physical address pointers, as well as user virtual and physical
scatter/gather lists. This allows user applications to have more
flexibility in their data handling operations.
Kernel memory for data transferred via the queued interface is
allocated from the zone allocator in MAXPHYS sized chunks, and user
data is copied in and out. This is likely faster than the
vmapbuf()/vunmapbuf() method used by the CAMIOCOMMAND ioctl in
configurations with many processors (there are more TLB shootdowns
caused by the mapping/unmapping operation) but may not be as fast
as running with unmapped I/O.
The new memory handling model for user requests also allows
applications to send CCBs with request sizes that are larger than
MAXPHYS. The pass(4) driver now limits queued requests to the I/O
size listed by the SIM driver in the maxio field in the Path
Inquiry (XPT_PATH_INQ) CCB.
There are some things things would be good to add:
1. Come up with a way to do unmapped I/O on multiple buffers.
Currently the unmapped I/O interface operates on a struct bio,
which includes only one address and length. It would be nice
to be able to send an unmapped scatter/gather list down to
busdma. This would allow eliminating the copy we currently do
for data.
2. Add an ioctl to list currently outstanding CCBs in the various
queues.
3. Add an ioctl to cancel a request, or use the XPT_ABORT CCB to do
that.
4. Test physical address support. Virtual pointers and scatter
gather lists have been tested, but I have not yet tested
physical addresses or scatter/gather lists.
5. Investigate multiple queue support. At the moment there is one
queue of commands per pass(4) device. If multiple processes
open the device, they will submit I/O into the same queue and
get events for the same completions. This is probably the right
model for most applications, but it is something that could be
changed later on.
Also, add a new utility, camdd(8) that uses the asynchronous pass(4)
driver interface.
This utility is intended to be a basic data transfer/copy utility,
a simple benchmark utility, and an example of how to use the
asynchronous pass(4) interface.
It can copy data to and from pass(4) devices using any target queue
depth, starting offset and blocksize for the input and ouptut devices.
It currently only supports SCSI devices, but could be easily extended
to support ATA devices.
It can also copy data to and from regular files, block devices, tape
devices, pipes, stdin, and stdout. It does not support queueing
multiple commands to any of those targets, since it uses the standard
read(2)/write(2)/writev(2)/readv(2) system calls.
The I/O is done by two threads, one for the reader and one for the
writer. The reader thread sends completed read requests to the
writer thread in strictly sequential order, even if they complete
out of order. That could be modified later on for random I/O patterns
or slightly out of order I/O.
camdd(8) uses kqueue(2)/kevent(2) to get I/O completion events from
the pass(4) driver and also to send request notifications internally.
For pass(4) devcies, camdd(8) uses a single buffer (CAM_DATA_VADDR)
per CAM CCB on the reading side, and a scatter/gather list
(CAM_DATA_SG) on the writing side. In addition to testing both
interfaces, this makes any potential reblocking of I/O easier. No
data is copied between the reader and the writer, but rather the
reader's buffers are split into multiple I/O requests or combined
into a single I/O request depending on the input and output blocksize.
For the file I/O path, camdd(8) also uses a single buffer (read(2),
write(2), pread(2) or pwrite(2)) on reads, and a scatter/gather list
(readv(2), writev(2), preadv(2), pwritev(2)) on writes.
Things that would be nice to do for camdd(8) eventually:
1. Add support for I/O pattern generation. Patterns like all
zeros, all ones, LBA-based patterns, random patterns, etc. Right
Now you can always use /dev/zero, /dev/random, etc.
2. Add support for a "sink" mode, so we do only reads with no
writes. Right now, you can use /dev/null.
3. Add support for automatic queue depth probing, so that we can
figure out the right queue depth on the input and output side
for maximum throughput. At the moment it defaults to 6.
4. Add support for SATA device passthrough I/O.
5. Add support for random LBAs and/or lengths on the input and
output sides.
6. Track average per-I/O latency and busy time. The busy time
and latency could also feed in to the automatic queue depth
determination.
sys/cam/scsi/scsi_pass.h:
Define two new ioctls, CAMIOQUEUE and CAMIOGET, that queue
and fetch asynchronous CAM CCBs respectively.
Although these ioctls do not have a declared argument, they
both take a union ccb pointer. If we declare a size here,
the ioctl code in sys/kern/sys_generic.c will malloc and free
a buffer for either the CCB or the CCB pointer (depending on
how it is declared). Since we have to keep a copy of the
CCB (which is fairly large) anyway, having the ioctl malloc
and free a CCB for each call is wasteful.
sys/cam/scsi/scsi_pass.c:
Add asynchronous CCB support.
Add two new ioctls, CAMIOQUEUE and CAMIOGET.
CAMIOQUEUE adds a CCB to the incoming queue. The CCB is
executed immediately (and moved to the active queue) if it
is an immediate CCB, but otherwise it will be executed
in passstart() when a CCB is available from the transport layer.
When CCBs are completed (because they are immediate or
passdone() if they are queued), they are put on the done
queue.
If we get the final close on the device before all pending
I/O is complete, all active I/O is moved to the abandoned
queue and we increment the peripheral reference count so
that the peripheral driver instance doesn't go away before
all pending I/O is done.
The new passcreatezone() function is called on the first
call to the CAMIOQUEUE ioctl on a given device to allocate
the UMA zones for I/O requests and S/G list buffers. This
may be good to move off to a taskqueue at some point.
The new passmemsetup() function allocates memory and
scatter/gather lists to hold the user's data, and copies
in any data that needs to be written. For virtual pointers
(CAM_DATA_VADDR), the kernel buffer is malloced from the
new pass(4) driver malloc bucket. For virtual
scatter/gather lists (CAM_DATA_SG), buffers are allocated
from a new per-pass(9) UMA zone in MAXPHYS-sized chunks.
Physical pointers are passed in unchanged. We have support
for up to 16 scatter/gather segments (for the user and
kernel S/G lists) in the default struct pass_io_req, so
requests with longer S/G lists require an extra kernel malloc.
The new passcopysglist() function copies a user scatter/gather
list to a kernel scatter/gather list. The number of elements
in each list may be different, but (obviously) the amount of data
stored has to be identical.
The new passmemdone() function copies data out for the
CAM_DATA_VADDR and CAM_DATA_SG cases.
The new passiocleanup() function restores data pointers in
user CCBs and frees memory.
Add new functions to support kqueue(2)/kevent(2):
passreadfilt() tells kevent whether or not the done
queue is empty.
passkqfilter() adds a knote to our list.
passreadfiltdetach() removes a knote from our list.
Add a new function, passpoll(), for poll(2)/select(2)
to use.
Add devstat(9) support for the queued CCB path.
sys/cam/ata/ata_da.c:
Add support for the BIO_VLIST bio type.
sys/cam/cam_ccb.h:
Add a new enumeration for the xflags field in the CCB header.
(This doesn't change the CCB header, just adds an enumeration to
use.)
sys/cam/cam_xpt.c:
Add a new function, xpt_setup_ccb_flags(), that allows specifying
CCB flags.
sys/cam/cam_xpt.h:
Add a prototype for xpt_setup_ccb_flags().
sys/cam/scsi/scsi_da.c:
Add support for BIO_VLIST.
sys/dev/md/md.c:
Add BIO_VLIST support to md(4).
sys/geom/geom_disk.c:
Add BIO_VLIST support to the GEOM disk class. Re-factor the I/O size
limiting code in g_disk_start() a bit.
sys/kern/subr_bus_dma.c:
Change _bus_dmamap_load_vlist() to take a starting offset and
length.
Add a new function, _bus_dmamap_load_pages(), that will load a list
of physical pages starting at an offset.
Update _bus_dmamap_load_bio() to allow loading BIO_VLIST bios.
Allow unmapped I/O to start at an offset.
sys/kern/subr_uio.c:
Add two new functions, physcopyin_vlist() and physcopyout_vlist().
sys/pc98/include/bus.h:
Guard kernel-only parts of the pc98 machine/bus.h header with
#ifdef _KERNEL.
This allows userland programs to include <machine/bus.h> to get the
definition of bus_addr_t and bus_size_t.
sys/sys/bio.h:
Add a new bio flag, BIO_VLIST.
sys/sys/uio.h:
Add prototypes for physcopyin_vlist() and physcopyout_vlist().
share/man/man4/pass.4:
Document the CAMIOQUEUE and CAMIOGET ioctls.
usr.sbin/Makefile:
Add camdd.
usr.sbin/camdd/Makefile:
Add a makefile for camdd(8).
usr.sbin/camdd/camdd.8:
Man page for camdd(8).
usr.sbin/camdd/camdd.c:
The new camdd(8) utility.
Sponsored by: Spectra Logic
MFC after: 1 week
|
||
|
|
0e358df062 |
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 MFC after: 1 week |
||
|
|
5672fac935 |
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 MFC after: 1 week |
||
|
|
873da79689 |
Remove some #if 0'ed code that apparently confuses cscope.
Requested by: Peter Xu <[email protected]> MFC after: 3 days |
||
|
|
d788649d0c |
Improve the mt(1) rblim display.
The granularity reported by READ BLOCK LIMITS is an exponent, not a byte value. So a granularity of 0 means 2^0, or 1 byte. A granularity of 1 means 2^1, or 2 bytes. Print out the individual block limits on separate lines to improve readability and avoid exceeding 80 columns. usr.bin/mt/mt.c: Fix and improve the 'mt rblim' output. Add a MT_PLURAL() macro so we can print "byte" or "bytes" as appropriate. Sponsored by: Spectra Logic MFC after: 4 days |
||
|
|
74a177ac50 |
Fix a couple of problems in the sa(4) media type reports.
The only drives I have discovered so far that support medium type reports are newer HP LTO (LTO-5 and LTO-6) drives. IBM drives only support the density reports. sys/cam/scsi/scsi_sa.h: The number of possible density codes in the medium type report is 9, not 8. This caused problems parsing all of the medium type report after this point in the structure. usr.bin/mt/mt.c: Run the density codes returned in the medium type report through denstostring(), just like the primary and secondary density codes in the density report. This will print the density code in hex, and give a text description if it is available. Thanks to Rudolf Cejka for doing extensive testing with HP LTO drives and Bacula and discovering these problems. Tested by: Rudolf Cejka <cejkar at fit.vutbr.cz> Sponsored by: Spectra Logic MFC after: 4 days |
||
|
|
5090c893b7 |
Add density code for DAT-72, and notes on DAT-160.
As it turns out, the density code for DAT-160 (0x48) is the same as for SDLT220. Since the SDLT values are already in the table, we will leave them in place. Thanks to Harald Schmalzbauer for confirming the DAT-72 density code. lib/libmt/mtlib.c: Add DAT-72 density code, and commented out DAT-160 density code. Explain why DAT-160 is commented out. Add notes explaining where the bpi values for these formats came from. usr.bin/mt/mt.1: Add DAT-72 density code, and add a note explaining that the SDLTTapeI(110) density code (0x48) is the same as DAT-160. Sponsored by: Spectra Logic MFC after: 3 weeks |
||
|
|
54eb0be231 |
Change the sa(4) driver to check for long position support on
SCSI-2 devices. Some older tape devices claim to be SCSI-2, but actually do support long position information. (Long position information includes the current file mark.) For example, the COMPAQ SuperDLT1. So we now only disable the check on SCSI-1 and older devices. sys/cam/scsi/scsi_sa.c: In saregister(), only disable fetching long position information on SCSI-1 and older drives. Update the comment to explain why. Confirmed by: dvl Sponsored by: Spectra Logic MFC after: 3 weeks |
||
|
|
fd8be18f3f |
Fix I/O size calculation for pass(4) driver requests and add latency
tracking. It is important to subtract the residual from the requested transfer size to see how much data was actually transferred. With tape drives in particular, it is common to request more data than is returned. Also, add I/O latency tracking for CAM requests issued by cam_periph_runccb(). If the caller supplies a struct devstat, and the I/O is a SCSI or ATA I/O, we will track the elapsed time to provide I/O latency statistics for the request. sys/cam/scsi/cam_periph.c: In cam_periph_runccb(), subtract the residual when reporting I/O totals to devstat(9) for SCSI and ATA passthrough requests. In cam_periph_runccb(), grab the I/O start time and supply the start time to devstat_end_transaction() so that it can calculate the elapsed I/O time. Sponsored by: Spectra Logic MFC after: 1 week |
||
|
|
999efd901b |
Remove an obsolete comment in devstat(3) about the accuracy of the
milliseconds per transaction (DSM_MS_PER_TRANSACTION) calculation. The comment was accurate many years ago when the kernel didn't record I/O times on a per-I/O basis, but now that we do collect that information in most areas, it isn't correct. The milliseconds per transaction values are correct, assuming the I/O duration has been recorded. Sponsored by: Spectra Logic MFC after: 3 days |
||
|
|
6c0541fa8e |
Add FreeBSD stable/10 version checks for the availability of the
CDAI_FLAG_NONE advanced information CCB flag. Support for the flag was merged to stable/10 in r279329, and the __FreeBSD_version in stable/10 was bumped to 1001510. Check for that version in the mps(4) and mpr(4) drivers when determining whether to use the flag. Sponsored by: Spectra Logic MFC after: 3 days |
||
|
|
7b7c7a0533 |
Fix several problems found by Coverity.
lib/libmt/mtlib.c: In mt_start_element(), make sure we don't overflow the cur_sb array. CID 1271325 usr.bin/mt/mt.c: In main(), bzero the mt_com structure so that we aren't using any uninitialized stack variables. CID 1271319 In mt_param(), only allow one -s and one -p argument. This will prevent a memory leak caused by overwriting the param_name and/or param_value variables. CID 1271320 and CID 1271322 To make things simpler in mt_param(), make sure there there is only one exit path for the function. Make sure the arguments are explicitly freed. Sponsored by: Spectra Logic Pointed out by: emaste MFC after: 1 month |
||
|
|
62d67aa923 |
Fix printf format warnings on sparc64 and mips.
Sponsored by: Spectra Logic MFC after: 1 month |
||
|
|
9aa8427101 |
Bump __FreeBSD_version for the mtio(4) / sa(4) ioctl and API additions
in revision 279219. Sponsored by: Spectra Logic MFC after: 1 month |
||
|
|
43518607b2 |
Significant upgrades to sa(4) and mt(1).
The primary focus of these changes is to modernize FreeBSD's
tape infrastructure so that we can take advantage of some of the
features of modern tape drives and allow support for LTFS.
Significant changes and new features include:
o sa(4) driver status and parameter information is now exported via an
XML structure. This will allow for changes and improvements later
on that will not break userland applications. The old MTIOCGET
status ioctl remains, so applications using the existing interface
will not break.
o 'mt status' now reports drive-reported tape position information
as well as the previously available calculated tape position
information. These numbers will be different at times, because
the drive-reported block numbers are relative to BOP (Beginning
of Partition), but the block numbers calculated previously via
sa(4) (and still provided) are relative to the last filemark.
Both numbers are now provided. 'mt status' now also shows the
drive INQUIRY information, serial number and any position flags
(BOP, EOT, etc.) provided with the tape position information.
'mt status -v' adds information on the maximum possible I/O size,
and the underlying values used to calculate it.
o The extra sa(4) /dev entries (/dev/saN.[0-3]) have been removed.
The extra devices were originally added as place holders for
density-specific device nodes. Some OSes (NetBSD, NetApp's OnTap
and Solaris) have had device nodes that, when you write to them,
will automatically select a given density for particular tape drives.
This is a convenient way of switching densities, but it was never
implemented in FreeBSD. Only the device nodes were there, and that
sometimes confused users.
For modern tape devices, the density is generally not selectable
(e.g. with LTO) or defaults to the highest availble density when
the tape is rewritten from BOT (e.g. TS11X0). So, for most users,
density selection won't be necessary. If they do need to select
the density, it is easy enough to use 'mt density' to change it.
o Protection information is now supported. This is either a
Reed-Solomon CRC or CRC32 that is included at the end of each block
read and written. On write, the tape drive verifies the CRC, and
on read, the tape drive provides a CRC for the userland application
to verify.
o New, extensible tape driver parameter get/set interface.
o Density reporting information. For drives that support it,
'mt getdensity' will show detailed information on what formats the
tape drive supports, and what formats the tape drive supports.
o Some mt(1) functionality moved into a new mt(3) library so that
external applications can reuse the code.
o The new mt(3) library includes helper routines to aid in parsing
the XML output of the sa(4) driver, and build a tree of driver
metadata.
o Support for the MTLOAD (load a tape in the drive) and MTWEOFI
(write filemark immediate) ioctls needed by IBM's LTFS
implementation.
o Improve device departure behavior for the sa(4) driver. The previous
implementation led to hangs when the device was open.
o This has been tested on the following types of drives:
IBM TS1150
IBM TS1140
IBM LTO-6
IBM LTO-5
HP LTO-2
Seagate DDS-4
Quantum DLT-4000
Exabyte 8505
Sony DDS-2
contrib/groff/tmac/doc-syms,
share/mk/bsd.libnames.mk,
lib/Makefile,
Add libmt.
lib/libmt/Makefile,
lib/libmt/mt.3,
lib/libmt/mtlib.c,
lib/libmt/mtlib.h,
New mt(3) library that contains functions moved from mt(1) and
new functions needed to interact with the updated sa(4) driver.
This includes XML parser helper functions that application writers
can use when writing code to query tape parameters.
rescue/rescue/Makefile:
Add -lmt to CRUNCH_LIBS.
src/share/man/man4/mtio.4
Clarify this man page a bit, and since it contains what is
essentially the mtio.h header file, add new ioctls and structure
definitions from mtio.h.
src/share/man/man4/sa.4
Update BUGS and maintainer section.
sys/cam/scsi/scsi_all.c,
sys/cam/scsi/scsi_all.h:
Add SCSI SECURITY PROTOCOL IN/OUT CDB definitions and CDB building
functions.
sys/cam/scsi/scsi_sa.c
sys/cam/scsi/scsi_sa.h
Many tape driver changes, largely outlined above.
Increase the sa(4) driver read/write timeout from 4 to 32
minutes. This is based on the recommended values for IBM LTO
5/6 drives. This may also avoid timeouts for other tape
hardware that can take a long time to do retries and error
recovery. Longer term, a better way to handle this is to ask
the drive for recommended timeout values using the REPORT
SUPPORTED OPCODES command. Modern IBM and Oracle tape drives
at least support that command, and it would allow for more
accurate timeout values.
Add XML status generation. This is done with a series of
macros to eliminate as much duplicate code as possible. The
new XML-based status values are reported through the new
MTIOCEXTGET ioctl.
Add XML driver parameter reporting, using the new MTIOCPARAMGET
ioctl.
Add a new driver parameter setting interface, using the new
MTIOCPARAMSET and MTIOCSETLIST ioctls.
Add a new MTIOCRBLIM ioctl to get block limits information.
Add CCB/CDB building routines scsi_locate_16, scsi_locate_10,
and scsi_read_position_10().
scsi_locate_10 implements the LOCATE command, as does the
existing scsi_set_position() command. It just supports
additional arguments and features. If/when we figure out a
good way to provide backward compatibility for older
applications using the old function API, we can just revamp
scsi_set_position(). The same goes for
scsi_read_position_10() and the existing scsi_read_position()
function.
Revamp sasetpos() to take the new mtlocate structure as an
argument. It now will use either scsi_locate_10() or
scsi_locate_16(), depending upon the arguments the user
supplies. As before, once we change position we don't have a
clear idea of what the current logical position of the tape
drive is.
For tape drives that support long form position data, we
read the current position and store that for later reporting
after changing the position. This should help applications
like Bacula speed tape access under FreeBSD once they are
modified to support the new ioctls.
Add a new quirk, SA_QUIRK_NO_LONG_POS, that is set for all
drives that report SCSI-2 or older, as well as drives that
report an Illegal Request type error for READ POSITION with
the long format. So we should automatically detect drives
that don't support the long form and stop asking for it after
an initial try.
Add a partition number to the sa(4) softc.
Improve device departure handling. The previous implementation
led to hangs when the device was open.
If an application had the sa(4) driver open, and attempted to
close it after it went away, the cam_periph_release() call in
saclose() would cause the periph to get destroyed because that
was the last reference to it. Because destroy_dev() was
called from the sa(4) driver's cleanup routine (sacleanup()),
and would block waiting for the close to happen, a deadlock
would result.
So instead of calling destroy_dev() from the cleanup routine,
call destroy_dev_sched_cb() from saoninvalidate() and wait for
the callback.
Acquire a reference for devfs in saregister(), and release it
in the new sadevgonecb() routine when all devfs devices for
the particular sa(4) driver instance are gone.
Add a new function, sasetupdev(), to centralize setting
per-instance devfs device parameters instead of repeating the
code in saregister().
Add an open count to the softc, so we know how many
peripheral driver references are a result of open
sessions.
Add the D_TRACKCLOSE flag to the cdevsw flags so
that we get a 1:1 mapping of open to close calls
instead of a N:1 mapping.
This should be a no-op for everything except the
control device, since we don't allow more than one
open on non-control devices.
However, since we do allow multiple opens on the
control device, the combination of the open count
and the D_TRACKCLOSE flag should result in an
accurate peripheral driver reference count, and an
accurate open count.
The accurate open count allows us to release all
peripheral driver references that are the result
of open contexts once we get the callback from devfs.
sys/sys/mtio.h:
Add a number of new mt(4) ioctls and the requisite data
structures. None of the existing interfaces been removed
or changed.
This includes definitions for the following new ioctls:
MTIOCRBLIM /* get block limits */
MTIOCEXTLOCATE /* seek to position */
MTIOCEXTGET /* get tape status */
MTIOCPARAMGET /* get tape params */
MTIOCPARAMSET /* set tape params */
MTIOCSETLIST /* set N params */
usr.bin/mt/Makefile:
mt(1) now depends on libmt, libsbuf and libbsdxml.
usr.bin/mt/mt.1:
Document new mt(1) features and subcommands.
usr.bin/mt/mt.c:
Implement support for mt(1) subcommands that need to
use getopt(3) for their arguments.
Implement a new 'mt status' command to replace the old
'mt status' command. The old status command has been
renamed 'ostatus'.
The new status function uses the MTIOCEXTGET ioctl, and
therefore parses the XML data to determine drive status.
The -x argument to 'mt status' allows the user to dump out
the raw XML reported by the kernel.
The new status display is mostly the same as the old status
display, except that it doesn't print the redundant density
mode information, and it does print the current partition
number and position flags.
Add a new command, 'mt locate', that will supersede the
old 'mt setspos' and 'mt sethpos' commands. 'mt locate'
implements all of the functionality of the MTIOCEXTLOCATE
ioctl, and allows the user to change the logical position
of the tape drive in a number of ways. (Partition,
block number, file number, set mark number, end of data.)
The immediate bit and the explicit address bits are
implemented, but not documented in the man page.
Add a new 'mt weofi' command to use the new MTWEOFI ioctl.
This allows the user to ask the drive to write a filemark
without waiting around for the operation to complete.
Add a new 'mt getdensity' command that gets the XML-based
tape drive density report from the sa(4) driver and displays
it. This uses the SCSI REPORT DENSITY SUPPORT command
to get comprehensive information from the tape drive about
what formats it is able to read and write.
Add a new 'mt protect' command that allows getting and setting
tape drive protection information. The protection information
is a CRC tacked on to the end of every read/write from and to
the tape drive.
Sponsored by: Spectra Logic
MFC after: 1 month
|
||
|
|
e8577fb489 |
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 MFC after: 1 week |
||
|
|
3bba3152a7 |
Add support for probing the SCSI VPD Extended Inquiry page (0x86).
This VPD page is effectively an extension of the standard Inquiry data page, and includes lots of additional bits. This commit includes support for probing the page in the SCSI probe code, and an additional request type for the XPT_DEV_ADVINFO CCB. CTL already supports the Extended Inquiry page. Support for querying this page in the sa(4) driver will come later. sys/cam/scsi/scsi_xpt.c: Probe the Extended Inquiry page, if the device supports it, and return it in response to a XPT_DEV_ADVINFO CCB if it is requested. sys/cam/scsi/cam_ccb.h: Define a new advanced information CCB data type, CDAI_TYPE_EXT_INQ. sys/cam/cam_xpt.c: Free the extended inquiry data in a device when the device goes away. sys/cam/cam_xpt_internal.h: Add an extended inquiry data pointer and length to struct cam_ed. sys/sys/param.h Bump __FreeBSD_version for the addition of the new CDAI_TYPE_EXT_INQ advanced information type. Sponsored by: Spectra Logic MFC after: 1 week |
||
|
|
e761f855a0 |
Improve SCSI Extended Inquiry VPD page (0x86) support.
sys/cam/scsi/scsi_all.h: In struct scsi_extended_inquiry_data: - Increase the length field to 2 bytes, as it is 2 bytes in SPC-4. - Add bit definitions for the various Activiate Microcode actions. - Add the Sequential Access Logical Block Protection support bit, since we need that in the sa(4) driver. (For modifications that will come later.) - Add definitions for the various Multi I_T Nexus Microcode Download modes. sys/cam/ctl/ctl.c: As of SPC-4, a single report of "REPORTED LUNS DATA HAS CHANGED" is to be given per I_T nexus. Once it is reported, the unit attention condition should be cleared for all LUNS attached to an I_T nexus. Previously that only happened when a REPORT LUNS command was processed. This behavior may be different (according to SAM-5) when the UA_INTLCK_CTRL bits are non-zero in the control mode page but CTL does not currently support that. So, in view of the spec, whenever we report a LUN inventory change unit attention, clear it on all LUNs for that particular I_T nexus. Add a new function, ctl_clear_ua() that will clear a unit attention on all LUNs for the given I_T nexus. One field in the extended inquiry data that we could potentially report at some point is the maximum supported sense data length. To do that, we would the SIM to report (via path inquiry perhaps) how much sense data it is able to send. Add comments to explain some of the bits that are set in the Extended Inquiry VPD page. Add a few comments to make it more clear which functions handle various VPD pages. Sponsored by: Spectra Logic MFC after: 1 week |
||
|
|
5704e6f06c |
Close a race in the isp(4) driver that caused devices to disappear
and not automatically come back if they were gone for a short period of time. The isp(4) driver has a 30 second gone device timer that gets activated whenever a device goes away. If the device comes back before the timer expires, we don't send a notification to CAM that it has gone away. If, however, there is a command sent to the device while it is gone and before it comes back, the isp(4) driver sends the command back with CAM_SEL_TIMEOUT status. CAM responds to the CAM_SEL_TIMEOUT status by removing the device. In the case where a device comes back within the 30 second gone device timer window, though, we weren't telling CAM the device came back. So, fix this by tracking whether we have told CAM the device is gone, and if we have, send a rescan if it comes back within the 30 second window. ispvar.h: In the fcportdb_t structure, add a new bitfield, reported_gone. This gets set whenever we return a command with CAM_SEL_TIMEOUT status on a Fibre Channel device. isp_freebsd.c: In isp_done(), if we're sending CAM_SEL_TIMEOUT for for a command sent to a FC device, set the reported_gone bit. In isp_async(), in the ISPASYNC_DEV_STAYED case, rescan the device in question if it is mapped to a target ID and has been reported gone. In isp_make_here(), take a port database entry argument, and clear the reported_gone bit when we send a rescan to CAM. In isp_make_gone(), take a port database entry as an argument, and set the reported_gone bit when we send an async event telling CAM consumers that the device is gone. Sponsored by: Spectra Logic MFC after: 1 week |